PageSourceSearch

https://www.cledepeau-beaute.com/on/demandware.static/Sites-cpb_jp-Site/-/ja_JP/v1790903323976/js/app.js

js cledepeau-beaute.com collected 2026-10-03 23:04:05 UTC 1,551,720 bytes, 47,198 lines download raw bytes

1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2'use strict';
3
4var progress = require('./progress'),
5    util = require('./util');
6
7var currentRequests = [];
8
9/**
10 * @function
11 * @description Ajax request to get json response
12 * @param {Boolean} async  Asynchronous or not
13 * @param {String} url URI for the request
14 * @param {Object} data Name/Value pair data request
15 * @param {Function} callback  Callback function to be called
16 */
17var getJson = function getJson(options) {
18  options.url = util.toAbsoluteUrl(options.url);
19  // return if no url exists or url matches a current request
20  if (!options.url || currentRequests[options.url]) {
21    return;
22  }
23
24  currentRequests[options.url] = true;
25
26  // make the server call
27  $.ajax({
28    dataType: 'json',
29    url: options.url,
30    async: typeof options.async === 'undefined' || options.async === null ? true : options.async,
31    data: options.data || {}
32  })
33  // success
34  .done(function (response) {
35    if (options.callback) {
36      options.callback(response);
37    }
38  })
39  // failed
40  .fail(function (xhr, textStatus) {
41    if (textStatus === 'parsererror') {
42      window.alert(Resources.BAD_RESPONSE);
43    }
44    if (options.callback) {
45      options.callback(null);
46    }
47  })
48  // executed on success or fail
49  .always(function () {
50    // remove current request from hash
51    if (currentRequests[options.url]) {
52      delete currentRequests[options.url];
53    }
54  });
55};
56/**
57 * @function
58 * @description ajax request to load html response in a given container
59 * @param {String} url URI for the request
60 * @param {Object} data Name/Value pair data request
61 * @param {Function} callback  Callback function to be called
62 * @param {Object} target Selector or element that will receive content
63 */
64var load = function load(options) {
65  options.url = util.toAbsoluteUrl(options.url);
66  // return if no url exists or url matches a current request
67  if (!options.url || currentRequests[options.url]) {
68    return;
69  }
70
71  currentRequests[options.url] = true;
72
73  // make the server call
74  $.ajax({
75    dataType: 'html',
76    url: util.appendParamToURL(options.url, 'format', 'ajax'),
77    data: options.data,
78    xhrFields: {
79      withCredentials: true
80    }
81  }).done(function (response) {
82    // success
83    if (options.target) {
84      $(options.target).empty().html(response);
85    }
86    if (options.callback) {
87      options.callback(response);
88    }
89  }).fail(function (xhr, textStatus) {
90    // failed
91    if (textStatus === 'parsererror') {
92      window.alert(Resources.BAD_RESPONSE);
93    }
94    options.callback(null, textStatus);
95  }).always(function () {
96    progress.hide();
97    // remove current request from hash
98    if (currentRequests[options.url]) {
99      delete currentRequests[options.url];
100    }
101  });
102};
103
104exports.getJson = getJson;
105exports.load = load;
106
107},{"./progress":64,"./util":77}],2:[function(require,module,exports){
108'use strict';
109
110var _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; };
111
112var util = require('./util');
113var unbind = 0;
114var unbindcarousel = 0;
115
116var targetNode = document.getElementsByClassName('js-product-top-content')[0];
117var config = { attributes: true, childList: true, subtree: true };
118var initializationFlag = false;
119var imageChangedFlag = true;
120
121var pushChangeImageDatalayer = function pushChangeImageDatalayer(mutationsList, observer) {
122  observer.disconnect();
123  if (initializationFlag) {
124    if (imageChangedFlag) {
125      imageChangedFlag = false;
126      pushToDataLayer({
127        event: 'productInteraction',
128        interactionType: 'Image Change',
129        productCategory: window.productCache.catid,
130        productSubCategory: window.productCache.subcategory,
131        productName: window.productCache.name,
132        productId: window.productCache.ID,
133        pageCategory: getPageCategory(),
134        productOutOfStock: window.productCache.productOutOfStock,
135        productAutoReplen: window.productCache.productautoreplenish,
136        productColor: window.productCache.productColor,
137        collectionName: window.productCache.catid.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
138        productType: window.productCache.master ? 'master' : window.productCache.variant ? 'variant' : window.productCache.bundle ? 'bundle' : window.productCache.productSet ? 'productSet' : 'product'
139      });
140    } else {
141      imageChangedFlag = true;
142    }
143  } else {
144    initializationFlag = true;
145  }
146  observer.observe(targetNode, config);
147};
148
149// Function to confirm that slick.js has been loaded
150var isSlickLoaded = function isSlickLoaded(mutationsList, observer) {
151  observer.disconnect();
152
153  var element = document.querySelector(".slick-slide.slick-current.slick-active");
154  if (element) {
155    // Activate tag submission observer as slick.js is completed
156    observer = new MutationObserver(pushChangeImageDatalayer);
157    config = { attributes: true, childList: false, subtree: false };
158    targetNode = document.getElementsByClassName('slick-slide slick-current slick-active')[0];
159    observer.observe(targetNode, config);
160  } else {
161    // Resume monitoring because slick.js is not finished
162    observer.observe(targetNode, config);
163  }
164};
165
166// Re-detect slick when color and variation changes are made
167function initObserver() {
168  initializationFlag = false;
169  imageChangedFlag = true;
170  observer.disconnect();
171  observer = new MutationObserver(isSlickLoaded);
172  config = { attributes: true, childList: true, subtree: true };
173  targetNode = document.getElementsByClassName('js-product-top-content')[0];
174  observer.observe(targetNode, config);
175}
176
177var observer = new MutationObserver(isSlickLoaded);
178
179function getPageCategory() {
180  //return window.pageContext.title || "Content"; ###### this throws product name
181  switch (window.Resources.PAGE_CATEGORY) {
182    case 'product-showincategory':
183      return 'Product Page';
184      break;
185    case 'product-show':
186      return 'Product Page';
187      break;
188    case 'search-show':
189      return 'Category Page';
190      break;
191    case 'home-show':
192      return 'Home Page';
193      break;
194    case 'cart-show':
195      return 'Cart Page';
196      break;
197    case 'cart-addtowishlist':
198      return 'Cart Page';
199      break;
200    case 'customerservice-contactus':
201      return 'Contact Customer Care';
202      break;
203    case 'customerservice-concierge':
204      return 'Ask An Expert';
205      break;
206    case 'account-startregister':
207      return 'Account Creation';
208      break;
209    case 'account-editprofile':
210      return 'My Account';
211      break;
212    case 'address-list':
213      return 'My Account';
214      break;
215    case 'paymentinstruments-list':
216      return 'My Account';
217      break;
218    case 'wishlist-show':
219      return 'My Account';
220      break;
221    case 'order-history':
222      return 'My Account';
223      break;
224    case 'orderreplenishment-show':
225      return 'My Account';
226      break;
227    case 'login-show':
228      return 'Account Registration';
229      break;
230    case 'coshipping-start':
231      return 'Checkout';
232      break;
233    case 'coshipping-singleshipping':
234      return 'Checkout';
235      break;
236    case 'cobilling-start':
237      return 'Checkout';
238      break;
239    case 'cobilling-billing':
240      return 'Checkout';
241      break;
242    case 'search-showcontent':
243      return 'Site Search';
244      break;
245    case 'giftcert-purchase':
246      return 'Gift Card Page';
247      break;
248    case 'cocustomer-loginform':
249      return 'Customer Login';
250      break;
251    case 'default-start':
252      return 'Home Page';
253      break;
254    case 'search-brandify':
255      return 'Store Locator Page';
256      break;
257    default:
258      return 'Content';
259      break;
260  }
261}
262// Specific for checkout and cart page only
263function couponsubcategory() {
264  switch (window.Resources.PAGE_CATEGORY) {
265    case 'cart-show':
266      return 'Cart';
267      break;
268    case 'coshipping-start':
269      return 'Shipping';
270      break;
271    case 'coshipping-singleshipping':
272      return 'Payment';
273      break;
274    case 'cobilling-start':
275      return 'Payment';
276      break;
277    case 'cobilling-removegiftcertificate':
278      return 'Payment';
279      break;
280    case 'cobilling-billing':
281      return 'Review';
282      break;
283    case 'account-editprofile':
284      return 'Profile';
285      break;
286    case 'address-list':
287      return 'Addresses';
288      break;
289    case 'paymentinstruments-list':
290      return 'Payment Methods';
291      break;
292    case 'wishlist-show':
293      return 'Saved For Later';
294      break;
295    case 'order-history':
296      return 'Order History';
297      break;
298    case 'orderreplenishment-show':
299      return 'Replenishment';
300      break;
301    default:
302      break;
303  }
304}
305
306function isMobile() {
307  return $(window).width() <= 640;
308}
309//Specific for PDP
310function getProductName() {
311  return $('.product-detail .product-name').text().trim();
312}
313//Specific for PDP
314function getProductBrand() {
315  return 'Shiseido'; //$(".product-detail .product-brand").text();
316}
317//Specific for PDP
318function getProductID() {
319  return $('#pid').val();
320}
321//Specific for PDP
322function getProductCategory() {
323  return $('.breadcrumb').find('.breadcrumb-element:eq(1)').text().trim();
324}
325//Specific for PDP
326function getProductsubCategory() {
327  return $('.breadcrumb').find('.breadcrumb-element:eq(2)').text().trim();
328}
329// Specific for PDP
330function getProductsubsubCategory() {
331  return $('.breadcrumb').find('.breadcrumb-element:eq(3)').text().trim();
332}
333// Specific for PDP
334function getProductOrederType() {
335  var replen = $('.replenishmentCycle').val();
336  if (replen > 0) {
337    return 'Replenishment';
338  } else {
339    return 'Regular';
340  }
341}
342
343function getPageSubcategory() {
344  return window.pageContext.title || 'Content';
345}
346
347function getLanguage() {
348  if (window.User.locale.indexOf('en') >= 0) {
349    return 'English';
350  } else if (window.User.locale.indexOf('cn') >= 0) {
351    return 'Chinese';
352  } else if (window.User.locale.indexOf('es') >= 0) {
353    return 'Spanish';
354  } else {
355    return window.User.locale;
356  }
357}
358
359// page-specific: Cart, Checkout
360function getPageError() {
361  var $errorMsg = $('.error-form');
362  if ($errorMsg.length === 0) {
363    return '';
364  }
365
366  return $errorMsg.html().trim();
367}
368
369function getActiveSortingRule() {
370  var httpParams = util.getQueryStringParams(window.location.href);
371  var sortParam = httpParams['srule'];
372
373  if (!sortParam) {
374    return null;
375  }
376
377  return sortParam.split('-').map(function (w) {
378    return w[0].toUpperCase() + w.substr(1);
379  }).join(' ');
380}
381
382function pushToDataLayer(o) {
383  window.dataLayer = window.dataLayer || [];
384  window.dataLayer.push(util.filterObj(o));
385  //alert(JSON.stringify(util.filterObj(o)));
386}
387
388function isScrolledIntoView(elem) {
389  var docViewTop = $(window).scrollTop();
390  var docViewBottom = docViewTop + $(window).height() - 150;
391  var elemTop = $(elem).offset().top;
392  return elemTop <= docViewBottom && elemTop >= docViewTop;
393}
394
395function getpage() {
396  var url = window.location.href;
397  var splittedurl = url.split('?');
398  var page = splittedurl[0].split('/');
399  return page[page.length - 1];
400}
401//page-specific: PLP
402function getRefinementsFromURL() {
403  var str = '';
404  if (window.location.href.split('?').length > 1) {
405    var urlparam;
406    if (window.location.href.split('?')[1].indexOf('&') > -1) {
407      urlparam = window.location.href.split('?')[1].split('&');
408      var length = urlparam.length;
409      var prefnval, prefnkey, prefvval, prefvkey;
410      for (var i = 0; i < length; i++) {
411        var prefn = urlparam[i].indexOf('prefn');
412        if (prefn > -1) {
413          prefnkey = urlparam[i].split('=')[0];
414          prefnval = urlparam[i].split('=')[1];
415          console.log(prefnkey);
416          var num = prefnkey.charAt(5);
417          for (var a = 0; a < length; a++) {
418            var prefv = urlparam[a].indexOf('prefv');
419            prefvkey = urlparam[a].split('=')[0];
420            if (prefvkey == 'prefv' + num) {
421              prefvval = urlparam[a].split('=')[1];
422              str += '[' + prefnval + ':' + prefvval + ']';
423            }
424          }
425        }
426      }
427    }
428  }
429  return str;
430}
431
432function trackConsultationEvent(data) {
433  var TOOL_TYPES = {
434    skincareConsultation: 'Skincare Consultation'
435  };
436
437  pushToDataLayer({
438    event: 'consultation' + data.element[0].toUpperCase() + data.element.substr(1),
439    pageCategory: 'Consultation Tool',
440    consultationToolType: TOOL_TYPES[data.toolname] || data.toolname,
441    consultationQuestion: data.question,
442    consultationResponse: data.answers[0]
443  });
444}
445
446function trackConsultationPageview(data) {
447  pushToDataLayer({
448    event: 'consultationSteps',
449    pageCategory: 'Consultation Tool',
450    consultationToolType: data.toolname,
451    consultationStep: data.pagename
452  });
453}
454
455function trackInternalPromotionEvent(data) {
456  var promotionURL = data.pageName;
457
458  pushToDataLayer({
459    event: 'eePromoClick',
460    pageSubCategory: data.pageSubCategory,
461    pageCategory: data.pageCategory,
462    promotions: [{
463      position: data.position,
464      id: data.id,
465      creative: data.creative,
466      name: data.name
467    }]
468  }), function () {
469    setTimeout(function () {
470      if (promotionURL != undefined) {
471        document.location = promotionURL;
472      }
473    }, 1000);
474  }();
475}
476
477function trackInternalPromotionPageView(data) {
478  pushToDataLayer({
479    eeAction: 'eePromoView',
480    event: 'eePromoView',
481    pageSubCategory: data.pageSubCategory,
482    pageCategory: data.pageCategory,
483    promotions: [{
484      position: data.position,
485      id: data.id,
486      creative: data.creative,
487      name: data.name
488    }]
489  });
490}
491
492function initializeGlobalEvents() {
493  var navctr = true;
494  var gtmNavData = '';
495
496  $(document)
497  // add to wishlist in pdp and quickview
498  .on('click', '#save-for-later', function (e) {
499    var data = $(this).data('catid');
500    var productCategory = data.length > 0 ? data[0] : '';
501    var productSubCategory = data.length > 1 ? data[1] : '';
502    pushToDataLayer({
503      event: 'clickSaveForLater',
504      productCategory: productCategory,
505      productSubCategory: productSubCategory,
506      productName: window.productCache.name,
507      productId: getProductID(),
508      pageCategory: getPageCategory(),
509      productOutOfStock: window.productCache.productOutOfStock,
510      productAutoReplen: window.productCache.productautoreplenish,
511      productColor: window.productCache.color ? window.productCache.color : 'null',
512      collectionName: window.productCache.catid.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
513      productType: 'Product'
514    });
515  })
516
517  // add to wishlist in cart
518  .on('click', '.add-to-wishlist', function (e) {
519    var index = $(this).parents('.cart-row').index();
520    pushToDataLayer({
521      event: 'clickSaveForLater',
522      productCategory: basketConfirmation.productLineItems[index].category,
523      productSubCategory: basketConfirmation.productLineItems[index].subCategory,
524      productName: basketConfirmation.productLineItems[index].name,
525      productId: basketConfirmation.productLineItems[index].id,
526      pageCategory: getPageCategory(),
527      productOutOfStock: $(this).data('instock'),
528      productAutoReplen: $(this).data('replenishable'),
529      productColor: $(this).parents('.c-list-products-full-item-text').first().find(".c-dlist_03-item[data-attribute='color']").length > 0 ? $(this).parents('.c-list-products-full-item-text').first().find(".c-dlist_03-item[data-attribute='color'] dd").text().trim() : 'null',
530      collectionName: basketConfirmation.productLineItems[index].category.toLowerCase().search('synactif') > -1 ? 'Synactif' : 'null',
531      productType: 'Product'
532    });
533  })
534
535  // remove to wishlist PDP
536  .on('click', '.remove-from-wishlist', function (e) {
537    var data = $(this).data('catid');
538    var productCategory = data.length > 0 ? data[0] : '';
539    var productSubCategory = data.length > 1 ? data[1] : '';
540    pushToDataLayer({
541      event: 'removeFromWishlist',
542      productCategory: productCategory,
543      productSubCategory: productSubCategory,
544      productName: window.productCache.name,
545      productId: getProductID(),
546      pageCategory: getPageCategory(),
547      productOutOfStock: window.productCache.productOutOfStock,
548      productAutoReplen: window.productCache.productautoreplenish,
549      productColor: window.productCache.color ? window.productCache.color : 'null',
550      collectionName: window.productCache.catid.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
551      productType: 'Product'
552    });
553  })
554
555  // remove to wishlist from my account
556  .on('click', '.c-list-products-full-item .delete-item', function (e) {
557    var $target = $(this);
558    var data = $target.data('catid');
559    var productCategory = data.length > 0 ? data[0] : '';
560    var productSubCategory = data.length > 1 ? data[1] : '';
561    var productName = $target.data('productname');
562    var productId = $target.data('productid');
563    var productOutOfStock = $target.data('instock');
564    var productAutoReplen = $target.data('replenishable');
565    var productColor = $target.data('productcolor');
566
567    pushToDataLayer({
568      event: 'removeFromWishlist',
569      productCategory: productCategory,
570      productSubCategory: productSubCategory,
571      productName: productName,
572      productId: productId,
573      pageCategory: getPageCategory(),
574      productOutOfStock: productOutOfStock,
575      productAutoReplen: productAutoReplen,
576      productColor: productColor ? productColor : 'null',
577      collectionName: productCategory.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
578      productType: 'Product'
579    });
580  })
581
582  // newsletter in navigation;
583  .on('clicknewsletter', function (e, data) {
584    pushToDataLayer({
585      event: 'newsletterSubscription',
586      siteLocation: data.siteloc
587    });
588  })
589
590  // click ask question in pdp
591  .on('click', '.bv-ask-question', function (e) {
592    pushToDataLayer({
593      page: getpage(),
594      event: 'askQuestion',
595      productCategory: getProductCategory(),
596      pageSubCategory: 'Ask a Question',
597      productName: getProductName(),
598      pageCategory: 'Product Page'
599    });
600  })
601
602  // Scroll on reviews in pdp
603  .scroll(function () {
604    if ($('.bv-section-summary').length) {
605      if (isScrolledIntoView('.bv-section-summary') && unbind < 1) {
606        unbind = 1;
607        pushToDataLayer({
608          event: 'productReviewsView',
609          page: getpage(),
610          pageCategory: 'Product Page',
611          productColor: window.productCache.productColor,
612          productType: 'Product',
613          collectionName: window.productCache.catid.toLowerCase().search('synactif') > -1 ? 'Synactif' : 'null'
614        });
615      }
616    }
617
618    // for recommendation in pdp and cart, Best Seller and Recently Viewed in Homepage
619    if ($('.pi .carousel-recommendations').length > 0 || $('.cross-sell .carousel-recommendations').length > 0) {
620      if (isScrolledIntoView('.carousel-recommendations') && unbindcarousel < 1) {
621        unbindcarousel = 1;
622        pushToDataLayer({
623          currencyCode: window.User.currencyCode,
624          eeAction: 'eeListView',
625          event: 'eeListView',
626          pageCategory: getPageCategory(),
627          products: window.forpageload.product
628        });
629      }
630    }
631  })
632
633  // Click on Reviews in PDP
634  .on('click', '.bv-inline-histogram-ratings-star-container', function () {
635    pushToDataLayer({
636      event: 'productReviewsView',
637      page: getpage(),
638      pageCategory: 'Product Page',
639      productColor: window.productCache.productColor,
640      productType: 'Product',
641      collectionName: window.productCache.catid.toLowerCase().search('synactif') > -1 ? 'Synactif' : 'null'
642    });
643  })
644
645  // Check balance giftcard in gift card page
646  .on('click', '#CheckBalanceButton', function () {
647    if ($('#dwfrm_giftcert_balance_giftCertID').val() != '' && $('#dwfrm_giftcert_balance_giftCertPIN').val() != '') {
648      pushToDataLayer({
649        event: 'checkBalance',
650        giftCardNumber: $('#dwfrm_giftcert_balance_giftCertID').val()
651        //					"pageSubCategory": "Gift Card",
652        //					"pageCategory": "My Account"
653      });
654    }
655  })
656
657  // Check balance giftcard in checkout modal
658  .on('click', '#check-giftcert-modal', function (e) {
659    if ($('#giftcardbalancemodal #dwfrm_billing_giftCertCode').val() != '' && $('#giftcardbalancemodal #dwfrm_giftcert_balance_giftCertPIN').val() != '') {
660      pushToDataLayer({
661        event: 'checkBalance',
662        giftCardNumber: $('#giftcardbalancemodal #dwfrm_billing_giftCertCode').val()
663        //					"pageSubCategory": "Payment",
664        //					"pageCategory": "Checkout"
665      });
666    }
667  })
668
669  // Redeem gift card in checkout page
670  .on('click', '.pt_checkout #add-giftcert', function () {
671    if ($('.gift-card-form #dwfrm_billing_giftCertCode').val() != '' && $('.gift-card-form #dwfrm_giftcert_balance_giftCertPIN').val() != '') {
672      pushToDataLayer({
673        event: 'redeemGiftCard',
674        giftCardNumber: $('.gift-card-form #dwfrm_billing_giftCertCode').val()
675      });
676    }
677  })
678
679  // Redeem gift card in checkout modal
680  .on('click', '#add-giftcert-modal', function () {
681    if ($('#giftcardbalancemodal #dwfrm_billing_giftCertCode').val() != '' && $('#giftcardbalancemodal #dwfrm_giftcert_balance_giftCertPIN').val() != '') {
682      pushToDataLayer({
683        event: 'redeemGiftCard',
684        giftCardNumber: $('#giftcardbalancemodal #dwfrm_billing_giftCertCode').val()
685      });
686    }
687  })
688
689  // add to cart from PDP
690  .on('click', '#add-to-cart', function (e) {
691    if (getPageCategory() == 'Cart Page') {
692      if (sessionStorage.getItem('cartupdate')) {
693        sessionStorage.setItem('productUpdate', '1');
694      }
695    } else {
696      window.productCache = window.productCache || {};
697      pushToDataLayer({
698        event: 'addToCart',
699        //"productOrderType": getProductOrederType(),
700        currencyCode: window.Resources.CURRENCY,
701        addToCartType: $(this).parents('.quick-view').length ? 'Quick Shop' : 'Product Page',
702        //"pageCategory": getPageCategory(),
703        products: [{
704          name: getProductName(),
705          id: getProductID(),
706          price: Number($('#add-to-cart').data('price')),
707          brand: getProductBrand(),
708          category: window.productCache.category,
709          variant: $('.c-block-shopingmodal-side-size .c-tileradio-input:checked').parent().find('.c-tileradio-label-text').first().text().trim(),
710          quantity: Number($('.c-quantitySelection .c-select-current').text().trim()),
711          productAutoReplen: $('#add-to-cart').data('replenishable'),
712          productColor: $('.c-list-color .c-list-color-panel.is-current').data('description'),
713          productOutOfStock: $('#add-to-cart').data('instock'),
714          collectionName: window.productCache.catid.toLowerCase().search('synactif') > -1 ? 'Synactif' : 'null',
715          productType: 'Product',
716          productStarRating: '',
717          productVariantID: $('.c-block-shopingmodal-side-size .c-tileradio-input:checked').parent().find('.c-tileradio-label-text').first().text().trim() != '' && $('.c-list-color .c-list-color-panel.is-current').data('description') != '' ? getProductID() : 'null',
718          numberOfProductReview: ''
719          //"subCategory" : window.productCache.subcategory,
720          //"subSubCategory" : window.productCache.subsubcategory,
721          //"productNumReviews":"",
722        }]
723      });
724    }
725  })
726
727  //Click at '+' on cart page
728  .on('click', '.c-list-products-full-item--cart .c-quantitySelection-btn-plus', function () {
729    sessionStorage.setItem('productUpdate', '1');
730    var index = $(this).parents('.cart-row').index();
731    var product = basketConfirmation.productLineItems[index];
732
733    pushToDataLayer({
734      event: 'addToCart',
735      addToCartType: 'Cart Page',
736      currencyCode: basketConfirmation.currencyCode,
737      products: [{
738        name: product.name,
739        id: product.id,
740        price: product.price,
741        brand: product.brand,
742        category: product.category,
743        variant: product.size,
744        quantity: 1,
745        productAutoReplen: product.productAutoReplen,
746        productColor: product.color,
747        productOutOfStock: product.productOutOfStock,
748        collectionName: product.collectionName,
749        productType: product.productType,
750        productStarRating: product.productStarRating,
751        productVariantID: product.productVariantID,
752        numberOfProductReview: product.numberOfProductReview
753      }]
754    });
755  })
756
757  //Click at '-' on cart page
758  .on('click', '.c-list-products-full-item--cart .c-quantitySelection-btn-minus', function () {
759    sessionStorage.setItem('productUpdate', '1');
760    var index = $(this).parents('.cart-row').index();
761    var product = basketConfirmation.productLineItems[index];
762    if (product.quantity > 1) {
763      pushToDataLayer({
764        event: 'removeFromCart',
765        addToCartType: 'Cart Page',
766        currencyCode: basketConfirmation.currencyCode,
767        products: [{
768          name: product.name,
769          id: product.id,
770          price: product.price,
771          brand: product.brand,
772          category: product.category,
773          variant: product.size,
774          quantity: 1,
775          productAutoReplen: product.productAutoReplen,
776          productColor: product.color,
777          productOutOfStock: product.productOutOfStock,
778          collectionName: product.collectionName,
779          productType: product.productType,
780          productStarRating: product.productStarRating,
781          productVariantID: product.productVariantID,
782          numberOfProductReview: product.numberOfProductReview
783        }]
784      });
785    }
786  })
787
788  //Click change quantity on cart page
789  .on('click', '.c-list-products-full-item--cart .c-quantitySelection .c-quantitySelection-num .c-select-list a', function () {
790    sessionStorage.setItem('productUpdate', '1');
791    var index = $(this).parents('.cart-row').index();
792    var product = basketConfirmation.productLineItems[index];
793    if ($(this).text() != '') {
794      pushToDataLayer({
795        event: Number($(this).text().trim()) - product.quantity > 0 ? 'addToCart' : 'removeFromCart',
796        addToCartType: 'Cart Page',
797        currencyCode: basketConfirmation.currencyCode,
798        products: [{
799          name: product.name,
800          id: product.id,
801          price: product.price,
802          brand: product.brand,
803          category: product.category,
804          variant: product.size,
805          quantity: Math.abs(Number($(this).text().trim()) - product.quantity),
806          productAutoReplen: product.productAutoReplen,
807          productColor: product.color,
808          productOutOfStock: product.productOutOfStock,
809          collectionName: product.collectionName,
810          productType: product.productType,
811          productStarRating: product.productStarRating,
812          productVariantID: product.productVariantID,
813          numberOfProductReview: product.numberOfProductReview
814        }]
815      });
816    }
817  })
818
819  // Submit ask a question
820  .on('click', ".bv-submission-section button:contains('Post Question')", function (e) {
821    pushToDataLayer({
822      //"page": getpage(),
823      event: 'submitQuestion',
824      //"productCategory": getProductCategory(),
825      question: $('#bv-textarea-field-questionsummary').val(),
826      //"productName": getProductName(),
827      //"pageSubCategory": "Ask a Question",
828      pageCategory: getPageCategory()
829    });
830  })
831
832  // remove from cart
833  .on('click', '.c-list-products-full-remove a', function (e) {
834    var index = $(this).parents('.cart-row').index();
835    pushToDataLayer({
836      event: 'removeFromCart',
837      currencyCode: window.Resources.CURRENCY,
838      addToCartType: getPageCategory(),
839      //"productOrderType": ($(this).parents(".cart-row").find(".replenishment .replenishmentDays").length > 0) ? "Replenishment" : "Regular",
840      //"pageCategory": getPageCategory(),
841      products: [{
842        name: basketConfirmation.productLineItems[index].name,
843        id: basketConfirmation.productLineItems[index].id,
844        price: basketConfirmation.productLineItems[index].price,
845        brand: getProductBrand(),
846        category: basketConfirmation.productLineItems[index].category,
847        variant: basketConfirmation.productLineItems[index].size,
848        quantity: basketConfirmation.productLineItems[index].quantity,
849        productAutoReplen: basketConfirmation.productLineItems[index].productAutoReplen,
850        productColor: basketConfirmation.productLineItems[index].productColor,
851        productType: basketConfirmation.productLineItems[index].productType,
852        productOutOfStock: basketConfirmation.productLineItems[index].productAutoReplen.productOutOfStock,
853        collectionName: basketConfirmation.productLineItems[index].category == 'Synactif' ? 'Synactif' : 'null',
854        productStarRating: '',
855        productVariantID: '',
856        numberOfProductReview: basketConfirmation.productLineItems[index].size != '' && basketConfirmation.productLineItems[index].productColor != '' ? basketConfirmation.productLineItems[index].id : 'null'
857      }]
858    });
859  })
860  // click zoom in pdp
861  .on('click', '.c-block-shopingmodal-main-image .c-modal-img', function (e) {
862    pushToDataLayer({
863      event: 'productInteraction',
864      interactionType: 'Zoom',
865      productCategory: window.productCache.catid,
866      productSubCategory: window.productCache.subcategory,
867      productName: window.productCache.name,
868      productId: window.productCache.ID,
869      pageCategory: getPageCategory(),
870      productOutOfStock: window.productCache.productOutOfStock,
871      productAutoReplen: window.productCache.productautoreplenish,
872      productColor: window.productCache.productColor,
873      collectionName: window.productCache.catid.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
874      productType: window.productCache.master ? 'master' : window.productCache.variant ? 'variant' : window.productCache.bundle ? 'bundle' : window.productCache.productSet ? 'productSet' : 'product'
875    });
876  })
877
878  // click full ingredients in pdp
879  .on('click', '.cpb-products-summary_cover .cpb-products-summary_tab_list a', function (e) {
880    var interactionType = $(this).data('tab-target');
881    switch (interactionType) {
882      case 'content1':
883        interactionType = 'About The Product';
884        break;
885      case 'content2':
886        interactionType = 'Features';
887        break;
888      case 'content3':
889        interactionType = 'How To Use';
890        break;
891      case 'content4':
892        interactionType = 'View Full Product Ingredients';
893        break;
894      default:
895        interactionType = 'Other Content';
896        break;
897    }
898    pushToDataLayer({
899      event: 'productInteraction',
900      interactionType: interactionType,
901      productCategory: window.productCache.catid,
902      productSubCategory: window.productCache.subcategory,
903      productName: window.productCache.name,
904      productId: window.productCache.ID,
905      pageCategory: getPageCategory(),
906      productOutOfStock: window.productCache.productOutOfStock,
907      productAutoReplen: window.productCache.productautoreplenish,
908      productColor: window.productCache.productColor,
909      collectionName: window.productCache.catid.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
910      productType: window.productCache.master ? 'master' : window.productCache.variant ? 'variant' : window.productCache.bundle ? 'bundle' : window.productCache.productSet ? 'productSet' : 'product'
911    });
912  }).on('click', '.cart-promo-approaching', function () {
913    pushToDataLayer({
914      event: 'eePromoClick',
915      pageSubCategory: 'Internal marketing',
916      pageCategory: 'Cart Page',
917      promotions: [{
918        position: 'Cart',
919        id: $('.cart-promo-approaching').data('promoid'),
920        creative: 'Cart-Banner',
921        name: $('.cart-promo-approaching').data('promoname')
922      }]
923    });
924  }).on('click', '.cart-coupon-code #add-coupon', function () {
925    localStorage.removeItem('couponvalidation');
926  })
927
928  // track share button on PDP
929  .on('click', '.social-sharing-container .share-icon', function () {
930    pushToDataLayer({
931      socialAction: 'Share',
932      event: 'socialShare',
933      siteLocation: 'product page',
934      pageCategory: getPageCategory(),
935      socialNetwork: $(this).data('share')
936    });
937  })
938
939  // Track Follow button on Footer
940  .on('click', '.ge-footer-connectWithUs-icon li a', function () {
941    pushToDataLayer({
942      event: 'socialClick',
943      socialNetwork: $(this).find('title').length > 0 ? $(this).find('title').text().trim() : 'null',
944      socialAction: 'Follow',
945      siteLocation: 'footer',
946      pageCategory: getPageCategory()
947    });
948  })
949
950  // Add to Cart in Save for later
951  .on('click', '.wishlist-item .add-to-cart', function () {
952    var index = $(this).parents('form').index();
953    pushToDataLayer({
954      currencyCode: window.Resources.CURRENCY,
955      event: 'addToCart',
956      //"productOrderType": getProductOrederType(),
957      addToCartType: getPageCategory(),
958      pageSubCategory: getProductsubCategory(),
959      pageCategory: getPageCategory(),
960      products: [{
961        id: wishlistItem.product[index].id,
962        category: wishlistItem.product[index].category,
963        price: wishlistItem.product[index].price,
964        name: wishlistItem.product[index].name,
965        brand: wishlistItem.product[index].brand,
966        quantity: wishlistItem.product[index].quantity,
967        size: wishlistItem.product[index].size,
968        subCategory: wishlistItem.product[index].subcategory,
969        subSubCategory: wishlistItem.product[index].subcategory,
970        productAutoReplen: wishlistItem.product[index].productAutoReplen,
971        productOutOfStock: wishlistItem.product[index].productOutOfStock,
972        productColor: wishlistItem.product[index].color,
973        productType: 'Product',
974        productNumReviews: '',
975        productStarRating: ''
976      }]
977    });
978  })
979
980  // Add to all to Cart
981  .on('click', '.add-all-to-cart', function () {
982    pushToDataLayer({
983      currencyCode: window.Resources.CURRENCY,
984      event: 'addToCart',
985      //"productOrderType": getProductOrederType(),
986      addToCartType: getPageCategory(),
987      pageSubCategory: getProductsubCategory(),
988      pageCategory: getPageCategory(),
989      products: wishlistItem.product
990    });
991  })
992
993  // click email hyper link in navigation
994  .on('click', '#header .emailcsr-nav', function () {
995    if (window.Resources.PAGE_CATEGORY == 'page-show') {
996      pushToDataLayer({
997        event: 'contactRequest',
998        contactType: 'Email',
999        siteLocation: 'Header',
1000        //					"pageSubCategory": couponsubcategory(),
1001        pageCategory: getProductCategory()
1002      });
1003    } else {
1004      pushToDataLayer({
1005        event: 'contactRequest',
1006        contactType: 'Email',
1007        siteLocation: 'Header',
1008        pageSubCategory: window.Resources.PAGE_CATEGORY == 'cart-show' ? '' : couponsubcategory(),
1009        pageCategory: getPageCategory()
1010      });
1011    }
1012  })
1013  // Click email link in the customer care
1014  //		.on("click",".content-asset a:contains('[email protected]')",function(){
1015  //			pushToDataLayer({
1016  //				"event": "contactRequest",
1017  //				"contactType": "Email",
1018  //				"siteLocation": window.Resources.PAGE_CATEGORY=="cart-show" ? "Right Nav":"Body",
1019  ////				"pageSubCategory": couponsubcategory(),
1020  //				"pageCategory": window.Resources.PAGE_CATEGORY=="cart-show" ? getPageCategory(): getProductCategory()
1021  //			});
1022  //		})
1023
1024  .on('gtmcontactus', function () {
1025    pushToDataLayer({
1026      event: 'contactRequest',
1027      contactType: 'Contact Customer Care Submission',
1028      siteLocation: 'Body',
1029      pageCategory: getPageCategory()
1030    });
1031  }).on('askanexpert', function () {
1032    pushToDataLayer({
1033      event: 'contactRequest',
1034      contactType: 'Ask An Expert Submission',
1035      siteLocation: 'Body',
1036      pageSubCategory: couponsubcategory(),
1037      pageCategory: 'Ask An Expert'
1038    });
1039  }).on('click', '#header .live-chat', function () {
1040    pushToDataLayer({
1041      event: 'contactRequest',
1042      contactType: 'Live Chat',
1043      siteLocation: 'Header',
1044      pageSubCategory: couponsubcategory(),
1045      pageCategory: getPageCategory()
1046    });
1047  }).on('click', '#header .call-us', function () {
1048    pushToDataLayer({
1049      event: 'contactRequest',
1050      contactType: 'Call Us',
1051      siteLocation: 'Header',
1052      pageSubCategory: couponsubcategory(),
1053      pageCategory: getPageCategory()
1054    });
1055  }).on('click', '.LPMimage', function () {
1056    var id = $(this).attr('id');
1057    var chk = id.charAt(id.length - 1);
1058    if (chk == 1) {
1059      pushToDataLayer({
1060        event: 'contactRequest',
1061        contactType: 'Live Chat',
1062        siteLocation: 'Pop-up',
1063        pageSubCategory: couponsubcategory(),
1064        pageCategory: getPageCategory()
1065      });
1066    }
1067  }).on('click', '.footer-container .products ul li:nth-child(4)', function () {
1068    pushToDataLayer({
1069      event: 'contactRequest',
1070      contactType: 'Phone',
1071      siteLocation: 'Footer',
1072      pageSubCategory: window.Resources.PAGE_CATEGORY == 'cart-show' ? '' : couponsubcategory(),
1073      pageCategory: getPageCategory()
1074    });
1075  })
1076
1077  // click on recommendation
1078  .on('click', '.recommendation-item', function () {
1079    if (getPageCategory() == 'Product Page') {
1080      sessionStorage.setItem('listType', 'Recommended Product List');
1081      sessionStorage.setItem('listName', 'Product Page');
1082    } else if (getPageCategory() == 'Home Page') {
1083      sessionStorage.setItem('listType', 'Recently Viewed List');
1084      sessionStorage.setItem('listName', 'Home Page');
1085    }
1086  }).on('click', '.catalog-link', function (e) {
1087    if (navctr == true) {
1088      gtmNavData = $(this).text().trim();
1089      sessionStorage.setItem('navlink', gtmNavData);
1090      sessionStorage.setItem('menuloc', 'topmenu');
1091      util.setCookie('navdata', gtmNavData, 0.2);
1092      navctr = false;
1093    }
1094  }).on('click', '.cmd-cross-nav_list a', function (e) {
1095    if (navctr == true) {
1096      gtmNavData = $(this).text().trim();
1097      sessionStorage.setItem('navlink', gtmNavData);
1098      sessionStorage.setItem('menuloc', 'topmenu');
1099      util.setCookie('navdata', gtmNavData, 0.2);
1100      navctr = false;
1101    }
1102  }).on('click', '.cpb-gnav_container .cpb-gnav_list a', function (e) {
1103    gtmNavData = $(this).text().trim();
1104    sessionStorage.setItem('navlink', gtmNavData);
1105    sessionStorage.setItem('menuloc', 'leftmenu');
1106    util.setCookie('navdata', gtmNavData, 0.2);
1107  }).on('click', '.cpb-gnav_container .cpb-gnav-utility_list a', function (e) {
1108    gtmNavData = $(this).text().trim();
1109    sessionStorage.setItem('navlink', gtmNavData);
1110    sessionStorage.setItem('menuloc', 'leftmenu');
1111    util.setCookie('navdata', gtmNavData, 0.2);
1112  }).on('click', '.cpb-modal_account .cpb-account_area a', function (e) {
1113    gtmNavData = $(this).text().trim();
1114    sessionStorage.setItem('navlink', gtmNavData);
1115    sessionStorage.setItem('menuloc', 'myacountmenu');
1116    util.setCookie('navdata', gtmNavData, 0.2);
1117  }).on('click', '.refinement-header', function (e) {
1118    gtmNavData = $(this).text().trim();
1119    sessionStorage.setItem('navlink', gtmNavData);
1120    sessionStorage.setItem('menuloc', 'leftmenu');
1121  }).on('click', '.refinement-link', function (e) {
1122    gtmNavData = $(this).text().trim();
1123    sessionStorage.setItem('navlink', gtmNavData);
1124    sessionStorage.setItem('menuloc', 'leftmenu');
1125  }).on('click', '.breadcrumb-element', function (e) {
1126    gtmNavData = $(this).text().trim();
1127    sessionStorage.setItem('breadcrumbs', gtmNavData);
1128    sessionStorage.setItem('menuloc', 'leftmenu');
1129  }).on('change', '#quantity', function (e) {
1130    if (getPageCategory() == 'Cart Page') {
1131      if ($('.edit-modal').length > 0) {
1132        sessionStorage.setItem('cartupdate', '1');
1133      } else {
1134        sessionStorage.setItem('productUpdate', '1');
1135      }
1136    }
1137  }).on('change', '.quantity-select', function (e) {
1138    if (window.Resources.PAGE_CATEGORY == 'wishlist-show') {
1139      sessionStorage.setItem('productUpdate', '1');
1140    }
1141  }).on('click', '.c-list-sideNavi li', function (e) {
1142    gtmNavData = $(this).text().trim();
1143    sessionStorage.setItem('navlink', gtmNavData);
1144    sessionStorage.setItem('menuloc', 'leftmenu');
1145  })
1146
1147  // Remove uservalidation attribute for userlogin validation and product update
1148  .on('click', '.user-logout', function (e) {
1149    localStorage.removeItem('uservalidation');
1150    sessionStorage.removeItem('productUpdate');
1151  }).on('click', '#pdp-swatches.c-block-shopingmodal-side-color a, .c-block-shopingmodal-side-colorSelect .c-select-list-item', function () {
1152    if (getPageCategory() == 'Cart Page') {
1153      sessionStorage.setItem('cartupdate', '1');
1154    }
1155  }).on('click', '.mfp-close', function () {
1156    if (getPageCategory() == 'Cart Page') {
1157      sessionStorage.setItem('cartupdate', '');
1158    }
1159  }).on('click', '#save-for-later', function () {
1160    if (getPageCategory() == 'Cart Page') {
1161      sessionStorage.setItem('cartupdate', '');
1162    }
1163  }).on('click', '#pdp-swatches .selectable', function () {
1164    if (getPageCategory() == 'Cart Page') {
1165      if (!$(this).hasClass('selected')) {
1166        sessionStorage.setItem('cartupdate', '1');
1167      }
1168    }
1169  }).on('click', '.search-suggestion-wrapper .hit', function () {
1170    gtmNavData = $(this).text().trim();
1171    sessionStorage.setItem('navlink', gtmNavData.replace(/\s\s+/g, ' '));
1172    sessionStorage.setItem('menuloc', 'site search pop-in');
1173  }).on('click', '.search-suggestion-wrapper .product-suggestion', function () {
1174    gtmNavData = $(this).text().trim();
1175    var rep = gtmNavData.replace(/\n/g, ' ');
1176    sessionStorage.setItem('navlink', rep.replace(/ +/g, ' '));
1177    sessionStorage.setItem('menuloc', 'site search pop-in');
1178  })
1179
1180  // PLP click in list
1181  .on('click', '.c-product-cards-list .c-product-cards-list-item a.c-product-cards-photo-img', function () {
1182    var index = $(this).parents('.c-product-cards-list-item').index('.c-product-cards-list-item');
1183    var url = $(this).attr('href');
1184    if (index >= 0) {
1185      if (productData.page >= 1) {
1186        pushToDataLayer({
1187          event: 'eeListClick',
1188          eeAction: 'eeListClick',
1189          pageCategory: searchItems.search ? 'Site Search' : 'Product List Page',
1190          page: url ? url : 'null',
1191          products: [prodholder[index]]
1192        }), function () {
1193          setTimeout(function () {
1194            if (url != undefined && url != null) {
1195              document.location = url;
1196            }
1197          }, 1000);
1198        }();
1199        sessionStorage.setItem('listType', prodholder[index].listType);
1200        sessionStorage.setItem('listName', prodholder[index].listName);
1201      } else {
1202        pushToDataLayer({
1203          event: 'eeListClick',
1204          eeAction: 'eeListClick',
1205          pageCategory: searchItems.search ? 'Site Search' : 'Product List Page',
1206          page: url ? url : 'null',
1207          products: [prodholder[0][index]]
1208        }), function () {
1209          setTimeout(function () {
1210            if (url != undefined && url != null) {
1211              document.location = url;
1212            }
1213          }, 1000);
1214        }();
1215        sessionStorage.setItem('listType', prodholder[0][index].listType);
1216        sessionStorage.setItem('listName', prodholder[0][index].listName);
1217      }
1218    }
1219  })
1220
1221  // PLP click in list
1222  .on('click', '.c-product-cards-list .c-product-cards-list-item .c-product-cards-text a', function () {
1223    var index = $(this).parents('.c-product-cards-list-item').index('.c-product-cards-list-item');
1224    var url = $(this).attr('href');
1225    if (index >= 0) {
1226      if (productData.page > 0) {
1227        pushToDataLayer({
1228          event: 'eeListClick',
1229          eeAction: 'eeListClick',
1230          pageCategory: searchItems.search ? 'Site Search' : 'Product List Page',
1231          page: url ? url : 'null',
1232          products: [prodholder[index]]
1233        }), function () {
1234          setTimeout(function () {
1235            if (url != undefined && url != null) {
1236              document.location = url;
1237            }
1238          }, 1000);
1239        }();
1240        sessionStorage.setItem('listType', prodholder[index].listType);
1241        sessionStorage.setItem('listName', prodholder[index].listName);
1242      } else {
1243        pushToDataLayer({
1244          event: 'eeListClick',
1245          eeAction: 'eeListClick',
1246          pageCategory: searchItems.search ? 'Site Search' : 'Product List Page',
1247          page: url ? url : 'null',
1248          products: [prodholder[0][index]]
1249        }), function () {
1250          setTimeout(function () {
1251            if (url != undefined && url != null) {
1252              document.location = url;
1253            }
1254          }, 1000);
1255        }();
1256        sessionStorage.setItem('listType', prodholder[0][index].listType);
1257        sessionStorage.setItem('listName', prodholder[0][index].listName);
1258      }
1259    }
1260  })
1261
1262  // Recommendation, bestseller eelistclick in homepage,pdp,cart
1263  .on('click', '.pi .carousel-recommendations .recommendation-item', function (e) {
1264    var index = $(this).index() - 3;
1265    if (_typeof(prodData.product[index]) != undefined && prodData.product[index] != null) {
1266      pushToDataLayer({
1267        event: 'eeListClick',
1268        pageSubCategory: '',
1269        pageCategory: getPageCategory(),
1270        filterChoice: '',
1271        dropDown: '',
1272        products: [{
1273          listType: prodData.product[index].listType,
1274          listName: prodData.product[index].listName,
1275          position: prodData.product[index].position,
1276          id: prodData.product[index].id,
1277          category: getProductCategory(),
1278          price: prodData.product[index].price,
1279          name: prodData.product[index].name,
1280          brand: getProductBrand(),
1281          quantity: prodData.product[index].quantity,
1282          size: prodData.product[index].size,
1283          subCategory: prodData.product[index].subCategory,
1284          subSubCategory: prodData.product[index].subSubCategory,
1285          productAutoReplen: prodData.product[index].productAutoReplen,
1286          productOutOfStock: prodData.product[index].productOutOfStock,
1287          productColor: prodData.product[index].productColor,
1288          productType: prodData.product[index].productType,
1289          productNumReviews: '',
1290          productStarRating: ''
1291        }]
1292      });
1293      sessionStorage.setItem('listType', prodData.product[index].listType);
1294      sessionStorage.setItem('listName', prodData.product[index].listName);
1295    }
1296  })
1297
1298  // Recently viewed eelistclick in homepage
1299  .on('click', '.cross-sell .carousel-recommendations ul .recommendation-item', function (e) {
1300    var index = $(this).index() - 3;
1301    if (_typeof(prodData.product[index]) != undefined && prodData.product[index] != null) {
1302      pushToDataLayer({
1303        event: 'eeListClick',
1304        pageSubCategory: '',
1305        pageCategory: getPageCategory(),
1306        filterChoice: '',
1307        dropDown: '',
1308        products: [{
1309          listType: prodData.product[index].listType,
1310          listName: prodData.product[index].listName,
1311          position: prodData.product[index].position,
1312          id: prodData.product[index].id,
1313          category: getProductCategory(),
1314          price: prodData.product[index].price,
1315          name: prodData.product[index].name,
1316          brand: getProductBrand(),
1317          quantity: prodData.product[index].quantity,
1318          size: prodData.product[index].size,
1319          subCategory: prodData.product[index].subCategory,
1320          subSubCategory: prodData.product[index].subSubCategory,
1321          productAutoReplen: prodData.product[index].productAutoReplen,
1322          productOutOfStock: prodData.product[index].productOutOfStock,
1323          productColor: prodData.product[index].productColor,
1324          productType: prodData.product[index].productType,
1325          productNumReviews: '',
1326          productStarRating: ''
1327        }]
1328      });
1329      sessionStorage.setItem('listType', prodData.product[index].listType);
1330      sessionStorage.setItem('listName', prodData.product[index].listName);
1331    }
1332  })
1333
1334  // click on viewmore button
1335  .on('plpviewmore', function (e) {
1336    if (getPageCategory() == 'Category Page') {
1337      if (prodholder && _typeof(productData.product) != undefined) {
1338        if (productData.page > 1) {
1339          prodholder = prodholder.concat(productData.product);
1340        } else {
1341          prodholder = prodholder[0].concat(productData.product);
1342        }
1343
1344        for (var i = 0; i < prodholder.length; i++) {
1345          prodholder[i].position = i + 1;
1346        }
1347        for (var a = 0; a < productData.product.length; a++) {
1348          var diff = productData.product.length - a;
1349          productData.product[a].position = prodholder.length - diff + 1;
1350        }
1351        pushDtLayer({
1352          event: 'eeListView',
1353          eeAction: 'eeListView',
1354          pageCategory: searchItems.search ? 'Site Search' : 'Product List Page',
1355          dropDown: '',
1356          filterChoice: '',
1357          currencyCode: window.User.currencyCode,
1358          products: productData.product || new Array()
1359        });
1360      }
1361    }
1362  }).on('click', '.c-block-shopingmodal-main-thumbnail .slick-slide', function () {
1363    $(document).trigger('clickproductthumbnail');
1364  })
1365  // change color
1366  .on('click', '.cpb-products-color_list li a', function (e) {
1367    pushToDataLayer({
1368      event: 'productInteraction',
1369      interactionType: 'Color Change',
1370      productCategory: window.productCache.catid,
1371      productSubCategory: window.productCache.subcategory,
1372      productName: window.productCache.name,
1373      productId: window.productCache.ID,
1374      pageCategory: getPageCategory(),
1375      productOutOfStock: window.productCache.productOutOfStock,
1376      productAutoReplen: window.productCache.productautoreplenish,
1377      productColor: window.productCache.productColor,
1378      collectionName: window.productCache.catid.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
1379      productType: window.productCache.master ? 'master' : window.productCache.variant ? 'variant' : window.productCache.bundle ? 'bundle' : window.productCache.productSet ? 'productSet' : 'product'
1380    });
1381    initObserver();
1382  })
1383  // change variation
1384  .on('click', '.c-tileradio-list .c-tileradio-list-item label', function (e) {
1385    pushToDataLayer({
1386      event: 'productInteraction',
1387      interactionType: 'Variant Change',
1388      productCategory: window.productCache.catid,
1389      productSubCategory: window.productCache.subcategory,
1390      productName: window.productCache.name,
1391      productId: window.productCache.ID,
1392      pageCategory: getPageCategory(),
1393      productOutOfStock: window.productCache.productOutOfStock,
1394      productAutoReplen: window.productCache.productautoreplenish,
1395      productColor: window.productCache.productColor,
1396      collectionName: window.productCache.catid.toLowerCase().search('シナクティフ') > -1 ? 'Synactif' : 'null',
1397      productType: window.productCache.master ? 'master' : window.productCache.variant ? 'variant' : window.productCache.bundle ? 'bundle' : window.productCache.productSet ? 'productSet' : 'product'
1398    });
1399    initObserver();
1400  })
1401
1402  // Click findstore button in PDP 「店舗を探す」クリック
1403  .on('click', '.cmd-button_box._wide._WHT.cpb-products-cart_submit.storelocator a', function () {
1404    pushToDataLayer({
1405      event: 'ec_retail_button_click',
1406      website_country: 'JP',
1407      language: 'jp',
1408      currency: 'JPY',
1409      item_name: window.productCache.name,
1410      item_id: window.productCache.ID,
1411      price: pdpdata.pricing.sale,
1412      item_brand: 'Cle de Peau Beaute',
1413      item_variant: pdpdata.color ? pdpdata.color : pdpdata.variant ? pdpdata.variant : 'null',
1414      item_category: ProductDataCat[2],
1415      item_category2: ProductDataCat[1],
1416      item_category3: ProductDataCat[0],
1417      button_text: this.innerText,
1418      next_page: this.href,
1419      section_name: '店舗を探す'
1420    });
1421  })
1422
1423  // Click onlineshopguide button in PDP 「オンラインショップを探す」クリック
1424  .on('click', '.cmd-button_box._wide._WHT.cpb-products-cart_submit.onlineshopguide a', function () {
1425    pushToDataLayer({
1426      event: 'ec_retail_button_click',
1427      website_country: 'JP',
1428      language: 'jp',
1429      currency: 'JPY',
1430      item_name: window.productCache.name,
1431      item_id: window.productCache.ID,
1432      price: pdpdata.pricing.sale,
1433      item_brand: 'Cle de Peau Beaute',
1434      item_variant: pdpdata.color ? pdpdata.color : pdpdata.variant ? pdpdata.variant : 'null',
1435      item_category: ProductDataCat[2],
1436      item_category2: ProductDataCat[1],
1437      item_category3: ProductDataCat[0],
1438      button_text: this.innerText,
1439      next_page: this.href,
1440      section_name: 'オンラインショップ'
1441    });
1442  })
1443
1444  // Click onlineshop button in onlineshopguide 「化粧品専門店」「総合スーパー」「デパート」「SHISEIDO ONLINE STORE」クリック
1445  .on('click', '.button.sppl10.sppr10.onlineshopguide', function () {
1446    pushToDataLayer({
1447      event: 'ec_retail_button_click',
1448      website_country: 'JP',
1449      language: 'jp',
1450      currency: 'JPY',
1451      item_name: ProductData.name,
1452      item_id: ProductData.ID,
1453      price: ProductData.pricing.sale,
1454      item_brand: 'Cle de Peau Beaute',
1455      item_variant: ProductData.productColor ? ProductData.productColor : ProductData.size ? ProductData.size : 'null',
1456      item_category: ProductDataCat[2],
1457      item_category2: ProductDataCat[1],
1458      item_category3: ProductDataCat[0],
1459      button_text: this.innerText,
1460      next_page: this.href,
1461      section_name: 'オンラインショップ' + ':' + this.innerText
1462    });
1463  })
1464
1465  // Click tokuisaki button in onlineshopguidespecialty 化粧品専門店 >「得意先EC名」クリック
1466  .on('click', '.button.sppl10.sppr10.onlineshop-guid-specialty', function () {
1467    pushToDataLayer({
1468      event: 'ec_retail_button_click',
1469      website_country: 'JP',
1470      language: 'jp',
1471      currency: 'JPY',
1472      item_name: ProductData.name,
1473      item_id: ProductData.ID,
1474      price: ProductData.pricing.sale,
1475      item_brand: 'Cle de Peau Beaute',
1476      item_variant: ProductData.productColor ? ProductData.productColor : ProductData.size ? ProductData.size : 'null',
1477      item_category: ProductDataCat[2],
1478      item_category2: ProductDataCat[1],
1479      item_category3: ProductDataCat[0],
1480      button_text: this.innerText.replace("\n", " "),
1481      next_page: this.href,
1482      section_name: 'オンラインショップ:化粧品専門店'
1483    });
1484  })
1485
1486  // Click omiseplus button in onlineshopguidespecialty 化粧品専門店 > Omise+「詳しくはこちらから」クリック
1487  .on('click', '.cmd-button_box._sizeS._WHT.omiseplus a', function () {
1488    pushToDataLayer({
1489      event: 'ec_retail_button_click',
1490      website_country: 'JP',
1491      language: 'jp',
1492      currency: 'JPY',
1493      item_name: ProductData.name,
1494      item_id: ProductData.ID,
1495      price: ProductData.pricing.sale,
1496      item_brand: 'Cle de Peau Beaute',
1497      item_variant: ProductData.productColor ? ProductData.productColor : ProductData.size ? ProductData.size : 'null',
1498      item_category: ProductDataCat[2],
1499      item_category2: ProductDataCat[1],
1500      item_category3: ProductDataCat[0],
1501      button_text: 'Omise+',
1502      next_page: this.href,
1503      section_name: 'オンラインショップ:化粧品専門店'
1504    });
1505  })
1506
1507  // Click omiseplus button in onlineshopguidedepartment デパート >「得意先EC名」クリック
1508  .on('click', '.button.sppl10.sppr10.onlineshop-guide-department', function () {
1509    pushToDataLayer({
1510      event: 'ec_retail_button_click',
1511      website_country: 'JP',
1512      language: 'jp',
1513      currency: 'JPY',
1514      item_name: ProductData.name,
1515      item_id: ProductData.ID,
1516      price: ProductData.pricing.sale,
1517      item_brand: 'Cle de Peau Beaute',
1518      item_variant: ProductData.productColor ? ProductData.productColor : ProductData.size ? ProductData.size : 'null',
1519      item_category: ProductDataCat[2],
1520      item_category2: ProductDataCat[1],
1521      item_category3: ProductDataCat[0],
1522      button_text: this.innerText.replace("\n", " "),
1523      next_page: this.href,
1524      section_name: 'オンラインショップ:デパート'
1525    });
1526  })
1527
1528  // Click omiseplus button in onlineshopguidegms 総合スーパー >「得意先EC名」クリック
1529  .on('click', '.button.sppl10.sppr10.onlineshop-guid-gms', function () {
1530    pushToDataLayer({
1531      event: 'ec_retail_button_click6',
1532      website_country: 'JP',
1533      language: 'jp',
1534      currency: 'JPY',
1535      item_name: ProductData.name,
1536      item_id: ProductData.ID,
1537      price: ProductData.pricing.sale,
1538      item_brand: 'Cle de Peau Beaute',
1539      item_variant: ProductData.productColor ? ProductData.productColor : ProductData.size ? ProductData.size : 'null',
1540      item_category: ProductData.subsubcategory,
1541      item_category2: ProductData.subcategory,
1542      item_category3: ProductData.catid,
1543      button_text: this.innerText.replace("\n", " "),
1544      next_page: this.href,
1545      section_name: 'オンラインショップ:総合スーパー'
1546    });
1547  })
1548
1549  // click on next arrow recommendation carousel and best seller
1550  .on('click', '.pi .carousel-recommendations .slick-next', function (e) {
1551    if ((typeof prodData === 'undefined' ? 'undefined' : _typeof(prodData)) != undefined && prodData != null) {
1552      var array = new Array();
1553      var listholder = new Array();
1554      var listchecker = false;
1555      var listctr = 0;
1556      $('.recommendation-item').each(function (index) {
1557        if ($('.recommendation-item').filter('.slick-active').length == 3) {
1558          if (index > 2 && $(this).hasClass('slick-active')) {
1559            array.push(index - 3);
1560          }
1561        } else {
1562          if (index > 2 && ($(this).hasClass('slick-active') || $(this).hasClass('slick-current'))) {
1563            listctr = 2;
1564            if (prodData.product.length > 3) {
1565              listchecker = true;
1566              listctr = 0;
1567            }
1568            array.push(index - 3);
1569          } else {
1570            if (listchecker && listctr < 2 && index > 2 && array.length <= 3) {
1571              if (array[array.length] != index - 3) {
1572                listctr += 1;
1573                array.push(index - 3);
1574              }
1575            } else {
1576              listchecker = false;
1577            }
1578          }
1579        }
1580      });
1581      for (var i = 0; i < prodData.product.length; i++) {
1582        for (var a = 0; a < array.length; a++) {
1583          if (i == array[a]) {
1584            listholder.push(prodData.product[i]);
1585          }
1586        }
1587      }
1588      pushToDataLayer({
1589        currencyCode: window.User.currencyCode,
1590        eeAction: 'eeListView',
1591        event: 'eeListView',
1592        pageCategory: getPageCategory(),
1593        products: listholder
1594      });
1595    }
1596  })
1597
1598  // click on next arrow recommendation carousel and best seller
1599  .on('click', '.pi .carousel-recommendations .slick-prev', function (e) {
1600    if ((typeof prodData === 'undefined' ? 'undefined' : _typeof(prodData)) != undefined && prodData != null) {
1601      var array = new Array();
1602      var listholder = new Array();
1603      var listchecker = false;
1604      var listctr = 0;
1605      $('.recommendation-item').each(function (index) {
1606        if ($('.recommendation-item').filter('.slick-active').length == 3) {
1607          if (index > 2 && $(this).hasClass('slick-active')) {
1608            array.push(index - 3);
1609          }
1610        } else {
1611          if (index > 2 && ($(this).hasClass('slick-active') || $(this).hasClass('slick-current'))) {
1612            listctr = 2;
1613            if (prodData.product.length > 3) {
1614              listchecker = true;
1615              listctr = 0;
1616            }
1617            array.push(index - 3);
1618          } else {
1619            if (listchecker && listctr < 2 && index > 2 && array.length <= 3) {
1620              if (array[array.length] != index - 3) {
1621                listctr += 1;
1622                array.push(index - 3);
1623              }
1624            } else {
1625              listchecker = false;
1626            }
1627          }
1628        }
1629      });
1630      for (var i = 0; i < prodData.product.length; i++) {
1631        for (var a = 0; a < array.length; a++) {
1632          if (i == array[a]) {
1633            listholder.push(prodData.product[i]);
1634          }
1635        }
1636      }
1637      pushToDataLayer({
1638        currencyCode: window.User.currencyCode,
1639        eeAction: 'eeListView',
1640        event: 'eeListView',
1641        pageCategory: getPageCategory(),
1642        products: listholder
1643      });
1644    }
1645  })
1646
1647  // click on next arrow recently viewed
1648  .on('click', '.cross-sell .carousel-recommendations .slick-next', function (e) {
1649    if ((typeof prodData === 'undefined' ? 'undefined' : _typeof(prodData)) != undefined && prodData != null) {
1650      var array = new Array();
1651      var listholder = new Array();
1652      $('.recommendation-item').each(function (index) {
1653        if (index > 2 && $(this).hasClass('slick-active')) {
1654          array.push(index - 3);
1655        }
1656      });
1657      for (var i = 0; i < prodData.product.length; i++) {
1658        for (var a = 0; a < array.length; a++) {
1659          if (i == array[a]) {
1660            listholder.push(prodData.product[i]);
1661          }
1662        }
1663      }
1664      pushToDataLayer({
1665        currencyCode: window.User.currencyCode,
1666        eeAction: 'eeListView',
1667        event: 'eeListView',
1668        pageCategory: getPageCategory(),
1669        products: listholder
1670      });
1671    }
1672  })
1673
1674  // click on next arrow recently viewed
1675  .on('click', '.cross-sell .carousel-recommendations .slick-prev', function (e) {
1676    if ((typeof prodData === 'undefined' ? 'undefined' : _typeof(prodData)) != undefined && prodData != null) {
1677      var array = new Array();
1678      var listholder = new Array();
1679      $('.recommendation-item').each(function (index) {
1680        if (index > 2 && $(this).hasClass('slick-active')) {
1681          array.push(index - 3);
1682        }
1683      });
1684      for (var i = 0; i < prodData.product.length; i++) {
1685        for (var a = 0; a < array.length; a++) {
1686          if (i == array[a]) {
1687            listholder.push(prodData.product[i]);
1688          }
1689        }
1690      }
1691      pushToDataLayer({
1692        currencyCode: window.User.currencyCode,
1693        eeAction: 'eeListView',
1694        event: 'eeListView',
1695        pageCategory: getPageCategory(),
1696        products: listholder
1697      });
1698    }
1699  })
1700
1701  // pdp fire when variation was change
1702  .on('gtvariationchange', function (e) {
1703    if (getPageCategory() == 'Product Page') {
1704      pushToDataLayer({
1705        eeAction: 'eeProductDetail',
1706        event: 'eeProductDetail',
1707        pageCategory: 'Product Page',
1708        products: [{
1709          listType: sessionStorage.getItem('listType'),
1710          listName: sessionStorage.getItem('listName'),
1711          id: pdpdata.defalutvariant ? pdpdata.defalutvariant : pdpdata.ID,
1712          category: pdpdata.category,
1713          price: pdpdata.pricing.sale ? pdpdata.pricing.sale : pdpdata.pricing.minprice,
1714          name: pdpdata.name,
1715          brand: pdpdata.brand,
1716          quantity: pdpdata.quantity,
1717          size: pdpdata.size,
1718          subCategory: pdpdata.subcategory,
1719          subSubCategory: pdpdata.subsubcategory,
1720          productAutoReplen: pdpdata.productautoreplenish,
1721          productOutOfStock: pdpdata.productOutOfStock,
1722          productColor: pdpdata.productColor,
1723          productType: 'Product',
1724          productNumReviews: '',
1725          productStarRating: ''
1726        }]
1727      });
1728    }
1729  })
1730
1731  // quickview action
1732  .on('click', '.c-product-cards-quickshop-toggle', function () {
1733    var index = $(this).parents('.c-product-cards-list-item').index('.c-product-cards-list-item');
1734    if (productData.product.length > 0 && prodholder[0].length > index) {
1735      pushToDataLayer({
1736        eeAction: 'eeProductDetail',
1737        event: 'eeProductDetail',
1738        pageCategory: 'Category Page',
1739        products: [prodholder[0][index]]
1740      });
1741    }
1742  })
1743
1744  // filter
1745  .on('click', '.c-block-products-search-panel--filter .c-select .c-select-list-item a', function () {
1746    pushToDataLayer({
1747      event: 'dropDownChoice',
1748      dropDownType: 'Filter',
1749      listType: 'product category list',
1750      listName: $('.c-title-pageHeading-title').length > 0 ? $('.c-title-pageHeading-title').text().trim() : 'null',
1751      filterChoice: $(this).length > 0 ? $(this).text().trim() : 'null'
1752    });
1753  })
1754
1755  // sort
1756  .on('click', '.c-block-products-search-panel--sort .c-select .c-select-list-item a', function () {
1757    pushToDataLayer({
1758      event: 'dropDownChoice',
1759      dropDownType: 'Sort',
1760      listType: 'product category list',
1761      listName: $('.c-title-pageHeading-title').length > 0 ? $('.c-title-pageHeading-title').text().trim() : 'null',
1762      filterChoice: $(this).length > 0 ? $(this).text().trim() : 'null'
1763    });
1764  })
1765
1766  // Transaction funnel steps - shipping to payment
1767  .on('click', 'button[name="dwfrm_singleshipping_shippingAddress_save"]', function () {
1768    pushToDataLayer({
1769      event: 'eeCheckoutOption',
1770      checkoutStep: '1',
1771      checkoutOption: sessionStorage.getItem('productUpdate') != '' ? sessionStorage.getItem('productUpdate') : '0'
1772    });
1773  })
1774
1775  // Transaction funnel step - payment to review
1776  .on('click', 'button[name="dwfrm_billing_save"]', function () {
1777    pushToDataLayer({
1778      event: 'eeCheckoutOption',
1779      checkoutStep: '2',
1780      checkoutOption: basketConfirmation.defaultShipping
1781    });
1782  })
1783
1784  // Transaction funnel step - review to confirmation
1785  .on('click', '.pt_checkout #summary-place-order', function () {
1786    pushToDataLayer({
1787      event: 'eeCheckoutOption',
1788      checkoutStep: '3',
1789      checkoutOption: basketConfirmation.paymentMethod
1790    });
1791
1792    sessionStorage.setItem('productUpdate', '');
1793  })
1794
1795  // subscription on account registration page
1796  .on('click', '.pt_account #register-new-account', function () {
1797    if ($('input[name="dwfrm_profile_customer_addtoemaillist"]').prop('checked')) {
1798      $(document).trigger('clicknewsletter', {
1799        siteloc: 'account registration page'
1800      });
1801      sessionStorage.setItem('subscription', true);
1802    } else {
1803      sessionStorage.setItem('subscription', false);
1804    }
1805  })
1806
1807  // subscription on profile page
1808  .on('click', '.pt_account #profile-save-changes', function () {
1809    if ($('input[name="dwfrm_profile_customer_addtoemaillist"]').prop('checked') && sessionStorage.getItem('subscription') == 'false') {
1810      $(document).trigger('clicknewsletter', { siteloc: 'profile page' });
1811      sessionStorage.setItem('subscription', true);
1812    }
1813  }).on('click', '.c-block-languagselection li a', function () {
1814    pushToDataLayer({
1815      event: 'changeLanguage',
1816      language: $(this).length > 0 ? $(this).text().trim() : 'null'
1817    });
1818  })
1819
1820  // Store locator interaction rate. click header
1821  .on('click', '.header-shop_btn a', function () {
1822    pushToDataLayer({
1823      event: 'storeLocator',
1824      pageCategory: getPageCategory()
1825    });
1826  })
1827
1828  // Store locator interaction rate in pdp
1829  .on('click', '.cpb-products-shop .cpb-products-cart_submit:first-child', function () {
1830    pushToDataLayer({
1831      event: 'storeLocator',
1832      pageCategory: getPageCategory()
1833    });
1834  })
1835
1836  // Store locator interaction rate in toppage header navigation
1837  .on('click', '.cmd-cross-nav_list li:nth-child(6)', function () {
1838    pushToDataLayer({
1839      event: 'storeLocator',
1840      pageCategory: getPageCategory()
1841    });
1842  })
1843
1844  // Contact form submission rate in footer
1845  .on('click', '.cpb-footer-nav_container .cpb-footer-nav_list .contactus', function () {
1846    var socialNetwork = $(this).text().trim();
1847    pushToDataLayer({
1848      event: 'contactRequest',
1849      contactType: 'Email',
1850      siteLocation: 'Body',
1851      pageCategory: getPageCategory()
1852    });
1853  })
1854  // Contact form submission rate in contact us page
1855  .on('click', '.cmd-button_box .contactus', function () {
1856    var socialNetwork = $(this).text().trim();
1857    pushToDataLayer({
1858      event: 'contactRequest',
1859      contactType: 'Email',
1860      siteLocation: 'Body',
1861      pageCategory: getPageCategory()
1862    });
1863  })
1864  // Contact form submission rate in global account menu
1865  .on('click', '.account-menu_list .contactus', function () {
1866    var socialNetwork = $(this).text().trim();
1867    pushToDataLayer({
1868      event: 'contactRequest',
1869      contactType: 'Email',
1870      siteLocation: 'Body',
1871      pageCategory: getPageCategory()
1872    });
1873  })
1874  // Contact form submission rate account page menu
1875  .on('click', '.c-list-sideNavi .contactus', function () {
1876    var socialNetwork = $(this).text().trim();
1877    pushToDataLayer({
1878      event: 'contactRequest',
1879      contactType: 'Email',
1880      siteLocation: 'Body',
1881      pageCategory: getPageCategory()
1882    });
1883  })
1884
1885  // Social attractivity(PDP)
1886  .on('click', '.item-link_sns_box .item-link_sns_list li a', function () {
1887    var socialNetwork = $(this).text().trim();
1888    pushToDataLayer({
1889      event: 'socialClick',
1890      socialNetwork: socialNetwork,
1891      socialAction: 'shere',
1892      siteLocation: 'product page',
1893      pageCategory: getPageCategory()
1894    });
1895  })
1896
1897  // Social attractivity(footer)
1898  .on('click', '.cpb-footer-sns_wrapper .cpb-footer-sns_list .list-item:not(.cpb-app) a', function () {
1899    var socialNetwork = $(this).text().trim();
1900    pushToDataLayer({
1901      event: 'socialClick',
1902      socialNetwork: socialNetwork,
1903      socialAction: 'shere',
1904      siteLocation: 'footer',
1905      pageCategory: getPageCategory()
1906    });
1907  })
1908
1909  // change product shade
1910  .on('click', '#ymk-modal_right a.swatchanchor', function () {
1911    var childThatHasColorText = $(this).find('.c-list-color-panel');
1912    if (childThatHasColorText == null) return;
1913
1914    pushToDataLayer({
1915      event: "youCamTryOnInteraction",
1916      tryOnInteraction: "change product shade",
1917      productName: productCache.name,
1918      productColor: childThatHasColorText.attr('data-description')
1919    });
1920  });
1921
1922  if (targetNode) {
1923    observer.observe(targetNode, config);
1924  }
1925}
1926
1927switch (gtCurPage) {
1928  case 'page-show':
1929    var contentsAssetID = window.location.href.split('/').pop().split('.')[0];
1930    if (contentsAssetID == 'synactif-top') {
1931      var products = [];
1932      $(document).find('.cmd-section_products .cmd-col-card_link').each(function (index) {
1933        products.push({
1934          name: $(this).data('name'),
1935          id: $(this).data('id'),
1936          price: $(this).data('price'),
1937          brand: getProductBrand(),
1938          category: 'Synactif',
1939          variant: $(this).data('variant'),
1940          list: 'product category list > Synactif',
1941          position: index + 1,
1942          collectionName: 'Synactif'
1943        });
1944      });
1945    }
1946    pushDtLayer({
1947      event: 'eeListView',
1948      eeAction: 'eeListView',
1949      currencyCode: window.User.currencyCode,
1950      pageCategory: 'Product List Page',
1951      pageSubCategory: 'Product Search Results',
1952      products: products
1953    });
1954    break;
1955}
1956
1957module.exports = {
1958  init: function init() {
1959    initializeGlobalEvents();
1960  },
1961  tagmanager: {
1962    click: function click(data) {
1963      return trackConsultationEvent(data);
1964    },
1965
1966    pageview: function pageview(data) {
1967      return trackConsultationPageview(data);
1968    }
1969  },
1970  gtmInternalPromotion: {
1971    click: function click(data) {
1972      return trackInternalPromotionEvent(data);
1973    },
1974
1975    pageview: function pageview(data) {
1976      return trackInternalPromotionPageView(data);
1977    }
1978  }
1979};
1980
1981},{"./util":77}],3:[function(require,module,exports){
1982'use strict';
1983
1984var analytics = require('./analytics'),
1985    countries = require('./countries'),
1986    dialog = require('./dialog'),
1987    quickview = require('./quickview'),
1988    minicart = require('./minicart'),
1989    page = require('./page'),
1990    rating = require('./rating'),
1991    searchplaceholder = require('./searchplaceholder'),
1992
1993//searchsuggest = require('./searchsuggest'),
1994tooltip = require('./tooltip'),
1995    util = require('./util'),
1996    validator = require('./validator'),
1997    slick = require('./slick'),
1998    tls = require('./tls'),
1999    video = require('./video'),
2000    headerMenu = require('./header-menu'),
2001    footerSelector = require('./footer-selector'),
2002    newsletter = require('./newsletter'),
2003    orderreplenishment = require('./order-replenishment'),
2004    inputEntry = require('./input-entry'),
2005    producttile = require('./product-tile'),
2006    design = require('./design'),
2007    newDesign = require('./new-design'),
2008    login = require('./login'),
2009    hanatsubaki_club_member_id_edit = require('./hanatsubaki_club_member_id_edit'),
2010    loading = require('./loading'),
2011    ajax = require('./ajax'),
2012    dd = require('./dd');
2013
2014//if jQuery has not been loaded, load from google cdn
2015if (!window.jQuery) {
2016  var s = document.createElement('script');
2017
2018  s.setAttribute('src', 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js');
2019  s.setAttribute('type', 'text/javascript');
2020
2021  document.getElementsByTagName('head')[0].appendChild(s);
2022}
2023
2024require('./jquery-ext')();
2025require('./cookieprivacy')();
2026//require('./captcha')();
2027
2028function initializeEvents() {
2029  var controlKeys = ['8', '13', '46', '45', '36', '35', '38', '37', '40', '39'];
2030
2031  $('body').on('keydown', 'textarea[data-character-limit]', function (e) {
2032    var text = $.trim($(this).val()),
2033        charsLimit = $(this).data('character-limit'),
2034        charsUsed = text.length;
2035
2036    if (charsUsed >= charsLimit && controlKeys.indexOf(e.which.toString()) < 0) {
2037      e.preventDefault();
2038    }
2039  }).on('change keyup mouseup', 'textarea[data-character-limit]', function () {
2040    var text = $(this).val(),
2041        charsLimit = $(this).data('character-limit'),
2042        charsUsed = text.length,
2043        charsRemain = charsLimit - charsUsed;
2044
2045    if (charsRemain < 0) {
2046      $(this).val(text.slice(0, charsRemain));
2047      charsRemain = 0;
2048    }
2049
2050    $(this).closest('.field-wrapper').find('.char-remain-count').html(charsRemain);
2051  });
2052
2053  /**
2054   * initialize search suggestions, pending the value of the site preference(enhancedSearchSuggestions)
2055   * this will either init the legacy(false) or the beta versions(true) of the the search suggest feature.
2056   * */
2057  var $searchContainer = $('.utility-nav .header-search');
2058
2059  //searchsuggest.init($searchContainer, Resources.SIMPLE_SEARCH);
2060
2061  // add show/hide navigation elements
2062  $('.secondary-navigation .toggle').click(function () {
2063    $(this).toggleClass('expanded').next('ul').toggle();
2064  });
2065
2066  // add generic toggle functionality
2067  $('.toggle').next('.toggle-content').hide();
2068  $('.toggle').click(function () {
2069    $(this).toggleClass('expanded').next('.toggle-content').toggle();
2070  });
2071
2072  // subscribe email box
2073  var $subscribeEmail = $('.subscribe-email');
2074
2075  if ($subscribeEmail.length > 0) {
2076    $subscribeEmail.focus(function () {
2077      var val = $(this.val());
2078
2079      if (val.length > 0 && val !== Resources.SUBSCRIBE_EMAIL_DEFAULT) {
2080        return;
2080 // do not animate when contains non-default value
2081      }
2082
2083      $(this).animate({
2084        color: '#999999'
2085      }, 500, 'linear', function () {
2086        $(this).val('').css('color', '#333333');
2087      });
2088    }).blur(function () {
2089      var val = $.trim($(this.val()));
2090
2091      if (val.length > 0) {
2092        return; // do not animate when contains value
2093      }
2094
2095      $(this).val(Resources.SUBSCRIBE_EMAIL_DEFAULT).css('color', '#999999').animate({
2096        color: '#333333'
2097      }, 500, 'linear');
2098    });
2099  }
2100
2101  if (SitePreferences.MOTIONPOINT_ENABLED) {
2102    $('#chooseLanguage').on('click', function (e) {
2103      e.preventDefault();
2104
2105      var script = document.createElement('script');
2106
2107      //MP.SrcUrl = unescape('mp_js_orgin_url'); - commented out per MotionPoint
2108      MP.UrlLang = 'mp_js_current_lang';
2109      MP.oSite = decodeURIComponent('mp_js_origin_baseUrl');
2110      MP.tSite = decodeURIComponent('mp_js_translated_baseUrl');
2111
2112      MP.init();
2113
2114      script.src = 'https://shiseidoamericas.mpeasylink.com/mpel/mpel_chooser.js';
2115
2116      document.body.appendChild(script);
2117
2118      return false;
2119    });
2120  }
2121
2122  $('.privacy-policy').on('click', function (e) {
2123    e.preventDefault();
2124
2125    dialog.open({
2126      url: $(e.target).attr('href'),
2127      options: {
2128        height: 600
2129      }
2130    });
2131  });
2132
2133  if ($('.order-confirmation-details').length) {
2134    sessionStorage.removeItem('isGift');
2135    sessionStorage.removeItem('giftMessage');
2136  }
2137
2138  var url = Urls.passwordReset;
2139
2140  if ($('.reset-password-link').length) {
2141    if (location.protocol === 'https:') {
2142      url = Urls.securePasswordReset;
2143    }
2144
2145    $('.reset-password-link').each(function () {
2146      $(this).find('a').attr('href', url);
2147    });
2148  }
2149
2150  if ($('.user-recognized').length) {
2151    if (location.protocol === 'https:') {
2152      url = Urls.securePasswordReset;
2153    }
2154
2155    $('.user-recognized').find('a').attr('href', url);
2156  }
2157
2158  // checkout checkout minicart on right side event handling
2159  addSummaryScrollbar();
2160  //quick view
2161  producttile.initQuickViewButtons();
2162  producttile.initColorChange();
2163
2164  $(document).on('click', '.js-modal-c_close, .js-modal-c_overlay', function (e) {
2165    var skinCheckModal = $(this).parents('#skin-trouble-check-modal');
2166    if (skinCheckModal.length === 0) {
2167      return;
2168    }
2169    //クイックビュー用一時確保formを削除する。
2170    $('.quickview-form').remove();
2171  });
2172
2173  // For product set
2174  if ($('#product-set').length > 0) {
2175    setTotalPrice();
2176  }
2177}
2178
2179/**
2180 * @private
2181 * @function
2182 * @description Adds class ('js') to html for css targeting and loads js specific styles.
2183 */
2184function initializeDom() {
2185  // add class to html for css targeting
2186  $('html').addClass('js');
2187
2188  if (SitePreferences.LISTING_INFINITE_SCROLL) {
2189    $('html').addClass('infinite-scroll');
2190  }
2191
2192  // load js specific styles
2193  util.limitCharacters();
2194}
2195
2196function backToTopHandler() {
2197  $(document).on('scroll', function () {
2198    if ($(window).scrollTop() > 100) {
2199      $('.scroll-top-wrapper').addClass('show');
2200    } else {
2201      $('.scroll-top-wrapper').removeClass('show');
2202    }
2203  });
2204
2205  $('.scroll-top-wrapper').on('click', scrollToTop);
2206}
2207
2208function scrollToTop(e) {}
2209//  e.preventDefault();
2210//  var verticalOffset =
2211//    typeof verticalOffset != 'undefined' ? verticalOffset : 0;
2212//  var element = $('body');
2213//  var offset = element.offset();
2214//  var offsetTop = offset.top;
2215
2216//  $('html, body').animate(
2217//    {
2218//      scrollTop: offsetTop
2219//    },
2220//    500,
2221//    'linear'
2222//  );
2223
2224
2225// Minimize header and make it stick to the top
2226function minimizedHeaderHandler() {
2227  checkScrolledDown();
2228
2229  $(window).scroll(function () {
2230    checkScrolledDown();
2231  });
2232}
2233
2234function checkScrolledDown() {
2235  var $stickyHeader = $('#minimized-header-container');
2236  var $headerScrollOffset = $('.header-banner').outerHeight();
2237  var $wrapper = $('#wrapper');
2238
2239  if ($('body').hasClass('is-reveal-open')) {
2240    return false;
2241  }
2242
2243  if ($(window).scrollTop() > $headerScrollOffset) {
2244    $stickyHeader.addClass('sticky-header');
2245    $wrapper.css('padding-top', $stickyHeader.outerHeight());
2246  } else {
2247    $stickyHeader.removeClass('sticky-header');
2248    $wrapper.css('padding-top', 0);
2249  }
2250}
2251
2252function responsiveMegaMenu() {
2253  var $dropdowns = $('.level-1 li.has-sub-menu');
2254
2255  $dropdowns.on('keydown', function (e) {
2256    var $this = $(this);
2257
2258    if (e.keyCode === 13) {
2259      if (!$this.hasClass('hover')) {
2260        e.preventDefault();
2261
2262        $dropdowns.removeClass('hover');
2263        $this.addClass('hover');
2264      }
2265    }
2266
2267    if (e.keyCode === 32) {
2268      e.preventDefault();
2269      $dropdowns.removeClass('hover');
2270    }
2271  });
2272
2273  $dropdowns.hover(function () {
2274    var $this = $(this);
2275    if ($this.prop('hoverTimeout')) {
2276      $this.prop('hoverTimeout', clearTimeout($this.prop('hoverTimeout')));
2277    }
2278    $this.prop('hoverIntent', setTimeout(function () {
2279      $this.addClass('hover');
2280    }, 200));
2281  }, function () {
2282    var $this = $(this);
2283    if ($this.prop('hoverIntent')) {
2284      $this.prop('hoverIntent', clearTimeout($this.prop('hoverIntent')));
2285    }
2286    $this.prop('hoverTimeout', setTimeout(function () {
2287      $this.removeClass('hover');
2288    }, 200));
2289  });
2290
2291  if ('ontouchstart' in document.documentElement && window.innerWidth >= 640) {
2292    $dropdowns.each(function () {
2293      var $this = $(this);
2294
2295      this.addEventListener('touchstart', function (e) {
2296        if (e.touches.length === 1) {
2297          e.stopPropagation();
2298
2299          if (!$this.hasClass('hover')) {
2300            if (e.target === this || e.target.parentNode === this) {
2301              e.preventDefault();
2302            }
2303
2304            $dropdowns.removeClass('hover');
2305            $this.addClass('hover');
2306
2307            document.addEventListener('touchstart', function closeDropdown(e) {
2308              e.stopPropagation();
2309
2310              $this.removeClass('hover');
2311              document.removeEventListener('touchstart', closeDropdown);
2312            });
2313          }
2314        }
2315      }, false);
2316    });
2317  }
2318
2319  $('a.no-link, span.category-header').on('click', function (e) {
2320    if (window.innerWidth < 640) {
2321      $(this).next($('.menu-item-toggle')).trigger('click');
2322    } else {
2323      e.preventDefault();
2324    }
2325  });
2326
2327  var ogMenuHeight = $('ul.level-1').height();
2328  // main menu toggle
2329  $('.menu-toggle').on('click', function () {
2330    $('#wrapper').toggleClass('menu-active');
2331    ogMenuHeight = $('ul.level-1').height();
2332  });
2333
2334  $('.main-nav li .menu-item-toggle').on('click', function (e) {
2335    e.preventDefault();
2336
2337    var $parentLi = $(e.target).closest('li');
2338    var menuHeight = $parentLi.find('.sub-level-wrapper').height();
2339
2340    if (ogMenuHeight <= menuHeight) {
2341      $('ul.level-1').css('height', menuHeight);
2342    }
2343
2344    $parentLi.siblings('li').removeClass('active').find('.menu-item-toggle');
2345    $parentLi.toggleClass('active');
2346
2347    $(e.target).toggleClass('active');
2348  });
2349
2350  $('.mobile-menu-back').on('click', function () {
2351    var $closestActiveMenu = $(this).closest('.active');
2352    var prevMenuHeight = $closestActiveMenu.parent().parent().height();
2353
2354    $closestActiveMenu.removeClass('active');
2355
2356    if (ogMenuHeight <= prevMenuHeight) {
2357      $('ul.level-1').css('height', prevMenuHeight);
2358    }
2359  });
2360
2361  $('.user-account').on('click', function (e) {
2362    e.preventDefault();
2363
2364    $(this).parent('.user-info').toggleClass('active');
2365  });
2366}
2367
2368function searchMenuEvent() {
2369  // Search for mobile view
2370  $('.quick-access-menu [title="Search"]').on('click', function (e) {
2371    e.preventDefault();
2372
2373    $('.header-search').slideToggle(200);
2374  });
2375
2376  // show the search button when the user switches to desktop view
2377  $(window).on('resize', function (e) {
2378    if (window.innerWidth > 639) {
2379      $('.header-search').show();
2380    }
2381  });
2382}
2383
2384//add class for scrollbar on miniline summary
2385function addSummaryScrollbar() {
2386  var itemCount = $('.pt_checkout .checkout-mini-cart .accordion-content .mini-cart-product').length;
2387
2388  if (itemCount > 4) {
2389    $('.checkout-mini-cart .accordion-content').addClass('scroll-items');
2390  }
2391}
2392
2393function playVideoHandler() {
2394  var MAIN_VIDEO_SELECTOR = '.main-video';
2395  var CAROUSEL_VIDEO_SELECTOR = '.modal-video';
2396  $(document)
2397  // main video (inline)
2398  .on('click', MAIN_VIDEO_SELECTOR, function () {
2399    var $this = $(this);
2400
2401    var $inlineEle = $this.parent('div'),
2402        videoId = $this.data('video-id');
2403
2404    video.playInline($inlineEle, videoId);
2405  })
2406
2407  // carousel videos (launched in modal)
2408  .on('click', CAROUSEL_VIDEO_SELECTOR, function () {
2409    var videoId = $(this).data('video-id');
2410
2411    video.playInModal(videoId);
2412  });
2413}
2414
2415function resetFooterError() {
2416  $('.store-locator-form input[type="text"]').val('');
2417
2418  if ($('.store-locator-form .field-button-container div').hasClass('error')) {
2419    $('.store-locator-form .field-button-container div').removeClass('error');
2420    $('.store-locator-form .field-button-container .error-message').remove();
2421  }
2422}
2423
2424/**
2425 * Dropdown event for quantity change
2426 * @returns
2427 */
2428function dropDownEvents() {
2429  $(document).on('click', '.js-num-drop_up', function (e) {
2430    e.preventDefault();
2431    var $box = $(this).closest('.js-num-drop_container');
2432    var limit = $box.find('.js-num-drop_select').children().length;
2433    var currentNum = $box.find('.js-num-drop_cnt').html();
2434
2435    if (currentNum < limit - 1) {
2436      currentNum++;
2437      $box.find('.js-num-drop_cnt').html(currentNum);
2438      $box.find('.js-num-drop_select').children().find('a').removeClass('is-current');
2439      if ($(this).closest('#product-set').length > 0) {
2440        $box.find('.js-num-drop_select').children().eq(currentNum).find('a').addClass('is-current');
2441      } else {
2442        $box.find('.js-num-drop_select').children().eq(currentNum - 1).find('a').addClass('is-current');
2443      }
2444      $box.find('.js-num-drop_input').val(currentNum);
2445    }
2446
2447    if ($(this).parents('.cpb-products_list_box').length > 0) {
2448      $(this).trigger('dropUpMinicart');
2449    } else if ($(this).parents('.cpb-cart-bag_box').length > 0) {
2450      $(this).trigger('dropUpCart');
2451    } else if ($(this).parents('.cpb-products-conut').length > 0) {
2452      $(this).trigger('dropUpProduct');
2453    }
2454
2455    // For product set
2456    if ($('#product-set').length > 0) {
2457      updateAddToCartButton();
2458      setTotalPrice();
2459    }
2460  });
2461  $(document).on('click', '.js-num-drop_down', function (e) {
2462    e.preventDefault();
2463    var $box = $(this).closest('.js-num-drop_container');
2464    var limit = $box.find('.js-num-drop_select').children().length;
2465    var currentNum = $box.find('.js-num-drop_cnt').html();
2466    var isMiniCart = function (element) {
2467      if ($(element).closest('.cpb-modal_minicart').length > 0) {
2468        return true;
2469      } else {
2470        return false;
2471      }
2472    }(this);
2473    // ミニカートはカウントが0にならないようにする
2474    var minNum = isMiniCart ? 1 : 0;
2475    if (currentNum > minNum) {
2476      currentNum--;
2477      $box.find('.js-num-drop_cnt').html(currentNum);
2478      $box.find('.js-num-drop_select').children().find('a').removeClass('is-current');
2479      if ($(this).closest('#product-set').length > 0) {
2480        $box.find('.js-num-drop_select').children().eq(currentNum).find('a').addClass('is-current');
2481      } else {
2482        $box.find('.js-num-drop_select').children().eq(currentNum - 1).find('a').addClass('is-current');
2483      }
2484      $box.find('.js-num-drop_input').val(currentNum);
2485    }
2486
2487    if ($(this).parents('.cpb-products_list_box').length > 0) {
2488      $(this).trigger('dropDownMinicart');
2489    } else if ($(this).parents('.cpb-cart-bag_box').length > 0) {
2490      $(this).trigger('dropDownCart');
2491    } else if ($(this).parents('.cpb-products-conut').length > 0) {
2492      $(this).trigger('dropDownProduct');
2493    }
2494
2495    // For product set
2496    if ($('#product-set').length > 0) {
2497      // all check product count
2498      var products = $('.cpb-products-conut .js-num-drop_input');
2499      var count = 0;
2500      for (var i = 0; i < products.length; i++) {
2501        if ($(products).eq(i).val() == 0) count++;
2502      }
2503      if (count == products.length) {
2504        $('#add-all-to-cart').prop('disabled', 'disabled');
2505      }
2506      updateAddToCartButton();
2507      setTotalPrice();
2508    }
2509  });
2510  $(document).on('click', '.js-num-drop_select a', function (e) {
2511    e.preventDefault();
2512    var $box = $(this).closest('.js-num-drop_container');
2513    var num = $(this).html();
2514    $box.find('.js-num-drop_cnt').html(num);
2515    $box.find('.js-num-drop_select').children().find('a').removeClass('is-current');
2516    if ($(this).closest('#product-set').length > 0) {
2517      $box.find('.js-num-drop_select').children().eq(num).find('a').addClass('is-current');
2518    } else {
2519      $box.find('.js-num-drop_select').children().eq(num - 1).find('a').addClass('is-current');
2520    }
2521    $box.find('.js-num-drop_input').val(num);
2522    $box.find('.js-num-drop_select').removeClass('is-active');
2523
2524    if ($(this).parents('.cpb-products_list_box').length > 0) {
2525      $(this).trigger('dropSelectMinicart');
2526    } else if ($(this).parents('.cpb-cart-bag_box').length > 0) {
2527      $(this).trigger('dropSelectCart');
2528    } else if ($(this).parents('.cpb-products-conut').length > 0) {
2529      $(this).trigger('dropSelectProduct');
2530    }
2531
2532    // For product set
2533    if ($('#product-set').length > 0) {
2534      // all check product count
2535      var products = $('.cpb-products-conut .js-num-drop_input');
2536      var count = 0;
2537      for (var i = 0; i < products.length; i++) {
2538        if ($(products).eq(i).val() == 0) count++;
2539      }
2540      if (count == products.length) {
2541        $('#add-all-to-cart').prop('disabled', 'disabled');
2542      } else {
2543        $('#add-all-to-cart').prop('disabled', '');
2544      }
2545      updateAddToCartButton();
2546      setTotalPrice();
2547    }
2548  });
2549  $(document).on('click', '.js-num-drop_drop', function (e) {
2550    e.preventDefault();
2551    var $box = $(this).closest('.js-num-drop_container');
2552    var eventName = '.event' + new Date().getTime();
2553
2554    if ($box.find('.js-num-drop_select').hasClass('is-active')) {
2555      $box.find('.js-num-drop_select').removeClass('is-active');
2556      $(document).off(eventName);
2557    } else {
2558      var offset = $(this).offset();
2559      var posY = offset.top - $(window).scrollTop();
2560      var height = $(window).height();
2561      if (posY * 2 > height) {
2562        $box.find('.js-num-drop_select').addClass('is-up');
2563      } else {
2564        $box.find('.js-num-drop_select').removeClass('is-up');
2565      }
2566
2567      $box.find('.js-num-drop_select').addClass('is-active');
2568
2569      $(document).on('click' + eventName + ' touchend' + eventName, function (e) {
2570        if (!$.contains($box[0], e.target)) {
2571          $box.find('.js-num-drop_select').removeClass('is-active');
2572          $(document).off(eventName);
2573        }
2574      });
2575    }
2576
2577    if ($(this).parents('.cpb-products_list_box').length > 0) {
2578      $(this).trigger('dropDropMinicart');
2579    } else if ($(this).parents('.cpb-cart-bag_box').length > 0) {
2580      $(this).trigger('dropDropCart');
2581    } else if ($(this).parents('.cpb-products-conut').length > 0) {
2582      $(this).trigger('dropDropProduct');
2583    }
2584  });
2585}
2586
2587function setTotalPrice() {
2588  $('.cpb-products-variety_area').siblings('.cpb-products-conut').find('.item-price span').text(productSetCalcPrice().toString().replace(/(\d)(?=(\d{3})+$)/g, '$1,'));
2589}
2590
2591function productSetCalcPrice() {
2592  return $('.cpb-products-variety_area .cpb-products-variety_box').toArray().reduce(function (totalPrice, currentValue) {
2593    var count = Number($(currentValue).find('.cpb-products-conut .js-num-drop_input').val()) || 0;
2594    var price = Number($(currentValue).find('.item-price .num').data().value) || 0;
2595    return totalPrice + count * price;
2596  }, 0);
2597}
2598
2599function updateAddToCartButton() {
2600  var elementList = $('.cpb-products-variety_area .cpb-products-variety_box').toArray();
2601  // 一つでも在庫切れ、オフライン、店舗限定の
2601商品が有った場合、true
2602  var checkProduct = function checkProduct() {
2603    return elementList.some(function (element) {
2604      return 'none' === $(element).find('.cmd-num_set').css('display');
2605    });
2606  };
2607  // すべての商品の購入個数が「0」の場合、true
2608  var checkNum = function checkNum() {
2609    return elementList.every(function (element) {
2610      return 0 < $(element).find('.cpb-products-conut .js-num-drop_input').length && 0 === Number($(element).find('.cpb-products-conut .js-num-drop_input').val());
2611    });
2612  };
2613  if (checkProduct() || checkNum()) {
2614    $('#add-all-to-cart').prop('disabled', 'disabled');
2615  } else {
2616    $('#add-all-to-cart').prop('disabled', '');
2617  }
2618}
2619
2620var pages = {
2621  account: require('./pages/account'),
2622  cart: require('./pages/cart'),
2623  checkout: require('./pages/checkout'),
2624  compare: require('./pages/compare'),
2625  product: require('./pages/product'),
2626  registry: require('./pages/registry'),
2627  orderconfirmation: require('./pages/order-confirm'),
2628  search: require('./pages/search'),
2629  tutorial: require('./pages/tutorial'),
2630  storefront: require('./pages/storefront'),
2631  wishlist: require('./pages/wishlist'),
2632  storelocator: require('./pages/storelocator'),
2633  checkorder: require('./pages/checkorder'),
2634  content: require('./pages/content'),
2635  promotionlanding: require('./pages/promotionlanding'),
2636  stocknotification: require('./pages/stocknotification')
2637};
2638
2639var app = {
2640  init: function init() {
2641    $(document).foundation();
2642
2643    // 「ajax」通信はパラメータに「isSkipOnHistory」を設定
2644    $.ajaxPrefilter(function (options) {
2645      var URI = require('urijs');
2646      var url = new URI(options.url);
2647      url.addQuery('isSkipOnHistory', true);
2648      options.url = url.toString();
2649    });
2650
2651    if (document.cookie.length === 0) {
2652      $('<div/>').addClass('browser-compatibility-alert').append($('<p/>').addClass('browser-error').html(Resources.COOKIES_DISABLED)).appendTo('#browser-check');
2653    }
2654
2655    initializeDom();
2656    // init events for design
2657    design.init();
2658    initializeEvents();
2659    //backToTopHandler();
2660    // minimizedHeaderHandler();
2661    //resetFooterError();
2662    //responsiveMegaMenu();
2663    //searchMenuEvent();
2664
2665    // init specific global components
2666    analytics.init();
2667    countries.init();
2668    tooltip.init();
2669    //minicart.init();
2670    validator.init();
2671    orderreplenishment.init();
2672    rating.init();
2673    slick.init();
2674    searchplaceholder.init();
2675    //headerMenu.init();
2676    video.init();
2677    //checkoutLogin.init();
2678    footerSelector.countrySelector();
2679    newsletter.newsletterHeader();
2680    newsletter.isNewsletterEnabled();
2681    inputEntry.entry();
2682    playVideoHandler();
2683    login.init();
2684    quickview.init();
2685    dropDownEvents();
2686    loading.init();
2687    dd.init();
2688    // execute page specific initializations
2689    $.extend(page, window.pageContext);
2690
2691    var ns = page.ns;
2692
2693    if (ns && pages[ns] && pages[ns].init) {
2694      pages[ns].init();
2695    }
2696
2697    // Check TLS status if indicated by site preference
2698    if (SitePreferences.CHECK_TLS === true) {
2699      tls.getUserAgent();
2700    }
2701  }
2702};
2703
2704//general extension functions
2705(function () {
2706  String.format = function () {
2707    var s = arguments[0];
2708    var i,
2709        len = arguments.length - 1;
2710
2711    for (i = 0; i < len; i++) {
2712      var reg = new RegExp('\\{' + i + '\\}', 'gm');
2713
2714      s = s.replace(reg, arguments[i + 1]);
2715    }
2716
2717    return s;
2718  };
2719})();
2720
2721// initialize app
2722$(document).ready(function () {
2723  app.init();
2724  // fixed button cart
2725  $('.cpb-cart-checkout_fixed .cpb-cart_submit .button').off('click.checkout_fixed').on('click.checkout_fixed', function (e) {
2726    e.preventDefault();
2727    $('.cpb-cart-side_submit .button').trigger('click');
2728  });
2729});
2730
2731// expose global app obj for 3rd party integrations
2732window.app = {
2733  quickView: quickview,
2734  minicart: minicart,
2735  user: window.User,
2736  SCemailUrl: window.Urls.SCemailUrl,
2737  Product: {},
2738  tagmanager: analytics.tagmanager,
2739  gtmInternalPromotion: analytics.gtmInternalPromotion
2740};
2741
2742// expose global saveURL to support legacy Composed integration
2743window.saveURL = window.Urls.saveConsultationURL;
2744// summary scroll bar global scope
2745window.addSummaryScrollbar = addSummaryScrollbar;
2746window.scrollToTop = scrollToTop;
2747
2748},{"./ajax":1,"./analytics":2,"./cookieprivacy":6,"./countries":7,"./dd":10,"./design":11,"./dialog":12,"./footer-selector":13,"./hanatsubaki_club_member_id_edit":17,"./header-menu":18,"./in
2748put-entry":19,"./jquery-ext":20,"./loading":21,"./login":22,"./minicart":23,"./new-design":25,"./newsletter":26,"./order-replenishment":27,"./page":28,"./pages/account":29,"./pages/cart":30,"./pages/checkorder":31,"./pages/checkout":37,"./pages/compare":41,"./pages/content":42,"./pages/order-confirm":43,"./pages/product":48,"./pages/promotionlanding":55,"./pages/registry":56,"./pages/search":57,"./pages/stocknotification":58,"./pages/storefront":59,"./pages/storelocator":60,"./pages/tutorial":61,"./pages/wishlist":62,"./product-tile":63,"./quickview":66,"./rating":67,"./searchplaceholder":70,"./slick":71,"./tls":75,"./tooltip":76,"./util":77,"./validator":78,"./video":79,"urijs":145}],4:[function(require,module,exports){
2749'use strict';
2750
2751var dialog = require('./dialog'),
2752    page = require('./page'),
2753    util = require('./util'),
2754    modal = require('./modal').global;
2755
2756var selectedList = [];
2757var maxItems = 1;
2758var bliUUID = '';
2759
2760/**
2761 * @private
2762 * @function
2763 * description Gets a list of bonus products related to a promoted product
2764 */
2765function getBonusProducts() {
2766  var bonusproducts = [];
2767
2768  var i, len;
2769  for (i = 0, len = selectedList.length; i < len; i++) {
2770    var p = {
2771      pid: selectedList[i].pid,
2772      qty: selectedList[i].qty,
2773      options: {}
2774    };
2775    var a,
2776        alen,
2777        bp = selectedList[i];
2778    if (bp.options) {
2779      for (a = 0, alen = bp.options.length; a < alen; a++) {
2780        var opt = bp.options[a];
2781        p.options = { optionName: opt.name, optionValue: opt.value };
2782      }
2783    }
2784    bonusproducts.push({ product: p });
2785  }
2786  return { bonusproducts: bonusproducts };
2787}
2788
2789var selectedItemTemplate = function selectedItemTemplate(data) {
2790  var attributes = '';
2791  for (var attrID in data.attributes) {
2792    var attr = data.attributes[attrID];
2793    attributes += '<li data-attribute-id="' + attrID + '">\n';
2794    attributes += '<span class="display-name">' + attr.displayName + '</span>: ';
2795    attributes += '<span class="display-value">' + attr.displayValue + '</span>\n';
2796    attributes += '</li>';
2797  }
2798  attributes += '<li class="item-qty">\n';
2799  attributes += '<span class="display-name">Qty</span>: ';
2800  attributes += '<span class="display-value">' + data.qty + '</span>';
2801  return ['<li class="selected-bonus-item" data-uuid="' + data.uuid + '" data-pid="' + data.pid + '">', '<i class="remove-link fa fa-remove" title="Remove this product" href="#"></i>', '<div class="item-name">' + data.name + '</div>', '<ul class="item-attributes">', attributes, '<ul>', '<li>'].join('\n');
2802};
2803
2804// hide swatches that are not selected or not part of a Product Variation Group
2805var hideSwatches = function hideSwatches() {
2806  $('.bonus-product-item:not([data-producttype="master"]) .swatches li').not('.selected').not('.variation-group-value').hide();
2807  // prevent unselecting the selected variant
2808  $('.bonus-product-item .swatches .selected').on('click', function () {
2809    return false;
2810  });
2811};
2812
2813/**
2814 * @private
2815 * @function
2816 * @description Updates the summary page with the selected bonus product
2817 */
2818function updateSummary() {
2819  var $bonusProductList = $('#bonus-product-list');
2820  if (!selectedList.length) {
2821    $bonusProductList.find('li.selected-bonus-item').remove();
2822  } else {
2823    var ulList = $bonusProductList.find('ul.selected-bonus-items').first();
2824    var i, len;
2825    for (i = 0, len = selectedList.length; i < len; i++) {
2826      var item = selectedList[i];
2827      var li = selectedItemTemplate(item);
2828      $(li).appendTo(ulList);
2829    }
2830  }
2831
2832  // get remaining item count
2833  var remain = maxItems - selectedList.length;
2834  $bonusProductList.find('.bonus-items-available').text(remain);
2835  if (remain <= 0) {
2836    $bonusProductList.find('.select-bonus-item').attr('disabled', 'disabled');
2837  } else {
2838    $bonusProductList.find('.select-bonus-item').removeAttr('disabled');
2839  }
2840}
2841
2842function initializeGrid() {
2843  var $bonusProduct = $('#bonus-product-dialog'),
2844      $bonusProductList = $('#bonus-product-list'),
2845      bliData = $bonusProductList.data('line-item-detail');
2846  maxItems = bliData.maxItems;
2847  bliUUID = bliData.uuid;
2848
2849  if (bliData.itemCount >= maxItems) {
2850    $bonusProductList.find('.select-bonus-item').attr('disabled', 'disabled');
2851  }
2852
2853  var cartItems = $bonusProductList.find('.selected-bonus-item');
2854  cartItems.each(function () {
2855    var ci = $(this);
2856    var product = {
2857      uuid: ci.data('uuid'),
2858      pid: ci.data('pid'),
2859      qty: ci.find('.item-qty').text(),
2860      name: ci.find('.item-name').html(),
2861      attributes: {}
2862    };
2863    var attributes = ci.find('ul.item-attributes li');
2864    attributes.each(function () {
2865      var li = $(this);
2866      product.attributes[li.data('attributeId')] = {
2867        displayName: li.children('.display-name').html(),
2868        displayValue: li.children('.display-value').html()
2869      };
2870    });
2871    selectedList.push(product);
2872  });
2873
2874  $bonusProductList.on('click', '.bonus-product-item a[href].swatchanchor', function (e) {
2875    e.preventDefault();
2876    var url = this.href,
2877        $this = $(this);
2878    url = util.appendParamsToUrl(url, {
2879      source: 'bonus',
2880      format: 'ajax'
2881    });
2882    $.ajax({
2883      url: url,
2884      success: function success(response) {
2885        $this.closest('.bonus-product-item').empty().html(response);
2886        hideSwatches();
2887      }
2888    });
2889  }).on('change', '.input-text', function () {
2890    $bonusProductList.find('.select-bonus-item').removeAttr('disabled');
2891    $(this).closest('.bonus-product-form').find('.quantity-error').text('');
2892  }).on('click', '.select-bonus-item', function (e) {
2893    e.preventDefault();
2894    if (selectedList.length >= maxItems) {
2895      $bonusProductList.find('.select-bonus-item').attr('disabled', 'disabled');
2896      $bonusProductList.find('.bonus-items-available').text('0');
2897      return;
2898    }
2899
2900    var form = $(this).closest('.bonus-product-form'),
2901        detail = $(this).closest('.product-detail'),
2902        uuid = form.find('input[name="productUUID"]').val(),
2903        qtyVal = form.find('input[name="Quantity"]').val(),
2904        qty = isNaN(qtyVal) ? 1 : +qtyVal;
2905
2906    if (qty > maxItems) {
2907      $bonusProductList.find('.select-bonus-item').attr('disabled', 'disabled');
2908      form.find('.quantity-error').text(Resources.BONUS_PRODUCT_TOOMANY);
2909      return;
2910    }
2911
2912    var product = {
2913      uuid: uuid,
2914      pid: form.find('input[name="pid"]').val(),
2915      qty: qty,
2916      name: detail.find('.product-name').text(),
2917      attributes: detail.find('.product-variations').data('attributes'),
2918      options: []
2919    };
2920
2921    var optionSelects = form.find('.product-option');
2922
2923    optionSelects.each(function () {
2924      product.options.push({
2925        name: this.name,
2926        value: $(this).val(),
2927        display: $(this).children(':selected').first().html()
2928      });
2929    });
2930    selectedList.push(product);
2931    updateSummary();
2932  }).on('click', '.remove-link', function (e) {
2933    e.preventDefault();
2934    var container = $(this).closest('.selected-bonus-item');
2935    if (!container.data('uuid')) {
2936      return;
2937    }
2938
2939    var uuid = container.data('uuid');
2940    var i,
2941        len = selectedList.length;
2942    for (i = 0; i < len; i++) {
2943      if (selectedList[i].uuid === uuid) {
2944        selectedList.splice(i, 1);
2945        break;
2946      }
2947    }
2948    updateSummary();
2949  }).on('click', '.add-to-cart-bonus', function (e) {
2950    e.preventDefault();
2951    var url = util.appendParamsToUrl(Urls.addBonusProduct, {
2952      bonusDiscountLineItemUUID: bliUUID
2953    });
2954    var bonusProducts = getBonusProducts();
2955    if (bonusProducts.bonusproducts[0].product.qty > maxItems) {
2956      bonusProducts.bonusproducts[0].product.qty = maxItems;
2957    }
2958    // make the server call
2959    $.ajax({
2960      type: 'POST',
2961      dataType: 'json',
2962      cache: false,
2963      contentType: 'application/json',
2964      url: url,
2965      data: JSON.stringify(bonusProducts)
2966    }).done(function () {
2967      // success
2968      page.refresh();
2969    }).fail(function (xhr, textStatus) {
2970      // failed
2971      if (textStatus === 'parsererror') {
2972        window.alert(Resources.BAD_RESPONSE);
2973      } else {
2974        window.alert(Resources.SERVER_CONNECTION_ERROR);
2975      }
2976    }).always(function () {
2977      $bonusProduct.dialog('close');
2978    });
2979  }).on('click', '#more-bonus-products', function (e) {
2980    e.preventDefault();
2981    var uuid = $('#bonus-product-list').data().lineItemDetail.uuid;
2982
2983    //get the next page of choice of bonus products
2984    var lineItemDetail = JSON.parse($('#bonus-product-list').attr('data-line-item-detail'));
2985    lineItemDetail.pageStart = lineItemDetail.pageStart + lineItemDetail.pageSize;
2986    $('#bonus-product-list').attr('data-line-item-detail', JSON.stringify(lineItemDetail));
2987
2988    var url = util.appendParamsToUrl(Urls.getBonusProducts, {
2989      bonusDiscountLineItemUUID: uuid,
2990      format: 'ajax',
2991      lazyLoad: 'true',
2992      pageStart: lineItemDetail.pageStart,
2993      pageSize: $('#bonus-product-list').data().lineItemDetail.pageSize,
2994      bonusProductsTotal: $('#bonus-product-list').data().lineItemDetail.bpTotal
2995    });
2996
2997    $.ajax({
2998      type: 'GET',
2999      cache: false,
3000      contentType: 'application/json',
3001      url: url
3002    }).done(function (data) {
3003      //add the new page to DOM and remove 'More' link if it is the last page of results
3004      $('#more-bonus-products').before(data);
3005      if (lineItemDetail.pageStart + lineItemDetail.pageSize >= $('#bonus-product-list').data().lineItemDetail.bpTotal) {
3006        $('#more-bonus-products').remove();
3007      }
3008    }).fail(function (xhr, textStatus) {
3009      if (textStatus === 'parsererror') {
3010        window.alert(Resources.BAD_RESPONSE);
3011      } else {
3012        window.alert(Resources.SERVER_CONNECTION_ERROR);
3013      }
3014    });
3015  });
3016}
3017
3018var bonusProductsView = {
3019  /**
3020   * @function
3021   * @description Open the list of bonus products selection dialog
3022   */
3023  show: function show(url) {
3024    var $bonusProduct = $('#bonus-product-dialog');
3025    // create the dialog
3026    dialog.open({
3027      target: $bonusProduct,
3028      url: url,
3029      options: {
3030        width: 795,
3031        title: Resources.BONUS_PRODUCTS
3032      },
3033      callback: function callback() {
3034        initializeGrid();
3035        hideSwatches();
3036      }
3037    });
3038  },
3039  /**
3040   * @function
3041   * @description Open bonus product promo prompt dialog
3042   */
3043  loadBonusOption: function loadBonusOption() {
3044    var self = this,
3045        bonusDiscountContainer = document.querySelector('.bonus-discount-container');
3046    if (!bonusDiscountContainer) {
3047      return;
3048    }
3049
3050    // get the html from minicart, then trash it
3051    var bonusDiscountContainerHtml = bonusDiscountContainer.outerHTML;
3052    bonusDiscountContainer.parentNode.removeChild(bonusDiscountContainer);
3053
3054    dialog.open({
3055      html: bonusDiscountContainerHtml,
3056      options: {
3057        width: 'auto',
3058        title: Resources.BONUS_PRODUCT,
3059        dialogClass: 'bonus-eligibility-modal',
3060        buttons: [{
3061          text: Resources.SELECT_BONUS_PRODUCTS,
3062          click: function click() {
3063            var uuid = $('.bonus-product-promo').data('lineitemid'),
3064                url = util.appendParamsToUrl(Urls.showBonusProducts, {
3065              bonusDiscountLineItemUUID: uuid,
3066              source: 'bonus',
3067              format: 'ajax',
3068              lazyLoad: 'false',
3069              pageStart: 0,
3070              pageSize: 0,
3071              bonusProductsTotal: -1
3072            });
3073            $(this).dialog('close');
3074            //self.show(url);
3075            modal.addCustomClass('bonus-item-modal');
3076            modal.renderByUrl(url);
3077          }
3078        }, {
3079          text: Resources.NO_THANKS,
3080          click: function click() {
3081            $(this).dialog('close');
3082          }
3083        }]
3084      },
3085      callback: function callback() {
3086        // show hide promo details
3087        $('.show-promo-details').on('click', function () {
3088          $('.promo-details').toggleClass('visible');
3089        });
3090      }
3091    });
3092  },
3093
3094  hasBonusOptions: function hasBonusOptions() {
3095    return $('.bonus-discount-container').length > 0;
3096  }
3097};
3098
3099module.exports = bonusProductsView;
3100
3101},{"./dialog":12,"./modal":24,"./page":28,"./util":77}],5:[function(require,module,exports){
3102'use strict';
3103
3104var page = require('./page'),
3105    util = require('./util'),
3106    TPromise = require('promise');
3107
3108var _currentCategory = '',
3109    MAX_ACTIVE = 6;
3110
3111/**
3112 * @private
3113 * @function
3114 * @description Verifies the number of elements in the compare container and updates it with sequential classes for ui targeting
3115 */
3116function refreshContainer() {
3117  var $compareContainer = $('.compare-items');
3118  var $compareItems = $compareContainer.find('.compare-item');
3119  var numActive = $compareItems.filter('.active').length;
3120
3121  if (numActive < 2) {
3122    $('#compare-items-button').attr('disabled', 'disabled');
3123  } else {
3124    $('#compare-items-button').removeAttr('disabled');
3125  }
3126
3127  $compareContainer.toggle(numActive > 0);
3128}
3129/**
3130 * @private
3131 * @function
3132 * @description Adds an item to the compare container and refreshes it
3133 */
3134function addToList(data) {
3135  // get the first compare-item not currently active
3136  var $item = $('.compare-items .compare-item').not('.active').first(),
3137      $productTile = $('#' + data.uuid);
3138
3139  if ($item.length === 0) {
3140    if ($productTile.length > 0) {
3141      $productTile.find('.compare-check')[0].checked = false;
3142    }
3143    window.alert(Resources.COMPARE_ADD_FAIL);
3144    return;
3145  }
3146
3147  // if already added somehow, return
3148  if ($('[data-uuid="' + data.uuid + '"]').length > 0) {
3149    return;
3150  }
3151  // set as active item
3152  $item.addClass('active').attr('data-uuid', data.uuid).attr('data-itemid', data.itemid).data('uuid', data.uuid).data('itemid', data.itemid).append($(data.img).clone().addClass('compare-item-image'));
3153}
3154/**
3155 * @private
3156 * @function
3157 * description Removes an item from the compare container and refreshes it
3158 */
3159function removeFromList($item) {
3160  if ($item.length === 0) {
3161    return;
3162  }
3163  // remove class, data and id from item
3164  $item.removeClass('active').removeAttr('data-uuid').removeAttr('data-itemid').data('uuid', '').data('itemid', '')
3165  // remove the image
3166  .find('.compare-item-image').remove();
3167}
3168
3169function addProductAjax(args) {
3170  var promise = new TPromise(function (resolve, reject) {
3171    $.ajax({
3172      url: Urls.compareAdd,
3173      data: {
3174        pid: args.itemid,
3175        category: _currentCategory
3176      },
3177      dataType: 'json'
3178    }).done(function (response) {
3179      if (!response || !response.success) {
3180        reject(new Error(Resources.COMPARE_ADD_FAIL));
3181      } else {
3182        resolve(response);
3183      }
3184    }).fail(function (jqxhr, status, err) {
3185      reject(new Error(err));
3186    });
3187  });
3188  return promise;
3189}
3190
3191function removeProductAjax(args) {
3192  var promise = new TPromise(function (resolve, reject) {
3193    $.ajax({
3194      url: Urls.compareRemove,
3195      data: {
3196        pid: args.itemid,
3197        category: _currentCategory
3198      },
3199      dataType: 'json'
3200    }).done(function (response) {
3201      if (!response || !response.success) {
3202        reject(new Error(Resources.COMPARE_REMOVE_FAIL));
3203      } else {
3204        resolve(response);
3205      }
3206    }).fail(function (jqxhr, status, err) {
3207      reject(new Error(err));
3208    });
3209  });
3210  return promise;
3211}
3212
3213function shiftImages() {
3214  return new TPromise(function (resolve) {
3215    var $items = $('.compare-items .compare-item');
3216    $items.each(function (i, item) {
3217      var $item = $(item);
3218      // last item
3219      if (i === $items.length - 1) {
3220        return removeFromList($item);
3221      }
3222      var $next = $items.eq(i + 1);
3223      if ($next.hasClass('active')) {
3224        // remove its own image
3225        $next.find('.compare-item-image').detach().appendTo($item);
3226        $item.addClass('active').attr('data-uuid', $next.data('uuid')).attr('data-itemid', $next.data('itemid')).data('uuid', $next.data('uuid')).data('itemid', $next.data('itemid'));
3227      }
3228    });
3229    resolve();
3230  });
3231}
3232
3233/**
3234 * @function
3235 * @description Adds product to the compare table
3236 */
3237function addProduct(args) {
3238  var promise;
3239  var $items = $('.compare-items .compare-item');
3240  var $cb = $(args.cb);
3241  var numActive = $items.filter('.active').length;
3242  if (numActive === MAX_ACTIVE) {
3243    if (!window.confirm(Resources.COMPARE_CONFIRMATION)) {
3244      $cb[0].checked = false;
3245      return;
3246    }
3247
3248    // remove product using id
3249    var $firstItem = $items.first();
3250    promise = removeItem($firstItem).then(function () {
3251      return shiftImages();
3252    });
3253  } else {
3254    promise = TPromise.resolve(0);
3255  }
3256  return promise.then(function () {
3257    return addProductAjax(args).then(function () {
3258      addToList(args);
3259      if ($cb && $cb.length > 0) {
3260        $cb[0].checked = true;
3261      }
3262      refreshContainer();
3263    });
3264  }).then(null, function () {
3265    if ($cb && $cb.length > 0) {
3266      $cb[0].checked = false;
3267    }
3268  });
3269}
3270
3271/**
3272 * @function
3273 * @description Removes product from the compare table
3274 * @param {object} args - the arguments object should have the following properties: itemid, uuid and cb (checkbox)
3275 */
3276function removeProduct(args) {
3277  var $cb = args.cb ? $(args.cb) : null;
3278  return removeProductAjax(args).then(function () {
3279    var $item = $('[data-uuid="' + args.uuid + '"]');
3280    removeFromList($item);
3281    if ($cb && $cb.length > 0) {
3282      $cb[0].checked = false;
3283    }
3284    refreshContainer();
3285  }, function () {
3286    if ($cb && $cb.length > 0) {
3287      $cb[0].checked = true;
3288    }
3289  });
3290}
3291
3292function removeItem($item) {
3293  var uuid = $item.data('uuid'),
3294      $productTile = $('#' + uuid);
3295  return removeProduct({
3296    itemid: $item.data('itemid'),
3297    uuid: uuid,
3298    cb: $productTile.length === 0 ? null : $productTile.find('.compare-check')
3299  });
3300}
3301
3302/**
3303 * @private
3304 * @function
3305 * @description Initializes the DOM-Object of the compare container
3306 */
3307function initializeDom() {
3308  var $compareContainer = $('.compare-items');
3309  _currentCategory = $compareContainer.data('category') || '';
3310  var $active = $compareContainer.find('.compare-item').filter('.active');
3311  $active.each(function () {
3312    var $productTile = $('#' + $(this).data('uuid'));
3313    if ($productTile.length === 0) {
3314      return;
3315    }
3316    $productTile.find('.compare-check')[0].checked = true;
3317  });
3318  // set container state
3319  refreshContainer();
3320}
3321
3322/**
3323 * @private
3324 * @function
3325 * @description Initializes the events on the compare container
3326 */
3327function initializeEvents() {
3328  // add event to buttons to remove products
3329  $('.compare-item').on('click', '.compare-item-remove', function () {
3330    removeItem($(this).closest('.compare-item'));
3331  });
3332
3333  // Button to go to compare page
3334  $('#compare-items-button').on('click', function () {
3335    page.redirect(util.appendParamToURL(Urls.compareShow, 'category', _currentCategory));
3336  });
3337
3338  // Button to clear all compared items
3339  // rely on refreshContainer to take care of hiding the container
3340  $('#clear-compared-items').on('click', function () {
3341    $('.compare-items .active').each(function () {
3342      removeItem($(this));
3343    });
3344  });
3345}
3346
3347exports.init = function () {
3348  initializeDom();
3349  initializeEvents();
3350};
3351
3352exports.addProduct = addProduct;
3353exports.removeProduct = removeProduct;
3354
3355},{"./page":28,"./util":77,"promise":121}],6:[function(require,module,exports){
3356'use strict';
3357
3358var dialog = require('./dialog');
3359
3360/**
3361 * @function cookieprivacy    Used to display/control the scrim containing the cookie privacy code
3362 **/
3363module.exports = function () {
3364  /**
3365   * If we have not accepted cookies AND we're not on the Privacy Policy page, then show the notification
3366   * NOTE: You will probably want to adjust the Privacy Page test to match your site's specific privacy / cookie page
3367   */
3368  if (SitePreferences.COOKIE_HINT === true && document.cookie.indexOf('dw_cookies_accepted') < 0) {
3369    // check for privacy policy page
3370    if ($('.privacy-policy').length === 0) {
3371      dialog.open({
3372        url: Urls.cookieHint,
3373        options: {
3374          closeOnEscape: false,
3375          dialogClass: 'no-close',
3376          buttons: [{
3377            text: Resources.I_AGREE,
3378            click: function click() {
3379              $(this).dialog('close');
3380              enableCookies();
3381            }
3382          }]
3383        }
3384      });
3385    }
3386  } else {
3387    // Otherwise, we don't need to show the asset, just enable the cookies
3388    enableCookies();
3389  }
3390
3391  function enableCookies() {
3392    if (document.cookie.indexOf('dw=1') < 0) {
3393      document.cookie = 'dw=1; path=/';
3394    }
3395    if (document.cookie.indexOf('dw_cookies_accepted') < 0) {
3396      document.cookie = 'dw_cookies_accepted=1; path=/';
3397    }
3398  }
3399};
3400
3401},{"./dialog":12}],7:[function(require,module,exports){
3402'use strict';
3403
3404exports.init = function init() {
3405  $('.country-selector .current-country').on('click', function () {
3406    $('.country-selector .selector').toggleClass('active');
3407    $(this).toggleClass('selector-active');
3408  });
3409  // set currency first before reload
3410  $('.country-selector .selector .locale').on('click', function (e) {
3411    e.preventDefault();
3412    var url = this.href;
3413    var currency = this.getAttribute('data-currency');
3414    $.ajax({
3415      dataType: 'json',
3416      url: Urls.setSessionCurrency,
3417      data: {
3418        format: 'ajax',
3419        currencyMnemonic: currency
3420      }
3421    }).done(function (response) {
3422      if (!response.success) {
3423        throw new Error('Unable to set currency');
3424      }
3425      window.location.href = url;
3426    });
3427  });
3428};
3429
3430},{}],8:[function(require,module,exports){
3431'use strict';
3432
3433module.exports = {
3434  init: function init() {
3435    $(function () {
3436      $('.c-modal-iframe-radiance-point').on('mfpOpen', function (e) {
3437        $('.mfp-content').addClass('iframe-radiance-point');
3438      });
3439      $('.c-modal-iframe-radiance-point').on('mfpAfterClose', function (e) {
3440        if ($('body').hasClass('is-noscroll')) {
3441          $('body').removeClass('is-noscroll');
3442          $('body').removeAttr('style');
3443          $('html, body').prop({ scrollTop: $('body').attr('data-scroll') });
3444        }
3445      });
3446    });
3447  }
3448};
3449
3450},{}],9:[function(require,module,exports){
3451'use strict';
3452
3453module.exports.init = function () {
3454  $(function () {
3455    $('.c-modal-inline-radiance-point').on('mfpOpen', function (e) {
3456      $('.mfp-content').addClass('inline-radiance-point');
3457    });
3458  });
3459};
3460
3461},{}],10:[function(require,module,exports){
3462'use strict';
3463
3464module.exports = {
3465  init: function init() {
3466    require('./app_diff-20200219').init();
3467    require('./app_diff-20200319').init();
3468  }
3469};
3470
3471},{"./app_diff-20200219":8,"./app_diff-20200319":9}],11:[function(require,module,exports){
3472'use strict';
3473
3474function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
3475
3476var design = {
3477  init: function init() {
3478    //product search
3479    this.productSearchInit();
3480
3481    //product list
3482    this.plpInit();
3483
3484    //PDP
3485    this.pdpInit();
3486
3487    //tmp_video
3488    this.tmpVideoInit();
3489
3490    //tmp_recently
3491    this.tmpRecentlyInit();
3492
3493    //tmp_image
3494    this.tmpImageInit();
3495
3496    this.commonInit();
3497
3498    this.clockInit();
3499  },
3500  tmpImageInit: function tmpImageInit() {
3501    $(function () {
3502      $('.c-block-template_02-slider-main').slick({
3503        asNavFor: '.c-block-template_02-slider-thumbnail',
3504        arrows: false,
3505        responsive: [{
3506          breakpoint: 991,
3507          settings: {
3508            arrows: false,
3509            dots: true
3510          }
3511        }, {
3512          breakpoint: 768,
3513          settings: {
3514            arrows: false,
3515            dots: false
3516          }
3517        }]
3518      });
3519      $('.c-block-template_02-slider-thumbnail').slick({
3520        asNavFor: '.c-block-template_02-slider-main',
3521        slidesToShow: 4,
3522        slidesToScroll: 1,
3523        focusOnSelect: true
3524      });
3525    });
3526  },
3527  plpInit: function plpInit() {
3528    $(function () {
3529      $('.c-product-cards-color-more>a').off('click').on('click', function () {
3530        $(this).closest('.c-product-cards-color').addClass('is-active');
3531        $(this).closest('.c-product-cards-color').find('.c-list-color.is-hidden').removeClass('is-hidden');
3532        $(this).parent().addClass('is-hidden');
3533        // use library jquery.matchHeight.js
3534        $.fn.matchHeight._maintainScroll = true;
3535        matchHeightProducts();
3536        return false;
3537      });
3538
3539      $(document).off('click.plp.swatch, mousehover.plp.swatch').on('click.plp.swatch, mousehover.plp.swatch', '.c-list-color li > a', function () {
3540        if (window.innerWidth > 767) {
3541          var thumbIndex = $(this).closest('.c-product-cards-color-list').find('a').index(this);
3542          $(this).closest('.c-product-cards').find('.c-product-cards-photo-img > img').stop().hide();
3543          $(this).closest('.c-product-cards').find('.c-list-color-panel').removeClass('is-current');
3544          if ($(this).closest('.c-product-cards').find('.c-product-cards-photo-img > img').eq(thumbIndex).is(':hidden')) {
3545            $(this).closest('.c-product-cards').find('.c-product-cards-photo-img > img').eq(thumbIndex).fadeIn('slow');
3546            $(this).children('.c-list-color-panel').addClass('is-current');
3547          }
3548          return false;
3549        }
3550      });
3551
3552      // SP size When there is nothing to display on Filter "Filter" itself is not displayed.
3553      if (window.innerWidth < 991 && $('.c-block-products-search-panel--filter li').length == 0) {
3554        $('.c-block-products-search-tabs--filter').remove();
3555        $('.c-block-products-search-panel--filter').remove();
3556      }
3557
3558      // $('.c-list-color li > a').hover(function(){
3559      // 	if(window.innerWidth>991) {
3560      // 		$(this).trigger('mousehover');
3561      // 	}
3562      // });
3563    });
3564  },
3565  selectGiftInit: function selectGiftInit() {
3566    $(function () {
3567      $('.c-block-shopingmodal .c-list-color a').on('colorSelect', function () {
3568        var element = $(this).closest('.c-list-color').find('a').index(this);
3569        $(this).closest('.c-block-shopingmodal').find('.c-block-shopingmodal-change-image').each(function () {
3570          $(this).children().stop().hide(), $(this).children().eq(element).fadeIn();
3571        });
3572        $(this).closest('.c-block-shopingmodal').find('.c-block-shopingmodal-side-colorSelect .c-select-list-item a').removeClass('is-selected');
3573        $(this).closest('.c-block-shopingmodal').find('.c-block-shopingmodal-side-colorSelect .c-select-list-item a').eq(element).addClass('is-selected');
3574        var text = $(this).closest('.c-block-shopingmodal').find('.c-select-list-item>a.is-selected .c-select-list-item-text').html();
3575        $(this).closest('.c-block-shopingmodal').find('.c-block-shopingmodal-side-colorSelect .c-select-current').html(text);
3576        $(this).closest('.c-list-color').find('.c-list-color-panel').removeClass('is-current');
3577        $(this).children('.c-list-color-panel').addClass('is-current');
3578      });
3579
3580      $('.c-block-shopingmodal .c-list-color a').on('click', function () {
3581        if (767 < window.innerWidth) {
3582          var element = $(this).closest('.c-list-color').find('a').index(this);
3583          $('.c-block-shopingmodal .c-list-color a').eq(element).trigger('colorSelect');
3584        }
3585      });
3586
3587      $('.c-block-shopingmodal-side-colorSelect .c-select-list-item a').on('click', function () {
3588        var element = $(this).closest('.c-select-list').find('a').index(this);
3589        $('.c-block-shopingmodal .c-list-color a').eq(element).trigger('colorSelect');
3590        return false;
3591      });
3592    });
3593  },
3594  selectQuantityInit: function selectQuantityInit() {
3595    $(function () {
3596      //countup
3597      $('.c-quantitySelection-btn-plus').off('click').on('click', function () {
3598        var current = $(this).closest('.c-quantitySelection').find('.c-select-current');
3599        var currentNum = current.html();
3600        var limit = $(this).closest('.c-quantitySelection').find('.c-select-list-item').length;
3601        var index = $(this).closest('.c-quantitySelection').find('.c-select-list-item').index();
3602        currentNum++;
3603        var qtyReal = limit;
3604        if (currentNum <= limit) {
3605          current.html(currentNum);
3606          $(this).closest('.c-quantitySelection').find('.c-select-list-item').children('a').removeClass('is-selected');
3607          $(this).closest('.c-quantitySelection').find('.c-select-list-item').eq(currentNum - 1).children('a').addClass('is-selected');
3608          qtyReal = currentNum;
3609        }
3610
3611        $(this).closest('.c-quantitySelection-btn-gather').prev().val(qtyReal);
3612
3613        var isWishList = $('form[name^="dwfrm_wishlist_items"]').length > 0;
3614        var isStockNotification = $('main').data('pageName') === 'stocknotification';
3615        if (isWishList || isStockNotification) {
3616          var defaultPrice = $(this).closest('.quantity-column').find('input[name="default-price"]').val();
3617
3618          var calcPrice = Number(defaultPrice) * qtyReal;
3619          var str = calcPrice.toLocaleString() + '円';
3620
3621          if (isStockNotification) {
3622            $(this).closest('.c-list-products-full-item-text-parts').find('.c-dlist_03-item dd.c-text_06').text(str);
3623          } else {
3624            $(this).closest('.c-list-products-full-item-text-parts').find('.c-text-price').text(str);
3625          }
3626        }
3627        return false;
3628      });
3629
3630      //countdown
3631      $('.c-quantitySelection-btn-minus').off('click').on('click', function () {
3632        var current = $(this).closest('.c-quantitySelection').find('.c-select-current');
3633        var currentNum = current.html();
3634        var limit = $(this).closest('.c-quantitySelection').find('.c-select-list-item').length;
3635        var index = $(this).closest('.c-quantitySelection').find('.c-select-list-item').index();
3636
3637        var qtyReal = 1;
3638        if (currentNum > 1) {
3639          currentNum--;
3640          current.html(currentNum);
3641          $(this).closest('.c-quantitySelection').find('.c-select-list-item').children('a').removeClass('is-selected');
3642          $(this).closest('.c-quantitySelection').find('.c-select-list-item').eq(currentNum - 1).children('a').addClass('is-selected');
3643          qtyReal = currentNum;
3644        } else if (currentNum == 0) {
3645          $(this).closest('.c-quantitySelection').find('.c-select-list-item').children('a').removeClass('is-selected');
3646        }
3647
3648        $(this).closest('.c-quantitySelection-btn-gather').prev().val(qtyReal);
3649
3650        var isWishList = $('form[name^="dwfrm_wishlist_items"]').length > 0;
3651        var isStockNotification = $('main').data('pageName') === 'stocknotification';
3652        if (isWishList || isStockNotification) {
3653          var defaultPrice = $(this).closest('.quantity-column').find('input[name="default-price"]').val();
3654
3655          var calcPrice = Number(defaultPrice) * qtyReal;
3656          var str = calcPrice.toLocaleString() + '円';
3657
3658          if (isStockNotification) {
3659            $(this).closest('.c-list-products-full-item-text-parts').find('.c-dlist_03-item dd.c-text_06').text(str);
3660          } else {
3661            $(this).closest('.c-list-products-full-item-text-parts').find('.c-text-price').text(str);
3662          }
3663        }
3664        return false;
3665      });
3666
3667      // Change quantity on cart
3668      $('.c-list-products-full-item--cart .c-quantitySelection-btn-plus').off('click').on('click', function () {
3669        var current = $(this).closest('.c-quantitySelection').find('.c-select-current');
3670        var currentNum = current.html();
3671        var limit = $(this).closest('.c-quantitySelection').find('.c-select-list-item').length;
3672        var index = $(this).closest('.c-quantitySelection').find('.c-select-list-item').index();
3673        currentNum++;
3674        var qtyReal = limit;
3675        if (currentNum <= limit) {
3676          current.html(currentNum);
3677          $(this).closest('.c-quantitySelection').find('.c-select-list-item').children('a').removeClass('is-selected');
3678          $(this).closest('.c-quantitySelection').find('.c-select-list-item').eq(currentNum - 1).children('a').addClass('is-selected');
3679          qtyReal = currentNum;
3680        }
3681
3682        $(this).closest('.c-quantitySelection-btn-gather').prev().val(qtyReal);
3683        $(this).parents('.c-quantitySelection').find('input[type="hidden"]').val(qtyReal);
3684        $('input[name$=_deleteGiftCertificate]').remove();
3685        $('input[name$=_deleteProduct]').remove();
3686        $(this).closest('form').submit();
3687      });
3688
3689      $('.c-list-products-full-item--cart .c-quantitySelection-btn-minus').off('click').on('click', function () {
3690        var current = $(this).closest('.c-quantitySelection').find('.c-select-current');
3691        var currentNum = current.html();
3692        var limit = $(this).closest('.c-quantitySelection').find('.c-select-list-item').length;
3693        var index = $(this).closest('.c-quantitySelection').find('.c-select-list-item').index();
3694
3695        var qtyReal = 1;
3696        if (currentNum > 1) {
3697          currentNum--;
3698          current.html(currentNum);
3699          $(this).closest('.c-quantitySelection').find('.c-select-list-item').children('a').removeClass('is-selected');
3700          $(this).closest('.c-quantitySelection').find('.c-select-list-item').eq(currentNum - 1).children('a').addClass('is-selected');
3701          qtyReal = currentNum;
3702        } else if (currentNum == 0) {
3703          $(this).closest('.c-quantitySelection').find('.c-select-list-item').children('a').removeClass('is-selected');
3704        }
3705
3706        $(this).closest('.c-quantitySelection-btn-gather').prev().val(qtyReal);
3707        $(this).parents('.c-quantitySelection').find('input[type="hidden"]').val(qtyReal);
3708        $('input[name$=_deleteGiftCertificate]').remove();
3709        $('input[name$=_deleteProduct]').remove();
3710        $(this).closest('form').submit();
3711      });
3712    });
3713  },
3714  toggleSelectInit: function toggleSelectInit(eventContinue) {
3715    $(function () {
3716      // select open
3717      $('.c-dropdown-toggle').off('click').on('click', function () {
3718        if (!$(this).parents('.c-block-review').length) {
3719          if ($(this).parents('.c-dropdown').find('.c-select-list').is(':hidden')) {
3720            $('.c-select-list').hide();
3721            $(this).parents('.c-dropdown').find('.c-select-list').show();
3722          } else {
3723            $(this).parents('.c-dropdown').find('.c-select-list').hide();
3724          }
3725          return false;
3726        }
3727      });
3728    });
3729
3730    $(function () {
3731      eventContinue = eventContinue || false;
3732      $('.c-input-3column li').first().removeClass('is-half');
3733      // select
3734      $('.c-select-toggle').off('click').on('click', function () {
3735        if ($(this).next('.c-select-list').is(':hidden') && !$(this).hasClass('is-noselect')) {
3736          $('.c-select-list').hide();
3737          $(this).next('.c-select-list').show();
3738
3739          // Auto up down display
3740          var offset = $(this).offset();
3741          var posY = offset.top - $(window).scrollTop();
3742          var heightS = $(window).height();
3743        } else {
3744          $(this).next('.c-select-list').hide();
3745        }
3746      });
3747
3748      $('.c-select-list-item a').off('click').on('click', function (e) {
3749        e.preventDefault();
3750        var current = $(this).closest('.c-select').find('.c-select-current');
3751        var value = $(this).data('v') || $(this).find('span').data('num'); // form field and quantity selector
3752        var displayValue = $(this).children('.c-select-list-item-text').html();
3753        $(this).closest('.c-select-list').find('.c-select-list-item').children('a').removeClass('is-selected');
3754        $(this).addClass('is-selected');
3755        current.html(displayValue);
3756        $(this).closest('.c-select-list').hide();
3757        $(this).closest('.c-select').next().val(value);
3758        $(this).closest('.c-select').next().change();
3759
3760        if ($(this).closest('.c-block-shopingmodal-side-colorSelect').length > 0 || $(this).closest('.c-block-shoppingDock').length > 0) {
3761          var index = $(this).closest('.c-select-list').find('a').index(this);
3762          if ($(this).closest('.c-block-shopingmodal-set-item').length > 0) {
3763            $(this).closest('.c-block-shopingmodal-set-item').find('.c-list-color a').eq(index).trigger('colorSelect');
3764          }
3765
3766          if ($(this).closest('.product-variations').length > 0) {
3767            $(this).closest('.product-variations').find('.c-list-color a').eq(index).trigger('colorSelect');
3768          }
3769
3770          if ($(this).closest('.c-block-shoppingDock').length > 0) {
3771            $('.product-variations').find('.c-list-color a').eq(index).trigger('colorSelect');
3772          }
3773        }
3774
3775        var isWishList = $('form[name^="dwfrm_wishlist_items"]').length > 0;
3776        var isStockNotification = $('main').data('pageName') === 'stocknotification';
3777        if (isWishList || isStockNotification) {
3778          var defaultPrice = $(this).closest('.quantity-column').find('input[name="default-price"]').val();
3779
3780          var calcPrice = Number(defaultPrice) * Number(displayValue);
3781          var str = calcPrice.toLocaleString() + '円';
3782
3783          if (isStockNotification) {
3784            $(this).closest('.c-list-products-full-item-text-parts').find('.c-dlist_03-item dd.c-text_06').text(str);
3785          } else {
3786            $(this).closest('.c-list-products-full-item-text-parts').find('.c-text-price').text(str);
3787          }
3788        }
3789        return eventContinue;
3790      });
3791
3792      $('.c-list-products-full-item--cart .c-select-list-item a').off('click').on('click', function (e) {
3793        e.preventDefault();
3794        var current = $(this).closest('.c-select').find('.c-select-current');
3795        var value = $(this).data('v') || $(this).find('span').data('num'); // form field and quantity selector
3796        var displayValue = $(this).children('.c-select-list-item-text').html();
3797        $(this).closest('.c-select-list').find('.c-select-list-item').children('a').removeClass('is-selected');
3798        $(this).addClass('is-selected');
3799        current.html(displayValue);
3800        $(this).closest('.c-select-list').hide();
3801        $(this).closest('.c-select').next().val(value);
3802        $(this).closest('.c-select').next().change();
3803
3804        if ($(this).closest('.c-block-shopingmodal-side-colorSelect')) {
3805          var index = $(this).closest('.c-select-list').find('a').index(this);
3806          if ($(this).closest('.c-block-shopingmodal-set-item')) {
3807            $(this).closest('.c-block-shopingmodal-set-item').find('.c-list-color a').eq(index).trigger('colorSelect');
3808          }
3809
3810          if ($(this).closest('.product-variations')) {
3811            $(this).closest('.product-variations').find('.c-list-color a').eq(index).trigger('colorSelect');
3812          }
3813        }
3814        var quantity = $(this).closest('.c-quantitySelection').find('.c-select-current').text();
3815        $(this).closest('.c-quantitySelection').find('input[type="hidden"]').val(quantity);
3816        $('input[name$=_deleteGiftCertificate]').remove();
3817        $('input[name$=_deleteProduct]').remove();
3818        $(this).closest('form').submit();
3819      });
3820
3821      $(document).on('touchstart click', function (e) {
3822        if (!$(e.target).closest('.c-select').length && !$(e.target).closest('.c-dropdown').length) {
3823          $('.c-select-list').hide();
3824        }
3825      });
3826    });
3827  },
3828  productSearchInit: function productSearchInit() {
3829    $(window).on('load resize', function () {
3830      if (window.innerWidth > 767) {
3831        setTimeout(function () {
3832          matchHeightProducts();
3833        }, 50);
3834      }
3835    });
3836
3837    $(function () {
3838      $('.c-block-products-search-tabs .tab').off('click').on('click', function () {
3839        if (window.innerWidth < 991) {
3840          var num = $(this).closest('.c-block-products-search-tabs').find('.tab').index(this);
3841          if ($(this).closest('.c-block-products-search-tabs').next('.c-block-products-search-panels').find('.c-block-products-search-panel').eq(num).is(':hidden')) {
3842            $(this).closest('.c-block-products-search-tabs').next('.c-block-products-search-panels').find('.c-block-products-search-panel').removeClass('is-active');
3843            $('.c-block-products-search-tabs .tab').removeClass('is-active');
3844            $(this).closest('.c-block-products-search-tabs').next('.c-block-products-search-panels').find('.c-block-products-search-panel').eq(num).addClass('is-active');
3845            $(this).addClass('is-active');
3846          } else {
3847            $(this).closest('.c-block-products-search-tabs').next('.c-block-products-search-panels').find('.c-block-products-search-panel').eq(num).removeClass('is-active');
3848            $(this).removeClass('is-active');
3849          }
3850          return false;
3851        }
3852      });
3853    });
3854  },
3855  modalInit: function modalInit() {
3856    $.extend(true, $.magnificPopup.defaults, {
3857      tClose: Resources.POPUP_CLOSE,
3858      tLoading: Resources.POPUP_LOADING,
3859      gallery: {
3860        tPrev: Resources.POPUP_PREVIOUS,
3861        tNext: Resources.POPUP_NEXT,
3862        tCounter: Resources.POPUP_COUNTER
3863      },
3864      image: {
3865        tError: Resources.POPUP_ERROR
3866      }
3867    });
3868
3869    $('.c-modal-img').magnificPopup({
3870      type: 'image',
3871      removalDelay: 500,
3872      fixedContentPos: true,
3873      callbacks: {
3874        open: function open() {
3875          $('.mfp-container').addClass('row');
3876          $.magnificPopup.instance.close = function () {
3877            if (window.innerWidth < 992) {
3878              var scrollpos = $('body').attr('data-scroll');
3879              $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
3880            }
3881            $.magnificPopup.proto.close.call(this);
3882          };
3883        }
3884      }
3885    });
3886
3887    $('.c-modal-video').each(function () {
3888      var link = $(this).attr('href');
3889      $(this).magnificPopup({
3890        type: 'iframe',
3891        removalDelay: 600,
3892        fixedContentPos: true,
3893        iframe: {
3894          patterns: {
3895            youtube: {
3896              src: link
3897            }
3898          }
3899        },
3900        callbacks: {
3901          open: function open() {
3902            $('.mfp-container').addClass('row');
3903            $.magnificPopup.instance.close = function () {
3904              if (window.innerWidth < 992) {
3905                var scrollpos = $('body').attr('data-scroll');
3906                $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
3907              }
3908              $.magnificPopup.proto.close.call(this);
3909            };
3910          }
3911        }
3912      });
3913    });
3914
3915    $('.c-modal-video-fullscreen').each(function () {
3916      var link = $(this).attr('href');
3917      $(this).magnificPopup({
3918        type: 'iframe',
3919        removalDelay: 600,
3920        fixedContentPos: true,
3921        iframe: {
3922          patterns: {
3923            youtube: {
3924              src: link
3925            }
3926          }
3927        },
3928        callbacks: {
3929          open: function open() {
3930            $('.mfp-container').addClass('row mfp-iframe-holder-fullscreen');
3931            $.magnificPopup.instance.close = function () {
3932              if (window.innerWidth < 992) {
3933                var scrollpos = $('body').attr('data-scroll');
3934                $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
3935              }
3936              $.magnificPopup.proto.close.call(this);
3937            };
3938          }
3939        }
3940      });
3941    });
3942
3943    $('.c-modal-inline').magnificPopup({
3944      type: 'inline',
3945      removalDelay: 500,
3946      preloader: false,
3947      fixedContentPos: true,
3948      callbacks: {
3949        open: function open() {
3950          $('.mfp-container').addClass('row');
3951          $('.mfp-content > div').addClass('row');
3952          $('.slick-slider').slick('setPosition');
3953          $('.c-slider-products-landscape').slick('setPosition');
3954          $('.c-slider-products-vertical').slick('setPosition');
3955          matchHeightProducts();
3956          if ($('.c-block-sampleselection-body').length) {
3957            $('.c-block-sampleselection-body').getNiceScroll().resize();
3958          }
3959          $.magnificPopup.instance.close = function () {
3960            if (window.innerWidth < 992) {
3961              var scrollpos = $('body').attr('data-scroll');
3962              $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
3963            }
3964            $.magnificPopup.proto.close.call(this);
3965          };
3966        }
3967      }
3968    });
3969
3970    $('.c-modal-autoreplenishment').on('click', function (e) {
3971      if ($.magnificPopup.instance.st !== undefined) {
3972        e.stopPropagation();
3973        $.magnificPopup.instance.st.callbacks = {
3974          afterClose: function afterClose() {
3975            if ($('#shopingmodal').length > 0) {
3976              e.stopPropagation();
3977              $.magnificPopup.open({
3978                items: {
3979                  src: '#shopingmodal',
3980                  type: 'inline',
3981                  removalDelay: 500
3982                }
3983              });
3984            }
3985          }
3986        };
3987      }
3988
3989      $.magnificPopup.open({
3990        items: {
3991          src: '#autoreplenishmentmodal',
3992          type: 'inline',
3993          removalDelay: 500
3994        }
3995      });
3996    });
3997
3998    $(document).on('click', '.c-block-share-toggle.c-modal', function (e) {
3999      if ($.magnificPopup.instance.st !== undefined) {
4000        e.stopPropagation();
4001        $.magnificPopup.instance.st.callbacks = {
4002          afterClose: function afterClose() {
4003            if ($('#shopingmodal').length > 0) {
4004              e.stopPropagation();
4005              $.magnificPopup.open({
4006                items: {
4007                  src: '#shopingmodal',
4008                  type: 'inline',
4009                  removalDelay: 500
4010                }
4011              });
4012            }
4013          }
4014        };
4015      }
4016
4017      $.magnificPopup.open({
4018        items: {
4019          src: '#sharemodal',
4020          type: 'inline',
4021          removalDelay: 500
4022        }
4023      });
4024    });
4025
4026    $('.c-modal-inline--noclose').magnificPopup({
4027      type: 'inline',
4028      removalDelay: 500,
4029      preloader: false,
4030      fixedContentPos: true,
4031      showCloseBtn: false,
4032      closeOnBgClick: false,
4033      callbacks: {
4034        open: function open() {
4035          $('.mfp-container').addClass('row');
4036          $('.mfp-content > div').addClass('row');
4037          matchHeightProducts();
4038          $.magnificPopup.instance.close = function () {
4039            if (window.innerWidth < 992) {
4040              var scrollpos = $('body').attr('data-scroll');
4041              $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4042            }
4043            $.magnificPopup.proto.close.call(this);
4044          };
4045        }
4046      }
4047    });
4048
4049    $('.c-modal-finish').click(function (e) {
4050      $.magnificPopup.open({
4051        items: {
4052          src: $('#finishmodal')
4053        },
4054        type: 'inline',
4055        removalDelay: 500,
4056        preloader: false,
4057        fixedContentPos: true,
4058        showCloseBtn: false,
4059        closeOnBgClick: false,
4060        callbacks: {
4061          open: function open() {
4062            $('.mfp-container').addClass('row');
4063            $('.mfp-content > div').addClass('row');
4064            matchHeightProducts();
4065            $.magnificPopup.instance.close = function () {
4066              if (window.innerWidth < 992) {
4067                var scrollpos = $('body').attr('data-scroll');
4068                $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4069              }
4070              $.magnificPopup.proto.close.call(this);
4071            };
4072          }
4073        }
4074      });
4075      return e.preventDefault();
4076    });
4077
4078    $('.c-modal-gallery').magnificPopup({
4079      delegate: 'a',
4080      type: 'image',
4081      removalDelay: 500,
4082      fixedContentPos: true,
4083      gallery: {
4084        enabled: true
4085      },
4086      image: {
4087        titleSrc: function titleSrc(item) {
4088          return item.el.attr('title') || item.el.find('img').attr('alt');
4089        }
4090      },
4091      callbacks: {
4092        open: function open() {
4093          $('.mfp-container').addClass('row');
4094          $.magnificPopup.instance.close = function () {
4095            if (window.innerWidth < 992) {
4096              var scrollpos = $('body').attr('data-scroll');
4097              $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4098            }
4099            $.magnificPopup.proto.close.call(this);
4100          };
4101        }
4102      }
4103    });
4104
4105    $('.c-modal-iframe').magnificPopup({
4106      type: 'iframe',
4107      removalDelay: 500,
4108      fixedContentPos: true,
4109      preloader: false
4110    });
4111
4112    $('.c-modal-cart-alert').magnificPopup({
4113      type: 'inline',
4114      removalDelay: 500,
4115      fixedContentPos: true,
4116      preloader: false
4117    });
4118
4119    // $(document)
4120    //   .off('click', '.c-modal')
4121    //   .on('click', '.c-modal', function (e) {
4122    //     if (window.innerWidth < 992) {
4123    //       var scrollpos = $(window).scrollTop();
4124    //       $('body').attr('data-scroll', scrollpos);
4125    //       $('body').addClass('is-noscroll').css({ top: -scrollpos });
4126    //     }
4127    //   });
4128    $('.c-modal-close').off('click').on('click', function (e) {
4129      e.preventDefault();
4130      $.magnificPopup.instance.close = function () {
4131        if (window.innerWidth < 992) {
4132          var scrollpos = $('body').attr('data-scroll');
4133          $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4134        }
4135        $.magnificPopup.proto.close.call(this);
4136      };
4137      var magnificPopup = $.magnificPopup.instance;
4138      magnificPopup.close();
4139    });
4140    $('.c-modal-cart-alert-close').off('click').on('click', function (e) {
4141      e.preventDefault();
4142      $.magnificPopup.instance.close = function () {
4143        if (window.innerWidth < 992) {
4144          var scrollpos = $('body').attr('data-scroll');
4145          $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4146        }
4147        $.magnificPopup.proto.close.call(this);
4148      };
4149    });
4150  },
4151  footerInit: function footerInit() {
4152    $(function () {
4153      $('.ge-changeregion-toggle').off('click').on('click', function () {
4154        var scrollpos;
4155        if ($('.ge-changeregion').is(':hidden')) {
4156          var scroll_bar = window.innerWidth - $(window).width();
4157          if ($('.ge-navi-list').is(':visible') || window.innerWidth < 992) {
4158            var scrollpos = $('body').attr('data-scroll');
4159            $('body').attr('data-scroll', scrollpos);
4160            $('body').addClass('is-noscroll').css({ top: -scrollpos });
4161          } else {
4162            var scrollpos = $(window).scrollTop();
4163            $('body').attr('data-scroll', scrollpos);
4164            $('body').addClass('is-noscroll').css({ top: -scrollpos });
4165          }
4166
4167          $('.ge-changeregion').fadeIn();
4168          $('.slick-slider').slick('setPosition');
4169          $('.ge-changeregion-close').css('padding-right', scroll_bar);
4170          if ($('.ge-changeregion-results-list').length) {
4171            $('.ge-changeregion').addClass('is-result');
4172          } else {
4173            $('.ge-changeregion').removeClass('is-result');
4174          }
4175          if (window.innerWidth < 992) {
4176            $('.ge-naviSpToggle').removeClass('is-active');
4177            $('.ge-header').removeClass('is-active');
4178            $('.ge-navi').fadeOut();
4179          }
4180        }
4181        return false;
4182      });
4183      $('.ge-changeregion-close a').off('click').on('click', function () {
4184        var scrollpos = $('body').attr('data-scroll');
4185        $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4186        $('.ge-changeregion').fadeOut();
4187        $('.ge-changeregion').removeClass('is-result');
4188        return false;
4189      });
4190    });
4191  },
4192  headerInit: function headerInit() {
4193    $(function () {
4194      $('.js-navi-toggle a').off('click').on('click', function (e) {
4195        $('.ge-header').toggleClass('is-naviOpen');
4196        $(this).parent().toggleClass('is-active');
4197        $('.js-navi-list').slideToggle();
4198        return false;
4199      });
4200
4201      //PC MEGA MENU item hover
4202      $('.ge-navi-list-first-text > a').hover(function () {
4203        if (window.innerWidth > 992) {
4204          //          $('.ge-navi-list-first-panel').not(this).stop().fadeOut();
4205          //          $('.ge-navi-list-first-text > a').not(this).removeClass('is-active');
4206          //          $(this).addClass('is-active');
4207          //          $(this)
4208          //            .parent('.ge-navi-list-first-text ')
4209          //            .next('.ge-navi-list-first-panel')
4210          //            .stop()
4211          //            .fadeIn();
4212        }
4213      });
4214
4215      //TABLET, MOBILE Navi open
4216      $('.ge-naviSpToggle > a').off('click').on('click', function () {
4217        var scrollpos = 0;
4218        if ($('.ge-navi').is(':hidden')) {
4219          $('.ge-navi').fadeIn();
4220          $('.ge-header').addClass('is-active');
4221          if (window.innerWidth < 992 || $('body').hasClass('is-noscroll')) {
4222            var scrollpos = $(window).scrollTop();
4223            $('body').attr('data-scroll', scrollpos);
4224            $(this).parent().addClass('is-active');
4225            $('body').addClass('is-noscroll').css({ top: -scrollpos });
4226          }
4227        } else {
4228          $('.ge-navi').fadeOut();
4229          $('.ge-header').removeClass('is-active');
4230          if (window.innerWidth < 992) {
4231            var scrollpos = $('body').attr('data-scroll');
4232            $(this).parent().removeClass('is-active');
4233            $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4234          }
4235        }
4236        return false;
4237      });
4238
4239      $(document).on('click', function (e) {
4240        if (!$(e.target).closest('.ge-header').length) {
4241          $('.js-navi-toggle').removeClass('is-active');
4242          $('.ge-header').removeClass('is-naviOpen');
4243          $('.ge-navi-gather>li').removeClass('is-active');
4244          $('.ge-naviSpToggle').removeClass('is-active');
4245          if (window.innerWidth > 992) {
4246            //            $('.js-navi-list').slideUp();
4247          } else {
4248            $('.ge-navi').slideUp();
4249          }
4250        }
4251      });
4252    });
4253
4254    this.dropdownToggleInit();
4255
4256    $(function () {
4257      $('.ge-navi-list-dropdown-toggle,.ge-navi-list-dropdown-toggleText').off('click').on('click', function () {
4258        if (window.innerWidth < 992) {
4259          if ($(this).parent().next('.ge-navi-list-dropdown-panel').is(':hidden')) {
4260            $(this).parent().next('.ge-navi-list-dropdown-panel').slideDown();
4261            $(this).parent().addClass('is-active');
4262          } else {
4263            $(this).parent().next('.ge-navi-list-dropdown-panel').slideUp();
4264            $(this).parent().removeClass('is-active');
4265          }
4266        }
4267      });
4268      //TABLET, MOBILE Navi item open
4269      $('.ge-naviSp-dropdown-toggle').off('click').on('click', function () {
4270        if ($(this).next('.ge-naviSp-dropdown-panel').is(':hidden')) {
4271          $(this).next('.ge-naviSp-dropdown-panel').slideDown();
4272          $(this).parent().addClass('is-active');
4273        } else {
4274          $(this).next('.ge-naviSp-dropdown-panel').slideUp();
4275          $(this).parent().removeClass('is-active');
4276        }
4277      });
4278
4279      //public header scroll
4280      geHeaderScroll();
4281      $(document).on('scroll', function () {
4282        geHeaderScroll();
4283      });
4284      function geHeaderScroll() {
4285        var scroll = $(window).scrollTop();
4286        if (scroll >= 1) {
4287          $('.ge-header').addClass('is-scroll');
4288        } else {
4289          if (!$('body').hasClass('is-noscroll')) {
4290            $('.ge-header').removeClass('is-scroll');
4291          }
4292        }
4293      }
4294    });
4295  },
4296  dropdownToggleInit: function dropdownToggleInit() {
4297    function headerNavScroll() {
4298      $('.ge-dropdown-cart-list').niceScroll({
4299        cursorcolor: '#D7D7D7',
4300        cursoropacitymin: 0.3,
4301        cursorwidth: 6,
4302        autohidemode: false
4303      });
4304      $(document).ready(function () {
4305        setTimeout(function () {
4306          if ($('.c-block-sampleselection-body').length) {
4307            $('.c-block-sampleselection-body').niceScroll('ul', {
4308              cursorcolor: '#D7D7D7',
4309              cursoropacitymin: 0.3,
4310              cursorwidth: 6,
4311              autohidemode: false
4312            });
4313          }
4314        }, 50);
4315      });
4316    }
4317    headerNavScroll();
4318    $(window).on('resize', function () {
4319      headerNavScroll();
4320    });
4321    $(function () {
4322      $('.ge-dropdown:not(.ge-dropdown--cart) > a').off('click').on('click', function () {
4323        if (window.innerWidth > 767) {
4324          if ($(this).next('.ge-dropdown-box').is(':hidden')) {
4325            $('.ge-dropdown').removeClass('is-active');
4326            $('.ge-dropdown-box').fadeOut();
4327            $(this).next('.ge-dropdown-box').fadeIn();
4328            $(this).parent().addClass('is-active');
4329            if ($(this).closest('.ge-dropdown').find('.ge-dropdown-cart-list').length) {
4330              $('.ge-dropdown-cart-list').getNiceScroll().resize();
4331            }
4332          } else {
4333            $(this).next('.ge-dropdown-box').fadeOut(0);
4334            $(this).parent().removeClass('is-active');
4335          }
4336          return false;
4337        } else {
4338          if ($(this).parent()[0].id === 'mini-cart') {
4339            location.href = $(this).next('div').children('.ge-dropdown-cart-button').children('ul').children('li').children('a')[0].href;
4340          }
4341        }
4342      });
4343      var getDevice = function () {
4344        var ua = navigator.userAgent;
4345        if (ua.indexOf('iPhone') > 0 || ua.indexOf('iPod') > 0 || ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0) {
4346          return 'sp';
4347        } else if (ua.indexOf('iPad') > 0 || ua.indexOf('Android') > 0) {
4348          return 'tab';
4349        } else {
4350          return 'other';
4351        }
4352      }();
4353      $('.ge-dropdown--cart').mouseenter(function () {
4354        if (window.innerWidth > 992 && getDevice == 'other') {
4355          //          if ($(this).find('.ge-dropdown-box').is(':hidden')) {
4356          //            $('.ge-dropdown').stop().removeClass('is-active');
4357          //            $('.ge-dropdown-box').stop().fadeOut();
4358          //            $(this).stop().addClass('is-active');
4359          //            $(this).find('.ge-dropdown-box').stop().fadeIn(0);
4360          //            $('.ge-dropdown-cart-list').niceScroll({
4361          //              cursorcolor: '#D7D7D7',
4362          //              cursoropacitymin: 0.3,
4363          //              cursorwidth: 6,
4364          //              autohidemode: false
4365          //            });
4366          //            $('.ge-dropdown-cart-list').getNiceScroll().resize();
4367          //            headerNavScroll();
4368          //          }
4369        }
4370      });
4371      $('.ge-dropdown--cart').mouseleave(function () {
4372        //        if (window.innerWidth > 992 && getDevice == 'other') {
4373        //          if (!$(this).find('.ge-dropdown-box').is(':hidden')) {
4374        //            $(this).find('.ge-dropdown-box').stop('true', 'true').fadeOut(0);
4375        //            $(this).stop().removeClass('is-active');
4376        //            headerNavScroll();
4377        //          }
4378        //        }
4379      });
4380      $(document).on('click', function (e) {
4381        if (!$(e.target).closest('.ge-dropdown').length && !$(e.target).closest('.ge-search').length && !$(e.target).hasClass('.c-modal') && !$(e.target).closest('.mfp-wrap').length) {
4382          if (window.innerWidth > 992) {
4383            //            var scrollpos = $('body').attr('data-scroll');
4384            //            $('html,body')
4385            //              .removeAttr('data-scroll')
4386            //              .removeClass('is-noscroll')
4387            //              .css({ top: 0 })
4388            //              .scrollTop(scrollpos);
4389          }
4390          $('.ge-dropdown').removeClass('is-active');
4391          $('.ge-dropdown-box').fadeOut();
4392        }
4393      });
4394    });
4395  },
4396  searchInit: function searchInit() {
4397    $(function () {
4398      //search open
4399      $('.ge-search-toggle').off('click').on('click', function () {
4400        var scrollpos;
4401        if ($('.ge-search').is(':hidden')) {
4402          var scrollpos = $(window).scrollTop();
4403          var scroll_bar = window.innerWidth - $(window).width();
4404          $('body').attr('data-scroll', scrollpos);
4405          $('body').addClass('is-noscroll').css({ top: -scrollpos });
4406          $('.ge-search').fadeIn();
4407          $('.slick-slider').slick('setPosition');
4408          $('.ge-search-close').css('padding-right', scroll_bar);
4409          if ($('.ge-search-results-list').length) {
4410            $('.ge-search').addClass('is-result');
4411          } else {
4412            $('.ge-search').removeClass('is-result');
4413          }
4414        }
4415        return false;
4416      });
4417
4418      //search close
4419      $('.ge-search-close a').off('click').on('click', function () {
4420        var scrollpos = $('body').attr('data-scroll');
4421        $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4422        $('.ge-search').fadeOut();
4423        $('.ge-search').removeClass('is-result');
4424        return false;
4425      });
4426
4427      //search reset
4428      $('.ge-search-input .c-input-btn-reset').off('click').on('click', function () {
4429        $(this).closest('.ge-search-input').find('.c-input-box').attr('value', '');
4430        $(this).closest('.ge-search-input').find('.c-input-btn-search').prop('disabled', true);
4431        $(this).fadeOut();
4432        $(this).closest('.ge-search-input').find('.c-input-btn-search').fadeIn();
4433        return false;
4434      });
4435
4436      $(window).on('load', function () {
4437        $('.ge-search-input').each(function () {
4438          var value = $(this).find('.c-input-box').val();
4439          if (value == '' && value != value) {
4440            $(this).find('.c-input-btn-reset').fadeOut();
4441            $(this).find('.c-input-btn-search').fadeIn();
4442          }
4443        });
4444      });
4445      $('.ge-search-input .c-input-box').on('change keypress keyup', function () {
4446        $('.ge-search-input').each(function () {
4447          var value = $(this).find('.c-input-box').val();
4448          $(this).find('.c-input-btn-reset').fadeOut();
4449          $(this).find('.c-input-btn-search').fadeIn();
4450        });
4451      });
4452      //search disabled
4453      $('input[type="search"]').on('change keypress keyup', function () {
4454        if ($(this).val() == '') {
4455          $(this).parent().find('.c-input-btn-search').prop('disabled', true);
4456        } else {
4457          $(this).parent().find('.c-input-btn-search').prop('disabled', false);
4458        }
4459      });
4460      matchHeightProducts();
4461    });
4462  },
4463  tmpRecentlyInit: function tmpRecentlyInit() {
4464    $(function () {
4465      $('.c-slider-recently').on('init', function () {
4466        $('.c-modal-inline').magnificPopup({
4467          type: 'inline',
4468          removalDelay: 500,
4469          preloader: false,
4470          fixedContentPos: true,
4471          callbacks: {
4472            open: function open() {
4473              $('.mfp-container').addClass('row');
4474              $('.mfp-content > div').addClass('row');
4475              $('.slick-slider').slick('setPosition');
4476              $('.c-slider-products-landscape').slick('setPosition');
4477              $('.c-slider-products-vertical').slick('setPosition');
4478              matchHeightProducts();
4479              $.magnificPopup.instance.close = function () {
4480                if (window.innerWidth < 992) {
4481                  var scrollpos = $('body').attr('data-scroll');
4482                  $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
4483                }
4484                $.magnificPopup.proto.close.call(this);
4485              };
4486            }
4487          }
4488        });
4489      });
4490
4491      $('.c-slider-recently').slick({
4492        slidesToShow: 4,
4493        slidesToScroll: 4,
4494        dots: true,
4495        responsive: [{
4496          breakpoint: 991,
4497          settings: {
4498            slidesToShow: 3,
4499            slidesToScroll: 3,
4500            arrows: false,
4501            dots: true
4502          }
4503        }, {
4504          breakpoint: 768,
4505          settings: {
4506            slidesToShow: 1,
4507            slidesToScroll: 1,
4508            arrows: false,
4509            dots: true
4510          }
4511        }]
4512      });
4513    });
4514  },
4515  tmpVideoInit: function tmpVideoInit() {
4516    $(function () {
4517      $('.c-slider-videocarousel').on('init', function () {
4518        $('.c-modal-video-fullscreen').each(function () {
4519          var link = $(this).attr('href');
4520          $(this).magnificPopup({
4521            type: 'iframe',
4522            removalDelay: 600,
4523            fixedContentPos: true,
4524            iframe: {
4525              patterns: {
4526                youtube: {
4527                  src: link
4528                }
4529              }
4530            },
4531            callbacks: {
4532              open: function open() {
4533                $('.mfp-container').addClass('row mfp-iframe-holder-fullscreen');
4534              }
4535            }
4536          });
4537        });
4538      });
4539      $('.c-slider-videocarousel').slick({
4540        slidesToShow: 4,
4541        slidesToScroll: 4,
4542        dots: true,
4543        pauseOnHover: false,
4544        responsive: [{
4545          breakpoint: 991,
4546          settings: {
4547            slidesToShow: 3,
4548            slidesToScroll: 3,
4549            arrows: false,
4550            dots: true
4551          }
4552        }, {
4553          breakpoint: 768,
4554          settings: {
4555            slidesToShow: 1,
4556            slidesToScroll: 1,
4557            arrows: false,
4558            dots: true
4559          }
4560        }]
4561      });
4562    });
4563  },
4564
4565  //WOW init
4566  wowInit: function wowInit() {
4567    $('template').each(function () {
4568      var $t = $(this),
4569          toId = $t.attr('data-forid'),
4570          inHtml = $t.html(),
4571          $box = $('#' + toId);
4572
4573      if ($box.length) {
4574        $box.html(inHtml);
4575      }
4576    });
4577
4578    $(function () {
4579      function wowstart() {
4580        if (window.innerWidth > 992) {
4581          //          new WOW().init();
4582        }
4583      }
4584      wowstart();
4585      var timer = false;
4586      var windowW = window.innerWidth;
4587      $(window).on('resize', function (e) {
4588        if (windowW != window.innerWidth) {
4589          if (timer !== false) {
4590            clearTimeout(timer);
4591          }
4592          timer = setTimeout(function () {
4593            wowstart();
4594          }, 200);
4595          windowW = window.innerWidth;
4596        }
4597      });
4598    });
4599  },
4600
4601  commonInit: function commonInit() {
4602    //search
4603    this.searchInit();
4604
4605    //header
4606    this.headerInit();
4607
4608    //footer
4609    this.footerInit();
4610
4611    //modal
4612    this.modalInit();
4613
4614    //toggle select
4615    this.toggleSelectInit();
4616
4617    //WOW init
4618    this.wowInit();
4619
4620    if ($('.c-list-instagram01').length) {
4621      var accessToken = '2680730803.d5ced9a.da86b2583a87427e8818b35ad0b3af39';
4622      var count = 7; // 取得件数
4623
4624      $.ajax({
4625        url: 'https://api.instagram.com/v1/users/self/media/recent/?access_token=' + accessToken + '&count=' + count,
4626        dataType: 'jsonp',
4627        success: function success(data) {
4628          var insert = '';
4629          for (var i = 0; i < data['data'].length; i++) {
4630            insert += "<li class='c-list-instagram01-item'>";
4631            insert += '<a  href="' + data['data'][i]['link'] + '" title="' + data['data'][i]['caption']['text'] + '" target="_blank">';
4632            insert += '<span style="background-image:url(' + data['data'][i]['images']['standard_resolution']['url'] + ')"></span>';
4633            insert += '</a>';
4634
4635            insert += '</li>';
4636          }
4637          $('.c-list-instagram01').append(insert);
4638        }
4639      });
4640    }
4641    if ($('.c-list-instagram02').length) {
4642      var accessToken = '2680730803.d5ced9a.da86b2583a87427e8818b35ad0b3af39';
4643      var count = 3; // 取得件数
4644
4645      $.ajax({
4646        url: 'https://api.instagram.com/v1/users/self/media/recent/?access_token=' 
4646+ accessToken + '&count=' + count,
4647        dataType: 'jsonp',
4648        success: function success(data) {
4649          var insert = '';
4650          for (var i = 0; i < data['data'].length; i++) {
4651            insert += "<li class='c-list-instagram02-item'>";
4652            insert += '<a  href="' + data['data'][i]['link'] + '" title="' + data['data'][i]['caption']['text'] + '" target="_blank">';
4653            insert += '<span style="background-image:url(' + data['data'][i]['images']['standard_resolution']['url'] + ')"></span>';
4654            insert += '</a>';
4655
4656            insert += '</li>';
4657          }
4658          $('.c-list-instagram02').append(insert);
4659        }
4660      });
4661    }
4662
4663    $(function () {
4664      $('.c-underColumn-toggle >a ').off('click').on('click', function () {
4665        var main = $(this).closest('.c-underColumn').find('.c-underColumn-main'),
4666            side = $(this).closest('.c-underColumn').find('.c-underColumn-side');
4667        if (window.innerWidth < 767 || side.is(':hidden')) {
4668          main.hide();
4669          side.show();
4670        } else {
4671          main.show();
4672          side.hide();
4673        }
4674        return false;
4675      });
4676    });
4677
4678    $(function () {
4679      //textarea count
4680      $('.c-textarea').keyup(function () {
4681        var txtcount = $(this).val().length,
4682            txtlimit = $(this).maxlength;
4683        $(this).closest('.c-textarea-box').find('.c-textarea-count .countnow').text(txtcount);
4684        if (txtcount == 0) {
4685          $(this).closest('.c-textarea-box').find('.c-textarea-count .countnow').text('0');
4686        }
4687        if (txtcount >= txtlimit) {
4688          $(this).closest('.c-textarea-box').find('.c-textarea-count .countnow').text(txtlimit);
4689        }
4690      });
4691
4692      $('.c-dlist-dropdown-link-toggle').off('click').on('click', function () {
4693        if ($(this).parent().next('dd').is(':hidden')) {
4694          $(this).parent().addClass('is-active');
4695          $(this).parent().next('dd').slideDown();
4696        } else {
4697          $(this).parent().removeClass('is-active');
4698          $(this).parent().next('dd').slideUp();
4699        }
4700        return false;
4701      });
4702      $('.c-dlist-dropdown > dt').off('click').on('click', function () {
4703        if ($(this).next('dd').is(':hidden')) {
4704          $(this).addClass('is-active');
4705          $(this).next('dd').slideDown();
4706          if ($(this).next('dd').find('.ge-dropdown-cart-list').length) {
4707            $('.ge-dropdown-cart-list').getNiceScroll().resize();
4708            $('.ge-dropdown-cart-list').niceScroll({
4709              cursorcolor: '#D7D7D7',
4710              cursoropacitymin: 0.3,
4711              cursorwidth: 6,
4712              autohidemode: false
4713            });
4714          }
4715        } else {
4716          $(this).removeClass('is-active');
4717          $(this).next('dd').slideUp();
4718          if ($(this).next('dd').find('.ge-dropdown-cart-list').length) {
4719            $('.ge-dropdown-cart-list').getNiceScroll().remove();
4720          }
4721        }
4722        return false;
4723      });
4724    });
4725
4726    this.selectQuantityInit();
4727
4728    // JavaScript Document
4729    var getDevice = function () {
4730      var ua = navigator.userAgent;
4731      if (ua.indexOf('iPhone') > 0 || ua.indexOf('iPod') > 0 || ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0) {
4732        return 'sp';
4733      } else if (ua.indexOf('iPad') > 0 || ua.indexOf('Android') > 0) {
4734        return 'tab';
4735      } else {
4736        return 'other';
4737      }
4738    }();
4739    $(function () {
4740      $(document).on('click', "[href^='#']:not(.c-modal)" + "[href!='#']", scroll_func);
4741      $(document).on('click', '#pageTop', function () {
4742        scroll_func('top');
4743      });
4744    });
4745
4746    $(function () {
4747      $("[href^='#']:not(.c-modal)" + "[href!='#']").off('click').on('click', function () {
4748        var headerH = $('.ge-header').height();
4749        var messageH = $('.ge-header-fixedMessage').height();
4750        var headerHight = headerH && messageH ? headerH + messageH : 0;
4751        var href = $(this).attr('href');
4752        var target = $(href == '#' || href == '' ? 'html' : href);
4753        var position = target.offset().top - headerHight;
4754        $('html, body').animate({ scrollTop: position }, 550, 'swing');
4755        return false;
4756      });
4757    });
4758
4759    /* ページTOPへスクロール */
4760    var scroll_func = function scroll_func(top) {
4761      //      if (top == 'top') {
4762      //        $('html,body')
4763      //          .scrollTop(800)
4764      //          .stop()
4765      //          .animate({ scrollTop: 0 }, 'slow', 'easeOutQuart');
4766      //      } else {
4767      //        $('html,body').animate(
4768      //          { scrollTop: $($(this).attr('href')).offset().top },
4769      //          'slow',
4770      //          'easeOutQuart'
4771      //        );
4772      //      }
4773      return false;
4774    };
4775    /* /ページTOPへスクロール */
4776
4777    var loading_func = function loading_func(mode) {
4778      if (mode == 'on') {
4779        $('.modLoading').remove();
4780        $('body').append('<div class="modLoading"><i class="fa fa-spinner fa-spin"></i></div>');
4781      }
4782      if (mode == 'off') {
4783        $('.modLoading').fadeOut(function () {
4784          $(this).remove();
4785        });
4786      }
4787    };
4788
4789    //modLoadingに対するBack Forward Cache 対策
4790    window.onpageshow = function (event) {
4791      if (event.persisted) {
4792        var elements = document.getElementsByClassName('modLoading');
4793        var length = elements.length;
4794        if (length) {
4795          window.location.reload();
4796        }
4797      }
4798    };
4799
4800    //    $(function () {
4801    //      $(window).on('load resize', function () {
4802    //        matchHeightAction();
4803    //      });
4804    //    });
4805    function matchHeightAction() {
4806      $('.js-height_01').matchHeight();
4807      $('.js-height_02').matchHeight();
4808      $('.js-height_03').matchHeight();
4809      $('.js-height_04').matchHeight();
4810      $('.js-height_05').matchHeight();
4811      $('.js-height_06').matchHeight();
4812      $('.js-height_07').matchHeight();
4813      $('.js-height_08').matchHeight();
4814      $('.js-height_09').matchHeight();
4815      $('.js-height_10').matchHeight();
4816    }
4817
4818    $(function () {
4819      if ($('.js-top-carousel')[0]) {
4820        var isPC = function isPC() {
4821          return matchMediaPC.matches;
4822        };
4823
4824        // sliderInit
4825        // YouTubeの埋め込み
4826        var onPlayerReady = function onPlayerReady(event) {
4827          event.target.mute();
4828          event.target.getPlaybackQuality('highres');
4829          sliderReady(event);
4830        };
4831
4832        var onPlayerStateChange = function onPlayerStateChange(event) {
4833          if (event.data === YT.PlayerState.ENDED) {
4834            // $('.js-top-carousel').slick('slickNext');
4835          }
4836        };
4837
4838        var onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() {
4839          $('.js-top-carousel').find('.c-topCarousel-item').each(function (index) {
4840            var $el = $(this).find('.c-topCarousel-iframe-wrap');
4841            if ($el[0]) {
4842              $('.js-top-carousel').removeClass('is-loading');
4843              $el.attr('id', 'c-topCarousel-movieid' + index);
4844              movieList.push({
4845                index: index,
4846                videoId: $el.attr('data-yt-id')
4847              });
4848              ytPlayers.push('');
4849            }
4850          });
4851
4852          if (movieList.length) {
4853            for (var i = 0; i < movieList.length; i++) {
4854              var playerVars = {
4855                // 'autoplay': 1,
4856                controls: 0,
4857                // 'loop': 1,
4858                // 'playlist': movieList[i].videoId,
4859                disablekb: 1,
4860                rel: 0,
4861                playsinline: 1
4862              };
4863
4864              isSingleAndMovie = $('.js-top-carousel').find('.c-topCarousel-item').length === 1;
4865
4866              if (isSingleAndMovie) {
4867                playerVars.playlist = movieList[i].videoId;
4868                playerVars.loop = 1;
4869              }
4870
4871              var ytPlayer = new YT.Player('c-topCarousel-movieid' + movieList[i].index, {
4872                width: 640,
4873                height: 480,
4874                videoId: movieList[i].videoId,
4875                playerVars: playerVars,
4876                events: {
4877                  onReady: onPlayerReady,
4878                  onStateChange: onPlayerStateChange
4879                }
4880              });
4881              ytPlayers[movieList[i].index] = ytPlayer;
4882            }
4883          } else {
4884            sliderReady();
4885          }
4886        };
4887
4888        var sliderReady = function sliderReady(event) {
4889          if (event && $(event.target.getIframe()).attr('id') === 'c-topCarousel-movieid0') {
4890            if (isPC() && ytPlayers[0] && ytPlayers[0].playVideo) {
4891              ytPlayers[0].playVideo();
4892
4893              setTimeout(function () {
4894                $('.js-top-carousel').removeClass('is-loading');
4895                $('.js-top-carousel').addClass('is-loaded');
4896              }, 100);
4897            }
4898          } else {
4899            setTimeout(function () {
4900              $('.js-top-carousel').removeClass('is-loading');
4901
4902              setTimeout(function () {
4903                $('.js-top-carousel').addClass('is-loaded');
4904              }, 2500);
4905            }, 500);
4906          }
4907          slideStart(null, 0);
4908        };
4909
4910        var getBgMovieSize = function getBgMovieSize() {
4911          var aspectW = 16;
4912          var aspectH = 9;
4913          var videoRatio = (aspectW / aspectH).toFixed(2);
4914          var minWidth = window.innerWidth ? window.innerWidth : $(window).width();
4915          var minHeight = $(window).height() + 100;
4916          var widthRatio = minWidth / aspectW;
4917          var heightRatio = minHeight / aspectH;
4918          var size = {};
4919          if (widthRatio > heightRatio) {
4920            size.width = minWidth;
4921            size.height = Math.ceil(minWidth / videoRatio);
4922          } else {
4923            size.height = minHeight;
4924            size.width = Math.ceil(minHeight * videoRatio);
4925          }
4926          return size;
4927        };
4928
4929        var sliderInit = function sliderInit() {
4930          $('.js-top-carousel').on('init', function (event, slick) {
4931            if (!$(slick.$slides[0]).find('.type-video')[0]) {
4932              $('.js-top-carousel').removeClass('is-loading');
4933            }
4934            if ($(slick.$slides[0]).find('.type-video')[0]) {
4935              $(slick.$slides[0]).addClass('is-wait');
4936            }
4937
4938            matchMediaPC.addListener(function (e) {
4939              if (e.matches) {
4940                var index = $('.js-top-carousel').find('.slick-active').attr('data-slick-index');
4941                if (ytPlayers[index] && ytPlayers[index].playVideo) {
4942                  ytPlayers[index].playVideo();
4943                }
4944              } else {
4945                for (var i = 0; i < ytPlayers.length; i++) {
4946                  if (ytPlayers[i].stopVideo) {
4947                    ytPlayers[i].stopVideo();
4948                  }
4949                }
4950              }
4951            });
4952          });
4953
4954          $('.js-top-carousel').slick({
4955            fade: true,
4956            infinite: true,
4957            dots: true,
4958            arrows: false
4959          });
4960
4961          $('.js-top-carousel').find('.slick-dots').find('button').append('<span class="bar"></span>');
4962
4963          $('.js-top-carousel').on('beforeChange', function (event, slick, currentSlide, nextSlide) {});
4964
4965          $('.js-top-carousel').on('afterChange', function (event, slick, currentSlide) {
4966            slideStart(slick, currentSlide);
4967          });
4968        };
4969
4970        var slideStart = function slideStart(slick, currentSlide) {
4971          clearTimeout(nextTimer);
4972          clearInterval(seekbarTimer);
4973          clearTimeout(loadingTimer);
4974
4975          for (var i = 0; i < ytPlayers.length; i++) {
4976            if (ytPlayers[i].stopVideo) {
4977              ytPlayers[i].stopVideo();
4978            }
4979          }
4980
4981          var $currentSlide = $('.js-top-carousel').find('.slick-slide[data-slick-index="' + currentSlide + '"]');
4982
4983          // 動画コンテンツはすべてwait
4984          $('.js-top-carousel').find('.slick-slide').each(function () {
4985            if ($(this).find('.type-video')[0]) {
4986              if (isPC()) {
4987                $(this).addClass('is-wait');
4988              }
4989            }
4990          });
4991
4992          // 動画が再生開始したらwait解除
4993          var loop = function loop() {
4994            if (ytPlayers[currentSlide] && ytPlayers[currentSlide].getPlayerState() === YT.PlayerState.PLAYING) {
4995              clearTimeout(loadingTimer);
4996              $currentSlide.removeClass('is-wait');
4997            }
4998            loadingTimer = setTimeout(loop, 50);
4999          };
5000          if (isPC()) {
5001            loop();
5002          } else {
5003            $currentSlide.removeClass('is-wait');
5004          }
5005
5006          $('.js-top-carousel').find('.slick-dots').find('.bar').css('width', 0);
5007
5008          if (ytPlayers[currentSlide] && isPC()) {
5009            ytPlayers[currentSlide].playVideo();
5010          }
5011
5012          seekbarPlay($currentSlide, currentSlide);
5013        };
5014
5015        var seekbarPlay = function seekbarPlay($currentSlide, currentSlide) {
5016          var cnt = 0;
5017          var step = 10;
5018          var subtract = 500;
5019          var $dotsBar = $('.js-top-carousel').find('.slick-dots').find('li').eq(currentSlide).find('.bar');
5020
5021          seekbarTimer = setInterval(function () {
5022            var duration = carouselDuration;
5023
5024            if (!$currentSlide.find('.type-video')[0] || !isPC()) {
5025              cnt += 10;
5026            } else {
5027              var movieDuration = ytPlayers[currentSlide].getDuration() * 1000 - subtract;
5028              duration = carouselDuration > movieDuration ? movieDuration : carouselDuration;
5029              cnt = ytPlayers[currentSlide].getCurrentTime() * 1000;
5030            }
5031
5032            $dotsBar.css('width', cnt / duration * 100 + '%');
5033
5034            if (duration > 0 && duration < cnt) {
5035              // 再生終了0.5秒前に次ぎスライドへ移動
5036              // 関連動画表示対処
5037              clearInterval(seekbarTimer);
5038
5039              if (isSingleAndMovie) {
5040                slideStart(null, 0);
5041              } else {
5042                $('.js-top-carousel').slick('slickNext');
5043              }
5044            }
5045          }, 10);
5046        };
5047
5048        var carouselDuration = 15000;
5049        var movieList = [];
5050        var ytPlayers = [];
5051        var nextTimer;
5052        var seekbarTimer;
5053        var loadingTimer;
5054        var isSingleAndMovie = false;
5055        window.ytPlayers = ytPlayers;
5056
5057        var matchMediaPC = window.matchMedia('screen and (min-width: 1025px)');
5058
5059        if (!isPC()) {
5060          $('.js-top-carousel').removeClass('is-loading');
5061        }
5062
5063        var tag = document.createElement('script');
5064        tag.src = 'https://www.youtube.com/iframe_api';
5065        var firstScriptTag = document.getElementsByTagName('script')[0];
5066        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
5067
5068        window.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady;
5069
5070        $(function () {
5071          var movieSize = getBgMovieSize();
5072          $('.type-video').each(function () {
5073            $(this).css(movieSize);
5074          });
5075          $(window).on('resize', function (e) {
5076            var movieSize = getBgMovieSize();
5077            $('.type-video').each(function () {
5078              $(this).css(movieSize);
5079            });
5080          });
5081
5082          sliderInit();
5083        });
5084      }
5085
5086      /*
5087      if ($('.js-fullscreen')[0] && $('.js-top-carousel')[0]) {
5088      	var interval = 200;
5089      	var last_time = 0;
5090      	var mousewheelevent = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
5091      	var isMoving = false;
5092      			$('.js-fullscreen').on(mousewheelevent, function(e) {
5093      		if (isMoving) {
5094      			return false;
5095      }
5096      				if(window.innerWidth > 1024 && $('.ge-search').is(':hidden')) {
5097      			var now = new Date().getTime();
5098      			if (now - last_time < interval) return;
5099      					var delta = e.originalEvent.deltaY ? -(e.originalEvent.deltaY) : e.originalEvent.wheelDelta ? e.originalEvent.wheelDelta : -(e.originalEvent.detail);
5100      			var scrollTop = $(window).scrollTop();
5101      			var mvHeight = $('.js-top-carousel').innerHeight();
5102      			var hHeight = $('#header').innerHeight();
5103      			var mHeight = 0;
5104      			var fixHeight = mvHeight - hHeight;
5105      			if($('.ge-header-fixedMessage')[0]) {
5106      				mHeight = $('.ge-header-fixedMessage').innerHeight();
5107      }
5108      					fixHeight = fixHeight - mHeight;
5109      					if (delta < 0){
5110      				if (scrollTop + 10 < fixHeight) {
5111      					isMoving = true;
5112      					if (scrollTop >= 5) {
5113      						$('html, body').stop().animate({scrollTop: fixHeight}, 1000, 'easeOutQuad', function() {
5114      							isMoving = false;
5115      			});
5116      		} else {
5117      			$('html, body').stop().animate({scrollTop: 5}, 450, 'easeOutQuad', function() {
5118      				hHeight = $('#header').innerHeight();
5119      				fixHeight = mvHeight - hHeight - mHeight;
5120      				$('html, body').stop().animate({scrollTop: fixHeight}, 1000, 'easeOutQuad', function() {
5121      					isMoving = false;
5122      				});
5123      			});
5124      		}
5125      		last_time = now;
5126      		return false;
5127      	}
5128      } else {
5129      	if (scrollTop <= fixHeight) {
5130      		isMoving = true;
5131      		$('html, body').stop().animate({scrollTop: 0}, 1000, 'easeOutQuad', function() {
5132      			isMoving = false;
5133      		});
5134      		last_time = now;
5135      		return false;
5136      	}
5137      }
5138      }
5139      });
5140      }
5141      */
5142    });
5143
5144    $(function () {
5145      $('.c-block-fullscreenModules--overlay .img source').each(function () {
5146        var srcset = $(this).attr('srcset');
5147        $(this).closest('.img').css('background-image', 'url(' + srcset + ')').addClass('isFinish');
5148      });
5149
5150      if ($('.js-fullscreen')[0] && $('.c-block-fullscreenModules--overlay')[0] && $('.c-block-fullscreenModules--overlay-blanc-block')[0]) {
5151        var timer;
5152        var index = 0;
5153        var interval = 200;
5154        var last_time = 0;
5155        var mousewheelevent = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
5156        var isMoving = false;
5157
5158        $('.js-fullscreen').on(mousewheelevent, function (e) {
5159          if (isMoving) {
5160            return;
5161          }
5162
5163          //          if (window.innerWidth > 992 && $('.ge-search').is(':hidden')) {
5164          //            var now = new Date().getTime();
5165          //            if (now - last_time > interval) {
5166          //              var delta = e.originalEvent.deltaY
5167          //                ? -e.originalEvent.deltaY
5168          //                : e.originalEvent.wheelDelta
5169          //                ? e.originalEvent.wheelDelta
5170          //                : -e.originalEvent.detail;
5171          //              var scrollTop = $(window).scrollTop();
5172          //              var wHeight = window.innerHeight;
5173          //              var vHeight = $(
5174          //                '.c-block-fullscreenModules--overlay'
5175          //              ).innerHeight();
5176          //              var hHeight = $('#header').innerHeight();
5177          //              var vTop = $('.c-block-fullscreenModules--overlay').offset().top;
5178          ////              var nTop = $('.c-block-fullscreenModules--overlay-blanc-block')
5179          ////                .next()
5180          ////                .offset().top;
5181          //              if ($('.ge-header-fixedMessage').length) {
5182          //                var mHeight = $('.ge-header-fixedMessage').innerHeight();
5183          //                var pos = nTop + hHeight + mHeight;
5184          //              } else {
5185          //                var pos = nTop + hHeight;
5186          //              }
5187
5188          /*
5189          if (delta < 0){
5190          if(scrollTop < nTop ) {
5191          isMoving = true;
5192          $("html,body").stop().animate({scrollTop:nTop + 5},1000,"easeOutQuad", function() {
5193          isMoving = false;
5194          });
5195          return false;
5196          }
5197          } else {
5198          if(1 < scrollTop && scrollTop < pos ) {
5199          isMoving = true;
5200          $("html,body").stop().animate({scrollTop:0},1000,"easeOutQuad", function() {
5201          isMoving = false;
5202          });
5203          return false;
5204          }
5205          }
5206          */
5207          //              if (scrollTop > nTop) {
5208          //                $('.c-block-fullscreenModules--overlay')
5209          //                  .css({
5210          //                    'z-index': -2,
5211          //                    opacity: 0,
5212          //                    display: 'none'
5213          //                  })
5214          //                  .addClass('is-hidden');
5215          //              } else {
5216          //                $('.c-block-fullscreenModules--overlay')
5217          //                  .css({
5218          //                    'z-index': 0,
5219          //                    opacity: 1,
5220          //                    display: 'block'
5221          //                  })
5222          //                  .removeClass('is-hidden');
5223          //              }
5224          //            }
5225          //            last_time = now;
5226          //          }
5227        });
5228
5229        $(window).on('load scroll resize', function (e) {
5230          if ($('.js-fullscreen').length) {
5231            if (window.innerWidth > 992) {
5232              //              var scrollTop = $(window).scrollTop();
5233              //              var wHeight = window.innerHeight;
5234              //              var vHeight = $(
5235              //                '.c-block-fullscreenModules--overlay'
5236              //              ).innerHeight();
5237              //              var hHeight = $('#header').innerHeight();
5238              //              var vTop = $('.c-block-fullscreenModules--overlay').offset().top;
5239              //              var nTop = $('.c-block-fullscreenModules--overlay-blanc-block')
5240              //                .next()
5241              //                .offset().top;
5242              //              if ($('.ge-header-fixedMessage').length) {
5243              //                var mHeight = $('.ge-header-fixedMessage').innerHeight();
5244              //                var pos = nTop + hHeight + mHeight;
5245              //              } else {
5246              //                var pos = nTop + hHeight;
5247              //              }
5248              //              if (scrollTop > nTop) {
5249              //                $('.c-block-fullscreenModules--overlay')
5250              //                  .css({
5251              //                    'z-index': -2,
5252              //                    opacity: 0,
5253              //                    display: 'none'
5254              //                  })
5255              //                  .addClass('is-hidden');
5256              //              } else {
5257              //                $('.c-block-fullscreenModules--overlay')
5258              //                  .css({
5259              //                    'z-index': 0,
5260              //                    opacity: 1,
5261              //                    display: 'block'
5262              //                  })
5263              //                  .removeClass('is-hidden');
5264              //              }
5265            }
5266          }
5267        });
5268      }
5269    });
5270
5271    $(function () {
5272      var targetList, list, visiblelist;
5273
5274      function btnCheck() {
5275        list = $('.js-order-list .js-order-list-item').length, visiblelist = $('.js-order-list .js-order-list-item:visible').length;
5276        if (visiblelist >= list) {
5277          $('.js-order-btn').hide();
5278        }
5279      }
5280      $('.js-order-btn-more').off('click').on('click', function () {
5281        var i = 0,
5282            list = $('.js-order-list .js-order-list-item').length,
5283            visiblelist = $('.js-order-list .js-order-list-item:visible').length,
5284            btnT = $('.js-order-btn').offset().top,
5285            winT = $(window).scrollTop();
5286        console.log(winT);
5287        $('.js-order-list .js-order-list-item:hidden').eq(i).fadeIn();
5288        i++;
5289        btnCheck();
5290        $('html, body').animate({ scrollTop: winT }, 0, 'swing');
5291        return false;
5292      });
5293
5294      $('.js-order-btn-all').off('click').on('click', function () {
5295        var i = 0,
5296            list = $('.js-order-list .js-order-list-item').length,
5297            visiblelist = $('.js-order-list .js-order-list-item:visible').length,
5298            btnT = $('.js-order-btn').offset().top,
5299            winT = $(window).scrollTop();
5300        $('.js-order-list .js-order-list-item:hidden').fadeIn();
5301        btnCheck();
5302        var listH = $('.js-order-list'),
5303            position = btnT + listH;
5304        if (window.innerWidth > 767) {
5305          $('html, body').animate({ scrollTop: position }, 0, 'swing');
5306        }
5307        $('html, body').animate({ scrollTop: winT }, 0, 'swing');
5308        return false;
5309      });
5310    });
5311
5312    $(function () {
5313      function scrollbarStyleChange() {
5314        $(document).ready(function () {
5315          if (getDevice == 'other') {
5316            setTimeout(function () {
5317              $('.c-textarea--smartScroll').niceScroll({
5318                cursorcolor: '#D7D7D7',
5319                cursoropacitymin: 0.3,
5320                cursorwidth: 6,
5321                autohidemode: false
5322              });
5323            }, 50);
5324          } else {
5325            $('.c-textarea--smartScroll').attr('style', 'overflow-y: auto;');
5326          }
5327        });
5328      }
5329
5330      scrollbarStyleChange();
5331      $(window).on('resize', function () {
5332        if (getDevice == 'other') {
5333          scrollbarStyleChange();
5334        }
5335      });
5336    });
5337  },
5338  pdpInit: function pdpInit() {
5339    $(function () {
5340      //AUTO-REPLENISHMENT
5341      $('.js-autoreplenishment').change(function () {
5342        if ($(this).is(':checked')) {
5343          $(this).closest('li').find('.js-autoreplenishment-text').fadeIn();
5344        } else {
5345          $(this).closest('li').find('.js-autoreplenishment-text').fadeOut();
5346        }
5347      });
5348    });
5349
5350    $(function () {
5351      function videoControl(action, target) {
5352        if ($('.c-slider-rich-video').find('iframe').length) {
5353          var currentSlide = target.find('.slick-current');
5354          var iframe = $('iframe', currentSlide);
5355          var $playerWindow = iframe[0].contentWindow;
5356          $playerWindow.postMessage('{"event":"command","func":"' + action + '","args":""}', '*');
5357        }
5358      }
5359
5360      $('.c-slider-rich-video').on('afterChange', function (event, slick, currentSlide, nextSlide) {
5361        slick = $(slick.$slider);
5362        videoControl('playVideo', slick);
5363      });
5364
5365      $('.c-slider-rich-video').on('beforeChange', function (event, slick, currentSlide, nextSlide) {
5366        slick = $(slick.$slider);
5367        videoControl('stopVideo', slick);
5368      });
5369
5370      $('.c-slider-rich-video').each(function (i) {
5371        $(this).addClass('c-slider-rich-video' + i);
5372        $('.c-slider-rich-video' + i).on('init', function () {
5373          $(this).find('.c-modal-video').each(function () {
5374            var link = $(this).attr('href');
5375            console.log(link);
5376            $(this).find('.c-modal-video').magnificPopup({
5377              type: 'iframe',
5378              removalDelay: 600,
5379              fixedContentPos: true,
5380              iframe: {
5381                patterns: {
5382                  youtube: {
5383                    src: link
5384                  }
5385                }
5386              },
5387              callbacks: {
5388                open: function open() {
5389                  $('.mfp-container').addClass('row');
5390                  $.magnificPopup.instance.close = function () {
5391                    if (window.innerWidth < 992) {
5392                      var scrollpos = $('body').attr('data-scroll');
5393                      $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
5394                    }
5395                    $.magnificPopup.proto.close.call(this);
5396                  };
5397                }
5398              }
5399            });
5400          });
5401        });
5402        $('.c-slider-rich-video' + i).not('.slick-initialized').slick({
5403          centerMode: true,
5404          centerPadding: '17.5%',
5405          arrows: false,
5406          slidesToShow: 1,
5407          asNavFor: '.c-slider-rich-description' + i,
5408          variableWidth: true,
5409          responsive: [{
5410            breakpoint: 992,
5411            settings: {
5412              centerPadding: '20%',
5413              variableWidth: false
5414            }
5415          }, {
5416            breakpoint: 767,
5417            settings: {
5418              centerPadding: '10%',
5419              variableWidth: false
5420            }
5421          }]
5422        });
5423      });
5424      $('.c-slider-rich-description').each(function (i) {
5425        $(this).addClass('c-slider-rich-description' + i);
5426        $('.c-slider-rich-description' + i).not('.slick-initialized').slick({
5427          asNavFor: '.c-slider-rich-video' + i,
5428          touchMove: false
5429        });
5430      });
5431    });
5432
5433    $(function () {
5434      if ($('.c-block-shoppingDock').length) {
5435        var shoppingDockHide = function shoppingDockHide() {
5436          $('.c-block-shoppingDock').hide();
5437        };
5438
5439        var shoppingDockShow = function shoppingDockShow() {
5440          $('.c-block-shoppingDock').fadeIn();
5441        };
5442
5443        shoppingDockHide();
5444        $(window).scroll(function () {
5445          var winT = $(window).scrollTop();
5446          var winH = $(window).height();
5447          var varH = $('.c-block-shoppingDock').innerHeight();
5448          var varTop = $('.c-block-shoppingDock').offset().top;
5449          var varPos = varH + varTop;
5450          var footT = $('#footer').offset().top;
5451          if (winT > 100) {
5452            shoppingDockShow();
5453          } else {
5454            shoppingDockHide();
5455          }
5456          if (varPos >= footT) {
5457            $('.c-block-shoppingDock').addClass('nofixed');
5458          } else {
5459            $('.c-block-shoppingDock').removeClass('nofixed');
5460          }
5461        });
5462      }
5463    });
5464
5465    $(function () {
5466      function sliderMobile() {
5467        var width = window.innerWidth;
5468        if (width <= 767) {
5469          $('.c-slider-mobile').not('.slick-initialized').slick({
5470            arrows: false,
5471            dots: true
5472          });
5473        } else {
5474          $('.c-slider-mobile.slick-initialized').slick('unslick');
5475        }
5476      }
5477      sliderMobile();
5478      $(window).resize(function () {
5479        sliderMobile();
5480      });
5481
5482      var timer;
5483      function sliderMobileArrow() {
5484        var width = window.innerWidth;
5485        if (width <= 767) {
5486          $('.c-block-richcontent01-content-list').not('.slick-initialized').slick({
5487            arrows: true
5488          });
5489          sliderArrowPositionSet();
5490        } else {
5491          $('.c-block-richcontent01-content-list.slick-initialized').slick('unslick');
5492        }
5493      }
5494      function sliderArrowPositionSet() {
5495        clearTimeout(timer);
5496        timer = setTimeout(function () {
5497          $('.c-block-richcontent01-content-list').each(function () {
5498            var $_t = $(this);
5499            var $photo = $_t.find('.slick-active').find('.c-block-richcontent01-content-list-item').find('.photo');
5500            var $arrow = $_t.find('.slick-arrow');
5501            if ($arrow[0] && $photo[0]) {
5502              var top = $photo.position().top;
5503              var height = $photo.height();
5504              var center = top + height / 2;
5505              $arrow.css({
5506                top: center
5507              });
5508            }
5509          });
5510        }, 100);
5511      }
5512      sliderMobileArrow();
5513      $(window).on('load', function () {
5514        if (window.innerWidth <= 767) {
5515          sliderArrowPositionSet();
5516        }
5517      });
5518      $(window).on('resize', function () {
5519        sliderMobileArrow();
5520      });
5521    });
5522    $(function () {
5523      $('.c-slider-fullscreenModulesImage').not('.slick-initialized').slick({
5524        asNavFor: '.c-slider-fullscreenModulesList',
5525        arrows: false
5526      });
5527      $('.c-slider-fullscreenModulesList').not('.slick-initialized').slick({
5528        asNavFor: '.c-slider-fullscreenModulesImage'
5529      });
5530
5531      if ($('.c-slider-products-vertical').length > 0) {
5532        $('.c-slider-products-landscape').not('.slick-initialized').slick({
5533          asNavFor: '.c-slider-products-vertical',
5534          arrows: false,
5535          responsive: [{
5536            breakpoint: 991,
5537            settings: {
5538              dots: true
5539            }
5540          }]
5541        });
5542      } else {
5543        $('.c-slider-products-landscape').not('.slick-initialized').slick();
5544      }
5545    });
5546    $(function () {
5547      $('.c-slider-products-vertical').on('init', function () {
5548        $('.c-modal-img').magnificPopup({
5549          type: 'image',
5550          removalDelay: 500,
5551          fixedContentPos: true,
5552          callbacks: {
5553            open: function open() {
5554              $('.mfp-container').addClass('row');
5555              $.magnificPopup.instance.close = function () {
5556                if (window.innerWidth < 992) {
5557                  var scrollpos = $('body').attr('data-scroll');
5558                  $('html,body').removeAttr('data-scroll').removeClass('is-noscroll').css({ top: 0 }).scrollTop(scrollpos);
5559                }
5560                $.magnificPopup.proto.close.call(this);
5561              };
5562            }
5563          }
5564        });
5565        if ($(this).find('.c-block-shopingmodal-change-image').length < 5) {
5566          $(this).addClass('is-nobutton');
5567        }
5568      });
5569      if ($('.c-slider-products-vertical').hasClass('is-standard')) {
5570        var thumbnail = 3;
5571      } else {
5572        var thumbnail = 5;
5573      }
5574      $('.c-slider-products-vertical').not('.slick-initialized').slick({
5575        asNavFor: '.c-slider-products-landscape',
5576        vertical: true,
5577        verticalSwiping: true,
5578        slidesToShow: thumbnail,
5579        focusOnSelect: true
5580      });
5581      $('.c-slider-products-landscape').on('afterChange', function (event, slick, currentSlide) {
5582        $('.c-slider-products-vertical').find('.slick-current').removeClass('slick-current');
5583        $('.c-slider-products-vertical').find('.slick-slide').eq(currentSlide).addClass('slick-current');
5584      });
5585    });
5586
5587    $(function () {
5588      //SHARE
5589      $('.c-block-share-toggle').off('click').on('click', function () {
5590        if ($(this).closest('.c-block-share').find('.c-block-share-box').is(':hidden')) {
5591          $(this).closest('.c-block-share').find('.c-block-share-box').fadeIn().removeClass('mfp-hide');
5592        } else {
5593          $(this).closest('.c-block-share').find('.c-block-share-box').fadeOut(function () {
5594            $(this).addClass('mfp-hide');
5595          });
5596        }
5597        if (window.innerWidth >= 767) {
5598          return false;
5599        }
5600      });
5601      $('.c-block-share-close').off('click').on('click', function () {
5602        $(this).closest('.c-block-share').find('.c-block-share-box').fadeOut(function () {
5603          $(this).addClass('mfp-hide');
5604        });
5605        return false;
5606      });
5607      $(document).on('click touchstart', function (e) {
5608        if (!$(e.target).closest('.c-block-share-box').length) {
5609          if (window.innerWidth >= 767) {
5610            if ($('.c-block-share-box').is(':visible')) {
5611              $('.c-block-share-box').fadeOut(function () {
5612                $(this).addClass('mfp-hide');
5613              });
5614            }
5615          }
5616        }
5617      });
5618      //textarea count
5619      $('.c-textarea').keyup(function () {
5620        var txtcount = $(this).val().length,
5621            txtlimit = $(this).attr('maxlength'),
5622            txtDown = txtlimit - txtcount;
5623        $(this).closest('.c-textarea-box').find('.c-textarea-count:not(.js-countDown) .countnow').text(txtcount);
5624        $(this).closest('.c-textarea-box').find('.c-textarea-count.js-countDown .countlimit').text(txtDown);
5625        if (txtcount == 0) {
5626          $(this).closest('.c-textarea-box').find('.c-textarea-count .countnow').text('0');
5627        }
5628        if (txtcount >= txtlimit) {
5629          $(this).closest('.c-textarea-box').find('.c-textarea-count .countnow').text(txtlimit);
5630        }
5631      });
5632      // Cut out character string of textarea when above limitting text is submited.
5633      $('button#sendBtn').on('mousedown', function () {
5634        var textareaElm = $('.c-textarea');
5635        if (textareaElm.length > 0 && textareaElm.val().length > textareaElm[0].dataset.characterLimit) {
5636          textareaElm.val(textareaElm.val().substr(0, textareaElm[0].dataset.characterLimit));
5637        }
5638      });
5639
5640      //AUTO-REPLENISHMENT
5641      $('.js-autoreplenishment').change(function () {
5642        if ($(this).is(':checked')) {
5643          $(this).closest('li').find('.js-autoreplenishment-text').fadeIn();
5644        } else {
5645          $(this).closest('li').find('.js-autoreplenishment-text').fadeOut();
5646        }
5647      });
5648    });
5649    $(function () {
5650      $('.c-underColumn-toggle >a ').on('click', function () {
5651        var main = $(this).closest('.c-underColumn').find('.c-underColumn-main'),
5652            side = $(this).closest('.c-underColumn').find('.c-underColumn-side');
5653        if (window.innerWidth < 767 || side.is(':hidden')) {
5654          main.hide();
5655          side.show();
5656        } else {
5657          main.show();
5658          side.hide();
5659        }
5660        return false;
5661      });
5662    });
5663    $(function () {
5664      $('.c-dlist_01 dt').off('click').on('click', function () {
5665        if (window.innerWidth < 991) {
5666          if ($(this).next('dd').is(':hidden')) {
5667            $(this).addClass('is-active');
5668            $(this).next('dd').slideDown();
5669          } else {
5670            $(this).removeClass('is-active');
5671            $(this).next('dd').slideUp();
5672          }
5673        }
5674        return false;
5675      });
5676      $('.c-dlist-dropdown-link-toggle').on('click', function () {
5677        if ($(this).parent().next('dd').is(':hidden')) {
5678          $(this).parent().addClass('is-active');
5679          $(this).parent().next('dd').slideDown();
5680        } else {
5681          $(this).parent().removeClass('is-active');
5682          $(this).parent().next('dd').slideUp();
5683        }
5684        return false;
5685      });
5686      $('.c-dlist-dropdown > dt').on('click', function () {
5687        if ($(this).next('dd').is(':hidden')) {
5688          $(this).addClass('is-active');
5689          $(this).next('dd').slideDown();
5690        } else {
5691          $(this).removeClass('is-active');
5692          $(this).next('dd').slideUp();
5693        }
5694        return false;
5695      });
5696    });
5697    $(function () {
5698      if ($('.c-block-shoppingDock').length) {
5699        var shoppingDockHide = function shoppingDockHide() {
5700          $('.c-block-shoppingDock').hide();
5701        };
5702
5703        var shoppingDockShow = function shoppingDockShow() {
5704          $('.c-block-shoppingDock').fadeIn();
5705        };
5706
5707        shoppingDockHide();
5708        $(window).scroll(function () {
5709          var winT = $(window).scrollTop();
5710          var winH = $(window).height();
5711          var varH = $('.c-block-shoppingDock').innerHeight();
5712          var varTop = $('.c-block-shoppingDock').offset().top;
5713          var varPos = varH + varTop;
5714          var footT = $('#footer').offset().top;
5715          if (winT > 100) {
5716            shoppingDockShow();
5717          } else {
5718            shoppingDockHide();
5719          }
5720          if (varPos >= footT) {
5721            $('.c-block-shoppingDock').addClass('nofixed');
5722          } else {
5723            $('.c-block-shoppingDock').removeClass('nofixed');
5724          }
5725        });
5726      }
5727    });
5728
5729    $(function () {
5730      if ($('.c-block-lineBox').length) {
5731        var t = function t() {
5732          $('.c-block-lineBox-wrapper').find('.c-block-lineBox').each(function (e) {
5733            var t = $(this).offset().top,
5734                i = ($(this).index(), $(this).children('.c-block-lineBox-circle').offset().top);
5735            o.push(t), n.push(i);
5736          }), $('.c-block-lineBox-circleMove').css('top', n[0] + 'px');
5737        };
5738
5739        var e,
5740            o = [],
5741            n = [],
5742            s = $(window).scrollTop(),
5743            r = 0;
5744
5745        t(), $(window).on('load resize', function () {
5746          t();
5747        }), $(window).on('scroll', function () {
5748          i();
5749        });
5750        var i = function i() {
5751          clearTimeout(e), e = setTimeout(function () {
5752            var e = $(window).scrollTop(),
5753                t = $(window).height(),
5754                i = ($('#header').innerHeight(), []);
5755            $('.c-block-lineBox').each(function (e) {
5756              var t = $(this);
5757              i[e] = t.find('.c-block-lineBox-circle').offset().top;
5758            }), e < s ? i[r - 1] >= e && ($('.c-block-lineBox-circleMove').stop().css('top', i[r - 1] + 'px'), $('.c-block-lineBox').children('.c-block-lineBox-circle').removeClass('is-active is-first'), $('.c-block-lineBox').eq(r - 1).children('.c-block-lineBox-circle').addClass('is-active'), 0 != r && r--) : i[r + 1] < e + t - t / 5 && ($('.c-block-lineBox-circleMove').stop().css('top', i[r + 1] + 'px'), $('.c-block-lineBox').children('.c-block-lineBox-circle').removeClass('is-active is-first'), $('.c-block-lineBox').eq(r + 1).children('.c-block-lineBox-circle').addClass('is-active'), r++), s = e;
5759          }, 30);
5760        };
5761      }
5762    }), $(function () {
5763      $('.js-giftcardbalancemodal-send').on('click', function () {
5764        if ($('.c-block-giftcardbalance-block-send').length) {
5765          $('.c-block-giftcardbalance-block-send').hide();
5766          $('.c-block-giftcardbalance-block-receive').show();
5767        }
5768        return false;
5769      });
5770    });
5771
5772    // JavaScript Document
5773    $(function () {
5774      $(document).on('click', "[href^='#']:not(.c-modal)" + "[href!='#']", scroll_func);
5775      $(document).on('click', '#pageTop', function () {
5776        scroll_func('top');
5777      });
5778    });
5779
5780    $(function () {
5781      $("[href^='#']:not(.c-modal)" + "[href!='#']").on('click', function () {
5782        var headerH = $('.ge-header').height();
5783        var messageH = $('.ge-header-fixedMessage').height();
5784        var headerHight = headerH + messageH;
5785        var href = $(this).attr('href');
5786        var target = $(href == '#' || href == '' ? 'html' : href);
5787        if (target[0]) {
5788          var position = target.offset().top - headerHight;
5789          // $('html, body').animate({ scrollTop: position }, 550, 'swing');
5790          return false;
5791        }
5792      });
5793    });
5794
5795    /* ページTOPへスクロール */
5796    var scroll_func = function scroll_func(top) {
5797      if (top == 'top') {
5798        $('html,body').scrollTop(800).stop().animate({ scrollTop: 0 }, 'slow', 'easeOutQuart');
5799      } else {
5800        var $target = $($(this).attr('href'));
5801        if ($target[0]) {
5802          $('html,body').animate({ scrollTop: $target.offset().top }, 'slow', 'easeOutQuart');
5803        }
5804      }
5805      return false;
5806    };
5807    /* /ページTOPへスクロール */
5808
5809    var loading_func = function loading_func(mode) {
5810      if (mode == 'on') {
5811        $('.modLoading').remove();
5812        $('body').append('<div class="modLoading"><i class="fa fa-spinner fa-spin"></i></div>');
5813      }
5814      if (mode == 'off') {
5815        $('.modLoading').fadeOut(function () {
5816          $(this).remove();
5817        });
5818      }
5819    };
5820
5821    //modLoadingに対するBack Forward Cache 対策
5822    window.onpageshow = function (event) {
5823      if (event.persisted) {
5824        var elements = document.getElementsByClassName('modLoading');
5825        var length = elements.length;
5826        if (length) {
5827          window.location.reload();
5828        }
5829      }
5830    };
5831
5832    $(function () {
5833      function btnCheck() {
5834        list = $('.js-order-list .js-order-list-item').length, visiblelist = $('.js-order-list .js-order-list-item:visible').length;
5835        if (visiblelist >= list) {
5836          $('.js-order-btn').hide();
5837        }
5838      }
5839      $('.js-order-btn-more').on('click', function () {
5840        var i = 0,
5841            list = $('.js-order-list .js-order-list-item').length,
5842            visiblelist = $('.js-order-list .js-order-list-item:visible').length;
5843        $('.js-order-list .js-order-list-item:hidden').eq(i).fadeIn();
5844        i++;
5845        btnCheck();
5846        return false;
5847      });
5848
5849      $('.js-order-btn-all').on('click', function () {
5850        var i = 0,
5851            list = $('.js-order-list .js-order-list-item').length,
5852            visiblelist = $('.js-order-list .js-order-list-item:visible').length;
5853        $('.js-order-list .js-order-list-item:hidden').fadeIn();
5854        btnCheck();
5855        return false;
5856      });
5857    });
5858    $(function () {
5859      if ($('#topics-video').length) {
5860        var resizeMovie = function resizeMovie() {
5861          var adjustWidth = $(window).width();
5862          var adjustHeight = $(window).height();
5863          if (adjustHeight > adjustWidth / movieRatio) {
5864            adjustWidth = adjustHeight * movieRatio;
5865          }
5866          $('#topics-video').css({
5867            width: adjustWidth * 1.4,
5868            height: adjustWidth / movieRatio * 1.4
5869          });
5870          // console.log(w, h, mw, mh);
5871        };
5872
5873        var onPlayerReady = function onPlayerReady(event) {
5874          $('#topics-video').fadeIn(1000);
5875          player.setVolume(0);
5876        };
5877
5878        var onPlayerStateChange = function onPlayerStateChange(event) {
5879          if (event.data == YT.PlayerState.ENDED) {
5880            player.playVideo();
5881            player.setVolume(0);
5882          }
5883        };
5884
5885        $('body').append('<script src="https://www.youtube.com/iframe_api">');
5886        $('#topics-video').hide();
5887        $(window).on('load resize', function () {
5888          if (navigator.userAgent.indexOf(/iPhone/) > 0 || navigator.userAgent.indexOf(/iPad/) > 0 || navigator.userAgent.indexOf(/Android/) > 0 || navigator.userAgent.indexOf('Mobile') > 0) {
5889            $('#topics-video').remove();
5890          }
5891        });
5892        var player;
5893        var movieRatio = 16 / 9;
5894
5895        resizeMovie();
5896        $(window).resize(resizeMovie);
5897
5898        var onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() {
5899          var _playerVars;
5900
5901          player = new YT.Player('topics-video', {
5902            videoId: '2uK6I6R6yVw',
5903            playerVars: (_playerVars = {
5904              autoplay: 1,
5905              version: 3,
5906              controls: 0,
5907              playlist: 'Fm-DQAE5vWM',
5908              enablejsapi: 1,
5909              iv_load_policy: 3,
5910              modestbranding: 1,
5911              disablekb: 1,
5912              showinfo: 0,
5913              rel: 0,
5914              start: 0
5915            }, _defineProperty(_playerVars, 'iv_load_policy', 3), _defineProperty(_playerVars, 'start', 6), _playerVars),
5916            events: {
5917              onReady: onPlayerReady,
5918              onStateChange: onPlayerStateChange
5919            }
5920          });
5921        };
5922        window.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady;
5923      }
5924    });
5925
5926    $(function () {
5927      $(document).on('load scroll', function () {
5928        if ($('.synactif-fixedNavi').length) {
5929          var scroll = $(window).scrollTop();
5930          if (scroll >= 1) {
5931            $('.synactif-fixedNavi').show();
5932          } else {
5933            $('.synactif-fixedNavi').hide();
5934          }
5935        }
5936      });
5937      $('.synactif-fixedNavi-list-item-dropdown-toggle').off('click').on('click', function () {
5938        if ($(this).parent('.synactif-fixedNavi-list-item-text').next('.synactif-fixedNavi-list-item-dropdown').is(':hidden')) {
5939          $(this).addClass('is-active');
5940          $(this).parent('.synactif-fixedNavi-list-item-text').next('.synactif-fixedNavi-list-item-dropdown').slideDown();
5941        } else {
5942          $(this).removeClass('is-active');
5943          $(this).parent('.synactif-fixedNavi-list-item-text').next('.synactif-fixedNavi-list-item-dropdown').slide
5943Up();
5944        }
5945        return false;
5946      });
5947      $('.synactif-fixedNavi-toggle a').off().on('click', function () {
5948        if ($(this).closest('.synactif-fixedNavi').find('.synactif-fixedNavi-list').is(':hidden')) {
5949          $(this).closest('.synactif-fixedNavi').find('.synactif-fixedNavi-list').slideDown();
5950        } else {
5951          $(this).closest('.synactif-fixedNavi').find('.synactif-fixedNavi-list').slideUp();
5952        }
5953        return false;
5954      });
5955      $(document).on('click', function (e) {
5956        if (!$(e.target).closest('.synactif-fixedNavi').length && window.innerWidth < 992) {
5957          $('.synactif-fixedNavi-list').fadeOut();
5958        }
5959      });
5960    });
5961
5962    $(function () {
5963      $('.js-appointment-next').on('click', function () {
5964        if ($(this).closest('.appointment-block').next('.appointment-block').is(':hidden')) {
5965          $(this).closest('.appointment-block').hide();
5966          $(this).closest('.appointment-block').next('.appointment-block').show();
5967          var headerH = $('.ge-header').height();
5968          var position = $(this).closest('.appointment-block').next('.appointment-block').offset().top - headerH;
5969          $('html, body').animate({ scrollTop: position }, 550, 'swing');
5970        }
5971        return false;
5972      });
5973      $('.js-appointment-select').on('change click', function () {
5974        if ($(this).closest('.appointment-block').next('.appointment-block').is(':hidden')) {
5975          $(this).closest('.appointment-block').hide();
5976          $(this).closest('.appointment-block').next('.appointment-block').show();
5977          var headerH = $('.ge-header').height();
5978          var position = $(this).closest('.appointment-block').next('.appointment-block').offset().top - headerH;
5979          $('html, body').animate({ scrollTop: position }, 550, 'swing');
5980        }
5981      });
5982      $('.js-appointment-prev').on('click', function () {
5983        if ($(this).closest('.appointment-block').prev('.appointment-block').is(':hidden')) {
5984          $(this).closest('.appointment-block').hide();
5985          $(this).closest('.appointment-block').prev('.appointment-block').show();
5986          var headerH = $('.ge-header').height();
5987          var position = $(this).closest('.appointment-block').prev('.appointment-block').offset().top - headerH;
5988          $('html, body').animate({ scrollTop: position }, 550, 'swing');
5989        }
5990        return false;
5991      });
5992
5993      $('.js-appointment-calendar .day:not(.dayOff)').on('click', function () {
5994        $('.js-appointment-calendar .day:not(.dayOff)').removeClass('is-active');
5995        $(this).addClass('is-active');
5996        if ($('.js-appointment-time').is(':hidden')) {
5997          $('.js-appointment-time').show();
5998        }
5999      });
6000    });
6001
6002    $(function () {
6003      $('.js-checkout-ApplyGiftcard-toggle').on('click', function () {
6004        $(this).hide();
6005        $(this).next('a').show();
6006        $('.js-checkout-ApplyGiftcard-box').slideDown();
6007        return false;
6008      });
6009    });
6010  },
6011  clockInit: function clockInit() {
6012    $(function () {
6013      $('#clockArea').each(function () {
6014        function showClock() {
6015          var nowTime = new Date();
6016          var nowHour = nowTime.getHours();
6017          // padding 0
6018          var nowMin = ('0' + nowTime.getMinutes()).slice(-2);
6019          var nowSec = ('0' + nowTime.getSeconds()).slice(-2);
6020          $('#clockArea').text(nowHour + ':' + nowMin + ':' + nowSec);
6021        }
6022
6023        setInterval(showClock, 1000);
6024
6025        // do only once if selector exists.
6026        return false;
6027      });
6028    });
6029  }
6030};
6031
6032function matchHeightProducts() {
6033  if ($('.c-product-cards-step-header').length) {
6034    $('.c-product-cards-list .c-product-cards-step-header').matchHeight();
6035  }
6036  if ($('.c-product-cards-list .c-product-cards-list-item').length) {
6037    $('.c-product-cards-list .c-product-cards-list-item').matchHeight();
6038  }
6039}
6040
6041module.exports = design;
6042
6043},{}],12:[function(require,module,exports){
6044'use strict';
6045
6046var ajax = require('./ajax'),
6047    util = require('./util'),
6048    _ = require('lodash'),
6049    imagesLoaded = require('imagesloaded');
6050
6051var dialog = {
6052  /**
6053   * @function
6054   * @description Appends a dialog to a given container (target)
6055   * @param {Object} params  params.target can be an id selector or an jquery object
6056   */
6057  create: function create(params) {
6058    var $target, id;
6059
6060    if (_.isString(params.target)) {
6061      if (params.target.charAt(0) === '#') {
6062        $target = $(params.target);
6063      } else {
6064        $target = $('#' + params.target);
6065      }
6066    } else if (params.target instanceof jQuery) {
6067      $target = params.target;
6068    } else {
6069      $target = $('#dialog-container');
6070    }
6071
6072    // if no element found, create one
6073    if ($target.length === 0) {
6074      if ($target.selector && $target.selector.charAt(0) === '#') {
6075        id = $target.selector.substr(1);
6076        $target = $('<div>').attr('id', id).addClass('dialog-content').appendTo('body');
6077      }
6078    }
6079
6080    // create the dialog
6081    this.$container = $target;
6082    this.$container.dialog(_.merge({}, this.settings, params.options || {}));
6083  },
6084  /**
6085   * @function
6086   * @description Opens a dialog using the given url (params.url) or html (params.html)
6087   * @param {Object} params
6088   * @param {Object} params.url should contain the url
6089   * @param {String} params.html contains the html of the dialog content
6090   */
6091  open: function open(params) {
6092    // close any open dialog
6093    this.close();
6094    this.create(params);
6095    this.replace(params);
6096  },
6097  /**
6098   * @description populate the dialog with html content, then open it
6099   **/
6100  openWithContent: function openWithContent(params) {
6101    var content, position, callback;
6102
6103    if (!this.$container) {
6104      return;
6105    }
6106    content = params.content || params.html;
6107    if (!content) {
6108      return;
6109    }
6110    this.$container.empty().html(content);
6111    if (!this.$container.dialog('isOpen')) {
6112      this.$container.dialog('open');
6113    }
6114
6115    if (params.options) {
6116      position = params.options.position;
6117    }
6118    if (!position) {
6119      position = this.settings.position;
6120    }
6121    imagesLoaded(this.$container).on('done', function () {
6122      this.$container.dialog('option', 'position', position);
6123    }.bind(this));
6124
6125    callback = typeof params.callback === 'function' ? params.callback : function () {};
6126    callback();
6127  },
6128  /**
6129   * @description Replace the content of current dialog
6130   * @param {object} params
6131   * @param {string} params.url - If the url property is provided, an ajax call is performed to get the content to replace
6132   * @param {string} params.html - If no url property is provided, use html provided to replace
6133   */
6134  replace: function replace(params) {
6135    if (!this.$container) {
6136      return;
6137    }
6138    if (params.url) {
6139      params.url = util.appendParamToURL(params.url, 'format', 'ajax');
6140      ajax.load({
6141        url: params.url,
6142        data: params.data,
6143        callback: function (response) {
6144          params.content = response;
6145          this.openWithContent(params);
6146        }.bind(this)
6147      });
6148    } else if (params.html) {
6149      this.openWithContent(params);
6150    }
6151  },
6152  /**
6153   * @function
6154   * @description Closes the dialog
6155   */
6156  close: function close() {
6157    if (!this.$container) {
6158      return;
6159    }
6160    this.$container.dialog('close');
6161  },
6162  exists: function exists() {
6163    return this.$container && this.$container.length > 0;
6164  },
6165  isActive: function isActive() {
6166    return this.exists() && this.$container.children.length > 0;
6167  },
6168  settings: {
6169    autoOpen: false,
6170    height: 'auto',
6171    modal: true,
6172    overlay: {
6173      opacity: 0.5,
6174      background: 'black'
6175    },
6176    resizable: false,
6177    title: '',
6178    width: '800',
6179    close: function close() {
6180      $(this).dialog('close');
6181    },
6182    position: {
6183      my: 'center',
6184      at: 'center',
6185      of: window,
6186      collision: 'flipfit'
6187    }
6188  }
6189};
6190
6191module.exports = dialog;
6192
6193},{"./ajax":1,"./util":77,"imagesloaded":110,"lodash":111}],13:[function(require,module,exports){
6194'use strict';
6195
6196var util = require('./util');
6197
6198function countrySelector() {
6199  $('.countries-selector').on('change', function (e) {
6200    e.preventDefault();
6201
6202    var countrySelected = $(this).find(':selected').text().toLowerCase();
6203    if (countrySelected == 'us' || countrySelected == 'united states') {
6204      return false;
6205    }
6206
6207    var countryUrl = countrySelected.indexOf('other') >= 0 ? Urls.countrySelectorUrl : $(this).find(':selected').val();
6208
6209    if (window.open(countryUrl, '_blank') == null) {
6210      document.location.href = countryUrl;
6211    }
6212  });
6213}
6214
6215exports.countrySelector = countrySelector;
6216
6217},{"./util":77}],14:[function(require,module,exports){
6218'use strict';
6219
6220var ajax = require('./ajax'),
6221    util = require('./util');
6222/**
6223 * @function
6224 * @description Load details to a given gift certificate
6225 * @param {String} id The ID of the gift certificate
6226 * @param {Function} callback A function to called
6227 */
6228exports.checkBalance = function (id, pin, callback) {
6229  // load gift certificate details
6230  ajax.getJson({
6231    url: util.appendParamsToUrl(Urls.giftCardCheckBalance, {
6232      giftCertCode: id,
6233      giftCertPIN: pin
6234    }),
6235    callback: callback
6236  });
6237};
6238
6239},{"./ajax":1,"./util":77}],15:[function(require,module,exports){
6240'use strict';
6241
6242var util = require('./util');
6243var giftcert = require('./giftcert');
6244var modal = require('./modal').global;
6245var validator = require('./validator');
6246
6247function updateCart() {
6248  $('#AddToBasketButton').on('click', function () {
6249    $('#GiftCertificateForm').submit();
6250  });
6251}
6252
6253exports.init = function () {
6254  $('.gift-cert-edit').on('click', function (e) {
6255    e.preventDefault();
6256
6257    modal.addCustomClass('edit-modal quickview-modal');
6258    modal.renderByUrl($(this).attr('href'));
6259    modal.setCallback(function () {
6260      updateCart();
6261      giftcert.init();
6262      util.limitCharacters();
6263      validator.initForm('form#GiftCertificateForm');
6264    });
6265  });
6266};
6267
6268exports.initModal = function () {
6269  updateCart();
6270  giftcert.init();
6271  util.limitCharacters();
6272  validator.initForm('form#GiftCertificateForm');
6273};
6274
6275}
6275,{"./giftcert":16,"./modal":24,"./util":77,"./validator":78}],16:[function(require,module,exports){
6276'use strict';
6277
6278var ajax = require('./ajax'),
6279    minicart = require('./minicart'),
6280    util = require('./util'),
6281    design = require('./design');
6282
6283var setAddToCartHandler = function setAddToCartHandler(e) {
6284  e.preventDefault();
6285  if ($('.termsandconditions').hasClass('error')) {
6286    return false;
6287  }
6288
6289  if ($('input').hasClass('is-error') || $('textarea').hasClass('is-error')) {
6290    return false;
6291  }
6292
6293  setGiftCard();
6294
6295  var form = $(this).closest('form');
6296  var options = {
6297    url: util.ajaxUrl(form.attr('action')),
6298    method: 'POST',
6299    cache: false,
6300    data: form.serialize()
6301  };
6302
6303  $.ajax(options).done(function (response) {
6304    if (response.success) {
6305      ajax.load({
6306        url: Urls.minicartGC,
6307        data: {
6308          lineItemId: response.result.lineItemId
6309        },
6310        callback: function callback(response) {
6311          minicart.show(response);
6312          form.find('input,textarea').val('');
6313          setGiftCard();
6314          design.dropdownToggleInit();
6315        }
6316      });
6317
6318      if (response.result.device === 'mobile') {
6319        var popup = new Foundation.Reveal($('#giftcertpurchase-notification'));
6320
6321        popup.open();
6322
6323        setTimeout(function () {
6324          popup.close();
6325        }, 3000);
6326      }
6327    }
6328  }).fail(function (xhr, textStatus) {
6329    // failed
6330    if (textStatus === 'parsererror') {
6331      return window.alert(Resources.BAD_RESPONSE);
6332    }
6333
6334    window.alert(Resources.SERVER_CONNECTION_ERROR);
6335  });
6336};
6337
6338function initializeEvents() {
6339  design.selectGiftInit();
6340
6341  $('.c-block-shopingmodal .c-list-color').on('colorSelect', function () {
6342    setGiftCard();
6343  });
6344}
6345
6346function setGiftCard() {
6347  var imageSource = $('.c-block-shopingmodal .c-list-color a .is-current').find('img').attr('src') || $('.img-source input').val();
6348  var imageAlt = $('.c-block-shopingmodal .c-list-color a .is-current').find('img').attr('alt') || $('.img-alt input').val();
6349
6350  setGiftCardImage(imageSource);
6351  setGiftCardName(imageAlt);
6352}
6353
6354function setGiftCardImage(imageSource) {
6355  $('#GiftCertificateForm .imagesource').val(imageSource);
6356}
6357
6358function setGiftCardName(imageAlt) {
6359  $('#GiftCertificateForm .imagealt').val(imageAlt);
6360}
6361
6362exports.init = function () {
6363  $('#AddToBasketButton').on('click', setAddToCartHandler);
6364
6365  initializeEvents();
6366};
6367
6368},{"./ajax":1,"./design":11,"./minicart":23,"./util":77}],17:[function(require,module,exports){
6369'use strict';
6370
6371(function ($) {
6372  var inputSelector = '.entry-mypage_member-edit input';
6373  var originalId = [];
6374  var registrationId = [];
6375  var cancellationId = [];
6376  $(function () {
6377    var rule = {
6378      hankaku: true,
6379      digits: true,
6380      length: 13,
6381      notDuplicate: inputSelector
6382    };
6383
6384    $('.entry-mypage_member-input-field input[type="tel"]').each(function () {
6385      originalId.push($(this).val());
6386    });
6387
6388    // validate
6389    var validatorForm = $('#editForm').validate({
6390      onkeyup: false,
6391      errorClass: 'is-error',
6392      errorElement: 'li',
6393      wrapper: 'ul',
6394      errorPlacement: function errorPlacement(error, element) {
6395        // insert error message
6396        if ($(element).parent('.c-input-group').length == 1) {
6397          if ($(element).parent().parent().find('.c-text-error').length == 0) {
6398            error.insertAfter($(element).parent());
6399          } else {
6400            $(element).parent().parent().find('.c-text-error').remove();
6401            error.insertAfter($(element).parent());
6402          }
6403        } else {
6404          if ($(element).parent().find('.c-text-error').length == 0) {
6405            if ($(element).parents('form.news-letter-form .ge-footer-connectWithUs-check').length) {
6406              error.insertAfter($(element).next());
6407            } else {
6408              error.insertAfter($(element));
6409            }
6410          } else {
6411            $(element).parent().find('.c-text-error').remove();
6412            error.insertAfter($(element));
6413          }
6414        }
6415        // add class error for ul tag
6416        if ($(element).closest($('form.news-letter-form')).length == 1) {
6417          error.addClass('c-text-error');
6418        } else {
6419          error.addClass('c-text-error c-text-error--simple');
6420        }
6421        // add class error for label
6422        error.parent().find('.c-input-label').first().addClass('is-error');
6423        // clear error message when has `no-display-error` attribute in the field
6424        if (error.parent().find('input[no-display-error]').length > 0) {
6425          error.remove();
6426        }
6427      },
6428      ignore: ':hidden, .ignore'
6429    });
6430    // add rule
6431    $(inputSelector).each(function (_, element) {
6432      $(element).rules('add', rule);
6433    });
6434
6435    /**
6436     * add method
6437     */
6438
6439    // 文字数
6440    jQuery.validator.addMethod('length', function (value, element, length) {
6441      return value.trim() === '' || value.length === length;
6442    }, '{0}文字で入力してください');
6443
6444    // 半角
6445    function isHankaku(value) {
6446      return (/^[0-9a-zA-Z -/:-@\\[-~ヲ-゚ー]+$/.test(value)
6447      );
6448    }
6449    jQuery.validator.addMethod('hankaku', function (value) {
6450      return value.trim() === '' || isHankaku(value);
6451    }, '半角文字で入力してください');
6452
6453    // 重複
6454    jQuery.validator.addMethod('notDuplicate', function (value, element, param) {
6455      if ($(element).val() === '') {
6456        return true;
6457      }
6458
6459      var that = this;
6460      var bool = true;
6461      $(param).each(function () {
6462        if (element === $(this).get(0)) {
6463          // 自身との同一チェックは行わない
6464          return true;
6465        }
6466        bool = bool && !$.validator.methods.equalTo.call(that, value, element, this);
6467      });
6468
6469      return bool;
6470    }, '値が重複しています');
6471
6472    // 登録解除
6473    $('.entry-mypage_member-edit').on('click', '.entry-formgroup_button--remove', function () {
6474      var input = $(this).closest('.entry-mypage_member_input').find('.entry-formgroup_input');
6475      var correctMemberIdRegex = new RegExp(/^[0-9]{13}$/);
6476      if (correctMemberIdRegex.test(input.val()) && cancellationId.indexOf(input.val()) == -1) {
6477        cancellationId.push(input.val());
6478        input.val('');
6479      } else {
6480        registrationId.length = 0;
6481        return false;
6482      }
6483
6484      $('.entry-mypage_member-edit .entry-formgroup_input').each(function () {
6485        validatorForm.element(this);
6486      });
6487    });
6488
6489    // 会員ID入力欄を追加
6490    //        var inputTemplate = $('#inputTemplate').html()
6491    //        $('.entry-mypgae_member-add')
6492    //            .click(function() {
6493    //                var id = $('.entry-mypage_confirm-title').length + 1
6494    //                    // 追加上限99個まで
6495    //                if (id > 99) {
6496    //                    return
6497    //                }
6498    //                $(inputTemplate.replace(/{{num}}/g, id))
6499    //                    .appendTo('.entry-mypage_member-edit')
6500    //                    .find('.entry-formgroup_input')
6501    //                    .focus()
6502    //                    .rules('add', rule)
6503    //            })
6504  });
6505
6506  // Get registration and cancellation id
6507  $('#to-confirm').on('click', function () {
6508    $('.entry-mypage_member-input-field input[type="tel"]').each(function () {
6509      var id = $(this).val();
6510      if (id != '' && $.inArray(id, originalId) == -1) {
6511        var correctMemberIdRegex = new RegExp(/^[0-9]{13}$/);
6512        if (correctMemberIdRegex.test(id) && registrationId.indexOf(id) == -1) {
6513          registrationId.push($(this).val());
6514        } else {
6515          registrationId.length = 0;
6516          return false;
6517        }
6518      }
6519    });
6520    $('input[id$="memberinquiry_registrationid"]').val(JSON.stringify(registrationId));
6521    $('input[id$="memberinquiry_cancellationid"]').val(JSON.stringify(cancellationId));
6522  });
6523})(window.jQuery);
6524
6525},{}],18:[function(require,module,exports){
6526'use strict';
6527
6528var util = require('./util'),
6529    minicart = require('./minicart');
6530
6531exports.init = function () {
6532  $('.menu-utility-user .contact, .menu-utility-user .newsletter').hover(function () {
6533    $(this).find('.menu-utility-content').show();
6534  });
6535
6536  // 'tap' doesn't work as expected so using touchstart instead
6537  $(document).on('touchstart', function (e) {
6538    // the tapped element
6539    var $target = $(e.target);
6540
6541    // check if it's not the menu or the dropdown itself
6542    if ($target.closest('.dropdown-menu').length == 0) {
6543      // check if some dropdown menu is open, otherwise foundation will return an error
6544      if ($('.dropdown-pane.is-open').length) {
6545        $('.dropdown-pane.is-open').foundation('close');
6546      }
6547    }
6548  });
6549
6550  $('a.utility-link').click(function (evt) {
6551    evt.preventDefault();
6552  });
6553
6554  // overwrite foundation Enter key event
6555  $('.menu-utility-user input').each(function (i, input) {
6556    var $input = $(input);
6557
6558    // overwrite only on input type text, email and password
6559    if ($input.attr('type') == 'text' || $input.attr('type') == 'email' || $input.attr('type') == 'password') {
6560      $input.keydown(function (e) {
6561        Foundation.Keyboard.handleKey(e, 'DropdownMenu', {
6562          submit: function submit() {
6563            var $form = $input.closest('form');
6564
6565            // simulate blur event to check if it has error or not
6566            $input.blur();
6567
6568            // prevent submit if there are errors
6569            if ($form.find('span.error').length == 0) {
6570              // $form.submit() doesn't work on login so it has to be this *sigh*
6571              $form.find('button[type="submit"]').click();
6572            }
6573          }
6574        });
6575      });
6576    }
6577  });
6578
6579  /** Search SP
6580   * Please make sure content asset `header-navigation` like
6581   * <a href="javascript:;" class="search-sp">サイト内検索</a>
6582   */
6583  $('.search-sp').on('click', function () {
6584    // close global navigation
6585    $('.js-gnav_close').trigger('click');
6586    // open search box
6587    $('.ge-search-toggle').trigger('click');
6588  });
6589};
6590Foundation.Keyboard.register('DropdownMenu', {
6591  ENTER: 'submit'
6592});
6593
6594},{"./minicart":23,"./util":77}],19:[function(require,module,exports){
6595'use strict';
6596
6597function entry() {
6598  $(document).on('keyup blur', '#q, .checkout-shoping-side-code input', function () {
6599    var $buttons = $(this).siblings('button').not('#cross-btn');
6600    if ($(this).val().trim().length) {
6601      return $buttons.prop('disabled', false);
6602    }
6603    $buttons.prop('disabled', true);
6604  });
6605}
6606
6607exports.entry = entry;
6608
6609},{}],20:[function(require,module,exports){
6610'use strict';
6611// jQuery extensions
6612
6613module.exports = function () {
6614  // params
6615  // toggleClass - required
6616  // triggerSelector - optional. the selector for the element that triggers the event handler. defaults to the child elements of the list.
6617  // eventName - optional. defaults to 'click'
6618  $.fn.toggledList = function (options) {
6619    if (!options.toggleClass) {
6620      return this;
6621    }
6622    var list = this;
6623    return list.on(options.eventName || 'click', options.triggerSelector || list.children(), function (e) {
6624      e.preventDefault();
6625      var classTarget = options.triggerSelector ? $(this).parent() : $(this);
6626      classTarget.toggleClass(options.toggleClass);
6627      // execute callback if exists
6628      if (options.callback) {
6629        options.callback();
6630      }
6631    });
6632  };
6633
6634  $.fn.syncHeight = function () {
6635    var arr = $.makeArray(this);
6636    arr.sort(function (a, b) {
6637      return $(a).height() - $(b).height();
6638    });
6639    return this.height($(arr[arr.length - 1]).height());
6640  };
6641};
6642
6643},{}],21:[function(require,module,exports){
6644'use strict';
6645
6646function init() {
6647  $(function () {
6648    var timeoutId = null;
6649    var count = 0;
6650    $(document).ajaxSend(function (_, __, ajaxOptions) {
6651      if (ajaxOptions.loading) {
6652        count += 1;
6653        if (count === 1) {
6654          lockScreen();
6655          timeoutId = setTimeout(function () {
6656            timeoutId = null;
6657            $('html').addClass('cpb-is-loading');
6658          }, 500);
6659        }
6660      }
6661    });
6662    $(document).ajaxComplete(function (_, __, ajaxOptions) {
6663      if (ajaxOptions.loading) {
6664        count -= 1;
6665        if (count === 0) {
6666          $('html').removeClass('cpb-is-loading');
6667          unlockScreen();
6668          if (timeoutId !== null) {
6669            clearTimeout(timeoutId);
6670            timeoutId = null;
6671          }
6672        }
6673      }
6674    });
6675  });
6676}
6677
6678function lockScreen() {
6679  $('<div id="screen-lock"></div>').appendTo('body');
6680}
6681
6682function unlockScreen() {
6683  $('#screen-lock').remove();
6684}
6685
6686module.exports = {
6687  init: init
6688};
6689
6690},{}],22:[function(require,module,exports){
6691'use strict';
6692
6693var _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"); } }; }();
6694
6695var _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; };
6696
6697var dialog = require('./dialog'),
6698    page = require('./page'),
6699    util = require('./util'),
6700    validator = require('./validator'),
6701    ajax = require('./ajax'),
6702    design = require('./design'),
6703    recaptcha = require('./recaptcha');
6704
6705var login = {
6706  /**
6707   * @private
6708   * @function
6709   * @description init events for the loginPage
6710   */
6711  init: function init() {
6712    //o-auth binding for which icon is clicked
6713    $('.oAuthIcon').bind('click', function () {
6714      $('#OAuthProvider').val(this.id);
6715    });
6716
6717    //toggle the value of the rememberme checkbox
6718    $('#dwfrm_login_rememberme').bind('change', function () {
6719      if ($('#dwfrm_login_rememberme').attr('checked')) {
6720        $('#rememberme').val('true');
6721      } else {
6722        $('#rememberme').val('false');
6723      }
6724    });
6725
6726    //Reset Password Sidebar
6727    $('.password-reset').on('click', function (e) {
6728      e.preventDefault();
6729
6730      ajax.load({
6731        url: $(e.target).attr('href'),
6732        callback: function callback(data) {
6733          $('.cpb-modal_reminder').html(data);
6734
6735          validator.initForm($('#PasswordResetForm'));
6736          design.toggleSelectInit(true);
6737          var $requestPasswordForm = $('[name$="_requestpassword"]');
6738          var $submit = $requestPasswordForm.find('[name$="_requestpassword_send"]');
6739          $($submit).on('click', function (e) {
6740            var $form = $('#PasswordResetForm');
6741            e.preventDefault();
6742
6743            if (Object.keys($form.data('error-fields')).length > 0 || $form.data('validator').errorList.length > 0) {
6744              e.stopPropagation();
6745              return false;
6746            }
6747
6748            var dataToPost = $requestPasswordForm.serialize();
6749            // add form action to data
6750            dataToPost += '&' + $submit.attr('name') + '=';
6751            // make sure the server knows this is an ajax request
6752            if (dataToPost.indexOf('ajax') === -1) {
6753              dataToPost += '&format=ajax';
6754            }
6755
6756            updateContentRightModal($('.cpb-modal_reminder_send'), $requestPasswordForm.attr('action'), dataToPost);
6757          });
6758        }
6759      });
6760    });
6761
6762    //Reset Password Popup
6763    $('.js-password-reset').on('click', function (e) {
6764      e.preventDefault();
6765
6766      ajax.load({
6767        url: util.ajaxUrl($(this).attr('href')),
6768        callback: function callback(data) {
6769          var $forgetPasswordModal = $('#forgetpasswordmodal');
6770          $forgetPasswordModal.html(data);
6771          var $passwordResetForm = $('#PasswordResetForm');
6772          validator.initForm($passwordResetForm);
6773          design.toggleSelectInit(true);
6774          $.magnificPopup.open({
6775            items: {
6776              src: $forgetPasswordModal, // can be a HTML string, jQuery object, or CSS selector
6777              type: 'inline'
6778            }
6779          });
6780
6781          var $submit = $passwordResetForm.find('[name$="_requestpassword_send"]');
6782          $submit.on('click', function (e) {
6783            e.preventDefault();
6784
6785            if (!$passwordResetForm.data('custom-validator')(e)) {
6786              e.preventDefault();
6787              e.stopPropagation();
6788              return false;
6789            }
6790
6791            var dataToPost = $passwordResetForm.serialize();
6792            // add form action to data
6793            dataToPost += '&' + $submit.attr('name') + '=';
6794            // make sure the server knows this is an ajax request
6795            if (dataToPost.indexOf('ajax') === -1) {
6796              dataToPost += '&format=ajax';
6797            }
6798
6799            updateContentPopup($forgetPasswordModal, $passwordResetForm.attr('action'), dataToPost);
6800          });
6801        }
6802      });
6803    });
6804
6805    // W+アカウント連携時:ボタンクリック時にフラグを保存
6806    $(document).on('click', 'button[name$="_loginexternal"]', function () {
6807      var $form = $(this).closest('form');
6808      $form.data('clickedButtonName', $(this).attr('name'));
6809    });
6810
6811    // Ajax Login
6812    $(document).on('submit', 'form[action*="Login-LoginForm"]', function (e) {
6813      var $form = $(this);
6814      var clickedButtonName = $form.data('clickedButtonName');
6815      var $btnLogin = $form.find('button[name$="_login"], button[name$="_loginexternal"]');
6816
6817      // W+アカウント連携フラグ
6818      var isWplusInitiate = clickedButtonName && clickedButtonName.indexOf('loginexternal') > -1;
6819
6820      // ログインボタンを非活性化
6821      $btnLogin.prop('disabled', true).addClass('c-btn--login_disabled');
6822
6823      // 通常ログインの場合
6824      if (!isWplusInitiate) {
6825        e.preventDefault();
6826
6827        var baseUrl = $form.attr('action');
6828        var ajaxUrl = baseUrl.replace('Login-LoginForm', 'Login-LoginAjax');
6829
6830        $.ajax({
6831          url: ajaxUrl,
6832          data: $form.serialize(),
6833          type: 'POST'
6834        }).done(function (response) {
6835          // CSRF token error
6836          if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.error === 'CSRF Token Mismatch') {
6837            if (window.Urls && window.Urls.csrffailed) {
6838              page.redirect(window.Urls.csrffailed);
6839            } else {
6840              window.location.reload();
6841            }
6842            // ログインボタンを活性化
6843            $btnLogin.prop('disabled', false).removeClass('c-btn--login_disabled');
6844            return;
6845          }
6846
6847          // ログイン失敗時:エラー内容をURLパラメータに付与してリダイレクト
6848          if (response.success === false && response.postData) {
6849            var params = new URLSearchParams();
6850            Object.keys(response.postData).forEach(function (key) {
6851              if (response.postData[key] !== null && response.postData[key] !== undefined && response.postData[key] !== '') {
6852                params.append(key, response.postData[key]);
6853              }
6854            });
6855            var urlWithParams = response.targetUrl + (response.targetUrl.indexOf('?') > -1 ? '&' : '?') + params.toString();
6856            page.redirect(urlWithParams);
6857            // ログインボタンを活性化
6858            $btnLogin.prop('disabled', false).removeClass('c-btn--login_disabled');
6859            return;
6860          }
6861
6862          var csrf_token = response && response.csrfToken || $form.find("input[name='csrf_token']").val();
6863
6864          // MFA要否に応じた後続処理を実行
6865          login.loginSubsequent.forEach(function (item) {
6866            if (item.isMfaRequired === (response && response.isMfaRequired)) {
6867              item.subsequentProcess(response.targetUrl, response.isPostMethod, response && response.postData || {}, csrf_token);
6868            }
6869          });
6870          // ログインボタンを活性化
6871          $btnLogin.prop('disabled', false).removeClass('c-btn--login_disabled');
6872        }).fail(function (jqxhr, status, err) {
6873          if (jqxhr.responseJSON && jqxhr.responseJSON.error) {
6874            console.error('Error details:', jqxhr.responseJSON.error);
6875          }
6876          if (jqxhr.responseJSON && jqxhr.responseJSON.targetUrl) {
6877            page.redirect(jqxhr.responseJSON.targetUrl);
6878          }
6879          // ログインボタンを活性化
6880          $btnLogin.prop('disabled', false).removeClass('c-btn--login_disabled');
6881        });
6882
6883        return;
6884      }
6885
6886      // W+アカウント連携の場合
6887      e.preventDefault();
6888
6889      var ajaxUrl = window.Urls && window.Urls.wplusInitiateSiteAccountAjax;
6890
6891      if (!ajaxUrl) {
6892        console.error('[ERROR] W+ account linking Ajax URL not found');
6893        return;
6894      }
6895
6896      $.ajax({
6897        url: ajaxUrl,
6898        data: $form.serialize(),
6899        type: 'POST'
6900      }).done(function (response) {
6901        // CSRF token error
6902        if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.error === 'CSRF Token Mismatch') {
6903          if (window.Urls && window.Urls.csrffailed) {
6904            page.redirect(window.Urls.csrffailed);
6905          } else {
6906            window.location.reload();
6907          }
6908          // ログインボタンを活性化
6909          $btnLogin.prop('disabled', false).removeClass('c-btn--login_disabled');
6910          return;
6911        }
6912
6913        var csrf_token = response && response.csrfToken || $form.find("input[name='csrf_token']").val();
6914
6915        // MFA要否に応じた後続処理を実行
6916        login.loginSubsequent.forEach(function (item) {
6917          if (item.isMfaRequired === (response && response.isMfaRequired)) {
6918            item.subsequentProcess(response.targetUrl, response.isPostMethod, response && response.postData || {}, csrf_token);
6919          }
6920        });
6921        // ログインボタンを活性化
6922        $btnLogin.prop('disabled', false).removeClass('c-btn--login_disabled');
6923      }).fail(function (jqxhr, status, err) {
6924        if (jqxhr.responseJSON && jqxhr.responseJSON.error) {
6925          console.error('Error details:', jqxhr.responseJSON.error);
6926        }
6927        if (jqxhr.responseJSON && jqxhr.responseJSON.targetUrl) {
6928          page.redirect(jqxhr.responseJSON.targetUrl);
6929        }
6930        // ログインボタンを活性化
6931        $btnLogin.prop('disabled', false).removeClass('c-btn--login_disabled');
6932      });
6933    });
6934  },
6935
6936  submitOmotionVerify: function submitOmotionVerify(e) {
6937    e.preventDefault();
6938    var $form = $(this);
6939    var url = $form.attr('action');
6940
6941    $.ajax({
6942      url: url,
6943      data: {
6944        authCode: $form.find('input[name*="_authCode"]').val() || $form.find('input[name="authCode"]').val(),
6945        email: $form.find('input[name="email"]').val(),
6946        rememberme: $form.find('input[name="rememberme"]').val(),
6947        verifyCategory: $form.find('input[name="verifyCategory"]').val(),
6948        csrf_token: $form.find("input[name='csrf_token']").val(),
6949        format: 'ajax'
6950      },
6951      type: 'POST'
6952    }).done(function (response) {
6953      // CSRF Token Error
6954      if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.error === 'CSRF Token Mismatch') {
6955        page.redirect(window.Urls.csrffailed);
6956        return;
6957      }
6958
6959      // authRedirect呼び出し
6960      $.ajax({
6961        url: response.redirectUrl,
6962        data: {
6963          email: $form.find('input[name="email"]').val(),
6964          rememberme: $form.find('input[name="rememberme"]').val() === 'true',
6965          verifyCategory: $form.find('input[name="verifyCategory"]').val(),
6966          isTokuisakiEC: $form.find('input[name="isTokuisakiEC"]').val(),
6967          accountCreation: $form.find('input[name="accountCreation"]').val(),
6968          isCustomerConnect: $form.find('input[name="isCustomerConnect"]').val(),
6969          format: 'ajax',
6970          csrf_token: $form.find("input[name='csrf_token']").val()
6971        },
6972        type: 'POST'
6973      }).done(function (response) {
6974        // POSTメソッドの場合:フォームを作成して送信
6975        if (response && response.isPostMethod) {
6976          var csrf_token = response && response.csrfToken || $form.find("input[name='csrf_token']").val();
6977          var postData = response && response.postData || {};
6978          var form = document.createElement('form');
6979          form.action = response.targetUrl;
6980          form.method = 'post';
6981          form.style.display = 'none';
6982
6983          Object.entries(postData).forEach(function (_ref) {
6984            var _ref2 = _slicedToArray(_ref, 2),
6985                key = _ref2[0],
6986                value = _ref2[1];
6987
6988            if (Array.isArray(value)) {
6989              value.forEach(function (item) {
6990                var input = document.createElement('input');
6991                input.type = 'hidden';
6992                input.name = key + '[]';
6993                input.value = item;
6994                form.appendChild(input);
6995              });
6996            } else {
6997              var _input = document.createElement('input');
6998              _input.type = 'hidden';
6999              _input.name = key;
7000              _input.value = value;
7001              form.appendChild(_input);
7002            }
7003          });
7004
7005          var input = document.createElement('input');
7006          input.type = 'hidden';
7007          input.name = 'csrf_token';
7008          input.value = csrf_token;
7009          form.appendChild(input);
7010
7011          document.body.appendChild(form);
7012          form.submit();
7013        } else {
7014          // GETメソッドの場合:リダイレクト
7015          page.redirect(response.targetUrl);
7016        }
7017      }).fail(function (jqxhr, status, err) {
7018        if (jqxhr.responseJSON && jqxhr.responseJSON.error) {
7019          console.error(jqxhr.responseJSON.error);
7020        }
7021        if (jqxhr.responseJSON && jqxhr.responseJSON.targetUrl) {
7022          page.redirect(jqxhr.responseJSON.targetUrl);
7023        }
7024      });
7025    }).fail(function (jqxhr, status, err) {
7026      if (jqxhr.responseJSON && jqxhr.responseJSON.redirectUrl) {
7027        // POSTメソッドの場合:フォームを作成して送信
7028        if (jqxhr.responseJSON && jqxhr.responseJSON.isPostMethod) {
7029          var csrf_token = $form.find("input[name='csrf_token']").val();
7030          var postData = jqxhr.responseJSON && jqxhr.responseJSON.postData || {};
7031          var form = document.createElement('form');
7032          form.action = jqxhr.responseJSON.redirectUrl;
7033          form.method = 'post';
7034          form.style.display = 'none';
7035
7036          Object.entries(postData).forEach(function (_ref3) {
7037            var _ref4 = _slicedToArray(_ref3, 2),
7038                key = _ref4[0],
7039                value = _ref4[1];
7040
7041            if (Array.isArray(value)) {
7042              value.forEach(function (item) {
7043                var input = document.createElement('input');
7044                input.type = 'hidden';
7045                input.name = key + '[]';
7046                input.value = item;
7047                form.appendChild(input);
7048              });
7049            } else {
7050              var _input2 = document.createElement('input');
7051              _input2.type = 'hidden';
7052              _input2.name = key;
7053              _input2.value = value;
7054              form.appendChild(_input2);
7055            }
7056          });
7057
7058          var input = document.createElement('input');
7059          input.type = 'hidden';
7060          input.name = 'csrf_token';
7061          input.value = csrf_token;
7062          form.appendChild(input);
7063
7064          document.body.appendChild(form);
7065          form.submit();
7066        } else {
7067          // GETメソッドの場合:リダイレクト
7068          $.magnificPopup.close();
7069          page.redirect(jqxhr.responseJSON.redirectUrl);
7070        }
7071      } else {
7072        // サーバーサイドバリデーションエラー(期限切れ・上限超過・認証コード不一致)
7073        // コンテンツアセットからメッセージを取得
7074        var $serverErrorList = $form.closest('.c-block-forgetpassword-gather').find('.omotion-server-error');
7075        var errorMsg = jqxhr.responseJSON && jqxhr.responseJSON.errorMessageHtml;
7076        $serverErrorList.html('<li>' + errorMsg + '</li>').show();
7077
7078        // 認証上限回数超過または有効期限切れの場合、送信ボタンを非活性化
7079        var errorStatus = jqxhr.responseJSON && jqxhr.responseJSON.status;
7080
7081        if (errorStatus === 'EXPIRED' || errorStatus === 'MAX_ATTEMPTS_EXCEEDED') {
7082          var $submitButton = $form.find('button[type="submit"]');
7083          $submitButton.prop('disabled', true).addClass('is-disabled');
7084        }
7085      }
7086    });
7087  },
7088
7089  loginSubsequent: [{
7090    // MFA必要
7091    isMfaRequired: true,
7092    subsequentProcess: function subsequentProcess(url, isPostMethod, postData, csrf_token) {
7093      // 既存のモーダルを閉じる
7094      if (typeof $.magnificPopup !== 'undefined') {
7095        $.magnificPopup.close();
7096      }
7097
7098      // ajax.loadで直接HTMLを取得してbodyに追加
7099      ajax.load({
7100        url: url,
7101        callback: function callback(data) {
7102          if (!data) {
7103            console.error('[ERROR] No modal HTML received');
7104            return;
7105          }
7106
7107          // モーダル要素の作成
7108          var $omotionAuthModal = $('#omotionAuthModal');
7109          if ($omotionAuthModal.length === 0) {
7110            $omotionAuthModal = $('<div id="omotionAuthModal" class="mfp-hide c-block-medium c-block-forgetpassword"></div>');
7111            $('body').append($omotionAuthModal);
7112          }
7113
7114          // モーダル内容を更新
7115          $omotionAuthModal.html(data);
7116
7117          $.magnificPopup.open({
7118            items: {
7119              src: $omotionAuthModal,
7120              type: 'inline'
7121            }
7122          });
7123
7124          // フォーム送信イベントを登録
7125          validator.init();
7126          var $submit = $('#OmotionAuthForm');
7127          if ($submit.length > 0) {
7128            $submit.off('submit').on('submit', login.submitOmotionVerify);
7129          }
7130        }
7131      });
7132    }
7133  }, {
7134    // MFA不要
7135    isMfaRequired: false,
7136    subsequentProcess: function subsequentProcess(url, isPostMethod, postData, csrf_token) {
7137      // POSTメソッドの場合:フォームを作成して送信
7138      if (isPostMethod) {
7139        var form = document.createElement('form');
7140        form.action = url;
7141        form.method = 'post';
7142        form.style.display = 'none';
7143
7144        // postDataの各キーと値をフォームに追加
7145        Object.entries(postData).forEach(function (_ref5) {
7146          var _ref6 = _slicedToArray(_ref5, 2),
7147              key = _ref6[0],
7148              value = _ref6[1];
7149
7150          if (Array.isArray(value)) {
7151            var _input3 = document.createElement('input');
7152            _input3.type = 'hidden';
7153            _input3.name = key;
7154            _input3.value = value.join(';');
7155            form.appendChild(_input3);
7156          } else {
7157            var _input4 = document.createElement('input');
7158            _input4.type = 'hidden';
7159            _input4.name = key;
7160            _input4.value = value;
7161            form.appendChild(_input4);
7162          }
7163        });
7164
7165        // CSRFトークンをフォームに追加
7166        var input = document.createElement('input');
7167        input.type = 'hidden';
7168        input.name = 'csrf_token';
7169        input.value = csrf_token;
7170        form.appendChild(input);
7171
7172        document.body.appendChild(form);
7173        form.submit();
7174      } else {
7175        // GETメソッドの場合:リダイレクト
7176        page.redirect(url);
7177      }
7178    }
7179  }]
7180};
7181
7182function updateContentRightModal($element, href, data) {
7183  $.ajax({
7184    type: 'POST',
7185    url: href,
7186    data: data,
7187    success: function success(response) {
7188      if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.error === 'CSRF Token Mismatch') {
7189        page.redirect(Urls.csrffailed);
7190      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.ErrorMsg) {
7191        var $modalReminder = $element.parent();
7192        var $errorPlacement = $modalReminder.find('.cmd-form_container>.cmd-form_err');
7193        if ($errorPlacement.length > 0) {
7194          $errorPlacement.remove();
7195        }
7196        $modalReminder.find('.cmd-form_container').prepend($('<p class="cmd-form_err"></p>').text(response.ErrorMsg));
7197      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
7198        window.location.href = Urls.generalError;
7199      } else if (typeof response === 'string') {
7200        ajax.load({
7201          url: $('#PasswordResetForm').find('[name$="_requestpassword_send"]').data('url'),
7202          callback: function callback(data) {
7203            $element.parent().find('.cpb-modal_reminder').addClass('is-hide');
7204            $element.removeClass('is-hide');
7205            $($element).html(data);
7206          }
7207        });
7208      }
7209    },
7210    failure: function failure() {
7211      $element.html('<h1>' + Resources.SERVER_ERROR + '</h1>');
7212    }
7213  });
7214}
7215
7216function updateContentPopup($element, href, data) {
7217  $.ajax({
7218    type: 'POST',
7219    url: href,
7220    data: data,
7221    success: function success(response) {
7222      if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.error === 'CSRF Token Mismatch') {
7223        page.redirect(Urls.csrffailed);
7224      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.ErrorMsg) {
7225        $element.find('form').parent().children('ul.c-text-error').remove();
7226        $('<ul></ul>').addClass('c-text-error').append($('<li></li>').text(response.ErrorMsg)).insertBefore($element.find('form'));
7227      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
7228        window.location.href = Urls.generalError;
7229      } else if (typeof response === 'string') {
7230        $element.html(response);
7231        $.magnificPopup.open({
7232          items: {
7233            src: $element, // can be a HTML string, jQuery object, or CSS selector
7234            type: 'inline'
7235          }
7236        });
7237        validator.initForm($('#PasswordResetForm'));
7238        design.toggleSelectInit(true);
7239
7240        $('.c-block-forgetpassword-block-receive .js-modal-close').on('click', function (e) {
7241          e.preventDefault();
7242          $.magnificPopup.close();
7243        });
7244      }
7245    },
7246    failure: function failure() {
7247      $element.html('<h1>' + Resources.SERVER_ERROR + '</h1>');
7248    }
7249  });
7250}
7251
7252module.exports = login;
7253
7254///Login Greetings
7255if (window.User.isCustomerAuthenticated != false || window.User.isRegistered == true) {
7256  var myDate = new Date();
7257  var hrs = myDate.getHours();
7258  var mins = myDate.getMinutes();
7259  var time;
7260  var greeting;
7261
7262  mins = ('0' + mins).slice(-2);
7263  time = hrs + mins;
7264  time = Number(time);
7265
7266  if (time >= 300 && time <= 1159) {
7267    greeting = window.Resources.GREETINGS_MORNING;
7268  } else if (time >= 1200 && time <= 1700) {
7269    greeting = window.Resources.GREETINGS_AFTERNOON;
7270  } else {
7271    greeting = window.Resources.GREETINGS_EVENING;
7272  }
7273
7274  $('#login-greetings').text(greeting);
7275  $('.menu-greeting #login-greetings').text(greeting);
7276}
7277
7278},{"./ajax":1,"./design":11,"./dialog":12,"./page":28,"./recaptcha":68,"./ut
7278il":77,"./validator":78}],23:[function(require,module,exports){
7279'use strict';
7280
7281var util = require('./util'),
7282    bonusProductsView = require('./bonus-products-view'),
7283    samples = require('./samples'),
7284    design = require('./design');
7285
7286var timer = {
7287  id: null,
7288  clear: function clear() {
7289    if (this.id) {
7290      window.clearTimeout(this.id);
7291      delete this.id;
7292    }
7293  },
7294  start: function start(duration, callback) {
7295    this.id = setTimeout(callback, duration);
7296  }
7297};
7298
7299var setAddToCartError = function setAddToCartError(msg) {
7300  var $errEle = $('.cmd-form_err');
7301  $errEle.html(msg);
7302  $errEle.show();
7303};
7304
7305var minicart = {
7306  init: function init() {
7307    initEvents();
7308  },
7309
7310  addProduct: function addProduct(data) {
7311    var show = this.show.bind(this);
7312
7313    return new Promise(function (resolve, reject) {
7314      if (data.hasOwnProperty('pid') === false) {
7315        return reject();
7316      }
7317
7318      $.post(util.appendParamsToUrl(Urls.addProduct, {
7319        format: 'ajax',
7320        pid: encodeURIComponent(data.pid),
7321        Quantity: data.hasOwnProperty('Quantity') ? data.Quantity : '1'
7322      }), function (data) {
7323        if (data.success === false) {
7324          return reject(data.error);
7325        }
7326
7327        show(data);
7328        resolve();
7329      }).fail(function (err) {
7330        reject(err.error);
7331      });
7332    });
7333  },
7334
7335  addAllToWishlistFromContent: function addAllToWishlistFromContent(pids) {
7336    return window.location.href = Urls.addAllFromContent + '?pid=' + pids.join(':1,') + // pass qty of one
7337    '&cid=' + window.contentAssetID + '&hashparam=' + window.location.hash.split('#')[1];
7338  },
7339
7340  addAllProducts: function addAllProducts(pids, to, currentTarget) {
7341    if (!pids || pids.length === 0) {
7342      return;
7343    }
7344
7345    var isWishlist = to && to.toLowerCase() === 'wishlist';
7346    if (isWishlist && !window.User.isCustomerAuthenticated) {
7347      if (window.contentAssetID) {
7348        return this.addAllToWishlistFromContent(pids);
7349      } else {
7350        var footerURL = $('footer') ? $('footer').data('url') : null;
7351        window.location = util.appendParamToURL(Urls.showLogin, 'original', footerURL);
7352        return;
7353      }
7354    }
7355
7356    var show = this.show.bind(this);
7357    var updateMiniCartInfo = this.updateMiniCartInfo.bind(this);
7358    var showAddToCartPopup = this.showAddToCartPopup.bind(this);
7359    var urlName = Urls.addMultipleProducts;
7360    var csrf_token = $(currentTarget).closest('#product-set').find('input[name=csrf_token]').val();
7361
7362    if (isWishlist) {
7363      urlName = Urls.wishlistAddAll.split(window.location.hostname)[1];
7364    }
7365
7366    return $.when($.post(util.appendParamsToUrl(urlName, {
7367      format: 'ajax',
7368      pid: pids,
7369      csrf_token: csrf_token
7370    }))).then(function (data) {
7371      if (isWishlist) {
7372        window.location.href = window.location.href;
7373        return;
7374      }
7375
7376      if (data) {
7377        $('form.pdpForm').find('.cmd-form_err').remove();
7378        if (data.success == false) {
7379          $('form.pdpForm').find('button#add-all-to-cart').parent().siblings('.cmd-form_err').remove();
7380          if (data.errorLst) {
7381            for (var i = 0; i < data.errorLst.length; i++) {
7382              $('form.pdpForm').find('div[data-pid="' + data.errorLst[i].pidError + '"]').find('.cpb-products-conut').before($("<div class='cmd-form_err _simple'></div>").text(data.errorLst[i].errorMsg));
7383            }
7384            window.scrollTo(0, $('form.pdpForm').find('div[data-pid="' + data.errorLst[0].pidError + '"]').offset().top);
7385            //refresh minicart
7386            return $.when($.post(util.appendParamsToUrl(Urls.miniCartShow, {
7387              format: 'ajax'
7388            }))).then(function (data) {
7389              return $.Deferred().reject(function () {
7390                // エラーがあった場合、ミニカートの情報のみ更新
7391                updateMiniCartInfo(data);
7392              }).progress();
7393            });
7394          } else if (!data.errorMsg) {
7395            window.location.href = window.location.href;
7396            return $.Deferred().reject().promise();
7397          } else {
7398            $('form.pdpForm').find('button#add-all-to-cart').parent().after($("<div class='cmd-form_err _simple'></div>").text(data.errorMsg));
7399            return $.Deferred().reject().promise();
7400          }
7401        }
7402
7403        return function () {
7404          show(data);
7405          showAddToCartPopup('#minicart-notification');
7406        };
7407      }
7408    });
7409  },
7410
7411  /**
7412   * @function
7413   * @description Shows the given content in the mini cart
7414   * @param {String} A HTML string with the content which will be shown
7415   */
7416  show: function show(html) {
7417    $('[data-modal-type="cart"]').find('.nicescroll-rails').remove();
7418    var quantity = $(html).find('.quantity_box').find('.num').data('quantity');
7419    if (quantity > 0) {
7420      $('.header-cart_btn .minicart-quantity').text(quantity);
7421      $('.header-cart_btn').prop('disabled', false);
7422      $('.header-cart_btn').css('cursor', 'pointer');
7423    }
7424    if (!$('.header-cart_btn').hasClass('_in') && quantity > 0) {
7425      $('.header-cart_btn').addClass('_in');
7426    }
7427    $('.js-modal-r_content[data-modal-type="cart"] .cpb-modalR_contents').html(html);
7428    this.init();
7429
7430    this.slide();
7431
7432    // identify if we can show the sample overlay
7433    var canShowSamples = false;
7434    $(document).find('[data-modal-type="cart"] input[name="eligible-for-sample"]').each(function () {
7435      if (!canShowSamples && $(this).val() == 'true') {
7436        canShowSamples = true;
7437      }
7438    });
7439
7440    if (bonusProductsView.hasBonusOptions() === false && samples.canShowSelection() && canShowSamples) {
7441      setTimeout(function () {
7442        samples.showSelection();
7443      }, 1000);
7444    }
7445
7446    bonusProductsView.loadBonusOption();
7447  },
7448  /**
7449   * 「show」のミニカート情報を更新だけ行う関数
7450   * @todo「show」の関数からのコピー関数のため時間があるときに関数化し「show」と合わせて修正したほうが良い
7451   * @param {*} html
7452   */
7453  updateMiniCartInfo: function updateMiniCartInfo(html) {
7454    $('[data-modal-type="cart"]').find('.nicescroll-rails').remove();
7455    var quantity = $(html).find('.quantity_box').find('.num').data('quantity');
7456    if (quantity > 0) {
7457      $('.header-cart_btn .minicart-quantity').text(quantity);
7458      $('.header-cart_btn').prop('disabled', false);
7459      $('.header-cart_btn').css('cursor', 'pointer');
7460    }
7461    if (!$('.header-cart_btn').hasClass('_in') && quantity > 0) {
7462      $('.header-cart_btn').addClass('_in');
7463    }
7464    $('.js-modal-r_content[data-modal-type="cart"] .cpb-modalR_contents').html(html);
7465    this.init();
7466
7467    // identify if we can show the sample overlay
7468    var canShowSamples = false;
7469    $(document).find('[data-modal-type="cart"] input[name="eligible-for-sample"]').each(function () {
7470      if (!canShowSamples && $(this).val() == 'true') {
7471        canShowSamples = true;
7472      }
7473    });
7474
7475    if (bonusProductsView.hasBonusOptions() === false && samples.canShowSelection() && canShowSamples) {
7476      setTimeout(function () {
7477        samples.showSelection();
7478      }, 1000);
7479    }
7480
7481    bonusProductsView.loadBonusOption();
7482  },
7483  /**
7484   * @function
7485   * @description Slides down and show the contents of the mini cart
7486   */
7487  slide: function slide() {
7488    // show the item
7489    cpbUi.util.rightModalOpen.call($('.header-cart_btn'), undefined, function (target) {
7490      cpbUi.niceScroll.ready();
7491    });
7492  },
7493  /**
7494   * @function
7495   * @description Closes the mini cart with given delay
7496   * @param {Number} delay The delay in milliseconds
7497   */
7498  close: function close(delay) {
7499    // close modal
7500    cpbUi.util.rightModalClose.call($('.js-modal-r_content[data-modal-type="cart"] .js-modal-r_close'), undefined, function (target) {});
7501  },
7502  /**
7503   * @function
7504   * @description Show mini popup when add to cart in SP
7505   */
7506  showAddToCartPopup: function showAddToCartPopup(src) {
7507    if (window.innerWidth <= 768 && $(src).length) {
7508      $.magnificPopup.open({
7509        items: {
7510          src: src, // can be a HTML string, jQuery object, or CSS selector
7511          type: 'inline'
7512        }
7513      });
7514    }
7515  }
7516};
7517
7518/**
7519 * Init events
7520 * @returns
7521 */
7522function initEvents() {
7523  //change quantity productlineItem
7524  $('.cpb-products_list_box .js-num-drop_select li').on('click', function (e) {
7525    var uuidProduct = $(this).closest('.cpb-products_list_box').find('.uuid-product').val();
7526    var current = $(this).find('a');
7527    var currentNum = current.html();
7528    var priceItem = $(this).closest('.cpb-products_list_box').find('.item-btm .item-price span');
7529    var dataSend = {
7530      uuid: uuidProduct,
7531      quantity: currentNum
7532    };
7533    $.ajax({
7534      url: Urls.updateQuantityProduct,
7535      type: 'GET',
7536      data: dataSend,
7537      success: function success(response) {
7538        if (response) {
7539          $('[data-modal-type="cart"]').find('.cpb-modalR_contents').html(response);
7540          var quantityTotal = $('#quantity-total-product').val();
7541          if (quantityTotal > 0) {
7542            $('.minicart-quantity').html(parseInt(quantityTotal));
7543          } else {
7544            $('.minicart-quantity').empty();
7545            $('.minicart-quantity').parent().removeClass('_in');
7546          }
7547          $('[data-modal-type="cart"]').find('.nicescroll-rails').remove();
7548          initEvents();
7549          cpbUi.niceScroll.ready();
7550        } else {
7551          console.log('error');
7552        }
7553      },
7554      error: function error(response) {
7555        return;
7556      },
7557      loading: true
7558    });
7559  });
7560
7561  if ($('#quantity-total-product').val() > 0) {
7562    if ($('#error-kit').length > 0) {
7563      $('#error-kit').css({ display: 'block' });
7564    }
7565  } else {
7566    $('#error-kit').css({ display: 'none' });
7567  }
7568
7569  $('.cpb-products_list_box .js-num-drop_down').off('click').on('click', function (e) {
7570    var uuidProduct = $(this).closest('.cpb-products_list_box').find('.uuid-product').val();
7571    var current = $(this).closest('.js-num-drop_container').find('.js-num-drop_cnt');
7572    var currentNum = current.html();
7573    if (currentNum > 1) {
7574      currentNum--;
7575    }
7576    var priceItem = $(this).closest('.cpb-products_list_box').find('.item-btm .item-price span');
7577    var dataSend = {
7578      uuid: uuidProduct,
7579      quantity: currentNum
7580    };
7581    $.ajax({
7582      url: Urls.updateQuantityProduct,
7583      type: 'GET',
7584      data: dataSend,
7585      success: function success(response) {
7586        if (response) {
7587          $('[data-modal-type="cart"]').find('.cpb-modalR_contents').html(response);
7588          var quantityTotal = $('#quantity-total-product').val();
7589          if (quantityTotal > 0) {
7590            $('.minicart-quantity').html(parseInt(quantityTotal));
7591          } else {
7592            $('.minicart-quantity').empty();
7593            $('.minicart-quantity').parent().removeClass('_in');
7594          }
7595          $('[data-modal-type="cart"]').find('.nicescroll-rails').remove();
7596          initEvents();
7597          cpbUi.niceScroll.ready();
7598        } else {
7599          console.log('error');
7600        }
7601      },
7602      error: function error(response) {
7603        return;
7604      },
7605      loading: true
7606    });
7607  });
7608
7609  $('.cpb-products_list_box .js-num-drop_up').off('click').on('click', function (e) {
7610    var uuidProduct = $(this).closest('.cpb-products_list_box').find('.uuid-product').val();
7611    var current = $(this).closest('.js-num-drop_container').find('.js-num-drop_cnt');
7612    var currentNum = current.html();
7613    var limit = $(this).closest('.js-num-drop_container').find('.js-num-drop_select li a').length;
7614    if (currentNum < limit) {
7615      currentNum++;
7616    }
7617    var priceItem = $(this).closest('.cpb-products_list_box').find('.item-btm .item-price span');
7618    var dataSend = {
7619      uuid: uuidProduct,
7620      quantity: currentNum
7621    };
7622    $.ajax({
7623      url: Urls.updateQuantityProduct,
7624      type: 'GET',
7625      data: dataSend,
7626      success: function success(response) {
7627        if (response) {
7628          $('[data-modal-type="cart"]').find('.cpb-modalR_contents').html(response);
7629          var quantityTotal = $('#quantity-total-product').val();
7630          if (quantityTotal > 0) {
7631            $('.minicart-quantity').html(parseInt(quantityTotal));
7632          } else {
7633            $('.minicart-quantity').empty();
7634            $('.minicart-quantity').parent().removeClass('_in');
7635          }
7636          $('[data-modal-type="cart"]').find('.nicescroll-rails').remove();
7637          initEvents();
7638          cpbUi.niceScroll.ready();
7639        } else {
7640          console.log('error');
7641        }
7642      },
7643      error: function error(response) {
7644        return;
7645      },
7646      loading: true
7647    });
7648  });
7649
7650  //remove productlineItem
7651  $('.cpb-products_list_box .item-remove a').on('click', function (e) {
7652    e.preventDefault();
7653    var uuidProduct = $(this).closest('.cpb-products_list_box').find('.uuid-product').val();
7654    var item = $(this).closest('.cpb-products_list_box');
7655    var dataSend = {
7656      uuid: uuidProduct
7657    };
7658    $.ajax({
7659      type: 'GET',
7660      data: dataSend,
7661      url: Urls.removeProduct,
7662      success: function success(response) {
7663        if (response) {
7664          $('[data-modal-type="cart"]').find('.cpb-modalR_contents').html(response);
7665          var quantityTotal = $('#quantity-total-product').val();
7666          if (quantityTotal > 0) {
7667            $('.minicart-quantity').html(parseInt(quantityTotal));
7668          } else {
7669            $('.minicart-quantity').empty();
7670            $('.minicart-quantity').parent().removeClass('_in');
7671            $('.header-cart_btn').prop('disabled', true);
7672            $('.header-cart_btn').css('cursor', 'auto');
7673          }
7674          $('[data-modal-type="cart"]').find('.nicescroll-rails').remove();
7675          initEvents();
7676          cpbUi.niceScroll.ready();
7677        } else {
7678          console.log('error:');
7679        }
7680      },
7681      loading: true
7682    });
7683  });
7684}
7685
7686module.exports = minicart;
7687
7688},{"./bonus-products-view":4,"./design":11,"./samples":69,"./util":77}],24:[function(require,module,exports){
7689'use strict';
7690
7691var util = require('./util');
7692
7693function Modal(modalCntr, modalBody, option) {
7694  this.$cntr = $(modalCntr);
7695  this.$body = $(modalBody);
7696
7697  if ($.isEmptyObject(option) === false) {
7698    this.modal = new Foundation.Reveal($(modalCntr), option);
7699  } else {
7700    this.modal = new Foundation.Reveal($(modalCntr));
7701  }
7702  this.callbackFn = null;
7703
7704  this.events = {
7705    onOpen: function onOpen(cb) {
7706      $(document).off('open.zf.reveal').on('open.zf.reveal', function () {
7707        cb();
7708        $(document).off('open.zf.reveal');
7709      });
7710    },
7711
7712    onClose: function onClose(cb) {
7713      $(document).off('closed.zf.reveal').on('closed.zf.reveal', function () {
7714        cb();
7715        $(document).off('closed.zf.reveal');
7716      });
7717    }
7718  };
7719}
7720
7721Modal.prototype.open = function () {
7722  this.modal.open();
7723};
7724
7725Modal.prototype.close = function () {
7726  this.modal.close();
7727};
7728
7729Modal.prototype.restoreDefaultClass = function () {
7730  this.$cntr.removeAttr('class');
7731  this.$cntr.attr('class', 'reveal');
7732};
7733
7734Modal.prototype.addCustomClass = function (customClass) {
7735  this.restoreDefaultClass();
7736  this.$cntr.addClass(customClass);
7737};
7738
7739Modal.prototype.setContent = function (content) {
7740  return this.$body.html(content);
7741};
7742
7743Modal.prototype.renderContent = function (content, type) {
7744  var classType = type || '';
7745
7746  this.$body.html('<div id="modal-content" class="modal-content ' + classType + '">' + content + '</div>');
7747  this.modal.open();
7748
7749  if (typeof this.callbackFn === 'function') {
7750    this.callbackFn();
7751    this.callbackFn = null; // clear after each use
7752  }
7753};
7754
7755Modal.prototype.renderByUrl = function (contentUrl) {
7756  return $.get(util.appendParamToURL(contentUrl, 'format', 'ajax')).done(this.renderContent.bind(this));
7757};
7758
7759Modal.prototype.setCallback = function (cb) {
7760  this.callbackFn = cb;
7761};
7762
7763module.exports.global = new Modal('#modal-cntr', '.modal-body', {}); // global modal
7764module.exports.create = function (modalCntr, modalBody, option) {
7765  return new Modal(modalCntr, modalBody, option);
7766};
7767
7768},{"./util":77}],25:[function(require,module,exports){
7769'use strict';
7770
7771var cpbUi = cpbUi || {};
7772var product = require('./pages/product');
7773
7774/**
7775 *
7776 * Variables
7777 *
7778 */
7779var transitionEndEvents = ['webkitTransitionEnd.transitionend', 'mozTransitionEnd.transitionend', 'oTransitionEnd.transitionend', 'transitionend.transitionend'].join(' ');
7780
7781cpbUi.isDomReady = false;
7782cpbUi.isHeaderFixed = false;
7783cpbUi.isPdp = false;
7784cpbUi.scrollDirection = '';
7785cpbUi.scrollbarSize;
7786
7787/**
7788 * Header
7789 */
7790var initHeader = function () {
7791  return {
7792    init: function init() {
7793      $(window).on('scroll', function (e) {
7794        if (!cpbUi.isDomReady) return;
7795        var ghH = $('.js-grobal-header').height();
7796        if (!cpbUi.isHeaderFixed && window.pageYOffset > ghH) {
7797          $('html').addClass('is-scroll');
7798          cpbUi.isHeaderFixed = true;
7799        } else if (cpbUi.isHeaderFixed && window.pageYOffset <= ghH) {
7800          $('html').removeClass('is-scroll');
7801          cpbUi.isHeaderFixed = false;
7802        }
7803      });
7804    },
7805    ready: function ready() {}
7806  };
7807}();
7808
7809/**
7810 * Footer
7811 */
7812var initFooter = function () {
7813  return {
7814    init: function init() {},
7815    ready: function ready() {}
7816  };
7817}();
7818
7819/**
7820 * Global Navigation Toggle
7821 */
7822var initGlobalNavigation = function () {
7823  var gnavOpen = function gnavOpen(e) {
7824    e.preventDefault();
7825    var targetName = $(this).attr('data-target');
7826    var $gnav = $('.cpb-gnav_container.is-' + targetName);
7827    $gnav.addClass('is-active');
7828    setTimeout(function () {
7829      util.setModalScrollbarFix();
7830      $('html').addClass('is-gnav-open');
7831      $gnav.find('.js-gnav_overlay').fadeIn(200, function () {
7832        $gnav.find('.js-gnav_close').eq(0).focus();
7833      });
7834      $gnav.find('.cpb-gnav_wrap').css({
7835        transform: 'translateX(0)'
7836      });
7837      cpbUi.niceScroll.resize($gnav);
7838    }, 10);
7839  };
7840  var gnavClose = function gnavClose(e) {
7841    e.preventDefault();
7842    var $gnav = $(this).closest('.cpb-gnav_container');
7843    var $gnavWrap = $gnav.find('.cpb-gnav_wrap');
7844    $gnavWrap.on(transitionEndEvents, function () {
7845      $gnav.find('.js-gnav_overlay').fadeOut(200, function () {
7846        util.removeModalScrollbarFix();
7847        $('html').removeClass('is-gnav-open');
7848        $gnav.removeClass('is-active');
7849        $gnav.find('.js-gnav_btn').eq(0).focus();
7850      });
7851      $gnavWrap.off('.transitionend');
7852    });
7853    $gnavWrap.css({
7854      transform: 'translateX(-100%)'
7855    });
7856  };
7857
7858  var gnavChildOpen = function gnavChildOpen(e) {
7859    e.preventDefault();
7860    var $gnav = $(this).closest('.cpb-gnav_container');
7861    var $box = $(this).closest('.js-gnav-item_contents');
7862    var target = $(this).attr('data-gnav-target');
7863    var $target = $gnav.find('.js-gnav-item_contents').filter('[data-gnav-name="' + target + '"]');
7864    if ($target[0]) {
7865      $target.on(transitionEndEvents, function () {
7866        $box.removeClass('is-visible');
7867        $target.off('.transitionend');
7868      });
7869      $target.addClass('is-visible');
7870      setTimeout(function () {
7871        $target.css({
7872          transform: 'translateX(0)'
7873        });
7874      }, 10);
7875      cpbUi.niceScroll.resize($target);
7876    }
7877  };
7878
7879  var gnavChildClose = function gnavChildClose(e) {
7880    e.preventDefault();
7881    var $gnav = $(this).closest('.cpb-gnav_container');
7882    var $box = $(this).closest('.js-gnav-item_contents');
7883    var target = $(this).attr('data-gnav-target');
7884    var $target = $gnav.find('.js-gnav-item_contents').filter('[data-gnav-name="' + target + '"]');
7885    if ($target[0]) {
7886      $box.on(transitionEndEvents, function () {
7887        $box.removeClass('is-visible');
7888        $box.off('.transitionend');
7889      });
7890      $box.css({
7891        transform: 'translateX(-100%)'
7892      });
7893
7894      $target.addClass('is-visible');
7895      setTimeout(function () {
7896        $target.css({
7897          transform: 'translateX(0)'
7898        });
7899      }, 10);
7900    }
7901  };
7902
7903  return {
7904    init: function init() {
7905      $(document).on('click', '.js-gnav_btn', gnavOpen);
7906      $(document).on('click', '.js-gnav_close', gnavClose);
7907      $(document).on('click', '.js-gnav_overlay', gnavClose);
7908      $(document).on('click', '.js-gnav-item_btn', gnavChildOpen);
7909      $(document).on('click', '.js-gnav_back', gnavChildClose);
7910    },
7911    ready: function ready() {}
7912  };
7913}();
7914
7915/**
7916 * Right Modal
7917 */
7918var initRightModal = function () {
7919  var loginCallback = function loginCallback() {};
7920  var accountCallback = function accountCallback() {};
7921  var cartCallback = function cartCallback() {};
7922
7923  return {
7924    init: function init() {
7925      $(document).on('click', '.js-modal-r_open', function (e) {
7926        e.preventDefault();
7927        util.rightModalOpen.call(this, undefined, function (target) {
7928          if (target === 'login') {
7929            loginCallback();
7930          }
7931          if (target === 'account') {
7932            accountCallback();
7933          }
7934          if (target === 'cart') {
7935            cartCallback();
7936          }
7937        });
7938      });
7939      $(document).on('click', '.js-modal-r_close', function (e) {
7940        e.preventDefault();
7941        util.rightModalClose.call(this, undefined, function (target) {});
7942      });
7943      $(document).on('click', '.js-modal-r_overlay', function (e) {
7944        e.preventDefault();
7945        util.rightModalClose.call(this, undefined, function (target) {});
7946      });
7947    },
7948    ready: function ready() {}
7949  };
7950}();
7951
7952/**
7953 * Center Modal
7954 */
7955var initCenterModal = function () {
7956  return {
7957    init: function init() {
7958      $(document).on('click', '.js-modal-c_open', function (e) {
7959        e.preventDefault();
7960        util.centerModalOpen.call(this, undefined, function (target) {});
7961      });
7962      $(document).on('click', '.js-modal-c_close', function (e) {
7963        e.preventDefault();
7964        util.centerModalClose.call(this, undefined, function (target) {});
7965      });
7966      $(document).on('click', '.js-modal-c_overlay', function (e) {
7967        e.preventDefault();
7968        util.centerModalClose.call(this, undefined, function (target) {});
7969      });
7970    },
7971    ready: function ready() {}
7972  };
7973}();
7974
7975/**
7976 * Right Modal Login
7977 */
7978var initRightModalLoginResetPassword = function () {
7979  return {
7980    init: function init() {
7981      $(document).on('click', '.js-reset-password-recerived', function (e) {
7982        e.preventDefault();
7983        util.rightModalScreenChange.call(this, undefined, function (target) {});
7984      });
7985      $(document).on('click', '.js-reset-password-request', function (e) {
7986        e.preventDefault();
7987        util.rightModalScreenChange.call(this, undefined, function (target) {});
7988      });
7989      $(document).on('click', '.js-reset-password-gotohome', function (e) {
7990        e.preventDefault();
7991        util.rightModalClose.call(this, undefined, function (target) {});
7992      });
7993    },
7994    ready: function ready() {}
7995  };
7996}();
7997
7998/**
7999 * QuickView
8000 */
8001cpbUi.directQuickView = function (href, callback) {
8002  var modalHtml = '<div id="cpb-modal-quickview" class="cpb-modalR_container js-quickview_content" data-modal-type="quickview">\
8003        <div class="cpb-modalR_wrap">\
8004            <div class="cpb-modalR_contents cpb-cart_style">\
8005                <form action="#">\
8006                    <div class="cpb-modalR_scroll_cover">\
8007                        <div class="cpb-modalR_inner cpb-modal_scroll js-modal_scroll">\
8008                            <div class="cpb-modal_quickview">\
8009                                <button class="cpb-modalR_close js-quickview_close"><span class="invisible">CLOSE</span></button>\
8010                                <!-- pdp -->\
8011                                <div class="cpb-modal_quickview-inner"></div>\
8012                                <!-- /pdp -->\
8013                            </div><!-- / cpb-modal_quickview -->\
8014                        </div><!-- / cpb-modalR_inner -->\
8015                        <div class="cpb-modalR_bottom">\
8016                            <!-- price -->\
8017                            <div class="quantity_box"></div>\
8018                            <!-- /price -->\
8019                            <!-- button -->\
8020                            <div class="cmd-button_container"></div>\
8021                            <!-- /button -->\
8022                        </div><!-- / cpb-modalR_bottom -->\
8023                    </div><!-- / cpb-modalR_scroll_cover -->\
8024                </form>\
8025            </div><!-- / cpb-modalR_contents" -->\
8026        </div><!-- / cpb-modalR_wrap -->\
8027        <div class="cpb-modal_overlay js-quickview_overlay"></div>\
8028    </div><!-- / cpb-modalR_container -->';
8029
8030  $.ajax({
8031    type: 'GET',
8032    url: href,
8033    dataType: 'html'
8034  }).done(function (data, textStatus, jqXHR) {
8035    var $pdpHtml = $(data);
8036    var $modal = $(modalHtml);
8037
8038    $modal.find('.cpb-modalR_bottom .quantity_box').append($pdpHtml.find('#cpb-products_price').prop('outerHTML'));
8039    $modal.find('.cpb-modalR_bottom .cmd-button_container').append($pdpHtml.find('#cpb-products_submit').prop('outerHTML'));
8040    $modal.find('.cpb-modal_quickview-inner').append($pdpHtml.find('.cpb-products-details'));
8041
8042    $('body').append($modal);
8043
8044    if (typeof callback === 'function') callback();
8045  }).fail(function (jqXHR, textStatus, errorThrown) {});
8046};
8047
8048var initQuickView = function () {
8049  var _init = function _init() {
8050    $(document).on('click', '.js-quickview-btn', function (e) {
8051      e.preventDefault();
8052      cpbUi.directQuickView($(this).attr('href'), function () {
8053        cpbUi.pdp.ready();
8054
8055        util.rightModalOpen.call(this, 'quickview', function () {
8056          cpbUi.niceScroll.ready();
8057          cpbUi.sliderControl.resize();
8058          // init product's events
8059          product.initializeEvents();
8060        });
8061      });
8062    });
8063    $(document).on('click', '.js-quickview_close', function (e) {
8064      e.preventDefault();
8065      util.rightModalClose.call(this, 'quickview', function () {
8066        $('#cpb-modal-quickview').find('.js-modal_scroll').getNiceScroll().remove();
8067        $('#cpb-modal-quickview').remove();
8068      });
8069    });
8070    $(document).on('click', '.js-quickview_overlay', function (e) {
8071      e.preventDefault();
8072      util.rightModalClose.call(this, 'quickview', function () {
8073        $('#cpb-modal-quickview').find('.js-modal_scroll').getNiceScroll().remove();
8074        $('#cpb-modal-quickview').remove();
8075      });
8076    });
8077  };
8078
8079  return {
8080    init: function init() {
8081      _init();
8082    },
8083    ready: function ready() {}
8084  };
8085}();
8086
8087/**
8088 * PDP
8089 */
8090cpbUi.pdp = function () {
8091  var initPdpFooterNav = function initPdpFooterNav() {
8092    if (!$('.cpb-products_details_area')[0] || $('.cpb-products_details_area').hasClass('is-initialized')) return;
8093
8094    var pdpFooterShow = false;
8095
8096    $('.cpb-products_details_area').addClass('is-initialized');
8097
8098    $(window).on('scroll', function (e) {
8099      if (!cpbUi.isDomReady) return;
8100
8101      var pdpMainHeight = $('.cpb-products_details_area').offset().top + $('.cpb-products_details_area').height();
8102      var scrollTop = window.pageYOffset;
8103
8104      if ($('#footer').offset().top <= scrollTop + $(window).height()) {
8105        $('.cpb-products-cart_fixed').removeClass('is-show');
8106
8107        if (cpbUi.scrollDirection === 'up') {
8108          $('.cpb-grobal-header').removeClass('is-hide');
8109        }
8110      } else {
8111        if (cpbUi.scrollDirection === 'down') {
8112          if (!pdpFooterShow && pdpMainHeight <= scrollTop) {
8113            pdpFooterShow = true;
8114            $('.cpb-products-cart_fixed').addClass('is-show');
8115            $('.cpb-grobal-header').addClass('is-hide');
8116          } else if (pdpFooterShow && pdpMainHeight > scrollTop) {
8117            pdpFooterShow = false;
8118            $('.cpb-products-cart_fixed').removeClass('is-show');
8119            $('.cpb-grobal-header').removeClass('is-hide');
8120          }
8121        } else if (cpbUi.scrollDirection === 'up' && pdpFooterShow) {
8122          pdpFooterShow = false;
8123          $('.cpb-products-cart_fixed').removeClass('is-show');
8124          $('.cpb-grobal-header').removeClass('is-hide');
8125        }
8126      }
8127    });
8128  };
8129
8130  var sliderOptions = {
8131    productsPhoto: {
8132      dots: true,
8133      infinite: false,
8134      slidesToScroll: 1
8135    },
8136    swatches: {
8137      dots: false,
8138      slidesToShow: 5,
8139      slidesToScroll: 5,
8140      infinite: false,
8141      responsive: [{
8142        breakpoint: 1120,
8143        settings: {
8144          slidesToShow: 3,
8145          slidesToScroll: 3
8146        }
8147      }]
8148    }
8149  };
8150
8151  var initSlider = function initSlider() {
8152    if (!$('.js-products-photo_slider').hasClass('slick-initialized')) {
8153      $('.js-products-photo_slider').slick(sliderOptions.productsPhoto);
8154    }
8155    if (!$('.js-swatches_slider').hasClass('slick-initialized')) {
8156      $('.js-swatches_slider').slick(sliderOptions.swatches);
8157    }
8158  };
8159
8160  var productsColorSelect = function productsColorSelect(list) {
8161    var $pdp = $('.cpb-products-details');
8162    var $slider = $pdp.find('.js-products-photo_slider');
8163    $slider.slick('destroy');
8164    $slider.empty();
8165
8166    var html = '';
8167    for (var i = 0; i < list.length; i++) {
8168      list[i];
8169      html += '<div class="cpb-products-photo_box cmd-slide">';
8170      html += '<img src="' + list[i] + '" alt="">';
8171      html += '</div>';
8172    }
8173
8174    $slider.append(html);
8175    $slider.slick(sliderOptions.productsPhoto);
8176  };
8177
8178  var initSelectColorChip = function initSelectColorChip() {
8179    $(document).on('click', '.cpb-products-color_list .selectable', function (e) {
8180      e.preventDefault();
8181
8182      $('.cpb-products-color_list').find('.selectable').removeClass('selected');
8183      $('.cpb-products-color_list').find('.c-list-color-panel').removeClass('is-current');
8184
8185      var $box = $(this).closest('.cpb-products-color_list');
8186      var index = $box.find('.selectable').index($(this));
8187      $('.cpb-products-color_list').each(function () {
8188        var $btn = $(this).find('.selectable').eq(index);
8189        $btn.addClass('selected');
8190        $btn.find('.c-list-color-panel').addClass('is-current');
8191      });
8192
8193      /*
8194            画像リストを取得する処理
8195            */
8196      var tempList = ['https://www.cledepeau-beaute.com/dw/image/v2/BBSC_PRD/on/demandware.static/-/Sites-master-catalog-cpb/default/dw3ee84eec/products/images/rouge/product-detail-cmk-pic-99a-3-0003.png?sw=580&sh=580&sm=fit', 'https://www.cledepeau-beaute.com/dw/image/v2/BBSC_PRD/on/demandware.static/-/Sites-master-catalog-cpb/default/dwcd0dd4ef/products/images/rouge/product-detail-cmk-pic-99b-3-0003.png?sw=580&sh=580&sm=fit'];
8197
8198      cpbUi.pdp.productsColorSelect(tempList);
8199    });
8200  };
8201
8202  return {
8203    init: function init() {},
8204    productsColorSelect: productsColorSelect,
8205    ready: function ready() {
8206      initSlider();
8207      initPdpFooterNav();
8208      initSelectColorChip();
8209    }
8210  };
8211}();
8212
8213/**
8214 * Nice Scroll
8215 */
8216cpbUi.niceScroll = function () {
8217  return {
8218    ready: function ready() {
8219      $('.js-modal_scroll').each(function () {
8220        var $ns = $(this);
8221        if (!$ns.hasClass('scroll-initialized')) {
8222          $ns.niceScroll({
8223            cursorcolor: 'rgba(0,0,0, .3)',
8224            cursoropacitymin: 0.3,
8225            cursorwidth: 3,
8226            autohidemode: false,
8227            zindex: '10000',
8228            cursorborder: 'none'
8229          });
8230          $ns.addClass('scroll-initialized');
8231        }
8232      });
8233    },
8234    resize: function resize($wrap) {
8235      var $target = $wrap && $wrap[0] ? $wrap.find('.js-modal_scroll') : $('.js-modal_scroll');
8236      return $target.getNiceScroll().resize();
8237    }
8238  };
8239}();
8240
8241/**
8242 * Slider Control
8243 */
8244cpbUi.sliderControl = function () {
8245  return {
8246    ready: function ready() {},
8247    resize: function resize($wrap) {
8248      var $target = $wrap && $wrap[0] ? $wrap.find('.js-slider_control') : $('.js-slider_control');
8249      return $target.slick('setPosition');
8250    }
8251  };
8252}();
8253
8254/**
8255 * Recommend Slider
8256 */
8257cpbUi.recommendSlider = function () {
8258  var sliderOption = {
8259    dots: true,
8260    slidesToShow: 4,
8261    slidesToScroll: 4,
8262    infinite: false,
8263    responsive: [{
8264      breakpoint: 1024,
8265      settings: {
8266        slidesToShow: 3,
8267        slidesToScroll: 3
8268      }
8269    }, {
8270      breakpoint: 768,
8271      settings: {
8272        slidesToShow: 1,
8273        slidesToScroll: 1
8274      }
8275    }]
8276  };
8277
8278  return {
8279    init: function init() {},
8280    ready: function ready($slider) {
8281      if ($slider && $slider[0]) {
8282        if (!$slider.hasClass('slick-initialized')) {
8283          $slider.slick(sliderOption);
8284        }
8285      } else {
8286        if (!$('.js-reco_slider').hasClass('slick-initialized')) {
8287          $('.js-reco_slider').slick(sliderOption);
8288        }
8289      }
8290    }
8291  };
8292}();
8293
8294/**
8295 * Select Change Content
8296 */
8297var selectChangeContent = function () {
8298  return {
8299    init: function init() {
8300      $(document).on('change', '.js-select-change_tab', function (e) {
8301        var $box = $(this).closest('.js-select-change_tab_container');
8302        var val = $(this).val();
8303        var $target = $box.find('.js-select-change_tab_box').filter('[data-target="' + val + '"]');
8304
8305        if ($target[0]) {
8306          /*$box.find('.js-select-change_tab_box').fadeOut(200, function() {
8307                      $target.fadeIn(200);
8308                    });*/
8309          $box.find('.js-select-change_tab_box').removeClass('is-active');
8310          $target.addClass('is-active');
8311        }
8312      });
8313    },
8314    ready: function ready() {
8315      $('.js-select-change_tab').trigger('change');
8316    }
8317  };
8318}();
8319
8320/**
8321 * Standard Toggle
8322 */
8323var standardToggle = function () {
8324  var _init2 = function _init2() {
8325    $(document).on('click', '.js-toggle_btn', function (e) {
8326      e.preventDefault();
8327      var $box = $(this).closest('.js-toggle_container');
8328
8329      if ($box.hasClass('is-active')) {
8330        util.toggleClose($(this), $box, function () {});
8331      } else {
8332        util.toggleOpen($(this), $box, function () {});
8333      }
8334    });
8335
8336    $(document).on('click', '.js-togge_close', function (e) {
8337      e.preventDefault();
8338      var $box = $(this).closest('.js-toggle_container');
8339      var toggleType = $box.attr('data-toggle-type') ? $box.attr('data-toggle-type') 
8339: 'slide';
8340      if ($box.hasClass('is-active')) {
8341        util.toggleClose($(this), $box, function () {});
8342      }
8343    });
8344  };
8345
8346  return {
8347    init: function init() {
8348      _init2();
8349    },
8350    ready: function ready() {}
8351  };
8352}();
8353
8354/**
8355 * SNS Toggle
8356 */
8357var snsToggle = function () {
8358  var _init3 = function _init3() {
8359    $(document).on('click', '.js-toggle-sns_btn', function (e) {
8360      e.preventDefault();
8361      var $box = $(this).closest('.js-toggle_container');
8362      var $this = $(this);
8363
8364      if ($box.hasClass('is-active')) {
8365        util.toggleClose($this, $box, function () {});
8366      } else {
8367        util.toggleOpen($this, $box, function () {});
8368      }
8369
8370      $(document).on('click.toggle-sns', function (e) {
8371        if (!$(e.target).closest('.js-toggle_container')[0]) {
8372          util.toggleClose($this, $box, function () {});
8373          $(document).off('.toggle-sns');
8374        }
8375      });
8376    });
8377
8378    $(document).on('click', '.js-togge-sns_close', function (e) {
8379      e.preventDefault();
8380      var $box = $(this).closest('.js-toggle_container');
8381      if ($box.hasClass('is-active')) {
8382        util.toggleClose($(this), $box, function () {});
8383        $(document).off('.toggle-sns');
8384      }
8385    });
8386  };
8387
8388  return {
8389    init: function init() {
8390      _init3();
8391    },
8392    ready: function ready() {}
8393  };
8394}();
8395
8396/**
8397 * Input Toggle
8398 */
8399var inputToggle = function () {
8400  var toggle = function toggle() {
8401    var type = $(this).attr('type');
8402    type = type ? type.toLowerCase() : '';
8403    var target = $(this).attr('data-target');
8404    var $target = $(target);
8405
8406    if ($target[0]) {
8407      if (type === 'checkbox') {
8408        if ($(this).prop('checked')) {
8409          $target.addClass('is-active');
8410        } else {
8411          $target.removeClass('is-active');
8412        }
8413      } else if (type === 'radio') {}
8414    }
8415  };
8416
8417  var _init4 = function _init4() {
8418    $(document).on('change', '.js-input-toggle_btn', function (e) {
8419      toggle.call(this);
8420    });
8421  };
8422
8423  var initDisp = function initDisp() {
8424    $('.js-input-toggle_btn').each(function () {
8425      toggle.call(this);
8426    });
8427  };
8428
8429  return {
8430    init: function init() {
8431      _init4();
8432    },
8433    ready: function ready() {
8434      initDisp();
8435    }
8436  };
8437}();
8438
8439/**
8440 * Standard Tab
8441 */
8442var standardTab = function () {
8443  return {
8444    init: function init() {
8445      $(document).on('click', '.js-tab_btn', function (e) {
8446        e.preventDefault();
8447        var $box = $(this).closest('.js-tab_container');
8448        var target = $(this).attr('data-tab-target');
8449        util.tabOpen($(this), $box, target, function () {});
8450      });
8451    },
8452    ready: function ready() {}
8453  };
8454}();
8455
8456/**
8457 * Tab Accordion
8458 */
8459var tabAccordion = function () {
8460  var initClickEvent = function initClickEvent() {
8461    $(document).on('click', '.js-tab-acc_btn', function (e) {
8462      e.preventDefault();
8463      var $container = $(this).closest('.js-tab-acc_container');
8464      var target = $(this).attr('data-tab-target');
8465
8466      $container.find('.js-tab-acc_inner').removeClass('is-active');
8467      $container.find('.js-tab-acc_btn').removeClass('is-active');
8468      $container.find('.js-tab-acc_drawer_btn').removeClass('is-active');
8469      $container.find('.js-tab-acc_btn').filter('[data-tab-target="' + target + '"]').addClass('is-active');
8470      $container.find('.js-tab-acc_drawer_btn').filter('[data-tab-target="' + target + '"]').addClass('is-active');
8471
8472      $container.find('.js-tab-acc_inner').filter('[data-tab-contents="' + target + '"]').fadeIn(function () {
8473        $(this).addClass('is-active');
8474        $(this).css({
8475          display: ''
8476        });
8477      });
8478    });
8479
8480    $(document).on('click', '.js-tab-acc_drawer_btn', function (e) {
8481      e.preventDefault();
8482      var $container = $(this).closest('.js-tab-acc_container');
8483      var target = $(this).attr('data-tab-target');
8484
8485      if ($(this).hasClass('is-active')) {
8486        $container.find('.js-tab-acc_btn').filter('[data-tab-target="' + target + '"]').removeClass('is-active');
8487        $container.find('.js-tab-acc_drawer_btn').filter('[data-tab-target="' + target + '"]').removeClass('is-active');
8488        $container.find('.js-tab-acc_inner').filter('[data-tab-contents="' + target + '"]').slide
8488Up(function () {
8489          $(this).removeClass('is-active');
8490          $(this).css({
8491            display: ''
8492          });
8493        });
8494      } else {
8495        $container.find('.js-tab-acc_btn').filter('[data-tab-target="' + target + '"]').addClass('is-active');
8496        $container.find('.js-tab-acc_drawer_btn').filter('[data-tab-target="' + target + '"]').addClass('is-active');
8497
8498        $container.find('.js-tab-acc_inner').filter('[data-tab-contents="' + target + '"]').slideDown(function () {
8499          $(this).addClass('is-active');
8500          $(this).css({
8501            display: ''
8502          });
8503        });
8504
8505        // var $box = $container.find('.js-tab-acc_inner').filter('[data-tab-contents="' + target + '"]').closest('.js-tab-acc_box');
8506        // var position = $box.offset().top - $('.js-grobal-header').height();
8507        // $('html, body').animate({scrollTop:position}, 500);
8508      }
8509    });
8510
8511    $(document).on('click', '.js-tab-acc_close', function (e) {
8512      e.preventDefault();
8513      var $container = $(this).closest('.js-tab-acc_container');
8514      var $box = $(this).closest('.js-tab-acc_box');
8515      var target = $box.find('.js-tab-acc_drawer_btn').attr('data-tab-target');
8516
8517      $container.find('.js-tab-acc_btn').filter('[data-tab-target="' + target + '"]').removeClass('is-active');
8518      $container.find('.js-tab-acc_drawer_btn').filter('[data-tab-target="' + target + '"]').removeClass('is-active');
8519      $container.find('.js-tab-acc_inner').filter('[data-tab-contents="' + target + '"]').slide
8519Up(function () {
8520        $(this).removeClass('is-active');
8521        $(this).css({
8522          display: ''
8523        });
8524      });
8525    });
8526  };
8527
8528  var initMatchMedia = function initMatchMedia() {
8529    window.matchMedia('(min-width:769px)').addListener(function () {
8530      if (window.matchMedia('(min-width:769px)').matches) {
8531        $('.js-tab-acc_container').each(function () {
8532          var $container = $(this);
8533
8534          var $selectedBtns = $container.find('.js-tab-acc_drawer_btn.is-active');
8535          var $selectBtnFirst = $selectedBtns.length === 0 ? $container.find('.js-tab-acc_drawer_btn').eq(0) : $selectedBtns.first();
8536
8537          if ($selectedBtns.length === 1) return;
8538
8539          // reset
8540          $container.find('.js-tab-acc_drawer_btn').removeClass('is-active');
8541          $container.find('.js-tab-acc_btn').removeClass('is-active');
8542          $container.find('.js-tab-acc_inner').removeClass('is-active');
8543
8544          // set
8545          var target = $selectBtnFirst.attr('data-tab-target');
8546          $selectBtnFirst.addClass('is-active');
8547          $container.find('.js-tab-acc_btn').filter('[data-tab-target="' + target + '"]').addClass('is-active');
8548          $container.find('.js-tab-acc_inner').filter('[data-tab-contents="' + target + '"]').addClass('is-active');
8549        });
8550      }
8551    });
8552  };
8553
8554  return {
8555    init: function init() {
8556      initClickEvent();
8557      initMatchMedia();
8558    },
8559    ready: function ready() {}
8560  };
8561}();
8562
8563/**
8564 * Number Drop Down
8565 */
8566var numDropDown = function () {
8567  var initClickEvent = function initClickEvent() {
8568    $(document).on('click', '.js-num-drop_up', function (e) {
8569      e.preventDefault();
8570      var $box = $(this).closest('.js-num-drop_container');
8571      var limit = $box.find('.js-num-drop_select').children().length;
8572      var currentNum = $box.find('.js-num-drop_cnt').html();
8573
8574      if (currentNum < limit) {
8575        currentNum++;
8576        $box.find('.js-num-drop_cnt').html(currentNum);
8577        $box.find('.js-num-drop_select').children().find('a').removeClass('is-current');
8578        $box.find('.js-num-drop_select').children().eq(currentNum - 1).find('a').addClass('is-current');
8579        $box.find('.js-num-drop_input').val(currentNum);
8580      }
8581    });
8582    $(document).on('click', '.js-num-drop_down', function (e) {
8583      e.preventDefault();
8584      var $box = $(this).closest('.js-num-drop_container');
8585      var limit = $box.find('.js-num-drop_select').children().length;
8586      var currentNum = $box.find('.js-num-drop_cnt').html();
8587
8588      if (currentNum > 1) {
8589        currentNum--;
8590        $box.find('.js-num-drop_cnt').html(currentNum);
8591        $box.find('.js-num-drop_select').children().find('a').removeClass('is-current');
8592        $box.find('.js-num-drop_select').children().eq(currentNum - 1).find('a').addClass('is-current');
8593        $box.find('.js-num-drop_input').val(currentNum);
8594      }
8595    });
8596    $(document).on('click', '.js-num-drop_select a', function (e) {
8597      e.preventDefault();
8598      var $box = $(this).closest('.js-num-drop_container');
8599      var num = $(this).html();
8600      $box.find('.js-num-drop_cnt').html(num);
8601      $box.find('.js-num-drop_select').children().find('a').removeClass('is-current');
8602      $box.find('.js-num-drop_select').children().eq(num - 1).find('a').addClass('is-current');
8603      $box.find('.js-num-drop_input').val(num);
8604      $box.find('.js-num-drop_select').removeClass('is-active');
8605    });
8606    $(document).on('click', '.js-num-drop_drop', function (e) {
8607      e.preventDefault();
8608      var $box = $(this).closest('.js-num-drop_container');
8609      var eventName = '.event' + new Date().getTime();
8610
8611      if ($box.find('.js-num-drop_select').hasClass('is-active')) {
8612        $box.find('.js-num-drop_select').removeClass('is-active');
8613        $(document).off(eventName);
8614      } else {
8615        var offset = $(this).offset();
8616        var posY = offset.top - $(window).scrollTop();
8617        var height = $(window).height();
8618        if (posY * 2 > height) {
8619          $box.find('.js-num-drop_select').addClass('is-up');
8620        } else {
8621          $box.find('.js-num-drop_select').removeClass('is-up');
8622        }
8623
8624        $box.find('.js-num-drop_select').addClass('is-active');
8625
8626        $(document).on('click' + eventName + ' touchend' + eventName, function (e) {
8627          if (!$.contains($box[0], e.target)) {
8628            $box.find('.js-num-drop_select').removeClass('is-active');
8629            $(document).off(eventName);
8630          }
8631        });
8632      }
8633    });
8634  };
8635
8636  return {
8637    init: function init() {
8638      initClickEvent();
8639    },
8640    ready: function ready() {}
8641  };
8642}();
8643
8644/**
8645 * Cart
8646 */
8647var cart = function () {
8648  var initCartFooterNavNormal = function initCartFooterNavNormal() {
8649    if (!$('.cpb-cart-checkout_fixed')[0] || !$('.cpb-cart-side_submit')[0]) return;
8650
8651    var cartFooterShow = false;
8652
8653    $(window).on('scroll', function (e) {
8654      if (!cpbUi.isDomReady) return;
8655
8656      // var targetHeight = $('.cpb-cart-side_submit').offset().top + $('.cpb-cart-side_submit').height();
8657      var ghHeight = $('.js-grobal-header').height();
8658      var scrollTop = window.pageYOffset;
8659
8660      if (cpbUi.scrollDirection === 'down') {
8661        if (!cartFooterShow && ghHeight <= scrollTop) {
8662          cartFooterShow = true;
8663          $('.cpb-cart-checkout_fixed').addClass('is-show');
8664          $('.cpb-grobal-header').addClass('is-hide');
8665        } else if (cartFooterShow && ghHeight > scrollTop) {
8666          cartFooterShow = false;
8667          $('.cpb-cart-checkout_fixed').removeClass('is-show');
8668          $('.cpb-grobal-header').removeClass('is-hide');
8669        }
8670      } else if (cpbUi.scrollDirection === 'up' && cartFooterShow) {
8671        cartFooterShow = false;
8672        $('.cpb-cart-checkout_fixed').removeClass('is-show');
8673        $('.cpb-grobal-header').removeClass('is-hide');
8674      }
8675
8676      if ($('#footer').offset().top <= scrollTop + $(window).height()) {
8677        $('.cpb-cart-checkout_fixed').removeClass('is-show');
8678
8679        if (cpbUi.scrollDirection === 'up') {
8680          $('.cpb-grobal-header').removeClass('is-hide');
8681        }
8682      } else {}
8683    });
8684  };
8685
8686  var initCartFooterNavSimple = function initCartFooterNavSimple() {
8687    if (!$('.cpb-cart-checkout_fixed')[0]) return;
8688
8689    var cartFooterShow = false;
8690
8691    $(window).on('scroll', function (e) {
8692      if (!cpbUi.isDomReady) return;
8693
8694      var scrollTop = window.pageYOffset;
8695
8696      if ($('#footer').offset().top <= scrollTop + $(window).height()) {
8697        $('.cpb-cart-checkout_fixed').addClass('is-bottom');
8698      } else {
8699        $('.cpb-cart-checkout_fixed').removeClass('is-bottom');
8700      }
8701    });
8702  };
8703
8704  var initCreditCardSecurityInputCheck = function initCreditCardSecurityInputCheck() {
8705    $(document).on('focusin', '.js-security-code-check input[type="text"]', function (e) {
8706      var $box = $(this).closest('.js-security-code-check');
8707      $box.find('input[type="radio"]').prop('checked', true);
8708    });
8709  };
8710
8711  var initInnerCheckboxTrigger = function initInnerCheckboxTrigger() {
8712    $(document).on('click', '.js-inner-checkbox-trigger', function (e) {
8713      var $checkbox = $(this).find('input[type="checkbox"]');
8714      var flg = $checkbox.prop('checked');
8715      $checkbox.prop('checked', !flg);
8716    });
8717  };
8718
8719  var initCreditTypeSelectImage = function initCreditTypeSelectImage() {
8720    $(document).on('change', '.js-credit-type-select', function (e) {
8721      if ($(this).val()) {
8722        var path = $(this).find('option:selected').attr('data-image');
8723        var alt = $(this).find('option:selected').text();
8724        $('.js-credit-type-image').html('<img src="' + path + '" alt="' + alt + '">');
8725      } else {
8726        $('.js-credit-type-image').html('');
8727      }
8728    });
8729  };
8730
8731  var initRadioTab = function initRadioTab() {
8732    $(document).on('change', '.js-tab_radio', function (e) {
8733      e.preventDefault();
8734      var $box = $(this).closest('.js-tab_container');
8735      var $contents = $box.find('.js-tab_contents');
8736      var target = $(this).attr('data-tab-target');
8737      var $target = $contents.filter('[data-tab-contents="' + target + '"]');
8738
8739      $contents.removeClass('is-active');
8740
8741      if ($target[0]) {
8742        $target.addClass('is-active');
8743      }
8744
8745      cpbUi.niceScroll.resize();
8746    });
8747  };
8748
8749  return {
8750    init: function init() {
8751      initCreditCardSecurityInputCheck();
8752      initRadioTab();
8753      initInnerCheckboxTrigger();
8754      initCreditTypeSelectImage();
8755    },
8756    ready: function ready() {
8757      if ($('.cpb-grobal-header').hasClass('is-simple')) {
8758        initCartFooterNavSimple();
8759      } else {
8760        initCartFooterNavNormal();
8761      }
8762    }
8763  };
8764}();
8765
8766/**
8767 * Utility Functions
8768 */
8769var util = {
8770  toggleOpen: function toggleOpen($btn, $box, callback) {
8771    var toggleType = $box.attr('data-toggle-type') ? $box.attr('data-toggle-type') 
8771: 'fade';
8772    if (toggleType === 'fade') {
8773      $box.find('.js-toggle_contents').eq(0).fadeIn(200, function () {
8774        $box.addClass('is-active');
8775        $(this).css('display', '');
8776        if (typeof callback === 'function') callback();
8777      });
8778    } else if (toggleType === 'slide') {
8779      $box.find('.js-toggle_contents').eq(0).slideDown(200, function () {
8780        $box.addClass('is-active');
8781        $(this).css('display', '');
8782        if (typeof callback === 'function') callback();
8783      });
8784    }
8785  },
8786  toggleClose: function toggleClose($btn, $box, callback) {
8787    var toggleType = $box.attr('data-toggle-type') ? $box.attr('data-toggle-type') : 'fade';
8788    if (toggleType === 'fade') {
8789      $box.find('.js-toggle_contents').eq(0).fadeOut(200, function () {
8790        $box.removeClass('is-active');
8791        $(this).css('display', '');
8792        if (typeof callback === 'function') callback();
8793      });
8794    } else if (toggleType === 'slide') {
8795      $box.find('.js-toggle_contents').eq(0).slideUp(200, function () {
8796        $box.removeClass('is-active');
8797        $(this).css('display', '');
8798        if (typeof callback === 'function') callback();
8799      });
8800    }
8801  },
8802  tabOpen: function tabOpen($btn, $box, target, callback) {
8803    var $btns = $box.find('.js-tab_btn');
8804    var $contents = $box.find('.js-tab_contents');
8805    var $target = $contents.filter('[data-tab-contents="' + target + '"]');
8806
8807    if ($target[0] && !$btn.hasClass('is-active')) {
8808      $btns.removeClass('is-active');
8809      $contents.removeClass('is-active');
8810      $btn.addClass('is-active');
8811      $target.addClass('is-active');
8812
8813      // scrollbar & slider reset
8814      cpbUi.niceScroll.resize($target);
8815      cpbUi.sliderControl.resize($target);
8816    }
8817  },
8818  rightModalOpen: function rightModalOpen(target, callback) {
8819    var baseClass = target ? target : 'modal-r';
8820    target = target || $(this).attr('data-modal-target');
8821
8822    var $modal = $('.js-' + baseClass + '_content[data-modal-type="' + target + '"]');
8823    if ($modal[0]) {
8824      util.setModalScrollbarFix();
8825      $modal.addClass('is-active');
8826      $('html').addClass('is-modal-open');
8827      setTimeout(function () {
8828        $modal.find('.js-' + baseClass + '_overlay').fadeIn(200, function () {
8829          if (typeof callback === 'function') {
8830            callback(target);
8831          }
8832        });
8833        $modal.find('.cpb-modalR_wrap').css({
8834          transform: 'translateX(0)'
8835        });
8836        cpbUi.niceScroll.resize($modal);
8837      }, 10);
8838    }
8839  },
8840  rightModalClose: function rightModalClose(target, callback) {
8841    var baseClass = target ? target : 'modal-r';
8842    var $modal = $(this).closest('.js-' + baseClass + '_content');
8843    if ($modal[0]) {
8844      var target = $modal.attr('data-modal-type');
8845      var $modalWrap = $modal.find('.cpb-modalR_wrap');
8846      $modalWrap.on(transitionEndEvents, function () {
8847        $modal.find('.js-' + baseClass + '_overlay').fadeOut(200, function () {
8848          $('html').removeClass('is-modal-open');
8849          util.removeModalScrollbarFix();
8850          $modal.removeClass('is-active');
8851          if (typeof callback === 'function') {
8852            callback(target);
8853          }
8854        });
8855        $modalWrap.off();
8856      });
8857      $modal.find('.cpb-modalR_wrap').css({
8858        transform: 'translateX(100%)'
8859      });
8860    }
8861  },
8862  centerModalOpen: function centerModalOpen(target, callback) {
8863    var baseClass = target ? target : 'modal-c';
8864    target = target || $(this).attr('data-modal-target');
8865
8866    var $modal = $('.js-' + baseClass + '_content[data-modal-type="' + target + '"]');
8867    if ($modal[0]) {
8868      util.setModalScrollbarFix();
8869      $('html').addClass('is-modal-open');
8870      $modal.fadeIn(200, function () {
8871        $modal.addClass('is-active');
8872        $modal.css({
8873          display: ''
8874        });
8875        if (typeof callback === 'function') {
8876          callback(target);
8877        }
8878      });
8879      cpbUi.niceScroll.resize($modal);
8880    }
8881  },
8882  centerModalClose: function centerModalClose(target, callback) {
8883    var baseClass = target ? target : 'modal-c';
8884    var $modal = $(this).closest('.js-' + baseClass + '_content');
8885    if ($modal[0]) {
8886      var target = $modal.attr('data-modal-type');
8887      $modal.fadeOut(200, function () {
8888        $('html').removeClass('is-modal-open');
8889        util.removeModalScrollbarFix();
8890        $modal.removeClass('is-active');
8891        $modal.css({
8892          display: ''
8893        });
8894        if (typeof callback === 'function') {
8895          callback(target);
8896        }
8897      });
8898    }
8899  },
8900  rightModalScreenChange: function rightModalScreenChange(target, callback) {
8901    var baseClass = target ? target : 'modal-r';
8902    var $modal = $(this).closest('.js-' + baseClass + '_content');
8903    if ($modal[0]) {
8904      var targetName = $(this).attr('data-target');
8905      var $target = $modal.find('.js-screen[data-name="' + targetName + '"]');
8906      $modal.find('.js-screen').addClass('is-hide');
8907      $target.removeClass('is-hide');
8908
8909      if (typeof callback === 'function') {
8910        callback(target);
8911      }
8912    }
8913  },
8914  hasScrollbar: function hasScrollbar(windowHeight) {
8915    return document.body.scrollHeight > (windowHeight || $(window).height());
8916  },
8917  getScrollbarSize: function getScrollbarSize() {
8918    if (cpbUi.scrollbarSize === undefined) {
8919      var scrollDiv = document.createElement('div');
8920      scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
8921      document.body.appendChild(scrollDiv);
8922      cpbUi.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
8923      document.body.removeChild(scrollDiv);
8924    }
8925    return cpbUi.scrollbarSize;
8926  },
8927  setModalScrollbarFix: function setModalScrollbarFix(windowHeight) {
8928    if (util.hasScrollbar(windowHeight)) {
8929      var ss = util.getScrollbarSize();
8930      if (ss) {
8931        $('html').css({
8932          marginRight: ss + 'px'
8933        });
8934      }
8935    }
8936  },
8937  removeModalScrollbarFix: function removeModalScrollbarFix() {
8938    $('html').css({
8939      marginRight: ''
8940    });
8941  },
8942  getUniqueStr: function getUniqueStr(myStrong) {
8943    var strong = 1000;
8944    if (myStrong) strong = myStrong;
8945    return new Date().getTime().toString(16) + Math.floor(strong * Math.random()).toString(16);
8946  }
8947};
8948
8949cpbUi.util = util;
8950
8951/**
8952 * Other
8953 */
8954var setDirectionCheck = function setDirectionCheck() {
8955  var defDirectionCheck = window.pageYOffset;
8956  var $html = $('html');
8957  $(window).on('scroll', function (e) {
8958    var scrollTop = window.pageYOffset;
8959    var flg = '';
8960    if (defDirectionCheck < scrollTop) {
8961      flg = 'down';
8962      if ($html.hasClass('is-up')) $html.removeClass('is-up');
8963    } else if (defDirectionCheck > scrollTop) {
8964      flg = 'up';
8965      if (!$html.hasClass('is-up')) $html.addClass('is-up');
8966    }
8967
8968    if (scrollTop === 0 && !$html.hasClass('is-pos-top')) {
8969      $html.addClass('is-pos-top');
8970    } else if (scrollTop !== 0 && $html.hasClass('is-pos-top')) {
8971      $html.removeClass('is-pos-top');
8972    }
8973
8974    cpbUi.scrollDirection = flg;
8975    defDirectionCheck = scrollTop;
8976  });
8977};
8978
8979/**
8980 * PDP SKINCOLOR
8981 */
8982cpbUi.pdpSkinColor = function () {
8983  var itemSort = function itemSort(array) {
8984    array.sort(function (a, b) {
8985      return a[0].skincolor_num - b[0].skincolor_num;
8986    });
8987    for (var i = 0; i < array.length; i++) {
8988      array[i].sort(function (a, b) {
8989        return a.no - b.no;
8990      });
8991    }
8992    return array;
8993  };
8994
8995  var getSkincolorDefaultNum = function getSkincolorDefaultNum(array) {
8996    var defaultNum;
8997    for (var i = 0; i < array.length; i++) {
8998      for (var j = 0; j < array[i].length; j++) {
8999        if (array[i][j].default && array[i][j].default === '1') {
9000          defaultNum = array[i][j].skincolor_num;
9001          break;
9002        }
9003      }
9004    }
9005    return defaultNum - 1;
9006  };
9007
9008  var skinColorMount = function skinColorMount() {
9009    var SkinColorComponent = Vue.extend({
9010      props: ['skincolorData', 'skinColorDefaultNum', 'skinColorDefaultView'],
9011      template: '<div class="pdp-skincolor">\
9012                   <h3 class="pdp-skincolor_ttl"><span>EXAMPLE OF USE</span></h3>\
9013\
9014                   <div class="pdp-skincolor_container cmd-tabAcc_container">\
9015                     <ul class="pdp-skincolor_skincolor-tabs cpb-products-summary_tab_list cmd-tabAcc_list cmd-md-4">\
9016                       <li class="pdp-skincolor_skincolor-tab" v-for="(skincolor, skinIndex) in skincolorData" :key="\'skincolorTab\' + skinIndex">\
9017                         <a href="javascript:void(0);" class="pdp-skincolor_skincolor-btn cmd-tabAcc_btn js-skincolor_skincolor-btn" :class="[{\'is-active\': isDefault(skinIndex)}]" :data-skincolor-num="skinIndex" data-type="pc">\
9018                           <span v-text="\'SKIN TONE \' + skincolor[0].skincolor_num"></span>\
9019                         </a>\
9020                       </li>\
9021                     </ul>\
9022\
9023                     <div class="pdp-skincolor_view-tabs">\
9024                       <div class="pdp-skincolor_view-tab _image-view">\
9025                         <a href="javascript:void(0);" class="pdp-skincolor_view-btn icoset js-skincolor_view-btn" :class="[{\'is-active\': isDefaultView(\'image\')}]" data-view-type="image"><span>Image VIEW</span></a>\
9026                       </div>\
9027                       <div class="pdp-skincolor_view-tab _grid-view">\
9028                         <a href="javascript:void(0);" class="pdp-skincolor_view-btn icoset js-skincolor_view-btn" :class="[{\'is-active\': isDefaultView(\'grid\')}]" data-view-type="grid"><span>Grid VIEW</span></a>\
9029                       </div>\
9030                     </div>\
9031\
9032                     <div class="pdp-skincolor_contents">\
9033                       <ul class="pdp-skincolor_content _image-view cmd-tabAcc_contents" :class="[{\'is-active\': isDefaultView(\'image\')}]" data-view-type="image">\
9034                         <li class="pdp-skincolor_content-skincolor cmd-tabAcc_box" :class="[{\'is-active\': isDefault(skinIndex)}]" v-for="(skincolor, skinIndex) in skincolorData" :key="\'skincolorContent\' + skinIndex" :data-skincolor-num="skinIndex">\
9035\
9036                           <div class="pdp-skincolor_sp-toggle cmd-tabAcc-in_btn">\
9037                             <a href="javascript:void(0);" class="pdp-skincolor_skincolor-btn cmd-tabAcc_drawer_btn js-skincolor_skincolor-btn" :class="[{\'is-active\': isDefault(skinIndex)}]" :data-skincolor-num="skinIndex" data-type="sp"><span v-text="\'SKIN TONE \' + skincolor[0].skincolor_num"></span></a>\
9038                           </div>\
9039\
9040                           <div class="pdp-skincolor_items js-skincolor-slider">\
9041                             <div class="pdp-skincolor_item" v-for="(item, itemIndex) in skincolor" :key="\'skincolorItem\' + item.no">\
9042                               <div class="item-row">\
9043                                 <div class="item-column _image">\
9044                                   <div class="item_color-image">\
9045                                     <img :src="getImagePath(item)" alt="">\
9046                                   </div>\
9047                                 </div>\
9048                                 <div class="item-column _color">\
9049                                   <div class="item-column_inner">\
9050                                     <div class="item_name" v-text="item.name"></div>\
9051                                     <div class="item_colorchip"><img :src="item.colorchip_path" alt=""></div>\
9052                                     <div class="item_colorchip-name">\
9053                                       <span v-text="item.color_code"></span>\
9054                                       <span v-text="\' \' + item.color_name" v-if="item.color_name"></span>\
9055                                     </div>\
9056                                   </div>\
9057                                 </div>\
9058                               </div>\
9059                             </div>\
9060                           </div>\
9061                         </li>\
9062                       </ul>\
9063\
9064                       <ul class="pdp-skincolor_content _grid-view cmd-tabAcc_contents" :class="[{\'is-active\': isDefaultView(\'grid\')}]" data-view-type="grid">\
9065                         <li class="pdp-skincolor_content-skincolor" :class="[{\'is-active\': isDefault(skinIndex)}]" v-for="(skincolor, skinIndex) in skincolorData" :key="\'skincolorContent\' + skinIndex" :data-skincolor-num="skinIndex">\
9066                           <ul class="pdp-skincolor_items">\
9067                             <li class="pdp-skincolor_item" v-for="(item, itemIndex) in skincolor" :key="\'skincolorItem\' + item.no">\
9068                               <div class="item_color-image">\
9069                                 <img :src="getImagePath(item)" alt="">\
9070                               </div>\
9071                               <div class="item_colorchip-name">\
9072                                 <span v-text="item.color_code"></span>\
9073                                 <span v-text="\' \' + item.color_name" v-if="item.color_name"></span>\
9074                               </div>\
9075                             </li>\
9076                           </ul>\
9077                         </li>\
9078                       </ul>\
9079                     </div>\
9080                   </div>\
9081                 </div>'
9082    });
9083
9084    var skinColorItemData = itemSort(skinColorData);
9085    var skinColorDefaultNum = getSkincolorDefaultNum(skinColorItemData);
9086    var skinColorDefaultView = $('#skincolor-app').attr('data-default-view') || 'image';
9087    var skinColorComponent = new SkinColorComponent({
9088      propsData: {
9089        skincolorData: skinColorItemData,
9090        skinColorDefaultNum: skinColorDefaultNum,
9091        skinColorDefaultView: skinColorDefaultView
9092      },
9093      methods: {
9094        getImagePath: function getImagePath(item) {
9095          return '/on/demandware.static/Sites-cpb_' + item.country + '-Site/pdp/skincolor/images/' + item.product_code + '/' + item.filename;
9096        },
9097        isDefault: function isDefault(skinIndex) {
9098          return skinIndex === this.skinColorDefaultNum;
9099        },
9100        isDefaultView: function isDefaultView(view) {
9101          return this.skinColorDefaultView === view;
9102        }
9103      }
9104    }).$mount();
9105
9106    var $skincolorApp = $('#skincolor-app');
9107    $skincolorApp.html(skinColorComponent.$el.outerHTML);
9108
9109    var $skincolor = $skincolorApp.find('.pdp-skincolor');
9110    $skincolor.addClass('initialize');
9111    $skincolor.find('.js-skincolor-slider').slick();
9112
9113    var setSkincolorHandler = function setSkincolorHandler(e) {
9114      e.preventDefault();
9115      var skincolorNum = $(this).attr('data-skincolor-num');
9116      var $skincolorContent = $skincolor.find('.pdp-skincolor_content-skincolor');
9117      var $skincolorBtn = $skincolor.find('.js-skincolor_skincolor-btn');
9118      var $skincolorSelectBtn = $skincolorBtn.filter('[data-skincolor-num="' + skincolorNum + '"]');
9119      var $skincolorContentSelect = $skincolorContent.filter('[data-skincolor-num="' + skincolorNum + '"]');
9120      var $skincolorContentSelectItems = $skincolorContentSelect.find('.pdp-skincolor_items');
9121      var isActive = $(this).hasClass('is-active');
9122
9123      if ($(this).attr('data-type') === 'sp') {
9124        if (isActive) {
9125          $skincolorSelectBtn.removeClass('is-active');
9126          $skincolorContentSelectItems.find('.slick-arrow').hide();
9127          $skincolorContentSelectItems.slideUp(300, function () {
9128            $skincolorContentSelect.removeClass('is-active');
9129            $skincolorContentSelectItems.css({
9130              display: ''
9131            });
9132            $skincolorContentSelectItems.find('.slick-arrow').css({
9133              display: ''
9134            });
9135          });
9136        } else {
9137          $skincolor.find('.js-skincolor_skincolor-btn').filter('[data-skincolor-num="' + skincolorNum + '"]').addClass('is-active');
9138
9139          // slider setposition
9140          $skincolorContentSelectItems.show().height(0);
9141          $skincolorContentSelect.find('.js-skincolor-slider').slick('setPosition');
9142          $skincolorContentSelectItems.hide().css({
9143            height: ''
9144          });
9145
9146          $skincolorContentSelect.find('.item-column_inner').css({
9147            opacity: 0
9148          });
9149          $skincolorContentSelect.find('.slick-arrow').css({
9150            opacity: 0
9151          });
9152
9153          $skincolorContentSelectItems.slideDown(500, function () {
9154            $skincolorContentSelect.addClass('is-active');
9155            $skincolorContentSelectItems.css({
9156              display: ''
9157            });
9158          });
9159
9160          setTimeout(function () {
9161            $skincolorContentSelect.find('.item-column_inner').animate({
9162              opacity: 1
9163            });
9164            $skincolorContentSelect.find('.slick-arrow').animate({
9165              opacity: 1
9166            }, function () {
9167              $skincolorContentSelect.find('.item-column_inner').css({
9168                display: ''
9169              });
9170              $skincolorContentSelect.find('.slick-arrow').css({
9171                display: ''
9172              });
9173            });
9174          }, 450);
9175        }
9176      } else {
9177        if (isActive) return;
9178
9179        $skincolor.find('.js-skincolor_skincolor-btn').removeClass('is-active');
9180        $skincolor.find('.js-skincolor_skincolor-btn').filter('[data-skincolor-num="' + skincolorNum + '"]').addClass('is-active');
9181
9182        $skincolorContent.css({
9183          opacity: 0
9184        });
9185
9186        setTimeout(function () {
9187          $skincolorContent.removeClass('is-active');
9188          $skincolorContent.css({
9189            opacity: ''
9190          });
9191          $skincolorContentSelect.addClass('is-active').css({
9192            opacity: 0
9193          });
9194
9195          setTimeout(function () {
9196            $skincolorContentSelect.css({
9197              opacity: ''
9198            });
9199            $skincolorContentSelect.find('.js-skincolor-slider').slick('setPosition');
9200          }, 50);
9201        }, 250);
9202      }
9203    };
9204
9205    var setViewTypeHandler = function setViewTypeHandler(e) {
9206      e.preventDefault();
9207      if ($(this).hasClass('is-active')) return;
9208
9209      var viewType = $(this).attr('data-view-type');
9210
9211      $skincolor.find('.pdp-skincolor_view-btn').removeClass('is-active');
9212      $skincolor.find('.pdp-skincolor_view-btn').filter('[data-view-type="' + viewType + '"]').addClass('is-active');
9213
9214      $skincolor.find('.pdp-skincolor_content').css({
9215        opacity: 0
9216      });
9217
9218      setTimeout(function () {
9219        $skincolor.find('.pdp-skincolor_content').removeClass('is-active');
9220        $skincolor.find('.pdp-skincolor_content').filter('[data-view-type="' + viewType + '"]').addClass('is-active').css({
9221          opacity: 0
9222        });
9223
9224        setTimeout(function () {
9225          $skincolor.find('.pdp-skincolor_content').css({
9226            opacity: ''
9227          });
9228
9229          if (viewType === 'image') {
9230            $skincolor.find('.pdp-skincolor_content').filter('[data-view-type="' + viewType + '"]').find('.js-skincolor-slider').slick('setPosition');
9231          }
9232        }, 50);
9233      }, 250);
9234    };
9235
9236    $(document).on('click', '.js-skincolor_skincolor-btn', setSkincolorHandler);
9237    $(document).on('click', '.js-skincolor_skincolor-btn-sp', setSkincolorHandler);
9238    $(document).on('click', '.js-skincolor_view-btn', setViewTypeHandler);
9239  };
9240
9241  var initMatchMedia = function initMatchMedia() {
9242    window.matchMedia('(min-width:769px)').addListener(function () {
9243      if (window.matchMedia('(min-width:769px)').matches) {
9244        var $skinColor = $('#skincolor-app');
9245        var $selectedBtns = $skinColor.find('.pdp-skincolor_skincolor-tabs').find('.js-skincolor_skincolor-btn.is-active');
9246        var $selectBtnFirst = $selectedBtns.length === 0 ? $skinColor.find('.pdp-skincolor_skincolor-tabs').find('.js-skincolor_skincolor-btn').eq(0) : $selectedBtns.first();
9247
9248        if ($selectedBtns.length === 1) return;
9249
9250        // reset
9251        $skinColor.find('.js-skincolor_skincolor-btn').removeClass('is-active');
9252        $skinColor.find('.pdp-skincolor_content-skincolor').removeClass('is-active');
9253
9254        // set
9255        var targetNum = $selectBtnFirst.attr('data-skincolor-num');
9256        $selectBtnFirst.addClass('is-active');
9257
9258        var $selectedImageContent = $skinColor.find('.pdp-skincolor_content._image-view').find('.pdp-skincolor_content-skincolor').filter('[data-skincolor-num="' + targetNum + '"]');
9259        $selectedImageContent.addClass('is-active');
9260        $selectedImageContent.find('.js-skincolor_skincolor-btn').addClass('is-active');
9261
9262        var $selectedGridContent = $skinColor.find('.pdp-skincolor_content._grid-view').find('.pdp-skincolor_content-skincolor').filter('[data-skincolor-num="' + targetNum + '"]');
9263        $selectedGridContent.addClass('is-active');
9264      }
9265    });
9266  };
9267
9268  return {
9269    init: function init() {},
9270    ready: function ready() {
9271      if (typeof window.skinColorData === 'undefined') return;
9272      if (!$('#skincolor-app')[0]) return;
9273      skinColorMount();
9274      initMatchMedia();
9275    }
9276  };
9277}();
9278
9279/**
9280 * Naire Modal
9281 */
9282var naireModal = function () {
9283  var naireTransition = function naireTransition(callback) {
9284    var target = $(this).attr('data-target');
9285    var $box = $(this).closest('.js-modal-r_content');
9286    var $currentBox = $(this).closest('.cpb-modalR_scroll_cover');
9287    var $targetBox = $box.find('.cpb-modalR_scroll_cover').filter('[data-name="' + target + '"]');
9288
9289    $currentBox.animate({
9290      opacity: 0
9291    }, 300, function () {
9292      $currentBox.addClass('is-hide').css({
9293        opacity: ''
9294      });
9295      $targetBox.removeClass('is-hide').css({
9296        opacity: 0
9297      }).animate({
9298        opacity: 1
9299      }, 300, function () {
9300        $targetBox.css({
9301          opacity: ''
9302        });
9303      });
9304
9305      cpbUi.niceScroll.resize($box);
9306
9307      if (typeof callback === 'function') callback();
9308    });
9309  };
9310
9311  return {
9312    init: function init() {
9313      $(document).on('click', '.js-naire-product', function (e) {
9314        e.preventDefault();
9315        naireTransition.call(this, function () {});
9316      });
9317      $(document).on('click', '.js-naire-setting', function (e) {
9318        e.preventDefault();
9319        naireTransition.call(this, function () {});
9320      });
9321      $(document).on('click', '.js-naire-back', function (e) {
9322        e.preventDefault();
9323        naireTransition.call(this, function () {});
9324      });
9325
9326      var textCheck = function textCheck() {
9327        var $box = $(this).closest('.js-modal-r_content');
9328        var text = $(this).val();
9329
9330        text = text.replace(/[^a-zA-Z0-9 .&]/g, '');
9331        text = text.substr(0, 10);
9332
9333        $(this).val(text);
9334        $box.find('.js-naire-preview').text(text);
9335
9336        if (!text) {
9337          $box.find('.js-naire-preview').text($(this).attr('placeholder'));
9338        }
9339      };
9340
9341      var composition = false;
9342
9343      $(document).on('keyup', '.js-naire-input', function (e) {
9344        if (!composition) {
9345          textCheck.call(this);
9346        }
9347      });
9348
9349      $(document).on('compositionstart', '.js-naire-input', function (e) {
9350        e.preventDefault();
9351        composition = true;
9352      });
9353      $(document).on('compositionend', '.js-naire-input', function (e) {
9354        composition = false;
9355        textCheck.call(this);
9356      });
9357
9358      $(document).on('focusout', '.js-naire-input', function (e) {
9359        textCheck.call(this);
9360      });
9361    },
9362    ready: function ready() {}
9363  };
9364}();
9365
9366/**
9367 * Movie Modal
9368 */
9369var movieModal = function () {
9370  var modalHtml = '\
9371 <div class="cpb-modalC_container cmd-modal-video js-modal-video_content">\
9372   <div class="cpb-modalC_wrap">\
9373     <div class="cpb-modalC_inner">\
9374       <div class="cmd-video_flex">\
9375         <iframe id="ytplayer" type="text/html" width="640" height="360" src="{{URL}}" frameborder="0" allowfullscreen allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"></iframe>\
9376       </div><!-- / cmd-video_flex-->\
9377     </div><!-- / cpb-modalC_inner -->\
9378   </div><!-- / cpb-modalC_wrap -->\
9379   <div class="cpb-modal_overlay js-modal-video_overlay"></div>\
9380 </div><!-- / cpb-modalC_container -->';
9381
9382  return {
9383    init: function init() {
9384      $(document).on('click', '.js-modal-video', function (e) {
9385        e.preventDefault();
9386        var embedUrl = $(this).attr('href');
9387        var html = modalHtml.replace('{{URL}}', embedUrl);
9388        var $modal = $(html);
9389        var $wrapSlider = $(this).closest('.js-slider_container');
9390
9391        $('html').addClass('is-modal-open');
9392        $('body').append($modal);
9393
9394        if ($wrapSlider[0] && $wrapSlider.hasClass('slick-initialized')) {
9395          var isAutoPlay = cpbUi.sectionSlider.getAutoPlay($wrapSlider);
9396          if (isAutoPlay) {
9397            var unique = 'id' + cpbUi.util.getUniqueStr();
9398            $modal.attr('data-slider-autoplay', 'true');
9399            $modal.attr('data-original', unique);
9400            $wrapSlider.addClass(unique);
9401            cpbUi.sectionSlider.pause($wrapSlider);
9402          }
9403        }
9404
9405        $modal.fadeIn();
9406      });
9407
9408      var closeFunc = function closeFunc(e) {
9409        e.preventDefault();
9410        var $modal = $(this).closest('.js-modal-video_content');
9411        var unique = $modal.attr('data-original');
9412        var $original = $('.' + unique);
9413        $modal.animate({
9414          opacity: 0
9415        }, 300, function () {
9416          $modal.find('iframe').attr('src', '//about:blank');
9417          $modal.remove();
9418          cpbUi.sectionSlider.play($original);
9419          $original.removeClass(unique);
9420          $('html').removeClass('is-modal-open');
9421        });
9422      };
9423
9424      $(document).on('click', '.js-modal-video_close', closeFunc);
9425      $(document).on('click', '.js-modal-video_overlay', closeFunc);
9426    },
9427    ready: function ready() {}
9428  };
9429}();
9430
9431/**
9432 * section slider
9433 */
9434cpbUi.sectionSlider = function () {
9435  var ytPlayersMainSlider = {};
9436  var matchMediaPC = window.matchMedia('screen and (min-width: 993px)');
9437  var isPC = function isPC() {
9438    return matchMediaPC.matches;
9439  };
9440
9441  var getBgMovieSize = function getBgMovieSize(aspectW, aspectH) {
9442    aspectW = aspectW || 16;
9443    aspectH = aspectH || 9;
9444    var videoRatio = (aspectW / aspectH).toFixed(2);
9445    var minWidth = window.innerWidth ? window.innerWidth : $(window).width();
9446    var minHeight = $(window).height() + 100;
9447    var widthRatio = minWidth / aspectW;
9448    var heightRatio = minHeight / aspectH;
9449    var size = {};
9450    if (widthRatio > heightRatio) {
9451      size.width = minWidth;
9452      size.height = Math.ceil(minWidth / videoRatio);
9453    } else {
9454      size.height = minHeight;
9455      size.width = Math.ceil(minHeight * videoRatio);
9456    }
9457    return size;
9458  };
9459
9460  var mainSliderReady = function mainSliderReady() {
9461    var windowWidth = $(window).width();
9462    var windowDelay = 0;
9463
9464    $('.js-slider_container[data-slider-type="main"]').each(function () {
9465      if ($(this).hasClass('slick-initialized')) return;
9466
9467      var $slider = $(this);
9468      var $sliderWrap = $slider.parent('.cmd-section_slider');
9469      var uniqueId = 'id' + cpbUi.util.getUniqueStr();
9470      var carouselDuration = $(this).attr('data-slider-duration') || 15000;
9471      var videoList = [];
9472      var nextTimer;
9473      var seekbarTimer;
9474      var loadingTimer;
9475      var isSingleAndMovie = false;
9476      var hasVideoContent = $slider.find('.cmd-visual_video')[0];
9477      ytPlayersMainSlider[uniqueId] = [];
9478
9479      $slider.addClass(uniqueId);
9480      if (hasVideoContent) $slider.addClass('has-video');
9481
9482      if (!isPC()) {
9483        $slider.removeClass('is-loading');
9484      }
9485
9486      // YouTubeの埋め込み
9487      function onPlayerReady(event) {
9488        event.target.mute();
9489        event.target.getPlaybackQuality('highres');
9490        sliderReady(event);
9491      }
9492
9493      function onPlayerStateChange(event) {
9494        if (event.data === YT.PlayerState.ENDED) {
9495          // $slider.slick('slickNext');
9496        }
9497      }
9498
9499      function getVideoList() {
9500        var videoList = [];
9501
9502        $slider.find('.cmd-visual_container').each(function (index) {
9503          var $el = $(this).find('.cmd-visual_iframe-wrap');
9504          if ($el[0]) {
9505            $slider.removeClass('is-loading');
9506            $el.attr('id', 'visual-slider_movieid_' + uniqueId + '_' + index);
9507            videoList.push({
9508              index: index,
9509              videoId: $el.attr('data-yt-id')
9510            });
9511          }
9512        });
9513
9514        return videoList;
9515      }
9516
9517      function youtubeSetup() {
9518        for (var i = 0; i < videoList.length; i++) {
9519          var playerVars = {
9520            // 'autoplay': 1,
9521            controls: 0,
9522            // 'loop': 1,
9523            // 'playlist': videoList[i].videoId,
9524            disablekb: 1,
9525            rel: 0,
9526            playsinline: 1
9527          };
9528
9529          // ytPlayersMainSlider[uniqueId].push('');
9530
9531          isSingleAndMovie = $slider.find('.cmd-slide').length === 1;
9532
9533          if (isSingleAndMovie) {
9534            playerVars.playlist = videoList[i].videoId;
9535            playerVars.loop = 1;
9536          }
9537
9538          var ytPlayer = new YT.Player('visual-slider_movieid_' + uniqueId + '_' + videoList[i].index, {
9539            width: 640,
9540            height: 480,
9541            videoId: videoList[i].videoId,
9542            playerVars: playerVars,
9543            events: {
9544              onReady: onPlayerReady,
9545              onStateChange: onPlayerStateChange
9546            }
9547          });
9548          // ytPlayersMainSlider[uniqueId][videoList[i].index] = ytPlayer;
9549          ytPlayersMainSlider[uniqueId].push(ytPlayer);
9550        }
9551      }
9552
9553      function sliderInit() {
9554        slickInit();
9555
9556        videoList = getVideoList();
9557
9558        if (videoList.length) {
9559          youtubeSetup();
9560        } else {
9561          sliderReady();
9562        }
9563      }
9564
9565      function sliderReady(event) {
9566        if (event && $(event.target.getIframe()).attr('id') === 'visual-slider_movieid_' + uniqueId + '_0') {
9567          if (isPC() && ytPlayersMainSlider[uniqueId][0] && ytPlayersMainSlider[uniqueId][0].playVideo) {
9568            ytPlayersMainSlider[uniqueId][0].playVideo();
9569
9570            setTimeout(function () {
9571              $slider.removeClass('is-loading');
9572              $slider.addClass('is-loaded');
9573            }, 100);
9574          }
9575        } else {
9576          setTimeout(function () {
9577            $slider.removeClass('is-loading');
9578
9579            setTimeout(function () {
9580              $slider.addClass('is-loaded');
9581            }, 2500);
9582          }, 500);
9583        }
9584        slideStart(null, 0);
9585      }
9586
9587      function slickInit() {
9588        $slider.on('init', function (event, slick) {
9589          if (!$(slick.$slides[0]).find('.cmd-visual_video')[0]) {
9590            $slider.removeClass('is-loading');
9591          }
9592          if ($(slick.$slides[0]).find('.cmd-visual_video')[0]) {
9593            $(slick.$slides[0]).addClass('is-wait');
9594          }
9595
9596          matchMediaPC.addListener(function (e) {
9597            if (e.matches) {
9598              var index = $slider.find('.slick-active').attr('data-slick-index');
9599              if (ytPlayersMainSlider[uniqueId][index] && ytPlayersMainSlider[uniqueId][index].playVideo) {
9600                ytPlayersMainSlider[uniqueId][index].playVideo();
9601              }
9602            } else {
9603              for (var i = 0; i < ytPlayersMainSlider[uniqueId].length; i++) {
9604                if (ytPlayersMainSlider[uniqueId][i].stopVideo) {
9605                  ytPlayersMainSlider[uniqueId][i].stopVideo();
9606                }
9607              }
9608            }
9609          });
9610        });
9611
9612        $slider.slick({
9613          fade: true,
9614          infinite: true,
9615          dots: true,
9616          appendDots: $slider.nextAll('.js-slider_dots'),
9617          arrows: true,
9618          appendArrows: $slider.nextAll('.js-slider_arrow')
9619        });
9620
9621        $sliderWrap.find('.slick-dots').find('button').append('<span class="bar"></span>');
9622
9623        $slider.on('beforeChange', function (event, slick, currentSlide, nextSlide) {});
9624
9625        $slider.on('afterChange', function (event, slick, currentSlide) {
9626          slideStart(slick, currentSlide);
9627        });
9628
9629        centerSet_arrow_dots($slider);
9630      }
9631
9632      function slideStart(slick, currentSlide) {
9633        clearTimeout(nextTimer);
9634        clearInterval(seekbarTimer);
9635        clearTimeout(loadingTimer);
9636
9637        for (var i = 0; i < ytPlayersMainSlider[uniqueId].length; i++) {
9638          if (ytPlayersMainSlider[uniqueId][i].stopVideo) {
9639            ytPlayersMainSlider[uniqueId][i].stopVideo();
9640          }
9641        }
9642
9643        var $currentSlide = $slider.find('.slick-slide[data-slick-index="' + currentSlide + '"]');
9644
9645        // 動画コンテンツはすべてwait
9646        $slider.find('.slick-slide').each(function () {
9647          if ($(this).find('.cmd-visual_video')[0]) {
9648            if (isPC()) {
9649              $(this).addClass('is-wait');
9650            }
9651          }
9652        });
9653
9654        // 動画が再生開始したらwait解除
9655        var loop = function loop() {
9656          if (ytPlayersMainSlider[uniqueId][currentSlide] && ytPlayersMainSlider[uniqueId][currentSlide].getPlayerState() === YT.PlayerState.PLAYING) {
9657            clearTimeout(loadingTimer);
9658            $currentSlide.removeClass('is-wait');
9659          }
9660          loadingTimer = setTimeout(loop, 50);
9661        };
9662        if (isPC()) {
9663          loop();
9664        } else {
9665          $currentSlide.removeClass('is-wait');
9666        }
9667
9668        $sliderWrap.find('.slick-dots').find('.bar').css('width', 0);
9669
9670        if (ytPlayersMainSlider[uniqueId][currentSlide] && isPC()) {
9671          ytPlayersMainSlider[uniqueId][currentSlide].playVideo();
9672        }
9673        seekbarPlay($currentSlide, currentSlide);
9674      }
9675
9676      function videoStop() {
9677        clearTimeout(nextTimer);
9678        clearInterval(seekbarTimer);
9679        clearTimeout(loadingTimer);
9680
9681        var currentSlideNum = $slider.slick('slickCurrentSlide');
9682        var $currentSlide = $slider.find('[data-slick-index="' + currentSlideNum + '"]');
9683
9684        if ($currentSlide.find('.cmd-visual_video')[0]) {
9685          if (isPC()) {
9686            $currentSlide.addClass('is-wait');
9687          }
9688        }
9689
9690        setTimeout(function () {
9691          ytPlayersMainSlider[uniqueId][currentSlideNum].stopVideo();
9692        }, 500);
9693      }
9694
9695      function seekbarPlay($currentSlide, currentSlide) {
9696        var cnt = 0;
9697        var step = 10;
9698        var subtract = 500;
9699        var $dotsBar = $sliderWrap.find('.slick-dots').find('li').eq(currentSlide).find('.bar');
9700
9701        seekbarTimer = setInterval(function () {
9702          var duration = carouselDuration;
9703
9704          if (!$currentSlide.find('.cmd-visual_video')[0] || !isPC()) {
9705            cnt += 10;
9706          } else {
9707            var movieDuration = ytPlayersMainSlider[uniqueId][currentSlide].getDuration() * 1000 - subtract;
9708            duration = carouselDuration > movieDuration ? movieDuration : carouselDuration;
9709            cnt = ytPlayersMainSlider[uniqueId][currentSlide].getCurrentTime() * 1000;
9710          }
9711
9712          $dotsBar.css('width', cnt / duration * 100 + '%');
9713
9714          if (duration > 0 && duration < cnt) {
9715            // 再生終了0.5秒前に次ぎスライドへ移動
9716            // 関連動画表示対処
9717            clearInterval(seekbarTimer);
9718            if (isSingleAndMovie) {
9719              if (typeof $slider.attr('data-slider-video-loop') !== 'undefined' && $slider.attr('data-slider-video-loop') === 'false') {
9720                // $slider.find('.slick-slide.slick-active').find('.cmd-visual_video').css({opacity: 0});
9721                videoStop();
9722              } else {
9723                slideStart(null, 0);
9724              }
9725            } else {
9726              if (typeof $slider.attr('data-slider-autoplay') !== 'undefined' && $slider.attr('data-slider-autoplay') === 'false') {
9727                videoStop();
9728              } else {
9729                $slider.slick('slickNext');
9730              }
9731            }
9732          }
9733        }, 10);
9734      }
9735
9736      sliderInit();
9737    });
9738
9739    $(window).on('resize', function (e) {
9740      if ($(window).width() !== windowWidth) {
9741        clearTimeout(windowDelay);
9742        windowDelay = window.setTimeout(function () {
9743          windowWidth = $(window).width();
9744
9745          $('.js-slider_container').filter('.has-video').each(function () {
9746            var movieSize = getBgMovieSize();
9747            $(this).find('.cmd-visual_video').each(function () {
9748              $(this).css(movieSize);
9749            });
9750          });
9751        }, 50);
9752      }
9753    }).trigger('resize');
9754  };
9755
9756  var mainSliderInit = function mainSliderInit() {
9757    // youtube api の読み込みと同時に YT YT.Player をチェック
9758    // APIの読み込みが完了したらsliderの実行
9759    // window.onYouTubeIframeAPIReadyは他のjsから実行されれている場合があるためYTをチェックする
9760    var youtubeApiLoad = function youtubeApiLoad() {
9761      var tag = document.createElement('script');
9762      tag.src = 'https://www.youtube.com/iframe_api';
9763      var firstScriptTag = document.getElementsByTagName('script')[0];
9764      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
9765    };
9766
9767    youtubeApiLoad();
9768
9769    var YTcheck = setInterval(function () {
9770      if (typeof YT !== 'undefined' && typeof YT.Player !== 'undefined') {
9771        mainSliderReady();
9772        clearInterval(YTcheck);
9773      }
9774    }, 50);
9775  };
9776
9777  var normalSliderInit = function normalSliderInit() {
9778    $('.js-slider_container').not('[data-slider-type="main"]').each(function () {
9779      var $slider = $(this);
9780      if (!$slider.hasClass('slick-initialized')) {
9781        var option = {
9782          arrows: true,
9783          appendArrows: $slider.nextAll('.js-slider_arrow'),
9784          dots: true,
9785          appendDots: $slider.nextAll('.js-slider_dots'),
9786          autoplay: $slider.attr('data-slider-autoplay') === 'true',
9787          autoplaySpeed: $slider.attr('data-slider-autoplay') === 'true' ? $slider.attr('data-sli
9787der-autoplayspeed') || 3000 : 0
9788        };
9789
9790        $slider.slick(option);
9791        centerSet_arrow_dots($slider);
9792      }
9793    });
9794  };
9795
9796  var centerSet_arrow_dots = function centerSet_arrow_dots($slider) {
9797    setTimeout(function () {
9798      if ($slider.hasClass('slick-initialized')) {
9799        var $arrow = $slider.nextAll('.js-slider_arrow');
9800        var $dots = $slider.nextAll('.js-slider_dots');
9801        var boxHeight = $slider.find('.slick-active').find('.cmd-visual_img').height();
9802        if ($slider.find('.slick-active').find('.cmd-visual_img')[0]) {
9803          if (boxHeight) {
9804            // $arrow.css({top: boxHeight/2});
9805            $dots.css({
9806              top: boxHeight
9807            });
9808          } else {
9809            centerSet_arrow_dots($slider);
9810          }
9811        }
9812      }
9813    }, 100);
9814  };
9815
9816  var resizeCheckSliderParts = function resizeCheckSliderParts() {
9817    var windowDelay;
9818    var windowWidth = $(window).width();
9819
9820    $(window).on('resize', function (e) {
9821      if ($(window).width() !== windowWidth) {
9822        clearTimeout(windowDelay);
9823        windowDelay = window.setTimeout(function () {
9824          windowWidth = $(window).width();
9825
9826          $('.js-slider_container').each(function () {
9827            var $slider = $(this);
9828            centerSet_arrow_dots($slider);
9829          });
9830        }, 50);
9831      }
9832    });
9833  };
9834
9835  return {
9836    init: function init() {},
9837    ready: function ready() {
9838      normalSliderInit();
9839      mainSliderInit();
9840      resizeCheckSliderParts();
9841    },
9842    reInit: function reInit($target, option) {
9843      if ($target[0] && typeof $target.slick !== 'undefined') {
9844        $target.slick('slickSetOption', option);
9845      }
9846    },
9847    getAutoPlay: function getAutoPlay($target) {
9848      if ($target[0] && typeof $target.slick !== 'undefined') {
9849        return $target.slick('slickGetOption', 'autoplay');
9850      } else {
9851        return undefined;
9852      }
9853    },
9854    playPause: function playPause($target) {
9855      if ($target[0] && typeof $target.slick !== 'undefined') {
9856        var nowPlay = $target.slick('slickGetOption', 'autoplay');
9857        if (nowPlay) {
9858          $target.slick('slickPause');
9859        } else {
9860          $target.slick('slickPlay');
9861        }
9862      }
9863    },
9864    pause: function pause($target) {
9865      if ($target[0] && typeof $target.slick !== 'undefined') {
9866        $target.slick('slickPause');
9867      }
9868    },
9869    play: function play($target) {
9870      if ($target[0] && typeof $target.slick !== 'undefined') {
9871        $target.slick('slickPlay');
9872      }
9873    }
9874  };
9875}();
9876
9877/**
9878 * inview animation
9879 */
9880var inViewAnimation = function () {
9881  return {
9882    init: function init() {},
9883    ready: function ready() {
9884      $('.js-anim-inout').on('inview', function (event, isInView) {
9885        if (isInView) {
9886          $(this).addClass('is-anim-active');
9887        } else {
9888          $(this).removeClass('is-anim-active');
9889        }
9890      });
9891      $('.js-anim-in').one('inview', function (event, isInView) {
9892        if (isInView) {
9893          $(this).addClass('is-anim-active');
9894        }
9895      });
9896    }
9897  };
9898}();
9899
9900var design = {
9901  init: function init() {
9902    setDirectionCheck();
9903    initHeader.init();
9904    initFooter.init();
9905    initGlobalNavigation.init();
9906    initRightModal.init();
9907    initRightModalLoginResetPassword.init();
9908    initCenterModal.init();
9909    initQuickView.init();
9910    standardTab.init();
9911    standardToggle.init();
9912    snsToggle.init();
9913    tabAccordion.init();
9914    selectChangeContent.init();
9915    numDropDown.init();
9916    inputToggle.init();
9917    cart.init();
9918    naireModal.init();
9919    movieModal.init();
9920
9921    /**
9922     * page:DOMContent​Loaded
9923     */
9924    cpbUi.isDomReady = true;
9925    cpbUi.isPdp = $('#contents').hasClass('pdp-main');
9926    cpbUi.niceScroll.ready();
9927    cpbUi.recommendSlider.ready();
9928    selectChangeContent.ready();
9929    if (cpbUi.isPdp) {
9930      cpbUi.pdp.ready();
9931      cpbUi.pdpSkinColor.ready();
9932    }
9933    inputToggle.ready();
9934    cart.ready();
9935    cpbUi.sectionSlider.ready();
9936    inViewAnimation.ready();
9937
9938    // scroll fix
9939    $(window).trigger('scroll');
9940    window.cpbUi = cpbUi;
9941  }
9942};
9943
9944module.exports = design;
9945
9946},{"./pages/product":48}],26:[function(require,module,exports){
9947'use strict';
9948
9949var util = require('./util'),
9950    validator = require('./validator'),
9951    modal = require('./modal').global;
9952
9953function showNewsletterModal() {
9954  modal.events.onClose(function () {
9955    var shouldDisplayNewsletter = [siteId, 'shouldDisplayNewsletter'].join('-');
9956    util.setCookie(shouldDisplayNewsletter, false, 10);
9957  });
9958
9959  modal.renderByUrl(Urls.showFullNewsletterForm).success(function (response) {
9960    modal.addCustomClass('newsletter-signup-modal');
9961
9962    $('.modal-content button').prop('disabled', true);
9963    $('.modal-content button').css('color', '#FFFFFF');
9964
9965    validator.initForm('.newsletter-signup-modal form');
9966  });
9967}
9968
9969function isNewsletterEnabled() {
9970  $('.register-newsletter').removeClass('hide');
9971  $('.newsletter-success').addClass('hide');
9972
9973  if (!enableNewsletter) {
9974    return;
9975  }
9976
9977  var hasViewedNewsletter = [siteId, 'hasViewedNewsletter'].join('-');
9978  var isViewedNewsletterValid = util.getCookieSelector(hasViewedNewsletter);
9979
9980  if (isViewedNewsletterValid === 'true') {
9981    return;
9982  }
9983
9984  var shouldDisplayNewsletter = [siteId, 'shouldDisplayNewsletter'].join('-');
9985  var isDisplayedNewsletterValid = util.getCookieSelector(shouldDisplayNewsletter);
9986
9987  if (isDisplayedNewsletterValid === 'false') {
9988    return;
9989  }
9990
9991  util.setCookie(hasViewedNewsletter, false, newsletterCookieDuration);
9992  util.setCookie(shouldDisplayNewsletter, true, newsletterCookieDuration);
9993
9994  setNewsletterCounterCookie();
9995  signUpEventListener();
9996}
9997
9998function setNewsletterCounterCookie() {
9999  var pageViewCount = [siteId, 'pageViewCount'].join('-');
10000  var isCookieValid = util.getCookieSelector(pageViewCount);
10001  var counterCookie = Number(isCookieValid);
10002
10003  if (!isCookieValid) {
10004    counterCookie = 0;
10005  } else {
10006    counterCookie += 1;
10007  }
10008
10009  util.setCookie(pageViewCount, counterCookie, newsletterCookieDuration);
10010
10011  var shouldDisplayNewsletter = [siteId, 'shouldDisplayNewsletter'].join('-');
10012  var isDisplayedNewsletterValid = util.getCookieSelector(shouldDisplayNewsletter);
10013
10014  if (counterCookie >= pageViewsToNewsletter && isDisplayedNewsletterValid === 'true') {
10015    showNewsletterModal();
10016  }
10017}
10018
10019function signUpEventListener() {
10020  $(document).on('submit', '.modal-content .news-letter-form', function (e) {
10021    e.preventDefault();
10022
10023    var emailAddress = $('.modal-content input').val();
10024    validateNewsletterEmail(true, emailAddress);
10025  }).on('keyup blur', '.modal-content input', function (e) {
10026    var emailAddress = $(this).val();
10027
10028    $('.modal-content button').prop('disabled', false);
10029    $('.modal-content button').css('color', '');
10030
10031    if (!emailAddress.length) {
10032      $('.modal-content button').prop('disabled', true);
10033      $('.modal-content button').css('color', '#FFFFFF');
10034    }
10035  });
10036}
10037
10038function newsletterHeader() {
10039  $(document).on('submit', '.cpb-footer-connect_container .news-letter-form', function (e) {
10040    e.preventDefault();
10041
10042    var emailAddress = $('.news-letter-form input').val();
10043    validateNewsletterEmail(false, emailAddress);
10044  });
10045}
10046
10047function validateNewsletterEmail(isModal, emailAddress) {
10048  var validateClass = '.news-letter-form';
10049
10050  if (isModal) {
10051    validateClass = '.modal-content';
10052  }
10053
10054  $(validateClass + ' input').removeAttr('aria-invalid');
10055  $(validateClass + ' input').removeAttr('aria-describedby');
10056  $(validateClass + ' input').removeAttr('class');
10057  $(validateClass + ' span').remove();
10058
10059  if (!util.validateEmail(emailAddress)) {
10060    var errorMessage;
10061
10062    if (isModal) {
10063      errorMessage = ['<span id="-error" class="error">', Resources.VALIDATE_EMAIL, '</span>'].join('');
10064
10065      $(validateClass + ' .promotions-container').after(errorMessage);
10066      $(validateClass + ' button').prop('disabled', true);
10067    } else {
10068      errorMessage = ['<span id="-error" class="error">', Resources.VALIDATE_EMAIL, '</span>'].join('');
10069
10070      $(validateClass + ' input').before(errorMessage);
10071    }
10072  }
10073
10074  var postData = ['dwfrm_newsletter_email=', emailAddress].join('');
10075  var formAction = $('.newsletter-container form').attr('action');
10076
10077  if ($('.newsletter-container form').length > 0) {
10078    $.ajax({
10079      type: 'POST',
10080      url: formAction,
10081      async: false,
10082      data: postData,
10083      success: function success(textStatus) {
10084        $('.register-newsletter').addClass('hide');
10085        $('.newsletter-success').removeClass('hide');
10086        $('.newsletter-success').addClass('show');
10087        $('.newsletter-success .registered-email').html(emailAddress);
10088        if (window.universal_variable !== undefined && !window.universal_variable.user.hasOwnProperty('user_id')) {
10089          window.universal_variable.user.email = emailAddress;
10090        }
10091      }
10092    });
10093  }
10094
10095  if (isModal) {
10096    setHasViewedNewsletterCookie(true);
10097  }
10098
10099  if ($('.news-letter-form').length > 0) {
10100    $.ajax({
10101      type: 'POST',
10102      url: $('.news-letter-form').attr('action'),
10103      async: false,
10104      data: {
10105        email: emailAddress,
10106        source: isModal ? 'modal' : 'header'
10107      },
10108      success: function success(response) {
10109        if (isModal) {
10110          modal.renderContent(response);
10111          modal.addCustomClass('newsletter-signup-modal');
10112          $(document).trigger('clicknewsletter', { siteloc: 'pop-up' });
10113        } else {
10114          $('.cpb-footer-connect_container form').html(response);
10115          $(document).trigger('clicknewsletter', { siteloc: 'footer' });
10116        }
10117        if (window.universal_variable !== undefined && !window.universal_variable.user.hasOwnProperty('user_id')) {
10118          window.universal_variable.user.email = emailAddress;
10119        }
10120      }
10121    });
10122  }
10123}
10124
10125function setHasViewedNewsletterCookie(val) {
10126  var hasViewedNewsletter = [siteId, 'hasViewedNewsletter'].join('-');
10127  util.setCookie(hasViewedNewsletter, val, newsletterCookieDuration);
10128}
10129
10130exports.isNewsletterEnabled = isNewsletterEnabled;
10131exports.newsletterHeader = newsletterHeader;
10132
10133},{"./modal":24,"./util":77,"./validator":78}],27:[function(require,module,exports){
10134'use strict';
10135
10136var modal = require('./modal').global,
10137    util = require('./util');
10138
10139exports.init = function init() {
10140  //On Change Select in PDP
10141  $('.replenishmentCycle').change(function () {
10142    var footerURL = window.location.href;
10143    var selection = $(this).val();
10144
10145    if (window.User.isCustomerAuthenticated == false && selection != 0) {
10146      $('.replenishmentCycle').val('0');
10147
10148      // render content to modal by url
10149      modal.renderByUrl(Urls.replenishmentLogin);
10150      modal.setCallback(function () {
10151        $('.modal-btn-signin').click(function () {
10152          var urlLink = util.appendParamToURL(Urls.showLogin, 'original', footerURL);
10153          window.location = util.appendParamToURL(urlLink, 'replenishment', selection);
10154        });
10155
10156        $('.modal-btn-register').click(function () {
10157          window.location = Urls.showCreateAccount;
10158        });
10159      });
10160    }
10161
10162    $('.modal-btn-signin').click(function () {
10163      var urlLink = util.appendParamToURL(Urls.showLogin, 'original', footerURL);
10164      window.location = util.appendParamToURL(urlLink, 'replenishment', selection);
10165    });
10166
10167    $('.modal-btn-register').click(function () {
10168      window.location = Urls.showCreateAccount;
10169    });
10170  });
10171
10172  //Update the Order replenishment suggestion based on product variant sizeVariations
10173  $('input[name=size]').click(function () {
10174    //Get the recommendation from the input data-isreplenishable
10175    var replennumber = this.getAttribute('data-isreplenishable');
10176
10177    //Construct the replenishment message
10178    var replenmsg = '';
10179    if (replennumber !== null && replennumber > 0) {
10180      var message = Resources.RECOMMENDED_REPLENISHMENT;
10181
10182      replenmsg += message;
10183      replenmsg += replennumber;
10184      replenmsg += ' ';
10185      replenmsg += replennumber > 1 ? '${spanPlural}' : '${span}';
10186      replenmsg += '.';
10187    }
10188
10189    //Assign it to replenreccomendation
10190    $('#replenrecommendation').text(replenmsg);
10191  });
10192
10193  //My Account Replenishment Update Button
10194  $('.replenishmentupdate').click(function (e) {
10195    e.preventDefault();
10196    var href = $(this).attr('href');
10197    var uuid = getQueryValue('rid', href);
10198    var rdays = $('.' + uuid.substring(0, 26) + '_days').val();
10199    var replenishmentQuantity = $('.' + uuid.substring(0, 26) + '_quantity').val();
10200    var updateReplenishment = href + '&rdays=' + rdays + '&qty=' + replenishmentQuantity;
10201    window.location = updateReplenishment;
10202  });
10203
10204  //My Account Replenishment Cancel Button
10205  $('.replenishmentcancel').click(function (e) {
10206    e.preventDefault();
10207    var href = $(this).attr('href');
10208    var popup = new Foundation.Reveal($('#cancel-replenishment'));
10209    popup.open();
10210
10211    $('.modal-btn-confirm').click(function () {
10212      window.location = href;
10213    });
10214
10215    $('.modal-btn-keep').click(function () {
10216      popup.close();
10217    });
10218  });
10219
10220  // Gets the query string value if it exists, returns null if it does not.
10221  // Example: getQueryValue("reset") will return the value true if the URL is http://www.domain.com?reset=true
10222  function getQueryValue(str, href) {
10223    /*var queryString = window.location.search.substring(1);*/
10224    var queryString = href;
10225    var queries = queryString.split('?');
10226    for (var i = 0; i < queries.length; i++) {
10227      var ft = queries[i].split('=');
10228      if (ft[0] == str) {
10229        return ft[1];
10230      }
10231    }
10232    return null;
10233  }
10234};
10235
10236}
10236,{"./modal":24,"./util":77}],28:[function(require,module,exports){
10237'use strict';
10238
10239var util = require('./util');
10240
10241var page = {
10242  title: '',
10243  type: '',
10244  params: util.getQueryStringParams(window.location.search.substr(1)),
10245  redirect: function redirect(newURL) {
10246    setTimeout(function () {
10247      window.location.href = newURL;
10248    }, 0);
10249  },
10250  refresh: function refresh() {
10251    setTimeout(function () {
10252      window.location.assign(window.location.href);
10253    }, 500);
10254  }
10255};
10256
10257module.exports = page;
10258
10259},{"./util":77}],29:[function(require,module,exports){
10260'use strict';
10261
10262var _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; };
10263
10264var giftcert = require('../giftcert'),
10265    tooltip = require('../tooltip'),
10266    util = require('../util'),
10267    dialog = require('../dialog'),
10268    page = require('../page'),
10269    login = require('../login'),
10270    modal = require('../modal').global,
10271
10272//cardValidation = require('./checkout/card-validation'),
10273validator = require('../validator'),
10274    search = require('./search'),
10275    ajax = require('../ajax'),
10276    design = require('../design');
10277
10278/**
10279 * @function
10280 * @description Initializes the events on the address form (apply, cancel, delete)
10281 * @param {Element} form The form which will be initialized
10282 */
10283function initializeAddressForm() {
10284  var $form = $('#edit-address-form');
10285
10286  $form.find('input[name="format"]').remove();
10287  tooltip.init();
10288  //$("<input/>").attr({type:"hidden", name:"format", value:"ajax"}).appendTo(form);
10289
10290  $form.on('click', '.apply-button', function (e) {
10291    /****
10292     * e.preventDefault();
10293     * if (!$form.valid()) {
10294     *     return false;
10295     * }
10296     * var url = util.appendParamToURL($form.attr('action'), 'format', 'ajax');
10297     * var applyName = $form.find('.apply-button').attr('name');
10298     * var options = {
10299     *     url: url,
10300     *     data: $form.serialize() + '&' + applyName + '=x',
10301     *     type: 'POST'
10302     * };
10303     * $.ajax(options).done(function (data) {
10304     *     if (typeof(data) !== 'string') {
10305     *         if (data.success) {
10306     *             dialog.close();
10307     *             page.refresh();
10308     *         } else if (data.error) {
10309     *             page.redirect(Urls.csrffailed);
10310     *         } else {
10311     *             window.alert(data.message);
10312     *             return false;
10313     *         }
10314     *     } else {
10315     *         $('#dialog-container').html(data);
10316     *         account.init();
10317     *         tooltip.init();
10318     *     }
10319     * });
10320     ****/
10321  }).on('click', '.cancel-button, .close-button', function (e) {
10322    e.preventDefault();
10323    dialog.close();
10324  }).on('click', '.delete-button', function (e) {
10325    e.preventDefault();
10326    if (window.confirm(String.format(Resources.CONFIRM_DELETE, Resources.TITLE_ADDRESS))) {
10327      var url = util.appendParamsToUrl(Urls.deleteAddress, {
10328        AddressID: $form.find('#addressid').val(),
10329        format: 'ajax'
10330      });
10331      $.ajax({
10332        url: url,
10333        method: 'POST',
10334        dataType: 'json'
10335      }).done(function (data) {
10336        if (data.status.toLowerCase() === 'ok') {
10337          dialog.close();
10338          page.refresh();
10339        } else if (data.message.length > 0) {
10340          window.alert(data.message);
10341          return false;
10342        } else {
10343          dialog.close();
10344          page.refresh();
10345        }
10346      });
10347    }
10348  });
10349}
10350/**
10351 * @private
10352 * @function
10353 * @description Toggles the list of Orders
10354 */
10355function toggleFullOrder() {
10356  $('.order-items').find('li.hidden:first').prev('li').append('<a class="toggle">View All</a>').children('.toggle').click(function () {
10357    $(this).parent().siblings('li.hidden').show();
10358    $(this).remove();
10359  });
10360}
10361/**
10362 * @private
10363 * @function
10364 * @description Binds the events on the address form (edit, create, delete)
10365 */
10366function initAddressEvents() {
10367  var addresses = $('#addresses');
10368  if (addresses.length === 0) {
10369    return;
10370  }
10371
10372  $(document).on('click', '.address-edit', function (evt) {
10373    evt.preventDefault();
10374    var element = document.getElementById(evt.currentTarget.id);
10375
10376    // for w+ api
10377    var addressObject = '';
10378    if (element.dataset.address == 'wplus') {
10379      addressObject = element.dataset.addressObject;
10380    }
10381
10382    var addressID = element.dataset.addressId;
10383    var url = Urls.checkoutEditAccountAddress + addressID + '&wplus=' + addressObject;
10384
10385    ajax.load({
10386      url: url,
10387      callback: function callback(data) {
10388        $('#editaddressmodal').html(data);
10389        $.magnificPopup.open({
10390          items: {
10391            src: '#editaddressmodal', // can be a HTML string, jQuery object, or CSS selector
10392            type: 'inline'
10393          }
10394        });
10395        validator.initForm('form[id="EditAddressForm"]');
10396        if (addressID == 0) {
10397          $("form[name='EditAddressForm'] #dwfrm_billing_billingAddress_addressFields_addressname").attr('readonly', 'true');
10398        }
10399        design.toggleSelectInit();
10400      }
10401    });
10402  });
10403
10404  $(document).on('click', '.address-delete', function (e) {
10405    e.preventDefault();
10406    var href = $(this).attr('href');
10407    var params = {
10408      wplus: $(this).attr('wplus'),
10409      format: 'ajax',
10410      csrf_token: this.dataset.csrfvalue
10411    };
10412    var url = util.appendParamsToUrl(href, params);
10413    var data = util.getQueryStringParams(util.getQueryString(url));
10414
10415    $.ajax({
10416      type: 'POST',
10417      url: url,
10418      data: data,
10419      dataType: 'json'
10420    }).done(function (data) {
10421      page.refresh();
10422    });
10423  });
10424
10425  $(document).on('click', '.address-make-default', function (e) {
10426    e.preventDefault();
10427    var params = {
10428      wplus: $(this).attr('wplus'),
10429      format: 'ajax',
10430      csrf_token: this.dataset.csrfvalue
10431    };
10432    var href = $(this).attr('href');
10433    href = util.appendParamsToUrl(href, params);
10434    var data = util.getQueryStringParams(util.getQueryString(href));
10435
10436    $.ajax({
10437      type: 'POST',
10438      url: href,
10439      data: data,
10440      dataType: 'json'
10441    }).done(function (data) {
10442      page.refresh();
10443    }).fail(function (jqXHR, textStatus, errorThrown) {
10444      console.log('error');
10445      console.log(jqXHR);
10446      console.log(textStatus);
10447      console.log(errorThrown);
10448    });
10449  });
10450
10451  $(document).on('click', '.address-create', function (evt) {
10452    evt.preventDefault();
10453
10454    ajax.load({
10455      url: Urls.checkoutAddAccountAddress,
10456      callback: function callback(data) {
10457        $('#editaddressmodal').html(data);
10458        $.magnificPopup.open({
10459          items: {
10460            src: '#editaddressmodal', // can be a HTML string, jQuery object, or CSS selector
10461            type: 'inline'
10462          }
10463        });
10464        validator.initForm('form[id="EditAddressForm"]');
10465        design.toggleSelectInit();
10466      }
10467    });
10468  });
10469
10470  $(document).on('click', "form[name='EditAddressForm'] button[name='dwfrm_profile_address_create'], form[n
10470ame='EditAddressForm'] button[name='dwfrm_profile_address_edit']", function (event) {
10471    event.preventDefault();
10472    var form = $(this).parents('form#EditAddressForm');
10473    var url = form.attr('action') + '&format=ajax';
10474    var dataSend = form.serialize() + '&dwfrm_profile_address_create=適用';
10475    $.ajax({
10476      type: 'POST',
10477      url: url,
10478      data: dataSend
10479    }).done(function (response) {
10480      var responseType = typeof response === 'undefined' ? 'undefined' : _typeof(response);
10481
10482      if (responseType === 'object' && !response.success && response.error === 'CSRF Token Mismatch') {
10483        window.location.href = Urls.csrffailed;
10484        return;
10485      }
10486      if (responseType === 'object' && (response.success || response.reload)) {
10487        window.location.reload();
10488        return;
10489      }
10490      if (responseType === 'object' && response.redirectToLogin) {
10491        window.location.href = Urls.showLogin;
10492        return;
10493      }
10494      if (responseType === 'object' && response.validationError) {
10495        response.errors.forEach(function (error) {
10496          var errorObj = {};
10497          errorObj[error.name] = error.message;
10498          form.data('validator').showErrors(errorObj);
10499          form.data('submitting', false);
10500        });
10501        return;
10502      }
10503      window.location.href = Urls.generalError;
10504    });
10505    return false;
10506  });
10507}
10508
10509/**
10510 * @private
10511 * @function
10512 * @description Binds the events of the payment methods list (delete card)
10513 */
10514function initPaymentEvents() {
10515  $('.add-card').on('click', function (e) {
10516    e.preventDefault();
10517    dialog.open({
10518      url: $(e.target).attr('href'),
10519      options: {
10520        open: initializePaymentForm
10521      }
10522    });
10523  });
10524
10525  if ($('#CreditCardForm').is(':visible')) {
10526    creditCardTypeDetector();
10527    validator.initForm('form[id$="CreditCardForm"]');
10528  }
10529
10530  $('.credit-card-create').on('click', function (e) {
10531    e.preventDefault();
10532    //validator.initForm('#CreditCardForm');
10533    resetForm($('#CreditCardForm'));
10534  });
10535
10536  $('.remove-card, .set-default-card').on('click', function (e) {
10537    e.preventDefault();
10538    var $form = $(this).closest('form.remove-card-form');
10539    if ($form.data('submitting')) {
10540      e.stopPropagation();
10541      return false;
10542    }
10543    // Allow only one form to submit.
10544    $('.remove-card-form').data('submitting', true);
10545    $.ajax({
10546      type: 'POST',
10547      url: $(this).hasClass('remove-card') ? $form.attr('action') : Urls.setDefaultCreditCard,
10548      data: {
10549        CardId: $form.find('input[name="Card_id"]').val(),
10550        CardSeq: $form.find('input[name="CardSeq"]').val(),
10551        CardNumber: $form.find('input[name="CardNumber"]').val(),
10552        csrf_token: $form.find('#csrf-token-modal').val()
10553      }
10554    }).done(function (response) {
10555      var responseType = typeof response === 'undefined' ? 'undefined' : _typeof(response);
10556
10557      if (responseType === 'object' && !response.success && response.error === 'CSRF Token Mismatch') {
10558        window.location.href = Urls.csrffailed;
10559        return;
10560      }
10561      if (responseType === 'object' && response.success) {
10562        page.redirect(Urls.paymentsList);
10563        return;
10564      }
10565      page.redirect(Urls.generalError);
10566    });
10567  });
10568
10569  $('#CreditCardForm .addCardSubmit').on('click', function (e) {
10570    var $form = $(this).closest('form');
10571    if (!$form.data('custom-validator')(e)) {
10572      e.preventDefault();
10573      e.stopPropagation();
10574      return false;
10575    }
10576    $('#CreditCardForm #applyBtn').trigger('click');
10577  });
10578}
10579
10580function resetForm($form) {
10581  //remove all error
10582  $form[0].reset();
10583  $form.validate().resetForm();
10584  var $month = $('[name$="_expiration_month"]');
10585  var $year = $('[name$="_expiration_year"]');
10586  var $type = $('[name$="_newcreditcard_type"]');
10587  $form.find('p.c-input-label.is-error').removeClass('is-error');
10588  $form.find('p.jquery-validation').parent().remove();
10589  $form.find('p.jquery-validation').remove();
10590  $month.prev().removeClass('is-error');
10591  $year.prev().removeClass('is-error');
10592  $type.prevAll().removeClass('is-error');
10593  var $typeUl = $type.closest('ul');
10594  var $expiryUl = $month.closest('ul');
10595  $expiryUl.find('.card-expiry-error').remove();
10596  $typeUl.find('.card-type-error').remove();
10597
10598  //reset value
10599  var resetValueField = [$type, $month, $year];
10600  var defaultMessage = [Resources.CREDIT_CARD_SELECT, Resources.CREDIT_CARD_MONTH, Resources.CREDIT_CARD_YEAR];
10601  resetValueField.forEach(function ($field, index) {
10602    var $selectField = $field.prev('.c-select');
10603    var $current = $selectField.find('.c-select-current');
10604    var $selectListItem = $selectField.find('ul.c-select-list>.c-select-list-item');
10605    var displayValue = defaultMessage[index];
10606    $selectListItem.children('a').removeClass('is-selected');
10607    $field.val('');
10608    $current.text(displayValue);
10609  });
10610}
10611
10612function initializePaymentForm() {
10613  $('#CreditCardForm').on('click', '.cancel-button', function (e) {
10614    e.preventDefault();
10615    dialog.close();
10616  });
10617}
10618
10619function mobileAccountMenu() {
10620  var pageContainer = $('#main');
10621  var primaryContent = $('#primary');
10622  var primaryContentHeight = $('#primary').outerHeight();
10623  var mobileNav = $('#secondary');
10624  var accountText = $('.account-text');
10625  var currentUrl = window.location.href;
10626  var cleanUrl = currentUrl.split('?')[0];
10627
10628  $('.account-nav-asset a[href="' + cleanUrl + '"]').addClass('active-menu');
10629
10630  $('.account-nav-asset a').on('click', function (e) {
10631    e.preventDefault();
10632    var url = $(this).attr('href');
10633
10634    if (url != cleanUrl) {
10635      window.location = url;
10636    } else {
10637      mobileNav.css('min-height', primaryContentHeight);
10638      pageContainer.addClass('content-show');
10639    }
10640  });
10641
10642  $('.back-to-account-btn a').on('click', function (e) {
10643    e.preventDefault();
10644    pageContainer.removeClass('content-show');
10645    mobileNav.css('min-height', 0);
10646  });
10647}
10648
10649function initOrderHistoryEvents() {
10650  $(document).on('click', '.view-order-details', function (evt) {
10651    evt.preventDefault();
10652
10653    $(this).prev().click();
10654  });
10655}
10656
10657function registerAccountEvents() {
10658  // get the field elements
10659  var $gender = $('.registration-box #dwfrm_profile_customer_gender');
10660  var $newsletterCB = $('.registration-box #dwfrm_profile_customer_addtoemaillist');
10661
10662  $gender.on('change', function (e) {
10663    $(this).closest('form').find('button[type="submit"]').prop('disabled', false);
10664  });
10665  $newsletterCB.on('change', function (e) {
10666    $(this).closest('form').find('button[type="submit"]').prop('disabled', false);
10667  });
10668}
10669
10670function addressEvents() {
10671  function toggleBillingAddressFields(visible) {
10672    if (visible == true) {
10673      $('.country-dependent').each(function () {
10674        $(this).show();
10675      });
10676    } else {
10677      $('.country-dependent').each(function () {
10678        $(this).hide();
10679      });
10680    }
10681
10682    if (window.User.isCustomerAuthenticated == false) {
10683      $('.checkout-billing').find('.set-default-cb').hide();
10684    }
10685  }
10686
10687  $(document).on('change', '#dwfrm_billing_billingAddress_addressFields_country', function () {
10688    var selectContry = $(this).val();
10689    var $form = $(this).closest('form');
10690
10691    if (selectContry == '') {
10692      toggleBillingAddressFields();
10693    } else if (selectContry == 'us') {
10694      toggleBillingAddressFields(true);
10695      $('.us-fields').show();
10696      $('.cn-fields').hide();
10697      $form.find('.postcode').removeClass('required');
10698      $form.find('.province').removeClass('required');
10699    } else {
10700      toggleBillingAddressFields(true);
10701      $('.cn-fields').show().css({ display: 'flex' });
10702      $('.us-fields').hide();
10703
10704      $form.find('.postcode').addClass('required').rules('add', {
10705        required: true,
10706        postal: true,
10707        messages: {
10708          postal: Resources.INVALID_POSTAL
10709        }
10710      });
10711      $form.find('.province').addClass('required').rules('add', {
10712        required: true,
10713        simpletext: true,
10714        messages: {
10715          simpletext: Resources.VALIDATE_PROVINCE
10716        }
10717      });
10718    }
10719  });
10720}
10721
10722function enableCountryField(status) {
10723  var countryField = $('select[id$="billing_billingAddress_addressFields_country"]');
10724  if (status) {
10725    countryField.removeAttr('disabled');
10726  } else {
10727    countryField.prop('disabled', true);
10728  }
10729}
10730
10731function initContactUs() {
10732  var registrationForm = $('form#RegistrationForm');
10733
10734  registrationForm.on('click', 'button#sendBtn', function (e) {
10735    e.preventDefault();
10736
10737    $.ajax({
10738      url: util.appendParamToURL(Urls.customerServiceSubmit, 'format', 'ajax'),
10739      data: registrationForm.serialize(),
10740      method: 'POST'
10741    }).done(function (response) {
10742      if (response.status) {
10743        // contact modal
10744        var windowHeight = window.innerHeight - 130;
10745        $.magnificPopup.open({
10746          items: {
10747            src: '#contactmodal', // can be a HTML string, jQuery object, or CSS selector
10748            type: 'inline'
10749          }
10750        });
10751
10752        $('#contactmodal .contact-success-container .row').css('height', windowHeight);
10753
10754        $(document).trigger('gtmcontactus');
10755        clearContactUsForm();
10756        registrationForm[0].reset();
10757      }
10758    });
10759  });
10760}
10761
10762/**
10763 * Clear contact us form
10764 */
10765function clearContactUsForm() {
10766  $('input[name$="_contactus_firstname"]').val('');
10767  $('input[name$="_contactus_lastname"]').val('');
10768  $('input[name$="_contactus_email"]').val('');
10769  $('input[name$="_contactus_phone"]').val('');
10770  $('input[name$="_contactus_ordernumber"]').val('');
10771  $('textarea[name$="_contactus_comment"]').val('');
10772  //	$('form#RegistrationForm button[type="submit"]').prop('disabled', true);
10773}
10774
10775function enableDisableSubmitButton(el) {
10776  var $saveBtn = $(el).closest('form').find('button[type="submit"]');
10777
10778  var hasError = $saveBtn.closest('form').find('span.error');
10779  if (hasError.length) {
10780    //        $saveBtn.prop('disabled', true);
10781  } else {
10782    $saveBtn.prop('disabled', false);
10783  }
10784}
10785
10786function setGender() {
10787  var gender = $('.gender select').data('gender');
10788
10789  $('.gender select').val(gender);
10790}
10791
10792function creditCardTypeDetector(options) {
10793  // the regular expressions check for possible matches as you type, hence the OR operators based on the number of chars
10794  // Visa
10795  var visa_regex = new RegExp('^4[0-9]{0,15}$'),
10796
10797  // MasterCard
10798  mastercard_regex = new RegExp('^5$|^5[1-5][0-9]{0,14}$'),
10799
10800  // American Express
10801  amex_regex = new RegExp('^3$|^3[47][0-9]{0,13}$'),
10802
10803  // Diners 300-305,3095,36,38-39
10804  diners_regex = new RegExp('^(30[0-5]\\d{11}|3095\\d{10}|36\\d{12}|3[8-9]\\d{12})$'),
10805
10806  // UnionPay
10807  unionpay_regex = new RegExp('^62[0-9]{0,14}$|^645[0-9]{0,13}$|^65[0-9]{0,14}$');
10808
10809  $('.cc-number input').focusout(function (e) {
10810    var cur_val = $(this).val();
10811
10812    //Commenting this out since the event is handled on focusout
10813    // if ( cur_val.length == 16 ) {
10814    //     e.preventDefault();
10815    //     return;
10816    // }
10817
10818    var $ccNumberContain = $(this).parents('.cc-number');
10819
10820    // get rid of spaces and dashes before using the regular expression
10821    cur_val = cur_val.replace(/ /g, '').replace(/-/g, '');
10822
10823    var $creditCard = $('[data-method="CREDIT_CARD"]');
10824
10825    // checks per each, as their could be multiple hits
10826    if (cur_val.match(visa_regex)) {
10827      $ccNumberContain.addClass('is_visa');
10828      $creditCard.find('input[name$="_type"]').val('Visa').trigger('change');
10829      clearCardIcon($creditCard);
10830      $creditCard.find('input[name*="_number"]').parent().append('<img class="visa" src="' + Urls.staticPath + 'images/common/icn_visa.gif" alt="">');
10831    } else {
10832      $ccNumberContain.removeClass('is_visa');
10833    }
10834
10835    if (cur_val.match(mastercard_regex)) {
10836      $ccNumberContain.addClass('is_mastercard');
10837      $creditCard.find('input[name$="_type"]').val('MasterCard').trigger('change');
10838      clearCardIcon($creditCard);
10839      $creditCard.find('input[name*="_number"]').parent().append('<img class="mastercard" src="' + Urls.staticPath + 'images/common/icn_mastercard.gif" alt="">');
10840    } else {
10841      $ccNumberContain.removeClass('is_mastercard');
10842    }
10843
10844    if (cur_val.match(amex_regex)) {
10845      $ccNumberContain.addClass('is_amex');
10846      $creditCard.find('input[name$="_type"]').val('Amex').trigger('change');
10847      clearCardIcon($creditCard);
10848      $creditCard.find('input[name*="_number"]').parent().append('<img class="amex" src="' + Urls.staticPath + 'images/common/icn_amex.gif" alt="">');
10849    } else {
10850      $ccNumberContain.removeClass('is_amex');
10851    }
10852
10853    if (cur_val.match(diners_regex)) {
10854      $ccNumberContain.addClass('is_diners');
10855      $creditCard.find('input[name$="_type"]').val('Diners').trigger('change');
10856      clearCardIcon($creditCard);
10857      $creditCard.find('input[name*="_number"]').parent().append('<img class="diners" src="' + Urls.staticPath + 'images/common/icn_diners.gif" alt="">');
10858    } else {
10859      $ccNumberContain.removeClass('is_diners');
10860    }
10861
10862    if (cur_val.match(unionpay_regex)) {
10863      $ccNumberContain.addClass('is_unionpay');
10864      $creditCard.find('input[name$="_type"]').val('Union').trigger('change');
10865      clearCardIcon($creditCard);
10866      $creditCard.find('input[name*="_number"]').parent().append('<img class="unionpay" src="' + Urls.staticPath + 'images/common/icn_unionpay.gif" alt="">');
10867    } else {
10868      $ccNumberContain.removeClass('is_unionpay');
10869    }
10870
10871    // if nothing is a hit we add a class to fade them all out
10872    if (cur_val != '' && !cur_val.match(visa_regex) && !cur_val.match(mastercard_regex) && !cur_val.match(amex_regex) && !cur_val.match(diners_regex) && !cur_val.match(unionpay_regex)) {
10873      $ccNumberContain.addClass('is_nothing');
10874      clearCardIcon($creditCard);
10875    } else {
10876      $ccNumberContain.removeClass('is_nothing');
10877    }
10878  });
10879}
10880
10881/**
10882 * Clear card icon
10883 * @returns
10884 */
10885function clearCardIcon($creditCard) {
10886  $creditCard.find('input[name*="_number"]').parent().find('.mastercard').remove();
10887  $creditCard.find('input[name*="_number"]').parent().find('.visa').remove();
10888  $creditCard.find('input[name*="_number"]').parent().find('.diners').remove();
10889  $creditCard.find('input[name*="_number"]').parent().find('.amex').remove();
10890  $creditCard.find('input[name*="_number"]').parent().find('.unionpay').remove();
10891}
10892
10893function withdrawReasonsEvents() {
10894  var reasons = $('.c-c-input-checklist label input[name^="dwfrm_withdrawreason_choices_reason"]');
10895  var validator = reasons.closest('form').data('validator');
10896  reasons.find('ul').remove();
10897  var isValid;
10898  reasons.on('change', function () {
10899    var flg = false;
10900    reasons.each(function (_, element) {
10901      $(element).closest('li').find('ul').remove();
10902      if ($.validator.methods.requireWithdraw()) {
10903        flg = true;
10904      }
10905    });
10906    if (flg) {
10907      $('#checkbox-atleast-one-error').remove();
10908    } else {
10909      reasons.closest('ul').append('<p id="checkbox-atleast-one-error" class="jquery-validation is-error c-input-label" style="margin-top: 5px;">' + Resources.VALIDATE_REASONS + '</p>');
10910    }
10911    return isValid;
10912  });
10913
10914  reasons.closest('form').submit(function () {
10915    var flg = false;
10916    reasons.each(function (_, element) {
10917      if ($.validator.methods.requireWithdraw()) {
10918        flg = true;
10919      }
10920    });
10921    if (flg) {
10922      $('#checkbox-atleast-one-error').remove();
10923    } else {
10924      reasons.closest('ul').append('<p id="checkbox-atleast-one-error" class="jquery-validation is-error c-input-label" style="margin-top: 5px;">' + Resources.VALIDATE_REASONS + '</p>');
10925    }
10926    return flg;
10927  });
10928}
10929
10930function tempRegisterEvents() {
10931  var $tempRegister = $('button[name="dwfrm_profile_tempregister"]');
10932  if ($tempRegister.length === 0) {
10933    return;
10934  }
10935  var $form = $tempRegister.closest('form');
10936  $(document).on('submit', $form, function (event) {
10937    if ($tempRegister.data('disabled')) {
10938      return false;
10939    }
10940    $tempRegister.data('disabled', true);
10941    // cvタグを外すことになったためコメントアウト(20191003)
10942    // // cvタグ処理(components/cv/conversiontag.ismlで関数を定義)
10943    // // GDN
10944    // const url = $tempRegister.closest('form').prop('action');
10945    // gtag_report_conversion(url);
10946    // // YDN
10947
10948    // // Facebook Pixel Code
10949    // fbq('track', 'CompleteRegistration');
10950  });
10951}
10952
10953/**
10954 * @private
10955 * @function
10956 * @description Binds the events of the order, address and payment pages
10957 */
10958function initializeEvents() {
10959  //cardValidation.init();
10960  toggleFullOrder();
10961  initAddressEvents();
10962  initPaymentEvents();
10963  login.init();
10964  registerAccountEvents();
10965  addressEvents();
10966  initContactUs();
10967  mobileAccountMenu();
10968  setGender();
10969  search.viewMore();
10970  initOrderHistoryEvents();
10971  withdrawReasonsEvents();
10972  tempRegisterEvents();
10973}
10974
10975var account = {
10976  init: function init() {
10977    initializeEvents();
10978    giftcert.init();
10979  },
10980  initCartLogin: function initCartLogin() {
10981    login.init();
10982  },
10983  initMobileMenu: function initMobileMenu() {
10984    mobileAccountMenu();
10985  }
10986};
10987
10988module.exports = account;
10989
10990},{"../ajax":1,"../design":11,"../dialog":12,"../giftcert":16,"../login":22,"../modal":24,"../page":28,"../tooltip":76,"../util":77,"../validator":78,"./search":57}],30:[function(require,module,exports){
10991'use strict';
10992
10993var _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; };
10994
10995var account = require('./account'),
10996    bonusProductsView = require('../bonus-products-view'),
10997    quickview = require('../quickview'),
10998    images = require('./product/image'),
10999    variant = require('./product/variant'),
11000    giftShipping = require('./checkout/shipping'),
11001    recommendations = require('./product/recommendations'),
11002    cartStoreInventory = require('../storeinventory/cart'),
11003    modal = require('../modal').global,
11004    samples = require('../samples'),
11005    giftCert = require('../giftcert-modal'),
11006    login = require('./checkout/login'),
11007    util = require('../util'),
11008    design = require('../design'),
11009    ajax = require('../ajax'),
11010    addToCart = require('./product/addToCart'),
11011    shipping = require('./checkout/shipping');
11012
11013/**
11014 * @private
11015 * @function
11016 * @description Binds events to the cart page (edit item's details, bonus item's actions, coupon code entry)
11017 */
11018function initializeEvents() {
11019  $('#cart-items-form .c-list-products-full-edit a').magnificPopup({
11020    type: 'ajax',
11021    ajax: {
11022      settings: null, // Ajax settings object that will extend default one - http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
11023      // For example:
11024      // settings: {cache:false, async:false}
11025
11026      cursor: 'mfp-ajax-cur', // CSS class that will be added to body during the loading (adds "progress" cursor)
11027      tError: '<a href="%url%">The content</a> could not be loaded.' //  Error message, can contain %curr% and %total% tags if gallery is enabled
11028    },
11029    callbacks: {
11030      parseAjax: function parseAjax(mfpResponse) {
11031        // mfpResponse.data is a "data" object from ajax "success" callback
11032        // for simple HTML file, it will be just String
11033
11034        // mfpResponse.data must be a String or a DOM (jQuery) element
11035        mfpResponse.data = $(mfpResponse.data).find('.c-block-shopingmodal').first();
11036      },
11037      ajaxContentAdded: function ajaxContentAdded() {
11038        $('#shopingmodal').html(this.content[0].outerHTML);
11039        $.magnificPopup.open({
11040          items: {
11041            src: '#shopingmodal', // can be a HTML string, jQuery object, or CSS selector
11042            type: 'inline'
11043          }
11044        });
11045
11046        images();
11047        variant();
11048        addToCart();
11049        renderThumbnails();
11050
11051        $('#BVRRSummaryContainer').on('click', '.bv-rating-stars-container', function () {
11052          window.location.href = url + '#reviews'; // redirect when rating star is clicked
11053        });
11054
11055        $(document).on('click', '.bv-popup-in .bv-read-review', function () {
11056          window.location.href = url + '#reviews'; // redirect when read reviews button is clicked
11057        });
11058
11059        design.modalInit();
11060        design.pdpInit();
11061        design.selectQuantityInit();
11062        design.toggleSelectInit();
11063        giftCert.initModal();
11064      }
11065    }
11066  });
11067
11068  $('#cart-table').on('click', '.item-edit-details a', function (e) {
11069    e.preventDefault();
11070
11071    quickview.show({
11072      url: e.target.href,
11073      source: 'cart',
11074      callback: function callback() {
11075        variant();
11076        renderThumbnails();
11077      }
11078    });
11079  }).on('click', '.bonus-item-actions a, .item-details .bonusproducts a', function (e) {
11080    e.preventDefault();
11081    bonusProductsView.show(this.href);
11082  });
11083
11084  // override enter key for coupon code entry
11085  $('input[name$="_couponCode"]').on('keydown', function (e) {
11086    if (e.which === 13 && $(this).val().length === 0) {
11087      return false;
11088    }
11089  });
11090
11091  //to prevent multiple submissions of the form when removing a product from the cart
11092  var removeItemEvent = false;
11093  $('.cpb-cart-bag_box .item-remove a').on('click', function (e) {
11094    if (removeItemEvent) {
11095      e.preventDefault();
11096    } else {
11097      removeItemEvent = true;
11098      var deleteHtml = $(this).closest('.cpb-cart-bag_box').find('input[name$=_deleteProduct]')[0].outerHTML;
11099      $('input[name$=_deleteGiftCertificate]').remove();
11100      $('input[name$=_deleteProduct]').remove();
11101      $('input[name$=_deleteCoupon]').remove();
11102      $(this).parent().append(deleteHtml);
11103      $(this).closest('form').submit();
11104    }
11105  });
11106
11107  $('.c-list-giftcard-full-remove a').on('click', function (e) {
11108    if (removeItemEvent) {
11109      e.preventDefault();
11110    } else {
11111      removeItemEvent = true;
11112      var deleteHtml = $(this).closest('.c-list-products-full-item-text-parts--short').find('input[name$=_deleteGiftCertificate]')[0].outerHTML;
11113      $('input[name$=_deleteGiftCertificate]').remove();
11114      $('input[name$=_deleteProduct]').remove();
11115      $('input[name$=_deleteCoupon]').remove();
11116      $(this).parent().append(deleteHtml);
11117      $(this).closest('form').submit();
11118    }
11119  });
11120
11121  $('.c-list-sample-remove a').on('click', function (e) {
11122    if (removeItemEvent) {
11123      e.preventDefault();
11124    } else {
11125      removeItemEvent = true;
11126      var deleteHtml = $(this).closest('.c-block-productsItem--smbreak').find('input[name$=_deleteProduct]')[0].outerHTML;
11127      $('input[name$=_deleteGiftCertificate]').remove();
11128      $('input[name$=_deleteProduct]').remove();
11129      $('input[name$=_deleteCoupon]').remove();
11130      $(this).parent().append(deleteHtml);
11131      $(this).closest('form').submit();
11132    }
11133  });
11134
11135  $('.c-list-coupon-remove a').on('click', function (e) {
11136    if (removeItemEvent) {
11137      e.preventDefault();
11138    } else {
11139      removeItemEvent = true;
11140      var deleteHtml = $(this).closest('.c-list-products-full-item-text-parts--short').find('input[name$=_deleteCoupon]')[0].outerHTML;
11141      $('input[name$=_deleteGiftCertificate]').remove();
11142      $('input[name$=_deleteProduct]').remove();
11143      $('input[name$=_deleteCoupon]').remove();
11144      $(this).parent().append(deleteHtml);
11145      $(this).closest('form').submit();
11146    }
11147  });
11148
11149  // product level bonus modal
11150  $('div.bonus-item-promo').on('click', 'a.select-bonus', function (e) {
11151    e.preventDefault();
11152
11153    var urlToRender = $(this).attr('href');
11154    if (urlToRender) {
11155      modal.addCustomClass('bonus-item-modal');
11156      modal.renderByUrl(urlToRender);
11157    }
11158  });
11159
11160  $(document).on('click', '#item-sample .cpb-cart_add_btn a.button[data-modal-target="sample"]', function (e) {
11161    samples.showSelectionInCart();
11162  }).on('click', '.paypal-container a', function (e) {
11163    e.preventDefault();
11164
11165    var cartCheckoutForm = $('.cart-action-checkout');
11166    if (cartCheckoutForm.length > 0) {
11167      cartCheckoutForm.attr('action', Urls.cartPaypalCheckout);
11168      cartCheckoutForm.submit();
11169    }
11170  });
11171
11172  reloadWishlistButtonEvent();
11173
11174  $('.add-to-wishlist').on('click', function (ev) {
11175    var form = document.createElement('form');
11176    form.setAttribute('action', this.dataset.posturl);
11177    form.setAttribute('method', 'post');
11178    form.style.display = 'none';
11179    document.body.appendChild(form);
11180
11181    $('.post-params').each(function (index, element) {
11182      var input = document.createElement('input');
11183      input.setAttribute('type', 'hidden');
11184      input.setAttribute('name', element.name);
11185      input.setAttribute('value', element.value);
11186      form.appendChild(input);
11187    });
11188    form.submit();
11189    ev.preventDefault();
11190    ev.stopPropagation();
11191    return false;
11192  });
11193
11194  $('.apply-points').on('click', function (e) {
11195    e.preventDefault();
11196    var $form = $(this).closest('form');
11197    var totalPoint = 0;
11198    var errListPoint = false;
11199    $form.find('._used input.point_value').each(function () {
11200      if ($(this).siblings('input[name*="_point_to_use"]').val() >= Number($(this).val())) {
11201        totalPoint += Number($(this).val());
11202      } else {
11203        errListPoint = true;
11204      }
11205    });
11206    $.ajax({
11207      url: Urls.validatePoint,
11208      data: {
11209        totalPoint: totalPoint,
11210        errListPoint: errListPoint
11211      }
11212    }).done(function (response) {
11213      if (response.error) {
11214        $form.find('.cpb-modalR_bottom').find('p.is-error').remove();
11215        $form.find('.cpb-modalR_bottom').find('.button.apply-points').attr('disabled', true);
11216        $form.find('.cpb-modalR_bottom').find('.point-use_box').before('<p class="is-error">' + response.errMsg + '<p>');
11217      } else {
11218        var formdata = $form.serialize();
11219        ajax.load({
11220          url: util.appendParamToURL($form.attr('action'), 'format', 'ajax'),
11221          data: formdata + '&totalPoint=' + totalPoint,
11222          target: $('.cart-use-point'),
11223          callback: function callback(data) {
11224            var sidebarItemPrice = $(data).find('.cpb-cart-side_total .item-price strong');
11225            if (sidebarItemPrice.length > 0) {
11226              var footerItemPrice = $('.cpb-cart-checkout_fixed .item-price');
11227              if (footerItemPrice.length > 0) {
11228                footerItemPrice.html(sidebarItemPrice[0]);
11229              }
11230            }
11231            usePointInit();
11232            shipping.initCouponCodeField();
11233            var isBilling = $('.cpb-template-paymentmethodsoptions').length !== 0;
11234            if (isBilling) {
11235              $.ajax({
11236                url: Urls.paymentmethodsoptions + '?checkedId=' + $('[name=dwfrm_billing_paymentMethods_selectedPaymentMethodID]:checked').val() + '&format=ajax'
11237              }).then(function (response) {
11238                if (typeof response !== 'string') {
11239                  throw response;
11240                }
11241                return response;
11242              }).then(function (response) {
11243                $('.cpb-template-paymentmethodsoptions').html(response);
11244                var $form = $('#add-use-point');
11245                var totalPoint = 0;
11246                $form.find('._used input.point_value').each(function () {
11247                  totalPoint += Number($(this).val());
11248                });
11249                var totalprice = Number($('.cpb-modalR_bottom').find('input[name="orderTotalValue"]').val());
11250                var radioChecked = $('[name=dwfrm_billing_paymentMethods_selectedPaymentMethodID]:checked').val();
11251                $('.payment-method-expanded').removeClass('is-active');
11252                $('.cpb-cart-input[data-tab-contents^="content-"]').removeClass('is-active');
11253                if (radioChecked === 'CREDIT_CARD') {
11254                  if (Number(totalPoint) !== totalprice) {
11255                    $('.payment-method-expanded').addClass('is-active');
11256                  }
11257                } else {
11258                  $('[data-tab-contents="content-' + radioChecked + '"]').addClass('is-active');
11259                }
11260                $form.find('.js-modal-r_close').click();
11261              }).fail(function (response) {
11262                if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && response.redirectToLogin) {
11263                  window.location.href = Urls.showLogin;
11264                  return;
11265                }
11266                window.location.href = Urls.generalError;
11267              });
11268            } else {
11269              $form.find('.js-modal-r_close').click();
11270            }
11271          }
11272        });
11273      }
11274    });
11275  });
11276
11277  $('#add-use-point').find('._used input.point_value').on('keydown', function (event) {
11278    if (event.keyCode == 13) {
11279      event.preventDefault();
11280      $('.apply-points').click();
11281    }
11282  });
11283
11284  usePointInit();
11285
11286  $('.js-edging-item-edit').on('click', function (e) {
11287    e.preventDefault();
11288
11289    var data = {
11290      uuid: $(this).closest('.cart-row').data('uuid'),
11291      edgingText: $(this).data('edging-text')
11292    };
11293    var url = util.appendParamToURL(Urls.showProductServiceForm, 'pid', $(this).data('product-id'));
11294    var target = '.product-service';
11295    $(target).empty();
11296
11297    ajax.load({
11298      url: url,
11299      target: target,
11300      data: { isCart: true },
11301      callback: function callback() {
11302        initProductServiceEvents(data);
11303      }
11304    });
11305  });
11306
11307  $(document).on('click', '.js-naire-setting-button', function (e) {
11308    e.preventDefault();
11309    $('#naire-data').siblings('p.is-error').remove();
11310    if ($('#naire-data').val() == '') {
11311      $('#naire-data').after($('<p class="c-input-label is-error"></p>').append(Resources.ENGRAVING_DATA_EMPTY));
11312    } else {
11313      $('.js-naire-setting').click();
11314    }
11315  });
11316}
11317
11318function usePointInit() {
11319  $('.delete-use-point').on('click', function (e) {
11320    e.preventDefault();
11321    ajax.load({
11322      url: util.appendParamToURL($(this).data('href'), 'format', 'ajax'),
11323      target: $('.cart-use-point'),
11324      callback: function callback(data) {
11325        shipping.initCouponCodeField();
11326        var isBilling = $('.cpb-template-paymentmethodsoptions').length !== 0 ? true : false;
11327        if (isBilling) {
11328          $.ajax({
11329            url: Urls.paymentmethodsoptions + '?checkedId=' + $('[name=dwfrm_billing_paymentMethods_selectedPaymentMethodID]:checked').val() + '&format=ajax'
11330          }).then(function (response) {
11331            if (typeof response !== 'string') {
11332              throw response;
11333            }
11334            return response;
11335          }).then(function (response) {
11336            $('.cpb-template-paymentmethodsoptions').html(response);
11337            var radioChecked = $('[name=dwfrm_billing_paymentMethods_selectedPaymentMethodID]:checked').val();
11338            if (radioChecked === 'CREDIT_CARD') {
11339              $('.payment-method-expanded').addClass('is-active');
11340            } else {
11341              $('[data-tab-contents="content-' + radioChecked + '"]').addClass('is-active');
11342            }
11343          }).fail(function (response) {
11344            if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && response.redirectToLogin) {
11345              window.location.href = Urls.showLogin;
11346              return;
11347            }
11348            window.location.href = Urls.generalError;
11349          });
11350        }
11351      }
11352    });
11353  });
11354  $('.wplus-point_box._used input').on('keyup', applyPoint);
11355  applyPoint();
11356}
11357
11358function applyPoint(e) {
11359  if (e) {
11360    e.preventDefault();
11361  }
11362  var $form = $('#add-use-point');
11363  var totalPoint = 0;
11364  var totalPointCanUse = 0;
11365  var isValidPoint = true,
11366      isValidPointTotal = true;
11367
11368  $form.find('._used input.point_value').each(function () {
11369    totalPointCanUse = $(this).parent().find('input[name$="_point_to_use"]').val();
11370    if (totalPointCanUse >= Number($(this).val())) {
11371      totalPoint += Number($(this).val());
11372    } else {
11373      totalPoint = 0;
11374      isValidPoint = false;
11375      return false;
11376    }
11377  });
11378
11379  var totalprice = Number($('.cpb-modalR_bottom').find('input[name="orderTotalValue"]').val());
11380  if (Number(totalPoint) > totalprice) {
11381    isValidPointTotal = false;
11382  }
11383  if (!isValidPoint) {
11384    $form.find('.cpb-modalR_bottom').find('p.is-error').remove();
11385    $form.find('.cpb-modalR_bottom').find('.button.apply-points').attr('disabled', true);
11386    $form.find('.cpb-modalR_bottom').find('.point-use_box').before('<p class="is-error">' + Resources.INVALID_POINT + '<p>');
11387  } else if (!isValidPointTotal) {
11388    $form.find('.cpb-modalR_bottom').find('p.is-error').remove();
11389    $form.find('.cpb-modalR_bottom').find('.button.apply-points').attr('disabled', true);
11390    $form.find('.cpb-modalR_bottom').find('.point-use_box').before('<p class="is-error">' + Resources.INVALID_POINT_TOTAL + '<p>');
11391  } else {
11392    $form.find('.cpb-modalR_bottom').find('p.is-error').remove();
11393    $form.find('.cpb-modalR_bottom').find('.button.apply-points').attr('disabled', false);
11394    $('span[name="total-point-value"]').html(totalPoint.toLocaleString());
11395    $('span[name="total-price-value"]').html((totalprice - totalPoint).toLocaleString());
11396  }
11397}
11398
11399function reloadWishlistButtonEvent() {
11400  $('.cpb-cart-bag_box #save-for-later').on('click', function (e) {
11401    if (!window.User.isCustomerAuthenticated) {
11402      return;
11403    }
11404
11405    e.preventDefault();
11406    var $target = $(this).parent();
11407    var url = util.appendParamsToUrl($(this).attr('href'), {
11408      format: 'ajax'
11409    });
11410    var data = {};
11411    data[this.dataset.csrfname] = this.dataset.csrfvalue;
11412
11413    $.ajax({
11414      type: 'POST',
11415      url: url,
11416      data: data
11417    }).done(function (response) {
11418      if (typeof response === 'string' && response !== '') {
11419        $target.empty().html(response);
11420        reloadWishlistButtonEvent();
11421      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
11422        window.alert(response.error);
11423      }
11424    });
11425  });
11426
11427  $('.cpb-cart-bag_box .remove-from-wishlist').on('click', function (e) {
11428    e.preventDefault();
11429
11430    var $target = $(this).parent();
11431    var url = util.appendParamsToUrl($(this).attr('href'), {
11432      format: 'ajax'
11433    });
11434    var data = {};
11435    data[this.dataset.csrfname] = this.dataset.csrfvalue;
11436
11437    $.ajax({
11438      type: 'POST',
11439      url: url,
11440      data: data
11441    }).done(function (response) {
11442      if (typeof response === 'string' && response !== '') {
11443        $target.empty().html(response);
11444        reloadWishlistButtonEvent();
11445      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
11446        window.alert(response.error);
11447      }
11448    }).fail(function (xhr, textStatus) {
11449      if (textStatus === 'parsererror') {
11450        window.alert(Resources.BAD_RESPONSE);
11451      } else {
11452        window.alert(Resources.SERVER_CONNECTION_ERROR);
11453      }
11454    });
11455  });
11456}
11457
11458function renderThumbnails() {
11459  if ($('#thumbnails').length > 0) {
11460    $('#thumbnails').empty(); // clear the list
11461    images(); // populate the thumbnails
11462  }
11463}
11464
11465function isGift() {
11466  var isGift = sessionStorage.getItem('isGift') === 'true';
11467  var isGiftName = [$('#cart-items-form').attr('name'), 'isGift'].join('_');
11468
11469  $('#checkout-form .is-gift').val(isGift);
11470  $('#checkout-form .is-gift').attr('name', isGiftName);
11471  $('.gift-container .input-checkbox').attr('checked', isGift);
11472  $('.gift-container .input-checkbox').change(function () {
11473    isGift = $(this).is(':checked');
11474
11475    if (!isGift) {
11476      $('.c-block-cartmessage .input-textarea').val('');
11477      $('#checkout-form .gift-message').val('');
11478      $('#checkout-form button').prop('disabled', false); // Added by ADe to enable Checkout button
11479      $('.third-party-container').css('opacity', 1);
11480      $('.third-party-container').css('pointer-events', 'all');
11481      //Ade
11482      if ($('.gift-message-textarea span.error:visible').length > 0) {
11483        $('.gift-message-textarea span.error').remove();
11484      }
11485      sessionStorage.removeItem('isGift');
11486      sessionStorage.removeItem('giftMessage');
11487    } else {
11488      $('.gift-container .input-textarea').keyup();
11489      sessionStorage.setItem('isGift', isGift);
11490    }
11491
11492    $('#checkout-form .is-gift').val(isGift);
11493  });
11494}
11495
11496function giftMessage() {
11497  var giftMessage = sessionStorage.getItem('giftMessage') ? sessionStorage.getItem('giftMessage') : '';
11498  var giftMessageName = [$('#cart-items-form').attr('name'), 'giftMe
11498ssage'].join('_');
11499
11500  $('#checkout-form .gift-message').val(giftMessage);
11501  $('#checkout-form .gift-message').attr('name', giftMessageName);
11502  $('.c-block-cartmessage .input-textarea').val(giftMessage);
11503  $('.c-block-cartmessage .input-textarea').on('keyup', function () {
11504    giftMessage = $(this).val().trim();
11505
11506    if (giftMessage === '' || util.validateMessage(giftMessage)) {
11507      $('#checkout-form .gift-message').val(giftMessage);
11508      $('.gift-message-textarea .form-caption').removeClass('error-message');
11509      $('.gift-message-textarea .form-caption').empty();
11510      $('#checkout-form button').prop('disabled', false);
11511      $('.third-party-container').css('opacity', 1);
11512      $('.third-party-container').css('pointer-events', 'all');
11513      sessionStorage.setItem('giftMessage', giftMessage);
11514    } else {
11515      $('.gift-message-textarea .form-caption').addClass('error-message');
11516      $('.gift-message-textarea .form-caption').text('Invalid message');
11517      $('#checkout-form button').prop('disabled', true);
11518      $('.third-party-container').css('opacity', 0.5);
11519      $('.third-party-container').css('pointer-events', 'none');
11520    }
11521  });
11522}
11523
11524function couponCodeEvent() {
11525  $('.cpb-cart-side_code input').on('keydown', function (e) {
11526    if (e.which === 13) {
11527      e.preventDefault();
11528
11529      $('#add-coupon').click();
11530    }
11531  });
11532}
11533
11534function updateCart() {
11535  $('.item-quantity select').change(function () {
11536    $('#cart-items-form').submit();
11537  });
11538}
11539
11540function cartCount() {
11541  if ($('.cart-empty').length) {
11542    sessionStorage.removeItem('isGift');
11543    sessionStorage.removeItem('giftMessage');
11544  }
11545}
11546
11547function initProductServiceEvents(data) {
11548  $('#productservicemodal .product-service-step1 .cpb-naire-color_list a').off('click').on('click', function (e) {
11549    e.preventDefault();
11550    updateContent($(this), $(this).attr('href'), data);
11551    return false;
11552  });
11553
11554  $('#add-to-cart-in-modal').on('click', data, editEdgingItem);
11555}
11556
11557function updateContent($element, url, data) {
11558  var $productServiceModal = $element.parents('.product-service-step1');
11559  if ($productServiceModal.length === 0) {
11560    return;
11561  }
11562  var edgingtext = $('[name=dwfrm_productengraving_edgingtext]').val();
11563  var edgingFont = $('input[name=naire-font]:checked').val();
11564  ajax.load({
11565    url: url,
11566    data: {
11567      Quantity: '1',
11568      isProductServiceModal: true,
11569      isCart: true
11570    },
11571    target: '.product-service',
11572    context: {
11573      edgingFont: edgingFont
11574    },
11575    callback: function callback() {
11576      $('#productservicemodal #naire-data').val(edgingtext);
11577      var edgingFont = this.context.edgingFont;
11578      // 選択状態にするラジオボタン要素を取得
11579      var checkedEdgingElement = $('input[name=naire-font]').toArray().filter(function (element) {
11580        return $(element).val() === edgingFont;
11581      });
11582      if (checkedEdgingElement.length === 0) {
11583        // 取得できなかった場合、一番最初の要素を選択状態する
11584        $('input[name=naire-font]').eq(0).prop('checked', true);
11585      } else {
11586        $(checkedEdgingElement).prop('checked', true);
11587      }
11588      $('#productservicemodal .js-naire-preview').empty().text(edgingtext);
11589      initProductServiceEvents(data);
11590    }
11591  });
11592}
11593
11594function editEdgingItem(e) {
11595  e.preventDefault();
11596
11597  var productId = $(this).data('product');
11598  var engravingText = $('#naire-data').val();
11599  var engravingFont = $('input[name=naire-font]:checked').data('id');
11600  if (productId === '') {
11601    return;
11602  }
11603  if (engravingText === '') {
11604    engravingText = $('#naire-data').attr('placeholder');
11605  }
11606
11607  $.ajax({
11608    type: 'post',
11609    url: Urls.addToCartInModal,
11610    data: {
11611      productId: productId,
11612      engravingText: engravingText,
11613      uuid: e.data.uuid,
11614      engravingFont: engravingFont
11615    }
11616  }).done(function (response) {
11617    if (response.success) {
11618      window.location.href = Urls.cartShow;
11619    } else {
11620      if (response.showGeneralError) {
11621        return window.location.href = Urls.generalError;
11622      }
11623      var $errorPlacement = $('#add-to-cart-in-modal').closest('.cpb-modalR_bottom').find('.c-text-error');
11624      $errorPlacement.find('li').remove();
11625      $errorPlacement.append($('<li></li>').text(response.error));
11626      $errorPlacement.removeClass('mfp-hide');
11627    }
11628  });
11629}
11630
11631exports.init = function () {
11632  login.init();
11633  initializeEvents();
11634  recommendations();
11635  isGift();
11636  giftMessage();
11637  updateCart();
11638  couponCodeEvent();
11639  cartCount();
11640  giftShipping.init();
11641  giftCert.init();
11642
11643  if (SitePreferences.STORE_PICKUP) {
11644    cartStoreInventory.init();
11645  }
11646
11647  account.initCartLogin();
11648};
11649
11650},{"../ajax":1,"../bonus-products-view":4,"../design":11,"../giftcert-modal":15,"../modal":24,"../quickview":66,"../samples":69,"../storeinventory/cart":72,"../util":77,"./account":29,"./checkout/login":38,"./checkout/shipping":40,"./product/addToCart":44,"./product/image":47,"./product/recommendations":51,"./product/variant":54}],31:[function(require,module,exports){
11651'use strict';
11652
11653var formPrepare = require('./checkout/formPrepare'),
11654    validator = require('../validator');
11655
11656/**
11657 * @private
11658 * @function
11659 * @description Validates if check order form is filled out before enabling button
11660 */
11661function initializeEvents() {
11662  validator.initForm('form[id$="ordertrack"]');
11663}
11664
11665exports.init = function () {
11666  initializeEvents();
11667};
11668
11669},{"../validator":78,"./checkout/formPrepare":36}],32:[function(require,module,exports){
11670'use strict';
11671
11672var util = require('../../util');
11673var shipping = require('./shipping');
11674
11675/**
11676 * @function
11677 * @description Selects the first address from the list of addresses
11678 */
11679exports.init = function () {
11680  var $form = $('.address');
11681  // select address from list
11682  $('select[name$="_addressList"]', $form).on('change', function () {
11683    var selected = $(this).children(':selected').first();
11684    var selectedAddress = $(selected).data('address');
11685    if (!selectedAddress) {
11686      return;
11687    }
11688    util.fillAddressFields(selectedAddress, $form);
11689    shipping.updateShippingMethodList();
11690    // re-validate the form
11691    $form.validate().form();
11692  });
11693};
11694
11695},{"../../util":77,"./shipping":40}],33:[function(require,module,exports){
11696'use strict';
11697
11698var ajax = require('../../ajax'),
11699    formPrepare = require('./formPrepare'),
11700    giftcard = require('../../giftcard'),
11701    util = require('../../util'),
11702    modal = require('../../modal').global,
11703    cardValidation = require('./card-validation'),
11704    validator = require('../../validator'),
11705    design = require('../../design');
11706
11707var $cache;
11708
11709/**
11710 * @function
11711 * @description Changes the payment method form depending on the passed paymentMethodID
11712 * @param {String} paymentMethodID the ID of the payment method, to which the payment method form should be changed to
11713 */
11714function updatePaymentMethod(paymentMethodID) {
11715  var $paymentMethods = $('.payment-method');
11716  $paymentMethods.removeClass('payment-method-expanded');
11717
11718  var dataMethod = paymentMethodID;
11719  if (paymentMethodID == 'SA_SILENTPOST') {
11720    dataMethod = 'CREDIT_CARD';
11721  }
11722
11723  var $selectedPaymentMethod = $paymentMethods.filter('[data-method="' + dataMethod + '"]');
11724  if ($selectedPaymentMethod.length === 0) {
11725    $selectedPaymentMethod = $('[data-method="Custom"]');
11726  }
11727
11728  if (paymentMethodID == 'CREDIT_CARD' || paymentMethodID == 'SA_SILENTPOST') {
11729    $('.spsavecard').show();
11730  } else if ((paymentMethodID == 'SA_REDIRECT' || paymentMethodID == 'SA_IFRAME') && SitePreferences.TOKENIZATION_ENABLED) {
11731    $('.spsavecard').show();
11732  } else {
11733    $('.spsavecard').hide();
11734  }
11735
11736  $selectedPaymentMethod.addClass('payment-method-expanded');
11737
11738  // ensure checkbox of payment method is checked
11739  /* $('input[name$="_selectedPaymentMethodID"]').removeAttr('checked');
11740    $('input[value=' + paymentMethodID + ']').prop('checked', 'checked');*/
11741}
11742
11743function creditCardTypeDetector(options) {
11744  // the regular expressions check for possible matches as you type, hence the OR operators based on the number of chars
11745  // Visa
11746  var visa_regex = new RegExp('^4[0-9]{0,15}$'),
11747
11748  // MasterCard
11749  mastercard_regex = new RegExp('^5$|^5[1-5][0-9]{0,14}$'),
11750
11751  // American Express
11752  amex_regex = new RegExp('^3$|^3[47][0-9]{0,13}$'),
11753
11754  // Diners 300-305,3095,36,38-39
11755  diners_regex = new RegExp('^(30[0-5]\\d{11}|3095\\d{10}|36\\d{12}|3[8-9]\\d{12})$'),
11756
11757  // UnionPay
11758  unionpay_regex = new RegExp('^62[0-9]{0,14}$|^645[0-9]{0,13}$|^65[0-9]{0,14}$');
11759
11760  $('.cc-number input').focusout(function (e) {
11761    var cur_val = $(this).val();
11762
11763    //Commenting this out since the event is handled on focusout
11764    // if ( cur_val.length == 16 ) {
11765    //     e.preventDefault();
11766    //     return;
11767    // }
11768
11769    var $ccNumberContain = $(this).parents('.cc-number');
11770
11771    // get rid of spaces and dashes before using the regular expression
11772    cur_val = cur_val.replace(/ /g, '').replace(/-/g, '');
11773
11774    var $creditCard = $('[data-method="CREDIT_CARD"]');
11775
11776    // checks per each, as their could be multiple hits
11777    if (cur_val.match(visa_regex)) {
11778      $ccNumberContain.addClass('is_visa');
11779      $creditCard.find('input[name$="_type"]').val('Visa').trigger('change');
11780      clearCardIcon($creditCard);
11781      $creditCard.find('input[name*="_number"]').parent().append('<img class="visa" src="' + Urls.staticPath + 'images/common/icn_visa.gif" alt="">');
11782    } else {
11783      $ccNumberContain.removeClass('is_visa');
11784    }
11785
11786    if (cur_val.match(mastercard_regex)) {
11787      $ccNumberContain.addClass('is_mastercard');
11788      $creditCard.find('input[name$="_type"]').val('MasterCard').trigger('change');
11789      clearCardIcon($creditCard);
11790      $creditCard.find('input[name*="_number"]').parent().append('<img class="mastercard" src="' + Urls.staticPath + 'images/common/icn_mastercard.gif" alt="">');
11791    } else {
11792      $ccNumberContain.removeClass('is_mastercard');
11793    }
11794
11795    if (cur_val.match(amex_regex)) {
11796      $ccNumberContain.addClass('is_amex');
11797      $creditCard.find('input[name$="_type"]').val('Amex').trigger('change');
11798      clearCardIcon($creditCard);
11799      $creditCard.find('input[name*="_number"]').parent().append('<img class="amex" src="' + Urls.staticPath + 'images/common/icn_amex.gif" alt="">');
11800    } else {
11801      $ccNumberContain.removeClass('is_amex');
11802    }
11803
11804    if (cur_val.match(diners_regex)) {
11805      $ccNumberContain.addClass('is_diners');
11806      $creditCard.find('input[name$="_type"]').val('Diners').trigger('change');
11807      clearCardIcon($creditCard);
11808      $creditCard.find('input[name*="_number"]').parent().append('<img class="diners" src="' + Urls.staticPath + 'images/common/icn_diners.gif" alt="">');
11809    } else {
11810      $ccNumberContain.removeClass('is_diners');
11811    }
11812
11813    if (cur_val.match(unionpay_regex)) {
11814      $ccNumberContain.addClass('is_unionpay');
11815      $creditCard.find('input[name$="_type"]').val('Union').trigger('change');
11816      clearCardIcon($creditCard);
11817      $creditCard.find('input[name*="_number"]').parent().append('<img class="unionpay" src="' + Urls.staticPath + 'images/common/icn_unionpay.gif" alt="">');
11818    } else {
11819      $ccNumberContain.removeClass('is_unionpay');
11820    }
11821
11822    // if nothing is a hit we add a class to fade them all out
11823    if (!cur_val.match(visa_regex) && !cur_val.match(mastercard_regex) && !cur_val.match(amex_regex) && !cur_val.match(diners_regex) && !cur_val.match(unionpay_regex)) {
11824      $ccNumberContain.addClass('is_nothing');
11825      clearCardIcon($creditCard);
11826    } else {
11827      $ccNumberContain.removeClass('is_nothing');
11828    }
11829  });
11830}
11831
11832/**
11833 * Clear card icon
11834 * @returns
11835 */
11836function clearCardIcon($creditCard) {
11837  $creditCard.find('input[name*="_number"]').parent().find('.mastercard').remove();
11838  $creditCard.find('input[name*="_number"]').parent().find('.visa').remove();
11839  $creditCard.find('input[name*="_number"]').parent().find('.diners').remove();
11840  $creditCard.find('input[name*="_number"]').parent().find('.amex').remove();
11841  $creditCard.find('input[name*="_number"]').parent().find('.unionpay').remove();
11842}
11843
11844function checkGiftCert() {
11845  var $balance = $('.c-block-giftcardbalance-block-send .balance');
11846  var $error = $('div#gift-card-balance-form .balance-error');
11847  var $giftCode = $('div#gift-card-balance-form input[name$="_giftCertCode"]');
11848  var $giftPin = $('div#gift-card-balance-form input[name$="_giftCertPIN"]');
11849
11850  $error.html('');
11851  $balance.html('');
11852  if ($giftCode.val().length === 0) {
11853    $error.html(Resources.GIFT_CARD_CODE_INVALID);
11854  } else if ($giftCode.val().length !== 0 && $giftPin.val().length === 0) {
11855    $error.html(Resources.GIFT_CARD_PIN_INVALID);
11856  } else if ($giftCode.val().length === 0 && $giftPin.val().length === 0) {
11857    $error.html(Resources.GIFT_CARD_CODE_PIN_INVALID);
11858  }
11859  if ($error.html() !== '') {
11860    $error.addClass('c-text-error');
11861    return;
11862  }
11863
11864  giftcard.checkBalance($giftCode.val(), $giftPin.val(), function (data) {
11865    if (data && data.error) {
11866      $error.addClass('c-text-error');
11867      return $error.html(data.error);
11868    }
11869
11870    if (!data || !data.giftCertificate) {
11871      $error.html(Resources.GIFT_CARD_CODE_PIN_INVALID);
11872      $error.addClass('c-text-error');
11873      return;
11874    }
11875
11876    if (!data || !data.giftCertificate) {
11877      $balance.html(Resources.GIFT_CERT_INVALID).removeClass('success').addClass('is-error');
11878      return;
11879    }
11880
11881    $balance.html('<div><dt>' + Resources.GIFT_CERT_CURRENT_BALANCE + '</dt><dd>' + data.giftCertificate.balance + '</dd></div>');
11882    $balance.addClass('c-list-total c-list-total--border c-list-total--large');
11883
11884    $('button#check-giftcert-modal').closest('.c-row').addClass('mfp-hide');
11885    $('button#add-giftcert-modal').closest('.c-row').removeClass('mfp-hide');
11886    $('button#new-giftcert-modal').removeClass('mfp-hide');
11887  });
11888}
11889
11890function applyGiftCert() {
11891  var $error = $('div#gift-card-balance-form .balance-error');
11892  var $giftCode = $('div#gift-card-balance-form input[name$="_giftCertCode"]');
11893  var $giftPin = $('div#gift-card-balance-form input[name$="_giftCertPIN"]');
11894
11895  $error.html('');
11896  if ($giftCode.val().length === 0) {
11897    $error.html(Resources.GIFT_CARD_CODE_INVALID);
11898    return;
11899  }
11900  /*else if ($giftCode.val().length !== 0 && $giftPin.val().length === 0) {
11901        $error.html(Resources.GIFT_CARD_PIN_INVALID);
11902        return;
11903    } else if ($giftCode.val().length === 0 && $giftPin.val().length === 0) {
11904        $error.html(Resources.GIFT_CARD_CODE_PIN_INVALID);
11905        return;
11906    }*/
11907
11908  var url = util.appendParamsToUrl(Urls.redeemGiftCert, {
11909    giftCertCode: $giftCode.val(),
11910    giftCertPIN: $giftPin.val(),
11911    format: 'ajax'
11912  });
11913  $.getJSON(url, function (data) {
11914    var fail = false;
11915    var msg = '';
11916    if (!data) {
11917      msg = Resources.BAD_RESPONSE;
11918      fail = true;
11919    } else if (!data.success) {
11920      msg = data.message.split('<').join('&lt;').split('>').join('&gt;');
11921      fail = true;
11922    }
11923    if (fail) {
11924      $error.html(msg);
11925      return;
11926    } else {
11927      window.location.assign(Urls.billing);
11928    }
11929  });
11930}
11931
11932function initCache() {
11933  $cache = {};
11934
11935  $cache.checkoutForm = $('.checkout-billing');
11936  $cache.selectedCardIdInput = $cache.checkoutForm.find('input[name$="_selectedCardID"]');
11937}
11938
11939function initCreditCardForm() {
11940  $cache.checkoutForm.find('input[name$="_selectedCardID"]').val('');
11941  $cache.checkoutForm.find('input[name*="_number"]').val('');
11942
11943  var $ccContainer = $cache.checkoutForm.find('.payment-method').filter(function () {
11944    return $(this).data('method') == 'CREDIT_CARD';
11945  });
11946
11947  $ccContainer.find('input[name*="_number"]').on('change', function (e) {
11948    $cache.checkoutForm.find('input[name$="_selectedCardID"]').val('');
11949  });
11950  $ccContainer.find('input[name$="_owner"]').on('change', function (e) {
11951    $cache.checkoutForm.find('input[name$="_selectedCardID"]').val('');
11952  });
11953
11954  $ccContainer.find('select[name*="expiration"]').on('change', function (e) {
11955    $cache.checkoutForm.find('input[name$="_selectedCardID"]').val('');
11956
11957    var selectedPaymentMethodID = $('input[name$="_selectedPaymentMethodID"]:checked').val();
11958    var cardNumber = $cache.checkoutForm.find('input[name*="_number"]').val();
11959    if (cardNumber.indexOf('****') != -1 && selectedPaymentMethodID == 'SA_SILENTPOST') {
11960      $cache.checkoutForm.find('input[name*="_number"]').val('');
11961    }
11962  });
11963}
11964
11965function initCreditCardEvents() {
11966  $(document).on('click', '#panel-newcard-label', function (evt) {
11967    var $form = $('#CreditCardForm');
11968    $('#CreditCardForm input[type="text"] , #CreditCardForm select').each(function () {
11969      $(this).val('');
11970    });
11971    $('#gmoPaymentCardList option[value="AddNewCard"]').prop('selected', true);
11972    $('#gmoPaymentCardList').change();
11973    $('.credit-card-save').css('display', 'flex');
11974    $('#panel-newcard').find('select,input').not('.payinfo').prop('disabled', false);
11975
11976    var validator = $form.data('validator');
11977    if (validator) {
11978      validator.resetForm();
11979    }
11980    $form.find('.is-error').removeClass('is-error');
11981  });
11982
11983  //select credit card tile
11984  $(document).on('click', '.creditcard-tile', function (evt) {
11985    var $this = $(this);
11986
11987    if ($this.is('.selected, .default')) {
11988      return false;
11989    }
11990
11991    $('.credit-card-save').css('display', 'flex');
11992
11993    /* $('input[name="creditcard"]').each(function () {
11994             $(this).prop('checked', false);
11995            
11996         });*/
11997
11998    //$this.addClass('selected');
11999    var selectedSeq = $this.find('input[name="CardSeq"]').val();
12000    $('#gmoPaymentCardList option[value="' + selectedSeq + '"]').prop('selected', true);
12001    $('#gmoPaymentCardList').change();
12002    $('#gmoPaymentCardList').siblings('input[name$="currentCardNo"]').val(selectedSeq);
12003  });
12004
12005  $(document).on('change', '#gmoPaymentCardList', function (evt) {
12006    var selectedValue = $('#gmoPaymentCardList option:selected').val();
12007    if (selectedValue) {
12008      $('#applyBtn').prop('disabled', false);
12009    } else {
12010      $('#applyBtn').prop('disabled', true);
12011    }
12012  });
12013
12014  //check validate card in dialog to submit form
12015  $(document).on('click', '#CreditCardForm .addCardSubmit', function (evt) {
12016    var $form = $(this).closest('form');
12017    if (!$form.data('custom-validator')(evt)) {
12018      evt.preventDefault();
12019      evt.stopPropagation();
12020      return false;
12021    }
12022    $(this).parent().find('button[id="applyBtn"]').click();
12023  });
12024  $(document).on('click', '.js-modal-r_overlay,.js-modal-r_close', function (evt) {
12025    $('#gmoPaymentCardList option[value="' + $('#gmoPaymentCardList').siblings('input[name$="currentCardNo"]').val() + '"]').prop('selected', true);
12026    $('#gmoPaymentCardList').change();
12027  });
12028}
12029
12030function setSelectedCardID(uuid) {
12031  $cache.selectedCardIdInput.val(uuid);
12032}
12033
12034function enableCountryField(status) {
12035  var countryField = $('input[id$="billing_billingAddress_addressFields_country"]');
12036  if (status) {
12037    countryField.removeAttr('disabled');
12038  } else {
12039    countryField.prop('disabled', true);
12040  }
12041}
12042
12043function addCVNEvent() {
12044  $('input[name$="creditCard_cvn"]').on('keydown', function (e) {
12045    if (e.key.toString().match(/[\d]/) || $.inArray(e.keyCode, [8, 9, 13, 46, 33, 34, 35, 36, 37, 38, 39, 40]) >= 0) {
12046      // do nothing
12047    } else {
12048      e.preventDefault();
12049      e.stopPropagation();
12050      return;
12051    }
12052  });
12053}
12054
12055function initGiftCardBalance() {
12056  var $checkoutForm = $('.checkout-billing');
12057  var $addGiftCert = $('#add-giftcert');
12058  var $giftCertCode = $('input[name$="_giftCertCode"]');
12059  var $giftCertPin = $('input[name$="_giftCertPIN"]');
12060  var $addCoupon = $('#add-coupon');
12061  var $couponCode = $('input[name$="_couponCode"]');
12062
12063  // Check Balance button is clicked in Check Balance Modal
12064  $(document).off('click', 'button#check-giftcert-modal');
12065  $(document).on('click', 'button#check-giftcert-modal', function (e) {
12066    e.preventDefault();
12067    checkGiftCert();
12068  });
12069
12070  // Check Another Card button is clicked in Check Balance Modal
12071  $(document).off('click', 'button#new-giftcert-modal');
12072  $(document).on('click', 'button#new-giftcert-modal', function (e) {
12073    var $balance = $('div#gift-card-balance-form .balance');
12074    var $error = $('div#gift-card-balance-form .balance-error');
12075    var $giftCode = $('div#gift-card-balance-form input[name$="_giftCertCode"]');
12076    var $giftPin = $('div#gift-card-balance-form input[name$="_giftCertPIN"]');
12077
12078    $balance.html('');
12079    $error.html('');
12080    $giftCode.val(null).removeAttr('disabled');
12081    $giftPin.val(null).removeAttr('disabled');
12082
12083    $('button#add-giftcert-modal').closest('.c-row').addClass('mfp-hide');
12084    $('button#new-giftcert-modal').addClass('mfp-hide');
12085    $('button#check-giftcert-modal').closest('.c-row').removeClass('mfp-hide');
12086  });
12087
12088  // Apply button is clicked in Check Balance Modal
12089  $(document).off('click', 'button#add-giftcert-modal');
12090  $(document).on('click', 'button#add-giftcert-modal', function (e) {
12091    e.preventDefault();
12092    applyGiftCert();
12093  });
12094
12095  $addGiftCert.off();
12096  $addGiftCert.on('click', function (e) {
12097    e.preventDefault();
12098    var code = $giftCertCode.val();
12099    var pin = $giftCertPin.val();
12100    //var $error = $checkoutForm.find('.giftcert-error');
12101    var $error = $checkoutForm.find('.apply-error');
12102
12103    // clear all errors
12104    $(this).closest('form').find('span.error').remove();
12105
12106    $error.html('');
12107    if (code.length === 0) {
12108      $error.html(Resources.GIFT_CARD_CODE_INVALID);
12109      return;
12110    } else if (code.length !== 0 && pin.length === 0) {
12111      $error.html(Resources.GIFT_CARD_PIN_INVALID);
12112      return;
12113    } else if (code.length === 0 && pin.length === 0) {
12114      $error.html(Resources.GIFT_CARD_CODE_PIN_INVALID);
12115      return;
12116    }
12117
12118    var url = util.appendParamsToUrl(Urls.redeemGiftCert, {
12119      giftCertCode: code,
12120      giftCertPIN: pin,
12121      format: 'ajax'
12122    });
12123    $.getJSON(url, function (data) {
12124      var fail = false;
12125      var msg = '';
12126      if (!data) {
12127        msg = Resources.BAD_RESPONSE;
12128        fail = true;
12129      } else if (!data.success) {
12130        msg = data.message.split('<').join('&lt;').split('>').join('&gt;');
12131        fail = true;
12132      }
12133      if (fail) {
12134        $error.html(msg);
12135        return;
12136      } else {
12137        window.location.assign(Urls.billing);
12138      }
12139    });
12140  });
12141
12142  $giftCertCode.off();
12143  $giftCertCode.on('keydown', function (e) {
12144    if (e.which === 13) {
12145      e.preventDefault();
12146      $addGiftCert.click();
12147    }
12148  });
12149}
12150
12151function initMaskCardNoBeforeNoCardSubmission() {
12152  $(document).off('submit.billing.mask').on('submit.billing.mask', '.cpb-cart-main form[id$="_billing"]', function () {
12153    var method = $('input[name$="selectedPaymentMethodID"]:checked').val();
12154    if (method === 'CREDIT_CARD') {
12155      return;
12156    }
12157    $('[name$="billing_paymentMethods_creditCard_type"]').val('');
12158    $('[name$="billing_paymentMethods_creditCard_number"]').val('');
12159    $('[name$="billing_paymentMethods_creditCard_month"]').val('');
12160    $('[name$="billing_paymentMethods_creditCard_year"]').val('');
12161    $('[name$="billing_paymentMethods_creditCard_expiration_month"]').val('');
12162    $('[name$="billing_paymentMethods_creditCard_expiration_year"]').val('');
12163    $('[name$="billing_paymentMethods_creditCard_cvn"]').val('');
12164  });
12165}
12166
12167/**
12168 * @function
12169 * @description loads billing address, Gift Certificates, Coupon and Payment methods
12170 */
12171exports.init = function () {
12172  cardValidation.init();
12173  initCache();
12174  initCreditCardForm();
12175  initCreditCardEvents();
12176  initGiftCardBalance();
12177  initMaskCardNoBeforeNoCardSubmission();
12178
12179  var $selectPaymentMethod = $('.payment-method-options');
12180  var selectedPaymentMethod = $selectPaymentMethod.find(':checked').val();
12181
12182  validator.initForm('form[id$="billing"]');
12183
12184  function toggleBillingAddressFields(visible) {
12185    if (visible == true) {
12186      $('.country-dependent').each(function () {
12187        $(this).show();
12188      });
12189    } else {
12190      $('.country-dependent').each(function () {
12191        $(this).hide();
12192      });
12193    }
12194
12195    if (window.User.isCustomerAuthenticated == false) {
12196      $('.checkout-billing').find('.set-default-cb').hide();
12197    }
12198  }
12199
12200  $(document).on('change', '#dwfrm_billing_billingAddress_addressFields_country, #dwfrm_billingaddress_country', function () {
12201    var selectContry = $(this).val();
12202    if (selectContry == '') {
12203      toggleBillingAddressFields();
12204    } else if (selectContry == 'us') {
12205      toggleBillingAddressFields(true);
12206      $('.us-fields').show();
12207      $('.us-fields input').each(function () {
12208        $(this).addClass('required');
12209      });
12210
12211      $('.cn-fields').hide();
12212      $('.cn-fields input').each(function () {
12213        $(this).removeClass('required');
12214      });
12215    } else {
12216      toggleBillingAddressFields(true);
12217      $('.cn-fields').show().css({ display: 'flex' });
12218      $('.cn-fields input').each(function () {
12219        $(this).addClass('required');
12220      });
12221
12222      $('.us-fields').hide();
12223      $('.us-fields input').each(function () {
12224        $(this).removeClass('required');
12225      });
12226    }
12227  });
12228
12229  $('.billing-address-section :input').on('change', function (e) {
12230    if (e.target.id == 'dwfrm_billing_billingAddress_useAsBillingAddress') {
12231      return false;
12232    }
12233
12234    $('#dwfrm_billing_billingAddress_useAsBillingAddress').prop('checked', false);
12235  });
12236
12237  if ($('input#same-as-shipping').is(':checked')) {
12238    $('.saved-addresses.select-billing-address').addClass('mfp-hide');
12239    $('.saved-addresses.default-billing-address').removeClass('mfp-hide');
12240  }
12241
12242  $('input#same-as-shipping').on('change', function () {
12243    var sameascheckbox = $(this);
12244
12245    if (sameascheckbox.is(':checked')) {
12246      $('.saved-addresses.select-billing-address').addClass('mfp-hide');
12247      $('.saved-addresses.default-billing-address').removeClass('mfp-hide');
12248
12249      $('#dwfrm_billing_billingAddress_addressFields_firstName').val($('#dwfrm_billing_billingAddress_addressFields_firstName').attr('data-firstname'));
12250      $('#dwfrm_billing_billingAddress_addressFields_lastName').val($('#dwfrm_billing_billingAddress_addressFields_lastName').attr('data-lastname'));
12251      $('#dwfrm_billing_billingAddress_addressFields_address1').val($('#dwfrm_billing_billingAddress_addressFields_address1').attr('data-address1'));
12252      $('#dwfrm_billing_billingAddress_addressFields_address2').val($('#dwfrm_billing_billingAddress_addressFields_address2').attr('data-address2') != 'null' ? $('#dwfrm_billing_billingAddress_addressFields_address2').attr('data-address2') : '');
12253      $('#dwfrm_billing_billingAddress_addressFields_city').val($('#dwfrm_billing_billingAddress_addressFields_city').attr('data-city'));
12254      $('#dwfrm_billing_billingAddress_addressFields_postal').val($('#dwfrm_billing_billingAddress_addressFields_postal').attr('data-postal'));
12255      $('#dwfrm_billing_billingAddress_addressFields_country').val($('#dwfrm_billing_billingAddress_addressFields_country').val());
12256      $('#dwfrm_billing_billingAddress_addressFields_states_state').val($('#dwfrm_billing_billingAddress_addressFields_states_state').parent().find('.c-select-current').attr('data-state'));
12257      $('#dwfrm_billing_billingAddress_addressFields_phone').val($('#dwfrm_billing_billingAddress_addressFields_phone').attr('data-phone'));
12258
12259      $('.flag-show-hide').fadeIn();
12260      toggleBillingAddressFields(true);
12261
12262      // for logged-in users with address, reselect default shipping address
12263      // if customer chooses to use the shipping address as their billing address
12264      var selectedShipping = $('div.address-tile.address-default');
12265      if (selectedShipping) {
12266        selectedShipping.removeClass('is-current');
12267        selectedShipping.removeClass('default');
12268        selectedShipping.click();
12269      }
12270    } else {
12271      $('.saved-addresses.default-billing-address').addClass('mfp-hide');
12272      $('.saved-addresses.select-billing-address').removeClass('mfp-hide');
12273
12274      $('#dwfrm_billing_billingAddress_addressFields_address1').val('');
12275      $('#dwfrm_billing_billingAddress_addressFields_address2').val('');
12276      $('#dwfrm_billing_billingAddress_addressFields_city').val('');
12277      $('#dwfrm_billing_billingAddress_addressFields_postal').val('');
12278      $('#dwfrm_billing_billingAddress_addressFields_phone').val('');
12279      $('#dwfrm_billing_billingAddress_addressFields_postcode').val('');
12280      $('#dwfrm_billing_billingAddress_addressFields_province').val('');
12281      $('#dwfrm_billing_billingAddress_addressFields_states_state').val('');
12282      $('#dwfrm_billing_billingAddress_addressFields_states_state').parent().find('.c-select-current').attr('data-v', '').html($('#dwfrm_billing_billingAddress_addressFields_states_state').prev().find('li:first .c-select-list-item-text').html());
12283      $('#dwfrm_billing_billingAddress_addressFields_states_state').prev().find('a.is-selected').removeClass('is-selected');
12284      $('#dwfrm_billing_billingAddress_addressFields_country').parent().find('.c-select-current').attr('data-v', '').html($('#dwfrm_billing_billingAddress_addressFields_country').prev().find('li:first .c-select-list-item-text').html());
12285      $('#dwfrm_billing_billingAddress_addressFields_country').prev().find('a.is-selected').removeClass('is-selected');
12286      $('.flag-show-hide').fadeOut();
12287      $('.us-fields').show();
12288      $('.cn-fields').hide();
12289
12290      $('#dwfrm_billing_billingAddress_addressFields_country').val('sg');
12291
12292      toggleBillingAddressFields();
12293    }
12294  });
12295
12296  // default payment method to 'CREDIT_CARD'
12297  updatePaymentMethod(selectedPaymentMethod ? selectedPaymentMethod : 'CREDIT_CARD');
12298  $selectPaymentMethod.on('click', 'input[type="radio"]', function () {
12299    updatePaymentMethod($(this).val());
12300  });
12301
12302  $('.gift-card-form-toggle').on('click', function (e) {
12303    e.preventDefault();
12304
12305    var $giftCardForm = $('.gift-card-form');
12306    var $giftCardCheckLink = $('.check-gift-card');
12307
12308    $giftCardForm.slideDown().removeClass('rolledup');
12309    $giftCardCheckLink.removeClass('mfp-hide');
12310    $(this).addClass('mfp-hide');
12311    initGiftCardBalance();
12312  });
12313
12314  var $inithtml = $('#giftcardbalancemodal').html();
12315
12316  $('.check-gift-card').on('click', function (e) {
12317    $('#giftcardbalancemodal').html($inithtml);
12318    $.magnificPopup.open({
12319      items: {
12320        src: '#giftcardbalancemodal', // can be a HTML string, jQuery object, or CSS selector
12321        type: 'inline'
12322      }
12323    });
12324    $('.gift-card-balance-modal input[name$="_giftCertCode"], .gift-card-balance-modal input[name$="_giftCertPIN"]').on('blur', function (e) {
12325      var $this = $(this);
12326      $this.siblings('ul.c-text-error').remove();
12327      $this.removeClass('is-error');
12328      $this.prev().removeClass('is-error');
12329      $('.gift-card-balance-modal button#check-giftcert-modal').prop('disabled', false);
12330      $('.gift-card-balance-modal .balance-error').html('');
12331      $('.gift-card-balance-modal .balance-error').removeClass('c-text-error');
12332      $('.c-block-giftcardbalance-block-send .balance').html('');
12333      $('.c-block-giftcardbalance-block-send .balance').removeClass('c-list-total c-list-total--border c-list-total--large');
12334      $('button#check-giftcert-modal').closest('.c-row').removeClass('mfp-hide');
12335      $('button#add-giftcert-modal').closest('.c-row').addClass('mfp-hide');
12336
12337      if ($this.val() && !$this.val().trim().match(/^[a-z0-9]+$/i)) {
12338        $('<ul class="c-text-error c-text-error--simple"><li>' + $this.attr('data-required-text') + '</li></ul>').insertAfter($this);
12339        $this.addClass('is-error');
12340        $this.prev().addClass('is-error');
12341      }
12342
12343      if ($('.gift-card-balance-modal span.error').length > 0) {
12344        //    			$('.gift-card-balance-modal button#check-giftcert-modal').prop('disabled',true);
12345      }
12346    });
12347  });
12348
12349  creditCardTypeDetector();
12350
12351  $(document).on('click', '.credit-card-create', function (evt) {
12352    modal.events.onOpen(function () {
12353      creditCardTypeDetector();
12354      validator.initForm('form[id$="CreditCardForm"]');
12355    });
12356    modal.restoreDefaultClass();
12357    modal.addCustomClass('medium add-credit-card');
12358    modal.renderByUrl(Urls.checkoutAddCreditCard);
12359    modal.setCallback(cardValidation.init);
12360  });
12361
12362  $(document).on('submit', '#CreditCardForm', function (evt) {
12363    evt.preventDefault();
12364
12365    var $form = $(this);
12366
12367    $.ajax({
12368      url: util.appendParamToURL($form.attr('action'), 'format', 'ajax'),
12369      data: $form.serialize() + '&' + $form.find('#applyBtn').attr('name') + '=x',
12370      type: 'POST'
12371    }).done(function (data) {
12372      if (data.length) {
12373        modal.setContent(data);
12374        validator.initForm('form[id$="CreditCardForm"]');
12375        return;
12376      }
12377
12378      if (!location.assign(Urls.billing)) {
12379        window.location.href = Urls.billing;
12380      }
12381    });
12382  });
12383
12384  $(document).on('click', '.credit-card-edit', function (evt) {
12385    var element = document.getElementById(evt.currentTarget.id);
12386    var creditcardPositin = element.dataset.creditcardPosition;
12387    var url = Urls.checkoutEditCreditCard + creditcardPositin;
12388
12389    modal.restoreDefaultClass();
12390    modal.events.onOpen(function () {
12391      $('.cc-number input').prop('disabled', true);
12392      validator.initForm('form[id$="CreditCardForm"]');
12393    });
12394    modal.addCustomClass('small edit-credit-card');
12395    modal.renderByUrl(url);
12396  });
12397
12398  //select credit card tile
12399  $(document).on('click', '.creditcard-tile', function (evt) {
12400    var $this = $(this);
12401    var $thisInner = $this.children('.creditcard-tile-inner');
12402
12403    if ($thisInner.find('#dwfrm_billing_paymentMethods_creditCard_cvn').length > 0) {
12404      return;
12405    }
12406
12407    var ccEdit = $this.find('.credit-card-edit');
12408    var fauxCVNInput = '<div class="cvn-input"></div>';
12409    var CVNInput = '<input class="input-text " type="text" id="dwfrm_billing_paymentMethods_creditCard_cvn" name="dwfrm_billing_paymentMethods_creditCard_cvn" value="" maxlength="4" aria-invalid="false">';
12410
12411    if (evt.target == ccEdit[0]) {
12412      return;
12413    }
12414
12415    if ($(this).is('.is-current, .default')) {
12416      return false;
12417    } else {
12418      $('.creditcard-tile-inner').each(function () {
12419        $(this).removeClass('is-current');
12420        $(this).removeClass('default');
12421        $(this).find('.saved-cvn').addClass('disabled');
12422        $(this).find('.saved-cvn input').replaceWith(fauxCVNInput);
12423      });
12424
12425      $thisInner.addClass('is-current');
12426      $this.find('.cvn-input').removeClass('disabled');
12427      $this.find('.saved-cvn .cvn-input').replaceWith(CVNInput);
12428      $this.find('.saved-cvn input').focus();
12429
12430      var element = document.getElementById(evt.currentTarget.getElementsByClassName('creditcard-tile-inner')[0].id);
12431
12432      var creditcardPosition = element.dataset.creditcardPosition;
12433
12434      var url = util.appendParamsToUrl(Urls.checkoutCreditCardSelection, {
12435        position: creditcardPosition
12436      });
12437      $.ajax({
12438        url: url,
12439        type: 'GET',
12440        success: function success(result) {}
12441      });
12442
12443      setSelectedCardID($this.data('uuid'));
12444      addCVNEvent();
12445    }
12446  });
12447
12448  //delete card payment
12449  $('.remove-cardpayment').on('click', function (e) {
12450    e.preventDefault();
12451    e.stopPropagation();
12452    var $paymentItemData = $(this).closest('.item-action_link');
12453    $.ajax({
12454      type: 'POST',
12455      url: $(this).attr('href'),
12456      data: {
12457        CardId: $paymentItemData.find('input[name="Card_id"]').val(),
12458        CardSeq: $paymentItemData.find('input[name="CardSeq"]').val(),
12459        CardNumber: $paymentItemData.find('input[name="CardNumber"]').val(),
12460        csrf_token: $paymentItemData.find('#csrf-token-modal').val()
12461      }
12462    }).done(function (response) {
12463      if (!response.success && response.error === 'CSRF Token Mismatch') {
12464        window.location.href = Urls.csrffailed;
12465        return;
12466      }
12467      if (response.success) {
12468        location.reload();
12469        return;
12470      }
12471      window.location.href = Urls.generalError;
12472    });
12473  });
12474
12475  $(document).on('click', '.button-billing-continue', function (e) {
12476    var $form = $('form[id$="_billing"]');
12477    var isFormValid = $form.data('custom-validator')(e);
12478    if (!isFormValid && !$('.payment_creditcard').hasClass('is-active')) {
12479      e.preventDefault();
12480      e.stopPropagation();
12481      return false;
12482    }
12483
12484    if ($('.payment_creditcard').hasClass('is-active')) {
12485      if (!isFormValid || $('[name$="billing_paymentMethods_credit
12485Card_type"]').val() == '' || $('select[name$=_creditCard_expiration_year]').val() == '' || $('select[name$=_creditCard_expiration_month]').val() == '') {
12486        cardValidation.validateCardType($('[name$="billing_paymentMethods_creditCard_type"]'));
12487        cardValidation.validateCardExpiryDropdown($('button#dwfrm_billing_save'), true, event);
12488        e.preventDefault();
12489        e.stopPropagation();
12490        return false;
12491      }
12492    }
12493    $('html').addClass('cpb-is-loading');
12494    $('button#dwfrm_billing_save').trigger('click');
12495  });
12496
12497  $(document).on('click', '.address-create', function (evt) {
12498    evt.preventDefault();
12499
12500    ajax.load({
12501      url: Urls.checkoutAddBillingAddress,
12502      callback: function callback(data) {
12503        $('#editaddressmodal').html(data);
12504        $.magnificPopup.open({
12505          items: {
12506            src: '#editaddressmodal', // can be a HTML string, jQuery object, or CSS selector
12507            type: 'inline'
12508          }
12509        });
12510        validator.initForm('form[id="EditAddressForm"]');
12511        design.toggleSelectInit();
12512      }
12513    });
12514  });
12515
12516  $(document).on('click', '.address-edit', function (evt) {
12517    evt.preventDefault();
12518    var element = document.getElementById(evt.currentTarget.id);
12519    var addressID = element.dataset.addressId;
12520    var addressCode = element.dataset.addressCode;
12521    var url = Urls.checkoutEditBillingAddress + addressID;
12522
12523    var $this = $(this);
12524    var addressID = $this.data('addressId');
12525
12526    ajax.load({
12527      url: url,
12528      callback: function callback(data) {
12529        $('#editaddressmodal').html(data);
12530        $.magnificPopup.open({
12531          items: {
12532            src: '#editaddressmodal', // can be a HTML string, jQuery object, or CSS selector
12533            type: 'inline'
12534          }
12535        });
12536
12537        validator.initForm('form[id="EditAddressForm"]');
12538        design.toggleSelectInit();
12539      }
12540    });
12541  });
12542
12543  $(document).on('click', '.address-list .address-tile', function (evt) {
12544    if ($(this).is('.selected, .default') || evt.target.nodeName == 'A') {
12545      return false;
12546    } else {
12547      $('.address-list .address-tile').each(function () {
12548        $(this).removeClass('is-current');
12549        $(this).removeClass('default');
12550      });
12551
12552      $(this).addClass('is-current');
12553
12554      var element = document.getElementById(evt.currentTarget.id);
12555      var addressID = element.dataset.addressId;
12556
12557      var url = util.appendParamsToUrl(Urls.updateBillingAddressDetails, {
12558        addressID: addressID
12559        //format: 'ajax'
12560      });
12561      $.ajax({
12562        url: url,
12563        type: 'GET',
12564        success: function success(result) {
12565          //alert(result);
12566        }
12567      });
12568    }
12569  });
12570
12571  $('.order-summary-footer form').submit(function () {
12572    $('#summary-place-order').prop('disabled', true).addClass('loading');
12573    return true;
12574  });
12575
12576  // if same as shipping is checked, re-select default address
12577  // or if nothing is selected, re-select default address
12578  if ($('input#same-as-shipping').length > 0 && $('input#same-as-shipping').is(':checked') || $('ul.address-list div.address-tile.is-current').length <= 0) {
12579    $(document).find('ul.address-list div.address-tile').each(function (ind, evt) {
12580      if ($(this).hasClass('default') || $(this).hasClass('is-current') || $(this).hasClass('address-default')) {
12581        $(this).removeClass('is-current');
12582        $(this).removeClass('default');
12583
12584        $(this).click();
12585      }
12586    });
12587  } else if ($('input#same-as-shipping').length == 0 && $('ul.address-list div.address-tile.is-current').length > 0) {
12588    // if no physical product to ship, re-select tile to properly assign billing address
12589    var reSelectTile = $('ul.address-list div.address-tile.is-current');
12590    reSelectTile.removeClass('is-current');
12591    reSelectTile.removeClass('default');
12592    reSelectTile.click();
12593  }
12594
12595  // trigger click event for selected by default cc (to manually trigger cc code)
12596  var selectedCC = $('div.payment-method div.creditcard-tile.selected');
12597  if (selectedCC) {
12598    selectedCC.removeClass('selected').click();
12599  }
12600
12601  // maximize order checkout summary dropdown
12602  util.maximizeCheckoutSummary();
12603
12604  // trigger only for non-registered users
12605  if (window.User.isCustomerAuthenticated == false) {
12606    $('input[name$="_creditCard_cvn"], input[name$="_creditCard_owner"]').on('change', function () {
12607      $('select[name$="_creditCard_expiration_month"]').trigger('change');
12608      $('select[name$="_creditCard_expiration_month"]').trigger('change');
12609    });
12610  }
12611
12612  $('.credit-card-create').magnificPopup({
12613    type: 'ajax',
12614    ajax: {
12615      settings: null, // Ajax settings object that will extend default one - http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
12616      // For example:
12617      // settings: {cache:false, async:false}
12618
12619      cursor: 'mfp-ajax-cur', // CSS class that will be added to body during the loading (adds "progress" cursor)
12620      tError: Resources.ADDNEWCARD_OPEN_ERROR //  Error message, can contain %curr% and %total% tags if gallery is enabled
12621    },
12622    callbacks: {
12623      parseAjax: function parseAjax(mfpResponse) {
12624        // mfpResponse.data is a "data" object from ajax "success" callback
12625        // for simple HTML file, it will be just String
12626
12627        // mfpResponse.data must be a String or a DOM (jQuery) element
12628        mfpResponse.data = $(mfpResponse.data).find('.c-block-modal01-gather').first();
12629      },
12630      ajaxContentAdded: function ajaxContentAdded() {
12631        $('#newcardmodal').remove();
12632        $('#dwfrm_billing').next().append('<div id="newcardmodal" class="c-block-modal01 mfp-hide"></div>');
12633        $('#newcardmodal').html(this.content[0].outerHTML);
12634        $.magnificPopup.open({
12635          items: {
12636            src: '#newcardmodal', // can be a HTML string, jQuery object, or CSS selector
12637            type: 'inline'
12638          }
12639        });
12640
12641        design.toggleSelectInit(true);
12642        creditCardTypeDetector();
12643        cardValidation.init();
12644        validator.initForm('form[id$="CreditCardForm"]');
12645      }
12646    }
12647  });
12648
12649  // select default credit card  after loading all javascript
12650  $(function () {
12651    if ($('#paymentmethods_defaultCardPositionNum').length > 0) {
12652      var $defaultCardPosition = $('#paymentmethods_defaultCardPositionNum');
12653      var defaultCardPositionNum = Number($defaultCardPosition.val());
12654      var gmoSelectedCard = Number($defaultCardPosition.data('gmo-selected-card'));
12655      var selectCreditId = '#card_' + gmoSelectedCard;
12656      if ($(selectCreditId).length === 0) {
12657        selectCreditId = '#card_' + defaultCardPositionNum;
12658      }
12659      $(selectCreditId).click();
12660      $(selectCreditId).closest('.creditcard-tile').click();
12661    }
12662  });
12663
12664  $(document).on('click', '.creditcard-tile-inner creditcarditem + label.label', function (ev) {
12665    ev.stopPropagation();
12666  });
12667};
12668
12669},{"../../ajax":1,"../../design":11,"../../giftcard":14,"../../modal":24,"../../util":77,"../../validator":78,"./card-validation":34,"./formPrepare":36}],34:[function(require,module,exports){
12670'use strict';
12671
12672// https://gist.github.com/ShirtlessKirk/2134376
12673
12674var errors = {};
12675var inputCVN = 'input[name$=_creditCard_cvn]';
12676var inputMonth = 'select[name$=_creditCard_expiration_month]';
12677var inputYear = 'select[name$=_creditCard_expiration_year]';
12678var inputType = 'select[name$=_creditCard_creditCard_type]';
12679
12680var luhnCheck = function (arr) {
12681  return function (ccNum) {
12682    var len = ccNum.length;
12683    var bit = 1;
12684    var sum = 0;
12685    var val;
12686
12687    while (len) {
12688      val = parseInt(ccNum.charAt(--len), 10);
12689      sum += (bit ^= 1) ? arr[val] : val;
12690    }
12691
12692    return sum && sum % 10 === 0;
12693  };
12694}([0, 2, 4, 6, 8, 1, 3, 5, 7, 9]);
12695
12696var cvvCheck = function cvvCheck(cvv) {
12697  return (/^[0-9]{3,4}$/.test(cvv)
12698  );
12699};
12700
12701var initCardExpiry = function initCardExpiry() {
12702  var ccSave = $('#CreditCardForm #applyBtn');
12703  ccSave.on('click', function (e) {
12704    validateCardExpiry(this, true);
12705  });
12706
12707  $('.card-expiry .c-select-current').on('change blur', function () {
12708    validateCardExpiry(this);
12709  });
12710
12711  $('form[id$=_billing] button[name$=_billing_save]').on('click touchstart', function (event) {
12712    if ($('.payment_creditcard').hasClass('is-active')) {
12713      validateCardExpiryDropdown($(this), true, event);
12714      validateCardType($(this), true, event);
12715    }
12716  });
12717
12718  $('form[id$=_billing] select[name$=_creditCard_expiration_month], form[id$=_billing] select[name$=_creditCard_expiration_year]').on('change', function () {
12719    validateCardExpiryDropdown($(this));
12720  });
12721
12722  $('form[id$=_billing] select[name$=_creditCard_type]').on('change', function () {
12723    validateCardType($(this));
12724  });
12725};
12726
12727var validateCardExpiry = function validateCardExpiry(el, checkEmpty) {
12728  console.log('validateCardExpiry');
12729  // need to declare specifically in order not to confuse with other forms with similar inputs
12730  var $this = $(el);
12731  var $month = $this.closest('form').find('.card-expiry.month .c-select-current');
12732  var $year = $this.closest('form').find('.card-expiry.year .c-select-current');
12733  var $submit = $this.closest('form').find('button[type="submit"]');
12734  var hasError = false;
12735
12736  var now = new Date();
12737  var nowMonth = now.getMonth() + 1;
12738  var nowYear = now.getFullYear();
12739
12740  $month.siblings('span.error').remove();
12741  $year.siblings('span.error').remove(); //-- Ade CG-4
12742  $month.removeClass('error');
12743  $year.removeClass('error');
12744  $submit.prop('disabled', false);
12745
12746  // validate only on form submit
12747  /*if(checkEmpty && (!$month.val() || !$year.val())){
12748  $('<span class="error">' + Resources.INVALID_CARDEXPIRY + '</span>').insertBefore($month);
12749  hasError = true;*/
12750  if (checkEmpty) {
12751    if (!$month.val()) {
12752      $('<span class="error" id="errormonth">' + Resources.INVALID_CARDEXPIRY + '</span>').insertBefore($month);
12753      hasError = true;
12754    }
12755    if (!$year.val()) {
12756      $('<span class="error" id="erroryear">' + Resources.INVALID_CARDEXPIRY + '</span>').insertBefore($year);
12757      hasError = true;
12758    }
12759    // validate only if month and year has value, otherwise, ignore
12760  } else if ($month.val() && $year.val()) {
12761    if ($year.val() < nowYear) {
12762      $('<span class="error">' + Resources.VALIDATE_CARDEXPIRY + '</span>').insertBefore($year);
12763      hasError = true;
12764    } else if ($month.val() < nowMonth && $year.val() == nowYear) {
12765      $('<span class="error">' + Resources.VALIDATE_CARDEXPIRY + '</span>').insertBefore($month);
12766      hasError = true;
12767    }
12768  }
12769
12770  // highlight inputs if expiry has error
12771  if (hasError) {
12772    $month.addClass('error');
12773    $year.addClass('error');
12774  }
12775
12776  // disable button if there are errors -- // change by ticket shi-5388
12777  if ($this.closest('form').find('span.error').length > 0) {
12778    $submit.prop('disabled', true);
12779  }
12780};
12781
12782function validateCardType($el, checkEmpty, e) {
12783  var $type = $el.closest('form').find('select[name$=_creditCard_type]');
12784
12785  if ($type.length) {
12786    var $typeWrapper = $type.parent();
12787    var typeValue = $type.val() ? $type.val() != 'null' ? $type.val() : 0 : 0;
12788
12789    if (checkEmpty) {
12790      if (!typeValue) {
12791        if ($type.attr('name').match('.*_creditCard_type')) {
12792          removeErrorType('select[name$=_creditCard_type]');
12793          showErrorType($type, Resources.INVALID_CREDITCARD_TYPE);
12794        } else {
12795          addError($type, Resources.INVALID_CREDITCARD_TYPE);
12796        }
12797      }
12798    } else {
12799      if (!typeValue) {
12800        if ($el.attr('name').match('.*_creditCard_type$')) {
12801          if ($el.closest($('form.checkout-billing')).length) {
12802            removeErrorType('select[name$=_creditCard_type]');
12803            showErrorType($type, Resources.INVALID_CREDITCARD_TYPE);
12804          } else {
12805            removeError($typeWrapper);
12806            if (!typeValue) {
12807              addError($typeWrapper, Resources.INVALID_CREDITCARD_TYPE);
12808            }
12809          }
12810        }
12811      } else if (typeValue) {
12812        removeErrorType('select[name$=_creditCard_type]');
12813      }
12814    }
12815  }
12816}
12817
12818function validateCardExpiryDropdown($el, checkEmpty, e) {
12819  var $month = $el.closest('form').find('select[name$=_creditCard_expiration_month]');
12820  var $year = $el.closest('form').find('select[name$=_creditCard_expiration_year]');
12821
12822  var monthValue = $month.val() ? $month.val() != 'null' ? $month.val() : 0 : 0;
12823  var yearValue = $year.val() ? $year.val() != 'null' ? $year.val() : 0 : 0;
12824
12825  var now = new Date();
12826  var nowMonth = now.getMonth() + 1;
12827  var nowYear = now.getFullYear();
12828
12829  var isAnyEmpty = !monthValue || !yearValue;
12830  var isInvalidExpiry = yearValue < nowYear || yearValue <= nowYear && monthValue < nowMonth;
12831
12832  // 保存ボタンを押した場合は、未入力チェックと期限チェックを実施
12833  // 期限を変更した場合は、未入力でない場合のみ期限チェックを実施(未入力の場合はバリデーションなし)
12834  if (checkEmpty && (isAnyEmpty || isInvalidExpiry) || !checkEmpty && !isAnyEmpty && isInvalidExpiry) {
12835    var errorMessage = !isAnyEmpty && isInvalidExpiry ? Resources.INVALID_CARDEXPIRY_EXPIRED : Resources.INVALID_CARDEXPIRY;
12836    pushError(inputMonth, errorMessage);
12837    pushError(inputYear);
12838    showError($month);
12839    return;
12840  }
12841  removeErrorInObj(inputMonth);
12842  removeErrorInObj(inputYear);
12843  $month.parents('.cmd-form_box.cmd-box_container').next('.cmd-form_err._simple').remove();
12844}
12845
12846function addError($el, message) {
12847  $el.find('.c-input-label').addClass('is-error');
12848  $el.find('.c-select').addClass('is-error');
12849  if (!$el.find('ul.c-text-error').length) {
12850    $('<ul class="c-text-error c-text-error--simple"><li class="is-error">' + message + '</li></ul>').insertAfter($el.find('.c-input-label'));
12851  }
12852}
12853
12854function removeError($el) {
12855  $el.find('ul.c-text-error').remove();
12856  $el.find('.c-input-label').removeClass('is-error');
12857  $el.find('.c-select').removeClass('is-error');
12858}
12859
12860function removeErrorInObj(key) {
12861  delete errors[key];
12862  var $el = $(key).closest('.cmd-form_box');
12863  if ($el.hasClass('is-error')) {
12864    $el.removeClass('is-error');
12865  }
12866}
12867
12868function removeErrorType(key) {
12869  $(key).parent().parent().closest('.cmd-box_container').next('.cmd-form_err._simple').remove();
12870  var $el = $('select[name$=_creditCard_type]').closest('.cmd-form_box');
12871
12872  if ($el.hasClass('is-error')) {
12873    $el.removeClass('is-error');
12874  }
12875}
12876
12877function pushError(key, val) {
12878  errors[key] = val;
12879}
12880
12881function showErrorType($el, message) {
12882  var $elCmd = $('select[name$=_creditCard_type]').closest('.cmd-form_box');
12883  if (!$elCmd.hasClass('is-error')) {
12884    $elCmd.addClass('is-error');
12885  }
12886  $('<p class="cmd-form_err _simple">' + message + '</p>').insertAfter($el.closest('.cmd-box_container'));
12887}
12888
12889function showError($el) {
12890  $el.parent().parent().parent().closest('.cmd-form_box').next('.cmd-form_err._simple').remove();
12891  if (Object.keys(errors).length > 0) {
12892    var errStr = '';
12893    for (var i in errors) {
12894      errStr += errors[i] ? errors[i] + '<br>' : '';
12895      // add class error
12896      var $elCmd = $(i).closest('.cmd-form_box');
12897      if (!$elCmd.hasClass('is-error')) {
12898        $elCmd.addClass('is-error');
12899      }
12900    }
12901    $('<p class="cmd-form_err _simple">' + errStr + '</p>').insertAfter($el.closest('.cmd-box_container'));
12902  }
12903}
12904
12905exports.init = function () {
12906  initCardExpiry();
12907};
12908exports.validateCardType = validateCardType;
12909exports.validateCardExpiryDropdown = validateCardExpiryDropdown;
12910
12911},{}],35:[function(require,module,exports){
12912'use strict';
12913
12914var customValidator = {
12915  RegistrationForm: function RegistrationForm($form) {
12916    var isBirthdayValid = birthdayCheck($form);
12917    var isStateValid = validateState($form);
12918    return isBirthdayValid && isStateValid;
12919  },
12920  EditAddressForm: function EditAddressForm($form) {
12921    return validateState($form);
12922  },
12923  PasswordResetForm: function PasswordResetForm($form) {
12924    return birthdayCheck($form);
12925  },
12926  ContactUsForm: function ContactUsForm($form) {
12927    return validateContactUs($form);
12928  },
12929  WithdrawForm: function WithdrawForm($form) {
12930    return validateWithdrawReason($form);
12931  },
12932  CreditCardForm: function CreditCardForm($form) {
12933    var isExpiry = validateCardExpiry($form, true);
12934    var isCardType = validateCardType($form);
12935    return isExpiry && isCardType;
12936  },
12937  dwfrm_billing: function dwfrm_billing($form) {
12938    if ($form.find('input[name$="_selectedPaymentMethodID"]:checked').val() === 'GMO_CVSSTORE') {
12939      return Boolean($('#gmo-cvs-code-selection').val());
12940    }
12941    if ($form.find('input[name$="_selectedPaymentMethodID"]:checked').val() === 'CREDIT_CARD') {
12942      var validateExpiryResult = validateExpiry($form);
12943      if (!validateExpiryResult.month || !validateExpiryResult.isValid) {
12944        addErrorFields($form, $form.find('[name$="_expiration_month"]'));
12945      } else if (!validateExpiryResult.year) {
12946        addErrorFields($form, $form.find('[name$="_expiration_year"]'));
12947      }
12948      return validateExpiryResult.isValid;
12949    }
12950    return true;
12951  }
12952};
12953
12954var initiator = {
12955  RegistrationForm: function RegistrationForm($form) {
12956    $form.find('[name$="_birthyear"], [name$="_birthmonth"], [name$="_dob"]').on('change', function () {
12957      var $birthday = $form.find('[name$="_birthday"]');
12958      if ($birthday.hasClass('is-error')) {
12959        birthdayCheck($form);
12960      }
12961    });
12962    $form.find('[name$="_state"]').on('change', function () {
12963      validateState($form);
12964    });
12965    $form.find('[name$="_addtodirectmaillist"]').on('change', function () {
12966      $form.find('[name$="_addtodirectmaillist"]').valid();
12967    });
12968  },
12969  EditAddressForm: function EditAddressForm($form) {
12970    $form.find('[name$="_state"]').on('change', function () {
12971      validateState($form);
12972    });
12973  },
12974  PasswordResetForm: function PasswordResetForm($form) {
12975    $form.find('[name$="_birthyear"], [name$="_birthmonth"], [name$="_dob"]').on('change', function () {
12976      var $birthday = $form.find('[name$="_birthday"]');
12977      if ($birthday.hasClass('is-error')) {
12978        birthdayCheck($form);
12979      }
12980    });
12981  },
12982  ContactUsForm: function ContactUsForm($form) {
12983    $form.find('[name$="_myquestion"]').on('change', function () {
12984      validateContactUs($form);
12985    });
12986  },
12987  WithdrawForm: function WithdrawForm($form) {
12988    $form.find('.c-c-input-checklist label input').on('change', function () {
12989      validateWithdrawReason($form);
12990    });
12991  },
12992  CreditCardForm: function CreditCardForm($form) {
12993    $form.find('[name$="_expiration_month"], [name$="_expiration_year"]').on('change', function () {
12994      validateCardExpiry($form, false);
12995    });
12996    $form.find('[name$="_newcreditcard_type"]').on('change', function () {
12997      validateCardType($form);
12998    });
12999  },
13000  'add-use-point': function addUsePoint($form) {
13001    function forceNaturalNumber(el) {
13002      var $el = $(el);
13003      var value = $el.val() || '';
13004      $el.val(value.replace(/[^0-9]/g, ''));
13005    }
13006    $form.find('input.point_value').on('blur', function (ev) {
13007      forceNaturalNumber(ev.target);
13008    });
13009  }
13010};
13011
13012function init($form) {
13013  var id = $form.attr('id');
13014  if (initiator[id]) {
13015    initiator[id]($form);
13016  }
13017
13018  var validator = customValidator[id] || function () {
13019    return true;
13020  };
13021  $form.data('custom-validator', function (e) {
13022    $form.data('error-fields', {});
13023
13024    var conditions = [$form.valid(), validator($form, e), $form.data('validator').numberOfInvalids() === 0, $form.data('submitting') !== true];
13025
13026    var isValid = conditions.reduce(function (valid, current) {
13027      return valid && current;
13028    }, true);
13029    if (!isValid) {
13030      scrollToFirstError($form);
13031    }
13032    return isValid;
13033  });
13034}
13035
13036function addErrorFields($form, $field, prev) {
13037  if (!$form.data('error-fields')) {
13038    $form.data('error-fields', {});
13039  }
13040  $form.data('error-fields')[$field.attr('name')] = prev ? $field.prev()[0] : $field[0];
13041}
13042
13043function scrollToFirstError($form) {
13044  if ($form.closest('.mfp-wrap').length > 0) {
13045    $form.closest('.mfp-wrap').animate({ scrollTop: 0 }, 200);
13046    return;
13047  }
13048  if ($form.find('.cpb-modalR_inner.cpb-modal_scroll.js-modal_scroll').length > 0) {
13049    $form.find('.cpb-modalR_inner.cpb-modal_scroll.js-modal_scroll').animate({ scrollTop: 0 }, 200);
13050    return;
13051  }
13052  var normalErrorFields = $form.data('validator').errorList.map(function (error) {
13053    return error.element;
13054  });
13055  var customErrorFields = Object.keys($form.data('error-fields')).map(function (key) {
13056    return $form.data('error-fields')[key];
13057  });
13058  var errorFields = normalErrorFields.concat(customErrorFields);
13059  var top = Math.min.apply(null, errorFields.map(function (e) {
13060    return $(e).offset().top;
13061  }));
13062  $('html, body').animate({ scrollTop: top - 100 }, 200);
13063}
13064function validateExpiry($form) {
13065  var $month = $form.find('[name$="_expiration_month"]');
13066  var $year = $form.find('[name$="_expiration_year"]');
13067  var month = Number($month.val());
13068  var year = Number($year.val());
13069  var now = new Date();
13070  var yearNow = now.getFullYear();
13071  var monthNow = now.getMonth() + 1;
13072
13073  return {
13074    month: month,
13075    year: year,
13076    isValid: month && year && (year > yearNow || year == yearNow && month >= monthNow)
13077  };
13078}
13079function birthdayCheck($form) {
13080  var $birthyear = $form.find('[name$="_birthyear"]');
13081  var $birthmonth = $form.find('[name$="_birthmonth"]');
13082  var $dob = $form.find('[name$="_dob"]');
13083  var $birthday = $form.find('[name$="_birthday"]');
13084  var fields = [$birthyear, $birthmonth, $dob];
13085  var $containerUl = $birthyear.closest('ul');
13086
13087  var onError = function onError(message) {
13088    $birthday.addClass('is-error');
13089    $containerUl.prev().addClass('is-error');
13090    $containerUl.find('.birthday-error').remove();
13091    $containerUl.append($('<li class="c-col c-col_sm_08 birthday-error"></li>').append($('<p style="margin-top: 5px;" class="c-input-label is-error"></p>').text(message)));
13092  };
13093
13094  var allValueExist = fields.reduce(function (valid, $field) {
13095    if (!Number($field.val())) {
13096      $field.prev().addClass('is-error');
13097      addErrorFields($form, $field, true);
13098      return false;
13099    }
13100    $field.prev().removeClass('is-error');
13101    return valid;
13102  }, true);
13103  if (!allValueExist) {
13104    onError(Resources.VALIDATE_REQUIRED);
13105    return false;
13106  }
13107
13108  var year = Number($birthyear.val());
13109  var month = Number($birthmonth.val());
13110  var date = Number($dob.val());
13111
13112  if (!validateDate(year, month, date)) {
13113    fields.forEach(function ($field) {
13114      $field.prev().addClass('is-error');
13115      addErrorFields($form, $field, true);
13116    });
13117    onError(Resources.INVALID_BIRTHDAY);
13118    return false;
13119  }
13120
13121  $birthday.removeClass('is-error');
13122  $birthday.val(zeroPadding(month, 2) + '/' + zeroPadding(date, 2) + '/' + year.toString());
13123  $containerUl.prev().removeClass('is-error');
13124  fields.forEach(function ($field) {
13125    $field.prev().removeClass('is-error');
13126  });
13127  $containerUl.find('.birthday-error').remove();
13128  return true;
13129}
13130
13131function validateDate(year, month, date) {
13132  var isLeapYear = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
13133  if (month === 2 && date > (isLeapYear ? 29 : 28)) {
13134    return false;
13135  }
13136  if (date > ([4, 6, 9, 11].indexOf(month) === -1 ? 31 : 30)) {
13137    return false;
13138  }
13139  var now = new Date();
13140  var yearNow = now.getFullYear();
13141  var monthNow = now.getMonth() + 1;
13142  var dateNow = now.getDate();
13143
13144  if (year < yearNow) {
13145    return true;
13146  }
13147  if (year > yearNow) {
13148    return false;
13149  }
13150  if (month < monthNow) {
13151    return true;
13152  }
13153  if (month > monthNow) {
13154    return false;
13155  }
13156  return date <= dateNow;
13157}
13158
13159function validateState($form) {
13160  var $state = $('[name$="_state"]');
13161  var $stateShippingPage = $('[name="dwfrm_singleshipping_shippingAddress_addressFields_states_state"]');
13162  var errorMessage;
13163  if (!$state.val()) {
13164    if ($state.closest('#editaddressmodal').length > 0 || $stateShippingPage.length > 0) {
13165      errorMessage = Resources.VALIDATE_REQUIRED;
13166    } else if (!$.validator.methods.addressForDM()) {
13167      errorMessage = Resources.VALIDATE_ADDRESS_FOR_DM;
13168    } else if (!$.validator.methods.primaryAddress()) {
13169      errorMessage = Resources.VALIDATE_ADDRESS;
13170    }
13171  }
13172  if (errorMessage && $stateShippingPage.length === 0) {
13173    addErrorFields($form, $state, true);
13174    $state.prev('.c-select').addClass('is-error');
13175    if ($state.parent().find('p.is-error').length === 0) {
13176      $state.parent().append('<p class="c-input-label is-error" style="margin-top:5px;">' + errorMessage + '</p>');
13177    }
13178    return false;
13179  }
13180
13181  if (errorMessage && $stateShippingPage.length > 0) {
13182    addErrorFields($form, $stateShippingPage, true);
13183    var errorId = $stateShippingPage.attr('name') + '-error';
13184    $stateShippingPage.parent().parent().find('#' + errorId).remove();
13185    $stateShippingPage.parent().after('<p id="' + errorId + '" class="jquery-validation is-error c-text-error c-text-error--simple">' + errorMessage + '</p>');
13186  } else {
13187    $stateShippingPage.parent().next().remove();
13188  }
13189
13190  $state.prev('.c-select').removeClass('is-error');
13191  $state.parent().find('.c-input-label.is-error').remove();
13192  return true;
13193}
13194
13195/**
13196 * Validate for contacus form
13197 * @returns
13198 */
13199function validateContactUs($form) {
13200  var $myquestion = $form.find('[name$=_myquestion]');
13201  var $myquestionField = $myquestion.parent().parent();
13202  if ($myquestion.val() === '') {
13203    $myquestion.prev().prev().addClass('is-error');
13204    $myquestion.prev().addClass('is-error');
13205    if ($myquestionField.find('li.c-col_sm_08>p.is-error').length === 0) {
13206      $('<li class="c-col c-col_sm_08"></li>').append($('<p class="c-input-label is-error"></p>').text(Resources.VALIDATE_REQUIRED)).insertAfter($myquestion.parent());
13207    }
13208    addErrorFields($form, $myquestion, true);
13209    return false;
13210  }
13211  $myquestion.prev().prev().removeClass('is-error');
13212  $myquestion.prev().removeClass('is-error');
13213  $myquestionField.find('li.c-col_sm_08>p.is-error').parent().remove();
13214  return true;
13215}
13216
13217function validateWithdrawReason($form) {
13218  var isChecked = $form.find('.c-c-input-checklist label input').toArray().some(function (e) {
13219    return $(e).prop('checked');
13220  });
13221  var $ul = $form.find('ul.c-c-input-checklist.c-block_01');
13222  if (!isChecked) {
13223    $ul.addClass('is-error');
13224    if ($ul.parent().find('.is-error.c-input-label').length === 0) {
13225      $('<p class="c-input-label is-error"></p>').text(Resources.VALIDATE_REASONS).insertBefore($ul);
13226    }
13227    addErrorFields($form, $ul.prev().prev());
13228    return false;
13229  }
13230  $ul.removeClass('is-error');
13231  $ul.parent().find('.is-error.c-input-label').remove();
13232  return true;
13233}
13234
13235/**
13236 * Validate for add new credit card form
13237 * @returns
13238 */
13239function validateCardExpiry($form, clickSave) {
13240  var $month = $form.find('[name$="_expiration_month"]');
13241  var $year = $form.find('[name$="_expiration_year"]');
13242  var fields = [$month, $year];
13243  var $containerUl = $month.closest('ul');
13244
13245  var month = Number($month.val());
13246  var year = Number($year.val());
13247  var now = new Date();
13248  var yearNow = now.getFullYear();
13249  var monthNow = now.getMonth() + 1;
13250
13251  var isAnyEmpty = 0 === month || 0 === year;
13252  var isInvalidExpiry = year < yearNow || year <= yearNow && month < monthNow;
13253
13254  // 保存ボタンを押した場合は、未入力チェックと期限チェックを実施
13255  // 期限を変更した場合は、未入力でない場合のみ期限チェックを実施(未入力の場合はバリデーションなし)
13256  if (clickSave && (isAnyEmpty || isInvalidExpiry) || !clickSave && !isAnyEmpty && isInvalidExpiry) {
13257    var errorMessage = !isAnyEmpty && isInvalidExpiry ? Resources.INVALID_CARDEXPIRY_EXPIRED : Resources.INVALID_CARDEXPIRY;
13258    fields.forEach(function ($field) {
13259      $month.parent().prev().addClass('is-error');
13260      $year.parent().prev().addClass('is-error');
13261      $month.parent().prev().parent().parent().parent().parent().find('#card-expiry-error').remove();
13262      $month.parent().prev().parent().parent().parent().after($('<p class="jquery-validation is-error c-text-error c-text-error--simple" id="card-expiry-error"></p>').text(errorMessage));
13263      $field.prev().addClass('is-error');
13264      addErrorFields($form, $field, true);
13265      $containerUl.prev().addClass('is-error');
13266      $containerUl.find('.card-expiry-error').remove();
13267
13268      //distinguish the validate text of between validate style  account-payment page and checkout-payment page
13269      if ($form.hasClass('credit-card-account')) {
13270        $containerUl.append($('<li class="c-col c-col_08 card-expiry-error"></li>').append($('<p class="c-input-label is-error"></p>').text(errorMessage)));
13271      } else {
13272        $containerUl.append($('<li class="c-col c-col_sm_08 card-expiry-error"></li>').append($('<p class="is-error c-text-error c-text-error--simple"></p>').text(errorMessage)));
13273      }
13274    });
13275    return false;
13276  }
13277
13278  $month.parent().prev().removeClass('is-error');
13279  $year.parent().prev().removeClass('is-error');
13280  $month.parent().prev().parent().parent().parent().parent().find('#card-expiry-error').remove();
13281  $containerUl.prev().removeClass('is-error');
13282  fields.forEach(function ($field) {
13283    $field.prev().removeClass('is-error');
13284  });
13285  $containerUl.find('.card-expiry-error').remove();
13286  return true;
13287}
13288
13289/**
13290 * Validate for add new credit card form
13291 * @returns
13292 */
13293function validateCardType($form) {
13294  var $cardType = $('[name$="_newcreditcard_type"]');
13295  var type = $cardType.val();
13296  var $containerUl = $cardType.closest('ul');
13297
13298  if (!type) {
13299    $cardType.prev().addClass('is-error');
13300    addErrorFields($form, $cardType, true);
13301    $cardType.prevAll().addClass('is-error');
13302    $containerUl.find('.card-type-error').remove();
13303
13304    //distinguish the validate text of between validate style  account-payment page and checkout-payment page
13305    if ($cardType.closest('li').length == 0) {
13306      $cardType.closest('.cmd-form_box').after($('<p class="jquery-validation is-error c-text-error c-text-error--simple card-type-error"></p>').text(Resources.VALIDATE_REQUIRED));
13307    } else if ($form.hasClass('credit-card-account')) {
13308      $cardType.closest('li').after($('<li class="c-col c-col_08 card-type-error"></li>').append($('<p class="c-input-label is-error"></p>').text(Resources.VALIDATE_REQUIRED)));
13309    } else {
13310      $cardType.closest('li').after($('<li class="c-col c-col_sm_08 card-type-error"></li>').append($('<p class="jquery-validation is-error c-text-error c-text-error--simple"></p>').text(Resources.VALIDATE_REQUIRED)));
13311    }
13312    return false;
13313  }
13314
13315  $cardType.prevAll().removeClass('is-error');
13316  if ($containerUl.length > 0) {
13317    $containerUl.find('.card-type-error').remove();
13318  } else {
13319    $cardType.closest('.cmd-form_box').siblings('.card-type-error').remove();
13320  }
13321  return true;
13322}
13323
13324/**
13325 * IEでは「Array.fill」が使えないため代替処理
13326 * 処理詳細は「MDN」参照
13327 *
13328 * @param {Array} value
13329 * @returns {Array}
13330 * @see {@link https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/fill#Polyfill Polyfill}
13331 */
13332function arrayFill(value) {
13333  // Steps 1-2.
13334  if (this == null) {
13335    throw new TypeError('this is null or not defined');
13336  }
13337
13338  var O = Object(this);
13339
13340  // Steps 3-5.
13341  var len = O.length >>> 0;
13342
13343  // Steps 6-7.
13344  var start = arguments[1];
13345  var relativeStart = start >> 0;
13346
13347  // Step 8.
13348  var k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
13349
13350  // Steps 9-10.
13351  var end = arguments[2];
13352  var relativeEnd = end === undefined ? len : end >> 0;
13353
13354  // Step 11.
13355  var final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);
13356
13357  // Step 12.
13358  while (k < final) {
13359    O[k] = value;
13360    k++;
13361  }
13362
13363  // Step 13.
13364  return O;
13365}
13366
13367function zeroPadding(number, digits) {
13368  if (Array.prototype.fill) {
13369    return (Array(digits).fill('0').join('') + number.toString()).slice(-digits);
13370  }
13371
13372  return (arrayFill.bind(Array(digits))('0').join('') + number.toString()).slice(-digits);
13373}
13374
13375module.exports = {
13376  init: init,
13377  validateDate: validateDate,
13378  zeroPadding: zeroPadding
13379};
13380
13381},{}],36:[function(require,module,exports){
13382'use strict';
13383
13384var _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; };
13385
13386var _ = require('lodash');
13387var customForm = require('./custom-form');
13388
13389var hasEmptyRequired = function hasEmptyRequired() {
13390  // filter out only the visible fields
13391  var requiredValues = this.$requiredInputs.filter(':visible').map(function () {
13392    return $(this).val();
13393  });
13394  return _(requiredValues).contains('');
13395};
13396
13397var validateForm = function validateForm() {
13398  var _self = this;
13399  // only validate form when all required fields are filled to avoid
13400  // throwing errors on empty form
13401  if (!this.validator) {
13402    return;
13403  }
13404
13405  // wait for the form to show before validating.. this applies to modals
13406  this.timer = setInterval(function () {
13407    if (_self.$form.is(':visible')) {
13408      if (_self.$form.find('span.error:visible, .error-form:visible').length == 0) {
13409        //!_self.hasEmptyRequired() &&
13410        _self.$continue.removeAttr('disabled');
13411      } else {
13412        _self.$continue.prop('disabled', true);
13413      }
13414      clearInterval(_self.timer);
13415    }
13416  }, 100);
13417};
13418
13419var validateEl = function validateEl(e) {
13420  if ($(e.target).val() === '') {
13421    this.$continue.prop('disabled', true);
13422  } else {
13423    // enable continue button on last required field that is valid
13424    // only validate single field
13425    if (!this.hasEmptyRequired()) {
13426      this.$continue.removeAttr('disabled');
13427    } else {
13428      this.$continue.prop('disabled', true);
13429    }
13430  }
13431};
13432
13433var checkValue = function checkValue(repopulateRequiredFields, e) {
13434  var $el = $(e.target);
13435  var attr = $el.attr('clear-on-error');
13436
13437  // check for new required fields (e.g. changing US -> CH in address)
13438  if (repopulateRequiredFields) {
13439    this.$requiredInputs = this.$form.find('input.required');
13440  }
13441
13442  // remove any error message residue from previous validation
13443  $el.siblings('span.is-error').remove();
13444
13445  if (this.validator.element($el) && this.$form.find('span.is-error:visible').length == 0) {
13446    this.$continue.prop('disabled', false);
13447  } else {
13448    //        this.$continue.prop('disabled', true);
13449
13450    // clear the value if input has error
13451    if ((typeof attr === 'undefined' ? 'undefined' : _typeof(attr)) !== (typeof undefined === 'undefined' ? 'undefined' : _typeof(undefined)) && attr !== false) $el.val('');
13452  }
13453};
13454
13455var submitForm = function submitForm(e) {
13456  this.$form.find('input').blur();
13457  this.$form.find('select').blur();
13458
13459  if (!this.$form.data('custom-validator')(e)) {
13460    //      this.$continue.prop('disabled', true);
13461    e.preventDefault();
13462    e.stopPropagation();
13463    return false;
13464  }
13465
13466  // adding this to prevent multiple submission of forms
13467  if (this.$form.attr('multiple-submission') === 'false') {
13468    this.$form.data('submitting', true);
13469  }
13470};
13471
13472var init = function init(opts, settings) {
13473  if (!opts.formSelector || !opts.continueSelector) {
13474    throw new Error('Missing form and continue action selectors.');
13475  }
13476  this.$form = $(opts.formSelector);
13477  this.$continue = $(opts.continueSelector);
13478  this.validator = settings ? this.$form.validate(settings) : this.$form.validate();
13479  this.$form.data('validator', this.validator);
13480  customForm.init(this.$form);
13481  this.$allInputs = $('input, textarea', this.$form);
13482  this.$allSelect = $('select', this.$form);
13483  this.$requiredInputs = this.$form.find('input.required');
13484  //    this.validateForm();
13485
13486  // start listening
13487  //    this.$requiredInputs.on('change', $.proxy(this.validateEl, this));
13488  //this.$allInputs.on('keyup', $.proxy(this.checkValue, this, false));
13489  this.$allSelect.on('blur', $.proxy(this.checkValue, this, true));
13490  this.$continue.on('click', $.proxy(this.submitForm, this));
13491  // [life-hack:5079] needed to trigger onclick since blur prevents the form from submitting
13492  if (this.$continue.attr('mousesubmit') === 'true') {
13493    this.$continue.on('mousedown', $.proxy(function (e) {
13494      this.$continue.click();
13495    }, this));
13496  }
13497};
13498
13499var formPrepare = function formPrepare() {
13500  return {
13501    $form: null,
13502    $continue: null,
13503    $allInputs: null,
13504    $allSelect: null,
13505    $requiredInputs: null,
13506    validator: null,
13507    init: init,
13508    timer: null,
13509    hasEmptyRequired: hasEmptyRequired,
13510    checkValue: checkValue,
13511    validateForm: validateForm,
13512    submitForm: submitForm,
13513    validateEl: validateEl
13514  };
13515};
13516
13517module.exports = formPrepare;
13518
13519},{"./custom-form":35,"lodash":111}],37:[function(require,module,exports){
13520'use strict';
13521
13522var address = require('./address'),
13523    billing = require('./billing'),
13524    multiship = require('./multiship'),
13525    shipping = require('./shipping'),
13526    cart = require('../cart');
13527
13528/**
13529 * @function Initializes the page events depending on the checkout stage (shipping/billing)
13530 */
13531exports.init = function () {
13532  address.init();
13533  cart.init();
13534  if ($('.checkout-shipping').length > 0) {
13535    shipping.init();
13536  } else if ($('.checkout-multi-shipping').length > 0) {
13537    multiship.init();
13538  } else {
13539    billing.init();
13540  }
13541
13542  //if on the order review page and there are products that are not available diable the submit order button
13543  if ($('.order-summary-footer').length > 0) {
13544    if ($('.notavailable').length > 0) {
13545      $('.order-summary-footer .submit-order .button-fancy-large').attr('disabled', 'disabled');
13546    }
13547  }
13548
13549  $('.cpb-cart-checkout_fixed.js-place-order').off('click.trigger.placeorder').on('click.trigger.placeorder', 'button', function () {
13550    $('#summary-place-order').trigger('click');
13551  });
13552  $(document).off('click.rakuten.placeorder', '.summary-place-order-rakuten').on('click.rakuten.placeorder', '.summary-place-order-rakuten', function () {
13553    $('#summary-place-order').trigger('click');
13554  });
13555  $('#summary-place-order').off('click.placeorder.loading').on('click.placeorder.loading', function () {
13556    $('html').addClass('cpb-is-loading');
13557  });
13558};
13559
13560},{"../cart":30,"./address":32,"./billing":33,"./multiship":39,"./shipping":40}],38:[function(require,module,exports){
13561'use strict';
13562
13563/**
13564 * @function
13565 * @description Enable/disable button depending if input has value
13566 */
13567
13568exports.init = function () {
13569  var $emailInput = $('.checkoutlogin input[type="email"]');
13570  var $emailButton = $('.checkoutlogin button');
13571  $emailInput.on('keyup', function (e) {
13572    if ($emailInput.val().length) {
13573      $emailButton.prop('disabled', false);
13574    } else {
13575      //    	    	$emailButton.prop('disabled', true);
13576    }
13577  });
13578};
13579
13580},{}],39:[function(require,module,exports){
13581'use strict';
13582
13583var address = require('./address'),
13584    formPrepare = require('./formPrepare'),
13585    dialog = require('../../dialog'),
13586    util = require('../../util'),
13587    validator = require('../../validator');
13588
13589/**
13590 * @function
13591 * @description Initializes gift message box for multiship shipping, the message box starts off as hidden and this will display it if the radio button is checked to yes, also added event handler to listen for when a radio button is pressed to display the message box
13592 */
13593function initMultiGiftMessageBox() {
13594  $.each($('.item-list'), function () {
13595    var $this = $(this);
13596    var $giftMessage = $this.find('.gift-message-text');
13597
13598    //handle initial load
13599    $giftMessage.toggleClass('hidden', $('input[name$="_isGift"]:checked', this).val() !== 'true');
13600
13601    //set event listeners
13602    $this.on('change', function () {
13603      $giftMessage.toggleClass('hidden', $('input[name$="_isGift"]:checked', this).val() !== 'true');
13604    });
13605  });
13606}
13607
13608/**
13609 * @function
13610 * @description capture add edit adddress form events
13611 */
13612function addEditAddress(target) {
13613  var $addressForm = $('form[name$="multishipping_editAddress"]'),
13614      $addressDropdown = $addressForm.find('select[name$=_addressList]'),
13615      $addressList = $addressForm.find('.address-list'),
13616      add = true,
13617      originalUUID,
13618      resetOptionValue = false,
13619      selectedAddressUUID = $(target).parent().siblings('.select-address').val();
13620
13621  $addressDropdown.on('change', function (e) {
13622    e.preventDefault();
13623
13624    var selectedAddress = $addressList.find('select').val();
13625    if (selectedAddress !== 'newAddress') {
13626      selectedAddress = $.grep($addressList.data('addresses'), function (add) {
13627        return add.UUID === selectedAddress;
13628      })[0];
13629      add = false;
13630      resetOptionValue = false;
13631      // proceed to fill the form with the selected address
13632      util.fillAddressFields(selectedAddress, $addressForm);
13633    } else if (selectedAddress === 'newAddress') {
13634      add = true;
13635      resetOptionValue = true;
13636      $addressForm.find('.input-text, .input-select').val('');
13637    } else {
13638      //reset the form if the value of the option is not a UUID
13639      $addressForm.find('.input-text, .input-select').val('');
13640    }
13641  });
13642
13643  $addressForm.on('click', '.cancel', function (e) {
13644    e.preventDefault();
13645    dialog.close();
13646  });
13647
13648  $addressForm.on('submit', function (e) {
13649    e.preventDefault();
13650    if (!$addressForm.valid()) {
13651      return false;
13652    }
13653
13654    $.getJSON(Urls.addEditAddress, $addressForm.serialize(), function (response) {
13655      if (!response.success) {
13656        $('#multiaddresserror').html(Resources.COULD_NOT_SAVE_ADDRESS);
13657        return;
13658      }
13659      $('#multiaddresserror').toggleClass('hidden', response.success);
13660
13661      var address = response.address,
13662          $shippingAddress = $(target).closest('.shippingaddress'),
13663          $select = $shippingAddress.find('.select-address'),
13664          $selected = $select.find('option:selected'),
13665          newOption = '<option value="' + address.UUID + '">' + (address.ID ? '(' + address.ID + ')' : address.firstName + ' ' + address.lastName) + ', ' + address.address1 + ', ' + address.city + ', ' + address.stateCode + ', ' + address.postalCode + '</option>';
13666      dialog.close();
13667
13668      if (address.UUID !== originalUUID) {
13669        resetOptionValue = true;
13670      }
13671
13672      if (add) {
13673        $('.shippingaddress select').removeClass('no-option').append(newOption);
13674        $('.no-address').hide();
13675      } else {
13676        $('.shippingaddress select').find('option[value="' + address.UUID + '"]').html(newOption);
13677      }
13678      // if there's no previously selected option, select it
13679      if ($selected.length === 0 || $selected.val() === '' || resetOptionValue) {
13680        $select.find('option[value="' + address.UUID + '"]').prop('selected', 'selected').trigger('change');
13681      }
13682    });
13683  });
13684
13685  //preserve the uuid of the option for the hop up form
13686  if (selectedAddressUUID) {
13687    //update the form with selected address
13688    $addressList.find('option').each(function () {
13689      //check the values of the options
13690      if ($(this).attr('value') === selectedAddressUUID) {
13691        $(this).prop('selected', 'selected');
13692        $addressDropdown.trigger('change');
13693      }
13694    });
13695    originalUUID = selectedAddressUUID;
13696  }
13697
13698  validator.init();
13699}
13700
13701/**
13702 * @function
13703 * @description shows gift message box in multiship, and if the page is the multi shipping address page it will call initmultishipshipaddress() to initialize the form
13704 */
13705exports.init = function () {
13706  initMultiGiftMessageBox();
13707  if ($('.cart-row .shippingaddress .select-address').length > 0) {
13708    validator.initForm('form[id$="multishipping_addressSelection"]');
13709  }
13710  $('.edit-address').on('click', 'span', function (e) {
13711    dialog.open({
13712      url: this.attributes.href.value,
13713      options: {
13714        open: function open() {
13715          address.init();
13716          addEditAddress(e.target);
13717        }
13718      }
13719    });
13720  });
13721};
13722
13723},{"../../dialog":12,"../../util":77,"../../validator":78,"./address":32,"./formPrepare":36}],40:[function(require,module,exports){
13724'use strict';
13725
13726var _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; };
13727
13728function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13729
13730var ajax = require('../../ajax'),
13731    progress = require('../../progress'),
13732    tooltip = require('../../tooltip'),
13733    util = require('../../util'),
13734    validator = require('../../validator'),
13735    modal = require('../../modal').global,
13736    design = require('../../design'),
13737    page = require('../../page'),
13738    addressVerificationSvc = require('../../qas');
13739
13740var $cache, shippingMethods;
13741
13742/**
13743 * Filter the delivery timespan based on the selected date and nearly date.
13744 * */
13745function filterDeliveryTimespan() {
13746  var selectedDate = $('.deliveryDate').val();
13747  var csrf_token = $('#checkout-shipping-deliverydate-csrf').val();
13748  var $form = $('#dwfrm_singleshipping_shippingAddress');
13749  var $shippingAddressSelection = $form.find('[name$="shipping"]:checked');
13750  var zipCode = $shippingAddressSelection.length > 0 ? $shippingAddressSelection.attr('data-postal-code') : $form.find('[name$="_postal"]').val();
13751
13752  if ($('.deliveryTime').length <= 0) {
13753    return;
13754  }
13755
13756  var url = Urls.filterDeliveryTimespan;
13757  var params = {
13758    selectedDate: selectedDate,
13759    zipCode: zipCode,
13760    format: 'ajax',
13761    csrf_token: csrf_token
13762  };
13763
13764  $.ajax({
13765    dataType: 'json',
13766    url: url,
13767    type: 'POST',
13768    data: params,
13769    loading: true
13770  }).done(function (data) {
13771    if (data && data.csrfToken) {
13772      $('#checkout-shipping-deliverydate-csrf').val(data.csrfToken);
13773    }
13774    if (!data || !data.success) {
13775      forceUnspecified($form.find('.deliveryDate'));
13776      forceUnspecified($form.find('.deliveryTime'));
13777      return;
13778    }
13779
13780    var selectbox = $('.deliveryTime');
13781    var currentlySelectedTime = $(selectbox).val();
13782    $(selectbox).empty();
13783    var deliveryTimeList = data.data;
13784    var isSelectedTimeValid = deliveryTimeList.some(function (item) {
13785      return item.value === currentlySelectedTime;
13786    });
13787    var selectedTime = isSelectedTimeValid ? currentlySelectedTime : '00'; // 00: Not Specified
13788    for (var i = 0; i < deliveryTimeList.length; i++) {
13789      var selectedText = deliveryTimeList[i].value === selectedTime ? 'selected="selected"' : '';
13790      $(selectbox).append($('<option ' + selectedText + '></option>').attr('value', deliveryTimeList[i].value).text(deliveryTimeList[i].name));
13791    }
13792
13793    if (data.isUnavailableTimespan) {
13794      $('.error-timespan').show();
13795      $('.error-timespan').text(Resources.UNAVAILABLE_TIMESPAN);
13796    } else {
13797      $('.error-timespan').hide();
13798      $('.error-timespan').text('');
13799    }
13800  });
13801}
13802
13803function updateDeliveryDateTime() {
13804  var url = Urls.updateDeliveryDateTimeSelection;
13805  var $form = $('#dwfrm_singleshipping_shippingAddress');
13806  var $shippingAddressSelection = $form.find('[name$="shipping"]:checked');
13807  var zipCode = $shippingAddressSelection.length > 0 ? $shippingAddressSelection.attr('data-postal-code') : $form.find('[name$="_postal"]').val();
13808  var params = {
13809    selectedDate: $('.deliveryDate').val(),
13810    selectedTimespan: $('.deliveryTime').val(),
13811    csrf_token: $('#checkout-shipping-deliverydate-csrf').val(),
13812    zipCode: zipCode
13813  };
13814  $.ajax({
13815    dataType: 'json',
13816    url: url,
13817    type: 'POST',
13818    data: params,
13819    loading: true
13820  }).done(function (data) {
13821    if (data && data.csrfToken) {
13822      $('#checkout-shipping-deliverydate-csrf').val(data.csrfToken);
13823    }
13824    if (!data.success && data.invalidDate) {
13825      updateDeliveryDateForm(zipCode);
13826      return;
13827    }
13828    if (!data.success) {
13829      forceUnspecified($form.find('.deliveryTime'));
13830      forceUnspecified($form.find('.deliveryDate'));
13831      return;
13832    }
13833    // do nothing if succeeded
13834  });
13835}
13836
13837function forceUnspecified($selectBox) {
13838  $selectBox.find('option:not(:first-of-type)').remove();
13839}
13840
13841function initCache() {
13842  var $formEle = $('form[id$="_shippingAddress"]');
13843  $cache = {
13844    addrForm: {
13845      address1: $formEle.find('input[name$="_address1"]'),
13846      address2: $formEle.find('input[name$="_address2"]'),
13847      countryCode: $formEle.find('input[id$="_country"]'),
13848      stateCode: $formEle.find('input[id$="_state"]'),
13849      postalCode: $formEle.find('input[name$="_postal"]'),
13850      city: $formEle.find('input[name$="_city"]')
13851    }
13852  };
13853}
13854
13855function updateDeliveryDateForm(zip7) {
13856  var params = {
13857    zip7: zip7,
13858    addunregistered: true
13859  };
13860  var $shippingErrorPlacement = $('#shipping-page-error');
13861  var $deliveryDatetime = $('#delivery-datetime');
13862  $.ajax({
13863    url: util.ajaxUrl(util.appendParamsToUrl(Urls.getdelivery, params)),
13864    type: 'get',
13865    loading: true
13866  }).done(function (data) {
13867    $shippingErrorPlacement.addClass('mfp-hide');
13868    $shippingErrorPlacement.text('');
13869    $deliveryDatetime.addClass('mfp-hide');
13870    $deliveryDatetime.text('');
13871    if (typeof data === 'string' && data !== '') {
13872      $deliveryDatetime.html(data);
13873      $deliveryDatetime.removeClass('mfp-hide');
13874    } else if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object' && !data.success) {
13875      $shippingErrorPlacement.text(data.errorMsg);
13876      $shippingErrorPlacement.removeClass('mfp-hide');
13877    } else {
13878      console.log('Something went wrong!');
13879    }
13880  });
13881}
13882
13883function initEvents() {
13884  $('#dwfrm_singleshipping_shippingAddress_addressFields_postal').change(function () {
13885    if ($(this).closest('.cmd-box_container').find('.customer-registered').length > 0) {
13886      var zipCode = $(this).val();
13887
13888      var regexp = new RegExp(/^[0-9]{7}$/);
13889      var valid = regexp.test(zipCode);
13890      if (valid) {
13891        $.ajax({
13892          url: Urls.getdelivery + '?zip7=' + zipCode,
13893          type: 'get'
13894        }).done(function (data) {
13895          if (data.length) {
13896            $('#delivrery-datatime').html(data);
13897            return;
13898          } else {
13899            console.log('delivery is empty');
13900          }
13901        });
13902      } else {
13903        console.log('invalid zipcode ');
13904      }
13905    }
13906  });
13907
13908  $(document)
13909  // create address link
13910  .on('click', '.address-create', function (evt) {
13911    evt.preventDefault();
13912    var $createShippingAddBtn = $(this);
13913    var dataSend = {
13914      format: 'ajax',
13915      showtype: 'rightmodal'
13916    };
13917    ajax.load({
13918      url: Urls.checkoutAddAddress,
13919      data: dataSend,
13920      callback: function callback(data) {
13921        $('.js-modal-r_content[data-modal-type="address"] .cpb-modalR_contents').html(data);
13922        // show modal
13923        cpbUi.util.rightModalOpen.call($createShippingAddBtn, undefined, function (target) {
13924          validator.initForm('form[id="EditAddressForm"]');
13925          cpbUi.niceScroll.ready();
13926          initAddressEvent();
13927        });
13928      }
13929    });
13930  })
13931
13932  // edit address link
13933  .on('click', '.address-edit', function (evt) {
13934    evt.preventDefault();
13935    var $editShippingAddressBtn = $(this);
13936    var addressID = $editShippingAddressBtn.data('address-id');
13937    var dataSend = {
13938      format: 'ajax',
13939      showtype: 'rightmodal'
13940    };
13941
13942    var addressObject = '';
13943    if ($editShippingAddressBtn.data('address') == 'wplus') {
13944      addressObject = $editShippingAddressBtn.data('address-object');
13945    }
13946
13947    var $target = $('.js-modal-r_content[data-modal-type="address"] .cpb-modalR_contents');
13948    $target.html('');
13949    ajax.load({
13950      url: Urls.checkoutEditShippingAddress + addressID + '&wplus=' + addressObject,
13951      data: dataSend,
13952      callback: function callback(data) {
13953        $target.html(data);
13954        if (addressID === 0) {
13955          var $addressName = $('#EditAddressForm input[name$="_addressFields_addressname"]');
13956          $addressName.prop('disabled', true);
13957          $addressName.prev().find('.required').hide();
13958        }
13959        // show modal
13960        cpbUi.util.rightModalOpen.call($editShippingAddressBtn, undefined, function (target) {
13961          validator.initForm('form[id="EditAddressForm"]');
13962          cpbUi.niceScroll.ready();
13963          initAddressEvent();
13964        });
13965      }
13966    });
13967  })
13968  // delete address link
13969  .on('click', '.address-delete', function (e) {
13970    e.preventDefault();
13971    var href = $(this).attr('href');
13972    var params = {
13973      wplus: $(this).attr('wplus'),
13974      format: 'ajax',
13975      csrf_token: this.dataset.csrfvalue
13976    };
13977    var url = util.appendParamsToUrl(href, params);
13978    var data = util.getQueryStringParams(util.getQueryString(url));
13979
13980    $.ajax({
13981      type: 'POST',
13982      url: url,
13983      data: data,
13984      dataType: 'json'
13985    }).done(function (data) {
13986      page.refresh();
13987    });
13988  })
13989
13990  // filter Delivery Timespan
13991  .off('change.filterDeliveryDate', '.deliveryDate').on('change.filterDeliveryDate', '.deliveryDate', function (e) {
13992    filterDeliveryTimespan();
13993  }).off('change.updateDeliveryDateTime', '.deliveryTime').on('change.updateDeliveryDateTime', '.deliveryTime', updateDeliveryDateTime)
13994
13995  // set default address
13996  .on('click', '.address-make-default', function (e) {
13997    e.preventDefault();
13998    var params = {
13999      wplus: $(this).attr('wplus'),
14000      format: 'ajax',
14001      csrf_token: this.dataset.csrfvalue,
14002      shipping: 'true'
14003    };
14004    var href = $(this).attr('href');
14005    href = util.appendParamsToUrl(href, params);
14006    var data = util.getQueryStringParams(util.getQueryString(href));
14007
14008    $.ajax({
14009      type: 'POST',
14010      url: href,
14011      data: data,
14012      dataType: 'json'
14013    }).done(function (data) {
14014      page.refresh();
14015    }).fail(function (jqXHR, textStatus, errorThrown) {
14016      console.log('error');
14017      console.log(jqXHR);
14018      console.log(textStatus);
14019      console.log(errorThrown);
14020    });
14021  })
14022
14023  // select address shipping
14024  .off('click', '.shipping-radio').on('click', '.shipping-radio', function () {
14025    var zip = $(this).data('postal-code');
14026    var addressId = $(this).data('address-id');
14027    var currentAddressId = $('input[name$="_shippingAddress_addressFields_addressid"]').val();
14028    var $form = $(this).closest('form.checkout-shipping');
14029    var $csrf = $form.find('#checkout-shipping-csrf');
14030    if (addressId == currentAddressId) {
14031      return;
14032    }
14033    $('input[name$="_shippingAddress_addressFields_addressid"]').val(addressId);
14034
14035    var $shippingErrorPlacement = $('#shipping-page-error');
14036    var $deliveryDatetime = $('#delivery-datetime');
14037    var url = Urls.updateAddressSelection;
14038    url = util.appendParamToURL(url, 'no', addressId);
14039    url = util.appendParamToURL(url, $csrf.attr('name'), $csrf.val());
14040
14041    $.ajax({
14042      url: util.ajaxUrl(url),
14043      type: 'get',
14044      loading: true
14045    }).done(function (data) {
14046      $shippingErrorPlacement.addClass('mfp-hide');
14047      $shippingErrorPlacement.text('');
14048      $deliveryDatetime.addClass('mfp-hide');
14049      $deliveryDatetime.text('');
14050      if (typeof data === 'string' && data !== '') {
14051        $deliveryDatetime.html(data);
14052        $deliveryDatetime.removeClass('mfp-hide');
14053      } else if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object' && !data.success) {
14054        if (data.invalidRequest) {
14055          window.location.href = Urls.generalError;
14056          return;
14057        }
14058        $shippingErrorPlacement.text(data.errorMsg);
14059        $shippingErrorPlacement.removeClass('mfp-hide');
14060      } else {
14061        console.log('Something went wrong!');
14062      }
14063    });
14064  }).off('focusout.deliveryDate', '#dwfrm_singleshipping_shippingAddress').on('focusout.deliveryDate', '#dwfrm_singleshipping_shippingAddress', function (ev) {
14065    if (!/_(postal|state|city|address1)$/.test($(ev.target).attr('name'))) {
14066      return;
14067    }
14068    var $form = $('#dwfrm_singleshipping_shippingAddress');
14069    var isAddressFullFilled = ['_postal', '_state', '_city', '_address1'].every(function (name) {
14070      return $form.find('[name$="' + name + '"]').val();
14071    });
14072    if (!isAddressFullFilled) {
14073      var $deliveryDatetime = $('#delivery-datetime');
14074      $deliveryDatetime.addClass('mfp-hide');
14075      return;
14076    }
14077    updateDeliveryDateForm($form.find('[name$="_postal"]').val());
14078  });
14079
14080  // authenticated user address change
14081  $('.address-list').on('change', '.address-tile input[name="shipping"]', function () {
14082    var $addressTile = $(this).closest('.address-tile');
14083    var addressID = $addressTile.data('addressId');
14084
14085    // update address; on success update shipping method list
14086    $.get(Urls.updateAddressDetails, { addressID: addressID }, function (response) {
14087      updateShippingMethodList();
14088    });
14089
14090    //checkSelectedAddress();
14091  });
14092
14093  // guest user address change
14094  var timer = null;
14095  $('form[id$="_shippingAddress"]').on('change', 'input[name$="_addressFields_address1"], input[name$="_addressFields_address2"], input[name$="_addressFields_states_state"], input[name$="_addressFields_city"], input[name$="_addressFields_postal"]', function () {
14096    if (!validateAddrForm()) {
14097      return;
14098    }
14099
14100    if (timer) {
14101      window.clearTimeout(timer);
14102    }
14103
14104    timer = window.setTimeout(function () {
14105      $.post(Urls.setShippingAddressDetails, $('form[id$="_singleshipping_shippingAddress"]').serialize(), function (result) {
14106        updateShippingMethodList();
14107      });
14108    }, 200);
14109  });
14110
14111  $('input[name$="_shippingAddress_isGift"]').on('click', giftMessageBox);
14112  $('input[name$="_cart_isGift"]').on('click', giftMessageBox);
14113
14114  $('.cpb-cart-gift_chk input[name$="_cart_isGift"]').on('change', applyGiftFlag);
14115  $('#checkout-form button[name$="_cart_checkoutCart"]').on('click', applyGiftFlag);
14116
14117  $('.cpb-cart-checkout_fixed .cpb-cart_submit button').off('click.checkout_fixed').on('click.checkout_fixed', function (e) {
14118    e.preventDefault();
14119    $('button.cpb-cart-side_submit').trigger('click');
14120  });
14121}
14122
14123/**
14124 * @function
14125 * @description Apply isGift flag to checkout form.
14126 */
14127function applyGiftFlag() {
14128  $('#checkout-form input[name$="_cart_isGift"]').val($('.cpb-cart-gift_chk input[name$="_cart_isGift"]').is(':checked'));
14129}
14130
14131/**
14132 * @function
14133 * @description Initializes gift message box, if shipment is gift
14134 */
14135function giftMessageBox() {
14136  // show gift message box, if shipment is gift
14137  $('.gift-message-text').toggleClass('hidden', $('input[name$="_shippingAddress_isGift"]:checked').val() !== 'true');
14138  $('.c-block-cartmessage').toggleClass('mfp-hide', $('input[name$="_cart_isGift"]:checked').val() !== 'true');
14139}
14140
14141/**
14142 * @function
14143 * @description updates the order summary based on a possibly recalculated basket after a shipping promotion has been applied
14144 */
14145function updateSummary() {
14146  var $summary = $('#secondary.summary');
14147  var couponError;
14148
14149  if ($('.cart-coupon-code .error').length) {
14150    couponError = $('.cart-coupon-code .error').clone();
14151  }
14152
14153  // indicate progress
14154  progress.show($summary);
14155
14156  // load the updated summary area
14157  $summary.load(Urls.summaryRefreshURL, function () {
14158    // hide edit shipping method link
14159    $summary.fadeIn('fast');
14160
14161    // checkout checkout minicart on right side event handling
14162    addSummaryScrollbar();
14163
14164    $summary.find('.checkout-mini-cart .minishipment .header a').hide();
14165    $summary.find('.order-totals-table .order-shipping .label a').hide();
14166    $('.cart-coupon-code').append(couponError);
14167    util.maximizeCheckoutSummary();
14168
14169    $('.checkout-mini-cart .accordion').foundation();
14170  });
14171}
14172
14173function getAddressFromTile() {
14174  var $selectedAddress = $('.address-tile.is-current address');
14175
14176  return {
14177    address1: $selectedAddress.data('address-one'),
14178    address2: $selectedAddress.data('address-two') || '',
14179    countryCode: $selectedAddress.data('country-code'),
14180    stateCode: $selectedAddress.data('state-code'),
14181    postalCode: $selectedAddress.data('postal-code'),
14182    city: $selectedAddress.data('city')
14183  };
14184}
14185
14186/**
14187 * Init submit button on address add/edit modal, on change content in form
14188 * @returns
14189 */
14190function initAddressEvent() {
14191  $('#EditAddressForm button[name$="_address_create"]').on('click', function (e) {
14192    e.preventDefault();
14193
14194    $(this).closest('[data-modal-type="address"]').find('.js-modal_scroll').removeClass('scroll-initialized');
14195
14196    cpbUi.niceScroll.ready();
14197  });
14198
14199  //link submit
14200  $('#EditAddressForm .shipping-address-submit-link').on('click', function (evt) {
14201    evt.preventDefault();
14202    $(this).parent().find('button.shipping-address-submit-button').click();
14203  });
14204
14205  $('#EditAddressForm button.shipping-address-submit-button').on('click', function (e) {
14206    var _util$appendParamsToU;
14207
14208    e.preventDefault();
14209    var $form = $('#EditAddressForm');
14210    if (!$form.data('custom-validator')(e)) {
14211      e.stopPropagation();
14212      return;
14213    }
14214    var dataToPost = $form.serialize();
14215    var url = util.appendParamsToUrl($(this).data('url'), (_util$appendParamsToU = {}, _defineProperty(_util$appendParamsToU, $(this).data('csrfname'), $(this).data('csrfvalue')), _defineProperty(_util$appendParamsToU, 'from', 'shipping'), _util$appendParamsToU));
14216    $.ajax({
14217      method: 'POST',
14218      url: url,
14219      data: dataToPost
14220    }).done(function (response) {
14221      if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success && response.validationError) {
14222        var errorObj = response.errors.reduce(function (result, error) {
14223          result[error.name] = error.message;
14224          return result;
14225        }, {});
14226        $form.data('validator').showErrors(errorObj);
14227        $form.data('submitting', false);
14228        return;
14229      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
14230        var errorText = response.errors.join('\n');
14231        var $errorPlacement = $('#EditAddressForm').find('.cmd-form_container>.cmd-form_err');
14232        $errorPlacement.empty().html(errorText);
14233        $errorPlacement.removeClass('mfp-hide');
14234      } else {
14235        page.refresh();
14236      }
14237    });
14238  });
14239}
14240
14241function getAddressFromForm() {
14242  return {
14243    address1: $cache.addrForm.address1.val(),
14244    address2: $cache.addrForm.address2.val(),
14245    countryCode: $cache.addrForm.countryCode.val(),
14246    stateCode: $cache.addrForm.stateCode.val(),
14247    postalCode: $cache.addrForm.postalCode.val(),
14248    city: $cache.addrForm.city.val()
14249  };
14250}
14251/**
14252 * @function
14253 * @description Helper method which constructs a URL for an AJAX request using the
14254 * entered address information as URL request parameters.
14255 */
14256function getShippingMethodURL(url, extraParams) {
14257  var params = User.isCustomerAuthenticated ? getAddressFromTile() : getAddressFromForm();
14258  return util.appendParamsToUrl(url, $.extend(params, extraParams));
14259}
14260
14261/**
14262 * @function
14263 * @description selects a shipping method for the default shipment and updates the summary section on the right hand side
14264 * @param
14265 */
14266function selectShippingMethod(shippingMethodID) {
14267  // nothing entered
14268  if (!shippingMethodID) {
14269    return;
14270  }
14271  // attempt to set shipping method
14272  var url = getShippingMethodURL(Urls.selectShippingMethodsList, {
14273    shippingMethodID: shippingMethodID
14274  });
14275  ajax.getJson({
14276    url: url,
14277    callback: function callback(data) {
14278      updateSummary();
14279      if (!data || !data.shippingMethodID) {
14280        window.alert("Couldn't select shipping method.");
14281        return false;
14282      }
14283      // display promotion in UI and update the summary section,
14284      // if some promotions were applied
14285      $('.shippingpromotions').empty();
14286
14287      // if (data.shippingPriceAdjustments && data.shippingPriceAdjustments.length > 0) {
14288      //     var len = data.shippingPriceAdjustments.length;
14289      //     for (var i=0; i < len; i++) {
14290      //         var spa = data.shippingPriceAdjustments[i];
14291      //     }
14292      // }
14293    }
14294  });
14295}
14296
14297/**
14298 * @function
14299 * @description Make an AJAX request to the server to retrieve the list of applicable shipping methods
14300 * based on the merchandise in the cart and the currently entered shipping address
14301 * (the address may be only partially entered).  If the list of applicable shipping methods
14302 * has changed because new address information has been entered, then issue another AJAX
14303 * request which updates the currently selected shipping method (if needed) and also updates
14304 * the UI.
14305 */
14306function updateShippingMethodList() {
14307  var $shippingMethodList = $('#shipping-method-list');
14308  if (!$shippingMethodList || $shippingMethodList.length === 0) {
14309    return;
14310  }
14311  var url = getShippingMethodURL(Urls.shippingMethodsJSON);
14312  ajax.getJson({
14313    url: url,
14314    callback: function callback(data) {
14315      if (!data) {
14316        window.alert("Couldn't get list of applicable shipping methods.");
14317        return false;
14318      }
14319
14320      // shipping methods remain unchanged; update summary as selected method may/may not change
14321      if (shippingMethods && shippingMethods.toString() === data.toString()) {
14322        updateSummary();
14323        return true;
14324      }
14325
14326      // We need to update the UI.  The list has changed.
14327      // Cache the array of returned shipping methods.
14328      shippingMethods = data;
14329      // indicate progress
14330      progress.show($shippingMethodList);
14331
14332      // load the shipping method form
14333      var smlUrl = getShippingMethodURL(Urls.shippingMethodsList);
14334      $shippingMethodList.load(smlUrl, function () {
14335        $shippingMethodList.fadeIn('fast');
14336        // rebind the radio buttons onclick function to a handler.
14337        $shippingMethodList.find('[name$="_shippingMethodID"]').click(function () {
14338          selectShippingMethod($(this).val());
14339        });
14340
14341        // update the summary
14342        updateSummary();
14343        progress.hide();
14344        tooltip.init();
14345        //if nothing is selected in the shipping methods select the first one
14346        if ($shippingMethodList.find('.input-radio:checked').length === 0) {
14347          $shippingMethodList.find('.input-radio:first').prop('checked', 'checked');
14348        }
14349      });
14350    }
14351  });
14352}
14353
14354/**
14355 * Check there is an address selected, if not, disable the continue button
14356 * */
14357function checkSelectedAddress() {
14358  var $form = $('form[id$="_shippingAddress"]');
14359  var $submit = $form.find('button[type="submit"]');
14360  var $footerSubmit = $('.cpb-cart-checkout_fixed .cpb-cart_submit button');
14361
14362  // enable the submit button if there are no shipping card
14363  // if there are, user must have at least 1 selected shipping card for the button to be enabled
14364  if ($form.find('.address-tile').length == 0 || $form.find('.address-tile input[name="shipping"]:checked').length) {
14365    $submit.prop('disabled', false);
14366    $footerSubmit.prop('disabled', false);
14367  } else {
14368    $submit.prop('disabled', true);
14369    $footerSubmit.prop('disabled', true);
14370  }
14371}
14372
14373function validateAddrForm() {
14374  var addr = getAddressFromForm();
14375  return addr.address1 && addr.city && addr.postalCode && addr.stateCode && addr.countryCode;
14376}
14377
14378function initCouponCodeField() {
14379  $('.cpb-cart-side_code input').on('keyup', function (e) {
14380    var couponCode = $('.cpb-cart-side_code input').val();
14381    if (couponCode == '') {
14382      $('#add-coupon').prop('disabled', true);
14383    } else {
14384      $('#add-coupon').prop('disabled', false);
14385    }
14386
14387    if (e.which === 13) {
14388      e.preventDefault();
14389      $('#add-coupon').click();
14390    }
14391  });
14392}
14393
14394exports.init = function () {
14395  initCache();
14396  initEvents();
14397  addressVerificationSvc.init();
14398
14399  if (window.User.isCustomerAuthenticated == false) {
14400    $('.checkout-shipping').find('.set-default-cb').hide();
14401  }
14402
14403  validator.initForm('form[name$="shippingAddress_save"]');
14404
14405  giftMessageBox();
14406  updateShippingMethodList();
14407  initCouponCodeField();
14408
14409  $(document).find('ul.address-list div.address-tile').each(function () {
14410    if ($(this).hasClass('default') || $(this).hasClass('is-current') || $(this).hasClass('address-default')) {
14411      $(this).removeClass('is-current');
14412      $(this).removeClass('default');
14413
14414      $(this).click();
14415    }
14416  });
14417
14418  //checkSelectedAddress();
14419};
14420exports.initCouponCodeField = initCouponCodeField;
14421exports.updateShippingMethodList = updateShippingMethodList;
14422
14423},{"../../ajax":1,"../../design":11,"../../modal":24,"../../page":28,"../../progress":64,"../../qas":65,"../../tooltip":76,"../../util":77,"../../validator":78}],41:[function(require,module,exports){
14424'use strict';
14425
14426var addProductToCart = require('./product/addToCart'),
14427    ajax = require('../ajax'),
14428    page = require('../page'),
14429    productTile = require('../product-tile'),
14430    quickview = require('../quickview');
14431
14432/**
14433 * @private
14434 * @function
14435 * @description Binds the click events to the remove-link and quick-view button
14436 */
14437function initializeEvents() {
14438  $('#compare-table').on('click', '.remove-link', function (e) {
14439    e.preventDefault();
14440    ajax.getJson({
14441      url: this.href,
14442      callback: function callback() {
14443        page.refresh();
14444      }
14445    });
14446  }).on('click', '.open-quick-view', function (e) {
14447    e.preventDefault();
14448    var url = $(this).closest('.product').find('.thumb-link').attr('href');
14449    quickview.show({
14450      url: url,
14451      source: 'quickview'
14452    });
14453  });
14454
14455  $('#compare-category-list').on('change', function () {
14456    $(this).closest('form').submit();
14457  });
14458}
14459
14460exports.init = function () {
14461  productTile.init();
14462  initializeEvents();
14463  addProductToCart();
14464};
14465
14466},{"../ajax":1,"../page":28,"../product-tile":63,"../quickview":66,"./product/addToCart":44}],42:[function(require,module,exports){
14467'use strict';
14468
14469var util = require('../util'),
14470    addToCart = require('./product/addToCart'),
14471    ajax = require('../ajax'),
14472    skin_trouble_check = require('./product/skin_trouble_check');
14473
14474function initializeEvents() {
14475  $(document)
14476  // mobile navigation
14477  .on('change', '.promotion-nav-select select', function (e) {
14478    var newUrl = $(this).find('option:selected').val();
14479
14480    if (newUrl) {
14481      window.location.href = newUrl;
14482    }
14483  });
14484
14485  // concierge form events
14486  var conciergeForm = $('form[id$="_beautyconsultant"]');
14487  if (conciergeForm.length > 0) {
14488    // secure concierge access
14489    /*if (location && location.protocol === 'http:') {
14490            window.location.href = Urls.secureConciergeForm;
14491        }*/
14492
14493    var successShown = false;
14494    conciergeForm.on('click', 'button#sendBtn', function (e) {
14495      e.preventDefault();
14496
14497      $.ajax({
14498        url: util.appendParamToURL(Urls.customerServiceSubmit, 'source', 'concierge'),
14499        data: conciergeForm.serialize(),
14500        method: 'POST'
14501      }).done(function (response) {
14502        var conciergeModal = $('#concierge-modal');
14503        if (response && response.success && conciergeModal.length > 0) {
14504          // show success modal
14505          successShown = true;
14506          var popup = new Foundation.Reveal(conciergeModal);
14507          //Window height minus 80px, which sets the modal to fit inside the device's screen
14508          var windowHeight = window.innerHeight - 130;
14509
14510          popup.$element.children('.modal-body').css('max-height', windowHeight);
14511          popup.open();
14512
14513          // trigger ga
14514          window.history.pushState('', '', Urls.conciergeForm);
14515          $(document).trigger('askanexpert');
14516        }
14517      });
14518    });
14519
14520    $(document).on('click', '.reveal-overlay', function () {
14521      // trigger redirect when concierge overlay is closed
14522      if (successShown && $(this).css('display') == 'none') {
14523        successShown = false;
14524        window.location.href = Urls.secureConciergeForm;
14525      }
14526    });
14527  }
14528
14529  var $productServiceModal = $('#psm-in-asset');
14530  if ($productServiceModal.length > 0) {
14531    $('.open_engrave_asset').on('click', function (e) {
14532      e.preventDefault();
14533
14534      $('#naire-data').val('');
14535      $('.cpb-naire_preview_txt.js-naire-preview').text(Resources.ENGRAVING_DEFAULT_DISP);
14536      simpleUpdateContent($(this).data('url'));
14537
14538      setTimeout(function () {
14539        cpbUi.util.rightModalOpen.call($('.open_engrave_asset'), undefined, function () {
14540          cpbUi.niceScroll.ready();
14541        });
14542      }, 300);
14543    });
14544  }
14545}
14546
14547function initActions() {
14548  $('#psm-in-asset .product-service-step1 .cpb-naire-color_list a').off('click.naire_color').on('click.naire_color', function (e) {
14549    e.preventDefault();
14550    var data = {
14551      Quantity: '1',
14552      isProductServiceModal: true
14553    };
14554    simpleUpdateContent($(this).attr('href'), data);
14555    return false;
14556  });
14557}
14558
14559function simpleUpdateContent(url, data) {
14560  var edgingtext = $('[name$=_edgingtext]').val();
14561  ajax.load({
14562    url: util.ajaxUrl(url),
14563    data: data,
14564    target: '.product-service',
14565    callback: function callback() {
14566      initActions();
14567      addToCart();
14568      if (edgingtext) {
14569        $('.product-service #naire-data').val(edgingtext);
14570        $('.product-service .js-naire-preview').empty().text(edgingtext);
14571      }
14572    }
14573  });
14574}
14575
14576module.exports.init = function () {
14577  initializeEvents();
14578};
14579
14580},{"../ajax":1,"../util":77,"./product/addToCart":44,"./product/skin_trouble_check":52}],43:[function(require,module,exports){
14581'use strict';
14582
14583var recommendations = require('./product/recommendations');
14584
14585exports.init = function () {
14586  if ($('.pt_order-confirmation').length) {
14587    recommendations();
14588  } else {
14589    return;
14590  }
14591};
14592
14593},{"./product/recommendations":51}],44:[function(require,module,exports){
14594'use strict';
14595
14596var _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; };
14597
14598var dialog = require('../../dialog'),
14599    minicart = require('../../minicart'),
14600    page = require('../../page'),
14601    util = require('../../util'),
14602    Promise = require('promise'),
14603    _ = require('lodash'),
14604    design = require('../../design'),
14605    skin_trouble_check = require('./skin_trouble_check');
14606var quickview = require('../../quickview');
14607
14608/**
14609 * @description set addToCart error message
14610 * @param {String} msg
14611 */
14612var timer;
14613var setAddToCartError = function setAddToCartError(msg) {
14614  var $errEle = $('.cmd-form_err');
14615  $errEle.html(msg);
14616  $errEle.show();
14617};
14618
14619/**
14620 * @description Make the AJAX request to add an item to cart
14621 * @param {Element} form The form element that contains the item quantity and ID data
14622 * @returns {Promise}
14623 */
14624var addItemToCart = function addItemToCart(form) {
14625  var $form = $(form);
14626  return $.ajax({
14627    type: 'POST',
14628    url: util.ajaxUrl(Urls.addProduct),
14629    data: $form.serialize(),
14630    loading: true
14631  }).then(function (response) {
14632    // handle error in the response
14633    if (response.error) {
14634      setAddToCartError(response.error);
14635      return { success: false, result: response };
14636    }
14637    return { success: true, result: response };
14638  });
14639};
14640
14641/**
14642 * set addToCartType
14643 */
14644var setAddToCartType = function setAddToCartType(type, pid) {
14645  $.ajax({
14646    type: 'POST',
14647    url: util.appendParamsToUrl(util.ajaxUrl(Urls.addToCartType), {
14648      type: type,
14649      pid: pid
14650    })
14651  });
14652};
14653
14654/**
14655 * @description Handler to handle the add to cart event
14656 */
14657var addToCart = function addToCart(e, $this) {
14658  e.preventDefault();
14659  var $form = $this ? $this.closest('form') : $(this).closest('form');
14660  $form.find('input[name="Quantity"]').val($form.find('.c-quantitySelection .c-select-current').text() || 1);
14661  var pid = $form.find('input[name="pid"]').val();
14662  var isQuickView = $(this).parents('#cpb-modal-quickview').length > 0 || $form.hasClass('quickview-form');
14663  var addToCartType = isQuickView ? 'Quick Shop' : 'Product page';
14664  return $.when(addItemToCart($form)).then(function (response) {
14665    var href = $form.find('.quickview-source-url').attr('href');
14666    // クイックビュー用一時確保formを削除する。
14667    $('.quickview-form').remove();
14668
14669    if (!response.success) {
14670      var error = {
14671        isQuickView: isQuickView,
14672        pid: pid,
14673        href: href,
14674        message: response.result.error
14675      };
14676      var deferred = $.Deferred();
14677      deferred.reject(error);
14678      return deferred.promise();
14679    }
14680
14681    var $uuid = $form.find('input[name="uuid"]');
14682    // ここで格納された関数は肌トラブルチェックの最後に実行される
14683    var callBackFunc = function () {
14684      if ($uuid.length > 0 && $uuid.val().length > 0) {
14685        return page.refresh;
14686      } else {
14687        // do not close quickview if adding individual item that is part of product set
14688        // @TODO should notify the user some other way that the add action has completed successfully
14689        $(document).trigger('gtadd-to-cart');
14690        return function () {
14691          minicart.show(response.result);
14692        };
14693      }
14694    }();
14695    setAddToCartType(addToCartType, pid);
14696    return callBackFunc;
14697  }.bind(this)).then(function (value) {
14698    // dummy success handler
14699    return value;
14700  }, function (error) {
14701    if ((typeof error === 'undefined' ? 'undefined' : _typeof(error)) !== 'object' || !error.isQuickView) {
14702      return $.Deferred().reject(error).promise();
14703    }
14704    quickview.openQuickView(error.href).then(function () {
14705      if (error.message) {
14706        var $bottom = $('#cpb-modal-quickview form .cpb-modalR_bottom');
14707        $bottom.find('.quickview-error-message').remove();
14708        $bottom.prepend($('<ul class="c-text-error quickview-error-message"><li>' + error.message + '</li></ul>'));
14709      }
14710    });
14711  });
14712};
14713exports.addToCart = addToCart;
14714
14715/**
14716 * @description Handler to handle the add all items to cart event
14717 */
14718var addAllTo = function addAllTo(e) {
14719  e.preventDefault();
14720
14721  var pidData = formatPidDataFromEles($('.cpb-products-variety_area').find('.cpb-products-variety_box'));
14722  return minicart.addAllProducts(pidData, e.data.to, e.currentTarget);
14723};
14724
14725/**
14726 * @description Handler to handle the add an item to cart event on PDP footer
14727 */
14728var addToCartOnFooter = function addToCartOnFooter(e) {
14729  e.preventDefault();
14730  var $form = $('.pdpForm');
14731  if (!$form.length || $(this).find('button').prop('disabled')) {
14732    return;
14733  }
14734
14735  var quantity = 1;
14736
14737  $form.find('input[name="Quantity"]').val(quantity);
14738  var pid = $form.find('input[name="pid"]').val();
14739
14740  return $.when(addItemToCart($form)).then(function (response) {
14741    if (!response.success) {
14742      return $.Deferred().reject().promise();
14743    }
14744
14745    var $uuid = $form.find('input[name="uuid"]');
14746
14747    // ここで格納された関数は肌トラブルチェックの最後に実行される
14748    var callBackFunc = function () {
14749      if ($uuid.length > 0 && $uuid.val().length > 0) {
14750        return page.refresh;
14751      } else {
14752        // do not close quickview if adding individual item that is part of product set
14753        // @TODO should notify the user some other way that the add action has completed successfully
14754        $(document).trigger('gtadd-to-cart');
14755        return function () {
14756          minicart.show(response.result);
14757        };
14758      }
14759    }();
14760
14761    setAddToCartType('Product page', pid);
14762    return callBackFunc;
14763  }.bind(this));
14764};
14765
14766// Accepts jQuery selector of n elements containing data attr storing pid
14767// Returns formatted pid data required for addAllProducts request (ex. 'pidA:1,pidB:1,pidN:1')
14768// To fetch qty, searches for qty dropdown or defaults to 1
14769function formatPidDataFromEles($selector) {
14770  return $selector.toArray().map(function (ele) {
14771    var $ele = $(ele),
14772        pid = $ele.find('input[name="setpd"]').val(),
14773        qty = $ele.find('input[name="Quantity"]').length ? $ele.find('input[name="Quantity"]').val() : 1;
14774
14775    return pid + ':' + qty;
14776  }).join(',');
14777}
14778
14779/**
14780 * @function
14781 * @description Binds the click event to a given target for the add-to-cart handling
14782 */
14783module.exports = function () {
14784  $('.add-to-cart[disabled]').attr('title', $('.availability-msg').text());
14785  $('#add-all-to-cart').off('click').on('click', { to: 'Cart' }, skinCheckAddAllTo);
14786  $('.cpb-products-cart_fixed').off('click.fotter').on('click.fotter', '.cpb-products-cart_submit button', skinCheckAddToCartOnFooter);
14787  $('.open_engrave.c-btn.c-btn-secondary').off('click').on('click', skincheckEngrave);
14788  $('#cpb-products_submit .add-to-cart').on('click', skinCheck);
14789  $('#add-to-cart-in-modal').on('click', addToCartFromServiceModal);
14790  $('.js-naire-setting-button').on('click', function (e) {
14791    e.preventDefault();
14792    $('#naire-data').siblings('p.is-error').remove();
14793    if ($('#naire-data').val() == '') {
14794      $('#naire-data').after($('<p class="c-input-label is-error"></p>').append(Resources.ENGRAVING_DATA_EMPTY));
14795    } else {
14796      $('.js-naire-setting').click();
14797    }
14798  });
14799};
14800
14801/**
14802 * duplicated add-to-cart from export above - endorse for re-factoring
14803 * reason for duplication : sometimes add to bag/cart script won't trigger/execute
14804 */
14805$(document).on('click', '#samples-add-to-cart', addSamplesToCart);
14806$(document).on('click', '.cpb-cart-sample_list .cpb-cart-sample_item .cpb-cart-sample_chk label', sampleTileSelect);
14807$(document).on('change', '.reveal.sample-selection .close-button', function (e) {
14808  scrollToTop(e);
14809});
14810$('form.multi-select-form').on('submit', function (e) {
14811  e.preventDefault();
14812
14813  var pidData = formatPidDataFromEles($(this).find('button.multiselect[value="selected"]'));
14814  minicart.addAllProducts(pidData, 'Cart');
14815});
14816
14817function sampleTileSelect(e) {
14818  e.preventDefault();
14819
14820  var $this = $(this).closest('.cpb-cart-sample_item');
14821  var $tile = $this.find('[name="sampleselect"]');
14822  $tile.prop('checked', !$tile.prop('checked'));
14823  var $multiSelectForm = $this.parents('form');
14824  var $thresholdInput = $multiSelectForm.find('input#pids');
14825
14826  var selectedCount = $multiSelectForm.find($('input[name="sampleselect"]:checked')).length;
14827  var limitCount = $thresholdInput.data('limit');
14828
14829  if (!$('#sampleserror').hasClass('invisible')) {
14830    $('#sampleserror').addClass('invisible');
14831    $('#sampleserror').text(null);
14832  }
14833
14834  // do checking to compare if limit is met
14835  if (selectedCount > limitCount) {
14836    // toggle val/text
14837    $tile.prop('checked', false);
14838    $('#sampleserror').removeClass('invisible');
14839    $('#sampleserror').text($('input#pids').data('error'));
14840
14841    // refresh niceScroll
14842    var $niceScrollPlace = $(this).closest('[data-modal-type="sample"]').find('.js-modal_scroll');
14843    $niceScrollPlace.removeClass('scroll-initialized');
14844    cpbUi.niceScroll.ready();
14845    $niceScrollPlace.getNiceScroll(0).doScrollTop(0);
14846  }
14847
14848  var selectedProductList = [];
14849
14850  // fetch all items that are selected
14851  $multiSelectForm.find('[name="sampleselect"]:checked').each(function (index, item) {
14852    selectedProductList.push($(item).val());
14853  });
14854
14855  // store all selected products to hidden input
14856  $thresholdInput.val(selectedProductList);
14857
14858  // update selected counter
14859  var selectedCount = parseInt(selectedProductList.length);
14860  var selectedLimit = parseInt($thresholdInput.data('count'));
14861  $('span#sample-count').html(selectedCount <= selectedLimit ? selectedCount : selectedLimit);
14862
14863  // enable "Add to Bag" button
14864  var cartButton = $thresholdInput.data('button');
14865  $('#' + cartButton).removeAttr('disabled');
14866  $('button#' + cartButton).removeClass('is-outofstock');
14867}
14868
14869function addSamplesToCart(e) {
14870  e.preventDefault();
14871
14872  var url = util.toAbsoluteUrl($(this).data('action'));
14873  var data = {};
14874  data['pid'] = $(this).parents('form').find('input#pids').val();
14875  data[$(this).parents('form').find('input#csrf')[0].name] = $(this).parents('form').find('input#csrf').val();
14876
14877  $.ajax({
14878    url: util.appendParamToURL(url, 'format', 'ajax'),
14879    data: data,
14880    method: 'POST'
14881  }).done(function (response) {
14882    if ($(location).attr('pathname').match('.*Cart-Show$|.*Cart-SubmitForm$') || pageContext.type === 'Cart') {
14883      window.location.assign(Urls.cartShow);
14884    } else {
14885      minicart.show(response);
14886      design.dropdownToggleInit();
14887    }
14888  });
14889
14890  // close sample modal
14891  cpbUi.util.rightModalClose.call($('.js-modal-r_content[data-modal-type="sample"] .js-modal-r_close'), undefined, function (target) {});
14892}
14893
14894function skinCheck(e) {
14895  var isQuickView = $(this).parents('#cpb-modal-quickview').length > 0;
14896  if (isQuickView) {
14897    // モーダルを閉じるときの時間差でsubmitが走ってしまうのでイベントを止める
14898    e.preventDefault();
14899    // クイックビュー内にフォームがあるため、一時的に外部に確保しておく。(addToCart関数内で削除する)
14900    $(this).closest('form').clone().addClass('quickview-form').addClass('mfp-hide').appendTo('body');
14901    // クイックビューを閉じてから、肌トラブルチェックを実行する
14902    cpbUi.util.rightModalClose.call($('#cpb-modal-quickview .js-quickview_close'), 'quickview', function () {
14903      $('#cpb-modal-quickview').find('.js-modal_scroll').getNiceScroll().remove();
14904      $('#cpb-modal-quickview').remove();
14905      cpbUi.isQuickView = false;
14906      skin_trouble_check.skinTroubleExecute(e, $('.quickview-form #cpb-products_submit .add-to-cart'), addToCart);
14907    });
14908  } else {
14909    skin_trouble_check.skinTroubleExecute(e, $(this), addToCart);
14910  }
14911}
14912
14913// skin check before displaying  engraving service
14914function skincheckEngrave(e) {
14915  $('#naire-data').val('');
14916  $('.cpb-naire_preview_txt.js-naire-preview').text(Resources.ENGRAVING_DEFAULT_DISP);
14917  setTimeout(function () {
14918    cpbUi.util.rightModalOpen.call($('.open_engrave'), undefined, function (target) {
14919      cpbUi.niceScroll.ready();
14920    });
14921  }, 300);
14922}
14923
14924function skinCheckAddAllTo(e) {
14925  var setNotEmpty = $(this).closest('form.pdpForm').find('input[name="Quantity"]').toArray().some(function (quantity) {
14926    return $(quantity).val() > 0;
14927  });
14928
14929  if (!setNotEmpty) {
14930    // セット小商品の個数がすべて0の場合はエラーを表示して処理を止める
14931    var errorBeforeElem = $('form.pdpForm').find('button#add-all-to-cart').parent();
14932    errorBeforeElem.siblings('.cmd-form_err').remove();
14933    errorBeforeElem.after($('<div class="cmd-form_err _simple"></div>').text(Resources.SET_NOT_ADD_PRODUCT));
14934    return false;
14935  }
14936
14937  skin_trouble_check.skinTroubleExecute(e, $(this), addAllTo);
14938}
14939
14940function skinCheckAddToCartOnFooter(e) {
14941  skin_trouble_check.skinTroubleExecute(e, $(this), addToCartOnFooter);
14942}
14943
14944/**
14945 * 刻印サービスのモーダル内にあるショッピングバッグに入れるボタン用関数(LP、PDP)
14946 *
14947 * @param {*} e イベント
14948 */
14949function addToCartFromServiceModal(e) {
14950  // カート追加用関数
14951  var addToCart = function () {
14952    e.preventDefault();
14953    var productId = $(this).attr('data-product');
14954    var engravingText = $('#naire-data').val();
14955    var engravingFont = $('input[name=naire-font]:checked').data('id');
14956    if (productId === '') {
14957      return;
14958    }
14959
14960    if (engravingText === '') {
14961      engravingText = $('#naire-data').attr('placeholder');
14962    }
14963
14964    return $.ajax({
14965      method: 'post',
14966      url: Urls.addToCartInModal,
14967      data: {
14968        productId: productId,
14969        engravingText: engravingText,
14970        engravingFont: engravingFont
14971      },
14972      loading: true
14973    }).then(function (response) {
14974      if (response.success) {
14975        window.location.href = Urls.cartShow;
14976      } else {
14977        if (response.showGeneralError) {
14978          return window.location.href = Urls.generalError;
14979        }
14980        var errorAreaArray = [];
14981        errorAreaArray.push($('#add-to-cart-in-modal').closest('.cpb-modalR_bottom').find('.c-text-error'));
14982        errorAreaArray.push(function () {
14983          var ele = $('.cpb-modalR_bottom').toArray().filter(function (ele) {
14984            return $(ele).find('button').data('target') === 'naire-setting';
14985          })[0];
14986          return $(ele).find('.c-text-error');
14987        }());
14988        errorAreaArray.forEach(function (ele) {
14989          $(ele).find('li').remove();
14990          $(ele).append($('<li></li>').text(response.error));
14991          $(ele).removeClass('mfp-hide');
14992        });
14993
14994        $('#productservicemodal').find('.cpb-naire-variation').before(response.error);
14995
14996        // 刻印サービス用モーダルは閉じているので再度開く
14997        var targetElement = function () {
14998          var element = $('.open_engrave');
14999          if (element.length > 0) {
15000            return element;
15001          }
15002          return $('.open_engrave_asset');
15003        }();
15004        return $.Deferred().reject(function () {
15005          cpbUi.util.rightModalOpen.call(targetElement, undefined, function (target) {
15006            cpbUi.niceScroll.ready();
15007          });
15008        }).promise();
15009      }
15010    });
15011  }.bind(this);
15012
15013  // 刻印サービス用モーダルを閉じてから肌トラブルチェックを行う
15014  cpbUi.util.rightModalClose.call($('.product-service .js-modal-r_close'), undefined, skin_trouble_check.skinTroubleExecute(e, $(this), addToCart));
15015}
15016
15017},{"../../design":11,"../../dialog":12,"../../minicart":23,"../../page":28,"../../quickview":66,"../../util":77,"./skin_trouble_check":52,"lodash":111,"promise":121}],45:[function(require,module,exports){
15018'use strict';
15019
15020var ajax = require('../../ajax'),
15021    util = require('../../util');
15022
15023var updateContainer = function updateContainer(data) {
15024  var $availabilityMsg = $('.pdp-main .cpb-products-stock');
15025  var message; // this should be lexically scoped, when `let` is supported (ES6)
15026  if (!data) {
15027    $availabilityMsg.html('<div class="item-txt">' + Resources.ITEM_STATUS_NOTAVAILABLE + '</div>');
15028    return;
15029  }
15030  $availabilityMsg.empty();
15031  // Look through levels ... if msg is not empty, then create span el
15032  if (data.levels.IN_STOCK > 0) {
15033    if (data.levels.PREORDER === 0 && data.levels.BACKORDER === 0 && data.levels.NOT_AVAILABLE === 0) {
15034      // Just in stock
15035      message = Resources.IN_STOCK;
15036    } else {
15037      // In stock with conditions ...
15038      message = Resources.IN_STOCK + '<br>' + data.inStockMsg;
15039    }
15040    $availabilityMsg.append('<div class="item-txt">' + message);
15041  }
15042  if (data.levels.PREORDER > 0) {
15043    if (data.levels.IN_STOCK === 0 && data.levels.BACKORDER === 0 && data.levels.NOT_AVAILABLE === 0) {
15044      message = Resources.PREORDER;
15045    } else {
15046      message = Resources.PREORDER + '<br>' + data.preOrderMsg;
15047    }
15048    $availabilityMsg.append('<div class="item-txt">' + message);
15049  }
15050  if (data.levels.BACKORDER > 0) {
15051    if (data.levels.IN_STOCK === 0 && data.levels.PREORDER === 0 && data.levels.NOT_AVAILABLE === 0) {
15052      message = Resources.BACKORDER;
15053    } else {
15054      message = Resources.BACKORDER + '<br>' + data.backOrderMsg;
15055    }
15056    $availabilityMsg.append('<div class="item-txt">' + message);
15057  }
15058  if (data.inStockDate !== '') {
15059    $availabilityMsg.append(String.format(Resources.IN_STOCK_DATE, data.inStockDate));
15060  }
15061  if (data.levels.NOT_AVAILABLE > 0) {
15062    if (data.levels.PREORDER === 0 && data.levels.BACKORDER === 0 && data.levels.IN_STOCK === 0) {
15063      message = Resources.NOT_AVAILABLE;
15064    } else {
15065      message = Resources.NOT_AVAILABLE + '<br>' + Resources.REMAIN_NOT_AVAILABLE;
15066    }
15067    $availabilityMsg.append('<div class="item-txt">' + message);
15068  }
15069
15070  $availabilityMsg.append('</div>');
15071};
15072
15073var getAvailability = function getAvailability() {
15074  ajax.getJson({
15075    url: util.appendParamsToUrl(Urls.getAvailability, {
15076      pid: $('#pid').val(),
15077      Quantity: $(this).val()
15078    }),
15079    callback: updateContainer
15080  });
15081};
15082
15083module.exports = function () {
15084  $('#pdpMain').on('change', '.pdpForm input[name="Quantity"]', getAvailability);
15085};
15086
15087},{"../../ajax":1,"../../util":77}],46:[function(require,module,exports){
15088'use strict';
15089
15090function initializeEvents() {
15091  $('.video-carousel').slick({
15092    dots: true,
15093    infinite: false,
15094    slidesToShow: 3,
15095    slidesToScroll: 1,
15096    responsive: [{
15097      breakpoint: 480,
15098      settings: 'unslick'
15099    }]
15100  });
15101}
15102
15103module.exports = {
15104  init: function init() {
15105    initializeEvents();
15106  }
15107};
15108
15109},{}],47:[function(require,module,exports){
15110'use strict';
15111
15112var dialog = require('../../dialog');
15113var modal = require('../../modal').global;
15114var util = require('../../util');
15115var qs = require('qs');
15116var url = require('url');
15117var _ = require('lodash');
15118
15119function getProductImageURL(viewType) {
15120  var pid = $("span[itemprop='productID']").data('pid');
15121  return util.appendParamsToUrl(Urls.getProductImages, {
15122    pid: pid,
15123    sz: viewType
15124  });
15125}
15126
15127function lazyLoadThumbnails() {
15128  var viewType = util.isMobile() ? 'large' : 'icon';
15129  var thumbnailProductImageURL = getProductImageURL(viewType);
15130
15131  $.get(thumbnailProductImageURL).done(function (res) {
15132    $('#thumbnails').html(res);
15133
15134    var thumbnailImageCount = $('#thumbnails li').length;
15135    if (thumbnailImageCount == 0) {
15136      return false;
15137    } else if (thumbnailImageCount > 1 && window.innerWidth > 767) {
15138      initThumbnailCarousel();
15139    } else if (thumbnailImageCount > 1 && window.innerWidth < 768) {
15140      initMainImageCarousel();
15141    }
15142  });
15143}
15144
15145function initThumbnailCarousel() {
15146  $('#thumbnails ul').slick({
15147    dots: false,
15148    infinite: true,
15149    arrows: true,
15150    vertical: true,
15151    slidesToShow: 4,
15152    slidesToScroll: 1,
15153    focusOnSelect: true
15154  });
15155}
15156
15157function initMainImageCarousel() {
15158  $('#thumbnails ul').slick({
15159    dots: true,
15160    vertical: false,
15161    infinite: true,
15162    arrows: false,
15163    centerMode: false,
15164    slidesToShow: 1,
15165    focusOnSelect: true
15166  });
15167}
15168
15169/**
15170 * @description Sets the main image attributes and the href for the surrounding <a> tag
15171 * @param {Object} atts Object with url, alt, title and hires properties
15172 */
15173function setMainImage(atts) {
15174  $('#pdpMain .primary-image').attr({
15175    src: atts.url,
15176    alt: atts.alt,
15177    title: atts.title
15178  });
15179  updatePinButton(atts.url);
15180  updateFacebookButton(atts.url);
15181  if (!dialog.isActive() && !util.isMobile()) {
15182    $('#pdpMain .main-image').find('img').attr('src', atts.hires);
15183  }
15184}
15185
15186function updatePinButton(imageUrl) {
15187  var pinButton = document.querySelector('.share-icon[data-share=pinterest]');
15188
15189  if (!pinButton) {
15190    return;
15191  }
15192  var newUrl = imageUrl;
15193  if (!imageUrl) {
15194    newUrl = document.querySelector('#pdpMain .primary-image').getAttribute('src');
15195  }
15196  var href = url.parse(pinButton.href);
15197  var query = qs.parse(href.query);
15198  query.media = url.resolve(window.location.href, newUrl);
15199  query.url = window.location.href;
15200  var newHref = url.format(_.extend({}, href, {
15201    query: query, // query is only used if search is absent
15202    search: qs.stringify(query)
15203  }));
15204  pinButton.href = newHref;
15205}
15206
15207function updateFacebookButton(imageUrl) {
15208  var facebookButton = document.querySelector('.share-icon[data-share=facebook]');
15209
15210  if (!facebookButton) {
15211    return;
15212  }
15213  var newUrl = imageUrl;
15214  if (!imageUrl) {
15215    newUrl = document.querySelector('#pdpMain .primary-image').getAttribute('src');
15216  }
15217  var href = url.parse(facebookButton.href);
15218  var query = qs.parse(href.query);
15219  query.picture = url.resolve(window.location.href, newUrl);
15220  query.u = window.location.href;
15221  var newHref = url.format(_.extend({}, href, {
15222    query: query, // query is only used if search is absent
15223    search: qs.stringify(query)
15224  }));
15225  facebookButton.href = newHref;
15226}
15227
15228/* @module image
15229 * @description this module handles the primary image viewer on PDP
15230 **/
15231
15232/**
15233 * @description by default, this function sets up zoom and event handler for thumbnail click
15234 **/
15235module.exports = function () {
15236  if (dialog.isActive() || util.isMobile()) {
15237    $('#pdpMain .main-image').removeAttr('href');
15238  }
15239  updatePinButton();
15240  updateFacebookButton();
15241  lazyLoadThumbnails();
15242
15243  // bind zoom event handler
15244  $(document).on('click', '.image-zoom', function (evt) {
15245    evt.preventDefault();
15246    var viewType = 'zoom';
15247    // var thumbnailProductImageURL = getSingleProductImageURL(viewType);
15248    // modal.renderByUrl(thumbnailProductImageURL);
15249
15250    var zoomImageUrl = null;
15251    if ($('.productthumbnail').length > 1) {
15252      zoomImageUrl = $('.productthumbnail.slick-current').data('zoomimg');
15253    } else {
15254      // for only one thumbnail, select that one image
15255      zoomImageUrl = $($('.productthumbnail')[0]).data('zoomimg');
15256    }
15257
15258    modal.renderContent('<img src="' + zoomImageUrl + '">');
15259
15260    modal.addCustomClass('productImageZoom');
15261  });
15262
15263  // handle product thumbnail click event
15264  $('#thumbnails').on('click', '.productthumbnail', function () {
15265    var $that = $(this);
15266    if (!$that.hasClass('selected')) {
15267      $(document).trigger('clickproductthumbnail');
15268    }
15269
15270    $('#thumbnails').find('.productthumbnail.selected').removeClass('selected');
15271    $that.addClass('selected');
15272    setMainImage($that.data('lgimg'));
15273  });
15274};
15275
15276module.exports.setMainImage = setMainImage;
15277module.exports.lazyLoadThumbnails = lazyLoadThumbnails;
15278
15279},{"../../dialog":12,"../../modal":24,"../../util":77,"lodash":111,"qs":130,"url":147}],48:[function(require,module,exports){
15280'use strict';
15281
15282var _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; };
15283
15284var dialog = require('../../dialog'),
15285    modal = require('../../modal').global,
15286    productStoreInventory = require('../../storeinventory/product'),
15287    util = require('../../util'),
15288    addToCart = require('./addToCart'),
15289    availability = require('./availability'),
15290    image = require('./image'),
15291
15292//productNav = require('./productNav'),
15293howToSection = require('./howToSection'),
15294    productSet = require('./productSet'),
15295    productKit = require('./productKit'),
15296    recommendations = require('./recommendations'),
15297    socialShareIcons = require('./socialShareIcons'),
15298    variant = require('./variant'),
15299    design = require('../../design'),
15300    ajax = require('../../ajax');
15301
15302/**
15303 * @description Initialize product detail page with reviews, recommendation and product navigation.
15304 */
15305
15306function initializeDom() {
15307  //productNav();
15308  recommendations();
15309  var ua = navigator.userAgent;
15310  if ((ua.indexOf('iPhone') > 0 || ua.indexOf('iPod') > 0 || ua.indexOf('Android') > 0) && ua.indexOf('Mobile') > 0) {
15311    // Processing for smartphones
15312  } else if (ua.indexOf('iPad') > 0 || ua.indexOf('Android') > 0 || ua.indexOf('Macintosh') > -1 && 'ontouchend' in document) {
15313    // Processing for tablets
15314  } else {
15315    // Processing for PC
15316    $('.hadapasha_link_sp').css('display', 'none');
15317  }
15318}
15319
15320var addToWishlist = function addToWishlist(e) {
15321  if (!window.User.isCustomerAuthenticated) {
15322    return;
15323  }
15324
15325  e.preventDefault();
15326  var $target = $(this).parent();
15327  var url = util.appendParamsToUrl($(this).attr('href'), {
15328    format: 'ajax'
15329  });
15330  var data = {};
15331  data[this.dataset.csrfname] = this.dataset.csrfvalue;
15332
15333  $.ajax({
15334    type: 'POST',
15335    url: url,
15336    data: data
15337  }).done(function (response) {
15338    if (typeof response === 'string' && response !== '') {
15339      $target.empty().html(response);
15340      product.initializeEvents();
15341    } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
15342      window.alert(response.error);
15343    }
15344  });
15345};
15346
15347var removeFromWishlist = function removeFromWishlist(e) {
15348  e.preventDefault();
15349
15350  var $target = $(this).parent();
15351  var url = util.appendParamsToUrl($(this).attr('href'), {
15352    format: 'ajax'
15353  });
15354  var data = {};
15355  data[this.dataset.csrfname] = this.dataset.csrfvalue;
15356
15357  $.ajax({
15358    type: 'POST',
15359    url: url,
15360    data: data
15361  }).done(function (response) {
15362    if (typeof response === 'string' && response !== '') {
15363      $target.empty().html(response);
15364      product.initializeEvents();
15365    } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
15366      window.alert(response.error);
15367    }
15368  }).fail(function (xhr, textStatus) {
15369    if (textStatus === 'parsererror') {
15370      window.alert(Resources.BAD_RESPONSE);
15371    } else {
15372      window.alert(Resources.SERVER_CONNECTION_ERROR);
15373    }
15374  });
15375};
15376
15377/**
15378 * @description Initialize event handlers on product detail page
15379 */
15380function initializeEvents() {
15381  var $pdpMain = $('#pdpMain');
15382
15383  addToCart();
15384  availability();
15385  variant();
15386  image();
15387  howToSection.init();
15388  //productSet();
15389  productKit();
15390  socialShareIcons();
15391  //    design.pdpInit();
15392  if (SitePreferences.STORE_PICKUP) {
15393    productStoreInventory.init();
15394  }
15395
15396  // Add to Wishlist and Add to Gift Registry links behaviors
15397  $pdpMain.on('click', '[data-action="wishlist"], [data-action="gift-registry"]', function () {
15398    var data = util.getQueryStringParams($('.pdpForm').serialize());
15399    if (data.cartAction) {
15400      delete data.cartAction;
15401    }
15402    var url = util.appendParamsToUrl(this.href, data);
15403    this.setAttribute('href', url);
15404  });
15405
15406  // product options
15407  $pdpMain.on('change', '.product-options select', function () {
15408    var salesPrice = $pdpMain.find('.product-add-to-cart .price-sales');
15409    var selectedItem = $(this).children().filter(':selected').first();
15410    salesPrice.text(selectedItem.data('combined'));
15411  });
15412
15413  // prevent default behavior of thumbnail link and add this Button
15414  $pdpMain.on('click', '.thumbnail-link, .unselectable a', function (e) {
15415    e.preventDefault();
15416  });
15417
15418  $('.full-ingredients').on('click', function (e) {
15419    e.preventDefault();
15420    var $this = $(this);
15421    var $fullIngredientList = $('.c-block-ingredientslist');
15422    var contentUrl = $this.attr('href');
15423
15424    if ($fullIngredientList.length) {
15425      $this.toggleClass('show-list');
15426    } else {
15427      $.get(util.appendParamToURL(contentUrl, 'format', 'ajax')).done(function (content) {
15428        $('<div class="full-ingredients-list"><a class="close"><i class="icon-close"></i></a>' + content + '</div>').insertAfter($this);
15429      });
15430      $this.toggleClass('show-list');
15431    }
15432  });
15433
15434  $pdpMain.on('click', '.close', function (e) {
15435    e.preventDefault();
15436    $('.full-ingredients.show-list').removeClass('show-list');
15437  });
15438
15439  $('.cpb-products-details #save-for-later').on('click', addToWishlist);
15440
15441  $('.cpb-products-details .remove-from-wishlist').on('click', removeFromWishlist);
15442
15443  if ($('.item-link_box').length > 0) {
15444    var $productForms = $('.cpb-products-variety_area').find('.cpb-products-variety_box .txtarea').toArray();
15445    var pids = $productForms.map(function (formEle) {
15446      return $(formEle).data('pid');
15447    }).join(',');
15448
15449    $.post(util.appendParamsToUrl(Urls.wishlistIsSavedForLater, {
15450      pid: pids
15451    }), function (data) {
15452      if (data === 'false') {
15453        $('.product-form-actions .product-set-wishlist').removeClass('invisible');
15454        $('.product-form-actions .remove-product-set-from-wishlist').addClass('invisible');
15455      } else {
15456        $('.product-form-actions .product-set-wishlist').addClass('invisible');
15457        $('.product-form-actions .remove-product-set-from-wishlist').removeClass('invisible');
15458      }
15459    });
15460
15461    $('.product-set-wishlist').on('click', function (e) {
15462      if (!window.User.isCustomerAuthenticated) {
15463        return;
15464      }
15465
15466      e.preventDefault();
15467
15468      var $productForms = $('.cpb-products-variety_area').find('.cpb-products-variety_box .txtarea').toArray();
15469      var pids = $productForms.map(function (formEle) {
15470        return $(formEle).data('pid');
15471      }).join(',');
15472
15473      $.post(util.appendParamsToUrl($(this).attr('href'), {
15474        pid: pids,
15475        format: 'ajax'
15476      }), function (data) {
15477        if (data === 'false') {
15478          $('.product-form-actions .product-set-wishlist').removeClass('invisible');
15479          $('.product-form-actions .remove-product-set-from-wishlist').addClass('invisible');
15480        } else {
15481          $('.product-form-actions .product-set-wishlist').addClass('invisible');
15482          $('.product-form-actions .remove-product-set-from-wishlist').removeClass('invisible');
15483        }
15484      });
15485    });
15486
15487    $('.remove-product-set-from-wishlist').on('click', function (e) {
15488      e.preventDefault();
15489
15490      var $productForms = $('.cpb-products-variety_area').find('.cpb-products-variety_box .txtarea').toArray();
15491      var pids = $productForms.map(function (formEle) {
15492        return $(formEle).data('pid');
15493      }).join(',');
15494
15495      $.post(util.appendParamsToUrl(Urls.wishlistRemoveAll, {
15496        pid: pids,
15497        format: 'ajax'
15498      }), function (data) {
15499        if (data === 'false') {
15500          $('.product-form-actions .product-set-wishlist').removeClass('invisible');
15501          $('.product-form-actions .remove-product-set-from-wishlist').addClass('invisible');
15502        } else {
15503          $('.product-form-actions .product-set-wishlist').addClass('invisible');
15504          $('.product-form-actions .remove-product-set-from-wishlist').removeClass('invisible');
15505        }
15506      });
15507    });
15508  }
15509
15510  $('.ico-favorite.unlogin').on('click', function (e) {
15511    e.preventDefault();
15512    var original = $(this).data('original');
15513    var pids = '';
15514    if ($('.cpb-products-variety_area').length > 0) {
15515      var _$productForms = $('.cpb-products-variety_area').find('.cpb-products-variety_box .txtarea').toArray();
15516      pids = _$productForms.map(function (formEle) {
15517        return $(formEle).data('pid');
15518      }).join(',');
15519    } else {
15520      pids = $('#pid').val();
15521    }
15522
15523    var originalUrl = original + pids;
15524
15525    window.location = Urls.showLogin + '?original=' + originalUrl;
15526  });
15527
15528  $('.size-chart-link a').on('click', function (e) {
15529    e.preventDefault();
15530    dialog.open({
15531      url: $(e.target).attr('href')
15532    });
15533  });
15534
15535  $('.accordion-toggle').on('click', function (e) {
15536    e.preventDefault();
15537    var $toggleFor = $(this).attr('href');
15538    var $toggleHeight = $('.accordion-toggle').outerHeight();
15539    var $stickyHeader = $('.sticky-header').outerHeight();
15540
15541    var totalOffset = $toggleHeight + $stickyHeader;
15542
15543    if ($(this).hasClass('is-open')) {
15544      $(this).removeClass('is-open');
15545      $($toggleFor).removeClass('is-open').slideUp();
15546      return false;
15547    } else {
15548      var accordionToggle = $('.accordion-toggle.is-open');
15549      var accordionContent = $('.pdp-content-section.is-open');
15550
15551      // $(document).find(accordionToggle).removeClass('is-open');
15552      // $(document).find(accordionContent).removeClass('is-open').slideUp(100);
15553
15554      $(this).toggleClass('is-open');
15555      $($toggleFor).toggleClass('is-open').slideDown(function () {
15556        $('html, body').animate({
15557          scrollTop: $(this).offset().top - totalOffset
15558        }, 400);
15559      });
15560    }
15561
15562    if ($(this).attr('id') == 'rec-toggle') {
15563      $('.carousel-recommendations.slick-slider').slick('refresh');
15564    }
15565  });
15566
15567  $('.js-modal-r_open[data-modal-target="product-service-modal"]').on('click', function () {
15568    if ($('#productservicemodal').length === 0) {
15569      return;
15570    }
15571    var $errorPlacement = $('#productservicemodal').find('.cpb-modalR_bottom>.c-text-error');
15572    $errorPlacement.addClass('mfp-hide');
15573    $errorPlacement.text('');
15574  });
15575}
15576
15577var product = {
15578  initializeEvents: initializeEvents,
15579  init: function init() {
15580    initializeDom();
15581    initializeEvents();
15582  }
15583};
15584
15585module.exports = product;
15586
15587},{"../../ajax":1,"../../design":11,"../../dialog":12,"../../modal":24,"../../storeinventory/product":74,"../../util":77,"./addToCart":44,"./availability":45,"./howToSection":46,"./image":47,"./productKit":49,"./productSet":50,"./recommendations":51,"./socialShareIcons":53,"./variant":54}],49:[function(require,module,exports){
15588'use strict';
15589
15590var ajax = require('../../ajax'),
15591    tooltip = require('../../tooltip'),
15592    variant = require('./variant'),
15593    util = require('../../util'),
15594    skin_trouble_check = require('./skin_trouble_check');
15595
15596function productKitInit() {
15597  // 新テンプレートの場合、新テンプレート用初期化処理を実行
15598  if ($('#kit-step-main-content').length > 0) {
15599    return productKitStepInit();
15600  }
15601  var $kitMainContent = $('#kit-main-content');
15602  var $kitBottomContent = $('#kit-bottom-content');
15603  var $kitModal = $('#kitproductmodal');
15604  var kitProductId = $kitMainContent.find('input[name="data-kit-product-id"]').val();
15605  var isOutOfStockIems = $kitMainContent.find('input[name="is-out-of-stock-kit-istems"]').length == 0 ? false : $kitMainContent.find('input[name="is-out-of-stock-kit-istems"]').val();
15606  // click on swatch for product set
15607  $kitMainContent.on('click', '.kit-select-variation', function (e) {
15608    e.preventDefault();
15609    var href = $(this).attr('href');
15610    var productId = $(this).attr('data-product');
15611    var setId = $(this).attr('set-id');
15612    var setNum = $(this).attr('set-number');
15613    var productNum = $(this).attr('product-number');
15614    var params = {
15615      productId: productId,
15616      kitProductId: kitProductId,
15617      setId: setId,
15618      productSetNumber: setNum,
15619      productNumber: productNum,
15620      isOutOfStockIems: isOutOfStockIems
15621    };
15622
15623    ajax.load({
15624      url: util.appendParamsToUrl(href, params),
15625      target: $('.product-kit'),
15626      callback: function callback() {
15627        $('#kit-main-content').find('input[name="kit-open-select-modal"]').click();
15628        variant();
15629      }
15630    });
15631  });
15632
15633  $kitModal.on('click', '.cpb-modalR_bottom .cmd-button_box button', function (e) {
15634    e.preventDefault();
15635    var productId = $(this).attr('data-product');
15636    var setId = $(this).attr('set-id');
15637    var variationImageUrl = $(this).attr('variation-image-url');
15638    var setNum = $(this).attr('set-number');
15639    var productNum = $(this).attr('product-number');
15640    var _target1 = '.kit-product-set-' + setNum;
15641    var _target2 = '.c-kit-confirm-' + setNum;
15642    if (productId === '') {
15643      return;
15644    }
15645
15646    var params = {
15647      productId: productId,
15648      kitProductId: kitProductId,
15649      setId: setId,
15650      productSetNumber: setNum,
15651      productNumber: productNum,
15652      variationImageUrl: variationImageUrl,
15653      unselectFlag: 'false'
15654    };
15655    ajax.load({
15656      url: Urls.selectProduct,
15657      data: params,
15658      target: $(_target1),
15659      callback: function callback() {
15660        $kitModal.find('.js-modal-r_close').click();
15661        $('.cpb-products_reccomend_slider').not('.slick-initialized').slick({
15662          dots: true,
15663          arrows: true,
15664          slidesToShow: 3,
15665          slidesToScroll: 3,
15666          infinite: false,
15667          responsive: [{
15668            breakpoint: 993,
15669            settings: {
15670              slidesToShow: 2,
15671              slidesToScroll: 2
15672            }
15673          }, {
15674            breakpoint: 768,
15675            settings: {
15676              slidesToShow: 1,
15677              slidesToScroll: 1
15678            }
15679          }]
15680        });
15681        updateConfirmKitButton($kitMainContent, kitProductId, isOutOfStockIems);
15682      }
15683    });
15684
15685    ajax.load({
15686      url: Urls.confirmKitProduct,
15687      data: params,
15688      target: $(_target2)
15689    });
15690  });
15691
15692  $kitMainContent.on('click', '.kit-select-product-no-variation', function (e) {
15693    e.preventDefault();
15694    var href = $(this).attr('href');
15695    var productId = $(this).attr('data-product');
15696    var setId = $(this).attr('set-id');
15697    var setNum = $(this).attr('set-number');
15698    var productNum = $(this).attr('product-number');
15699    var _target1 = '.kit-product-set-' + setNum;
15700    var _target2 = '.c-kit-confirm-' + setNum;
15701    var params = {
15702      productId: productId,
15703      kitProductId: kitProductId,
15704      setId: setId,
15705      productSetNumber: setNum,
15706      productNumber: productNum,
15707      variationImageUrl: '',
15708      unselectFlag: 'false'
15709    };
15710
15711    ajax.load({
15712      url: util.appendParamsToUrl(href, params),
15713      target: $(_target1),
15714      callback: function callback() {
15715        $('.cpb-products_reccomend_slider').not('.slick-initialized').slick({
15716          dots: true,
15717          arrows: true,
15718          slidesToShow: 3,
15719          slidesToScroll: 3,
15720          infinite: false,
15721          responsive: [{
15722            breakpoint: 993,
15723            settings: {
15724              slidesToShow: 2,
15725              slidesToScroll: 2
15726            }
15727          }, {
15728            breakpoint: 768,
15729            settings: {
15730              slidesToShow: 1,
15731              slidesToScroll: 1
15732            }
15733          }]
15734        });
15735        updateConfirmKitButton($kitMainContent, kitProductId, isOutOfStockIems);
15736      }
15737    });
15738
15739    ajax.load({
15740      url: Urls.confirmKitProduct,
15741      data: params,
15742      target: $(_target2)
15743    });
15744  });
15745
15746  $kitMainContent.on('click', '.kit-select-product-selected', function (e) {
15747    e.preventDefault();
15748    var href = $(this).attr('href');
15749    var productId = $(this).attr('data-product');
15750    var setId = $(this).attr('set-id');
15751    var setNum = $(this).attr('set-number');
15752    var productNum = $(this).attr('product-number');
15753    var _target1 = '.kit-product-set-' + setNum;
15754    var _target2 = '.c-kit-confirm-' + setNum;
15755    var params = {
15756      productId: productId,
15757      kitProductId: kitProductId,
15758      setId: setId,
15759      productSetNumber: setNum,
15760      productNumber: productNum,
15761      variationImageUrl: '',
15762      unselectFlag: 'true'
15763    };
15764
15765    ajax.load({
15766      url: util.appendParamsToUrl(href, params),
15767      target: $(_target1),
15768      callback: function callback() {
15769        $('.cpb-products_reccomend_slider').not('.slick-initialized').slick({
15770          dots: true,
15771          arrows: true,
15772          slidesToShow: 3,
15773          slidesToScroll: 3,
15774          infinite: false,
15775          responsive: [{
15776            breakpoint: 993,
15777            settings: {
15778              slidesToShow: 2,
15779              slidesToScroll: 2
15780            }
15781          }, {
15782            breakpoint: 768,
15783            settings: {
15784              slidesToShow: 1,
15785              slidesToScroll: 1
15786            }
15787          }]
15788        });
15789        updateConfirmKitButton($kitMainContent, kitProductId, isOutOfStockIems);
15790      }
15791    });
15792
15793    ajax.load({
15794      url: Urls.confirmKitProduct,
15795      data: params,
15796      target: $(_target2)
15797    });
15798  });
15799
15800  $kitBottomContent.on('click', '.kit-confirm-products-button', skinCheckKit);
15801
15802  function skinCheckKit(e) {
15803    skin_trouble_check.skinTroubleExecute(e, $(this), addToCartKit);
15804  }
15805
15806  function addToCartKit(e, $this) {
15807    e.preventDefault();
15808    var selected_items = [];
15809    var length = $kitMainContent.find('.c-kit-product-reccomend').length;
15810    var mandatory_length = $kitMainContent.find('.c-kit-other_element').length;
15811    var mandatoryFlag = $kitMainContent.find('input[name="mandatory-flag"]').val();
15812    var gift_length = $kitMainContent.find('.c-kit-gift_element').length;
15813    var pset, pid, master_id, set_id;
15814    var kitProductId = $('#kit-main-content').find('input[name="data-kit-product-id"]').val();
15815    var checkedit = $('input[name=edit-cart-product]').val();
15816    if (checkedit == 'cart_edit_kit') {
15817      checkedit = true;
15818      var $productDetailForm = $('#add-to-cart').closest('form');
15819      $productDetailForm.append('<input type="hidden" name="cartAction" value="editkit">');
15820    } else {
15821      checkedit = false;
15822    }
15823
15824    return $.ajax({
15825      url: Urls.checkExistAnyProduct,
15826      data: {
15827        pid: kitProductId,
15828        checkEdit: checkedit
15829      },
15830      loading: true
15831    }).then(function (response) {
15832      if (!response.error) {
15833        for (var i = 0; i < length; i++) {
15834          pset = '#c-kit-recomend_select' + i.toFixed();
15835          pid = $(pset).find('a').attr('pid');
15836          master_id = $(pset).find('a').attr('master-id');
15837          set_id = $(pset).find('a').attr('set-id');
15838          selected_items.push(set_id + ';' + master_id + ';' + pid);
15839        }
15840        for (var j = 0; j < mandatory_length; j++) {
15841          pset = '#c-kit-other-element' + j.toFixed();
15842          pid = $(pset).find('a').attr('pid');
15843          master_id = $(pset).find('a').attr('master-id');
15844          set_id = $(pset).find('a').attr('set-id');
15845          selected_items.push(set_id + ';' + master_id + ';' + pid);
15846        }
15847        for (var k = 0; k < gift_length; k++) {
15848          pset = '#c-kit-gift_element' + k.toFixed();
15849          pid = $(pset).find('a').attr('pid');
15850          master_id = $(pset).find('a').attr('master-id');
15851          set_id = 'bonus';
15852          selected_items.push(set_id + ';' + master_id + ';' + pid);
15853        }
15854        $('#items_selected').val(selected_items.join());
15855
15856        var $form = $('#items_selected').closest('form');
15857        return $.ajax({
15858          type: 'POST',
15859          url: util.ajaxUrl(Urls.addProduct),
15860          data: $form.serialize(),
15861          loading: true
15862        }).then(function () {
15863          return function () {
15864            window.location.href = Urls.cartShow;
15865          };
15866        });
15867      } else {
15868        $('#kit-main-content').find('.cmd-form_err._simple').remove();
15869        $('#kit-main-content').find('div').first().before($("<div class='cmd-form_err _simple' style='text-align: center'></div>").text(response.errorMsg));
15870        ajax.load({
15871          url: Urls.confirmKitButton,
15872          data: {
15873            allSelectedFlag: false,
15874            mandatoryFlag: mandatoryFlag,
15875            kitProductId: kitProductId,
15876            isOutOfStockIems: isOutOfStockIems
15877          },
15878          target: $('.c-kit-confirmproducts-button-form')
15879        });
15880        return $.Deferred().reject().promise();
15881      }
15882    });
15883  }
15884}
15885
15886function updateConfirmKitButton(kitMainContent, kitProductId, isOutOfStockIems) {
15887  var allSelectedFlag = function () {
15888    if (0 < kitMainContent.find('.no-product-selected').length) {
15889      return false;
15890    } else {
15891      return true;
15892    }
15893  }();
15894  var mandatoryFlag = kitMainContent.find('input[name="mandatory-flag"]').length == 0 ? true : kitMainContent.find('input[name="mandatory-flag"]').val();
15895  var data = {
15896    allSelectedFlag: allSelectedFlag,
15897    mandatoryFlag: mandatoryFlag,
15898    kitProductId: kitProductId,
15899    isOutOfStockIems: isOutOfStockIems
15900  };
15901  // ショッピングバックの編集から遷移した時のみ設定する
15902  if ($('.kit_product_cart_edit_kit').length > 0) data['source'] = $('.kit_product_cart_edit_kit').val();
15903
15904  ajax.load({
15905    url: Urls.confirmKitButton,
15906    data: data,
15907    target: $('.c-kit-confirmproducts-button-form')
15908  });
15909}
15910
15911/**
15912 * キット新テンプレート用初期化処理
15913 * 既存テンプレートとHTML構造が大分違うため処理完全に切り分ける
15914 * 新テンプレート内で使う関数は全てこの関数内で定義
15915 *
15916 * ※「_assets/js/cpb.trialset.js」でデザイン側の処理をしている
15917 */
15918function productKitStepInit() {
15919  var URI = require('urijs');
15920
15921  var dataCategoryFirstId = '0';
15922  // 一部デザイン側の処理を変更するため使用
15923  var isEdit = false;
15924
15925  /**
15926   * 選択内容の確認画面に表示される画像を更新する関数
15927   *
15928   * @param {object} target - 処理対象の「this」
15929   * @param {string} path -画像path
15930   */
15931  function updateConfirmImg(target, path) {
15932    var index = $(target).closest('.tks-category_box').closest('.slick-slide').data('slick-index');
15933    var imgList = $('.tks-confirm-img_list li');
15934    var imgElement = imgList.toArray().filter(function (element) {
15935      return $(element).data('img-index') == index;
15936    });
15937
15938    // 「path」が空の場合、style「display:none」を付与する関数
15939    var updateStyle = function updateStyle(element) {
15940      if (path) {
15941        $(element).prop('style').display = '';
15942      } else {
15943        $(element).prop('style').display = 'none';
15944      }
15945    };
15946
15947    // 選択したエリアの画像がすでにある場合上書き、無い場合HTMLを追加
15948    if (imgElement.length > 0) {
15949      $(imgElement).find('img').prop('src', path);
15950      updateStyle(imgElement);
15951    } else {
15952      var appendImgElement = $('<img>');
15953      var appendListElement = $('<li>');
15954      appendImgElement.prop('src', path);
15955      appendImgElement.prop('alt', '');
15956      appendListElement.attr('data-img-index', index);
15957      appendListElement.append($('<span>').append(appendImgElement));
15958      $('.tks-confirm-img_list').append(appendListElement);
15959      updateStyle(appendListElement);
15960    }
15961  }
15962
15963  /**
15964   * 選択内容の確認画面の各項目を更新する関数
15965   *
15966   * @param {object} info - 更新する情報を格納している連想配列
15967   * {
15968   *   productSetId: productSetId,
15969   *   itemName: itemName,
15970   *   itemDispPrice: itemDispPrice,
15971   *   calcPrice: calcPrice,
15972   *   itemProductId: itemProductId,
15973   *   itemProductMasterId: itemProductMasterId
15974   *   chipUrl: chipUrl,
15975   *   chipText: chipText
15976   * }
15977   */
15978  function updateConfirmProductInfo(info) {
15979    // 選択内容の確認画面を取得
15980    var confirmItemArea = $('.tks-confirm_item');
15981    var updateTargetDdElement = confirmItemArea.find('dd').toArray().filter(function (element) {
15982      return $(element).data('product-set-id') === info.productSetId;
15983    });
15984
15985    $(updateTargetDdElement).find('.item-name').text(info.itemName || '');
15986
15987    $(updateTargetDdElement).find('.item-price').text(info.itemDispPrice || '');
15988
15989    $(updateTargetDdElement).find('.calc-price').val(info.calcPr
15989ice || 0);
15990
15991    $(updateTargetDdElement).find('.product-id').val(info.itemProductId || '');
15992
15993    $(updateTargetDdElement).find('.product-master-id').val(info.itemProductMasterId || '');
15994
15995    // バリエーション商品の場合、表示用エリアを追加、変更等を考慮し最初に削除
15996    $(updateTargetDdElement).find('.item-colors').remove();
15997    if (info.chipUrl && info.chipText) {
15998      var pColors = $('<p>');
15999      var spanChip = $('<span>');
16000      var spanTxt = $('<span>');
16001      var img = $('<img>');
16002      pColors.addClass('item-colors');
16003      spanChip.addClass('chip');
16004      spanTxt.addClass('txt');
16005      spanTxt.text(info.chipText);
16006      img.prop('src', info.chipUrl);
16007      img.prop('alt', '');
16008      spanChip.append(img);
16009      pColors.append(spanChip);
16010      pColors.append(spanTxt);
16011      $(updateTargetDdElement).find('.item-name').after(pColors);
16012    }
16013
16014    // 合計金額を再計算
16015    var totalPrice = confirmItemArea.find('dd .calc-price').toArray().reduce(function (price, currentValue) {
16016      return price + Number($(currentValue).val());
16017    }, 0);
16018    confirmItemArea.find('.tks-confirm_total').text(Number(totalPrice).toLocaleString() + Resources.YEN_TAX);
16019  }
16020
16021  /**
16022   * 「選択内容をご確認」から変更をクリックして商品を選択した際の処理
16023   */
16024  function moveConfirmByEdit(e) {
16025    cpbUi.trialKitSet.moveConfirm();
16026    isEdit = false;
16027    e.stopPropagation();
16028  }
16029
16030  /**
16031   * 「選択する」ボタンクリック時の処理
16032   *  選択内容確認画面を更新する
16033   */
16034  function productSelect(e) {
16035    e.preventDefault();
16036    // 選択内容の確認画面の表示更新に使う値を取得
16037    var productSetId = $(this).closest('.tks-category_box').data('product-set-id');
16038
16039    var prorductInfoElement = $(this).closest('.cmd-button_container');
16040
16041    /* 画像の追加処理 */
16042    var imgPath = function () {
16043      var confirmImg = $(prorductInfoElement).find('.item-confirm-image').val();
16044      if (confirmImg) {
16045        return confirmImg;
16046      }
16047      return $(this).closest('.slick-slide').find('span.thumb img').prop('src');
16048    }.call(this);
16049    updateConfirmImg(this, imgPath);
16050
16051    var itemName = $(prorductInfoElement).find('.item-name').val();
16052    var itemDispPrice = $(prorductInfoElement).find('.item-disp-price').val();
16053    var calcPrice = $(prorductInfoElement).find('.item-calc-price').val();
16054    var itemProductId = $(prorductInfoElement).find('.item-product-id').val();
16055    var chipUrl = $(prorductInfoElement).find('.item-chip-url').val();
16056    var chipText = $(prorductInfoElement).find('.item-chip-text').val();
16057    var itemProductMasterId = $(prorductInfoElement).find('.item-product-master-id').val();
16058
16059    // 更新
16060    updateConfirmProductInfo({
16061      productSetId: productSetId,
16062      itemName: itemName,
16063      itemDispPrice: itemDispPrice,
16064      calcPrice: calcPrice,
16065      itemProductId: itemProductId,
16066      itemProductMasterId: itemProductMasterId,
16067      chipUrl: chipUrl,
16068      chipText: chipText
16069    });
16070
16071    $('.tks-confirm_wrap .tks-confirm_item_list .tks-confirm_item_txt .sold-out').remove();
16072    // ショッピングバッグに入れるボタンを活性
16073    $('.tks-confirm_item .cmd-button_container button').prop('disabled', false);
16074    $('.tks-confirm_item .tks-error p').html('');
16075
16076    // 確認内容画面から遷移した時はデザイン側のイベントを止めて確認内容画面へ遷移
16077    if (isEdit) moveConfirmByEdit(e);
16078  }
16079
16080  /**
16081   * 「選択しない」ボタンクリック時の処理
16082   *  選択内容確認画面を更新する
16083   */
16084  function notProductSelect(e) {
16085    e.preventDefault();
16086    // 画像表示の更新
16087    updateConfirmImg(this, '');
16088    // 選択内容の確認画面更新
16089    var productSetId = $(this).closest('.tks-category_box').data('product-set-id');
16090    updateConfirmProductInfo({
16091      productSetId: productSetId,
16092      itemName: '',
16093      itemDispPrice: '',
16094      calcPrice: 0,
16095      itemProductId: '',
16096      itemProductMasterId: '',
16097      chipUrl: '',
16098      chipText: ''
16099    });
16100
16101    $('.tks-confirm_wrap .tks-confirm_item_list .tks-confirm_item_txt .sold-out').remove();
16102    // ショッピングバッグに入れるボタンを活性
16103    $('.tks-confirm_item .cmd-button_container button').prop('disabled', false);
16104    $('.tks-confirm_item .tks-error p').html('');
16105
16106    // 確認内容画面から遷移した時はデザイン側のイベントを止めて確認内容画面へ遷移
16107    if (isEdit) moveConfirmByEdit(e);
16108  }
16109
16110  /**
16111   * 「色を選択する」ボタンクリック時の処理
16112   */
16113  function openModal(e) {
16114    e.preventDefault();
16115    var href = $(this).attr('href');
16116    var paramInfo = $(this).closest('.cmd-button_container').find('.param-info');
16117    var productId = paramInfo.attr('product-id');
16118    var kitId = paramInfo.attr('kit-id');
16119    var setId = paramInfo.attr('set-id');
16120    var productNum = paramInfo.attr('product-number');
16121    var setNum = paramInfo.attr('set-number');
16122    var params = {
16123      productId: productId,
16124      kitProductId: kitId,
16125      setId: setId,
16126      productSetNumber: setNum,
16127      productNumber: productNum
16128    };
16129
16130    ajax.load({
16131      url: util.appendParamsToUrl(href, params),
16132      target: $('.product-kit'),
16133      callback: function callback() {
16134        $('#kit-step-main-content').find('input[name="kit-open-select-modal"]').click();
16135        variant();
16136      }
16137    });
16138  }
16139
16140  /**
16141   * バリエーション商品を選択した時の処理
16142   */
16143  function selectVariation(e) {
16144    e.preventDefault();
16145
16146    var modalInfo = $(this).closest('.cpb-modalR_scroll_cover').find('.cmd-form_container .cpb-naire-variation li.is-current a');
16147
16148    // 画面を更新するための値を取得
16149    var productId = modalInfo.data('product');
16150    var colorChipUrl = modalInfo.find('img').prop('src');
16151    var dispValue = $(this).closest('.cpb-modalR_scroll_cover').find('.cmd-form_container .cpb-naire-data_box .item-color').text().trim();
16152    var prorductImgUrl = $(this).closest('.cpb-modalR_scroll_cover').find('.cmd-form_container .cpb-naire-photo img').prop('src');
16153
16154    // 更新対象の商品エリアを取得
16155    var updateProductArea = function () {
16156      var productNumber = modalInfo.attr('product-number');
16157      var setNumber = modalInfo.attr('set-number');
16158      return $('.tks-item_box').toArray().filter(function (element) {
16159        var paramInfo = $(element).find('.param-info');
16160        if (paramInfo.length <= 0) return;
16161        return paramInfo.attr('set-number') == setNumber && paramInfo.attr('product-number') == productNumber;
16162      })[0];
16163    }();
16164
16165    // 値を更新
16166    $(updateProductArea).find('.param-info').attr('product-id', productId);
16167
16168    $(updateProductArea).find('._TRP a .item-colors img').prop('src', colorChipUrl);
16169
16170    $(updateProductArea).find('._TRP a .item-colors span.txt').text(dispValue);
16171
16172    $(updateProductArea).find('.item-product-id').val(productId);
16173
16174    $(updateProductArea).find('.thumb img').prop('src', prorductImgUrl);
16175
16176    $(updateProductArea).find('.item-chip-url').val(colorChipUrl);
16177
16178    $(updateProductArea).find('.item-chip-text').val(dispValue);
16179
16180    // ボタンの表示を切り替える
16181    $(updateProductArea).find('.cmd-button_box').toArray().forEac
16181h(function (element, index) {
16182      if (index == 0) {
16183        $(element).css('display', 'none');
16184        return;
16185      }
16186      $(element).css('display', 'flex');
16187    });
16188    $(updateProductArea).find('.in-stock').css('display', '');
16189    $(updateProductArea).find('.sold-out').css('display', 'none');
16190
16191    $('.product-kit .js-modal-r_close').click();
16192  }
16193
16194  function addKitStepCart(e) {
16195    // カート追加処理
16196    var addToCartKit = function addToCartKit(e, $this) {
16197      e.preventDefault();
16198      var kitProductId = $('#kit-step-main-content').find('#pid').val();
16199
16200      var checkedit = function () {
16201        var inputElement = $('input[name=edit-cart-product]').val();
16202        if (inputElement == 'cart_edit_kit') {
16203          var productDetailForm = $('#add-to-cart').closest('form');
16204          productDetailForm.append('<input type="hidden" name="cartAction" value="editkit">');
16205          return true;
16206        } else {
16207          return false;
16208        }
16209      }();
16210
16211      var selectProductInfo = $('.tks-confirm_item dd').toArray().reduce(function (map, currentValue) {
16212        var productId = $(currentValue).find('.product-id').val();
16213        // 選択しないの場合「productId」が取得できないためreturn
16214        if (!productId) return map;
16215        var productSetId = $(currentValue).data('productSetId');
16216        var productMasterId = $(currentValue).find('.product-master-id').val();
16217        map.productId.push(productId);
16218        map.productSetId.push(productSetId);
16219        map.productMasterId.push(productMasterId);
16220        return map;
16221      }, {
16222        productId: [],
16223        productSetId: [],
16224        productMasterId: []
16225      });
16226
16227      return $.ajax({
16228        url: Urls.checkExistAnyProduct,
16229        data: {
16230          pid: kitProductId,
16231          checkEdit: checkedit,
16232          selectProductInfo: {
16233            productId: selectProductInfo.productId.join(','),
16234            productSetId: selectProductInfo.productSetId.join(','),
16235            productMasterId: selectProductInfo.productMasterId.join(',')
16236          }
16237        },
16238        loading: true
16239      }).then(function (response) {
16240        if (!response.error) {
16241          var selectedItems = $('.tks-confirm_item dd').toArray().reduce(function (array, currentValue) {
16242            var setId = $(currentValue).data('product-set-id');
16243            var masterId = $(currentValue).find('.product-master-id').val();
16244            var productId = $(currentValue).find('.product-id').val();
16245            // 選択しないの場合「productId」が取得できないためreturn
16246            if (!productId) return array;
16247            array.push(setId + ';' + masterId + ';' + productId);
16248            return array;
16249          }, []);
16250          $('#items_selected').val(selectedItems.join());
16251
16252          var $form = $('#items_selected').closest('form');
16253          return $.ajax({
16254            type: 'POST',
16255            url: util.ajaxUrl(Urls.addProduct),
16256            data: $form.serialize(),
16257            loading: true
16258          }).then(function () {
16259            return function () {
16260              window.location.href = Urls.cartShow;
16261            };
16262          });
16263        } else {
16264          if (!response.updateDispProductList) {
16265            var url = new URI(location.href);
16266            url.addQuery('reload', true);
16267            return location.replace(url.toString());
16268          }
16269          var productIdList = response.updateDispProductList.map(function (obj) {
16270            return obj.productId;
16271          });
16272          // 品切れを表示
16273          $('.tks-confirm_item dd').toArray().forEach(function (element) {
16274            if (productIdList.indexOf($(element).find('input.product-id').val()) >= 0) {
16275              // 品切れの表示がすでにある場合削除
16276              $(element).find('.sold-out').remove();
16277              var pElement = '<p class="colRED sold-out"> ' + Resources.PRODUCT_OUT_OF_STOCK + '</p>';
16278              if ($(element).find('.item-colors').length > 0) {
16279                $(element).find('.item-colors').after(pElement);
16280              } else {
16281                $(element).find('.item-name').after(pElement);
16282              }
16283            }
16284          });
16285          // 選択するボタンを品切れに切り替える
16286          $('.item-product-id').toArray().forEach(function (element) {
16287            if (productIdList.indexOf($(element).val()) >= 0) {
16288              $(element).siblings('p').find('button.in-stock').prop('style').display = 'none';
16289              $(element).siblings('p').find('button.sold-out').prop('style').display = '';
16290            } else {
16291              var inStockBottun = $(element).siblings('p').find('button.in-stock');
16292              var soldOutButton = $(element).siblings('p').find('button.sold-out');
16293              if (inStockBottun.length > 0 && soldOutButton.length > 0) {
16294                $(inStockBottun).prop('style').display = '';
16295                $(soldOutButton).prop('style').display = 'none';
16296              }
16297            }
16298          });
16299          // ショッピングバッグに入れるボタンを非活性
16300          $('.tks-confirm_item .cmd-button_container button').prop('disabled', true);
16301          $('.tks-confirm_item .tks-error p').html(response.errorMsg);
16302          return $.Deferred().reject().promise();
16303        }
16304      });
16305    };
16306
16307    if ($('input[name=edit-cart-product]').val() == 'cart_edit_kit') {
16308      return $.when(addToCartKit(e, $(this))).then(function (arg) {
16309        if (typeof arg === 'function') {
16310          arg();
16311        }
16312      });
16313    }
16314    skin_trouble_check.skinTroubleExecute(e, $(this), addToCartKit);
16315  }
16316
16317  /**
16318   * イベント追加
16319   */
16320  // 「選択する」ボタン
16321  $('#kit-step-main-content').off('click.selectProduct', '.slick-slide .tks-item_box .cmd-button_container button').on('click.selectProduct', '.slick-slide .tks-item_box .cmd-button_container button', productSelect);
16322
16323  // 「色を選択する」ボタン
16324  $('#kit-step-main-content').off('click.openModal', '.slick-slide .tks-item_box .cmd-button_container a.button').on('click.openModal', '.slick-slide .tks-item_box .cmd-button_container a.button', openModal);
16325
16326  // 「このカラーを選択する」ボタン
16327  $('.product-kit').off('click.selectVariation', '.cpb-modalR_scroll_cover .cmd-button_box button').on('click.selectVariation', '.cpb-modalR_scroll_cover .cmd-button_box button', selectVariation);
16328  // 「選択しない」ボタン
16329  $('#kit-step-main-content').off('click.notSelectProduct', '.tks-category_box .cmd-button_box .not-select-button').on('click.notSelectProduct', '.tks-category_box .cmd-button_box .not-select-button', notProductSelect);
16330
16331  // 「ショッピングバッグに入れる」ボタン
16332  $('#kit-step-main-content').off('click.addKitStepCart', '.tks-confirm_item .cmd-button_container button').on('click.addKitStepCart', '.tks-confirm_item .cmd-button_container button', addKitStepCart);
16333
16334  $('.js-tks-edit').on('click', function (e) {
16335    isEdit = true;
16336  });
16337
16338  /**
16339   * 画面初期表示時に実行する関数
16340   * 内部でajax処理を行うため必ず返却値はPromiseにすること
16341   */
16342  function dispInit() {
16343    if ($('[name=edit-cart-product]').length === 0) {
16344      // 初回表示時は最初のカテゴリを表示状態にする
16345      return $.Deferred().resolve(function () {
16346        cpbUi.trialKitSet.moveSelect(dataCategoryFirstId);
16347      }).promise();
16348    }
16349
16350    // カート編集から遷移した場合は、カートから商品情報を取得し画面を更新
16351    return $.ajax({
16352      url: Urls.getProductInfoUseKitStep,
16353      type: 'get',
16354      loading: true
16355    }).then(function (resp) {
16356      var click = function click(inputElement) {
16357        $(inputElement).siblings().find('button.in-stock').click();
16358      };
16359
16360      resp.forEach(function (object) {
16361        if (!object.masterId) {
16362          // バリエーション商品以外の場合、選択するボタンをクリック
16363          var _inputElement = function () {
16364            return $('input.item-product-id').toArray().filter(function (element) {
16365              return $(element).val() === object.productId;
16366            })[0];
16367          }();
16368          click(_inputElement);
16369          return;
16370        }
16371        // バリエーション商品の場合、各カテゴリに表示されている情報を取得
16372        var inputElement = function () {
16373          var element = $('input.item-product-master-id').toArray().filter(function (item) {
16374            return $(item).val() === object.masterId;
16375          });
16376          if (element.length > 0) {
16377            // 足りない情報を設定
16378            $(element[0]).siblings('input.item-chip-text').val(object.chipText);
16379            $(element[0]).siblings('input.item-chip-url').val(object.chipUrl);
16380            $(element[0]).siblings('input.item-confirm-image').val(object.confirmImageUrl);
16381            $(element[0]).closest('.tks-item_box').find('.cmd-visual_card .thumb img').prop('src', object.productImage);
16382            return element[0];
16383          }
16384          // バリエーション商品でもバリエーション子商品がキットに含まれるパターン
16385          return $('input.item-product-id').toArray().filter(function (item) {
16386            return $(item).val() === object.productId;
16387          })[0];
16388        }();
16389        click(inputElement);
16390      });
16391
16392      // 確認内容画面へ遷移
16393      return $.Deferred().resolve(function () {
16394        cpbUi.trialKitSet.moveConfirm();
16395      }).promise();
16396    });
16397  }
16398
16399  $.when(dispInit()).then(function (resp) {
16400    if (typeof resp === 'function') {
16401      resp();
16402    }
16403    var url = new URI(location.href);
16404    // リロードの際は画面をスクロール
16405    if (url.hasQuery('reload')) {
16406      var position = $('#kit-step-main-content').offset().top;
16407      $('html, body').animate({ scrollTop: position }, 550, 'swing');
16408    }
16409  });
16410}
16411
16412module.exports = function () {
16413  productKitInit();
16414};
16415
16416},{"../../ajax":1,"../../tooltip":76,"../../util":77,"./skin_trouble_check":52,"./variant":54,"urijs":145}],50:[function(require,module,exports){
16417'use strict';
16418
16419var ajax = require('../../ajax'),
16420    tooltip = require('../../tooltip'),
16421    util = require('../../util');
16422
16423module.exports = function () {
16424  var $addToCart = $('#add-to-cart'),
16425      $addAllToCart = $('#add-all-to-cart'),
16426      $productSetList = $('#product-set-list');
16427
16428  var updateAddToCartButtons = function updateAddToCartButtons() {
16429    if ($productSetList.find('.add-to-cart[disabled]').length > 0) {
16430      $addAllToCart.attr('disabled', 'disabled');
16431      // product set does not have an add-to-cart button, but product bundle does
16432      $addToCart.attr('disabled', 'disabled');
16433    } else {
16434      $addAllToCart.removeAttr('disabled');
16435      $addToCart.removeAttr('disabled');
16436    }
16437  };
16438
16439  if ($productSetList.length > 0) {
16440    updateAddToCartButtons();
16441  }
16442  // click on swatch for product set
16443  $productSetList.on('click', '.product-set-item .swatchanchor', function (e) {
16444    e.preventDefault();
16445    var url = Urls.getSetItem + this.search;
16446    var $container = $(this).closest('.product-set-item');
16447    var qty = $container.find('form input[name="Quantity"]').first().val();
16448
16449    ajax.load({
16450      url: util.appendParamToURL(url, 'Quantity', isNaN(qty) ? '1' : qty),
16451      target: $container,
16452      callback: function callback() {
16453        updateAddToCartButtons();
16454        tooltip.init();
16455      }
16456    });
16457  });
16458
16459  $productSetList.on('change', '.product-set-item .variation-select', function (e) {
16460    e.preventDefault();
16461
16462    var $selectedVariantOption = $(this).find('option:selected');
16463    if ($selectedVariantOption.length === 0 || !$selectedVariantOption.val()) {
16464      return;
16465    }
16466
16467    var url = Urls.getSetItem + '?' + util.getQueryString($selectedVariantOption.val());
16468    var $container = $(this).closest('.product-set-item');
16469    var qty = $container.find('select[name="Quantity"] option:selected').val();
16470
16471    ajax.load({
16472      url: util.appendParamToURL(url, 'Quantity', isNaN(qty) ? '1' : qty),
16473      target: $container,
16474      callback: function callback() {
16475        updateAddToCartButtons();
16476        tooltip.init();
16477      }
16478    });
16479  });
16480  if (screen.width > 640) {
16481    $(window).load(function () {
16482      $('#pdpMain').find('#BVRRSummaryContainer .bv-rating-stars-container').off().on('click', function (e) {
16483        e.preventDefault();
16484        e.stopPropagation();
16485        $('.tabs-title:nth-child(1)').removeClass('is-active');
16486        $('.tabs-title:nth-child(2)').addClass('is-active');
16487        $('#questions').removeClass('is-active');
16488        $('#reviews').addClass('is-active').stop(true, true);
16489        $('html, body').stop(true, true).animate({
16490          scrollTop: $('#bazaarvoice-tabs').offset().top - 150
16491        }, 1000);
16492      });
16493    });
16494  }
16495};
16496
16497$(document).on('click', '.bv-popup-in .bv-read-review', function () {
16498  $('.tabs-title:nth-child(1)').removeClass('is-active');
16499  $('.tabs-title:nth-child(2)').addClass('is-active');
16500  $('#questions').removeClass('is-active');
16501  $('#reviews').addClass('is-active');
16502  e.preventDefault();
16503  e.stopPropagation();
16504  $('html, body').stop(true, true).animate({
16505    scrollTop: $('#bazaarvoice-tabs').offset().top - 150
16506  }, 1000);
16507});
16508
16509},{"../../ajax":1,"../../tooltip":76,"../../util":77}],51:[function(require,module,exports){
16510'use strict';
16511
16512/**
16513 * @description Creates product recommendation carousel using Slick carousel
16514 **/
16515
16516module.exports = function () {
16517  var $carousel = $('.carousel-recommendations').not('.slick-initialized');
16518  if (!$carousel || $carousel.length === 0 || $carousel.children().length === 0) {
16519    return;
16520  }
16521  $carousel.slick({
16522    infinite: true,
16523    slidesToShow: 3,
16524    slidesToScroll: 3,
16525    slide: 'li',
16526    dots: true,
16527    responsive: [{
16528      breakpoint: 600,
16529      settings: {
16530        slidesToShow: 3,
16531        slidesToScroll: 3,
16532        infinite: true,
16533        dots: true
16534      }
16535    }, {
16536      breakpoint: 480,
16537      settings: {
16538        slidesToShow: 1,
16539        slidesToScroll: 1,
16540        infinite: true,
16541        arrows: false,
16542        dots: true
16543      }
16544    }]
16545  });
16546};
16547
16548},{}],52:[function(require,module,exports){
16549'use strict';
16550
16551var util = require('../../util');
16552
16553var cpbUi = window.cpbUi || {};
16554var SkinCheck = window.SkinCheck || false;
16555
16556(function (window, $, cpbUi, browserWindow, Urls, SkinCheck, util) {
16557  if (!SkinCheck) {
16558    return;
16559  }
16560
16561  var isTroubleCheckFinished;
16562  var isTotalCounselingFinished;
16563  var isTroubleCheckType;
16564
16565  function skinTroubleExecute(buttonEvent, buttonElement, buttonCallback) {
16566    // 購入前チェック完了フラグ取得処理記述箇所
16567    isTroubleCheckFinished = buttonElement.data('skincheck') === false ? 'OK' : SkinCheck.isTroubleCheckFinished;
16568
16569    // 購入前チェック完了タイプ
16570    isTroubleCheckType = SkinCheck.isTroubleCheckType;
16571
16572    // カウンセリング完了フラグ取得処理記述箇所
16573    isTotalCounselingFinished = buttonElement.data('skincheck') === false ? true : SkinCheck.isTotalCounselingFinished;
16574
16575    skinTroubleCheckModalViewModel.$children[0].buttonEvent = buttonEvent;
16576    skinTroubleCheckModalViewModel.$children[0].buttonElement = buttonElement;
16577    skinTroubleCheckModalViewModel.$children[0].buttonCallback = buttonCallback;
16578
16579    if (isTroubleCheckFinished == 'OK') {
16580      // トラブルチェック完了時処理
16581      if (!isTotalCounselingFinished) {
16582        // カウンセリング未完了時処理
16583        switch (isTroubleCheckType) {
16584          default:
16585            skinTroubleCheckModalViewModel.$children[0].page = 6;
16586            break;
16587          case 'b':
16588            skinTroubleCheckModalViewModel.$children[0].q3Text = SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL2;
16589            skinTroubleCheckModalViewModel.$children[0].page = 4;
16590            break;
16591          case 'c':
16592            skinTroubleCheckModalViewModel.$children[0].q3Text = SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL3;
16593            skinTroubleCheckModalViewModel.$children[0].page = 4;
16594            break;
16595          case 'd':
16596            skinTroubleCheckModalViewModel.$children[0].q3Text = SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL4;
16597            skinTroubleCheckModalViewModel.$children[0].page = 4;
16598            break;
16599          case 'e':
16600            skinTroubleCheckModalViewModel.$children[0].q3Text = null;
16601            skinTroubleCheckModalViewModel.$children[0].page = 4;
16602            break;
16603        }
16604        buttonEvent.preventDefault();
16605        cpbUi.util.centerModalOpen.call(this, 'skin_trouble_check_modal', function (target) {});
16606      } else {
16607        // カウンセリング完了時処理
16608        $.when(_addToCart(buttonEvent, buttonElement, buttonCallback)).then(function (arg) {
16609          if (typeof arg === 'function') {
16610            arg();
16611          }
16612        });
16613      }
16614    } else if (isTroubleCheckFinished == 'NG') {
16615      // トラブルチェック結果NG時処理
16616      skinTroubleCheckModalViewModel.$children[0].page = 3;
16617      buttonEvent.preventDefault();
16618      cpbUi.util.centerModalOpen.call(this, 'skin_trouble_check_modal', function (target) {});
16619    } else {
16620      // トラブルチェック未完了時処理
16621      skinTroubleCheckModalViewModel.$children[0].page = 1;
16622      buttonEvent.preventDefault();
16623      cpbUi.util.centerModalOpen.call(this, 'skin_trouble_check_modal', function (target) {});
16624    }
16625    return false;
16626  }
16627  exports.skinTroubleExecute = skinTroubleExecute;
16628
16629  function _addToCart(e, element, callback) {
16630    return $.when(callback(e, element));
16631  }
16632
16633  Vue.component('skin-trouble-check-modal', {
16634    template: '<div class="cpb-modalC_container js-modal-c_content js-skin_trouble_check_modal_content" data-modal-type="skin_trouble_check_modal">\
16635      <div class="cpb-modalC_wrap">\
16636        <div class="cpb-modalC_inner cpb-modalC_inner--trouble">\
16637          <div class="cpb-modal_scroll js-modal_scroll">\
16638            <button class="cpb-modalC_close js-modal-c_close" @click="onCloseModal"><span class="invisible">CLOSE</span></button>\
16639\
16640            <!--質問1-->\
16641            <transition name="fade">\
16642              <div class="cpb-modalC_contents" v-if="page === 1">\
16643                <div class="cmd-title-section _h2 modal-trouble-title">\
16644                  <h2 class="title">' + SkinCheck.Asset.SKIN_CHECK_ASSET_TITLE + '</h2>\
16645                </div>\
16646                <div class="modal-trouble-lead">\
16647                  ' + SkinCheck.Asset.SKIN_CHECK_ASSET_SUBTITLE + '\
16648                </div>\
16649                <div class="modal-trouble-content">\
16650                  <div class="cmd-title-section _h3">\
16651                    <h3 class="title">' + Resources.SKIN_CHECK_QUESTION1 + '</h3>\
16652                  </div>\
16653                  ' + SkinCheck.Asset.SKIN_CHECK_ASSET_QUESTION1 + '\
16654                  <div class="modal-trouble-content_form">\
16655                    <div class="modal-trouble-content_element">\
16656                      <label><input type="radio" name="a1" value="yes" v-model="answer.q1" @click="onClickQ1RadioButton($event.target.value)"><span>' + Resources.SKIN_CHECK_YES + '</span></label>\
16657                    </div>\
16658                    <div class="modal-trouble-content_element">\
16659                      <label><input type="radio" name="a1" value="no" v-model="answer.q1" @click="onClickQ1RadioButton($event.target.value)"><span>' + Resources.SKIN_CHECK_NO + '</span></label>\
16660                    </div>\
16661                  </div>\
16662                </div>\
16663                <transition name="fade">\
16664                  <div class="modal-trouble-content" v-if="answer.q1 === \'yes\'">\
16665                    <div class="cmd-title-section _h3">\
16666                      <h3 class="title">' + Resources.SKIN_CHECK_QUESTION1_1 + '</h3>\
16667                    </div>\
16668                    ' + SkinCheck.Asset.SKIN_CHECK_ASSET_QUESTION1_1 + '\
16669                    <div class="modal-trouble-content_form">\
16670                      <div class="modal-trouble-content_element">\
16671                        <label><input type="radio" name="a1-1" value="yes" v-model="answer.q1_1"><span>' + Resources.SKIN_CHECK_YES + '</span></label>\
16672                      </div>\
16673                      <div class="modal-trouble-content_element">\
16674                        <label><input type="radio" name="a1-1" value="no" v-model="answer.q1_1"><span>' + Resources.SKIN_CHECK_NO + '</span></label>\
16675                      </div>\
16676                    </div>\
16677                  </div>\
16678                </transition>\
16679                <div class="modal-trouble-content_button">\
16680                  <p class="cmd-button_box _sizeM _WHT"><button class="button js-modal-c_close" @click="onCloseModal"><span class="txt">' + Resources.SKIN_CHECK_CLOSE + '</span></button></p>\
16681                  <p class="cmd-button_box _sizeM"><button class="button" @click="onClickPage1NextButton" v-bind:disabled="!isPage1Completed"><span class="txt">' + Resources.SKIN_CHECK_NEXT + '</span></button></p>\
16682                </div>\
16683              </div><!-- / cpb-modalC_contents -->\
16684            </transition>\
16685\
16686            <!--質問2-->\
16687            <transition name="fade">\
16688              <div class="cpb-modalC_contents" v-if="page === 2">\
16689                <div class="cmd-title-section _h2 modal-trouble-title">\
16690                  <h2 class="title">' + SkinCheck.Asset.SKIN_CHECK_ASSET_TITLE + '</h2>\
16691                </div>\
16692                <div class="modal-trouble-content">\
16693                  <div class="cmd-title-section _h3">\
16694                    <h3 class="title">' + Resources.SKIN_CHECK_QUESTION2 + '</h3>\
16695                  </div>\
16696                  ' + SkinCheck.Asset.SKIN_CHECK_ASSET_QUESTION2 + '\
16697                  <div class="modal-trouble-content_form">\
16698                    <div class="modal-trouble-content_element">\
16699                      <label><input type="radio" name="a2" value="yes" v-model="answer.q2"><span>' + Resources.SKIN_CHECK_YES + '</span></label>\
16700                    </div>\
16701                    <div class="modal-trouble-content_element">\
16702                      <label><input type="radio" name="a2" value="no" v-model="answer.q2"><span>' + Resources.SKIN_CHECK_NO + '</span></label>\
16703                    </div>\
16704                  </div>\
16705                </div>\
16706                <div class="modal-trouble-content_button">\
16707                  <p class="cmd-button_box _sizeM _WHT"><button class="button js-modal-c_close" @click="onCloseModal"><span class="txt">' + Resources.SKIN_CHECK_CLOSE + '</span></button></p>\
16708                  <p class="cmd-button_box _sizeM"><button class="button" @click="onClickPage2NextButton" v-bind:disabled="!isPage2Completed"><span class="txt">' + Resources.SKIN_CHECK_NEXT + '</span></button></p>\
16709                </div>\
16710              </div><!-- / cpb-modalC_contents -->\
16711            </transition>\
16712\
16713            <!--購入不可-->\
16714            <transition name="fade">\
16715              <div class="cpb-modalC_contents" v-if="page === 3">\
16716                <div class="cmd-title-section _h2 modal-trouble-title">\
16717                  <h2 class="title">' + SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_TITLE + '</h2>\
16718                </div>\
16719                <div class="cmd-title-section _h3 modal-trouble-title-s">\
16720                  <h3 class="title">' + SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_SUBTITLE1 + '</h3>\
16721                </div>\
16722                <div class="modal-trouble-caption">\
16723                  ' + SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL1 + '\
16724                  <div class="modal-trouble-content_button">\
16725                    <p class="cmd-button_box _sizeM _WHT"><button class="button" @click="onClickPage3AgainButton"><span class="txt">' + Resources.SKIN_CHECK_SKINCHECKAGAIN + '</span></button></p>\
16726                  </div>\
16727                </div>\
16728                <p class="cmd-button_box _sizeM modal-trouble-close"><button class="button js-modal-c_close" @click="onCloseModal"><span class="txt">' + Resources.SKIN_CHECK_CLOSE + '</span></button></p>\
16729              </div><!-- / cpb-modalC_contents -->\
16730            </transition>\
16731\
16732            <!--質問3-->\
16733            <transition name="fade">\
16734              <div class="cpb-modalC_contents" v-if="page === 4">\
16735                <div class="cmd-title-section _h2 modal-trouble-title">\
16736                  <h2 class="title">' + SkinCheck.Asset.SKIN_CHECK_ASSET_TITLE + '</h2>\
16737                </div>\
16738                <template v-if="q3Text">\
16739                  <div class="modal-trouble-caption_head">\
16740                    <h3 class="title">' + SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_SUBTITLE2 + '</h3>\
16741                  </div>\
16742                  <div class="modal-trouble-caption">\
16743                    <div class="modal-trouble-caption_text" v-html="q3Text"></div>\
16744                  </div>\
16745                </template>\
16746                <div class="modal-trouble-content">\
16747                  <div class="cmd-title-section _h3">\
16748                    <h3 class="title">' + Resources.SKIN_CHECK_QUESTION3 + '</h3>\
16749                  </div>\
16750                  <p>' + SkinCheck.Asset.SKIN_CHECK_ASSET_QUESTION3 + '</p>\
16751                  <div class="modal-trouble-content_form">\
16752                    <div class="modal-trouble-content_element modal-trouble-content_element--block">\
16753                      <label><input type="radio" name="a3" value="yes" v-model="answer.q3"><span>' + Resources.SKIN_CHECK_TC_YES + '</span></label>\
16754                    </div>\
16755                    <div class="modal-trouble-content_element modal-trouble-content_element--block">\
16756                      <label><input type="radio" name="a3" value="no" v-model="answer.q3"><span>' + Resources.SKIN_CHECK_TC_NO + '</span></label>\
16757                    </div>\
16758                  </div>\
16759                </div>\
16760                <div class="modal-trouble-content_button">\
16761                  <p class="cmd-button_box _sizeM _WHT"><button class="button js-modal-c_close" @click="onCloseModal"><span class="txt">' + Resources.SKIN_CHECK_CLOSE + '</span></button></p>\
16762                  <p class="cmd-button_box _sizeM"><button class="button" @click="onClickPage4NextButton" v-bind:disabled="!isPage4Completed"><span class="txt">' + Resources.SKIN_CHECK_NEXT + '</span></button></p>\
16763                </div>\
16764                <div class="modal-trouble-app">\
16765                  ' + SkinCheck.Asset.SKIN_CHECK_ASSET_TOTAL_COUNSELING_APP + '\
16766                </div>\
16767              </div><!-- / cpb-modalC_contents -->\
16768            </transition>\
16769\
16770            <!--終了-->\
16771            <transition name="fade">\
16772              <div class="cpb-modalC_contents" v-if="page === 5">\
16773                <div class="cmd-title-section _h3 modal-trouble-title-s modal-trouble-title-s--margin">\
16774                  <h3 class="title tcenter">' + SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL_FINISH + '</h3>\
16775                </div>\
16776                <p class="cmd-button_box _sizeM modal-trouble-close"><button class="button js-modal-c_close" @click="onClickPage5CloseButton"><span class="txt">' + Resources.SKIN_CHECK_CLOSE + '</span></button></p>\
16777              </div><!-- / cpb-modalC_contents -->\
16778            </transition>\
16779\
16780            <!--購入前診断完了済-->\
16781            <transition name="fade">\
16782              <div class="cpb-modalC_contents" v-if="page === 6">\
16783                <div class="cmd-title-section _h2 modal-trouble-title">\
16784                  <h2 class="title"></h2>\
16785                </div>\
16786                <div class="modal-trouble-content">\
16787                  <div class="cmd-title-section _h3">\
16788                    <h3 class="title"></h3>\
16789                  </div>\
16790                  <p class="trouble_completed">' + SkinCheck.Asset.SKIN_CHECK_ASSET_QUESTION3 + '</p>\
16791                  <div class="modal-trouble-content_form">\
16792                    <div class="modal-trouble-content_element modal-trouble-content_element--block">\
16793                      <label><input type="radio" name="a4" value="yes" v-model="answer.q3"><span>' + Resources.SKIN_CHECK_TC_YES + '</span></label>\
16794                    </div>\
16795                    <div class="modal-trouble-content_element modal-trouble-content_element--block">\
16796                      <label><input type="radio" name="a4" value="no" v-model="answer.q3"><span>
16796' + Resources.SKIN_CHECK_TC_NO + '<br><small>' + Resources.SKIN_CHECK_TC_NO_CONTINUE + '</small></span></label>\
16797                    </div>\
16798                  </div>\
16799                </div>\
16800                <div class="modal-trouble-content_button-close">\
16801                  <p class="cmd-button_box _sizeM"><button class="button" @click="onClickPage6NextButton" v-bind:disabled="!isPage4Completed"><span class="txt">' + Resources.SKIN_CHECK_NEXT + '</span></button></p>\
16802                </div>\
16803                <div class="modal-trouble-app">\
16804                  ' + SkinCheck.Asset.SKIN_CHECK_ASSET_TOTAL_COUNSELING_APP + '\
16805                </div>\
16806              </div><!-- / cpb-modalC_contents -->\
16807            </transition>\
16808\
16809          </div><!-- / cpb-modalC_scroll-->\
16810        </div><!-- / cpb-modalC_inner-->\
16811      </div><!-- / cpb-modalC_wrap -->\
16812      <div class="cpb-modal_overlay js-modal-c_overlay" @click="onCloseModal"></div>\
16813    </div><!-- / cpb-modalC_container -->',
16814    data: function data() {
16815      return {
16816        isTroubleCheckFinished: isTroubleCheckFinished,
16817        page: 1,
16818        answer: {
16819          q1: null,
16820          q1_1: null,
16821          q2: null,
16822          q3: null
16823        },
16824        q3Text: null
16825      };
16826    },
16827    created: function created() {
16828      if (isTroubleCheckFinished == 'OK') {
16829        this.page = 6;
16830      } else if (isTroubleCheckFinished == 'NG') {
16831        this.page = 3;
16832      } else {
16833        this.page = 1;
16834      }
16835    },
16836    computed: {
16837      isPage1Completed: function isPage1Completed() {
16838        return this.answer.q1 === 'no' || this.answer.q1 === 'yes' && this.answer.q1_1;
16839      },
16840      isPage2Completed: function isPage2Completed() {
16841        return !!this.answer.q2;
16842      },
16843      isPage4Completed: function isPage4Completed() {
16844        return !!this.answer.q3;
16845      }
16846    },
16847    methods: {
16848      onClickQ1RadioButton: function onClickQ1RadioButton(v) {
16849        this.answer.q1 = v;
16850        this.$nextTick(function () {
16851          cpbUi.niceScroll.resize(skinTroubleCheckModalViewModel.$children[0].$el);
16852        });
16853      },
16854      onCloseModal: function onCloseModal() {
16855        setTimeout(this.resetAnswers, 300);
16856      },
16857      resetAnswers: function resetAnswers() {
16858        this.answer = {
16859          q1: null,
16860          q1_1: null,
16861          q2: null,
16862          q3: null
16863        };
16864      },
16865      onClickPage1NextButton: function onClickPage1NextButton() {
16866        this.page = 2;
16867      },
16868      onClickPage2NextButton: function onClickPage2NextButton() {
16869        isTroubleCheckFinished = 'OK';
16870        SkinCheck.isTroubleCheckFinished = isTroubleCheckFinished;
16871        isTroubleCheckType = this.checkResult();
16872        SkinCheck.isTroubleCheckType = isTroubleCheckType;
16873        switch (isTroubleCheckType) {
16874          case 'a':
16875            isTroubleCheckFinished = 'NG';
16876            SkinCheck.isTroubleCheckFinished = isTroubleCheckFinished;
16877          default:
16878            this.page = 3;
16879            break;
16880          case 'b':
16881            this.q3Text = SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL2;
16882            this.page = 4;
16883            break;
16884          case 'c':
16885            this.q3Text = SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL3;
16886            this.page = 4;
16887            break;
16888          case 'd':
16889            this.q3Text = SkinCheck.Asset.SKIN_CHECK_ASSET_RESULT_DETAIL4;
16890            this.page = 4;
16891            break;
16892          case 'e':
16893            this.q3Text = null;
16894            this.page = 4;
16895            break;
16896        }
16897        $.ajax({
16898          url: util.ajaxUrl(util.appendParamsToUrl(Urls.setSkinCheckSession, {
16899            value: isTroubleCheckFinished,
16900            type: isTroubleCheckType
16901          }))
16902        });
16903        this.saveTroubleCheckFlg();
16904      },
16905      checkResult: function checkResult() {
16906        if (this.answer.q1 === 'yes') {
16907          if (this.answer.q1_1 === 'yes') {
16908            if (this.answer.q2 === 'yes') {
16909              // q1:yes q1_1:yes q2:yes
16910              return 'b';
16911            } else {
16912              // q1:yes q1_1:yes q2:no
16913              return 'c';
16914            }
16915          } else {
16916            if (this.answer.q2 === 'yes') {
16917              // q1:yes q1_1:no q2:yes
16918              return 'a';
16919            } else {
16920              // q1:yes q1_1:no q2:no
16921              return 'a';
16922            }
16923          }
16924        } else {
16925          if (this.answer.q2 === 'yes') {
16926            // q1:no q2:yes
16927            return 'd';
16928          } else {
16929            // q1:no q2:no
16930            return 'e';
16931          }
16932        }
16933      },
16934      saveTroubleCheckFlg: function saveTroubleCheckFlg() {
16935        // モーダル開閉時のフラグ切り替え処理
16936      },
16937      onClickPage3AgainButton: function onClickPage3AgainButton() {
16938        this.clearTroubleCheckFlg();
16939        this.resetAnswers();
16940        this.page = 1;
16941      },
16942      clearTroubleCheckFlg: function clearTroubleCheckFlg() {
16943        // モーダル開閉時のフラグ切り替え処理
16944        isTroubleCheckFinished = null;
16945        SkinCheck.isTroubleCheckFinished = null;
16946        $.ajax({
16947          url: Urls.clearSkinCheckSession
16948        });
16949      },
16950      onClickPage4NextButton: function onClickPage4NextButton(e) {
16951        if (this.answer.q3 === 'yes') {
16952          $.ajax({
16953            url: util.ajaxUrl(util.appendParamsToUrl(Urls.setSkinCheckSession, {
16954              value: 'OK',
16955              type: ''
16956            }))
16957          });
16958          e.preventDefault();
16959          var closeModal = function (arg) {
16960            // 肌トラのモーダルを閉じた後に実行する関数を格納
16961            var modalCallBackFunc = function () {
16962              if (typeof arg === 'function') {
16963                return arg;
16964              }
16965              return function () {};
16966            }.bind(this)();
16967            setTimeout(function () {
16968              cpbUi.util.centerModalClose.call(e.target, 'skin_trouble_check_modal', modalCallBackFunc, 10);
16969            });
16970            this.onCloseModal();
16971          }.bind(this);
16972          $.when(this.addToCart()).then(function (_) {
16973            return this.redirectToTotalCounsellingPage();
16974          }.bind(this)).fail(closeModal);
16975        } else {
16976          $.ajax({
16977            url: util.ajaxUrl(util.appendParamsToUrl(Urls.setSkinCheckSession, {
16978              value: 'OK',
16979              type: ''
16980            }))
16981          });
16982          // 終了画面を開く
16983          this.page = 5;
16984        }
16985      },
16986      onClickPage5CloseButton: function onClickPage5CloseButton(e) {
16987        var closeModal = function (arg) {
16988          // 肌トラのモーダルを閉じた後に実行する関数を格納
16989          var modalCallBackFunc = function () {
16990            if (typeof arg === 'function') {
16991              return arg;
16992            }
16993            return function () {};
16994          }.bind(this)();
16995          setTimeout(function () {
16996            cpbUi.util.centerModalClose.call(e.target, 'skin_trouble_check_modal', modalCallBackFunc, 10);
16997          });
16998          this.onCloseModal();
16999        }.bind(this);
17000        $.when(this.addToCart()).then(closeModal).fail(closeModal);
17001      },
17002      onClickPage6NextButton: function onClickPage6NextButton(e) {
17003        e.preventDefault();
17004        var closeModal = function (arg) {
17005          // 肌トラのモーダルを閉じた後に実行する関数を格納
17006          var modalCallBackFunc = function () {
17007            if (typeof arg === 'function') {
17008              return arg;
17009            }
17010            return function () {};
17011          }.bind(this)();
17012          setTimeout(function () {
17013            cpbUi.util.centerModalClose.call(e.target, 'skin_trouble_check_modal', modalCallBackFunc, 10);
17014          });
17015          this.onCloseModal();
17016        }.bind(this);
17017        $.when(this.addToCart()).then(function (arg) {
17018          if (this.answer.q3 === 'yes') {
17019            return this.redirectToTotalCounsellingPage();
17020          }
17021          // カート追加時に画面遷移する物はモーダルを閉じなくても良いが
17022          // ajaxで処理をしている場合、ミニカートを表示する必要があるためモーダルを必ず閉じる
17023          closeModal(arg);
17024        }.bind(this)).fail(closeModal);
17025      },
17026      openTotalCounsellingTab: function openTotalCounsellingTab() {
17027        // カウンセリングを新規タブで開く処理を記述
17028        browserWindow.open(Urls.totalCounselingInput + ($('main#contents').data('pid') ? '?callerpid=' + $('main#contents').data('pid') : '?callerlocation=' + browserWindow.location.href), '_blank');
17029      },
17030      redirectToTotalCounsellingPage: function redirectToTotalCounsellingPage() {
17031        // redirect to the consultation process
17032        $(document).ajaxComplete(function () {
17033          browserWindow.window.location.href = Urls.totalCounselingInput + ($('main#contents').data('pid') ? '?callerpid=' + $('main#contents').data('pid') : '?callerlocation=' + browserWindow.location.href);
17034        });
17035      },
17036      addToCart: function addToCart() {
17037        // カートに追加する処理を記述
17038        return $.when(_addToCart(this.buttonEvent, this.buttonElement, this.buttonCallback));
17039      }
17040    }
17041  });
17042
17043  var skinTroubleCheckModalViewModel = new Vue({
17044    el: '#skin-trouble-check-modal'
17045  });
17046})(undefined, jQuery, cpbUi, window, Urls, SkinCheck, util);
17047
17048},{"../../util":77}],53:[function(require,module,exports){
17049'use strict';
17050
17051module.exports = function socialShareIcons() {
17052  $('.social-share-trigger').on('click', function () {
17053    $(this).parent().toggleClass('animate');
17054
17055    if (!Foundation.MediaQuery.atLeast('medium')) {
17056      $('#wrapper').toggleClass('overlay');
17057    }
17058  });
17059
17060  $('.social-modal-close').on('click', function () {
17061    $(this).parent().removeClass('animate');
17062    $('#wrapper').removeClass('overlay');
17063  });
17064};
17065
17066},{}],54:[function(require,module,exports){
17067'use strict';
17068
17069var _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; };
17070
17071var ajax = require('../../ajax'),
17072    progress = require('../../progress'),
17073    productStoreInventory = require('../../storeinventory/product'),
17074    util = require('../../util'),
17075    design = require('../../design'),
17076    addToCart = require('./addToCart');
17077
17078function colorSelectInit() {
17079  var index = 0;
17080  /**
17081   * NORMAL PRODUCT
17082   */
17083
17084  $('.cpb-products_details_area .cpb-products-color_list a').off('click').on('click', function (e) {
17085    e.preventDefault();
17086
17087    // 追従フッダー用
17088    var suppressScrollOnce = function suppressScrollOnce(ev) {
17089      ev.stopPropagation();
17090      ev.preventDefault();
17091      window.removeEventListener('scroll', suppressScrollOnce, true);
17092      return;
17093    };
17094    window.addEventListener('scroll', suppressScrollOnce, true);
17095
17096    $('.cpb-products-cart_fixed .cpb-products-color_list li').removeClass('selected');
17097    $('.cpb-products-cart_fixed .cpb-products-color_list .c-list-color-panel').removeClass('is-current');
17098    var index = $('.cpb-products_details_area .cpb-products-color_list a').index(this);
17099    $('.cpb-products-cart_fixed .cpb-products-color_list').each(function () {
17100      var $btn = $(this).find('li').eq(index);
17101      $btn.addClass('selected');
17102      $btn.find('.c-list-color-panel').addClass('is-current');
17103    });
17104
17105    var href = $(this).attr('href');
17106    updateContent($(this), href, '.js-product-top-content');
17107    updateProductSummaryArea($(this).data('params'), $('.js-product-top-content+.cpb-products-summary_area'));
17108    return;
17109  });
17110
17111  $('.cpb-products_details_area .c-tileradio-list li.c-tileradio-list-item').off('click').on('click', function (e) {
17112    e.preventDefault();
17113    var href = $(this).data('href');
17114    updateContent($(this), href, '.js-product-top-content');
17115    updateProductSummaryArea($(this).data('params'), $('.js-product-top-content+.cpb-products-summary_area'));
17116  });
17117
17118  $('.cmd-select select.js-select-change_tab').off('change.ingredientContent').on('change.ingredientContent', function (e) {
17119    e.preventDefault();
17120    updateProductSummaryArea($(this).children('option:selected').data('params'), $('#ingredient-tab-content'), true);
17121  });
17122
17123  $('.cmd-select select.js-select-change-variation').off('change.pdpVariation').on('change.pdpVariation', function (e) {
17124    e.preventDefault();
17125    var href = $(this).val();
17126    updateContent($(this), href, '.js-product-top-content');
17127    updateProductSummaryArea($(this).children('option:selected').data('params'), $('.js-product-top-content+.cpb-products-summary_area'));
17128  });
17129
17130  $('.cpb-modal_quickview-inner .cpb-products-color_list a').off('click').on('click', function (e) {
17131    e.preventDefault();
17132
17133    $('.cpb-products-cart_fixed .cpb-products-color_list li').removeClass('selected');
17134    $('.cpb-products-cart_fixed .cpb-products-color_list .c-list-color-panel').removeClass('is-current');
17135    var index = $('.cpb-modal_quickview-inner .cpb-products-color_list a').index(this);
17136    $('.cpb-products-cart_fixed .cpb-products-color_list').each(function () {
17137      var $btn = $(this).find('li').eq(index);
17138      $btn.addClass('selected');
17139      $btn.find('.c-list-color-panel').addClass('is-current');
17140    });
17141
17142    var href = $(this).attr('href');
17143    updateQuickviewContent($(this), href);
17144    return;
17145  });
17146
17147  $('.cpb-modal_quickview-inner .c-tileradio-list .cmd-chk_parts').off('click').on('click', function (e) {
17148    var href = $(this).closest('li').attr('data-href');
17149    updateQuickviewContent($(this), href);
17150    return;
17151  });
17152
17153  $('.cpb-products-cart_fixed .cpb-products-color_list a').off('click').on('click', function (e) {
17154    e.preventDefault();
17155
17156    $(this).closest('.cpb-products-color_list').find('li').removeClass('selected');
17157    $(this).closest('.cpb-products-color_list').find('.c-list-color-panel').removeClass('is-current');
17158    var index = $('.cpb-products-cart_fixed .cpb-products-color_list a').index(this);
17159    $('.cpb-products-cart_fixed .cpb-products-color_list').each(function () {
17160      var $btn = $(this).find('li').eq(index);
17161      $btn.addClass('selected');
17162      $btn.find('.c-list-color-panel').addClass('is-current');
17163    });
17164
17165    if ($('.cpb-products_details_area').length > 0) {
17166      $('.cpb-products_details_area .cpb-products-color_list a').eq(index).trigger('click');
17167    }
17168    if ($('.cpb-modal_quickview-inner').length > 0) {
17169      $('.cpb-modal_quickview-inner .cpb-products-color_list a').eq(index).trigger('click');
17170    }
17171  });
17172
17173  $('#productservicemodal .product-service-step1 .cpb-naire-color_list a').off('click').on('click', function (e) {
17174    e.preventDefault();
17175    var index = $(this).closest('.cpb-naire-color_list').find('a').index(this);
17176    var href = $(this).attr('href');
17177    updateContent($(this), href);
17178    return false;
17179  });
17180
17181  $('.cpb-products_details_area .cpb-products-size_list li').off('click').on('click', function (e) {
17182    e.preventDefault();
17183
17184    var href = $(this).data('href');
17185    updateContent($(this), href, '.js-product-top-content');
17186    updateProductSummaryArea($(this).data('params'), $('.js-product-top-content+.cpb-products-summary_area'));
17187    return;
17188  });
17189
17190  // Change color / Bottom bar - color swatch
17191  $('.c-block-shoppingDock .c-list-color a').off('click').on('click', function (e) {
17192    e.preventDefault();
17193    var index = $(this).closest('.c-list-color').find('a').index(this);
17194    $($('#shopingmodalAnker.c-block-shopingmodal .c-list-color a')[index]).trigger('colorSelect');
17195  });
17196
17197  /**
17198   * PRODUCT SET
17199   */
17200  $('#product-set.c-block-shopingmodal .c-list-color a').off('colorSelect').on('colorSelect', function (e) {
17201    e.preventDefault();
17202    var index = $(this).closest('.c-list-color').find('a').index(this);
17203
17204    var href = $(this).attr('href');
17205
17206    updateSetContent($(this), href);
17207
17208    return false;
17209  });
17210
17211  //PC時 クリック処理
17212  $('#product-set.c-block-shopingmodal .c-list-color a').off('click').on('click', function (e) {
17213    e.preventDefault();
17214    if (window.innerWidth > 992) {
17215      var index = $(this).closest('.c-list-color').find('a').index(this);
17216      $(this).trigger('colorSelect');
17217      return;
17218    }
17219
17220    var href = $(this).attr('href');
17221
17222    updateSetContent($(this), href);
17223  });
17224
17225  //セレクトボックス内選択時
17226  $('#product-set .c-block-shopingmodal-side-colorSelect .c-select-list-item a').off('click').on('click', function () {
17227    var index = $(this).closest('.c-select-list').find('a').index(this);
17228    $(this).closest('.c-block-shopingmodal-set-item').find('.c-list-color a').eq(index).trigger('colorSelect');
17229  });
17230
17231  $('#product-set .c-block-shopingmodal-side-size li.c-tileradio-list-item').off('click').on('click', function (e) {
17232    e.preventDefault();
17233
17234    var href = $(this).data('href');
17235
17236    updateSetContent($(this), href);
17237  });
17238
17239  $('.cpb-products-variety_box .cpb-products-color_list a').off('click').on('click', function (e) {
17240    e.preventDefault();
17241    var href = $(this).attr('href');
17242    updateSetContent($(this), href);
17243    return;
17244  });
17245
17246  $('.cpb-products-variety_box li.c-tileradio-list-item').off('click').on('click', function (e) {
17247    e.preventDefault();
17248    var href = $(this).data('href');
17249    updateSetContent($(this), href);
17250  });
17251
17252  /**
17253   * PRODUCT KIT
17254   */
17255  $('#kitproductmodal .cpb-naire-variation .cpb-naire-color_list a').off('click.kit_product_modal').on('click.kit_product_modal', function (e) {
17256    e.preventDefault();
17257    var href = $(this).attr('href');
17258    updateKitModalContent($(this), href);
17259    return false;
17260  });
17261
17262  var url = location.href;
17263  if (url.indexOf('?') != -1) {
17264    var params = url.split('?');
17265    var paramms = params[1].split('&');
17266    var paramArray = [];
17267    var neet = void 0;
17268    for (var i = 0; i < paramms.length; i++) {
17269      neet = paramms[i].split('=');
17270      paramArray.push(neet[0]);
17271      paramArray[neet[0]] = neet[1];
17272    }
17273    index = paramArray['color'];
17274    $('#shopingmodalAnker.c-block-shopingmodal .c-list-color a').eq(index).trigger('colorSelect');
17275  }
17276}
17277
17278function updateContent($ele, href, target) {
17279  var $pdpForm = $('.pdpForm');
17280  var isPopup = $ele.parents('.pt_product-details').length == 0;
17281  var isColorSelect = $ele.parents('.c-block-shopingmodal-side-color').length == 1;
17282  var isProductServiceModal = $ele.parents('.product-service-step1').length == 1;
17283  var _target = '.c-block-shopingmodal';
17284  var edgingtext = '';
17285  var edgingFont = '';
17286  if (target != null) {
17287    _target = target;
17288  }
17289  if (isProductServiceModal == true) {
17290    isPopup = false;
17291    _target = '.product-service';
17292    edgingtext = $('[name=dwfrm_productengraving_edgingtext]').val();
17293    edgingFont = $('input[name=naire-font]:checked').data('id');
17294  }
17295  var qty = $pdpForm.find('.c-quantitySelection-num .c-select-list a.is-selected .c-select-list-item-text').first().data('num');
17296
17297  var params = {
17298    Quantity: isNaN(qty) ? '1' : qty,
17299    format: 'ajax',
17300    productlistid: $pdpForm.find('input[name="productlistid"]').first().val(),
17301    isProductServiceModal: isProductServiceModal
17302  };
17303
17304  ajax.load({
17305    url: util.appendParamsToUrl(href, params),
17306    target: $(_target),
17307    callback: function callback() {
17308      updateVariationContent($ele, false);
17309      changeBottomButton();
17310
17311      if (typeof VIRTUAL_MAKE !== 'undefined') {
17312        VIRTUAL_MAKE.MODULE.setVM();
17313      }
17314
17315      if (SitePreferences.STORE_PICKUP) {
17316        productStoreInventory.init();
17317      }
17318
17319      //$(document).trigger("gtvariationchange");
17320      cpbUi.pdp.ready();
17321      addToCart();
17322      colorSelectInit();
17323      design.selectQuantityInit();
17324      design.toggleSelectInit(true);
17325      design.modalInit();
17326      //design.pdpInit();
17327      if (isColorSelect) {
17328        $('.c-block-shoppingDock').show();
17329      }
17330
17331      // update zenSeibunHyjny on tab content
17332      $('#ingredient-tab-content').html($('#zenSeibunHyjny').val());
17333      $('.cmd-select select > option').each(function () {
17334        if (this.value === href) {
17335          this.setAttribute('selected', 'selected');
17336        } else {
17337          this.removeAttribute('selected');
17338        }
17339      });
17340      if (isPopup) {
17341        $.magnificPopup.open({
17342          items: {
17343            src: '#shopingmodal', // can be a HTML string, jQuery object, or CSS selector
17344            type: 'inline'
17345          }
17346        });
17347      }
17348
17349      if ('' !== edgingtext) {
17350        $('#productservicemodal #naire-data').val(edgingtext);
17351        $('#productservicemodal .js-naire-preview').empty().text(edgingtext);
17352      }
17353      if ('' !== edgingFont) {
17354        // 選択状態にするラジオボタン要素を取得
17355        var checkedEdgingElement = $('input[name=naire-font]').toArray().filter(function (element) {
17356          return $(element).data('id') === edgingFont;
17357        });
17358        if (checkedEdgingElement.length === 0) {
17359          // 取得できなかった場合、一番最初の要素を選択状態する
17360          $('input[name=naire-font]').eq(0).prop('checked', true);
17361        } else {
17362          $(checkedEdgingElement).prop('checked', true);
17363        }
17364      }
17365      // reload wishlist button event
17366      reloadWishlistButtonEvent();
17367      changeBottomButton();
17368
17369      var ua = navigator.userAgent;
17370      if ((ua.indexOf('iPhone') > 0 || ua.indexOf('iPod') > 0 || ua.indexOf('Android') > 0) && ua.indexOf('Mobile') > 0) {
17371        // Processing for smartphones
17372      } else if (ua.indexOf('iPad') > 0 || ua.indexOf('Android') > 0 || ua.indexOf('Macintosh') > -1 && 'ontouchend' in document) {
17373        // Processing for tablets
17374      } else {
17375        // Processing for PC
17376        $('.hadapasha_link_sp').css('display', 'none');
17377      }
17378    }
17379  });
17380}
17381
17382/**
17383 * Update product summary area (information right below cpb-products_details_area)
17384 *
17385 * @param {Object} params: This variant params
17386 * @returns {HTML}
17387 */
17388function updateProductSummaryArea(params, $target) {
17389  var isPartialUpdate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
17390
17391  if ($target === undefined || $target.length === 0) {
17392    return;
17393  }
17394
17395  var targetBeforeUpdate = isPartialUpdate ? '' : $target.find('.js-tab-acc_list a.js-tab-acc_btn.is-active').data('tab-target');
17396  var url = params ? Urls.productSummaryArea + '?' + params : Urls.productSummaryArea;
17397
17398  $.ajax({
17399    dataType: 'html',
17400    url: util.appendParamToURL(url, 'format', 'ajax'),
17401    xhrFields: {
17402      withCredentials: true
17403    }
17404  }).done(function (response) {
17405    colorSelectInit();
17406    if (isPartialUpdate) {
17407      var updateInformation = $(response).find($target.selector).text();
17408      $target.empty().text(updateInformation);
17409      return;
17410    }
17411    $target.empty().html(response);
17412    $target.find('.js-tab-acc_list a[data-tab-target="' + targetBeforeUpdate + '"]').click();
17413  });
17414}
17415
17416function updateSetContent($ele, href) {
17417  var $productSetItemCtnr = $ele.closest('.cpb-products-variety_box');
17418  var qty = $productSetItemCtnr.find('input[name="Quantity"]').val();
17419
17420  ajax.load({
17421    url: util.appendParamsToUrl(href, {
17422      Quantity: isNaN(qty) ? '1' : qty,
17423      format: 'ajax',
17424      setproduct: true
17425    }),
17426    target: $productSetItemCtnr,
17427    callback: function callback() {
17428      updateVariationContent($ele, true);
17429
17430      if (typeof VIRTUAL_MAKE !== 'undefined') {
17431        VIRTUAL_MAKE.MODULE.setVM();
17432      }
17433
17434      addToCart();
17435      colorSelectInit(true);
17436
17437      // Update wishlist button
17438      updateWishlistButton();
17439      updateAmountPricePS($productSetItemCtnr, href);
17440      updateAddToCartButton();
17441    }
17442  });
17443}
17444
17445/**
17446 * Update amount price for product set
17447 * @param $ele
17448 * @returns
17449 */
17450function updateAmountPricePS($ele, href) {
17451  var totalPrice = $('.cpb-products-variety_area .cpb-products-variety_box').toArray().reduce(function (totalPrice, currentValue) {
17452    var count = Number($(currentValue).find('.cpb-products-conut .js-num-drop_input').val()) || 0;
17453    var price = Number($(currentValue).find('.item-price .num').data().value) || 0;
17454    return totalPrice + count * price;
17455  }, 0);
17456
17457  var $target = $ele.parent().siblings('.cpb-products-conut').find('.item-price');
17458  ajax.load({
17459    url: util.appendParamsToUrl(href, {
17460      format: 'ajax',
17461      pricingps: true
17462    }),
17463    target: $target,
17464    data: {
17465      standardPricePS: totalPrice,
17466      salesPricePS: totalPrice
17467    },
17468    callback: function callback() {}
17469  });
17470}
17471
17472function updateKitModalContent($ele, href) {
17473  var productId = $ele.attr('data-product');
17474  var kitProductId = $ele.attr('data-kit-product');
17475  var setId = $ele.attr('set-id');
17476
17477  var params = {
17478    isKitModal: true,
17479    productId: productId,
17480    kitProductId: kitProductId,
17481    setId: setId,
17482    productSetNumber: $ele.attr('set-number'),
17483    productNumber: $ele.attr('product-number')
17484  };
17485
17486  ajax.load({
17487    url: util.appendParamsToUrl(href, params),
17488    target: $('.product-kit'),
17489    callback: function callback() {
17490      colorSelectInit();
17491    }
17492  });
17493}
17494
17495/**
17496 * Update selected color
17497 * @param $ele
17498 * @param isSet
17499 * @returns
17500 */
17501function updateVariationContent($ele, isSet) {
17502  // update product bottom fixed position
17503  if ($('.cpb-products-cart_fixed .cpb-products-data_box').length > 0) {
17504    if ($('.cpb-products-cart_fixed .cpb-products-data_box').find('.item-color').length > 0) {
17505      $('.cpb-products-cart_fixed .cpb-products-data_box .item-color').remove();
17506      $('.cpb-products-cart_fixed .cpb-products-data_box .item-state').remove();
17507    }
17508
17509    if ($('.cpb-products_details_area .c-tileradio-list li.c-tileradio-list-item input').length == 0) {
17510      $('.cpb-products-cart_fixed .cpb-products-data_box').prepend(colorSelectedTag($ele));
17511    }
17512
17513    // update price bottom fixed position
17514    if ($('.cpb-products-cart_fixed .cpb-products-data_box').find('.item-price').html() != '') {
17515      $('.cpb-products-cart_fixed .cpb-products-data_box .item-price').html('');
17516    }
17517
17518    $('.cpb-products-cart_fixed .cpb-products-data_box .item-price').html($('#cpb-products_price').html().replace('class="num"', ''));
17519  }
17520}
17521
17522function colorSelectedTag($ele) {
17523  var description = $ele.find('span').first().data('description');
17524  return '<p class="item-color">' + description + '</p>';
17525}
17526
17527function updateQuickviewContent($ele, href) {
17528  var $pdpForm = $('.pdpForm');
17529
17530  var params = {
17531    Quantity: '1',
17532    format: 'ajax',
17533    productlistid: $pdpForm.find('input[name="productlistid"]').first().val(),
17534    isQuickviewModal: true
17535  };
17536
17537  ajax.load({
17538    url: util.appendParamsToUrl(href, params),
17539    callback: function callback(data) {
17540      var $pdpHtml = $(data);
17541      var $modal = $('#cpb-modal-quickview');
17542      updateVariationContent($ele, false);
17543
17544      $modal.find('.cpb-modalR_bottom .quantity_box').html($pdpHtml.find('#cpb-products_price').prop('outerHTML'));
17545      $modal.find('.cpb-modalR_bottom .cmd-button_container').html($pdpHtml.find('#cpb-products_submit').prop('outerHTML'));
17546      $modal.find('.cpb-modal_quickview-inner').html($pdpHtml.find('.cpb-products-details'));
17547
17548      changeBottomButton();
17549
17550      if (SitePreferences.STORE_PICKUP) {
17551        productStoreInventory.init();
17552      }
17553
17554      // re-init pdp events
17555      cpbUi.pdp.ready();
17556
17557      addToCart();
17558      colorSelectInit();
17559
17560      // reload wishlist button event
17561      reloadWishlistButtonEvent();
17562      changeBottomButton();
17563      if (/Product-Variation/.test(href)) {
17564        $('.quickview-source-url').attr('href', href.replace('Product-Variation', 'Product-Show'));
17565        $('.quickview-error-message').remove();
17566      }
17567    }
17568  });
17569}
17570
17571/**
17572 * Reload wishlist button event
17573 * @returns
17574 */
17575function reloadWishlistButtonEvent() {
17576  $('.cpb-products-details #save-for-later').on('click', function (e) {
17577    if (!window.User.isCustomerAuthenticated) {
17578      return;
17579    }
17580
17581    e.preventDefault();
17582    var $target = $(this).parent();
17583    var url = util.appendParamsToUrl($(this).attr('href'), {
17584      format: 'ajax'
17585    });
17586    var data = {};
17587    data[this.dataset.csrfname] = this.dataset.csrfvalue;
17588
17589    $.ajax({
17590      type: 'POST',
17591      url: url,
17592      data: data
17593    }).done(function (response) {
17594      if (typeof response === 'string' && response !== '') {
17595        $target.empty().html(response);
17596        reloadWishlistButtonEvent();
17597      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
17598        window.alert(response.error);
17599      }
17600    });
17601  });
17602
17603  $('.cpb-products-details .remove-from-wishlist').on('click', function (e) {
17604    e.preventDefault();
17605
17606    var $target = $(this).parent();
17607    var url = util.appendParamsToUrl($(this).attr('href'), {
17608      format: 'ajax'
17609    });
17610    var data = {};
17611    data[this.dataset.csrfname] = this.dataset.csrfvalue;
17612
17613    $.ajax({
17614      type: 'POST',
17615      url: url,
17616      data: data
17617    }).done(function (response) {
17618      if (typeof response === 'string' && response !== '') {
17619        $target.empty().html(response);
17620        reloadWishlistButtonEvent();
17621      } else if ((typeof response === 'undefined' ? 'undefined' : _typeof(response)) === 'object' && !response.success) {
17622        window.alert(response.error);
17623      }
17624    }).fail(function (xhr, textStatus) {
17625      if (textStatus === 'parsererror') {
17626        window.alert(Resources.BAD_RESPONSE);
17627      } else {
17628        window.alert(Resources.SERVER_CONNECTION_ERROR);
17629      }
17630    });
17631  });
17632}
17633
17634/**
17635 * Update wishlist button
17636 * @returns
17637 */
17638function updateWishlistButton() {
17639  if ($('.item-link_box').length > 0) {
17640    var $productForms = $('.cpb-products-variety_area').find('.cpb-products-variety_box .txtarea').toArray();
17641    var pids = $productForms.map(function (formEle) {
17642      return $(formEle).data('pid');
17643    }).join(',');
17644
17645    $.post(util.appendParamsToUrl(Urls.wishlistIsSavedForLater, {
17646      pid: pids
17647    }), function (data) {
17648      if (data === 'false') {
17649        $('.product-form-actions .product-set-wishlist').removeClass('invisible');
17650        $('.product-form-actions .remove-product-set-from-wishlist').addClass('invisible');
17651      } else {
17652        $('.product-form-actions .product-set-wishlist').addClass('invisible');
17653        $('.product-form-actions .remove-product-set-from-wishlist').removeClass('invisible');
17654      }
17655    });
17656  }
17657}
17658
17659/**
17660 * 商品セット内のバリエーションを変えた際に「ショッピングバックに入れる」の表示を更新
17661 */
17662function updateAddToCartButton() {
17663  var elementList = $('.cpb-products-variety_area .cpb-products-variety_box').toArray();
17664  // 一つでも在庫切れ、オフライン、店舗限定の
17664商品が有った場合、true
17665  var checkProduct = function checkProduct() {
17666    return elementList.some(function (element) {
17667      return 'none' === $(element).find('.cmd-num_set').css('display');
17668    });
17669  };
17670  // すべての商品の購入個数が「0」の場合、true
17671  var checkNum = function checkNum() {
17672    return elementList.every(function (element) {
17673      return 0 < $(element).find('.cpb-products-conut .js-num-drop_input').length && 0 === Number($(element).find('.cpb-products-conut .js-num-drop_input').val());
17674    });
17675  };
17676  if (checkProduct() || checkNum()) {
17677    $('#add-all-to-cart').prop('disabled', 'disabled');
17678  } else {
17679    $('#add-all-to-cart').prop('disabled', '');
17680  }
17681}
17682
17683/**
17684 * Update product bottom fixed position cart button when select variation
17685 * @returns
17686 */
17687function changeBottomButton() {
17688  var $dockButton = $('.cpb-products-cart_fixed .cpb-products-cart_submit button');
17689  var $cartButton = $('#add-to-cart');
17690  var isDisabledAddCart = $('#is_disabled_add_cart').length === 0 ? false : true;
17691  if (!isDisabledAddCart && ($cartButton.length === 0 || $('.cpb-products-cart_fixed').length === 0)) {
17692    return;
17693  }
17694  if (isDisabledAddCart) {
17695    // ショッピングバックに入れるボタンを削除
17696    $dockButton.remove();
17697    // 追従フッダーにクラスを付与する
17698    if ($('.cpb-products-cart_fixed').length !== 0) {
17699      $('.cpb-products-cart_fixed')[0].classList.add('sp_disabled_footer');
17700    }
17701    return;
17702  } else {
17703    // ショッピングバックに入れるボタンが無い場合、作成
17704    if ($dockButton.length === 0) {
17705      var element = document.createElement('button');
17706      element.classList.add('button');
17707      element.type = 'submit';
17708      $('.cpb-products-cart_fixed .cpb-products-cart_submit').append(element);
17709      $dockButton = $(element);
17710    }
17711    // 追従フッダーのクラスを削除する
17712    if ($('.cpb-products-cart_fixed').length !== 0) {
17713      $('.cpb-products-cart_fixed')[0].classList.remove('sp_disabled_footer');
17714    }
17715  }
17716
17717  var buttonText = $cartButton.text();
17718  $dockButton.text(buttonText);
17719  if ($cartButton.prop('disabled') == true) {
17720    $dockButton.attr('disabled', 'disabled');
17721  } else {
17722    $dockButton.removeAttr('disabled');
17723  }
17724}
17725
17726module.exports = function () {
17727  var isSet = $('.cpb-products-variety_area').length > 0;
17728  // color select event
17729  if ($('.cpb-products-details .cpb-products-color_list a span.is-current').length > 0) {
17730    var $ele = $('.cpb-products-details .cpb-products-color_list a span.is-current').closest('a');
17731    updateVariationContent($ele, isSet);
17732  } else if ($('.cpb-products_details_area .c-tileradio-list li.c-tileradio-list-item input:checked').length > 0) {
17733    var _$ele = $('.cpb-products_details_area .c-tileradio-list li.c-tileradio-list-item input:checked').closest('li');
17734    updateVariationContent(_$ele, isSet);
17735  }
17736  changeBottomButton();
17737  colorSelectInit();
17738};
17739
17740},{"../../ajax":1,"../../design":11,"../../progress":64,"../../storeinventory/product":74,"../../util":77,"./addToCart":44}],55:[function(require,module,exports){
17741'use strict';
17742
17743var util = require('../util');
17744
17745var $cache;
17746
17747function initializeCache() {
17748  $cache = {};
17749  $cache['errorMsg'] = $('#promotion-landing-container .landing-error');
17750}
17751
17752function initializeEvents() {
17753  $(document).on('submit', '#PromoLandingForm', function (e) {
17754    var httpParams = util.getQueryStringParams(util.getQueryString(window.location.href));
17755    $('<input type="hidden" name="promoid" value="' + httpParams['promoid'] + '" />').appendTo(e.target);
17756  }).on('focus', '#PromoLandingForm input', function () {
17757    $cache.errorMsg.hide();
17758  });
17759}
17760
17761module.exports.init = function () {
17762  initializeCache();
17763  initializeEvents();
17764
17765  if (window.location.href.indexOf('error') > -1) {
17766    $cache.errorMsg.show();
17767  }
17768  if (window.couponCode) {
17769    $('#promo-code').text(window.couponCode);
17770  }
17771};
17772
17773},{"../util":77}],56:[function(require,module,exports){
17774'use strict';
17775
17776var addProductToCart = require('./product/addToCart'),
17777    ajax = require('../ajax'),
17778    login = require('../login'),
17779    quickview = require('../quickview'),
17780    util = require('../util');
17781
17782/**
17783 * @function
17784 * @description Loads address details to a given address and fills the address form
17785 * @param {String} addressID The ID of the address to which data will be loaded
17786 */
17787function populateForm(addressID, $form) {
17788  // load address details
17789  var url = Urls.giftRegAdd + addressID;
17790  ajax.getJson({
17791    url: url,
17792    callback: function callback(data) {
17793      if (!data || !data.address) {
17794        window.alert(Resources.REG_ADDR_ERROR);
17795        return false;
17796      }
17797      // fill the form
17798      $form.find('[name$="_addressid"]').val(data.address.ID);
17799      $form.find('[name$="_firstname"]').val(data.address.firstName);
17800      $form.find('[name$="_lastname"]').val(data.address.lastName);
17801      $form.find('[name$="_address1"]').val(data.address.address1);
17802      $form.find('[name$="_address2"]').val(data.address.address2);
17803      $form.find('[name$="_city"]').val(data.address.city);
17804      $form.find('[name$="_country"]').val(data.address.countryCode).trigger('change');
17805      $form.find('[name$="_postal"]').val(data.address.postalCode);
17806      $form.find('[name$="_state"]').val(data.address.stateCode);
17807      $form.find('[name$="_phone"]').val(data.address.phone);
17808      // $form.parent('form').validate().form();
17809    }
17810  });
17811}
17812
17813/**
17814 * @private
17815 * @function
17816 * @description Initializes events for the gift registration
17817 */
17818function initializeEvents() {
17819  var $eventAddressForm = $('form[name$="_giftregistry"]'),
17820      $beforeAddress = $eventAddressForm.find('fieldset[name="address-before"]'),
17821      $afterAddress = $eventAddressForm.find('fieldset[name="address-after"]');
17822
17823  $('.usepreevent').on('click', function () {
17824    // filter out storefront toolkit
17825    $(':input', $beforeAddress).not('[id^="ext"]').not('select[name$="_addressBeforeList"]').each(function () {
17826      var fieldName = $(this).attr('name'),
17827          $afterField = $afterAddress.find('[name="' + fieldName.replace('Before', 'After') + '"]');
17828      $afterField.val($(this).val()).trigger('change');
17829    });
17830  });
17831  $eventAddressForm.on('change', 'select[name$="_addressBeforeList"]', function () {
17832    var addressID = $(this).val();
17833    if (addressID.length === 0) {
17834      return;
17835    }
17836    populateForm(addressID, $beforeAddress);
17837  }).on('change', 'select[name$="_addressAfterList"]', function () {
17838    var addressID = $(this).val();
17839    if (addressID.length === 0) {
17840      return;
17841    }
17842    populateForm(addressID, $afterAddress);
17843  });
17844
17845  $('.item-list').on('click', '.item-edit-details a', function (e) {
17846    e.preventDefault();
17847    var productListID = $('input[name=productListID]').val();
17848    quickview.show({
17849      url: e.target.href,
17850      source: 'giftregistry',
17851      productlistid: productListID
17852    });
17853  });
17854}
17855
17856exports.init = function () {
17857  initializeEvents();
17858  addProductToCart();
17859  login.init();
17860  util.setDeleteConfirmation('.item-list', String.format(Resources.CONFIRM_DELETE, Resources.TITLE_GIFTREGISTRY));
17861};
17862
17863},{"../ajax":1,"../login":22,"../quickview":66,"../util":77,"./product/addToCart":44}],57:[function(require,module,exports){
17864'use strict';
17865
17866var compareWidget = require('../compare-widget'),
17867    productTile = require('../product-tile'),
17868    progress = require('../progress'),
17869    video = require('../video'),
17870    util = require('../util'),
17871    design = require('../design');
17872
17873function copyBottomResultHitsToTop() {
17874  $('#results-hits-top').html($('#results-hits-bottom .results-hits').html());
17875}
17876
17877function viewAllClick(ev) {
17878  return viewMoreClick(ev, $('.order-view-all'));
17879}
17880
17881function viewMoreClick(ev, $target) {
17882  // getting the hidden div, which is the placeholder for the next page
17883  var loadingPlaceHolder = $('.infinite-scroll-placeholder[data-loading-state="unloaded"]');
17884  // get url hidden in DOM
17885  if (loadingPlaceHolder.length === 0) {
17886    return;
17887  }
17888  var gridUrl = loadingPlaceHolder.attr('data-grid-url');
17889  if ($target && $target.attr('data-grid-count')) {
17890    var splitted = gridUrl.split('?');
17891    var base = splitted[0];
17892    var params = splitted[1].split('&').map(function (str) {
17893      var pair = str.split('=');
17894      if (pair[0] === 'sz') {
17895        pair[1] = $target.attr('data-grid-count');
17896      }
17897      return pair.join('=');
17898    }).join('&');
17899    if (params) {
17900      gridUrl = base + '?' + params;
17901    }
17902  }
17903  if (loadingPlaceHolder.length === 1) {
17904    // switch state to 'loading'
17905    // - switches state, so the above selector is only matching once
17906    // - shows loading indicator
17907    loadingPlaceHolder.attr('data-loading-state', 'loading');
17908    loadingPlaceHolder.addClass('infinite-scroll-loading');
17909
17910    // named wrapper function, which can either be called, if cache is hit, or ajax repsonse is received
17911    var fillEndlessScrollChunk = function fillEndlessScrollChunk(html) {
17912      loadingPlaceHolder.removeClass('infinite-scroll-loading');
17913      loadingPlaceHolder.attr('data-loading-state', 'loaded');
17914      $('.js-page-list').append(html);
17915
17916      var currentNum = $('.number-item-of-page').last().text().trim();
17917      $('.c-list-pagination .js-list-num-current').html(currentNum);
17918
17919      var winT = $(window).scrollTop();
17920      matchHeightProducts();
17921      $(window).scrollTop(winT);
17922
17923      // rebind the View More event
17924      $('#view-more').off();
17925      $('#view-more').on('click', viewMoreClick);
17926      $('.order-view-all').off('click').on('click', viewAllClick);
17927      // hide view-more button and view-all button when items in OrderHistory all loaded
17928      if ($('.ajaxAllOrderHistory').length === 1 || $('.ajax-all').length > 0) {
17929        $('#view-more').parents('li').remove();
17930        $('#view-all').parents('li').remove();
17931      }
17932    };
17933
17934    // old condition for caching was `'sessionStorage' in window && sessionStorage["scroll-cache_" + gridUrl]`
17935    // it was removed to temporarily address RAP-2649
17936    $.ajax({ type: 'GET', dataType: 'html', url: gridUrl }).done(function (response) {
17937      // put response into cache
17938      try {
17939        sessionStorage['scroll-cache_' + gridUrl] = response;
17940      } catch (e) {}
17941      // nothing to catch in case of out of memory of session storage
17942      // it will fall back to load via ajax
17943
17944      // update UI
17945      $('.results-hits').remove();
17946      fillEndlessScrollChunk(response);
17947      copyBottomResultHitsToTop();
17948      productTile.init();
17949      $(document).trigger('plpviewmore');
17950    }).then(function () {
17951      updateHistoryURL($('.c-block-listItem-wrap > .c-block-listItem-history').length);
17952    });
17953  }
17954}
17955
17956function updateHistoryURL(sz) {
17957  if (!sz) {
17958    return;
17959  }
17960  window.history.replaceState(null, document.title, window.location.href.split('?')[0] + '?sz=' + sz.toFixed(0));
17961}
17962
17963/**
17964 * @private
17965 * @function
17966 * @description replaces breadcrumbs, lefthand nav and product listing with ajax and puts a loading indicator over the product listing
17967 */
17968function updateProductListing(url, tabType) {
17969  if (!url || url === window.location.href) {
17970    return;
17971  }
17972  progress.show($('.js-page-list'));
17973  if (typeof tabType === 'undefined' || tabType === null) {
17974    tabType = 'undefined';
17975  }
17976
17977  $.ajax({
17978    type: 'GET',
17979    dataType: 'html',
17980    url: util.appendParamToURL(url, 'format', 'ajax')
17981  }).done(function (data, textStatus, jqXHR) {
17982    var dataRes = $($.parseHTML(data));
17983    if (dataRes.find('main').length > 0) {
17984      $('main').html(dataRes.find('main')[0].innerHTML);
17985    } else {
17986      $('main').html(data);
17987    }
17988
17989    compareWidget.init();
17990    productTile.init();
17991    design.searchInit();
17992    design.plpInit();
17993    design.selectQuantityInit();
17994    design.productSearchInit();
17995    if (tabType === 'sort') {
17996      $('.c-block-products-search-tabs .c-block-products-search-tabs--sort .tab').trigger('click');
17997    }
17998    if (tabType === 'filter') {
17999      $('.c-block-products-search-tabs .c-block-products-search-tabs--filter .tab').trigger('click');
18000    }
18001    design.toggleSelectInit(true);
18002    matchHeightProducts();
18003    progress.hide();
18004    history.pushState(undefined, '', url);
18005  });
18006}
18007
18008function excludeCompoundAttributeRefinements(refineUrl) {
18009  var newUrl = refineUrl;
18010
18011  var params = util.getQueryStringParams(refineUrl);
18012  Object.keys(params).forEach(function (paramName) {
18013    if (paramName.indexOf('prefv') === -1) {
18014      return;
18015    }
18016
18017    var splitParam = params[paramName].split('|');
18018    newUrl = util.updateQueryStringParam(newUrl, paramName, splitParam[splitParam.length - 1]);
18019  });
18020
18021  return newUrl;
18022}
18023
18024/**
18025 * @private
18026 * @function
18027 * @description Initializes events for the following elements:<br/>
18028 * <p>refinement blocks</p>
18029 * <p>updating grid: refinements, pagination, breadcrumb</p>
18030 * <p>item click</p>
18031 * <p>sorting changes</p>
18032 */
18033function initializeEvents() {
18034  var $main = $('main');
18035  // compare checked
18036  $main.on('click', 'input[type="checkbox"].compare-check', function () {
18037    var cb = $(this);
18038    var tile = cb.closest('.product-tile');
18039
18040    var func = this.checked ? compareWidget.addProduct : compareWidget.removeProduct;
18041    var itemImg = tile.find('.product-image a img').first();
18042    func({
18043      itemid: tile.data('itemid'),
18044      uuid: tile[0].id,
18045      img: itemImg,
18046      cb: cb
18047    });
18048  });
18049
18050  // handle events for updating grid
18051  $main.on('click', '.refinements a, .pagination a, .breadcrumb-refinement-value a', function (e) {
18052    // don't intercept for category and folder refinements, as well as unselectable
18053    if ($(this).parents('.category-refinement').length > 0 || $(this).parents('.folder-refinement').length > 0 || $(this).parent().hasClass('unselectable')) {
18054      return;
18055    }
18056    e.preventDefault();
18057    updateProductListing(this.href);
18058  });
18059
18060  // handle sorting change
18061  $main.on('click', '.c-block-products-search-panel--sort .c-select-list-item', function (e) {
18062    e.preventDefault();
18063    updateProductListing($(this).find('a').attr('data'), 'sort');
18064  }).on('change', '.items-per-page select', function () {
18065    var refineUrl = $(this).find('option:selected').val();
18066    if (refineUrl === 'INFINITE_SCROLL') {
18067      $('html').addClass('infinite-scroll').removeClass('disable-infinite-scroll');
18068    } else {
18069      $('html').addClass('disable-infinite-scroll').removeClass('infinite-scroll');
18070      updateProductListing(refineUrl);
18071    }
18072  });
18073
18074  //handle refinement change
18075  $main.on('click', '.c-block-products-search-panel--filter .c-select-list-item', function (e) {
18076    e.preventDefault();
18077
18078    if ($(this).hasClass('is-skip')) {
18079      return;
18080    }
18081
18082    var refineUrl = $(this).data('url');
18083    if (refineUrl.indexOf('prefv') > -1) {
18084      refineUrl = excludeCompoundAttributeRefinements(refineUrl);
18085    }
18086
18087    updateProductListing(refineUrl, 'filter');
18088  }).on('change', '.items-per-page select', function () {
18089    var refineUrl = $(this).find('option:selected').val();
18090    $('html').addClass('disable-infinite-scroll').removeClass('infinite-scroll');
18091    updateProductListing(refineUrl);
18092  });
18093
18094  $('.category-tab-links select').off('change').on('change', function (e) {
18095    var $selected = $(this).find(':selected');
18096    var link = $selected.attr('href');
18097
18098    if (link) {
18099      window.location.href = link;
18100    }
18101  });
18102}
18103
18104function matchHeightProducts() {
18105  if ($('.c-product-cards-step-header').length) {
18106    $('.c-product-cards-list .c-product-cards-step-header').matchHeight();
18107  }
18108  $('.c-product-cards-list .c-product-cards-list-item').matchHeight();
18109}
18110
18111exports.init = function () {
18112  video.init(function () {
18113    initializeEvents();
18114  });
18115
18116  compareWidget.init();
18117  //$("#view-more").on("click", viewMoreClick);
18118
18119  $(document).on('click', '#view-more', viewMoreClick);
18120  $(document).on('click', '.order-view-all', viewAllClick);
18121  //$('#filter1-submit').click(function() {
18122  //	$('#filter1').val('0');
18123  //});
18124  productTile.init();
18125  //initializeEvents();
18126  design.toggleSelectInit(true);
18127
18128  // content navigation title link
18129  $('.nav.content-navigation .accordion-title span').on('click', function () {
18130    window.location = $(this).data('url');
18131  });
18132
18133  // content navigation dropdown redirect
18134  $('.nav.content-navigation select').on('change', function () {
18135    window.location = $(this).val();
18136  });
18137
18138  var $accordionToggle = $('.refinements .accordion-arrow');
18139
18140  $accordionToggle.on('click', function (evt) {
18141    console.log($(this));
18142    evt.preventDefault();
18143
18144    $(this).next($('#category-level-2')).slideToggle();
18145
18146    $(this).parent($('li')).toggleClass('expanded');
18147  });
18148};
18149exports.viewMore = function () {
18150  $(document).on('click', '#view-more', viewMoreClick);
18151  $(document).on('click', '.order-view-all', viewAllClick);
18152};
18153
18154},{"../compare-widget":5,"../design":11,"../product-tile":63,"../progress":64,"../util":77,"../video":79}],58:[function(require,module,exports){
18155'use strict';
18156
18157var addProductToCart = require('./product/addToCart'),
18158    login = require('../login'),
18159    util = require('../util'),
18160    account = require('./account'),
18161    minicart = require('../minicart'),
18162    design = require('../design'),
18163    skin_trouble_check = require('./product/skin_trouble_check');
18164
18165function addItemToBag(e, $this) {
18166  e.preventDefault();
18167  if (!$this) {
18168    var $this = $(this);
18169  }
18170  var displayPopup = false;
18171
18172  if (window.innerWidth <= 768) {
18173    displayPopup = true;
18174  }
18175
18176  var $form = $this.closest('form');
18177  var $errorLocation = $form.find('ul.c-text-error>li');
18178
18179  return $.ajax({
18180    type: 'POST',
18181    url: util.ajaxUrl(Urls.wishlistAddToCart),
18182    data: $form.serialize() + '&displayPopup=' + displayPopup,
18183    loading: true
18184  }).then(function (response) {
18185    if (response.error) {
18186      $errorLocation.html(response.error);
18187      $errorLocation.parent().removeClass('mfp-hide');
18188      return $.Deferred().reject().promise();
18189    }
18190    $errorLocation.parent().addClass('mfp-hide');
18191    $errorLocation.html(null);
18192    return function () {
18193      minicart.show(response);
18194      design.dropdownToggleInit();
18195    };
18196  });
18197}
18198
18199function initAddToCart() {
18200  $(document).off('click', 'button[name="waitlist_addtocart"]').on('click', 'button[name="waitlist_addtocart"]', skinCheck);
18201}
18202
18203function skinCheck(e) {
18204  skin_trouble_check.skinTroubleExecute(e, $(this), addItemToBag);
18205}
18206
18207exports.init = function () {
18208  // addProductToCart();
18209  initAddToCart();
18210  design.selectQuantityInit();
18211  //login.init();
18212  account.initMobileMenu();
18213};
18214
18215},{"../design":11,"../login":22,"../minicart":23,"../util":77,"./account":29,"./product/addToCart":44,"./product/skin_trouble_check":52}],59:[function(require,module,exports){
18216'use strict';
18217
18218var recommendations = require('./product/recommendations');
18219
18220exports.init = function () {
18221  recommendations();
18222  $('#homepage-hero').slick({
18223    arrows: true,
18224    autoplay: true,
18225    autoplaySpeed: 4000,
18226    dots: true,
18227    slidesToShow: 1,
18228    slidesToScroll: 1,
18229    responsive: [{
18230      breakpoint: 480,
18231      settings: {
18232        arrows: false
18233      }
18234    }]
18235  });
18236  $('.sub-feature-article').slick({
18237    arrows: false,
18238    dots: false,
18239    infinite: false,
18240    slidesToShow: 3,
18241    slidesToScroll: 3,
18242    responsive: [{
18243      breakpoint: 480,
18244      settings: {
18245        slidesToShow: 1,
18246        slidesToScroll: 1,
18247        infinite: true,
18248        arrows: false,
18249        dots: true
18250      }
18251    }]
18252  });
18253};
18254
18255},{"./product/recommendations":51}],60:[function(require,module,exports){
18256'use strict';
18257
18258var dialog = require('../dialog');
18259
18260exports.init = function () {
18261  $('.store-details-link').on('click', function (e) {
18262    e.preventDefault();
18263    dialog.open({
18264      url: $(e.target).attr('href')
18265    });
18266  });
18267};
18268
18269},{"../dialog":12}],61:[function(require,module,exports){
18270'use strict';
18271
18272function initTutorialCarousel() {
18273  $('.related-carousel-wrapper .tutorial-wrapper').slick({
18274    infinite: true,
18275    slidesToShow: 4,
18276    slidesToScroll: 4,
18277    dots: true,
18278    arrows: false,
18279    responsive: [{
18280      breakpoint: 1024,
18281      settings: {
18282        slidesToShow: 3,
18283        slidesToScroll: 1,
18284        infinite: true,
18285        arrows: false,
18286        dots: true
18287      }
18288    }, {
18289      breakpoint: 640,
18290      settings: {
18291        slidesToShow: 1,
18292        slidesToScroll: 1,
18293        infinite: true,
18294        arrows: false,
18295        dots: true
18296      }
18297    }]
18298  });
18299
18300  if ($('#thumbnails li').length == 0) {
18301    return false;
18302  } else if ($('#thumbnails li').length > 1 && window.innerWidth > 767) {
18303    tutorialThumbnailCarousel();
18304  } else if ($('#thumbnails li').length > 1 && window.innerWidth < 768) {
18305    tutorialMainImageCarousel();
18306  }
18307  tutorialImages();
18308}
18309
18310function tutorialThumbnailCarousel() {
18311  $('#thumbnails ul').slick({
18312    dots: false,
18313    infinite: true,
18314    arrows: true,
18315    vertical: true,
18316    slidesToShow: 4,
18317    slidesToScroll: 1
18318  });
18319}
18320
18321function tutorialMainImageCarousel() {
18322  $('#thumbnails').find('.productthumbnail.selected').removeClass('selected');
18323  $('#thumbnails ul').slick({
18324    dots: true,
18325    vertical: false,
18326    infinite: true,
18327    arrows: false,
18328    centerMode: false,
18329    slidesToShow: 1
18330  });
18331}
18332
18333// tutorial image carousel
18334function tutorialImages() {
18335  $('#thumbnails').on('click', '.productthumbnail', function () {
18336    var $that = $(this);
18337
18338    $('#thumbnails').find('.productthumbnail.selected').removeClass('selected');
18339    $that.addClass('selected');
18340    setTutorialMainImage($that.find('img').attr('src'));
18341  });
18342}
18343
18344function setTutorialMainImage(src) {
18345  $('#tutorial-image-template .primary-image').attr('src', src);
18346}
18347
18348exports.init = function () {
18349  initTutorialCarousel();
18350};
18351
18352},{}],62:[function(require,module,exports){
18353'use strict';
18354
18355var page = require('../page'),
18356    login = require('../login'),
18357    util = require('../util'),
18358    account = require('./account'),
18359    minicart = require('../minicart'),
18360    design = require('../design'),
18361    skin_trouble_check = require('./product/skin_trouble_check');
18362
18363function addAllItemToBag(e, $this) {
18364  e.preventDefault();
18365  if (!$this) {
18366    var $this = $(this);
18367  }
18368
18369  //Clear list of product added to cart
18370  $('.add-all-form .cart-added-list').data('plist', '');
18371  $('#minicart-notification .notify').text('');
18372  var deferredList = $(document).find('.c-pcOnly-tb>button[name$="_addToCart"]').map(function (index) {
18373    return addItemToBag(e, $(this), {
18374      isAddAllToBagClicked: true,
18375      count: index + 1
18376    }); //since we want to know if the click is from add all to bag or not.
18377  });
18378
18379  // 「...rest」には「addItemToBag」の返却値が格納される
18380  return $.when.apply($this, deferredList).then(function () {
18381    for (var _len = arguments.length, rest = Array(_len), _key = 0; _key < _len; _key++) {
18382      rest[_key] = arguments[_key];
18383    }
18384
18385    var isAllFailed = rest.some(function (result) {
18386      return !result.success;
18387    });
18388    if (isAllFailed) {
18389      return $.Deferred().reject().promise();
18390    }
18391    // 一つでもカートに追加出来た商品があった場合、ミニカートを表示
18392    // 最後に返却された結果のコールバック関数を使用
18393    var sortResult = rest.sort(function (a, b) {
18394      if (a.execTime < b.execTime) {
18395        return -1;
18396      }
18397      if (a.execTime > b.execTime) {
18398        return 1;
18399      }
18400      return 0;
18401    });
18402    return sortResult.reduce(function (func, currentValue) {
18403      if (currentValue.success) {
18404        return currentValue.callBackFunc;
18405      }
18406      return func;
18407    });
18408  });
18409}
18410
18411/**
18412 * お気に入り内にある「ショッピングバッグに入れる」「すべての商品をショッピングバッグに入れる」クリック時に実行される関数
18413 * 肌トラブルチェックの仕様上、返却値は以下になる
18414 * ・ショッピングバッグに入れる:肌トラブルチェック後に実行するコールバック関数
18415 * ・すべての商品をショッピングバッグに入れる:エラーがあるか無いか判定するためのオブジェクト
18416 *
18417 * @param {*} e
18418 * @param {*} $this
18419 * @param {*} wishListData
18420 */
18421function addItemToBag(e, $this, wishListData) {
18422  e.preventDefault();
18423  if (!$this) {
18424    var $this = $(this);
18425  }
18426
18427  var displayPopup = false;
18428  var wishListItemLen = $('.c-list-products-full-item').length;
18429  var displayProdSpecificMsg = wishListItemLen === 1 ? true : false;
18430  if (typeof wishListData == 'undefined') {
18431    var wishListData = {};
18432    wishListData.isAddAllToBagClicked = false;
18433    wishListData.count = 1;
18434    displayProdSpecificMsg = true;
18435  }
18436
18437  if (window.innerWidth <= 768) {
18438    displayPopup = true;
18439  }
18440  if (wishListData.isAddAllToBagClicked === false) {
18441    $('#minicart-notification .notify').text('');
18442    displayPopup = true;
18443  } else {
18444    if (wishListItemLen === wishListData.count) {
18445      displayPopup = true;
18446    }
18447  }
18448
18449  var $form = $this.closest('form');
18450  var extraParams = '&displayPopup=' + displayPopup + '&displayProdSpecificMsg=' + displayProdSpecificMsg + '&isAddAllToBagClicked=' + wishListData.isAddAllToBagClicked;
18451  var $errorLocation = $form.find('ul.c-text-error>li');
18452  var $cartAddedList = $('.add-all-form .cart-added-list');
18453
18454  return $.ajax({
18455    type: 'POST',
18456    url: util.ajaxUrl(Urls.wishlistAddToCart),
18457    data: $form.serialize() + extraParams,
18458    loading: true
18459  }).then(function (response) {
18460    if (response.error) {
18461      $errorLocation.text(response.error);
18462      $errorLocation.parent().removeClass('mfp-hide');
18463      if (wishListData.isAddAllToBagClicked) {
18464        // 「すべての商品をショッピングバッグに入れる」で使用するため判定用の連想配列を返却
18465        // 最後に実行した結果を画面に出力するため実行終了時間も設定
18466        return { success: false, execTime: new Date().getTime() };
18467      }
18468      return $.Deferred().reject().promise();
18469    }
18470    $errorLocation.parent().addClass('mfp-hide');
18471    $errorLocation.text('');
18472
18473    if (wishListData.isAddAllToBagClicked == true && window.innerWidth <= 768) {
18474      //Create a list of product added to cart successful
18475      if ($cartAddedList.data('plist') !== '') {
18476        $cartAddedList.data('plist', $cartAddedList.data('plist') + ', ' + $form.find('input[name=pname]').val());
18477      } else {
18478        $cartAddedList.data('plist', $form.find('input[name=pname]').val());
18479      }
18480
18481      //Copy list of product added to cart successful to display
18482      $('#minicart-notification .notify').text($cartAddedList.data('plist'));
18483    } else if (wishListData.isAddAllToBagClicked == false && window.innerWidth <= 768) {
18484      $('#minicart-notification .notify').text($form.find('input[name=pname]').val());
18485    }
18486
18487    var callBackFunc = function callBackFunc() {
18488      minicart.show(response);
18489      design.dropdownToggleInit();
18490    };
18491    // 「すべての商品をショッピングバッグに入れる」で使用するため判定用の連想配列を返却
18492    // 最後に実行した結果を画面に出力するため実行終了時間も設定
18493    if (wishListData.isAddAllToBagClicked) {
18494      return {
18495        success: true,
18496        callBackFunc: callBackFunc,
18497        execTime: new Date().getTime()
18498      };
18499    }
18500    // 肌トラブルチェック後に実行するコールバック関数
18501    return callBackFunc;
18502  });
18503}
18504
18505function initAddToCart() {
18506  $(document).off('click', 'button.add-all-to-cart').on('click', 'button.add-all-to-cart', skinCheckOnAll);
18507  $(document).off('click', 'button[name$="_addToCart"]').on('click', 'button[name$="_addToCart"]', skinCheck);
18508}
18509
18510function skinCheckOnAll(e) {
18511  skin_trouble_check.skinTroubleExecute(e, $(this), addAllItemToBag);
18512}
18513
18514function skinCheck(e) {
18515  skin_trouble_check.skinTroubleExecute(e, $(this), addItemToBag);
18516}
18517
18518exports.init = function () {
18519  initAddToCart();
18520
18521  $('#editAddress').on('change', function () {
18522    page.redirect(util.appendParamToURL(Urls.wishlistAddress, 'AddressID', $(this).val()));
18523  });
18524
18525  //add js logic to remove the , from the qty feild to pass regex expression on client side
18526  $('.option-quantity-desired input').on('focusout', function () {
18527    $(this).val($(this).val().replace(',', ''));
18528  });
18529
18530  login.init();
18531  account.initMobileMenu();
18532};
18533
18534},{"../design":11,"../login":22,"../minicart":23,"../page":28,"../util":77,"./account":29,"./product/skin_trouble_check":52}],63:[function(require,module,exports){
18535'use strict';
18536
18537var imagesLoaded = require('imagesloaded'),
18538    images = require('./pages/product/image'),
18539    quickview = require('./quickview'),
18540    addToCart = require('./pages/product/addToCart'),
18541    variant = require('./pages/product/variant'),
18542    design = require('./design');
18543
18544function initQuickViewButtons() {
18545  if (!quickViewEnabled) {
18546    return;
18547  }
18548
18549  $('.c-product-cards-quickshop-toggle').magnificPopup({
18550    type: 'ajax',
18551    ajax: {
18552      settings: null, // Ajax settings object that will extend default one - http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
18553      // For example:
18554      // settings: {cache:false, async:false}
18555
18556      cursor: 'mfp-ajax-cur', // CSS class that will be added to body during the loading (adds "progress" cursor)
18557      tError: Resources.QUICKVIEW_ERROR //  Error message, can contain %curr% and %total% tags if gallery is enabled
18558    },
18559    callbacks: {
18560      parseAjax: function parseAjax(mfpResponse) {
18561        // mfpResponse.data is a "data" object from ajax "success" callback
18562        // for simple HTML file, it will be just String
18563
18564        // mfpResponse.data must be a String or a DOM (jQuery) element
18565        mfpResponse.data = $(mfpResponse.data).find('.c-block-shopingmodal').first();
18566      },
18567      ajaxContentAdded: function ajaxContentAdded() {
18568        $('#shopingmodal').html(this.content[0].outerHTML);
18569        $.magnificPopup.open({
18570          items: {
18571            src: '#shopingmodal', // can be a HTML string, jQuery object, or CSS selector
18572            type: 'inline'
18573          }
18574        });
18575
18576        images();
18577        addToCart();
18578        variant();
18579        renderThumbnails();
18580        quickview.initWishlistButton();
18581
18582        $('#BVRRSummaryContainer').on('click', '.bv-rating-stars-container', function () {
18583          window.location.href = url + '#reviews'; // redirect when rating star is clicked
18584        });
18585
18586        $(document).on('click', '.bv-popup-in .bv-read-review', function () {
18587          window.location.href = url + '#reviews'; // redirect when read reviews button is clicked
18588        });
18589
18590        design.toggleSelectInit(true);
18591        design.modalInit();
18592        design.pdpInit();
18593        design.selectQuantityInit();
18594      }
18595    }
18596  });
18597}
18598
18599function gridViewToggle() {
18600  $('.toggle-grid').on('click', function () {
18601    $('.search-result-content').toggleClass('wide-tiles');
18602    $(this).toggleClass('wide');
18603  });
18604}
18605
18606function renderThumbnails() {
18607  if ($('#thumbnails').length > 0) {
18608    $('#thumbnails').empty(); // clear the list
18609    images(); // populate the thumbnails
18610  }
18611}
18612
18613function initCarouselSwatches() {
18614  $('.swatch-list').not('.slick-slider').slick({
18615    dots: false,
18616    focusOnSelect: true,
18617    infinite: false,
18618    slidesToShow: 6,
18619    slidesToScroll: 3,
18620    speed: 300
18621  });
18622}
18623
18624/**
18625 * @private
18626 * @function
18627 * @description Initializes events on the product-tile for the following elements:
18628 * - swatches
18629 * - thumbnails
18630 */
18631function initializeEvents() {
18632  initQuickViewButtons();
18633  initColorChange();
18634  gridViewToggle();
18635  $('.swatch-list').on('mouseleave', function () {
18636    // Restore current thumb image
18637    var $tile = $(this).closest('.product-tile'),
18638        $thumb = $tile.find('.product-image .thumb-link img').eq(0),
18639        data = $thumb.data('current');
18640
18641    if (!data) {
18642      return;
18643    }
18644
18645    $thumb.attr({
18646      src: data.src,
18647      alt: data.alt,
18648      title: data.title
18649    });
18650  });
18651  $('.swatch-list .swatch').on('click', function (e) {
18652    e.preventDefault();
18653    if ($(this).hasClass('selected')) {
18654      return;
18655    }
18656
18657    var $tile = $(this).closest('.product-tile');
18658    $(this).closest('.swatch-list').find('.swatch.selected').removeClass('selected');
18659    $(this).addClass('selected');
18660    $tile.find('.thumb-link').attr('href', $(this).attr('href'));
18661    $tile.find('name-link').attr('href', $(this).attr('href'));
18662
18663    var data = $(this).children('img').filter(':first').data('thumb');
18664    var $thumb = $tile.find('.product-image .thumb-link img').eq(0);
18665    var currentAttrs = {
18666      src: data.src,
18667      alt: data.alt,
18668      title: data.title
18669    };
18670    $thumb.attr(currentAttrs);
18671    $thumb.data('current', currentAttrs);
18672  }).on('mouseenter', function () {
18673    // get current thumb details
18674    var $tile = $(this).closest('.product-tile'),
18675        $thumb = $tile.find('.product-image .thumb-link img').eq(0),
18676        data = $(this).children('img').filter(':first').data('thumb'),
18677        current = $thumb.data('current');
18678
18679    if (!data) {
18680      return;
18681    }
18682
18683    // If this is the first time, then record the current img
18684    if (!current) {
18685      $thumb.data('current', {
18686        src: $thumb[0].src,
18687        alt: $thumb[0].alt,
18688        title: $thumb[0].title
18689      });
18690    }
18691
18692    // Set the tile image to the values provided on the swatch data attributes
18693    $thumb.attr({
18694      src: data.src,
18695      alt: data.alt,
18696      title: data.title
18697    });
18698  });
18699}
18700
18701function initColorChange() {
18702  $('div.c-product-cards .c-list-color li > a').on('click mousehover', function () {
18703    $(this).closest('.c-product-cards').find('.c-product-cards-photo-img').attr('href', $(this).attr('href') + '&cgid=' + $('#categoryId').val());
18704    $(this).closest('.c-product-cards').find('.c-product-cards-text > a').attr('href', $(this).attr('href') + '&cgid=' + $('#categoryId').val());
18705    $(this).closest('.c-product-cards').find('.c-product-cards-quickshop-toggle').attr('href', $(this).attr('href') + '&cgid=' + $('#categoryId').val() + '&source=quickview');
18706  });
18707}
18708
18709exports.init = function () {
18710  var $tiles = $('.c-product-cards-list .c-product-cards-list-item');
18711  if ($tiles.length === 0) {
18712    return;
18713  }
18714
18715  initCarouselSwatches();
18716  initializeEvents();
18717};
18718
18719exports.initCarouselSwatches = initCarouselSwatches;
18720exports.initQuickViewButtons = initQuickViewButtons;
18721exports.initColorChange = initColorChange;
18722
18723},{"./design":11,"./pages/product/addToCart":44,"./pages/product/image":47,"./pages/product/variant":54,"./quickview":66,"imagesloaded":110}],64:[function(require,module,exports){
18724'use strict';
18725
18726var $loader;
18727
18728/**
18729 * @function
18730 * @description Shows an AJAX-loader on top of a given container
18731 * @param {Element} container The Element on top of which the AJAX-Loader will be shown
18732 */
18733var show = function show(container) {
18734  var target = !container || $(container).length === 0 ? $('body') : $(container);
18735  $loader = $loader || $('.loader');
18736
18737  if ($loader.length === 0) {
18738    $loader = $('<div/>').addClass('loader').append($('<div/>').addClass('loader-indicator'), $('<div/>').addClass('loader-bg'));
18739  }
18740  return $loader.appendTo(target).show();
18741};
18742/**
18743 * @function
18744 * @description Hides an AJAX-loader
18745 */
18746var hide = function hide() {
18747  if ($loader) {
18748    $loader.hide();
18749  }
18750};
18751
18752exports.show = show;
18753exports.hide = hide;
18754
18755},{}],65:[function(require,module,exports){
18756'use strict';
18757
18758var util = require('./util');
18759var page = require('./page');
18760var modal = require('./modal');
18761var cache = {};
18762
18763function initCache() {
18764  if ($('#EditAddressForm').length > 0) {
18765    cache['$formId'] = '#EditAddressForm';
18766    cache['$form'] = $('#EditAddressForm');
18767    cache['$source'] = 'dwfrm_shippingaddress';
18768    cache['$save'] = $('#EditAddressForm').find('.apply-button').attr('name');
18769  } else if ($('#dwfrm_singleshipping_shippingAddress').length > 0) {
18770    cache['$formId'] = '#dwfrm_singleshipping_shippingAddress';
18771    cache['$form'] = $('#dwfrm_singleshipping_shippingAddress');
18772    cache['$source'] = 'dwfrm_singleshipping_shippingAddress_addressFields';
18773    cache['$save'] = 'dwfrm_singleshipping_shippingAddress_save';
18774  }
18775
18776  cache['$modal'] = modal.create('#qas-modal', '#qas-modal .modal-body', {
18777    closeOnClick: false,
18778    closeOnEsc: false
18779  });
18780}
18781
18782function initEvents() {
18783  if (cache.$form && cache.$form.length > 0) {
18784    cache.$form.off('click').on('click', ' button[name="' + cache.$save + '"]', validate);
18785  }
18786}
18787
18788function submitForm() {
18789  cache.$form.append('<input type="hidden" name="' + cache.$save + '"/>');
18790  cache.$form.submit();
18791}
18792
18793function updateAddressForm(addr) {
18794  cache.$form.find('input[name$="_address1"]').val(addr.add1);
18795  cache.$form.find('input[name$="_address2"]').val(addr.add2);
18796  cache.$form.find('select[id$="_state"]').val(addr.state ? addr.state.toUpperCase() : '');
18797  cache.$form.find('input[name$="_city"]').val(addr.city);
18798  cache.$form.find('input[name$="_postal"]').val(addr.zip);
18799}
18800
18801function updateAddress(data) {
18802  $.ajax({
18803    type: 'POST',
18804    url: Urls.qasUpdateAddress,
18805    data: data,
18806    dataType: 'html'
18807  }).done(function (response, textStatus, request) {
18808    var response = JSON.parse(response);
18809    if (response.action === 'reValidate') {
18810      cache.$modal.close();
18811      validate('reValidate');
18812    } else {
18813      if (response.action !== 'useOrig') {
18814        updateAddressForm(response.address);
18815      }
18816
18817      submitForm();
18818    }
18819  });
18820}
18821
18822function validate(action) {
18823  if ($('#dwfrm_singleshipping_shippingAddress').length > 0 && !$('#EditAddressForm').is(':visible')) {
18824    //Ade -- if (cache.$formId === '#EditAddressForm' &&
18825    cache['$formId'] = '#dwfrm_singleshipping_shippingAddress';
18826    cache['$form'] = $('#dwfrm_singleshipping_shippingAddress');
18827    cache['$source'] = 'dwfrm_singleshipping_shippingAddress_addressFields';
18828    cache['$save'] = 'dwfrm_singleshipping_shippingAddress_save';
18829  }
18830
18831  if (!cache.$form.validate().form()) {
18832    return;
18833  }
18834
18835  var data = cache.$form.serialize() + '&source=' + cache.$source;
18836  if (typeof action === 'string') {
18837    data = data + '&dwfrm_addForm_action=' + action;
18838  }
18839
18840  $.ajax({
18841    type: 'POST',
18842    url: Urls.qasVerifyAddress,
18843    data: data,
18844    dataType: 'html'
18845  }).done(function (content, textStatus, request) {
18846    if (/json/.test(request.getResponseHeader('Content-Type'))) {
18847      var response = JSON.parse(content);
18848      if (response.action === 'addrVerified') {
18849        updateAddressForm(response.address);
18850        submitForm();
18851      } else if (response.action === 'verified') {
18852        submitForm();
18853      }
18854    } else {
18855      cache.$modal.renderContent(content);
18856
18857      $('.addForm').on('click', 'button', function () {
18858        var form = $(this).parents('form');
18859        form.append('<input type="hidden" name="' + $(this).attr('name') + '"/>');
18860
18861        updateAddress(form.serialize());
18862        cache.$modal.close();
18863
18864        return false;
18865      });
18866    }
18867  });
18868
18869  return false;
18870}
18871
18872var qas = {
18873  init: function init() {
18874    if (SitePreferences.IS_QAS_ENABLED) {
18875      initCache();
18876      initEvents();
18877    }
18878  }
18879};
18880
18881module.exports = qas;
18882
18883},{"./modal":24,"./page":28,"./util":77}],66:[function(require,module,exports){
18884'use strict';
18885
18886module.exports = {};
18887var product = require('./pages/product');
18888
18889/**
18890 * QuickView
18891 */
18892cpbUi.directQuickView = function (href, callback) {
18893  var modalHtml = '<div id="cpb-modal-quickview" class="cpb-modalR_container js-quickview_content" data-modal-type="quickview">\
18894        <div class="cpb-modalR_wrap">\
18895            <div class="cpb-modalR_contents cpb-cart_style">\
18896                <form action="#">\
18897                    <div class="cpb-modalR_scroll_cover">\
18898                        <div class="cpb-modalR_inner cpb-modal_scroll js-modal_scroll">\
18899                            <div class="cpb-modal_quickview">\
18900                                <button class="cpb-modalR_close js-quickview_close"><span class="invisible">CLOSE</span></button>\
18901                                <!-- pdp -->\
18902                                <div class="cpb-modal_quickview-inner"></div>\
18903                                <!-- /pdp -->\
18904                            </div><!-- / cpb-modal_quickview -->\
18905                        </div><!-- / cpb-modalR_inner -->\
18906                        <div class="cpb-modalR_bottom">\
18907                            <!-- price -->\
18908                            <div class="quantity_box"></div>\
18909                            <!-- /price -->\
18910                            <!-- button -->\
18911                            <div class="cmd-button_container"></div>\
18912                            <!-- /button -->\
18913                        </div><!-- / cpb-modalR_bottom -->\
18914                    </div><!-- / cpb-modalR_scroll_cover -->\
18915                </form>\
18916            </div><!-- / cpb-modalR_contents" -->\
18917        </div><!-- / cpb-modalR_wrap -->\
18918        <div class="cpb-modal_overlay js-quickview_overlay"></div>\
18919    </div><!-- / cpb-modalR_container -->';
18920
18921  $.ajax({
18922    type: 'GET',
18923    url: href,
18924    dataType: 'html'
18925  }).done(function (data, textStatus, jqXHR) {
18926    var $pdpHtml = $(data);
18927    var $modal = $(modalHtml);
18928
18929    $modal.find('.cpb-modalR_bottom .quantity_box').append($pdpHtml.find('#cpb-products_price').prop('outerHTML'));
18930    $modal.find('.cpb-modalR_bottom .cmd-button_container').append($pdpHtml.find('#cpb-products_submit').prop('outerHTML'));
18931    $modal.find('.cpb-modal_quickview-inner').append($pdpHtml.find('.cpb-products_details_area .cpb-products-details'));
18932    var isSynactifProduct = $modal.find('.cpb-products-details').attr('data-issynactifproduct');
18933    if (isSynactifProduct === 'true') {
18934      $modal.addClass('quickView-synactif');
18935    }
18936    $('body').append($modal);
18937
18938    if (typeof callback === 'function') callback();
18939  }).fail(function (jqXHR, textStatus, errorThrown) {});
18940};
18941
18942function openQuickView(href) {
18943  var deferred = $.Deferred();
18944  cpbUi.isQuickView = true;
18945  cpbUi.directQuickView(href, function () {
18946    cpbUi.pdp.ready();
18947
18948    cpbUi.util.rightModalOpen.call(this, 'quickview', function () {
18949      // init product's events
18950      product.initializeEvents();
18951
18952      cpbUi.niceScroll.ready();
18953      cpbUi.sliderControl.resize();
18954      var $form = $('#cpb-modal-quickview form');
18955      $form.find('.quickview-source-url').remove();
18956      $form.append($('<a class="quickview-source-url mfp-hide" href=' + href + '></a>'));
18957      deferred.resolve();
18958    });
18959  });
18960  return deferred.promise();
18961}
18962
18963module.exports.init = function () {
18964  $(document).on('click', '.js-quickview-btn', function (e) {
18965    e.preventDefault();
18966    if (!cpbUi.isQuickView) {
18967      var href = $(this).attr('href');
18968      openQuickView(href);
18969    }
18970  });
18971  $(document).on('click', '.js-quickview_close', function (e) {
18972    e.preventDefault();
18973    cpbUi.util.rightModalClose.call(this, 'quickview', function () {
18974      $('#cpb-modal-quickview').find('.js-modal_scroll').getNiceScroll().remove();
18975      $('#cpb-modal-quickview').remove();
18976      cpbUi.isQuickView = false;
18977    });
18978  });
18979  $(document).on('click', '.js-quickview_overlay', function (e) {
18980    e.preventDefault();
18981    cpbUi.util.rightModalClose.call(this, 'quickview', function () {
18982      $('#cpb-modal-quickview').find('.js-modal_scroll').getNiceScroll().remove();
18983      $('#cpb-modal-quickview').remove();
18984      cpbUi.isQuickView = false;
18985    });
18986  });
18987};
18988
18989module.exports.openQuickView = openQuickView;
18990
18991},{"./pages/product":48}],67:[function(require,module,exports){
18992'use strict';
18993
18994/**
18995 * copied from https://github.com/darkskyapp/string-hash
18996 */
18997
18998function hashFn(str) {
18999  var hash = 5381,
19000      i = str.length;
19001
19002  while (i) {
19003    hash = hash * 33 ^ str.charCodeAt(--i);
19004  }
19005  /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
19006   * integers. Since we want the results to be always positive, convert the
19007   * signed int to an unsigned by doing an unsigned bitshift. */
19008  return hash >>> 0;
19009}
19010
19011/**
19012 * Create rating based on hash ranging from 2-5
19013 * @param pid
19014 */
19015function getRating(pid) {
19016  return hashFn(pid.toString()) % 30 / 10 + 2;
19017}
19018
19019module.exports = {
19020  init: function init() {
19021    $('.product-review').each(function (index, review) {
19022      var pid = $(review).data('pid');
19023      if (!pid) {
19024        return;
19025      }
19026      // rating range from 2 - 5
19027      var rating = getRating(pid);
19028      var baseRating = Math.floor(rating);
19029      var starsCount = 0;
19030      for (var i = 0; i < baseRating; i++) {
19031        $('.rating', review).append('<i class="fa fa-star"></i>');
19032        starsCount++;
19033      }
19034      // give half star for anything in between
19035      if (rating > baseRating) {
19036        $('.rating', review).append('<i class="fa fa-star-half-o"></i>');
19037        starsCount++;
19038      }
19039      if (starsCount < 5) {
19040        for (var j = 0; j < 5 - starsCount; j++) {
19041          $('.rating', review).append('<i class="fa fa-star-o"></i>');
19042        }
19043      }
19044    });
19045  }
19046};
19047
19048},{}],68:[function(require,module,exports){
19049'use strict';
19050
19051// recaptcha
19052$(function () {
19053  $('[name*="_login_username_"]').on('blur', function () {
19054    validateForm();
19055  });
19056  $('[name*="_login_password_"]').on('blur', function () {
19057    validateForm();
19058  });
19059
19060  $('button[name$="_login"], button[name$="_loginexternal"]').prop('disabled', true);
19061
19062  window.validateForm = validateForm;
19063
19064  // if recaptcha is off, do nothing.
19065  if ($('#captcha').length === 0) {
19066    return;
19067  }
19068  window.recaptchaCallback = recaptchaCallback;
19069  window.recaptchaExpiredCallback = recaptchaExpiredCallback;
19070});
19071/**
19072 * Callback of recaptcha
19073 * @returns
19074 */
19075function recaptchaCallback() {
19076  $('button.c-btn--login_disabled, button[name$="_login"], button[name$="_loginexternal"]').prop('disabled', false).removeClass('c-btn--login_disabled');
19077  $('#dummy-error-span-for-recaptcha').css({ visibility: 'hidden' });
19078}
19079/**
19080 * Expired callback of recaptcha
19081 * @returns
19082 */
19083function recaptchaExpiredCallback() {
19084  $('button.c-btn--login_disabled, button[name$="_login"], button[name$="_loginexternal"]').prop('disabled', true).addClass('c-btn--login_disabled');
19085  $('#dummy-error-span-for-recaptcha').css({ visibility: 'visible' });
19086}
19087/**
19088 * Validate and reset submit button
19089 * @returns
19090 */
19091function validateForm() {
19092  var recaptchaIsEnabled = $('#captcha').length > 0;
19093  var recaptchaRegistration = recaptchaIsEnabled ? $('#hiddenRecaptcha_registration').val() == 'false' : false;
19094
19095  if ($('[id*="_login_password_"][id$="-error"]').text() != '' || $('[name*="_login_password_"]').val() == '' || $('[id*="_login_username_"][id$="-error"]').text() != '' || $('[name*="_login_username_"]').val() == '' || recaptchaRegistration) {
19096    // バリデーションチェックNG
19097    $('form[id$="_login"]').find('input[type="submit"], button[type="submit"]').closest('form').data('submitting', true);
19098
19099    // reCAPTCHAオフの場合は、バリデーションNG時にログインボタンを非活性にする
19100    if (!recaptchaIsEnabled) {
19101      recaptchaExpiredCallback();
19102    }
19103  } else {
19104    // バリデーションチェックOK
19105    $('form[id$="_login"]').find('input[type="submit"], button[type="submit"]').closest('form').data('submitting', false);
19106
19107    // reCAPTCHAオフの場合は、バリデーションOK時にログインボタンを活性化する
19108    if (!recaptchaIsEnabled) {
19109      recaptchaCallback();
19110    }
19111  }
19112}
19113
19114},{}],69:[function(require,module,exports){
19115'use strict';
19116
19117var util = require('./util'),
19118    modal = require('./modal').global,
19119    ajax = require('./ajax'),
19120    sampleCookieName = 'sample.selection.shown';
19121
19122/**
19123 * Creates sample selection cookie
19124 */
19125var createSelectionShownCookie = function createSelectionShownCookie() {
19126  util.setCookie(sampleCookieName, '1');
19127};
19128
19129/**
19130 * Checks if sample selection cookie exists
19131 * @return {boolean}
19132 */
19133var canShowSelection = function canShowSelection() {
19134  return !SitePreferences.SAMPLES_ENABLED ? false : true;
19135};
19136
19137/**
19138 * Render Samples
19139 * @return {boolean}
19140 */
19141var showSelection = function showSelection() {
19142  // set selection cookie
19143  //createSelectionShownCookie();
19144
19145  // render content to modal by url
19146
19147  modal.addCustomClass('sample-selection');
19148  modal.renderByUrl(Urls.showSampleSelection);
19149
19150  // close quickview
19151  if ($('.mfp-ready').length > 0) {
19152    $.magnificPopup.close();
19153  }
19154
19155  $.magnificPopup.open({
19156    items: {
19157      src: '#sampleselectionmodal',
19158      type: 'inline',
19159      removalDelay: 500
19160    }
19161  });
19162};
19163
19164var showSelectionInCart = function showSelectionInCart() {
19165  $.get(util.appendParamsToUrl(Urls.showSampleSelectionInCart, {
19166    format: 'ajax',
19167    isOnlyShowcontent: true
19168  })).done(function (data) {
19169    $('.js-modal-r_content[data-modal-type="sample"] .cpb-modalR_contents').html(data);
19170    cpbUi.util.rightModalOpen.call($('#item-sample .cpb-cart_add_btn a.button[data-modal-target="sample"]'), undefined, function (target) {
19171      cpbUi.niceScroll.ready();
19172    });
19173  });
19174};
19175
19176exports.createSelectionShownCookie = createSelectionShownCookie;
19177exports.canShowSelection = canShowSelection;
19178exports.showSelection = showSelection;
19179exports.showSelectionInCart = showSelectionInCart;
19180
19181},{"./ajax":1,"./modal":24,"./util":77}],70:[function(require,module,exports){
19182'use strict';
19183
19184/**
19185 * @private
19186 * @function
19187 * @description Binds event to the place holder (.blur)
19188 */
19189
19190function initializeEvents() {
19191  $('#q').focus(function () {
19192    var input = $(this);
19193    if (input.val() === input.attr('placeholder')) {
19194      input.val('');
19195    }
19196  }).blur(function () {
19197    var input = $(this);
19198    if (input.val() === '' || input.val() === input.attr('placeholder')) {
19199      input.val(input.attr('placeholder'));
19200    }
19201  }).blur();
19202}
19203
19204exports.init = initializeEvents;
19205
19206},{}],71:[function(require,module,exports){
19207'use strict';
19208
19209/**
19210 * @function
19211 * @description Initializes Slick carousels
19212 */
19213
19214exports.init = function () {
19215  $('.slick').slick();
19216};
19217
19218},{}],72:[function(require,module,exports){
19219'use strict';
19220
19221var inventory = require('./');
19222
19223var cartInventory = {
19224  setSelectedStore: function setSelectedStore(storeId) {
19225    var $selectedStore = $('.store-tile.' + storeId),
19226        $lineItem = $('.cart-row[data-uuid="' + this.uuid + '"]'),
19227        storeAddress = $selectedStore.find('.store-address').html(),
19228        storeStatus = $selectedStore.find('.store-status').data('status'),
19229        storeStatusText = $selectedStore.find('.store-status').text();
19230    this.selectedStore = storeId;
19231
19232    $lineItem.find('.instore-delivery .selected-store-address').data('storeId', storeId).attr('data-store-id', storeId).html(storeAddress);
19233    $lineItem.find('.instore-delivery .selected-store-availability').data('status', storeStatus).attr('data-status', storeStatus).text(storeStatusText);
19234    $lineItem.find('.instore-delivery .delivery-option').removeAttr('disabled').trigger('click');
19235  },
19236  cartSelectStore: function cartSelectStore(selectedStore) {
19237    var self = this;
19238    inventory.getStoresInventory(this.uuid).then(function (stores) {
19239      inventory.selectStoreDialog({
19240        stores: stores,
19241        selectedStoreId: selectedStore,
19242        selectedStoreText: Resources.SELECTED_STORE,
19243        continueCallback: function continueCallback() {},
19244        selectStoreCallback: self.setSelectedStore.bind(self)
19245      });
19246    }).done();
19247  },
19248  setDeliveryOption: function setDeliveryOption(value, storeId) {
19249    // set loading state
19250    $('.item-delivery-options').addClass('loading').children().hide();
19251
19252    var data = {
19253      plid: this.uuid,
19254      storepickup: value === 'store' ? true : false
19255    };
19256    if (value === 'store') {
19257      data.storepickup = true;
19258      data.storeid = storeId;
19259    } else {
19260      data.storepickup = false;
19261    }
19262    $.ajax({
19263      url: Urls.setStorePickup,
19264      data: data,
19265      success: function success() {
19266        // remove loading state
19267        $('.item-delivery-options').removeClass('loading').children().show();
19268      }
19269    });
19270  },
19271  init: function init() {
19272    var self = this;
19273    $('.item-delivery-options .set-preferred-store').on('click', function (e) {
19274      e.preventDefault();
19275      self.uuid = $(this).data('uuid');
19276      var selectedStore = $(this).closest('.instore-delivery').find('.selected-store-address').data('storeId');
19277      if (!User.zip) {
19278        inventory.zipPrompt(function () {
19279          self.cartSelectStore(selectedStore);
19280        });
19281      } else {
19282        self.cartSelectStore(selectedStore);
19283      }
19284    });
19285    $('.item-delivery-options .delivery-option').on('click', function () {
19286      // reset the uuid
19287      var selectedStore = $(this).closest('.instore-delivery').find('.selected-store-address').data('storeId');
19288      self.uuid = $(this).closest('.cart-row').data('uuid');
19289      self.setDeliveryOption($(this).val(), selectedStore);
19290    });
19291  }
19292};
19293
19294module.exports = cartInventory;
19295
19296},{"./":73}],73:[function(require,module,exports){
19297'use strict';
19298
19299var _ = require('lodash'),
19300    dialog = require('../dialog'),
19301    TPromise = require('promise'),
19302    util = require('../util');
19303
19304var newLine = '\n';
19305var storeTemplate = function storeTemplate(store, selectedStoreId, selectedStoreText) {
19306  return ['<li class="store-tile ' + store.storeId + (store.storeId === selectedStoreId ? ' selected' : '') + '">
19306', '    <p class="store-address">', '        ' + store.address1 + '<br/>', '        ' + store.city + ', ' + store.stateCode + ' ' + store.postalCode, '    </p>', '    <p class="store-status" data-status="' + store.statusclass + '">' + store.status + '</p>', '    <button class="select-store-button" data-store-id="' + store.storeId + '"' + (store.statusclass !== 'store-in-stock' ? 'disabled="disabled"' : '') + '>', '        ' + (store.storeId === selectedStoreId ? selectedStoreText : Resources.SELECT_STORE), '    </button>', '</li>'].join(newLine);
19307};
19308
19309var storeListTemplate = function storeListTemplate(stores, selectedStoreId, selectedStoreText) {
19310  if (stores && stores.length) {
19311    return ['<div class="store-list-container">', '<ul class="store-list">', _.map(stores, function (store) {
19312      return storeTemplate(store, selectedStoreId, selectedStoreText);
19313    }).join(newLine), '</ul>', '</div>', '<div class="store-list-pagination">', '</div>'].join(newLine);
19314  } else {
19315    return '<div class="no-results">' + Resources.INVALID_ZIP + '</div>';
19316  }
19317};
19318
19319var zipPromptTemplate = function zipPromptTemplate() {
19320  return ['<div id="preferred-store-panel">', '    <input type="text" id="user-zip" placeholder="' + Resources.ENTER_ZIP + '" name="zipCode"/>', '</div>'].join(newLine);
19321};
19322
19323/**
19324 * @description test whether zipcode is valid for either US or Canada
19325 * @return {Boolean} true if the zipcode is valid for either country, false if it's invalid for both
19326 **/
19327var validateZipCode = function validateZipCode(zipCode) {
19328  var regexes = {
19329    canada: /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ]( )?\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i,
19330    usa: /^\d{5}(-\d{4})?$/
19331  },
19332      valid = false;
19333  if (!zipCode) {
19334    return;
19335  }
19336  _.each(regexes, function (re) {
19337    var regexp = new RegExp(re);
19338    valid = regexp.test(zipCode);
19339  });
19340  return valid;
19341};
19342
19343var storeinventory = {
19344  zipPrompt: function zipPrompt(callback) {
19345    var self = this;
19346    dialog.open({
19347      html: zipPromptTemplate(),
19348      options: {
19349        title: Resources.STORE_NEAR_YOU,
19350        width: 500,
19351        buttons: [{
19352          text: Resources.SEARCH,
19353          click: function click() {
19354            var zipCode = $('#user-zip').val();
19355            if (validateZipCode(zipCode)) {
19356              self.setUserZip(zipCode);
19357              if (callback) {
19358                callback(zipCode);
19359              }
19360            }
19361          }
19362        }],
19363        open: function open() {
19364          $('#user-zip').on('keypress', function (e) {
19365            if (e.which === 13) {
19366              // trigger the search button
19367              $('.ui-dialog-buttonset .ui-button').trigger('click');
19368            }
19369          });
19370        }
19371      }
19372    });
19373  },
19374  getStoresInventory: function getStoresInventory(pid) {
19375    return TPromise.resolve($.ajax({
19376      url: util.appendParamsToUrl(Urls.storesInventory, {
19377        pid: pid,
19378        zipCode: User.zip
19379      }),
19380      dataType: 'json'
19381    }));
19382  },
19383  /**
19384   * @description open the dialog to select store
19385   * @param {Array} options.stores
19386   * @param {String} options.selectedStoreId
19387   * @param {String} options.selectedStoreText
19388   * @param {Function} options.continueCallback
19389   * @param {Function} options.selectStoreCallback
19390   **/
19391  selectStoreDialog: function selectStoreDialog(options) {
19392    var self = this,
19393        stores = options.stores,
19394        selectedStoreId = options.selectedStoreId,
19395        selectedStoreText = options.selectedStoreText,
19396        storeList = storeListTemplate(stores, selectedStoreId, selectedStoreText);
19397    dialog.open({
19398      html: storeList,
19399      options: {
19400        title: Resources.SELECT_STORE + ' - ' + User.zip,
19401        buttons: [{
19402          text: Resources.CHANGE_LOCATION,
19403          click: function () {
19404            self.setUserZip(null);
19405            // trigger the event to start the process all over again
19406            $('.set-preferred-store').trigger('click');
19407          }.bind(this)
19408        }, {
19409          text: Resources.CONTINUE,
19410          click: function click() {
19411            if (options.continueCallback) {
19412              options.continueCallback(stores);
19413            }
19414            dialog.close();
19415          }
19416        }],
19417        open: function open() {
19418          $('.select-store-button').on('click', function (e) {
19419            e.preventDefault();
19420            var storeId = $(this).data('storeId');
19421            // if the store is already selected, don't select again
19422            if (storeId === selectedStoreId) {
19423              return;
19424            }
19425            $('.store-list .store-tile.selected').removeClass('selected').find('.select-store-button').text(Resources.SELECT_STORE);
19426            $(this).text(selectedStoreText).closest('.store-tile').addClass('selected');
19427            if (options.selectStoreCallback) {
19428              options.selectStoreCallback(storeId);
19429            }
19430          });
19431        }
19432      }
19433    });
19434  },
19435  setUserZip: function setUserZip(zip) {
19436    User.zip = zip;
19437    $.ajax({
19438      type: 'POST',
19439      url: Urls.setZipCode,
19440      data: {
19441        zipCode: zip
19442      }
19443    });
19444  },
19445  shippingLoad: function shippingLoad() {
19446    var $checkoutForm = $('.address');
19447    $checkoutForm.off('click');
19448    $checkoutForm.on('click', 'input[name$="_shippingAddress_isGift"]', function () {
19449      $(this).parent().siblings('.gift-message-text').toggleClass('hidden', $('input[name$="_shippingAddress_isGift"]:checked').val());
19450    });
19451  }
19452};
19453
19454module.exports = storeinventory;
19455
19456},{"../dialog":12,"../util":77,"lodash":111,"promise":121}],74:[function(require,module,exports){
19457'use strict';
19458
19459var _ = require('lodash'),
19460    inventory = require('./'),
19461    util = require('../util');
19462
19463var newLine = '\n';
19464var pdpStoreTemplate = function pdpStoreTemplate(store) {
19465  return ['<li class="store-list-item ' + (store.storeId === User.storeId ? ' selected' : '') + '">
19465', '    <div class="store-address">' + store.address1 + ', ' + store.city + ' ' + store.stateCode + ' ' + store.postalCode + '</div>', '    <div class="store-status" data-status="' + store.statusclass + '">' + store.status + '</div>', '</li>'].join(newLine);
19466};
19467var pdpStoresListingTemplate = function pdpStoresListingTemplate(stores) {
19468  if (stores && stores.length) {
19469    return ['<div class="store-list-pdp-container">', stores.length > 1 ? '    <a class="stores-toggle collapsed" href="#">' + Resources.SEE_MORE + '</a>' : '', '    <ul class="store-list-pdp">', _.map(stores, pdpStoreTemplate).join(newLine), '    </ul>', '</div>'].join(newLine);
19470  }
19471};
19472
19473var storesListing = function storesListing(stores) {
19474  // list all stores on PDP page
19475  if ($('.store-list-pdp-container').length) {
19476    $('.store-list-pdp-container').remove();
19477  }
19478  $('.availability-results').append(pdpStoresListingTemplate(stores));
19479};
19480
19481var productInventory = {
19482  setPreferredStore: function setPreferredStore(storeId) {
19483    User.storeId = storeId;
19484    $.ajax({
19485      url: Urls.setPreferredStore,
19486      type: 'POST',
19487      data: { storeId: storeId }
19488    });
19489  },
19490  productSelectStore: function productSelectStore() {
19491    var self = this;
19492    inventory.getStoresInventory(this.pid).then(function (stores) {
19493      inventory.selectStoreDialog({
19494        stores: stores,
19495        selectedStoreId: User.storeId,
19496        selectedStoreText: Resources.PREFERRED_STORE,
19497        continueCallback: storesListing,
19498        selectStoreCallback: self.setPreferredStore
19499      });
19500    }).done();
19501  },
19502  init: function init() {
19503    var $availabilityContainer = $('.availability-results'),
19504        self = this;
19505    this.pid = $('input[name="pid"]').val();
19506
19507    $('#product-content .set-preferred-store').on('click', function (e) {
19508      e.preventDefault();
19509      if (!User.zip) {
19510        inventory.zipPrompt(function () {
19511          self.productSelectStore();
19512        });
19513      } else {
19514        self.productSelectStore();
19515      }
19516    });
19517
19518    if ($availabilityContainer.length) {
19519      if (User.storeId) {
19520        inventory.getStoresInventory(this.pid).then(storesListing);
19521      }
19522
19523      // See more or less stores in the listing
19524      $availabilityContainer.on('click', '.stores-toggle', function (e) {
19525        e.preventDefault();
19526        $('.store-list-pdp .store-list-item').toggleClass('visible');
19527        if ($(this).hasClass('collapsed')) {
19528          $(this).text(Resources.SEE_LESS);
19529        } else {
19530          $(this).text(Resources.SEE_MORE);
19531        }
19532        $(this).toggleClass('collapsed');
19533      });
19534    }
19535
19536    if ($('.js-select-change_tab option').length == 0) {
19537      $('.cmd-select._auto').hide();
19538    }
19539  }
19540};
19541
19542module.exports = productInventory;
19543
19544$('#product-image-carousel').slick({
19545  dots: true,
19546  infinite: false,
19547  speed: 300,
19548  slidesToShow: 3,
19549  slidesToScroll: 3,
19550  responsive: [{
19551    breakpoint: 1024,
19552    settings: {
19553      slidesToShow: 3,
19554      slidesToScroll: 3,
19555      infinite: true,
19556      dots: true
19557    }
19558  }, {
19559    breakpoint: 600,
19560    settings: {
19561      slidesToShow: 2,
19562      slidesToScroll: 2
19563    }
19564  }, {
19565    breakpoint: 480,
19566    settings: {
19567      slidesToShow: 1,
19568      slidesToScroll: 1
19569    }
19570    // You can unslick at a given breakpoint now by adding:
19571    // settings: "unslick"
19572    // instead of a settings object
19573  }]
19574});
19575
19576$('#product-video-carousel').slick({
19577  dots: true,
19578  infinite: false,
19579  speed: 300,
19580  slidesToShow: 3,
19581  slidesToScroll: 3,
19582  responsive: [{
19583    breakpoint: 1024,
19584    settings: {
19585      slidesToShow: 3,
19586      slidesToScroll: 3,
19587      infinite: true,
19588      dots: true
19589    }
19590  }, {
19591    breakpoint: 600,
19592    settings: {
19593      slidesToShow: 2,
19594      slidesToScroll: 2
19595    }
19596  }, {
19597    breakpoint: 480,
19598    settings: {
19599      slidesToShow: 1,
19600      slidesToScroll: 1
19601    }
19602    // You can unslick at a given breakpoint now by adding:
19603    // settings: "unslick"
19604    // instead of a settings object
19605  }]
19606});
19607
19608},{"../util":77,"./":73,"lodash":111}],75:[function(require,module,exports){
19609'use strict';
19610
19611var util = require('./util');
19612
19613/**
19614 * Checks the TLS and displays a warning if appropriate
19615 * @function getUserAgent Checks the TLS and displays a warning if appropriate
19616 **/
19617function getUserAgent() {
19618  // Use an external service to check the TLS of the browser
19619  // NOTE: this implementation uses https://www.howsmyssl.com
19620  //     you may also wish to consider the API available at https://www.ssllabs.com/projects/ssllabs-apis/index.html
19621  var url = 'https://www.howsmyssl.com/a/check';
19622  var cookieName = 'dw_TLSWarning';
19623  var cookieValue = getCookie(cookieName);
19624
19625  // Test to see if this browser has already been flagged by looking at its cookies
19626  if (!cookieValue) {
19627    getTLS(url, function (message) {
19628      if (message.length > 0) {
19629        showWarning(message[0]);
19630
19631        // the browser is bad - set the cookie to true (for 15 minutes)
19632        util.setCookie(cookieName, 'true', 15);
19633      } else {
19634        // else the browser is good, set the cookie to false (for 30 days) so we don't check again
19635        util.setCookie(cookieName, 'false', 60 * 24 * 30);
19636      }
19637    });
19638  } else if (cookieValue === 'true') {
19639    // if we already know that this is an invalid browser, show the warning
19640    showWarning(Resources.TLS_WARNING);
19641  }
19642}
19643
19644/**
19645 * Calls out to the TLS service and calls the callback with a message (if necessary)
19646 * @function getTLS
19647 *
19648 * @param {string} url - URL of external TLS-checking API
19649 * @param {function} callback - function to call with response
19650 **/
19651function getTLS(url, callback) {
19652  var message = [];
19653
19654  // First, see if the browser is among the suspect browsers to see if a TLS check is necessary
19655  var userAgent = navigator.userAgent;
19656
19657  /** This list derived from https://www.ssllabs.com/ssltest/clients.html **/
19658  var badBrowsers = ['MSIE 6.0', 'MSIE 7.0', 'MSIE 8.0', 'MSIE 9.0', 'MSIE 10.0', 'Android 2.3.7', 'Android 4.0.4', 'Android 4.1.1', 'Android 4.2.2', 'Android 4.3', 'Safari 5.1.9 / OS X 10.6.8', 'Safari 6.0.4 / OS X 10.8.4 '];
19659  function checkTLSLevel(data) {
19660    // If we can determine the TLS level, check to see if it's less than 1.2
19661    if (parseFloat(data.tls_version.split(' ')[1]) < 1.1) {
19662      message.push(Resources.TLS_WARNING);
19663      callback(message);
19664
19665      //If you want to track statistics on bad TLS hits, include this call
19666      $.ajax({ url: Urls.TLSBadTLS });
19667    }
19668  }
19669
19670  function reportBadBrowser() {
19671    // If the TLS level cannot be determined just report that this browser is suspect
19672    message.push(Resources.TLS_WARNING);
19673    callback(message);
19674
19675    //If you want to track statistics on deprecated browsers, include this call
19676    $.ajax({ url: Urls.TLSBadBrowser });
19677  }
19678
19679  for (var i = 0; i < badBrowsers.length; i++) {
19680    if (userAgent.match(badBrowsers[i])) {
19681      // It's a suspect browser, let's see what it's TLS level is
19682      $.ajax({
19683        url: url
19684      }).done(checkTLSLevel).fail(reportBadBrowser);
19685      break;
19686    }
19687  }
19688
19689  /** For testing purposes, uncomment this block
19690        message.push(Resources.TLS_WARNING);
19691    **/
19692  callback(message);
19693}
19694
19695/**
19696 * @function showWarning turns on the browser-compatibility-alert and sets the message
19697 *
19698 * @param {string} message - the message that will be shown upon detection of a bad browser
19699 **/
19700function showWarning(message) {
19701  $('<div/>').addClass('browser-compatibility-alert').append($('<p/>').addClass('browser-error').html(message)).appendTo('#browser-check');
19702}
19703
19704/**
19705 * @function getCookie
19706 *
19707 * @param {string} key - The cookie name
19708 * @returns {string} value - the value of the cookie if found, null otherwise
19709 **/
19710function getCookie(key) {
19711  var cookies = document.cookie.split(';');
19712  for (var i = 0; i < cookies.length; i++) {
19713    var tokens = cookies[i].split('=');
19714    var cookieKey = tokens[0].trim();
19715    if (cookieKey === key) {
19716      return tokens[1];
19717    }
19718  }
19719  return '';
19720}
19721
19722/**
19723 * Export the getUserAgent function
19724 */
19725
19726exports.getUserAgent = getUserAgent;
19727
19728},{"./util":77}],76:[function(require,module,exports){
19729'use strict';
19730
19731/**
19732 * @function
19733 * @description Initializes the tooltip-content and layout
19734 */
19735
19736exports.init = function () {
19737  $(document).tooltip({
19738    items: '.tooltip',
19739    track: true,
19740    content: function content() {
19741      return $(this).find('.tooltip-content').html();
19742    }
19743  });
19744
19745  $('.share-link').on('click', function (e) {
19746    e.preventDefault();
19747    var target = $(this).data('target');
19748    if (!target) {
19749      return;
19750    }
19751    $(target).toggleClass('active');
19752  });
19753};
19754
19755},{}],77:[function(require,module,exports){
19756'use strict';
19757
19758var _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; };
19759
19760var _ = require('lodash');
19761var validator = require('./validator');
19762var util = {
19763  filterArr: function filterArr(arr) {
19764    var finishedArr = new Array();
19765
19766    arr.forEach(function (o) {
19767      if ((typeof o === 'undefined' ? 'undefined' : _typeof(o)) === 'object') {
19768        var finishedObj = new Object();
19769
19770        Object.keys(o).forEach(function (k) {
19771          if (!o[k]) {
19772            return;
19773          }
19774          finishedObj[k] = o[k];
19775        });
19776
19777        if (Object.keys(finishedObj).length > 0) {
19778          finishedArr.push(finishedObj);
19779        }
19780      } else if (!!o) {
19781        finishedArr.push(o);
19782      }
19783    });
19784
19785    return finishedArr;
19786  },
19787
19788  filterObj: function filterObj(o) {
19789    var finishedObj = {};
19790
19791    Object.keys(o).forEach(function (k) {
19792      if (!o[k]) {
19793        return;
19794      } else if (o[k] instanceof Array) {
19795        finishedObj[k] = this.filterArr(o[k]);
19796      } else {
19797        finishedObj[k] = o[k];
19798      }
19799    }, this);
19800
19801    return finishedObj;
19802  },
19803
19804  /**
19805   * @function
19806   * @description appends the parameter with the given name and value to the given url and returns the changed url
19807   * @param {String} url the url to which the parameter will be added
19808   * @param {String} name the name of the parameter
19809   * @param {String} value the value of the parameter
19810   */
19811  appendParamToURL: function appendParamToURL(url, name, value) {
19812    // quit if the param already exists
19813    if (url.indexOf(name + '=') !== -1) {
19814      return url;
19815    }
19816    var separator = url.indexOf('?') !== -1 ? '&' : '?';
19817
19818    return url + separator + name + '=' + encodeURIComponent(value);
19819  },
19820
19821  /**
19822   * @function
19823   * @description remove the parameter and its value from the given url and returns the changed url
19824   * @param {String} url the url from which the parameter will be removed
19825   * @param {String} name the name of parameter that will be removed from url
19826   */
19827  removeParamFromURL: function removeParamFromURL(url, name) {
19828    if (url.indexOf('?') === -1 || url.indexOf(name + '=') === -1) {
19829      return url;
19830    }
19831    var hash;
19832    var params;
19833    var domain = url.split('?')[0];
19834    var paramUrl = url.split('?')[1];
19835    var newParams = [];
19836    // if there is a hash at the end, store the hash
19837    if (paramUrl.indexOf('#') > -1) {
19838      hash = paramUrl.split('#')[1] || '';
19839      paramUrl = paramUrl.split('#')[0];
19840    }
19841    params = paramUrl.split('&');
19842    for (var i = 0; i < params.length; i++) {
19843      // put back param to newParams array if it is not the one to be removed
19844      if (params[i].split('=')[0] !== name) {
19845        newParams.push(params[i]);
19846      }
19847    }
19848    return domain + '?' + newParams.join('&') + (hash ? '#' + hash : '');
19849  },
19850
19851  /**
19852   * @function
19853   * @description appends the parameters to the given url and returns the changed url
19854   * @param {String} url the url to which the parameters will be added
19855   * @param {Object} params
19856   */
19857  appendParamsToUrl: function appendParamsToUrl(url, params) {
19858    var _url = url;
19859    _.each(params, function (value, name) {
19860      _url = this.appendParamToURL(_url, name, value);
19861    }.bind(this));
19862
19863    return _url;
19864  },
19865  /**
19866   * @function
19867   * @description extract the query string from URL
19868   * @param {String} url the url to extra query string from
19869   **/
19870  getQueryString: function getQueryString(url) {
19871    var qs;
19872    if (!_.isString(url)) {
19873      return;
19874    }
19875    var a = document.createElement('a');
19876    a.href = url;
19877    if (a.search) {
19878      qs = a.search.substr(1); // remove the leading ?
19879    }
19880    return qs;
19881  },
19882
19883  updateQueryStringParam: function updateQueryStringParam(url, paramName, newVal) {
19884    var _url = url;
19885
19886    if (_url.indexOf(paramName) === -1) {
19887      return _url;
19888    }
19889
19890    var newParamObj = new Object();
19891    newParamObj[paramName] = newVal;
19892
19893    _url = this.removeParamFromURL(_url, paramName);
19894    _url = this.appendParamsToUrl(_url, newParamObj);
19895
19896    return _url;
19897  },
19898
19899  getHashParam: function getHashParam(paramName) {
19900    var output = '';
19901
19902    var hashParams = window.location.hash.replace('#', '').split('&');
19903    for (var i = 0; i < hashParams.length; i++) {
19904      if (hashParams[i].indexOf(paramName) > -1) {
19905        output = hashParams[i].split('=')[1];
19906      }
19907    }
19908
19909    return output;
19910  },
19911
19912  /**
19913   * @function
19914   * @description
19915   * @param {String}
19916   * @param {String}
19917   */
19918  elementInViewport: function elementInViewport(el, offsetToTop) {
19919    var top = el.offsetTop,
19920        left = el.offsetLeft,
19921        width = el.offsetWidth,
19922        height = el.offsetHeight;
19923
19924    while (el.offsetParent) {
19925      el = el.offsetParent;
19926      top += el.offsetTop;
19927      left += el.offsetLeft;
19928    }
19929
19930    if (typeof offsetToTop !== 'undefined') {
19931      top -= offsetToTop;
19932    }
19933
19934    if (window.pageXOffset !== null) {
19935      return top < window.pageYOffset + window.innerHeight && left < window.pageXOffset + window.innerWidth && top + height > window.pageYOffset && left + width > window.pageXOffset;
19936    }
19937
19938    if (document.compatMode === 'CSS1Compat') {
19939      return top < window.document.documentElement.scrollTop + window.document.documentElement.clientHeight && left < window.document.documentElement.scrollLeft + window.document.documentElement.clientWidth && top + height > window.document.documentElement.scrollTop && left + width > window.document.documentElement.scrollLeft;
19940    }
19941  },
19942
19943  /**
19944   * @function
19945   * @description Appends the parameter 'format=ajax' to a given path
19946   * @param {String} path the relative path
19947   */
19948  ajaxUrl: function ajaxUrl(path) {
19949    return this.appendParamToURL(path, 'format', 'ajax');
19950  },
19951
19952  /**
19953   * @function
19954   * @description
19955   * @param {String} url
19956   */
19957  toAbsoluteUrl: function toAbsoluteUrl(url) {
19958    if (url.indexOf('http') !== 0 && url.charAt(0) !== '/') {
19959      url = '/' + url;
19960    }
19961    return url;
19962  },
19963  /**
19964   * @function
19965   * @description Loads css dynamically from given urls
19966   * @param {Array} urls Array of urls from which css will be dynamically loaded.
19967   */
19968  loadDynamicCss: function loadDynamicCss(urls) {
19969    var i,
19970        len = urls.length;
19971    for (i = 0; i < len; i++) {
19972      this.loadedCssFiles.push(this.loadCssFile(urls[i]));
19973    }
19974  },
19975
19976  /**
19977   * @function
19978   * @description Loads css file dynamically from given url
19979   * @param {String} url The url from which css file will be dynamically loaded.
19980   */
19981  loadCssFile: function loadCssFile(url) {
19982    return $('<link/>').appendTo($('head')).attr({
19983      type: 'text/css',
19984      rel: 'stylesheet'
19985    }).attr('href', url); // for i.e. <9, href must be added after link has been appended to head
19986  },
19987  // array to keep track of the dynamically loaded CSS files
19988  loadedCssFiles: [],
19989
19990  /**
19991   * @function
19992   * @description Removes all css files which were dynamically loaded
19993   */
19994  clearDynamicCss: function clearDynamicCss() {
19995    var i = this.loadedCssFiles.length;
19996    while (0 > i--) {
19997      $(this.loadedCssFiles[i]).remove();
19998    }
19999    this.loadedCssFiles = [];
20000  },
20001
20002  /**
20003   * @function
20004   * @description Extracts all parameters from a given query string into an object
20005   * @param {String} qs The query string from which the parameters will be extracted
20006   */
20007  getQueryStringParams: function getQueryStringParams(qs) {
20008    if (!qs || qs.length === 0) {
20009      return {};
20010    }
20011    var params = {},
20012        unescapedQS = decodeURIComponent(qs);
20013    // Use the String::replace method to iterate over each
20014    // name-value pair in the string.
20015    unescapedQS.replace(new RegExp('([^?=&]+)(=([^&]*))?', 'g'), function ($0, $1, $2, $3) {
20016      params[$1] = $3;
20017    });
20018    return params;
20019  },
20020
20021  fillAddressFields: function fillAddressFields(address, $form) {
20022    for (var field in address) {
20023      if (field === 'ID' || field === 'UUID' || field === 'key') {
20024        continue;
20025      }
20026      // if the key in address object ends with 'Code', remove that suffix
20027      // keys that ends with 'Code' are postalCode, stateCode and countryCode
20028      $form.find('[name$="' + field.replace('Code', '') + '"]').val(address[field]);
20029      // update the state fields
20030      if (field === 'countryCode') {
20031        $form.find('[name$="country"]').trigger('change');
20032        // retrigger state selection after country has changed
20033        // this results in duplication of the state code, but is a 
20033necessary evil
20034        // for now because sometimes countryCode comes after stateCode
20035        $form.find('[name$="state"]').val(address.stateCode);
20036      }
20037    }
20038  },
20039  /**
20040   * @function
20041   * @description Updates the number of the remaining character
20042   * based on the character limit in a text area
20043   */
20044  limitCharacters: function limitCharacters() {
20045    $('form').find('textarea[data-character-limit]').each(function () {
20046      var characterLimit = $(this).data('character-limit');
20047      var charCountHtml = String.format(Resources.CHAR_LIMIT_MSG, '<span class="countnow">0</span>', '<span class="countlimit">' + characterLimit + '</span>');
20048
20049      //if window size is small then char-count should be after
20050      var containerPlacement = $(this).prev('p.c-textarea-count');
20051      var containerInsert = $('<p class="c-textarea-count"/>').insertBefore($(this));
20052
20053      if ($(window).width() < 640) {
20054        containerPlacement = $(this).next('p.c-textarea-count');
20055        containerInsert = $('<p class="c-textarea-count"/>').insertAfter($(this));
20056      }
20057
20058      var charCountContainer = containerPlacement;
20059      if (charCountContainer.length === 0) {
20060        charCountContainer = containerInsert;
20061      }
20062      charCountContainer.html(charCountHtml);
20063      // trigger the keydown event so that any existing character data is calculated
20064      $(this).change();
20065    });
20066
20067    $('form').find('textarea[maxlength]').each(function () {
20068      if ($(this).data('character-limit') !== undefined || $(this).parent().find('.c-textarea-count').length) {
20069        return;
20070      }
20071      var characterLimit = $(this).attr('maxlength');
20072      var charCountHtml = String.format(Resources.CHAR_LIMIT_MSG_BOT, '<span class="countlimit">' + characterLimit + '</span>');
20073
20074      var containerPlacement = $(this).next('p.c-textarea-count');
20075      var containerInsert = $('<p class="c-textarea-count js-countDown is-bottom"/>').insertAfter($(this));
20076      var charCountContainer = containerPlacement;
20077      if (charCountContainer.length === 0) {
20078        charCountContainer = containerInsert;
20079      }
20080      charCountContainer.html(charCountHtml);
20081      // trigger the keydown event so that any existing character data is calculated
20082      $(this).change();
20083    });
20084  },
20085  /**
20086   * @function
20087   * @description Binds the onclick-event to a delete button on a given container,
20088   * which opens a confirmation box with a given message
20089   * @param {String} container The name of element to which the function will be bind
20090   * @param {String} message The message the will be shown upon a click
20091   */
20092  setDeleteConfirmation: function setDeleteConfirmation(container, message) {
20093    $(container).on('click', '.delete', function () {
20094      return window.confirm(message);
20095    });
20096  },
20097  /**
20098   * @function
20099   * @description Scrolls a browser window to a given x point
20100   * @param {String} The x coordinate
20101   */
20102  scrollBrowser: function scrollBrowser(xLocation) {
20103    $('html, body').animate({ scrollTop: xLocation }, 500);
20104  },
20105
20106  isMobile: function isMobile() {
20107    var mobileAgentHash = ['mobile', 'tablet', 'phone', 'ipad', 'ipod', 'android', 'blackberry', 'windows ce', 'opera mini', 'palm'];
20108    var idx = 0;
20109    var isMobile = false;
20110    var userAgent = navigator.userAgent.toLowerCase();
20111
20112    while (mobileAgentHash[idx] && !isMobile) {
20113      isMobile = userAgent.indexOf(mobileAgentHash[idx]) >= 0;
20114      idx++;
20115    }
20116    return isMobile;
20117  },
20118
20119  /**
20120   * @function getCookieSelector
20121   * @description Returns the cookie value
20122   **/
20123  getCookieSelector: function getCookieSelector(cookieName) {
20124    var regularExpression = '(?:(?:^|.*;\\s*)' + cookieName + '\\s*\\=\\s*([^;]*).*$)|^.*$';
20125    var regExp = new RegExp(regularExpression, '');
20126
20127    return document.cookie.replace(regExp, '$1');
20128  },
20129
20130  /**
20131   * @function setCookie
20132   *
20133   * @param {string} key - The cookie name
20134   * @param {string} value - The cookie value
20135   * @param {integer} minutes - The number of minutes to expire the cookie
20136   **/
20137  setCookie: function setCookie(key, value, minutes) {
20138    var duration = '';
20139
20140    if (minutes) {
20141      var date = new Date();
20142
20143      date.setTime(date.getTime() + minutes * 60 * 1000);
20144
20145      duration = ' expires=' + date.toGMTString() + ';';
20146    }
20147
20148    document.cookie = key + '=' + value + ';' + duration + ' path=/';
20149  },
20150
20151  /**
20152   * @function validateEmail
20153   *
20154   * @description Returns boolean
20155   * @param {string} emailAddress - The email address
20156   **/
20157  validateEmail: function validateEmail(emailAddress) {
20158    var emailRegExp = new RegExp('^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,3}$');
20159
20160    return emailRegExp.test(emailAddress);
20161  },
20162
20163  /**
20164   * @function validateMessage
20165   *
20166   * @description Returns boolean
20167   * @param {string} message - The message
20168   **/
20169  validateMessage: function validateMessage(message) {
20170    var country = 'other';
20171
20172    if (window.User.locale) {
20173      switch (window.User.locale) {
20174        case 'default':
20175        case 'en_SG':
20176        case 'en_ID':
20177        case 'en_MY':
20178          break;
20179        case 'en':
20180          country = 'int';
20181          break;
20182        default:
20183          country = window.User.locale.slice(-2).toLowerCase();
20184          break;
20185      }
20186    }
20187    var messageRegExp = validator.regex.message[country];
20188
20189    return messageRegExp.test(message);
20190  },
20191
20192  /**
20193   * @function maximizeCheckoutSummary
20194   *
20195   * @description Maximizes/Expands the Order Checkout Summary
20196   **/
20197  maximizeCheckoutSummary: function maximizeCheckoutSummary() {
20198    if (SitePreferences.IS_CHECKOUT_MAXIMIZED) {
20199      $('.accordion-navigation').addClass('is-active');
20200      $('.accordion-title').attr('aria-expanded', true);
20201      $('.accordion-title').attr('aria-selected', true);
20202      $('#panel11a').css('display', 'block');
20203    }
20204  }
20205};
20206
20207module.exports = util;
20208
20209},{"./validator":78,"lodash":111}],78:[function(require,module,exports){
20210'use strict';
20211
20212var formPrepare = require('./pages/checkout/formPrepare');
20213
20214var naPhone = /^\(?([2-9][0-8][0-9])\)?[\-\. ]?([2-9][0-9]{2})[\-\. ]?([0-9]{4})(\s*x[0-9]+)?$/;
20215var regex = {
20216  phone: {
20217    ca: /^\d{10}$/,
20218    hk: /^\d{8}$/,
20219    id: /^\d{10,11}$/,
20220    int: /^\d{1,30}$/,
20221    jp: /^\d{10,11}$/,
20222    kr: /^\d{10,11}$/,
20223    my: /^\d{10,11}$/,
20224    ru: /^\d{10}$/,
20225    sg: /^\d{8}$/,
20226    th: /^\d{9,10}$/,
20227    tw: /^\d{10}$/,
20228    vn: /^\d{10,11}$/,
20229    us: naPhone,
20230    fr: /^0[1-6]{1}(([0-9]{2}){4})|((\s[0-9]{2}){4})|((-[0-9]{2}){4})$/,
20231    it: /^(([0-9]{2,4})([-\s\/]{0,1})([0-9]{4,8}))?$/,
20232    cn: /.*/,
20233    gb: /^((\(?0\d{4}\)?\s?\d{3}\s?\d{3})|(\(?0\d{3}\)?\s?\d{3}\s?\d{4})|(\(?0\d{2}\)?\s?\d{4}\s?\d{4}))(\s?\#(\d{4}|\d{3}))?$/,
20234    other: /^\(?([0-9][0-8][0-9])\)?[\-\. ]?([2-9][0-9]{2})[\-\. ]?([0-9]{4})(\s*x[0-9]+)?$/
20235  },
20236  postal: {
20237    ca: /^([0-9]){6}$/,
20238    id: /^([0-9]){5}$/,
20239    jp: /^([0-9]){7}$/,
20240    kr: /^([0-9]){6}$/,
20241    my: /^([0-9]){5}$/,
20242    ru: /^([0-9]){6}$/,
20243    sg: /^([0-9]){6}$/,
20244    th: /^([0-9]){5}$/,
20245    tw: /^([0-9]){5}$/,
20246    vn: /^([0-9]){6}$/,
20247    us: /^\d{5}(-\d{4})?$/,
20248    fr: /^(F-)?((2[A|B])|[0-9]{2})[0-9]{3}$/,
20249    it: /^([0-9]){5}$/,
20250    cn: /^([0-9]){6}$/,
20251    gb: /^([A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? {1,2}[0-9][ABD-HJLN-UW-Z]{2}|GIR 0AA)$/,
20252    other: /^\d{5}
20252(-\d{4})?$/
20253  },
20254  name: {
20255    ca: /^[a-zA-ZÀ-ÿ ]+$/,
20256    hk: /^[豈-舘㐀-䶵一-鿏 ]+$/,
20257    kr: /^[ᄀ-ᇿㄱ-ㆎ가-힣 ]+$/,
20258    int: /.+/,
20259    jp: /^[一-龥ぁ-ゔァ-ヴー々〆〤]+$/,
20260    ru: /^[Ѐ-ӷ ]+$/,
20261    th: /^[ก-๛ ]+$/,
20262    tw: /^[豈-舘㐀-䶵一-鿏 ]+$/,
20263    vn: /^[ A-Za-z\xC0-\xC3\xC8-\xCA\xCC\xCD\xD2-\xD5\xD9\xDA\xE0-\xE3\xE8-\xEA\xEC\xED\xF2-\xF5\xF9\xFA\u0102\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01A0\u01A1\u01AF\u01B0\u1EA0-\u1EF9]+$/,
20264    other: /^[a-zA-Z\s.-]*$/
20265  },
20266  simpletext: {
20267    ca: /^[a-zA-ZÀ-ÿ 0-9-.,']+$/,
20268    hk: /^[豈-舘㐀-䶵一-鿏 0-9-.,']+$/,
20269    kr: /^[ᄀ-ᇿㄱ-ㆎ가-힣 0-9-.,']+$/,
20270    jp: /^[一-鿏ぁ-ゔァ-ヴー々〆〤 0-9-0-9-。、’]+$/,
20271    ru: /^[Ѐ-ӷ 0-9-.,']+$/,
20272    th: /^[ก-๛ 0-9-.,']+$/,
20273    tw: /^[豈-舘㐀-䶵一-鿏 0-9-.,']+$/,
20274    vn: /^[ ',-9A-Za-z\xC0-\xC3\xC8-\xCA\xCC\xCD\xD2-\xD5\xD9\xDA\xE0-\xE3\xE8-\xEA\xEC\xED\xF2-\xF5\xF9\xFA\u0102\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01A0\u01A1\u01AF\u01B0\u1EA0-\u1EF9]+$/,
20275    other: /^[0-9a-zA-Z .,'-]*$/
20276  },
20277  addr2regex: {
20278    ca: /^[a-zA-ZÀ-ÿa-zA-Z  0-9-0-9-.,'#]*$/,
20279    hk: /^[豈-舘㐀-䶵一-鿏a-zA-Za-zA-Z  0-9-0-9-.,'#]*$/,
20280    kr: /^[a-zA-Zᄀ-ᇿㄱ-ㆎ가-힣a-zA-Za-zA-Z  0-9-0-9-.,'#]*$/,
20281    jp: /^[一-鿏ぁ-ゔァ-ヴー々〆〤a-zA-Za-zA-Z  0-9-0-9-。、’#]*$/,
20282    ru: /^[Ѐ-ӷa-zA-Za-zA-Z  0-9-0-9-.,'#]*$/,
20283    th: /^[ก-๛a-zA-Za-zA-Z  0-9-0-9-.,'#]*$/,
20284    tw: /^[豈-舘㐀-䶵一-鿏a-zA-Za-zA-Z  0-9-0-9-.,'#]*$/,
20285    vn: /^[ #',-9A-Za-z\xC0-\xC3\xC8-\xCA\xCC\xCD\xD2-\xD5\xD9\xDA\xE0-\xE3\xE8-\xEA\xEC\xED\xF2-\xF5\xF9\xFA\u0102\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01A0\u01A1\u01AF\u01B0\u1EA0-\u1EF9\u3000\uFF0D\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A]*$/,
20286    other: /^[0-9a-zA-Z .,'#]*$/
20287  },
20288  message: {
20289    ca: /^[a-zA-ZÀ-ÿ 0-9-.,'!?;:()"\n]*$/,
20290    hk: /^[豈-舘㐀-䶵一-鿏 0-9-.,'!?;:()"\n]*$/,
20291    kr: /^[ᄀ-ᇿㄱ-ㆎ가-힣 0-9-.,'!?;:()"\n]*$/,
20292    int: /^[\s\S]*$/,
20293    jp: /^[一-鿏ぁ-ゔァ-ヴー々〆〤 0-9-0-9-。、’!?;:()”\n]*$/,
20294    ru: /^[Ѐ-ӷ 0-9-.,'!?;:()"\n]*$/,
20295    th: /^[ก-๛ 0-9-.,'!?;:()"\n]*$/,
20296    tw: /^[豈-舘㐀-䶵一-鿏 0-9-.,'!?;:()"\n]*$/,
20297    vn: /^[\n -"'-\),-\.0-;\?A-Za-z\xC0-\xC3\xC8-\xCA\xCC\xCD\xD2-\xD5\xD9\xDA\xDD\xE0-\xE3\xE8-\xEA\xEC\xED\xF2-\xF5\xF9\xFA\xFD\u0102\u0103\u0110\u0111\u0128\u0129\u0168\u0169\u01A0\u01A1\u01AF\u01B0\u1EA0-\u1EF9]*$/,
20298    other: /^[\w\.\,\!\?\;\:\(\)\'\" \n]*$/
20299  },
20300  notCC: /^(?!(([0-9 -]){13,19}))([a-zA-Z0-9 .-]*)$/,
20301  password: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,12}$/,
20302  email: /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$/i,
20303  hasPOBox: /[p]+(ost)*\.*\s*[o|0]+(ffice)*\.*\s*b[o|0]x/gi,
20304  ordernumber: /^[0-9a-z\s-\(\)#]*$/i,
20305  cvn: /^\d{3,4}$/,
20306  cvn_amex: /^\d{4}$/,
20307  cvn_visa: /^\d{3}$/,
20308  cvn_master: /^\d{3}$/,
20309  cvn_diners: /^\d{3}$/,
20310  cvn_union: /^\d{3}$/,
20311  alphanumeric: /^[a-z0-9]*$/i
20312};
20313var nameKana = /^[ァ-ヶー]+$/;
20314// global form validator settings
20315var settings = {
20316  errorClass: 'jquery-validation is-error',
20317  errorElement: 'p',
20318  onkeyup: false,
20319  onfocusout: function onfocusout(element) {
20320    if (!this.checkable(element) || element.className.indexOf('required') > -1) {
20321      this.element(element);
20322    }
20323
20324    // remove label error class
20325    if (!$(element).hasClass('is-error')) {
20326      // remove error message when no error
20327      if ($(element).parent().find('.c-text-error').length > 0) {
20328        $(element).parent().find('.c-text-error').remove();
20329      }
20330      if ($(element).parent().find('p[id="' + $(element).attr('id') + '-error"]').length > 0) {
20331        $(element).parent().find('p[id="' + $(element).attr('id') + '-error"]').remove();
20332      }
20333      if ($(element).parent('.c-input-group').length == 1) {
20334        $(element).parent().parent().children('.c-text-error').remove();
20335        $(element).parent().parent().children('.c-input-label').first().removeClass('is-error');
20336      }
20337      if ($(element).hasClass('pcemail') || $(element).hasClass('spemail')) {
20338        $(element).parent().find('.c-input-label').first().removeClass('is-error');
20339      } else if ($(element).prev().hasClass('c-input-label')) {
20340        $(element).prev().removeClass('is-error');
20341        if ($(element).parent().next().children().hasClass('jquery-validation is-error') && $(element).closest('.credit-card-account').length > 0) {
20342          // remove message validate on register payment account
20343          $(element).parent().next().remove();
20344        }
20345      } else if ($(element).parent().prev().hasClass('c-input-label') && $(element).closest('.credit-card-account').length > 0) {
20346        // remove tag content message validate on register payment account
20347        $(element).parent().prev().removeClass('is-error');
20348        if ($(element).closest('.c-col.c-col_08').next().children().hasClass('jquery-validation is-error')) {
20349          $(element).closest('.c-col.c-col_08').next().remove();
20350        }
20351      } else if ($(element).hasClass('c-input-box')) {
20352        if ($(element).closest('.shipping-address-checkout').length == 1) {
20353          //remove class is-error for shipping address of checkout page
20354          $(element).closest('.cmd-form_box').find('p.cmd-form_ttl').removeClass('is-error');
20355        } else {
20356          $(element).parent().parent().prev().removeClass('is-error');
20357        }
20358      } else if ($(element).parents('.cmd-form_box').length === 1) {
20359        if ($(element).parents('.cmd-form_input').length === 1) {
20360          $(element).parent().prev().removeClass('is-error');
20361        } else if ($(element).closest('.shipping-address-checkout').length == 1) {
20362          // remove class is error for label select box state on shipping address page
20363          $(element).closest('.cmd-form_box').find('p.cmd-form_ttl').removeClass('is-error');
20364        } else {
20365          $(element).prev().removeClass('is-error');
20366        }
20367      } else {
20368        $(element).parent().parent().prev().removeClass('is-error');
20369      }
20370    } else {
20371      // add label error class
20372      if ($(element).hasClass('pcemail') || $(element).hasClass('spemail')) {
20373        $(element).parent().find('.c-input-label').first().addClass('is-error');
20374      } else if ($(element).prev().hasClass('c-input-label')) {
20375        $(element).prev().addClass('is-error');
20376      } else if ($(element).hasClass('c-input-box') && $(element).closest('.shipping-address-checkout').length == 1) {
20377        // add label error class for shipping address on checkout shipping page
20378        $(element).closest('.cmd-form_box').find('p.cmd-form_ttl').addClass('is-error');
20379      } else if ($(element).hasClass('c-input-box')) {
20380        $(element).parent().parent().prev().addClass('is-error');
20381      } else if ($(element).parents('.cmd-form_box').length === 1) {
20382        if ($(element).parents('.cmd-form_input').length === 1) {
20383          $(element).parent().prev().addClass('is-error');
20384        } else {
20385          $(element).prev().addClass('is-error');
20386        }
20387      } else {
20388        $(element).parent().parent().prev().addClass('is-error');
20389      }
20390    }
20391  },
20392  errorPlacement: function errorPlacement(error, element) {
20393    // insert error message
20394    if ($(element).prop('type') === 'checkbox') {
20395      error.insertAfter($(element).parent());
20396    } else if ($(element).parent('.c-input-group').length == 1) {
20397      if ($(element).parent().parent().find('.c-text-error').length == 0) {
20398        error.insertAfter($(element).parent());
20399      } else {
20400        $(element).parent().parent().find('.c-text-error').remove();
20401        error.insertAfter($(element).parent());
20402      }
20403    } else if (element.parents('.cmd-form_box').length === 1) {
20404      error.insertAfter(element.parent());
20405    } else if (element.closest('.credit-card-account').length > 0) {
20406      if (element.closest('.c-input-group--card').length > 0) {
20407        error.insertAfter($(element).parent().parent()).wrap('<li class="c-col c-col_08" />');
20408      } else {
20409        error.insertAfter($(element).parent()).wrap('<li class="c-col c-col_08" />');
20410      }
20411    } else {
20412      if ($(element).parent().find('.c-text-error').length == 0) {
20413        if ($(element).parents('form.news-letter-form .ge-footer-connectWithUs-check').length) {
20414          error.insertAfter($(element).next());
20415        } else {
20416          if (element.prev('p.c-input-label').length === 0) {
20417            element.parent().parent().prev().addClass('is-error');
20418          } else if (element.attr('name').indexOf('passwordconfirm') > -1) {
20419            element.prev().addClass('is-error');
20420          }
20421          error.insertAfter($(element));
20422        }
20423      } else {
20424        $(element).parent().find('.c-text-error').remove();
20425        error.insertAfter($(element));
20426      }
20427    }
20428    // add class error for ul tag
20429    if ($(element).closest($('form.news-letter-form')).length == 1) {
20430      error.addClass('c-text-error');
20431    } else if ($(element).attr('id') == 'dwfrm_profile_tempcustomer_email' || $(element).attr('id') == 'dwfrm_profile_tempcustomer_emailconfirm' || $(element).attr('id') == 'dwfrm_contactus_comment' || $(element).attr('id') == 'dwfrm_requestpassword_email' || $(element).attr('id') == 'dwfrm_requestpassword_postal' || $(element).closest('#RegistrationForm').length > 0 || $(element).closest('#ChangeUsername').length > 0 || $(element).closest('#ChangePasswordForm').length > 0 || $(element).closest('.credit-card-account').length > 0 || $(element).closest('#OmotionAuthForm').length > 0) {
20432      error.addClass('c-input-label');
20433    } else {
20434      error.addClass('c-text-error c-text-error--simple');
20435    }
20436    // add class error for label
20437    if (element.closest('.credit-card-account').length > 0) {
20438      // add label error class for register payment on account - payment page
20439      error.parent().prev().children('p.c-input-label').addClass('is-error');
20440    } else if (element.closest('.shipping-address-checkout').length == 1) {
20441      // add label error class for shipping address on check out shipping page
20442      $(element).closest('.cmd-form_box').find('p.cmd-form_ttl').addClass('is-error');
20443    } else {
20444      error.parent().find('.c-input-label').first().addClass('is-error');
20445    }
20446    // clear error message when has `no-display-error` attribute in the field
20447    if (error.parent().find('input[no-display-error]').length > 0) {
20448      error.remove();
20449    }
20450  },
20451  ignore: ':hidden, .ignore'
20452};
20453
20454/**
20455 * @function
20456 * @description Validates a given credit card if it has the correct format
20457 * @param {String} value of credit card which will be validated
20458 */
20459var luhnCheck = function (arr) {
20460  return function (ccNum) {
20461    // luhn check only in production.
20462    if (Constants.INSTANCE_TYPE != Constants.INSTANCE_TYPE_PRODUCTION) {
20463      return true;
20464    }
20465    var len = ccNum.length;
20466    var bit = 1;
20467    var sum = 0;
20468    var val;
20469
20470    while (len) {
20471      val = parseInt(ccNum.charAt(--len), 10);
20472      sum += (bit ^= 1) ? arr[val] : val;
20473    }
20474
20475    return sum && sum % 10 === 0;
20476  };
20477}([0, 2, 4, 6, 8, 1, 3, 5, 7, 9]);
20478
20479/**
20480 * @function
20481 * @description Determine the current country
20482 * @param {String} el The input field
20483 * @param {Object} regex The type of regex
20484 */
20485function findSelectedCountry(el, regex) {
20486  var selectedCountry = 'other';
20487  var country = 'sg';
20488
20489  if (window.User.locale) {
20490    switch (window.User.locale) {
20491      case 'default':
20492        break;
20493      case 'en':
20494        country = 'int';
20495        break;
20496      default:
20497        country = window.User.locale.slice(-2).toLowerCase();
20498        break;
20499    }
20500  }
20501
20502  if (regex[country]) {
20503    selectedCountry = country;
20504  }
20505  return selectedCountry;
20506}
20507
20508/**
20509 * @function
20510 * @description Validates that a credit card owner is not a Credit card number
20511 * @param {String} value The owner field which will be validated
20512 * @param {String} el The input field
20513 */
20514var validateOwner = function validateOwner(value) {
20515  var isValid = regex.notCC.test($.trim(value));
20516  return isValid;
20517};
20518
20519/**
20520 * Add CCOwner validation method to jQuery validation plugin.
20521 * Text fields must have 'owner' css class to be validated as not a credit card
20522 */
20523$.validator.addMethod('owner', validateOwner, Resources.INVALID_OWNER);
20524
20525/**
20526 * Add Alphanumeric method to jQuery validation plugin.
20527 * Text fields must have 'alphanumeric' css class to be validated.
20528 */
20529$.validator.addMethod('alphanumeric', function (value) {
20530  var isValid = regex.alphanumeric.test($.trim(value));
20531  return isValid;
20532}, simpleTextMessage);
20533
20534/**
20535 * Add gift cert amount validation method to jQuery validation plugin.
20536 * Text fields must have 'gift-cert-amont' css class to be validated
20537 */
20538$.validator.addMethod('gift-cert-amount', function (value, el) {
20539  var isOptional = this.optional(el);
20540  var isValid = !isNaN(value) && parseFloat(value) >= 5 && parseFloat(value) <= 5000;
20541  return isOptional || isValid;
20542}, Resources.GIFT_CERT_AMOUNT_INVALID);
20543
20544/**
20545 * Add positive number validation method to jQuery validation plugin.
20546 * Text fields must have 'positivenumber' css class to be validated as positivenumber
20547 */
20548$.validator.addMethod('positivenumber', function (value) {
20549  if ($.trim(value).length === 0) {
20550    return true;
20551  }
20552  return !isNaN(value) && Number(value) >= 0;
20553}, ''); // '' should be replaced with error message if needed
20554
20555/**
20556 * Add CC number validation method to jQuery validation plugin.
20557 * Text fields must have 'number' css class to be validated
20558 */
20559$.validator.addMethod('number', function (value) {
20560  // number == Credit card number
20561  var isValid = luhnCheck($.trim(value));
20562  return isValid;
20563}, Resources.VALIDATE_CREDIT_NUMBER);
20564
20565/**
20566 * Add CVN number validation method to jQuery validation plugin.
20567 * Text fields must have 'cvn' css class to be validated
20568 */
20569$.validator.addMethod('cvn', function (value, el) {
20570  // Visa
20571  var visa_regex = new RegExp('^4[0-9]{0,15}$'),
20572
20573  // MasterCard
20574  mastercard_regex = new RegExp('^5$|^5[1-5][0-9]{0,14}$'),
20575
20576  // American Express
20577  amex_regex = new RegExp('^3$|^3[47][0-9]{0,13}$'),
20578
20579  // Diners 300-305,3095,36,38-39
20580  diners_regex = new RegExp('^(30[0-5]\\d{11}|3095\\d{10}|36\\d{12}|3[8-9]\\d{12})$'),
20581
20582  // UnionPay
20583  unionpay_regex = new RegExp('^62[0-9]{0,14}$|^645[0-9]{0,13}$|^65[0-9]{0,14}$');
20584
20585  var isValid = false;
20586  var $form = $(el).closest('form');
20587  var cur_val = $form.find('input[name$="_number"]').val();
20588
20589  // get rid of spaces and dashes before using the regular expression
20590  cur_val = cur_val.replace(/ /g, '').replace(/-/g, '');
20591
20592  if (cur_val.match(visa_regex)) {
20593    isValid = regex.cvn_visa.test($.trim(value));
20594  } else if (cur_val.match(mastercard_regex)) {
20595    isValid = regex.cvn_master.test($.trim(value));
20596  } else if (cur_val.match(amex_regex)) {
20597    isValid = regex.cvn_amex.test($.trim(value));
20598  } else if (cur_val.match(diners_regex)) {
20599    isValid = regex.cvn_diners.test($.trim(value));
20600  } else if (cur_val.match(unionpay_regex)) {
20601    isValid = regex.cvn_union.test($.trim(value));
20602  } else {
20603    isValid = regex.cvn.test($.trim(value));
20604  }
20605
20606  return isValid;
20607}, Resources.VALIDATE_CVN);
20608
20609/**
20610 * Add Order number validation method to jQuery validation plugin.
20611 * Text fields must have 'ordernumber' css class to be validated
20612 */
20613$.validator.addMethod('ordernumber', function (value) {
20614  var isValid = regex.ordernumber.test($.trim(value));
20615  return isValid;
20616}, Resources.INVALID_ORDER_NUMBER);
20617
20618/**
20619 * Add equal value validation method to jQuery validation plugin.
20620 * Text fields must have 'equal-to' css class to be validated
20621 */
20622$.validator.addMethod('equal-to', function (value, el) {
20623  var equalTo = $(el).attr('equal-to');
20624  var $equalToEl = $(el).closest('form').find(equalTo);
20625
20626  return value === $equalToEl.val();
20627}, function (value, el) {
20628  var message = $(el).attr('data-required-text');
20629  return message || Resources.VALIDATE_EQUALTO;
20630});
20631
20632$.validator.addMethod('regexp', function (value, el) {
20633  var pattern = $(el).attr('pattern');
20634  if (!pattern || !$(el).val()) {
20635    return true;
20636  }
20637  var re = new RegExp(pattern);
20638  return re.test($.trim(value));
20639}, function (value, el) {
20640  return $(el).attr('data-parse-error-text') || Resources.VALIDATE_REGEXP;
20641});
20642
20643// Validators for multi-field relations.
20644
20645var addressFormNames = ['state', 'city', 'address1', 'address2', 'address3'];
20646var primaryAddressFormNames = ['state', 'city', 'address1'];
20647
20648function validateAddress(value) {
20649  var primaryAddresses = primaryAddressFormNames.map(function (name) {
20650    return $('[name$="_' + name + '"]');
20651  });
20652
20653  var allAddresses = addressFormNames.map(function (name) {
20654    return $('[name$="_' + name + '"]');
20655  }).filter(function ($item) {
20656    return $item.length > 0;
20657  });
20658
20659  if (allAddresses.some(function ($item) {
20660    return $item.val();
20661  })) {
20662    return value && value.length > 0 || primaryAddresses.every(function ($item) {
20663      return $item.val();
20664    });
20665  }
20666
20667  return true;
20668}
20669
20670function validateAddressForDM(value) {
20671  var addToDMListElement = $('[name$="_addtodirectmaillist"]');
20672  if (addToDMListElement.data('home-address-fullfilled') !== undefined) {
20673    return addToDMListElement.data('home-address-fullfilled') || !addToDMListElement.prop('checked');
20674  }
20675  var primaryAddresses = primaryAddressFormNames.map(function (name) {
20676    return $('[name$="_' + name + '"]');
20677  });
20678  if (addToDMListElement.length > 0 && addToDMListElement.prop('checked')) {
20679    return value && value.length > 0 || primaryAddresses.every(function ($item) {
20680      return $item.val();
20681    });
20682  }
20683  return true;
20684}
20685
20686function validateConfirm(value, el, param) {
20687  var $form = $(el).closest('form');
20688  var actualValueSelector = param.dynamic ? 'input[name*="_' + param.actual + '_"]' : 'input[name$="_' + param.actual + '"]';
20689  var actualValue = $form.find(actualValueSelector).val();
20690  return actualValue === value;
20691}
20692
20693function requireOther(value, el, param) {
20694  var $form = $(el).closest('form');
20695  var $target = param.target ? $form.find('[name$="_' + param.target + '"]') : $(el);
20696  if (param.source) {
20697    var valueExists = param.source.some(function (src) {
20698      var $source = $form.find('[name$="_' + src.name + '"]');
20699      return src.value && src.value === $source.val() || $source.prop('checked');
20700    });
20701    return !valueExists || $target.val();
20702  }
20703  if (param.value && param.value === $(el).val() || $(el).prop('checked')) {
20704    return $target.val();
20705  }
20706  return true;
20707}
20708
20709/**
20710 * Modify password validation method of jQuery validation plugin.
20711 * Text fields must have 'password' css class to be validated.
20712 */
20713$.validator.addMethod('create-password', function (value) {
20714  //Not same as local part of email address
20715  if ($(this.currentForm).find('input[name$="_email"]').length > 0) {
20716    if ($('input[name$="_email"]').val().split('@')[0].indexOf(value) > -1) {
20717      return false;
20718    }
20719  }
20720  return true;
20721}, Resources.VALIDATE_PASSWORD);
20722
20723$.validator.addMethod('addressForDM', validateAddressForDM, Resources.VALIDATE_ADDRESS_FOR_DM);
20724$.validator.addMethod('primaryAddress', validateAddress, Resources.VALIDATE_ADDRESS);
20725$.validator.addMethod('confirmValue', validateConfirm, Resources.VALIDATE_EQUALTO);
20726$.validator.addMethod('requireOther', requireOther, function (value, el) {
20727  var message = $(el).attr('data-require-other-text');
20728  return message || Resources.VALIDATE_REQUIRE_OTHER;
20729});
20730
20731$.validator.addClassRules('addtodirectmaillist', { addressForDM: true });
20732$.validator.addClassRules('state', {
20733  addressForDM: true,
20734  primaryAddress: true
20735});
20736$.validator.addClassRules('city', { addressForDM: true, primaryAddress: true });
20737$.validator.addClassRules('address1', {
20738  addressForDM: true,
20739  primaryAddress: true
20740});
20741$.validator.addClassRules('emailconfirm', {
20742  confirmValue: { actual: 'email' }
20743});
20744$.validator.addClassRules('pcemailconfirm', {
20745  confirmValue: { actual: 'pcemail' }
20746});
20747$.validator.addClassRules('spemailconfirm', {
20748  confirmValue: { actual: 'spemail' }
20749});
20750$.validator.addClassRules('passwordconfirm', {
20751  confirmValue: { actual: 'password', dynamic: true }
20752});
20753$.validator.addClassRules('newpasswordconfirm', {
20754  confirmValue: { actual: 'newpassword', dynamic: true }
20755});
20756$.validator.addClassRules('spemail', {
20757  requireOther: {
20758    source: [{ name: 'mobilemailmagazine' }, { name: 'useemail', value: '2' }]
20759  }
20760});
20761$.validator.addClassRules('mobilemailmagazine', {
20762  requireOther: { target: 'spemail' }
20763});
20764$.validator.addClassRules('useemail', {
20765  requireOther: { target: 'spemail', value: '2' }
20766});
20767
20768var requiredMessage = function requiredMessage(value, el) {
20769  var message = $(el).attr('data-required-text');
20770  return message || Resources.VALIDATE_REQUIRED;
20771};
20772
20773var simpleTextMessage = function simpleTextMessage(value, el) {
20774  var message = $(el).attr('data-required-text');
20775  return message || Resources.VALIDATE_REQUIRED;
20776};
20777
20778var passwordMessage = function passwordMessage(value, el) {
20779  var message = $(el).attr('data-required-text');
20780  return message || Resources.VALIDATE_PASSWORD;
20781};
20782
20783$.extend($.validator.messages, {
20784  required: Resources.VALIDATE_REQUIRED,
20785  remote: Resources.VALIDATE_REMOTE,
20786  email: Resources.VALIDATE_EMAIL,
20787  address1: Resources.ADDRESS_PO_BOX_ERROR,
20788  password: passwordMessage,
20789  url: Resources.VALIDATE_URL,
20790  date: Resources.VALIDATE_DATE,
20791  dateISO: Resources.VALIDATE_DATEISO,
20792  number: Resources.VALIDATE_CREDIT_NUMBER,
20793  digits: Resources.VALIDATE_DIGITS,
20794  creditcard: Resources.VALIDATE_CREDITCARD,
20795  equalTo: Resources.VALIDATE_EQUALTO,
20796  maxlength: $.validator.format(Resources.VALIDATE_MAXLENGTH),
20797  minlength: $.validator.format(Resources.VALIDATE_MINLENGTH),
20798  rangelength: $.validator.format(Resources.VALIDATE_RANGELENGTH),
20799  range: $.validator.format(Resources.VALIDATE_RANGE),
20800  max: $.validator.format(Resources.VALIDATE_MAX),
20801  min: $.validator.format(Resources.VALIDATE_MIN),
20802  postal: Resources.INVALID_ZIP,
20803  message: Resources.INVALID_MESSAGE,
20804  fullname: simpleTextMessage,
20805  simpletext: simpleTextMessage,
20806  alphanumeric: simpleTextMessage
20807});
20808// Updated code to populate green tick check if the password meets the requirements.
20809var validator = {
20810  regex: regex,
20811  settings: settings,
20812  init: function init() {
20813    var _self = this;
20814    $('form:not(.suppress)').each(function () {
20815      _self.initForm(this);
20816    });
20817  },
20818  initForm: function initForm(f) {
20819    var _self = this;
20820    var $form = $(f);
20821    var $submitForm = $form.find('button[type="submit"], input[type="submit"]').not('.ignore');
20822    var fp = formPrepare();
20823    fp.init({
20824      formSelector: $form,
20825      continueSelector: $submitForm
20826    }, _self.settings);
20827  }
20828};
20829
20830module.exports = validator;
20831
20832},{"./pages/checkout/formPrepare":36}],79:[function(require,module,exports){
20833'use strict';
20834
20835var modal = require('./modal').global;
20836
20837module.exports = {
20838  init: function init(cb) {
20839    if (typeof window.YT !== 'undefined') {
20840      if (cb !== undefined) {
20841        return cb();
20842      } else {
20843        return;
20844      }
20845    }
20846
20847    window.onYouTubeIframeAPIReady = cb;
20848
20849    // load youtube iframe api
20850    var tag = document.createElement('script');
20851
20852    tag.async = true;
20853    tag.src = 'https://www.youtube.com/iframe_api';
20854
20855    var firstScriptTag = document.getElementsByTagName('script')[0];
20856    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
20857  },
20858
20859  playInline: function playInline($ele, videoId) {
20860    var eleId = $ele.attr('id');
20861    if (!eleId || !videoId) {
20862      return;
20863    }
20864
20865    new YT.Player(eleId, {
20866      videoId: videoId,
20867      width: $ele.width(),
20868      height: $ele.height(),
20869      playerVars: { rel: 0 },
20870      events: {
20871        onReady: function onReady(evt) {
20872          var player = evt.target;
20873          player.playVideo();
20874        }
20875      }
20876    });
20877  },
20878
20879  playInModal: function playInModal(videoId) {
20880    if (!videoId) {
20881      return;
20882    }
20883
20884    modal.setContent('<div class="responsive-embed"><div id="video-player"></div></div>');
20885
20886    new YT.Player('video-player', {
20887      videoId: videoId,
20888      events: {
20889        onReady: function onReady(evt) {
20890          var player = evt.target;
20891          modal.events.onOpen(function () {
20892            var modalBodyWidth = $('.modal-body').width();
20893            //$("#video-player").width(modalBodyWidth);
20894            player.playVideo();
20895          });
20896          modal.events.onClose(function () {
20897            player.destroy();
20898          });
20899          modal.open();
20900        }
20901      }
20902    });
20903  }
20904};
20905
20906},{"./modal":24}],80:[function(require,module,exports){
20907"use strict";
20908
20909// rawAsap provides everything we need except exception management.
20910var rawAsap = require("./raw");
20911// RawTasks are recycled to reduce GC churn.
20912var freeTasks = [];
20913// We queue errors to ensure they are thrown in right order (FIFO).
20914// Array-as-queue is good enough here, since we are just dealing with exceptions.
20915var pendingErrors = [];
20916var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);
20917
20918function throwFirstError() {
20919    if (pendingErrors.length) {
20920        throw pendingErrors.shift();
20921    }
20922}
20923
20924/**
20925 * Calls a task as soon as possible after returning, in its own event, with priority
20926 * over other events like animation, reflow, and repaint. An error thrown from an
20927 * event will not interrupt, nor even substantially slow down the processing of
20928 * other events, but will be rather postponed to a lower priority event.
20929 * @param {{call}} task A callable object, typically a function that takes no
20930 * arguments.
20931 */
20932module.exports = asap;
20933function asap(task) {
20934    var rawTask;
20935    if (freeTasks.length) {
20936        rawTask = freeTasks.pop();
20937    } else {
20938        rawTask = new RawTask();
20939    }
20940    rawTask.task = task;
20941    rawAsap(rawTask);
20942}
20943
20944// We wrap tasks with recyclable task objects.  A task object implements
20945// `call`, just like a function.
20946function RawTask() {
20947    this.task = null;
20948}
20949
20950// The sole purpose of wrapping the task is to catch the exception and recycle
20951// the task object after its single use.
20952RawTask.prototype.call = function () {
20953    try {
20954        this.task.call();
20955    } catch (error) {
20956        if (asap.onerror) {
20957            // This hook exists purely for testing purposes.
20958            // Its name will be periodically randomized to break any code that
20959            // depends on its existence.
20960            asap.onerror(error);
20961        } else {
20962            // In a web browser, exceptions are not fatal. However, to avoid
20963            // slowing down the queue of pending tasks, we rethrow the error in a
20964            // lower priority turn.
20965            pendingErrors.push(error);
20966            requestErrorThrow();
20967        }
20968    } finally {
20969        this.task = null;
20970        freeTasks[freeTasks.length] = this;
20971    }
20972};
20973
20974},{"./raw":81}],81:[function(require,module,exports){
20975(function (global){
20976"use strict";
20977
20978// Use the fastest means possible to execute a task in its own turn, with
20979// priority over other events including IO, animation, reflow, and redraw
20980// events in browsers.
20981//
20982// An exception thrown by a task will permanently interrupt the processing of
20983// subsequent tasks. The higher level `asap` function ensures that if an
20984// exception is thrown by a task, that the task queue will continue flushing as
20985// soon as possible, but if you use `rawAsap` directly, you are responsible to
20986// either ensure that no exceptions are thrown from your task, or to manually
20987// call `rawAsap.requestFlush` if an exception is thrown.
20988module.exports = rawAsap;
20989function rawAsap(task) {
20990    if (!queue.length) {
20991        requestFlush();
20992        flushing = true;
20993    }
20994    // Equivalent to push, but avoids a function call.
20995    queue[queue.length] = task;
20996}
20997
20998var queue = [];
20999// Once a flush has been requested, no further calls to `requestFlush` are
21000// necessary until the next `flush` completes.
21001var flushing = false;
21002// `requestFlush` is an implementation-specific method that attempts to kick
21003// off a `flush` event as quickly as possible. `flush` will attempt to exhaust
21004// the event queue before yielding to the browser's own event loop.
21005var requestFlush;
21006// The position of the next task to execute in the task queue. This is
21007// preserved between calls to `flush` so that it can be resumed if
21008// a task throws an exception.
21009var index = 0;
21010// If a task schedules additional tasks recursively, the task queue can grow
21011// unbounded. To prevent memory exhaustion, the task queue will periodically
21012// truncate already-completed tasks.
21013var capacity = 1024;
21014
21015// The flush function processes all tasks that have been scheduled with
21016// `rawAsap` unless and until one of those tasks throws an exception.
21017// If a task throws an exception, `flush` ensures that its state will remain
21018// consistent and will resume where it left off when called again.
21019// However, `flush` does not make any arrangements to be called again if an
21020// exception is thrown.
21021function flush() {
21022    while (index < queue.length) {
21023        var currentIndex = index;
21024        // Advance the index before calling the task. This ensures that we will
21025        // begin flushing on the next task the task throws an error.
21026        index = index + 1;
21027        queue[currentIndex].call();
21028        // Prevent leaking memory for long chains of recursive calls to `asap`.
21029        // If we call `asap` within tasks scheduled by `asap`, the queue will
21030        // grow, but to avoid an O(n) walk for every task we execute, we don't
21031        // shift tasks off the queue after they have been executed.
21032        // Instead, we periodically shift 1024 tasks off the queue.
21033        if (index > capacity) {
21034            // Manually shift all values starting at the index back to the
21035            // beginning of the queue.
21036            for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
21037                queue[scan] = queue[scan + index];
21038            }
21039            queue.length -= index;
21040            index = 0;
21041        }
21042    }
21043    queue.length = 0;
21044    index = 0;
21045    flushing = false;
21046}
21047
21048// `requestFlush` is implemented using a strategy based on data collected from
21049// every available SauceLabs Selenium web driver worker at time of writing.
21050// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593
21051
21052// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
21053// have WebKitMutationObserver but not un-prefixed MutationObserver.
21054// Must use `global` or `self` instead of `window` to work in both frames and web
21055// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
21056
21057/* globals self */
21058var scope = typeof global !== "undefined" ? global : self;
21059var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
21060
21061// MutationObservers are desirable because they have high priority and work
21062// reliably everywhere they are implemented.
21063// They are implemented in all modern browsers.
21064//
21065// - Android 4-4.3
21066// - Chrome 26-34
21067// - Firefox 14-29
21068// - Internet Explorer 11
21069// - iPad Safari 6-7.1
21070// - iPhone Safari 7-7.1
21071// - Safari 6-7
21072if (typeof BrowserMutationObserver === "function") {
21073    requestFlush = makeRequestCallFromMutationObserver(flush);
21074
21075// MessageChannels are desirable because they give direct access to the HTML
21076// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
21077// 11-12, and in web workers in many engines.
21078// Although message channels yield to any queued rendering and IO tasks, they
21079// would be better than imposing the 4ms delay of timers.
21080// However, they do not work reliably in Internet Explorer or Safari.
21081
21082// Internet Explorer 10 is the only browser that has setImmediate but does
21083// not have MutationObservers.
21084// Although setImmediate yields to the browser's renderer, it would be
21085// preferrable to falling back to setTimeout since it does not have
21086// the minimum 4ms penalty.
21087// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (
21087and
21088// Desktop to a lesser extent) that renders both setImmediate and
21089// MessageChannel useless for the purposes of ASAP.
21090// https://github.com/kriskowal/q/issues/396
21091
21092// Timers are implemented universally.
21093// We fall back to timers in workers in most engines, and in foreground
21094// contexts in the following browsers.
21095// However, note that even this simple case requires nuances to operate in a
21096// broad spectrum of browsers.
21097//
21098// - Firefox 3-13
21099// - Internet Explorer 6-9
21100// - iPad Safari 4.3
21101// - Lynx 2.8.7
21102} else {
21103    requestFlush = makeRequestCallFromTimer(flush);
21104}
21105
21106// `requestFlush` requests that the high priority event queue be flushed as
21107// soon as possible.
21108// This is useful to prevent an error thrown in a task from stalling the event
21109// queue if the exception handled by Node.js’s
21110// `process.on("uncaughtException")` or by a domain.
21111rawAsap.requestFlush = requestFlush;
21112
21113// To request a high priority event, we induce a mutation observer by toggling
21114// the text of a text node between "1" and "-1".
21115function makeRequestCallFromMutationObserver(callback) {
21116    var toggle = 1;
21117    var observer = new BrowserMutationObserver(callback);
21118    var node = document.createTextNode("");
21119    observer.observe(node, {characterData: true});
21120    return function requestCall() {
21121        toggle = -toggle;
21122        node.data = toggle;
21123    };
21124}
21125
21126// The message channel technique was discovered by Malte Ubl and was the
21127// original foundation for this library.
21128// http://www.nonblocking.io/2011/06/windownexttick.html
21129
21130// Safari 6.0.5 (at least) intermittently fails to create message ports on a
21131// page's first load. Thankfully, this version of Safari supports
21132// MutationObservers, so we don't need to fall back in that case.
21133
21134// function makeRequestCallFromMessageChannel(callback) {
21135//     var channel = new MessageChannel();
21136//     channel.port1.onmessage = callback;
21137//     return function requestCall() {
21138//         channel.port2.postMessage(0);
21139//     };
21140// }
21141
21142// For reasons explained above, we are also unable to use `setImmediate`
21143// under any circumstances.
21144// Even if we were, there is another bug in Internet Explorer 10.
21145// It is not sufficient to assign `setImmediate` to `requestFlush` because
21146// `setImmediate` must be called *by name* and therefore must be wrapped in a
21147// closure.
21148// Never forget.
21149
21150// function makeRequestCallFromSetImmediate(callback) {
21151//     return function requestCall() {
21152//         setImmediate(callback);
21153//     };
21154// }
21155
21156// Safari 6.0 has a problem where timers will get lost while the user is
21157// scrolling. This problem does not impact ASAP because Safari 6.0 supports
21158// mutation observers, so that implementation is used instead.
21159// However, if we ever elect to use timers in Safari, the prevalent work-around
21160// is to add a scroll event listener that calls for a flush.
21161
21162// `setTimeout` does not call the passed callback if the delay is less than
21163// approximately 7 in web workers in Firefox 8 through 18, and sometimes not
21164// even then.
21165
21166function makeRequestCallFromTimer(callback) {
21167    return function requestCall() {
21168        // We dispatch a timeout with a specified delay of 0 for engines that
21169        // can reliably accommodate that request. This will usually be snapped
21170        // to a 4 milisecond delay, but once we're flushing, there's no delay
21171        // between events.
21172        var timeoutHandle = setTimeout(handleTimer, 0);
21173        // However, since this timer gets frequently dropped in Firefox
21174        // workers, we enlist an interval handle that will try to fire
21175        // an event 20 times per second until it succeeds.
21176        var intervalHandle = setInterval(handleTimer, 50);
21177
21178        function handleTimer() {
21179            // Whichever timer succeeds will cancel both timers and
21180            // execute the callback.
21181            clearTimeout(timeoutHandle);
21182            clearInterval(intervalHandle);
21183            callback();
21184        }
21185    };
21186}
21187
21188// This is for `asap.js` only.
21189// Its name will be periodically randomized to break any code that depends on
21190// its existence.
21191rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;
21192
21193// ASAP was originally a nextTick shim included in Q. This was factored out
21194// into this ASAP package. It was later adapted to RSVP which made further
21195// amendments. These decisions, particularly to marginalize MessageChannel and
21196// to capture the MutationObserver implementation in a closure, were integrated
21197// back into ASAP proper.
21198// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
21199
21200}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
21201},{}],82:[function(require,module,exports){
21202'use strict';
21203
21204var bind = require('function-bind');
21205
21206var $apply = require('./functionApply');
21207var $call = require('./functionCall');
21208var $reflectApply = require('./reflectApply');
21209
21210/** @type {import('./actualApply')} */
21211module.exports = $reflectApply || bind.call($call, $apply);
21212
21213},{"./functionApply":83,"./functionCall":84,"./reflectApply":86,"function-bind":100}],83:[function(require,module,exports){
21214'use strict';
21215
21216/** @type {import('./functionApply')} */
21217module.exports = Function.prototype.apply;
21218
21219},{}],84:[function(require,module,exports){
21220'use strict';
21221
21222/** @type {import('./functionCall')} */
21223module.exports = Function.prototype.call;
21224
21225},{}],85:[function(require,module,exports){
21226'use strict';
21227
21228var bind = require('function-bind');
21229var $TypeError = require('es-errors/type');
21230
21231var $call = require('./functionCall');
21232var $actualApply = require('./actualApply');
21233
21234/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */
21235module.exports = function callBindBasic(args) {
21236	if (args.length < 1 || typeof args[0] !== 'function') {
21237		throw new $TypeError('a function is required');
21238	}
21239	return $actualApply(bind, $call, args);
21240};
21241
21242},{"./actualApply":82,"./functionCall":84,"es-errors/type":95,"function-bind":100}],86:[function(require,module,exports){
21243'use strict';
21244
21245/** @type {import('./reflectApply')} */
21246module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply;
21247
21248},{}],87:[function(require,module,exports){
21249'use strict';
21250
21251var GetIntrinsic = require('get-intrinsic');
21252
21253var callBindBasic = require('call-bind-apply-helpers');
21254
21255/** @type {(thisArg: string, searchString: string, position?: number) => number} */
21256var $indexOf = callBindBasic([GetIntrinsic('%String.prototype.indexOf%')]);
21257
21258/** @type {import('.')} */
21259module.exports = function callBoundIntrinsic(name, allowMissing) {
21260	/* eslint no-extra-parens: 0 */
21261
21262	var intrinsic = /** @type {(this: unknown, ...args: unknown[]) => unknown} */ (GetIntrinsic(name, !!allowMissing));
21263	if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
21264		return callBindBasic(/** @type {const} */ ([intrinsic]));
21265	}
21266	return intrinsic;
21267};
21268
21269},{"call-bind-apply-helpers":85,"get-intrinsic":101}],88:[function(require,module,exports){
21270'use strict';
21271
21272var callBind = require('call-bind-apply-helpers');
21273var gOPD = require('gopd');
21274
21275var hasProtoAccessor;
21276try {
21277	// eslint-disable-next-line no-extra-parens, no-proto
21278	hasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */ ([]).__proto__ === Array.prototype;
21279} catch (e) {
21280	if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') {
21281		throw e;
21282	}
21283}
21284
21285// eslint-disable-next-line no-extra-parens
21286var desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__'));
21287
21288var $Object = Object;
21289var $getPrototypeOf = $Object.getPrototypeOf;
21290
21291/** @type {import('./get')} */
21292module.exports = desc && typeof desc.get === 'function'
21293	? callBind([desc.get])
21294	: typeof $getPrototypeOf === 'function'
21295		? /** @type {import('./get')} */ function getDunder(value) {
21296			// eslint-disable-next-line eqeqeq
21297			return $getPrototypeOf(value == null ? value : $Object(value));
21298		}
21299		: false;
21300
21301},{"call-bind-apply-helpers":85,"gopd":106}],89:[function(require,module,exports){
21302'use strict';
21303
21304/** @type {import('.')} */
21305var $defineProperty = Object.defineProperty || false;
21306if ($defineProperty) {
21307	try {
21308		$defineProperty({}, 'a', { value: 1 });
21309	} catch (e) {
21310		// IE 8 has a broken defineProperty
21311		$defineProperty = false;
21312	}
21313}
21314
21315module.exports = $defineProperty;
21316
21317},{}],90:[function(require,module,exports){
21318'use strict';
21319
21320/** @type {import('./eval')} */
21321module.exports = EvalError;
21322
21323},{}],91:[function(require,module,exports){
21324'use strict';
21325
21326/** @type {import('.')} */
21327module.exports = Error;
21328
21329},{}],92:[function(require,module,exports){
21330'use strict';
21331
21332/** @type {import('./range')} */
21333module.exports = RangeError;
21334
21335},{}],93:[function(require,module,exports){
21336'use strict';
21337
21338/** @type {import('./ref')} */
21339module.exports = ReferenceError;
21340
21341},{}],94:[function(require,module,exports){
21342'use strict';
21343
21344/** @type {import('./syntax')} */
21345module.exports = SyntaxError;
21346
21347},{}],95:[function(require,module,exports){
21348'use strict';
21349
21350/** @type {import('./type')} */
21351module.exports = TypeError;
21352
21353},{}],96:[function(require,module,exports){
21354'use strict';
21355
21356/** @type {import('./uri')} */
21357module.exports = URIError;
21358
21359},{}],97:[function(require,module,exports){
21360'use strict';
21361
21362/** @type {import('.')} */
21363module.exports = Object;
21364
21365},{}],98:[function(require,module,exports){
21366/**
21367 * EvEmitter v1.1.0
21368 * Lil' event emitter
21369 * MIT License
21370 */
21371
21372/* jshint unused: true, undef: true, strict: true */
21373
21374( function( global, factory ) {
21375  // universal module definition
21376  /* jshint strict: false */ /* globals define, module, window */
21377  if ( typeof define == 'function' && define.amd ) {
21378    // AMD - RequireJS
21379    define( factory );
21380  } else if ( typeof module == 'object' && module.exports ) {
21381    // CommonJS - Browserify, Webpack
21382    module.exports = factory();
21383  } else {
21384    // Browser globals
21385    global.EvEmitter = factory();
21386  }
21387
21388}( typeof window != 'undefined' ? window : this, function() {
21389
21390"use strict";
21391
21392function EvEmitter() {}
21393
21394var proto = EvEmitter.prototype;
21395
21396proto.on = function( eventName, listener ) {
21397  if ( !eventName || !listener ) {
21398    return;
21399  }
21400  // set events hash
21401  var events = this._events = this._events || {};
21402  // set listeners array
21403  var listeners = events[ eventName ] = events[ eventName ] || [];
21404  // only add once
21405  if ( listeners.indexOf( listener ) == -1 ) {
21406    listeners.push( listener );
21407  }
21408
21409  return this;
21410};
21411
21412proto.once = function( eventName, listener ) {
21413  if ( !eventName || !listener ) {
21414    return;
21415  }
21416  // add event
21417  this.on( eventName, listener );
21418  // set once flag
21419  // set onceEvents hash
21420  var onceEvents = this._onceEvents = this._onceEvents || {};
21421  // set onceListeners object
21422  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
21423  // set flag
21424  onceListeners[ listener ] = true;
21425
21426  return this;
21427};
21428
21429proto.off = function( eventName, listener ) {
21430  var listeners = this._events && this._events[ eventName ];
21431  if ( !listeners || !listeners.length ) {
21432    return;
21433  }
21434  var index = listeners.indexOf( listener );
21435  if ( index != -1 ) {
21436    listeners.splice( index, 1 );
21437  }
21438
21439  return this;
21440};
21441
21442proto.emitEvent = function( eventName, args ) {
21443  var listeners = this._events && this._events[ eventName ];
21444  if ( !listeners || !listeners.length ) {
21445    return;
21446  }
21447  // copy over to avoid interference if .off() in listener
21448  listeners = listeners.slice(0);
21449  args = args || [];
21450  // once stuff
21451  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
21452
21453  for ( var i=0; i < listeners.length; i++ ) {
21454    var listener = listeners[i]
21455    var isOnce = onceListeners && onceListeners[ listener ];
21456    if ( isOnce ) {
21457      // remove listener
21458      // remove before trigger to prevent recursion
21459      this.off( eventName, listener );
21460      // unset once flag
21461      delete onceListeners[ listener ];
21462    }
21463    // trigger listener
21464    listener.apply( this, args );
21465  }
21466
21467  return this;
21468};
21469
21470proto.allOff = function() {
21471  delete this._events;
21472  delete this._onceEvents;
21473};
21474
21475return EvEmitter;
21476
21477}));
21478
21479},{}],99:[function(require,module,exports){
21480'use strict';
21481
21482/* eslint no-invalid-this: 1 */
21483
21484var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
21485var toStr = Object.prototype.toString;
21486var max = Math.max;
21487var funcType = '[object Function]';
21488
21489var concatty = function concatty(a, b) {
21490    var arr = [];
21491
21492    for (var i = 0; i < a.length; i += 1) {
21493        arr[i] = a[i];
21494    }
21495    for (var j = 0; j < b.length; j += 1) {
21496        arr[j + a.length] = b[j];
21497    }
21498
21499    return arr;
21500};
21501
21502var slicy = function slicy(arrLike, offset) {
21503    var arr = [];
21504    for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) {
21505        arr[j] = arrLike[i];
21506    }
21507    return arr;
21508};
21509
21510var joiny = function (arr, joiner) {
21511    var str = '';
21512    for (var i = 0; i < arr.length; i += 1) {
21513        str += arr[i];
21514        if (i + 1 < arr.length) {
21515            str += joiner;
21516        }
21517    }
21518    return str;
21519};
21520
21521module.exports = function bind(that) {
21522    var target = this;
21523    if (typeof target !== 'function' || toStr.apply(target) !== funcType) {
21524        throw new TypeError(ERROR_MESSAGE + target);
21525    }
21526    var args = slicy(arguments, 1);
21527
21528    var bound;
21529    var binder = function () {
21530        if (this instanceof bound) {
21531            var result = target.apply(
21532                this,
21533                concatty(args, arguments)
21534            );
21535            if (Object(result) === result) {
21536                return result;
21537            }
21538            return this;
21539        }
21540        return target.apply(
21541            that,
21542            concatty(args, arguments)
21543        );
21544
21545    };
21546
21547    var boundLength = max(0, target.length - args.length);
21548    var boundArgs = [];
21549    for (var i = 0; i < boundLength; i++) {
21550        boundArgs[i] = '$' + i;
21551    }
21552
21553    bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder);
21554
21555    if (target.prototype) {
21556        var Empty = function Empty() {};
21557        Empty.prototype = target.prototype;
21558        bound.prototype = new Empty();
21559        Empty.prototype = null;
21560    }
21561
21562    return bound;
21563};
21564
21565},{}],100:[function(require,module,exports){
21566'use strict';
21567
21568var implementation = require('./implementation');
21569
21570module.exports = Function.prototype.bind || implementation;
21571
21572},{"./implementation":99}],101
vendor: 6,095 bytes, lines 21572-21719
21572:[function(require,module,exports){
21573'use strict';
21574
21575var undefined;
21576
21577var $Object = require('es-object-atoms');
21578
21579var $Error = require('es-errors');
21580var $EvalError = require('es-errors/eval');
21581var $RangeError = require('es-errors/range');
21582var $ReferenceError = require('es-errors/ref');
21583var $SyntaxError = require('es-errors/syntax');
21584var $TypeError = require('es-errors/type');
21585var $URIError = require('es-errors/uri');
21586
21587var abs = require('math-intrinsics/abs');
21588var floor = require('math-intrinsics/floor');
21589var max = require('math-intrinsics/max');
21590var min = require('math-intrinsics/min');
21591var pow = require('math-intrinsics/pow');
21592var round = require('math-intrinsics/round');
21593var sign = require('math-intrinsics/sign');
21594
21595var $Function = Function;
21596
21597// eslint-disable-next-line consistent-return
21598var getEvalledConstructor = function (expressionSyntax) {
21599	try {
21600		return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
21601	} catch (e) {}
21602};
21603
21604var $gOPD = require('gopd');
21605var $defineProperty = require('es-define-property');
21606
21607var throwTypeError = function () {
21608	throw new $TypeError();
21609};
21610var ThrowTypeError = $gOPD
21611	? (function () {
21612		try {
21613			// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
21614			arguments.callee; // IE 8 does not throw here
21615			return throwTypeError;
21616		} catch (calleeThrows) {
21617			try {
21618				// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
21619				return $gOPD(arguments, 'callee').get;
21620			} catch (gOPDthrows) {
21621				return throwTypeError;
21622			}
21623		}
21624	}())
21625	: throwTypeError;
21626
21627var hasSymbols = require('has-symbols')();
21628
21629var getProto = require('get-proto');
21630var $ObjectGPO = require('get-proto/Object.getPrototypeOf');
21631var $ReflectGPO = require('get-proto/Reflect.getPrototypeOf');
21632
21633var $apply = require('call-bind-apply-helpers/functionApply');
21634var $call = require('call-bind-apply-helpers/functionCall');
21635
21636var needsEval = {};
21637
21638var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);
21639
21640var INTRINSICS = {
21641	__proto__: null,
21642	'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
21643	'%Array%': Array,
21644	'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
21645	'%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,
21646	'%AsyncFromSyncIteratorPrototype%': undefined,
21647	'%AsyncFunction%': needsEval,
21648	'%AsyncGenerator%': needsEval,
21649	'%AsyncGeneratorFunction%': needsEval,
21650	'%AsyncIteratorPrototype%': needsEval,
21651	'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
21652	'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
21653	'%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,
21654	'%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,
21655	'%Boolean%': Boolean,
21656	'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
21657	'%Date%': Date,
21658	'%decodeURI%': decodeURI,
21659	'%decodeURIComponent%': decodeURIComponent,
21660	'%encodeURI%': encodeURI,
21661	'%encodeURIComponent%': encodeURIComponent,
21662	'%Error%': $Error,
21663	'%eval%': eval, // eslint-disable-line no-eval
21664	'%EvalError%': $EvalError,
21665	'%Float16Array%': typeof Float16Array === 'undefined' ? undefined : Float16Array,
21666	'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
21667	'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
21668	'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
21669	'%Function%': $Function,
21670	'%GeneratorFunction%': needsEval,
21671	'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
21672	'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
21673	'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
21674	'%isFinite%': isFinite,
21675	'%isNaN%': isNaN,
21676	'%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,
21677	'%JSON%': typeof JSON === 'object' ? JSON : undefined,
21678	'%Map%': typeof Map === 'undefined' ? undefined : Map,
21679	'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),
21680	'%Math%': Math,
21681	'%Number%': Number,
21682	'%Object%': $Object,
21683	'%Object.getOwnPropertyDescriptor%': $gOPD,
21684	'%parseFloat%': parseFloat,
21685	'%parseInt%': parseInt,
21686	'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
21687	'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
21688	'%RangeError%': $RangeError,
21689	'%ReferenceError%': $ReferenceError,
21690	'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
21691	'%RegExp%': RegExp,
21692	'%Set%': typeof Set === 'undefined' ? undefined : Set,
21693	'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),
21694	'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
21695	'%String%': String,
21696	'%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,
21697	'%Symbol%': hasSymbols ? Symbol : undefined,
21698	'%SyntaxError%': $SyntaxError,
21699	'%ThrowTypeError%': ThrowTypeError,
21700	'%TypedArray%': TypedArray,
21701	'%TypeError%': $TypeError,
21702	'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
21703	'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
21704	'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
21705	'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
21706	'%URIError%': $URIError,
21707	'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
21708	'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
21709	'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet,
21710
21711	'%Function.prototype.call%': $call,
21712	'%Function.prototype.apply%': $apply,
21713	'%Object.defineProperty%': $defineProperty,
21714	'%Object.getPrototypeOf%': $ObjectGPO,
21715	'%Math.abs%': abs,
21716	'%Math.floor%': floor,
21717	'%Math.max%': max,
21718	'%Math.min%': min,
21719	'%Math.pow%': pow,
vendor: 8,380 bytes, lines 21720-21950
21720	'%Math.round%': round,
21721	'%Math.sign%': sign,
21722	'%Reflect.getPrototypeOf%': $ReflectGPO
21723};
21724
21725if (getProto) {
21726	try {
21727		null.error; // eslint-disable-line no-unused-expressions
21728	} catch (e) {
21729		// https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229
21730		var errorProto = getProto(getProto(e));
21731		INTRINSICS['%Error.prototype%'] = errorProto;
21732	}
21733}
21734
21735var doEval = function doEval(name) {
21736	var value;
21737	if (name === '%AsyncFunction%') {
21738		value = getEvalledConstructor('async function () {}');
21739	} else if (name === '%GeneratorFunction%') {
21740		value = getEvalledConstructor('function* () {}');
21741	} else if (name === '%AsyncGeneratorFunction%') {
21742		value = getEvalledConstructor('async function* () {}');
21743	} else if (name === '%AsyncGenerator%') {
21744		var fn = doEval('%AsyncGeneratorFunction%');
21745		if (fn) {
21746			value = fn.prototype;
21747		}
21748	} else if (name === '%AsyncIteratorPrototype%') {
21749		var gen = doEval('%AsyncGenerator%');
21750		if (gen && getProto) {
21751			value = getProto(gen.prototype);
21752		}
21753	}
21754
21755	INTRINSICS[name] = value;
21756
21757	return value;
21758};
21759
21760var LEGACY_ALIASES = {
21761	__proto__: null,
21762	'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
21763	'%ArrayPrototype%': ['Array', 'prototype'],
21764	'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
21765	'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
21766	'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
21767	'%ArrayProto_values%': ['Array', 'prototype', 'values'],
21768	'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
21769	'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
21770	'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
21771	'%BooleanPrototype%': ['Boolean', 'prototype'],
21772	'%DataViewPrototype%': ['DataView', 'prototype'],
21773	'%DatePrototype%': ['Date', 'prototype'],
21774	'%ErrorPrototype%': ['Error', 'prototype'],
21775	'%EvalErrorPrototype%': ['EvalError', 'prototype'],
21776	'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
21777	'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
21778	'%FunctionPrototype%': ['Function', 'prototype'],
21779	'%Generator%': ['GeneratorFunction', 'prototype'],
21780	'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
21781	'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
21782	'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
21783	'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
21784	'%JSONParse%': ['JSON', 'parse'],
21785	'%JSONStringify%': ['JSON', 'stringify'],
21786	'%MapPrototype%': ['Map', 'prototype'],
21787	'%NumberPrototype%': ['Number', 'prototype'],
21788	'%ObjectPrototype%': ['Object', 'prototype'],
21789	'%ObjProto_toString%': ['Object', 'prototype', 'toString'],
21790	'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
21791	'%PromisePrototype%': ['Promise', 'prototype'],
21792	'%PromiseProto_then%': ['Promise', 'prototype', 'then'],
21793	'%Promise_all%': ['Promise', 'all'],
21794	'%Promise_reject%': ['Promise', 'reject'],
21795	'%Promise_resolve%': ['Promise', 'resolve'],
21796	'%RangeErrorPrototype%': ['RangeError', 'prototype'],
21797	'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
21798	'%RegExpPrototype%': ['RegExp', 'prototype'],
21799	'%SetPrototype%': ['Set', 'prototype'],
21800	'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
21801	'%StringPrototype%': ['String', 'prototype'],
21802	'%SymbolPrototype%': ['Symbol', 'prototype'],
21803	'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
21804	'%TypedArrayPrototype%': ['TypedArray', 'prototype'],
21805	'%TypeErrorPrototype%': ['TypeError', 'prototype'],
21806	'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
21807	'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
21808	'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
21809	'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
21810	'%URIErrorPrototype%': ['URIError', 'prototype'],
21811	'%WeakMapPrototype%': ['WeakMap', 'prototype'],
21812	'%WeakSetPrototype%': ['WeakSet', 'prototype']
21813};
21814
21815var bind = require('function-bind');
21816var hasOwn = require('hasown');
21817var $concat = bind.call($call, Array.prototype.concat);
21818var $spliceApply = bind.call($apply, Array.prototype.splice);
21819var $replace = bind.call($call, String.prototype.replace);
21820var $strSlice = bind.call($call, String.prototype.slice);
21821var $exec = bind.call($call, RegExp.prototype.exec);
21822
21823/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
21824var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
21825var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
21826var stringToPath = function stringToPath(string) {
21827	var first = $strSlice(string, 0, 1);
21828	var last = $strSlice(string, -1);
21829	if (first === '%' && last !== '%') {
21830		throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
21831	} else if (last === '%' && first !== '%') {
21832		throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
21833	}
21834	var result = [];
21835	$replace(string, rePropName, function (match, number, quote, subString) {
21836		result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
21837	});
21838	return result;
21839};
21840/* end adaptation */
21841
21842var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
21843	var intrinsicName = name;
21844	var alias;
21845	if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
21846		alias = LEGACY_ALIASES[intrinsicName];
21847		intrinsicName = '%' + alias[0] + '%';
21848	}
21849
21850	if (hasOwn(INTRINSICS, intrinsicName)) {
21851		var value = INTRINSICS[intrinsicName];
21852		if (value === needsEval) {
21853			value = doEval(intrinsicName);
21854		}
21855		if (typeof value === 'undefined' && !allowMissing) {
21856			throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
21857		}
21858
21859		return {
21860			alias: alias,
21861			name: intrinsicName,
21862			value: value
21863		};
21864	}
21865
21866	throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
21867};
21868
21869module.exports = function GetIntrinsic(name, allowMissing) {
21870	if (typeof name !== 'string' || name.length === 0) {
21871		throw new $TypeError('intrinsic name must be a non-empty string');
21872	}
21873	if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
21874		throw new $TypeError('"allowMissing" argument must be a boolean');
21875	}
21876
21877	if ($exec(/^%?[^%]*%?$/, name) === null) {
21878		throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');
21879	}
21880	var parts = stringToPath(name);
21881	var intrinsicBaseName = parts.length > 0 ? parts[0] : '';
21882
21883	var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
21884	var intrinsicRealName = intrinsic.name;
21885	var value = intrinsic.value;
21886	var skipFurtherCaching = false;
21887
21888	var alias = intrinsic.alias;
21889	if (alias) {
21890		intrinsicBaseName = alias[0];
21891		$spliceApply(parts, $concat([0, 1], alias));
21892	}
21893
21894	for (var i = 1, isOwn = true; i < parts.length; i += 1) {
21895		var part = parts[i];
21896		var first = $strSlice(part, 0, 1);
21897		var last = $strSlice(part, -1);
21898		if (
21899			(
21900				(first === '"' || first === "'" || first === '`')
21901				|| (last === '"' || last === "'" || last === '`')
21902			)
21903			&& first !== last
21904		) {
21905			throw new $SyntaxError('property names with quotes must have matching quotes');
21906		}
21907		if (part === 'constructor' || !isOwn) {
21908			skipFurtherCaching = true;
21909		}
21910
21911		intrinsicBaseName += '.' + part;
21912		intrinsicRealName = '%' + intrinsicBaseName + '%';
21913
21914		if (hasOwn(INTRINSICS, intrinsicRealName)) {
21915			value = INTRINSICS[intrinsicRealName];
21916		} else if (value != null) {
21917			if (!(part in value)) {
21918				if (!allowMissing) {
21919					throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
21920				}
21921				return void undefined;
21922			}
21923			if ($gOPD && (i + 1) >= parts.length) {
21924				var desc = $gOPD(value, part);
21925				isOwn = !!desc;
21926
21927				// By convention, when a data property is converted to an accessor
21928				// property to emulate a data property that does not suffer from
21929				// the override mistake, that accessor's getter is marked with
21930				// an `originalValue` property. Here, when we detect this, we
21931				// uphold the illusion by pretending to see that original data
21932				// property, i.e., returning the value rather than the getter
21933				// itself.
21934				if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
21935					value = desc.get;
21936				} else {
21937					value = value[part];
21938				}
21939			} else {
21940				isOwn = hasOwn(value, part);
21941				value = value[part];
21942			}
21943
21944			if (isOwn && !skipFurtherCaching) {
21945				INTRINSICS[intrinsicRealName] = value;
21946			}
21947		}
21948	}
21949	return value;
21950};
vendor: 3,776 bytes, lines 21951-22054
21951
21952},{"call-bind-apply-helpers/functionApply":83,"call-bind-apply-helpers/functionCall":84,"es-define-property":89,"es-errors":91,"es-errors/eval":90,"es-errors/range":92,"es-errors/ref":93,"es-errors/syntax":94,"es-errors/type":95,"es-errors/uri":96,"es-object-atoms":97,"function-bind":100,"get-proto":104,"get-proto/Object.getPrototypeOf":102,"get-proto/Reflect.getPrototypeOf":103,"gopd":106,"has-symbols":107,"hasown":109,"math-intrinsics/abs":112,"math-intrinsics/floor":113,"math-intrinsics/max":115,"math-intrinsics/min":116,"math-intrinsics/pow":117,"math-intrinsics/round":118,"math-intrinsics/sign":119}],102:[function(require,module,exports){
21953'use strict';
21954
21955var $Object = require('es-object-atoms');
21956
21957/** @type {import('./Object.getPrototypeOf')} */
21958module.exports = $Object.getPrototypeOf || null;
21959
21960},{"es-object-atoms":97}],103:[function(require,module,exports){
21961'use strict';
21962
21963/** @type {import('./Reflect.getPrototypeOf')} */
21964module.exports = (typeof Reflect !== 'undefined' && Reflect.getPrototypeOf) || null;
21965
21966},{}],104:[function(require,module,exports){
21967'use strict';
21968
21969var reflectGetProto = require('./Reflect.getPrototypeOf');
21970var originalGetProto = require('./Object.getPrototypeOf');
21971
21972var getDunderProto = require('dunder-proto/get');
21973
21974/** @type {import('.')} */
21975module.exports = reflectGetProto
21976	? function getProto(O) {
21977		// @ts-expect-error TS can't narrow inside a closure, for some reason
21978		return reflectGetProto(O);
21979	}
21980	: originalGetProto
21981		? function getProto(O) {
21982			if (!O || (typeof O !== 'object' && typeof O !== 'function')) {
21983				throw new TypeError('getProto: not an object');
21984			}
21985			// @ts-expect-error TS can't narrow inside a closure, for some reason
21986			return originalGetProto(O);
21987		}
21988		: getDunderProto
21989			? function getProto(O) {
21990				// @ts-expect-error TS can't narrow inside a closure, for some reason
21991				return getDunderProto(O);
21992			}
21993			: null;
21994
21995},{"./Object.getPrototypeOf":102,"./Reflect.getPrototypeOf":103,"dunder-proto/get":88}],105:[function(require,module,exports){
21996'use strict';
21997
21998/** @type {import('./gOPD')} */
21999module.exports = Object.getOwnPropertyDescriptor;
22000
22001},{}],106:[function(require,module,exports){
22002'use strict';
22003
22004/** @type {import('.')} */
22005var $gOPD = require('./gOPD');
22006
22007if ($gOPD) {
22008	try {
22009		$gOPD([], 'length');
22010	} catch (e) {
22011		// IE 8 has a broken gOPD
22012		$gOPD = null;
22013	}
22014}
22015
22016module.exports = $gOPD;
22017
22018},{"./gOPD":105}],107:[function(require,module,exports){
22019'use strict';
22020
22021var origSymbol = typeof Symbol !== 'undefined' && Symbol;
22022var hasSymbolSham = require('./shams');
22023
22024/** @type {import('.')} */
22025module.exports = function hasNativeSymbols() {
22026	if (typeof origSymbol !== 'function') { return false; }
22027	if (typeof Symbol !== 'function') { return false; }
22028	if (typeof origSymbol('foo') !== 'symbol') { return false; }
22029	if (typeof Symbol('bar') !== 'symbol') { return false; }
22030
22031	return hasSymbolSham();
22032};
22033
22034},{"./shams":108}],108:[function(require,module,exports){
22035'use strict';
22036
22037/** @type {import('./shams')} */
22038/* eslint complexity: [2, 18], max-statements: [2, 33] */
22039module.exports = function hasSymbols() {
22040	if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; }
22041	if (typeof Symbol.iterator === 'symbol') { return true; }
22042
22043	/** @type {{ [k in symbol]?: unknown }} */
22044	var obj = {};
22045	var sym = Symbol('test');
22046	var symObj = Object(sym);
22047	if (typeof sym === 'string') { return false; }
22048
22049	if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; }
22050	if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; }
22051
22052	// temp disabled per https://github.com/ljharb/object.assign/issues/17
22053	// if (sym instanceof Symbol) { return false; }
22054	// temp disabled per https://github.com/WebReflection/get-own-property-symbol
22054s/issues/4
22055	// if (!(symObj instanceof Symbol)) { return false; }
22056
22057	// if (typeof Symbol.prototype.toString !== 'function') { return false; }
22058	// if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; }
22059
22060	var symVal = 42;
22061	obj[sym] = symVal;
22062	for (var _ in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop
22063	if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; }
22064
22065	if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; }
22066
22067	var syms = Object.getOwnPropertySymbols(obj);
22068	if (syms.length !== 1 || syms[0] !== sym) { return false; }
22069
22070	if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; }
22071
22072	if (typeof Object.getOwnPropertyDescriptor === 'function') {
22073		// eslint-disable-next-line no-extra-parens
22074		var descriptor = /** @type {PropertyDescriptor} */ (Object.getOwnPropertyDescriptor(obj, sym));
22075		if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; }
22076	}
22077
22078	return true;
22079};
22080
22081},{}],109:[function(require,module,exports){
22082'use strict';
22083
22084var call = Function.prototype.call;
22085var $hasOwn = Object.prototype.hasOwnProperty;
22086var bind = require('function-bind');
22087
22088/** @type {import('.')} */
22089module.exports = bind.call(call, $hasOwn);
22090
22091},{"function-bind":100}],110:[function(require,module,exports){
22092/*!
22093 * imagesLoaded v4.1.4
22094 * JavaScript is all like "You images are done yet or what?"
22095 * MIT License
22096 */
22097
22098( function( window, factory ) { 'use strict';
22099  // universal module definition
22100
22101  /*global define: false, module: false, require: false */
22102
22103  if ( typeof define == 'function' && define.amd ) {
22104    // AMD
22105    define( [
22106      'ev-emitter/ev-emitter'
22107    ], function( EvEmitter ) {
22108      return factory( window, EvEmitter );
22109    });
22110  } else if ( typeof module == 'object' && module.exports ) {
22111    // CommonJS
22112    module.exports = factory(
22113      window,
22114      require('ev-emitter')
22115    );
22116  } else {
22117    // browser global
22118    window.imagesLoaded = factory(
22119      window,
22120      window.EvEmitter
22121    );
22122  }
22123
22124})( typeof window !== 'undefined' ? window : this,
22125
22126// --------------------------  factory -------------------------- //
22127
22128function factory( window, EvEmitter ) {
22129
22130'use strict';
22131
22132var $ = window.jQuery;
22133var console = window.console;
22134
22135// -------------------------- helpers -------------------------- //
22136
22137// extend objects
22138function extend( a, b ) {
22139  for ( var prop in b ) {
22140    a[ prop ] = b[ prop ];
22141  }
22142  return a;
22143}
22144
22145var arraySlice = Array.prototype.slice;
22146
22147// turn element or nodeList into an array
22148function makeArray( obj ) {
22149  if ( Array.isArray( obj ) ) {
22150    // use object if already an array
22151    return obj;
22152  }
22153
22154  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
22155  if ( isArrayLike ) {
22156    // convert nodeList to array
22157    return arraySlice.call( obj );
22158  }
22159
22160  // array of single index
22161  return [ obj ];
22162}
22163
22164// -------------------------- imagesLoaded -------------------------- //
22165
22166/**
22167 * @param {Array, Element, NodeList, String} elem
22168 * @param {Object or Function} options - if function, use as callback
22169 * @param {Function} onAlways - callback function
22170 */
22171function ImagesLoaded( elem, options, onAlways ) {
22172  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
22173  if ( !( this instanceof ImagesLoaded ) ) {
22174    return new ImagesLoaded( elem, options, onAlways );
22175  }
22176  // use elem as selector string
22177  var queryElem = elem;
22178  if ( typeof elem == 'string' ) {
22179    queryElem = document.querySelectorAll( elem );
22180  }
22181  // bail if bad element
22182  if ( !queryElem ) {
22183    console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
22184    return;
22185  }
22186
22187  this.elements = makeArray( queryElem );
22188  this.options = extend( {}, this.options );
22189  // shift arguments if no options set
22190  if ( typeof options == 'function' ) {
22191    onAlways = options;
22192  } else {
22193    extend( this.options, options );
22194  }
22195
22196  if ( onAlways ) {
22197    this.on( 'always', onAlways );
22198  }
22199
22200  this.getImages();
22201
22202  if ( $ ) {
22203    // add jQuery Deferred object
22204    this.jqDeferred = new $.Deferred();
22205  }
22206
22207  // HACK check async to allow time to bind listeners
22208  setTimeout( this.check.bind( this ) );
22209}
22210
22211ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
22212
22213ImagesLoaded.prototype.options = {};
22214
22215ImagesLoaded.prototype.getImages = function() {
22216  this.images = [];
22217
22218  // filter & find items if we have an item selector
vendor: 4,347 bytes, lines 22219-22375
22219  this.elements.forEach( this.addElementImages, this );
22220};
22221
22222/**
22223 * @param {Node} element
22224 */
22225ImagesLoaded.prototype.addElementImages = function( elem ) {
22226  // filter siblings
22227  if ( elem.nodeName == 'IMG' ) {
22228    this.addImage( elem );
22229  }
22230  // get background image on element
22231  if ( this.options.background === true ) {
22232    this.addElementBackgroundImages( elem );
22233  }
22234
22235  // find children
22236  // no non-element nodes, #143
22237  var nodeType = elem.nodeType;
22238  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
22239    return;
22240  }
22241  var childImgs = elem.querySelectorAll('img');
22242  // concat childElems to filterFound array
22243  for ( var i=0; i < childImgs.length; i++ ) {
22244    var img = childImgs[i];
22245    this.addImage( img );
22246  }
22247
22248  // get child background images
22249  if ( typeof this.options.background == 'string' ) {
22250    var children = elem.querySelectorAll( this.options.background );
22251    for ( i=0; i < children.length; i++ ) {
22252      var child = children[i];
22253      this.addElementBackgroundImages( child );
22254    }
22255  }
22256};
22257
22258var elementNodeTypes = {
22259  1: true,
22260  9: true,
22261  11: true
22262};
22263
22264ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
22265  var style = getComputedStyle( elem );
22266  if ( !style ) {
22267    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
22268    return;
22269  }
22270  // get url inside url("...")
22271  var reURL = /url\((['"])?(.*?)\1\)/gi;
22272  var matches = reURL.exec( style.backgroundImage );
22273  while ( matches !== null ) {
22274    var url = matches && matches[2];
22275    if ( url ) {
22276      this.addBackground( url, elem );
22277    }
22278    matches = reURL.exec( style.backgroundImage );
22279  }
22280};
22281
22282/**
22283 * @param {Image} img
22284 */
22285ImagesLoaded.prototype.addImage = function( img ) {
22286  var loadingImage = new LoadingImage( img );
22287  this.images.push( loadingImage );
22288};
22289
22290ImagesLoaded.prototype.addBackground = function( url, elem ) {
22291  var background = new Background( url, elem );
22292  this.images.push( background );
22293};
22294
22295ImagesLoaded.prototype.check = function() {
22296  var _this = this;
22297  this.progressedCount = 0;
22298  this.hasAnyBroken = false;
22299  // complete if no images
22300  if ( !this.images.length ) {
22301    this.complete();
22302    return;
22303  }
22304
22305  function onProgress( image, elem, message ) {
22306    // HACK - Chrome triggers event before object properties have changed. #83
22307    setTimeout( function() {
22308      _this.progress( image, elem, message );
22309    });
22310  }
22311
22312  this.images.forEach( function( loadingImage ) {
22313    loadingImage.once( 'progress', onProgress );
22314    loadingImage.check();
22315  });
22316};
22317
22318ImagesLoaded.prototype.progress = function( image, elem, message ) {
22319  this.progressedCount++;
22320  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
22321  // progress event
22322  this.emitEvent( 'progress', [ this, image, elem ] );
22323  if ( this.jqDeferred && this.jqDeferred.notify ) {
22324    this.jqDeferred.notify( this, image );
22325  }
22326  // check if completed
22327  if ( this.progressedCount == this.images.length ) {
22328    this.complete();
22329  }
22330
22331  if ( this.options.debug && console ) {
22332    console.log( 'progress: ' + message, image, elem );
22333  }
22334};
22335
22336ImagesLoaded.prototype.complete = function() {
22337  var eventName = this.hasAnyBroken ? 'fail' : 'done';
22338  this.isComplete = true;
22339  this.emitEvent( eventName, [ this ] );
22340  this.emitEvent( 'always', [ this ] );
22341  if ( this.jqDeferred ) {
22342    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
22343    this.jqDeferred[ jqMethod ]( this );
22344  }
22345};
22346
22347// --------------------------  -------------------------- //
22348
22349function LoadingImage( img ) {
22350  this.img = img;
22351}
22352
22353LoadingImage.prototype = Object.create( EvEmitter.prototype );
22354
22355LoadingImage.prototype.check = function() {
22356  // If complete is true and browser supports natural sizes,
22357  // try to check for image status manually.
22358  var isComplete = this.getIsImageComplete();
22359  if ( isComplete ) {
22360    // report based on naturalWidth
22361    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
22362    return;
22363  }
22364
22365  // If none of the checks above matched, simulate loading on detached element.
22366  this.proxyImage = new Image();
22367  this.proxyImage.addEventListener( 'load', this );
22368  this.proxyImage.addEventListener( 'error', this );
22369  // bind to image as well for Firefox. #191
22370  this.img.addEventListener( 'load', this );
22371  this.img.addEventListener( 'error', this );
22372  this.proxyImage.src = this.img.src;
22373};
22374
22375LoadingImage.prototype.getIsImageComplete = function() {
22376  // check for non-zero, non-undefined naturalWidth
22377  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
22378  return this.img.complete && this.img.naturalWidth;
22379};
22380
22381LoadingImage.prototype.confirm = function( isLoaded, message ) {
22382  this.isLoaded = isLoaded;
22383  this.emitEvent( 'progress', [ this, this.img, message ] );
22384};
22385
22386// ----- events ----- //
22387
22388// trigger specified handler for event type
22389LoadingImage.prototype.handleEvent = function( event ) {
22390  var method = 'on' + event.type;
22391  if ( this[ method ] ) {
22392    this[ method ]( event );
22393  }
22394};
22395
22396LoadingImage.prototype.onload = function() {
22397  this.confirm( true, 'onload' );
22398  this.unbindEvents();
22399};
22400
22401LoadingImage.prototype.onerror = function() {
22402  this.confirm( false, 'onerror' );
22403  this.unbindEvents();
22404};
22405
22406LoadingImage.prototype.unbindEvents = function() {
22407  this.proxyImage.removeEventListener( 'load', this );
22408  this.proxyImage.removeEventListener( 'error', this );
22409  this.img.removeEventListener( 'load', this );
22410  this.img.removeEventListener( 'error', this );
22411};
22412
22413// -------------------------- Background -------------------------- //
22414
22415function Background( url, element ) {
22416  this.url = url;
22417  this.element = element;
22418  this.img = new Image();
22419}
22420
22421// inherit LoadingImage prototype
22422Background.prototype = Object.create( LoadingImage.prototype );
22423
22424Background.prototype.check = function() {
22425  this.img.addEventListener( 'load', this );
22426  this.img.addEventListener( 'error', this );
22427  this.img.src = this.url;
22428  // check if image is already complete
22429  var isComplete = this.getIsImageComplete();
22430  if ( isComplete ) {
22431    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
22432    this.unbindEvents();
22433  }
22434};
22435
22436Background.prototype.unbindEvents = function() {
22437  this.img.removeEventListener( 'load', this );
22438  this.img.removeEventListener( 'error', this );
22439};
22440
22441Background.prototype.confirm = function( isLoaded, message ) {
22442  this.isLoaded = isLoaded;
22443  this.emitEvent( 'progress', [ this, this.element, message ] );
22444};
22445
22446// -------------------------- jQuery -------------------------- //
22447
22448ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
22449  jQuery = jQuery || window.jQuery;
22450  if ( !jQuery ) {
22451    return;
22452  }
22453  // set local variable
22454  $ = jQuery;
22455  // $().imagesLoaded()
22456  $.fn.imagesLoaded = function( options, callback ) {
22457    var instance = new ImagesLoaded( this, options, callback );
22458    return instance.jqDeferred.promise( $(this) );
22459  };
22460};
22461// try making plugin
22462ImagesLoaded.makeJQueryPlugin();
22463
22464// --------------------------  -------------------------- //
22465
22466return ImagesLoaded;
22467
22468});
22469
22470},{"ev-emitter":98}],111:[function(require,module,exports){
22471(function (global){
22472/**
22473 * @license
22474 * Lodash <https://lodash.com/>
22475 * Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
22476 * Released under MIT license <https://lodash.com/license>
22477 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
22478 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
22479 */
22480;(function() {
22481
22482  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
22483  var undefined;
22484
22485  /** Used as the semantic version number. */
22486  var VERSION = '4.18.1';
22487
22488  /** Used as the size to enable large array optimizations. */
22489  var LARGE_ARRAY_SIZE = 200;
22490
22491  /** Error message constants. */
22492  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.',
22493      FUNC_ERROR_TEXT = 'Expected a function',
22494      INVALID_TEMPL_VAR_ERROR_TEXT = 'Invalid `variable` option passed into `_.template`',
22495      INVALID_TEMPL_IMPORTS_ERROR_TEXT = 'Invalid `imports
vendor: 11,797 bytes, lines 22495-22787
22495` option passed into `_.template`';
22496
22497  /** Used to stand-in for `undefined` hash values. */
22498  var HASH_UNDEFINED = '__lodash_hash_undefined__';
22499
22500  /** Used as the maximum memoize cache size. */
22501  var MAX_MEMOIZE_SIZE = 500;
22502
22503  /** Used as the internal argument placeholder. */
22504  var PLACEHOLDER = '__lodash_placeholder__';
22505
22506  /** Used to compose bitmasks for cloning. */
22507  var CLONE_DEEP_FLAG = 1,
22508      CLONE_FLAT_FLAG = 2,
22509      CLONE_SYMBOLS_FLAG = 4;
22510
22511  /** Used to compose bitmasks for value comparisons. */
22512  var COMPARE_PARTIAL_FLAG = 1,
22513      COMPARE_UNORDERED_FLAG = 2;
22514
22515  /** Used to compose bitmasks for function metadata. */
22516  var WRAP_BIND_FLAG = 1,
22517      WRAP_BIND_KEY_FLAG = 2,
22518      WRAP_CURRY_BOUND_FLAG = 4,
22519      WRAP_CURRY_FLAG = 8,
22520      WRAP_CURRY_RIGHT_FLAG = 16,
22521      WRAP_PARTIAL_FLAG = 32,
22522      WRAP_PARTIAL_RIGHT_FLAG = 64,
22523      WRAP_ARY_FLAG = 128,
22524      WRAP_REARG_FLAG = 256,
22525      WRAP_FLIP_FLAG = 512;
22526
22527  /** Used as default options for `_.truncate`. */
22528  var DEFAULT_TRUNC_LENGTH = 30,
22529      DEFAULT_TRUNC_OMISSION = '...';
22530
22531  /** Used to detect hot functions by number of calls within a span of milliseconds. */
22532  var HOT_COUNT = 800,
22533      HOT_SPAN = 16;
22534
22535  /** Used to indicate the type of lazy iteratees. */
22536  var LAZY_FILTER_FLAG = 1,
22537      LAZY_MAP_FLAG = 2,
22538      LAZY_WHILE_FLAG = 3;
22539
22540  /** Used as references for various `Number` constants. */
22541  var INFINITY = 1 / 0,
22542      MAX_SAFE_INTEGER = 9007199254740991,
22543      MAX_INTEGER = 1.7976931348623157e+308,
22544      NAN = 0 / 0;
22545
22546  /** Used as references for the maximum length and index of an array. */
22547  var MAX_ARRAY_LENGTH = 4294967295,
22548      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
22549      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
22550
22551  /** Used to associate wrap methods with their bit flags. */
22552  var wrapFlags = [
22553    ['ary', WRAP_ARY_FLAG],
22554    ['bind', WRAP_BIND_FLAG],
22555    ['bindKey', WRAP_BIND_KEY_FLAG],
22556    ['curry', WRAP_CURRY_FLAG],
22557    ['curryRight', WRAP_CURRY_RIGHT_FLAG],
22558    ['flip', WRAP_FLIP_FLAG],
22559    ['partial', WRAP_PARTIAL_FLAG],
22560    ['partialRight', WRAP_PARTIAL_RIGHT_FLAG],
22561    ['rearg', WRAP_REARG_FLAG]
22562  ];
22563
22564  /** `Object#toString` result references. */
22565  var argsTag = '[object Arguments]',
22566      arrayTag = '[object Array]',
22567      asyncTag = '[object AsyncFunction]',
22568      boolTag = '[object Boolean]',
22569      dateTag = '[object Date]',
22570      domExcTag = '[object DOMException]',
22571      errorTag = '[object Error]',
22572      funcTag = '[object Function]',
22573      genTag = '[object GeneratorFunction]',
22574      mapTag = '[object Map]',
22575      numberTag = '[object Number]',
22576      nullTag = '[object Null]',
22577      objectTag = '[object Object]',
22578      promiseTag = '[object Promise]',
22579      proxyTag = '[object Proxy]',
22580      regexpTag = '[object RegExp]',
22581      setTag = '[object Set]',
22582      stringTag = '[object String]',
22583      symbolTag = '[object Symbol]',
22584      undefinedTag = '[object Undefined]',
22585      weakMapTag = '[object WeakMap]',
22586      weakSetTag = '[object WeakSet]';
22587
22588  var arrayBufferTag = '[object ArrayBuffer]',
22589      dataViewTag = '[object DataView]',
22590      float32Tag = '[object Float32Array]',
22591      float64Tag = '[object Float64Array]',
22592      int8Tag = '[object Int8Array]',
22593      int16Tag = '[object Int16Array]',
22594      int32Tag = '[object Int32Array]',
22595      uint8Tag = '[object Uint8Array]',
22596      uint8ClampedTag = '[object Uint8ClampedArray]',
22597      uint16Tag = '[object Uint16Array]',
22598      uint32Tag = '[object Uint32Array]';
22599
22600  /** Used to match empty string literals in compiled template source. */
22601  var reEmptyStringLeading = /\b__p \+= '';/g,
22602      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
22603      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
22604
22605  /** Used to match HTML entities and HTML characters. */
22606  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
22607      reUnescapedHtml = /[&<>"']/g,
22608      reHasEscapedHtml = RegExp(reEscapedHtml.source),
22609      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
22610
22611  /** Used to match template delimiters. */
22612  var reEscape = /<%-([\s\S]+?)%>/g,
22613      reEvaluate = /<%([\s\S]+?)%>/g,
22614      reInterpolate = /<%=([\s\S]+?)%>/g;
22615
22616  /** Used to match property names within property paths. */
22617  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
22618      reIsPlainProp = /^\w*$/,
22619      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
22620
22621  /**
22622   * Used to match `RegExp`
22623   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
22624   */
22625  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
22626      reHasRegExpChar = RegExp(reRegExpChar.source);
22627
22628  /** Used to match leading whitespace. */
22629  var reTrimStart = /^\s+/;
22630
22631  /** Used to match a single whitespace character. */
22632  var reWhitespace = /\s/;
22633
22634  /** Used to match wrap detail comments. */
22635  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
22636      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
22637      reSplitDetails = /,? & /;
22638
22639  /** Used to match words composed of alphanumeric characters. */
22640  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
22641
22642  /**
22643   * Used to validate the `validate` option in `_.template` variable.
22644   *
22645   * Forbids characters which could potentially change the meaning of the function argument definition:
22646   * - "()," (modification of function parameters)
22647   * - "=" (default value)
22648   * - "[]{}" (destructuring of function parameters)
22649   * - "/" (beginning of a comment)
22650   * - whitespace
22651   */
22652  var reForbiddenIdentifierChars = /[()=,{}\[\]\/\s]/;
22653
22654  /** Used to match backslashes in property paths. */
22655  var reEscapeChar = /\\(\\)?/g;
22656
22657  /**
22658   * Used to match
22659   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
22660   */
22661  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
22662
22663  /** Used to match `RegExp` flags from their coerced string values. */
22664  var reFlags = /\w*$/;
22665
22666  /** Used to detect bad signed hexadecimal string values. */
22667  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
22668
22669  /** Used to detect binary string values. */
22670  var reIsBinary = /^0b[01]+$/i;
22671
22672  /** Used to detect host constructors (Safari). */
22673  var reIsHostCtor = /^\[object .+?Constructor\]$/;
22674
22675  /** Used to detect octal string values. */
22676  var reIsOctal = /^0o[0-7]+$/i;
22677
22678  /** Used to detect unsigned integer values. */
22679  var reIsUint = /^(?:0|[1-9]\d*)$/;
22680
22681  /** Used to match Latin Unicode letters (excluding mathematical operators). */
22682  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
22683
22684  /** Used to ensure capturing order of template delimiters. */
22685  var reNoMatch = /($^)/;
22686
22687  /** Used to match unescaped characters in compiled string literals. */
22688  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
22689
22690  /** Used to compose unicode character classes. */
22691  var rsAstralRange = '\\ud800-\\udfff',
22692      rsComboMarksRange = '\\u0300-\\u036f',
22693      reComboHalfMarksRange = '\\ufe20-\\ufe2f',
22694      rsComboSymbolsRange = '\\u20d0-\\u20ff',
22695      rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange,
22696      rsDingbatRange = '\\u2700-\\u27bf',
22697      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
22698      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
22699      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
22700      rsPunctuationRange = '\\u2000-\\u206f',
22701      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
22702      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
22703      rsVarRange = '\\ufe0e\\ufe0f',
22704      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
22705
22706  /** Used to compose unicode capture groups. */
22707  var rsApos = "['\u2019]",
22708      rsAstral = '[' + rsAstralRange + ']',
22709      rsBreak = '[' + rsBreakRange + ']',
22710      rsCombo = '[' + rsComboRange + ']',
22711      rsDigits = '\\d+',
22712      rsDingbat = '[' + rsDingbatRange + ']',
22713      rsLower = '[' + rsLowerRange + ']',
22714      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
22715      rsFitz = '\\ud83c[\\udffb-\\udfff]',
22716      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
22717      rsNonAstral = '[^' + rsAstralRange + ']',
22718      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
22719      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
22720      rsUpper = '[' + rsUpperRange + ']',
22721      rsZWJ = '\\u200d';
22722
22723  /** Used to compose unicode regexes. */
22724  var rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')',
22725      rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')',
22726      rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
22727      rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
22728      reOptMod = rsModifier + '?',
22729      rsOptVar = '[' + rsVarRange + ']?',
22730      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
22731      rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])',
22732      rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])',
22733      rsSeq = rsOptVar + reOptMod + rsOptJoin,
22734      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
22735      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
22736
22737  /** Used to match apostrophes. */
22738  var reApos = RegExp(rsApos, 'g');
22739
22740  /**
22741   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
22742   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
22743   */
22744  var reComboMark = RegExp(rsCombo, 'g');
22745
22746  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
22747  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
22748
22749  /** Used to match complex or compound words. */
22750  var reUnicodeWord = RegExp([
22751    rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
22752    rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')',
22753    rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower,
22754    rsUpper + '+' + rsOptContrUpper,
22755    rsOrdUpper,
22756    rsOrdLower,
22757    rsDigits,
22758    rsEmoji
22759  ].join('|'), 'g');
22760
22761  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
22762  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboRange + rsVarRange + ']');
22763
22764  /** Used to detect strings that need a more robust regexp to match words. */
22765  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
22766
22767  /** Used to assign default `context` object properties. */
22768  var contextProps = [
22769    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
22770    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
22771    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
22772    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
22773    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
22774  ];
22775
22776  /** Used to make template sourceURLs easier to identify. */
22777  var templateCounter = -1;
22778
22779  /** Used to identify `toStringTag` values of typed arrays. */
22780  var typedArrayTags = {};
22781  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
22782  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
22783  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
22784  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
22785  typedArrayTags[uint32Tag] = true;
22786  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
22787  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
vendor: 5,923 bytes, lines 22788-22922
22788  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
22789  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
22790  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
22791  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
22792  typedArrayTags[setTag] = typedArrayTags[stringTag] =
22793  typedArrayTags[weakMapTag] = false;
22794
22795  /** Used to identify `toStringTag` values supported by `_.clone`. */
22796  var cloneableTags = {};
22797  cloneableTags[argsTag] = cloneableTags[arrayTag] =
22798  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
22799  cloneableTags[boolTag] = cloneableTags[dateTag] =
22800  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
22801  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
22802  cloneableTags[int32Tag] = cloneableTags[mapTag] =
22803  cloneableTags[numberTag] = cloneableTags[objectTag] =
22804  cloneableTags[regexpTag] = cloneableTags[setTag] =
22805  cloneableTags[stringTag] = cloneableTags[symbolTag] =
22806  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
22807  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
22808  cloneableTags[errorTag] = cloneableTags[funcTag] =
22809  cloneableTags[weakMapTag] = false;
22810
22811  /** Used to map Latin Unicode letters to basic Latin letters. */
22812  var deburredLetters = {
22813    // Latin-1 Supplement block.
22814    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
22815    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
22816    '\xc7': 'C',  '\xe7': 'c',
22817    '\xd0': 'D',  '\xf0': 'd',
22818    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
22819    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
22820    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
22821    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
22822    '\xd1': 'N',  '\xf1': 'n',
22823    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
22824    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
22825    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
22826    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
22827    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
22828    '\xc6': 'Ae', '\xe6': 'ae',
22829    '\xde': 'Th', '\xfe': 'th',
22830    '\xdf': 'ss',
22831    // Latin Extended-A block.
22832    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
22833    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
22834    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
22835    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
22836    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
22837    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
22838    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
22839    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
22840    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
22841    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
22842    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
22843    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
22844    '\u0134': 'J',  '\u0135': 'j',
22845    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
22846    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
22847    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
22848    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
22849    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
22850    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
22851    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
22852    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
22853    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
22854    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
22855    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
22856    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
22857    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
22858    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
22859    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
22860    '\u0174': 'W',  '\u0175': 'w',
22861    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
22862    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
22863    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
22864    '\u0132': 'IJ', '\u0133': 'ij',
22865    '\u0152': 'Oe', '\u0153': 'oe',
22866    '\u0149': "'n", '\u017f': 's'
22867  };
22868
22869  /** Used to map characters to HTML entities. */
22870  var htmlEscapes = {
22871    '&': '&amp;',
22872    '<': '&lt;',
22873    '>': '&gt;',
22874    '"': '&quot;',
22875    "'": '&#39;'
22876  };
22877
22878  /** Used to map HTML entities to characters. */
22879  var htmlUnescapes = {
22880    '&amp;': '&',
22881    '&lt;': '<',
22882    '&gt;': '>',
22883    '&quot;': '"',
22884    '&#39;': "'"
22885  };
22886
22887  /** Used to escape characters for inclusion in compiled string literals. */
22888  var stringEscapes = {
22889    '\\': '\\',
22890    "'": "'",
22891    '\n': 'n',
22892    '\r': 'r',
22893    '\u2028': 'u2028',
22894    '\u2029': 'u2029'
22895  };
22896
22897  /** Built-in method references without a dependency on `root`. */
22898  var freeParseFloat = parseFloat,
22899      freeParseInt = parseInt;
22900
22901  /** Detect free variable `global` from Node.js. */
22902  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
22903
22904  /** Detect free variable `self`. */
22905  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
22906
22907  /** Used as a reference to the global object. */
22908  var root = freeGlobal || freeSelf || Function('return this')();
22909
22910  /** Detect free variable `exports`. */
22911  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
22912
22913  /** Detect free variable `module`. */
22914  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
22915
22916  /** Detect the popular CommonJS extension `module.exports`. */
22917  var moduleExports = freeModule && freeModule.exports === freeExports;
22918
22919  /** Detect free variable `process` from Node.js. */
22920  var freeProcess = moduleExports && freeGlobal.process;
22921
22922  /** Used to access faster Node.js helpers. */
vendor: 8,860 bytes, lines 22923-23216
22923  var nodeUtil = (function() {
22924    try {
22925      // Use `util.types` for Node.js 10+.
22926      var types = freeModule && freeModule.require && freeModule.require('util').types;
22927
22928      if (types) {
22929        return types;
22930      }
22931
22932      // Legacy `process.binding('util')` for Node.js < 10.
22933      return freeProcess && freeProcess.binding && freeProcess.binding('util');
22934    } catch (e) {}
22935  }());
22936
22937  /* Node.js helper references. */
22938  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
22939      nodeIsDate = nodeUtil && nodeUtil.isDate,
22940      nodeIsMap = nodeUtil && nodeUtil.isMap,
22941      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
22942      nodeIsSet = nodeUtil && nodeUtil.isSet,
22943      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
22944
22945  /*--------------------------------------------------------------------------*/
22946
22947  /**
22948   * A faster alternative to `Function#apply`, this function invokes `func`
22949   * with the `this` binding of `thisArg` and the arguments of `args`.
22950   *
22951   * @private
22952   * @param {Function} func The function to invoke.
22953   * @param {*} thisArg The `this` binding of `func`.
22954   * @param {Array} args The arguments to invoke `func` with.
22955   * @returns {*} Returns the result of `func`.
22956   */
22957  function apply(func, thisArg, args) {
22958    switch (args.length) {
22959      case 0: return func.call(thisArg);
22960      case 1: return func.call(thisArg, args[0]);
22961      case 2: return func.call(thisArg, args[0], args[1]);
22962      case 3: return func.call(thisArg, args[0], args[1], args[2]);
22963    }
22964    return func.apply(thisArg, args);
22965  }
22966
22967  /**
22968   * A specialized version of `baseAggregator` for arrays.
22969   *
22970   * @private
22971   * @param {Array} [array] The array to iterate over.
22972   * @param {Function} setter The function to set `accumulator` values.
22973   * @param {Function} iteratee The iteratee to transform keys.
22974   * @param {Object} accumulator The initial aggregated object.
22975   * @returns {Function} Returns `accumulator`.
22976   */
22977  function arrayAggregator(array, setter, iteratee, accumulator) {
22978    var index = -1,
22979        length = array == null ? 0 : array.length;
22980
22981    while (++index < length) {
22982      var value = array[index];
22983      setter(accumulator, value, iteratee(value), array);
22984    }
22985    return accumulator;
22986  }
22987
22988  /**
22989   * A specialized version of `_.forEach` for arrays without support for
22990   * iteratee shorthands.
22991   *
22992   * @private
22993   * @param {Array} [array] The array to iterate over.
22994   * @param {Function} iteratee The function invoked per iteration.
22995   * @returns {Array} Returns `array`.
22996   */
22997  function arrayEach(array, iteratee) {
22998    var index = -1,
22999        length = array == null ? 0 : array.length;
23000
23001    while (++index < length) {
23002      if (iteratee(array[index], index, array) === false) {
23003        break;
23004      }
23005    }
23006    return array;
23007  }
23008
23009  /**
23010   * A specialized version of `_.forEachRight` for arrays without support for
23011   * iteratee shorthands.
23012   *
23013   * @private
23014   * @param {Array} [array] The array to iterate over.
23015   * @param {Function} iteratee The function invoked per iteration.
23016   * @returns {Array} Returns `array`.
23017   */
23018  function arrayEachRight(array, iteratee) {
23019    var length = array == null ? 0 : array.length;
23020
23021    while (length--) {
23022      if (iteratee(array[length], length, array) === false) {
23023        break;
23024      }
23025    }
23026    return array;
23027  }
23028
23029  /**
23030   * A specialized version of `_.every` for arrays without support for
23031   * iteratee shorthands.
23032   *
23033   * @private
23034   * @param {Array} [array] The array to iterate over.
23035   * @param {Function} predicate The function invoked per iteration.
23036   * @returns {boolean} Returns `true` if all elements pass the predicate check,
23037   *  else `false`.
23038   */
23039  function arrayEvery(array, predicate) {
23040    var index = -1,
23041        length = array == null ? 0 : array.length;
23042
23043    while (++index < length) {
23044      if (!predicate(array[index], index, array)) {
23045        return false;
23046      }
23047    }
23048    return true;
23049  }
23050
23051  /**
23052   * A specialized version of `_.filter` for arrays without support for
23053   * iteratee shorthands.
23054   *
23055   * @private
23056   * @param {Array} [array] The array to iterate over.
23057   * @param {Function} predicate The function invoked per iteration.
23058   * @returns {Array} Returns the new filtered array.
23059   */
23060  function arrayFilter(array, predicate) {
23061    var index = -1,
23062        length = array == null ? 0 : array.length,
23063        resIndex = 0,
23064        result = [];
23065
23066    while (++index < length) {
23067      var value = array[index];
23068      if (predicate(value, index, array)) {
23069        result[resIndex++] = value;
23070      }
23071    }
23072    return result;
23073  }
23074
23075  /**
23076   * A specialized version of `_.includes` for arrays without support for
23077   * specifying an index to search from.
23078   *
23079   * @private
23080   * @param {Array} [array] The array to inspect.
23081   * @param {*} target The value to search for.
23082   * @returns {boolean} Returns `true` if `target` is found, else `false`.
23083   */
23084  function arrayIncludes(array, value) {
23085    var length = array == null ? 0 : array.length;
23086    return !!length && baseIndexOf(array, value, 0) > -1;
23087  }
23088
23089  /**
23090   * This function is like `arrayIncludes` except that it accepts a comparator.
23091   *
23092   * @private
23093   * @param {Array} [array] The array to inspect.
23094   * @param {*} target The value to search for.
23095   * @param {Function} comparator The comparator invoked per element.
23096   * @returns {boolean} Returns `true` if `target` is found, else `false`.
23097   */
23098  function arrayIncludesWith(array, value, comparator) {
23099    var index = -1,
23100        length = array == null ? 0 : array.length;
23101
23102    while (++index < length) {
23103      if (comparator(value, array[index])) {
23104        return true;
23105      }
23106    }
23107    return false;
23108  }
23109
23110  /**
23111   * A specialized version of `_.map` for arrays without support for iteratee
23112   * shorthands.
23113   *
23114   * @private
23115   * @param {Array} [array] The array to iterate over.
23116   * @param {Function} iteratee The function invoked per iteration.
23117   * @returns {Array} Returns the new mapped array.
23118   */
23119  function arrayMap(array, iteratee) {
23120    var index = -1,
23121        length = array == null ? 0 : array.length,
23122        result = Array(length);
23123
23124    while (++index < length) {
23125      result[index] = iteratee(array[index], index, array);
23126    }
23127    return result;
23128  }
23129
23130  /**
23131   * Appends the elements of `values` to `array`.
23132   *
23133   * @private
23134   * @param {Array} array The array to modify.
23135   * @param {Array} values The values to append.
23136   * @returns {Array} Returns `array`.
23137   */
23138  function arrayPush(array, values) {
23139    var index = -1,
23140        length = values.length,
23141        offset = array.length;
23142
23143    while (++index < length) {
23144      array[offset + index] = values[index];
23145    }
23146    return array;
23147  }
23148
23149  /**
23150   * A specialized version of `_.reduce` for arrays without support for
23151   * iteratee shorthands.
23152   *
23153   * @private
23154   * @param {Array} [array] The array to iterate over.
23155   * @param {Function} iteratee The function invoked per iteration.
23156   * @param {*} [accumulator] The initial value.
23157   * @param {boolean} [initAccum] Specify using the first element of `array` as
23158   *  the initial value.
23159   * @returns {*} Returns the accumulated value.
23160   */
23161  function arrayReduce(array, iteratee, accumulator, initAccum) {
23162    var index = -1,
23163        length = array == null ? 0 : array.length;
23164
23165    if (initAccum && length) {
23166      accumulator = array[++index];
23167    }
23168    while (++index < length) {
23169      accumulator = iteratee(accumulator, array[index], index, array);
23170    }
23171    return accumulator;
23172  }
23173
23174  /**
23175   * A specialized version of `_.reduceRight` for arrays without support for
23176   * iteratee shorthands.
23177   *
23178   * @private
23179   * @param {Array} [array] The array to iterate over.
23180   * @param {Function} iteratee The function invoked per iteration.
23181   * @param {*} [accumulator] The initial value.
23182   * @param {boolean} [initAccum] Specify using the last element of `array` as
23183   *  the initial value.
23184   * @returns {*} Returns the accumulated value.
23185   */
23186  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
23187    var length = array == null ? 0 : array.length;
23188    if (initAccum && length) {
23189      accumulator = array[--length];
23190    }
23191    while (length--) {
23192      accumulator = iteratee(accumulator, array[length], length, array);
23193    }
23194    return accumulator;
23195  }
23196
23197  /**
23198   * A specialized version of `_.some` for arrays without support for iteratee
23199   * shorthands.
23200   *
23201   * @private
23202   * @param {Array} [array] The array to iterate over.
23203   * @param {Function} predicate The function invoked per iteration.
23204   * @returns {boolean} Returns `true` if any element passes the predicate check,
23205   *  else `false`.
23206   */
23207  function arraySome(array, predicate) {
23208    var index = -1,
23209        length = array == null ? 0 : array.length;
23210
23211    while (++index < length) {
23212      if (predicate(array[index], index, array)) {
23213        return true;
23214      }
23215    }
23216    return false;
vendor: 12,899 bytes, lines 23217-23654
23217  }
23218
23219  /**
23220   * Gets the size of an ASCII `string`.
23221   *
23222   * @private
23223   * @param {string} string The string inspect.
23224   * @returns {number} Returns the string size.
23225   */
23226  var asciiSize = baseProperty('length');
23227
23228  /**
23229   * Converts an ASCII `string` to an array.
23230   *
23231   * @private
23232   * @param {string} string The string to convert.
23233   * @returns {Array} Returns the converted array.
23234   */
23235  function asciiToArray(string) {
23236    return string.split('');
23237  }
23238
23239  /**
23240   * Splits an ASCII `string` into an array of its words.
23241   *
23242   * @private
23243   * @param {string} The string to inspect.
23244   * @returns {Array} Returns the words of `string`.
23245   */
23246  function asciiWords(string) {
23247    return string.match(reAsciiWord) || [];
23248  }
23249
23250  /**
23251   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
23252   * without support for iteratee shorthands, which iterates over `collection`
23253   * using `eachFunc`.
23254   *
23255   * @private
23256   * @param {Array|Object} collection The collection to inspect.
23257   * @param {Function} predicate The function invoked per iteration.
23258   * @param {Function} eachFunc The function to iterate over `collection`.
23259   * @returns {*} Returns the found element or its key, else `undefined`.
23260   */
23261  function baseFindKey(collection, predicate, eachFunc) {
23262    var result;
23263    eachFunc(collection, function(value, key, collection) {
23264      if (predicate(value, key, collection)) {
23265        result = key;
23266        return false;
23267      }
23268    });
23269    return result;
23270  }
23271
23272  /**
23273   * The base implementation of `_.findIndex` and `_.findLastIndex` without
23274   * support for iteratee shorthands.
23275   *
23276   * @private
23277   * @param {Array} array The array to inspect.
23278   * @param {Function} predicate The function invoked per iteration.
23279   * @param {number} fromIndex The index to search from.
23280   * @param {boolean} [fromRight] Specify iterating from right to left.
23281   * @returns {number} Returns the index of the matched value, else `-1`.
23282   */
23283  function baseFindIndex(array, predicate, fromIndex, fromRight) {
23284    var length = array.length,
23285        index = fromIndex + (fromRight ? 1 : -1);
23286
23287    while ((fromRight ? index-- : ++index < length)) {
23288      if (predicate(array[index], index, array)) {
23289        return index;
23290      }
23291    }
23292    return -1;
23293  }
23294
23295  /**
23296   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
23297   *
23298   * @private
23299   * @param {Array} array The array to inspect.
23300   * @param {*} value The value to search for.
23301   * @param {number} fromIndex The index to search from.
23302   * @returns {number} Returns the index of the matched value, else `-1`.
23303   */
23304  function baseIndexOf(array, value, fromIndex) {
23305    return value === value
23306      ? strictIndexOf(array, value, fromIndex)
23307      : baseFindIndex(array, baseIsNaN, fromIndex);
23308  }
23309
23310  /**
23311   * This function is like `baseIndexOf` except that it accepts a comparator.
23312   *
23313   * @private
23314   * @param {Array} array The array to inspect.
23315   * @param {*} value The value to search for.
23316   * @param {number} fromIndex The index to search from.
23317   * @param {Function} comparator The comparator invoked per element.
23318   * @returns {number} Returns the index of the matched value, else `-1`.
23319   */
23320  function baseIndexOfWith(array, value, fromIndex, comparator) {
23321    var index = fromIndex - 1,
23322        length = array.length;
23323
23324    while (++index < length) {
23325      if (comparator(array[index], value)) {
23326        return index;
23327      }
23328    }
23329    return -1;
23330  }
23331
23332  /**
23333   * The base implementation of `_.isNaN` without support for number objects.
23334   *
23335   * @private
23336   * @param {*} value The value to check.
23337   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
23338   */
23339  function baseIsNaN(value) {
23340    return value !== value;
23341  }
23342
23343  /**
23344   * The base implementation of `_.mean` and `_.meanBy` without support for
23345   * iteratee shorthands.
23346   *
23347   * @private
23348   * @param {Array} array The array to iterate over.
23349   * @param {Function} iteratee The function invoked per iteration.
23350   * @returns {number} Returns the mean.
23351   */
23352  function baseMean(array, iteratee) {
23353    var length = array == null ? 0 : array.length;
23354    return length ? (baseSum(array, iteratee) / length) : NAN;
23355  }
23356
23357  /**
23358   * The base implementation of `_.property` without support for deep paths.
23359   *
23360   * @private
23361   * @param {string} key The key of the property to get.
23362   * @returns {Function} Returns the new accessor function.
23363   */
23364  function baseProperty(key) {
23365    return function(object) {
23366      return object == null ? undefined : object[key];
23367    };
23368  }
23369
23370  /**
23371   * The base implementation of `_.propertyOf` without support for deep paths.
23372   *
23373   * @private
23374   * @param {Object} object The object to query.
23375   * @returns {Function} Returns the new accessor function.
23376   */
23377  function basePropertyOf(object) {
23378    return function(key) {
23379      return object == null ? undefined : object[key];
23380    };
23381  }
23382
23383  /**
23384   * The base implementation of `_.reduce` and `_.reduceRight`, without support
23385   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
23386   *
23387   * @private
23388   * @param {Array|Object} collection The collection to iterate over.
23389   * @param {Function} iteratee The function invoked per iteration.
23390   * @param {*} accumulator The initial value.
23391   * @param {boolean} initAccum Specify using the first or last element of
23392   *  `collection` as the initial value.
23393   * @param {Function} eachFunc The function to iterate over `collection`.
23394   * @returns {*} Returns the accumulated value.
23395   */
23396  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
23397    eachFunc(collection, function(value, index, collection) {
23398      accumulator = initAccum
23399        ? (initAccum = false, value)
23400        : iteratee(accumulator, value, index, collection);
23401    });
23402    return accumulator;
23403  }
23404
23405  /**
23406   * The base implementation of `_.sortBy` which uses `comparer` to define the
23407   * sort order of `array` and replaces criteria objects with their corresponding
23408   * values.
23409   *
23410   * @private
23411   * @param {Array} array The array to sort.
23412   * @param {Function} comparer The function to define sort order.
23413   * @returns {Array} Returns `array`.
23414   */
23415  function baseSortBy(array, comparer) {
23416    var length = array.length;
23417
23418    array.sort(comparer);
23419    while (length--) {
23420      array[length] = array[length].value;
23421    }
23422    return array;
23423  }
23424
23425  /**
23426   * The base implementation of `_.sum` and `_.sumBy` without support for
23427   * iteratee shorthands.
23428   *
23429   * @private
23430   * @param {Array} array The array to iterate over.
23431   * @param {Function} iteratee The function invoked per iteration.
23432   * @returns {number} Returns the sum.
23433   */
23434  function baseSum(array, iteratee) {
23435    var result,
23436        index = -1,
23437        length = array.length;
23438
23439    while (++index < length) {
23440      var current = iteratee(array[index]);
23441      if (current !== undefined) {
23442        result = result === undefined ? current : (result + current);
23443      }
23444    }
23445    return result;
23446  }
23447
23448  /**
23449   * The base implementation of `_.times` without support for iteratee shorthands
23450   * or max array length checks.
23451   *
23452   * @private
23453   * @param {number} n The number of times to invoke `iteratee`.
23454   * @param {Function} iteratee The function invoked per iteration.
23455   * @returns {Array} Returns the array of results.
23456   */
23457  function baseTimes(n, iteratee) {
23458    var index = -1,
23459        result = Array(n);
23460
23461    while (++index < n) {
23462      result[index] = iteratee(index);
23463    }
23464    return result;
23465  }
23466
23467  /**
23468   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
23469   * of key-value pairs for `object` corresponding to the property names of `props`.
23470   *
23471   * @private
23472   * @param {Object} object The object to query.
23473   * @param {Array} props The property names to get values for.
23474   * @returns {Object} Returns the key-value pairs.
23475   */
23476  function baseToPairs(object, props) {
23477    return arrayMap(props, function(key) {
23478      return [key, object[key]];
23479    });
23480  }
23481
23482  /**
23483   * The base implementation of `_.trim`.
23484   *
23485   * @private
23486   * @param {string} string The string to trim.
23487   * @returns {string} Returns the trimmed string.
23488   */
23489  function baseTrim(string) {
23490    return string
23491      ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
23492      : string;
23493  }
23494
23495  /**
23496   * The base implementation of `_.unary` without support for storing metadata.
23497   *
23498   * @private
23499   * @param {Function} func The function to cap arguments for.
23500   * @returns {Function} Returns the new capped function.
23501   */
23502  function baseUnary(func) {
23503    return function(value) {
23504      return func(value);
23505    };
23506  }
23507
23508  /**
23509   * The base implementation of `_.values` and `_.valuesIn` which creates an
23510   * array of `object` property values corresponding to the property names
23511   * of `props`.
23512   *
23513   * @private
23514   * @param {Object} object The object to query.
23515   * @param {Array} props The property names to get values for.
23516   * @returns {Object} Returns the array of property values.
23517   */
23518  function baseValues(object, props) {
23519    return arrayMap(props, function(key) {
23520      return object[key];
23521    });
23522  }
23523
23524  /**
23525   * Checks if a `cache` value for `key` exists.
23526   *
23527   * @private
23528   * @param {Object} cache The cache to query.
23529   * @param {string} key The key of the entry to check.
23530   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
23531   */
23532  function cacheHas(cache, key) {
23533    return cache.has(key);
23534  }
23535
23536  /**
23537   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
23538   * that is not found in the character symbols.
23539   *
23540   * @private
23541   * @param {Array} strSymbols The string symbols to inspect.
23542   * @param {Array} chrSymbols The character symbols to find.
23543   * @returns {number} Returns the index of the first unmatched string symbol.
23544   */
23545  function charsStartIndex(strSymbols, chrSymbols) {
23546    var index = -1,
23547        length = strSymbols.length;
23548
23549    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
23550    return index;
23551  }
23552
23553  /**
23554   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
23555   * that is not found in the character symbols.
23556   *
23557   * @private
23558   * @param {Array} strSymbols The string symbols to inspect.
23559   * @param {Array} chrSymbols The character symbols to find.
23560   * @returns {number} Returns the index of the last unmatched string symbol.
23561   */
23562  function charsEndIndex(strSymbols, chrSymbols) {
23563    var index = strSymbols.length;
23564
23565    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
23566    return index;
23567  }
23568
23569  /**
23570   * Gets the number of `placeholder` occurrences in `array`.
23571   *
23572   * @private
23573   * @param {Array} array The array to inspect.
23574   * @param {*} placeholder The placeholder to search for.
23575   * @returns {number} Returns the placeholder count.
23576   */
23577  function countHolders(array, placeholder) {
23578    var length = array.length,
23579        result = 0;
23580
23581    while (length--) {
23582      if (array[length] === placeholder) {
23583        ++result;
23584      }
23585    }
23586    return result;
23587  }
23588
23589  /**
23590   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
23591   * letters to basic Latin letters.
23592   *
23593   * @private
23594   * @param {string} letter The matched letter to deburr.
23595   * @returns {string} Returns the deburred letter.
23596   */
23597  var deburrLetter = basePropertyOf(deburredLetters);
23598
23599  /**
23600   * Used by `_.escape` to convert characters to HTML entities.
23601   *
23602   * @private
23603   * @param {string} chr The matched character to escape.
23604   * @returns {string} Returns the escaped character.
23605   */
23606  var escapeHtmlChar = basePropertyOf(htmlEscapes);
23607
23608  /**
23609   * Used by `_.template` to escape characters for inclusion in compiled string literals.
23610   *
23611   * @private
23612   * @param {string} chr The matched character to escape.
23613   * @returns {string} Returns the escaped character.
23614   */
23615  function escapeStringChar(chr) {
23616    return '\\' + stringEscapes[chr];
23617  }
23618
23619  /**
23620   * Gets the value at `key` of `object`.
23621   *
23622   * @private
23623   * @param {Object} [object] The object to query.
23624   * @param {string} key The key of the property to get.
23625   * @returns {*} Returns the property value.
23626   */
23627  function getValue(object, key) {
23628    return object == null ? undefined : object[key];
23629  }
23630
23631  /**
23632   * Checks if `string` contains Unicode symbols.
23633   *
23634   * @private
23635   * @param {string} string The string to inspect.
23636   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
23637   */
23638  function hasUnicode(string) {
23639    return reHasUnicode.test(string);
23640  }
23641
23642  /**
23643   * Checks if `string` contains a word composed of Unicode symbols.
23644   *
23645   * @private
23646   * @param {string} string The string to inspect.
23647   * @returns {boolean} Returns `true` if a word is found, else `false`.
23648   */
23649  function hasUnicodeWord(string) {
23650    return reHasUnicodeWord.test(string);
23651  }
23652
23653  /**
23654   * Converts `iterator` to an array.
vendor: 8,214 bytes, lines 23655-23964
23655   *
23656   * @private
23657   * @param {Object} iterator The iterator to convert.
23658   * @returns {Array} Returns the converted array.
23659   */
23660  function iteratorToArray(iterator) {
23661    var data,
23662        result = [];
23663
23664    while (!(data = iterator.next()).done) {
23665      result.push(data.value);
23666    }
23667    return result;
23668  }
23669
23670  /**
23671   * Converts `map` to its key-value pairs.
23672   *
23673   * @private
23674   * @param {Object} map The map to convert.
23675   * @returns {Array} Returns the key-value pairs.
23676   */
23677  function mapToArray(map) {
23678    var index = -1,
23679        result = Array(map.size);
23680
23681    map.forEach(function(value, key) {
23682      result[++index] = [key, value];
23683    });
23684    return result;
23685  }
23686
23687  /**
23688   * Creates a unary function that invokes `func` with its argument transformed.
23689   *
23690   * @private
23691   * @param {Function} func The function to wrap.
23692   * @param {Function} transform The argument transform.
23693   * @returns {Function} Returns the new function.
23694   */
23695  function overArg(func, transform) {
23696    return function(arg) {
23697      return func(transform(arg));
23698    };
23699  }
23700
23701  /**
23702   * Replaces all `placeholder` elements in `array` with an internal placeholder
23703   * and returns an array of their indexes.
23704   *
23705   * @private
23706   * @param {Array} array The array to modify.
23707   * @param {*} placeholder The placeholder to replace.
23708   * @returns {Array} Returns the new array of placeholder indexes.
23709   */
23710  function replaceHolders(array, placeholder) {
23711    var index = -1,
23712        length = array.length,
23713        resIndex = 0,
23714        result = [];
23715
23716    while (++index < length) {
23717      var value = array[index];
23718      if (value === placeholder || value === PLACEHOLDER) {
23719        array[index] = PLACEHOLDER;
23720        result[resIndex++] = index;
23721      }
23722    }
23723    return result;
23724  }
23725
23726  /**
23727   * Converts `set` to an array of its values.
23728   *
23729   * @private
23730   * @param {Object} set The set to convert.
23731   * @returns {Array} Returns the values.
23732   */
23733  function setToArray(set) {
23734    var index = -1,
23735        result = Array(set.size);
23736
23737    set.forEach(function(value) {
23738      result[++index] = value;
23739    });
23740    return result;
23741  }
23742
23743  /**
23744   * Converts `set` to its value-value pairs.
23745   *
23746   * @private
23747   * @param {Object} set The set to convert.
23748   * @returns {Array} Returns the value-value pairs.
23749   */
23750  function setToPairs(set) {
23751    var index = -1,
23752        result = Array(set.size);
23753
23754    set.forEach(function(value) {
23755      result[++index] = [value, value];
23756    });
23757    return result;
23758  }
23759
23760  /**
23761   * A specialized version of `_.indexOf` which performs strict equality
23762   * comparisons of values, i.e. `===`.
23763   *
23764   * @private
23765   * @param {Array} array The array to inspect.
23766   * @param {*} value The value to search for.
23767   * @param {number} fromIndex The index to search from.
23768   * @returns {number} Returns the index of the matched value, else `-1`.
23769   */
23770  function strictIndexOf(array, value, fromIndex) {
23771    var index = fromIndex - 1,
23772        length = array.length;
23773
23774    while (++index < length) {
23775      if (array[index] === value) {
23776        return index;
23777      }
23778    }
23779    return -1;
23780  }
23781
23782  /**
23783   * A specialized version of `_.lastIndexOf` which performs strict equality
23784   * comparisons of values, i.e. `===`.
23785   *
23786   * @private
23787   * @param {Array} array The array to inspect.
23788   * @param {*} value The value to search for.
23789   * @param {number} fromIndex The index to search from.
23790   * @returns {number} Returns the index of the matched value, else `-1`.
23791   */
23792  function strictLastIndexOf(array, value, fromIndex) {
23793    var index = fromIndex + 1;
23794    while (index--) {
23795      if (array[index] === value) {
23796        return index;
23797      }
23798    }
23799    return index;
23800  }
23801
23802  /**
23803   * Gets the number of symbols in `string`.
23804   *
23805   * @private
23806   * @param {string} string The string to inspect.
23807   * @returns {number} Returns the string size.
23808   */
23809  function stringSize(string) {
23810    return hasUnicode(string)
23811      ? unicodeSize(string)
23812      : asciiSize(string);
23813  }
23814
23815  /**
23816   * Converts `string` to an array.
23817   *
23818   * @private
23819   * @param {string} string The string to convert.
23820   * @returns {Array} Returns the converted array.
23821   */
23822  function stringToArray(string) {
23823    return hasUnicode(string)
23824      ? unicodeToArray(string)
23825      : asciiToArray(string);
23826  }
23827
23828  /**
23829   * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
23830   * character of `string`.
23831   *
23832   * @private
23833   * @param {string} string The string to inspect.
23834   * @returns {number} Returns the index of the last non-whitespace character.
23835   */
23836  function trimmedEndIndex(string) {
23837    var index = string.length;
23838
23839    while (index-- && reWhitespace.test(string.charAt(index))) {}
23840    return index;
23841  }
23842
23843  /**
23844   * Used by `_.unescape` to convert HTML entities to characters.
23845   *
23846   * @private
23847   * @param {string} chr The matched character to unescape.
23848   * @returns {string} Returns the unescaped character.
23849   */
23850  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
23851
23852  /**
23853   * Gets the size of a Unicode `string`.
23854   *
23855   * @private
23856   * @param {string} string The string inspect.
23857   * @returns {number} Returns the string size.
23858   */
23859  function unicodeSize(string) {
23860    var result = reUnicode.lastIndex = 0;
23861    while (reUnicode.test(string)) {
23862      ++result;
23863    }
23864    return result;
23865  }
23866
23867  /**
23868   * Converts a Unicode `string` to an array.
23869   *
23870   * @private
23871   * @param {string} string The string to convert.
23872   * @returns {Array} Returns the converted array.
23873   */
23874  function unicodeToArray(string) {
23875    return string.match(reUnicode) || [];
23876  }
23877
23878  /**
23879   * Splits a Unicode `string` into an array of its words.
23880   *
23881   * @private
23882   * @param {string} The string to inspect.
23883   * @returns {Array} Returns the words of `string`.
23884   */
23885  function unicodeWords(string) {
23886    return string.match(reUnicodeWord) || [];
23887  }
23888
23889  /*--------------------------------------------------------------------------*/
23890
23891  /**
23892   * Create a new pristine `lodash` function using the `context` object.
23893   *
23894   * @static
23895   * @memberOf _
23896   * @since 1.1.0
23897   * @category Util
23898   * @param {Object} [context=root] The context object.
23899   * @returns {Function} Returns a new `lodash` function.
23900   * @example
23901   *
23902   * _.mixin({ 'foo': _.constant('foo') });
23903   *
23904   * var lodash = _.runInContext();
23905   * lodash.mixin({ 'bar': lodash.constant('bar') });
23906   *
23907   * _.isFunction(_.foo);
23908   * // => true
23909   * _.isFunction(_.bar);
23910   * // => false
23911   *
23912   * lodash.isFunction(lodash.foo);
23913   * // => false
23914   * lodash.isFunction(lodash.bar);
23915   * // => true
23916   *
23917   * // Create a suped-up `defer` in Node.js.
23918   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
23919   */
23920  var runInContext = (function runInContext(context) {
23921    context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps));
23922
23923    /** Built-in constructor references. */
23924    var Array = context.Array,
23925        Date = context.Date,
23926        Error = context.Error,
23927        Function = context.Function,
23928        Math = context.Math,
23929        Object = context.Object,
23930        RegExp = context.RegExp,
23931        String = context.String,
23932        TypeError = context.TypeError;
23933
23934    /** Used for built-in method references. */
23935    var arrayProto = Array.prototype,
23936        funcProto = Function.prototype,
23937        objectProto = Object.prototype;
23938
23939    /** Used to detect overreaching core-js shims. */
23940    var coreJsData = context['__core-js_shared__'];
23941
23942    /** Used to resolve the decompiled source of functions. */
23943    var funcToString = funcProto.toString;
23944
23945    /** Used to check objects for own properties. */
23946    var hasOwnProperty = objectProto.hasOwnProperty;
23947
23948    /** Used to generate unique IDs. */
23949    var idCounter = 0;
23950
23951    /** Used to detect methods masquerading as native. */
23952    var maskSrcKey = (function() {
23953      var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
23954      return uid ? ('Symbol(src)_1.' + uid) : '';
23955    }());
23956
23957    /**
23958     * Used to resolve the
23959     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
23960     * of values.
23961     */
23962    var nativeObjectToString = objectProto.toString;
23963
23964    /** Used to infer the `Object` constructor. */
vendor: 7,209 bytes, lines 23965-24109
23965    var objectCtorString = funcToString.call(Object);
23966
23967    /** Used to restore the original `_` reference in `_.noConflict`. */
23968    var oldDash = root._;
23969
23970    /** Used to detect if a method is native. */
23971    var reIsNative = RegExp('^' +
23972      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
23973      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
23974    );
23975
23976    /** Built-in value references. */
23977    var Buffer = moduleExports ? context.Buffer : undefined,
23978        Symbol = context.Symbol,
23979        Uint8Array = context.Uint8Array,
23980        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
23981        getPrototype = overArg(Object.getPrototypeOf, Object),
23982        objectCreate = Object.create,
23983        propertyIsEnumerable = objectProto.propertyIsEnumerable,
23984        splice = arrayProto.splice,
23985        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined,
23986        symIterator = Symbol ? Symbol.iterator : undefined,
23987        symToStringTag = Symbol ? Symbol.toStringTag : undefined;
23988
23989    var defineProperty = (function() {
23990      try {
23991        var func = getNative(Object, 'defineProperty');
23992        func({}, '', {});
23993        return func;
23994      } catch (e) {}
23995    }());
23996
23997    /** Mocked built-ins. */
23998    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
23999        ctxNow = Date && Date.now !== root.Date.now && Date.now,
24000        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
24001
24002    /* Built-in method references for those with the same name as other `lodash` methods. */
24003    var nativeCeil = Math.ceil,
24004        nativeFloor = Math.floor,
24005        nativeGetSymbols = Object.getOwnPropertySymbols,
24006        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
24007        nativeIsFinite = context.isFinite,
24008        nativeJoin = arrayProto.join,
24009        nativeKeys = overArg(Object.keys, Object),
24010        nativeMax = Math.max,
24011        nativeMin = Math.min,
24012        nativeNow = Date.now,
24013        nativeParseInt = context.parseInt,
24014        nativeRandom = Math.random,
24015        nativeReverse = arrayProto.reverse;
24016
24017    /* Built-in method references that are verified to be native. */
24018    var DataView = getNative(context, 'DataView'),
24019        Map = getNative(context, 'Map'),
24020        Promise = getNative(context, 'Promise'),
24021        Set = getNative(context, 'Set'),
24022        WeakMap = getNative(context, 'WeakMap'),
24023        nativeCreate = getNative(Object, 'create');
24024
24025    /** Used to store function metadata. */
24026    var metaMap = WeakMap && new WeakMap;
24027
24028    /** Used to lookup unminified function names. */
24029    var realNames = {};
24030
24031    /** Used to detect maps, sets, and weakmaps. */
24032    var dataViewCtorString = toSource(DataView),
24033        mapCtorString = toSource(Map),
24034        promiseCtorString = toSource(Promise),
24035        setCtorString = toSource(Set),
24036        weakMapCtorString = toSource(WeakMap);
24037
24038    /** Used to convert symbols to primitives and strings. */
24039    var symbolProto = Symbol ? Symbol.prototype : undefined,
24040        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
24041        symbolToString = symbolProto ? symbolProto.toString : undefined;
24042
24043    /*------------------------------------------------------------------------*/
24044
24045    /**
24046     * Creates a `lodash` object which wraps `value` to enable implicit method
24047     * chain sequences. Methods that operate on and return arrays, collections,
24048     * and functions can be chained together. Methods that retrieve a single value
24049     * or may return a primitive value will automatically end the chain sequence
24050     * and return the unwrapped value. Otherwise, the value must be unwrapped
24051     * with `_#value`.
24052     *
24053     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
24054     * enabled using `_.chain`.
24055     *
24056     * The execution of chained methods is lazy, that is, it's deferred until
24057     * `_#value` is implicitly or explicitly called.
24058     *
24059     * Lazy evaluation allows several methods to support shortcut fusion.
24060     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
24061     * the creation of intermediate arrays and can greatly reduce the number of
24062     * iteratee executions. Sections of a chain sequence qualify for shortcut
24063     * fusion if the section is applied to an array and iteratees accept only
24064     * one argument. The heuristic for whether a section qualifies for shortcut
24065     * fusion is subject to change.
24066     *
24067     * Chaining is supported in custom builds as long as the `_#value` method is
24068     * directly or indirectly included in the build.
24069     *
24070     * In addition to lodash methods, wrappers have `Array` and `String` methods.
24071     *
24072     * The wrapper `Array` methods are:
24073     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
24074     *
24075     * The wrapper `String` methods are:
24076     * `replace` and `split`
24077     *
24078     * The wrapper methods that support shortcut fusion are:
24079     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
24080     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
24081     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
24082     *
24083     * The chainable wrapper methods are:
24084     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
24085     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
24086     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
24087     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
24088     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
24089     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
24090     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
24091     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
24092     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
24093     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
24094     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
24095     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
24096     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
24097     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
24098     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
24099     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
24100     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
24101     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
24102     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
24103     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
24104     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
24105     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
24106     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
24107     * `zipObject`, `zipObjectDeep`, and `zipWith`
24108     *
24109     * The wrapper methods that are **not** chainable by default are:
vendor: 5,816 bytes, lines 24110-24287
24110     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
24111     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
24112     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
24113     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
24114     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
24115     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
24116     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
24117     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
24118     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
24119     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
24120     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
24121     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
24122     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
24123     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
24124     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
24125     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
24126     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
24127     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
24128     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
24129     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
24130     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
24131     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
24132     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
24133     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
24134     * `upperFirst`, `value`, and `words`
24135     *
24136     * @name _
24137     * @constructor
24138     * @category Seq
24139     * @param {*} value The value to wrap in a `lodash` instance.
24140     * @returns {Object} Returns the new `lodash` wrapper instance.
24141     * @example
24142     *
24143     * function square(n) {
24144     *   return n * n;
24145     * }
24146     *
24147     * var wrapped = _([1, 2, 3]);
24148     *
24149     * // Returns an unwrapped value.
24150     * wrapped.reduce(_.add);
24151     * // => 6
24152     *
24153     * // Returns a wrapped value.
24154     * var squares = wrapped.map(square);
24155     *
24156     * _.isArray(squares);
24157     * // => false
24158     *
24159     * _.isArray(squares.value());
24160     * // => true
24161     */
24162    function lodash(value) {
24163      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
24164        if (value instanceof LodashWrapper) {
24165          return value;
24166        }
24167        if (hasOwnProperty.call(value, '__wrapped__')) {
24168          return wrapperClone(value);
24169        }
24170      }
24171      return new LodashWrapper(value);
24172    }
24173
24174    /**
24175     * The base implementation of `_.create` without support for assigning
24176     * properties to the created object.
24177     *
24178     * @private
24179     * @param {Object} proto The object to inherit from.
24180     * @returns {Object} Returns the new object.
24181     */
24182    var baseCreate = (function() {
24183      function object() {}
24184      return function(proto) {
24185        if (!isObject(proto)) {
24186          return {};
24187        }
24188        if (objectCreate) {
24189          return objectCreate(proto);
24190        }
24191        object.prototype = proto;
24192        var result = new object;
24193        object.prototype = undefined;
24194        return result;
24195      };
24196    }());
24197
24198    /**
24199     * The function whose prototype chain sequence wrappers inherit from.
24200     *
24201     * @private
24202     */
24203    function baseLodash() {
24204      // No operation performed.
24205    }
24206
24207    /**
24208     * The base constructor for creating `lodash` wrapper objects.
24209     *
24210     * @private
24211     * @param {*} value The value to wrap.
24212     * @param {boolean} [chainAll] Enable explicit method chain sequences.
24213     */
24214    function LodashWrapper(value, chainAll) {
24215      this.__wrapped__ = value;
24216      this.__actions__ = [];
24217      this.__chain__ = !!chainAll;
24218      this.__index__ = 0;
24219      this.__values__ = undefined;
24220    }
24221
24222    /**
24223     * By default, the template delimiters used by lodash are like those in
24224     * embedded Ruby (ERB) as well as ES2015 template strings. Change the
24225     * following template settings to use alternative delimiters.
24226     *
24227     * **Security:** See
24228     * [threat model](https://github.com/lodash/lodash/blob/main/threat-model.md)
24229     * — `_.template` is insecure and will be removed in v5.
24230     *
24231     * @static
24232     * @memberOf _
24233     * @type {Object}
24234     */
24235    lodash.templateSettings = {
24236
24237      /**
24238       * Used to detect `data` property values to be HTML-escaped.
24239       *
24240       * @memberOf _.templateSettings
24241       * @type {RegExp}
24242       */
24243      'escape': reEscape,
24244
24245      /**
24246       * Used to detect code to be evaluated.
24247       *
24248       * @memberOf _.templateSettings
24249       * @type {RegExp}
24250       */
24251      'evaluate': reEvaluate,
24252
24253      /**
24254       * Used to detect `data` property values to inject.
24255       *
24256       * @memberOf _.templateSettings
24257       * @type {RegExp}
24258       */
24259      'interpolate': reInterpolate,
24260
24261      /**
24262       * Used to reference the data object in the template text.
24263       *
24264       * @memberOf _.templateSettings
24265       * @type {string}
24266       */
24267      'variable': '',
24268
24269      /**
24270       * Used to import variables into the compiled template.
24271       *
24272       * @memberOf _.templateSettings
24273       * @type {Object}
24274       */
24275      'imports': {
24276
24277        /**
24278         * A reference to the `lodash` function.
24279         *
24280         * @memberOf _.templateSettings.imports
24281         * @type {Function}
24282         */
24283        '_': lodash
24284      }
24285    };
24286
24287    // Ensure wrappers are instances of `baseLodash`.
vendor: 12,811 bytes, lines 24288-24766
24288    lodash.prototype = baseLodash.prototype;
24289    lodash.prototype.constructor = lodash;
24290
24291    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
24292    LodashWrapper.prototype.constructor = LodashWrapper;
24293
24294    /*------------------------------------------------------------------------*/
24295
24296    /**
24297     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
24298     *
24299     * @private
24300     * @constructor
24301     * @param {*} value The value to wrap.
24302     */
24303    function LazyWrapper(value) {
24304      this.__wrapped__ = value;
24305      this.__actions__ = [];
24306      this.__dir__ = 1;
24307      this.__filtered__ = false;
24308      this.__iteratees__ = [];
24309      this.__takeCount__ = MAX_ARRAY_LENGTH;
24310      this.__views__ = [];
24311    }
24312
24313    /**
24314     * Creates a clone of the lazy wrapper object.
24315     *
24316     * @private
24317     * @name clone
24318     * @memberOf LazyWrapper
24319     * @returns {Object} Returns the cloned `LazyWrapper` object.
24320     */
24321    function lazyClone() {
24322      var result = new LazyWrapper(this.__wrapped__);
24323      result.__actions__ = copyArray(this.__actions__);
24324      result.__dir__ = this.__dir__;
24325      result.__filtered__ = this.__filtered__;
24326      result.__iteratees__ = copyArray(this.__iteratees__);
24327      result.__takeCount__ = this.__takeCount__;
24328      result.__views__ = copyArray(this.__views__);
24329      return result;
24330    }
24331
24332    /**
24333     * Reverses the direction of lazy iteration.
24334     *
24335     * @private
24336     * @name reverse
24337     * @memberOf LazyWrapper
24338     * @returns {Object} Returns the new reversed `LazyWrapper` object.
24339     */
24340    function lazyReverse() {
24341      if (this.__filtered__) {
24342        var result = new LazyWrapper(this);
24343        result.__dir__ = -1;
24344        result.__filtered__ = true;
24345      } else {
24346        result = this.clone();
24347        result.__dir__ *= -1;
24348      }
24349      return result;
24350    }
24351
24352    /**
24353     * Extracts the unwrapped value from its lazy wrapper.
24354     *
24355     * @private
24356     * @name value
24357     * @memberOf LazyWrapper
24358     * @returns {*} Returns the unwrapped value.
24359     */
24360    function lazyValue() {
24361      var array = this.__wrapped__.value(),
24362          dir = this.__dir__,
24363          isArr = isArray(array),
24364          isRight = dir < 0,
24365          arrLength = isArr ? array.length : 0,
24366          view = getView(0, arrLength, this.__views__),
24367          start = view.start,
24368          end = view.end,
24369          length = end - start,
24370          index = isRight ? end : (start - 1),
24371          iteratees = this.__iteratees__,
24372          iterLength = iteratees.length,
24373          resIndex = 0,
24374          takeCount = nativeMin(length, this.__takeCount__);
24375
24376      if (!isArr || (!isRight && arrLength == length && takeCount == length)) {
24377        return baseWrapperValue(array, this.__actions__);
24378      }
24379      var result = [];
24380
24381      outer:
24382      while (length-- && resIndex < takeCount) {
24383        index += dir;
24384
24385        var iterIndex = -1,
24386            value = array[index];
24387
24388        while (++iterIndex < iterLength) {
24389          var data = iteratees[iterIndex],
24390              iteratee = data.iteratee,
24391              type = data.type,
24392              computed = iteratee(value);
24393
24394          if (type == LAZY_MAP_FLAG) {
24395            value = computed;
24396          } else if (!computed) {
24397            if (type == LAZY_FILTER_FLAG) {
24398              continue outer;
24399            } else {
24400              break outer;
24401            }
24402          }
24403        }
24404        result[resIndex++] = value;
24405      }
24406      return result;
24407    }
24408
24409    // Ensure `LazyWrapper` is an instance of `baseLodash`.
24410    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
24411    LazyWrapper.prototype.constructor = LazyWrapper;
24412
24413    /*------------------------------------------------------------------------*/
24414
24415    /**
24416     * Creates a hash object.
24417     *
24418     * @private
24419     * @constructor
24420     * @param {Array} [entries] The key-value pairs to cache.
24421     */
24422    function Hash(entries) {
24423      var index = -1,
24424          length = entries == null ? 0 : entries.length;
24425
24426      this.clear();
24427      while (++index < length) {
24428        var entry = entries[index];
24429        this.set(entry[0], entry[1]);
24430      }
24431    }
24432
24433    /**
24434     * Removes all key-value entries from the hash.
24435     *
24436     * @private
24437     * @name clear
24438     * @memberOf Hash
24439     */
24440    function hashClear() {
24441      this.__data__ = nativeCreate ? nativeCreate(null) : {};
24442      this.size = 0;
24443    }
24444
24445    /**
24446     * Removes `key` and its value from the hash.
24447     *
24448     * @private
24449     * @name delete
24450     * @memberOf Hash
24451     * @param {Object} hash The hash to modify.
24452     * @param {string} key The key of the value to remove.
24453     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
24454     */
24455    function hashDelete(key) {
24456      var result = this.has(key) && delete this.__data__[key];
24457      this.size -= result ? 1 : 0;
24458      return result;
24459    }
24460
24461    /**
24462     * Gets the hash value for `key`.
24463     *
24464     * @private
24465     * @name get
24466     * @memberOf Hash
24467     * @param {string} key The key of the value to get.
24468     * @returns {*} Returns the entry value.
24469     */
24470    function hashGet(key) {
24471      var data = this.__data__;
24472      if (nativeCreate) {
24473        var result = data[key];
24474        return result === HASH_UNDEFINED ? undefined : result;
24475      }
24476      return hasOwnProperty.call(data, key) ? data[key] : undefined;
24477    }
24478
24479    /**
24480     * Checks if a hash value for `key` exists.
24481     *
24482     * @private
24483     * @name has
24484     * @memberOf Hash
24485     * @param {string} key The key of the entry to check.
24486     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
24487     */
24488    function hashHas(key) {
24489      var data = this.__data__;
24490      return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
24491    }
24492
24493    /**
24494     * Sets the hash `key` to `value`.
24495     *
24496     * @private
24497     * @name set
24498     * @memberOf Hash
24499     * @param {string} key The key of the value to set.
24500     * @param {*} value The value to set.
24501     * @returns {Object} Returns the hash instance.
24502     */
24503    function hashSet(key, value) {
24504      var data = this.__data__;
24505      this.size += this.has(key) ? 0 : 1;
24506      data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
24507      return this;
24508    }
24509
24510    // Add methods to `Hash`.
24511    Hash.prototype.clear = hashClear;
24512    Hash.prototype['delete'] = hashDelete;
24513    Hash.prototype.get = hashGet;
24514    Hash.prototype.has = hashHas;
24515    Hash.prototype.set = hashSet;
24516
24517    /*------------------------------------------------------------------------*/
24518
24519    /**
24520     * Creates an list cache object.
24521     *
24522     * @private
24523     * @constructor
24524     * @param {Array} [entries] The key-value pairs to cache.
24525     */
24526    function ListCache(entries) {
24527      var index = -1,
24528          length = entries == null ? 0 : entries.length;
24529
24530      this.clear();
24531      while (++index < length) {
24532        var entry = entries[index];
24533        this.set(entry[0], entry[1]);
24534      }
24535    }
24536
24537    /**
24538     * Removes all key-value entries from the list cache.
24539     *
24540     * @private
24541     * @name clear
24542     * @memberOf ListCache
24543     */
24544    function listCacheClear() {
24545      this.__data__ = [];
24546      this.size = 0;
24547    }
24548
24549    /**
24550     * Removes `key` and its value from the list cache.
24551     *
24552     * @private
24553     * @name delete
24554     * @memberOf ListCache
24555     * @param {string} key The key of the value to remove.
24556     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
24557     */
24558    function listCacheDelete(key) {
24559      var data = this.__data__,
24560          index = assocIndexOf(data, key);
24561
24562      if (index < 0) {
24563        return false;
24564      }
24565      var lastIndex = data.length - 1;
24566      if (index == lastIndex) {
24567        data.pop();
24568      } else {
24569        splice.call(data, index, 1);
24570      }
24571      --this.size;
24572      return true;
24573    }
24574
24575    /**
24576     * Gets the list cache value for `key`.
24577     *
24578     * @private
24579     * @name get
24580     * @memberOf ListCache
24581     * @param {string} key The key of the value to get.
24582     * @returns {*} Returns the entry value.
24583     */
24584    function listCacheGet(key) {
24585      var data = this.__data__,
24586          index = assocIndexOf(data, key);
24587
24588      return index < 0 ? undefined : data[index][1];
24589    }
24590
24591    /**
24592     * Checks if a list cache value for `key` exists.
24593     *
24594     * @private
24595     * @name has
24596     * @memberOf ListCache
24597     * @param {string} key The key of the entry to check.
24598     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
24599     */
24600    function listCacheHas(key) {
24601      return assocIndexOf(this.__data__, key) > -1;
24602    }
24603
24604    /**
24605     * Sets the list cache `key` to `value`.
24606     *
24607     * @private
24608     * @name set
24609     * @memberOf ListCache
24610     * @param {string} key The key of the value to set.
24611     * @param {*} value The value to set.
24612     * @returns {Object} Returns the list cache instance.
24613     */
24614    function listCacheSet(key, value) {
24615      var data = this.__data__,
24616          index = assocIndexOf(data, key);
24617
24618      if (index < 0) {
24619        ++this.size;
24620        data.push([key, value]);
24621      } else {
24622        data[index][1] = value;
24623      }
24624      return this;
24625    }
24626
24627    // Add methods to `ListCache`.
24628    ListCache.prototype.clear = listCacheClear;
24629    ListCache.prototype['delete'] = listCacheDelete;
24630    ListCache.prototype.get = listCacheGet;
24631    ListCache.prototype.has = listCacheHas;
24632    ListCache.prototype.set = listCacheSet;
24633
24634    /*------------------------------------------------------------------------*/
24635
24636    /**
24637     * Creates a map cache object to store key-value pairs.
24638     *
24639     * @private
24640     * @constructor
24641     * @param {Array} [entries] The key-value pairs to cache.
24642     */
24643    function MapCache(entries) {
24644      var index = -1,
24645          length = entries == null ? 0 : entries.length;
24646
24647      this.clear();
24648      while (++index < length) {
24649        var entry = entries[index];
24650        this.set(entry[0], entry[1]);
24651      }
24652    }
24653
24654    /**
24655     * Removes all key-value entries from the map.
24656     *
24657     * @private
24658     * @name clear
24659     * @memberOf MapCache
24660     */
24661    function mapCacheClear() {
24662      this.size = 0;
24663      this.__data__ = {
24664        'hash': new Hash,
24665        'map': new (Map || ListCache),
24666        'string': new Hash
24667      };
24668    }
24669
24670    /**
24671     * Removes `key` and its value from the map.
24672     *
24673     * @private
24674     * @name delete
24675     * @memberOf MapCache
24676     * @param {string} key The key of the value to remove.
24677     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
24678     */
24679    function mapCacheDelete(key) {
24680      var result = getMapData(this, key)['delete'](key);
24681      this.size -= result ? 1 : 0;
24682      return result;
24683    }
24684
24685    /**
24686     * Gets the map value for `key`.
24687     *
24688     * @private
24689     * @name get
24690     * @memberOf MapCache
24691     * @param {string} key The key of the value to get.
24692     * @returns {*} Returns the entry value.
24693     */
24694    function mapCacheGet(key) {
24695      return getMapData(this, key).get(key);
24696    }
24697
24698    /**
24699     * Checks if a map value for `key` exists.
24700     *
24701     * @private
24702     * @name has
24703     * @memberOf MapCache
24704     * @param {string} key The key of the entry to check.
24705     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
24706     */
24707    function mapCacheHas(key) {
24708      return getMapData(this, key).has(key);
24709    }
24710
24711    /**
24712     * Sets the map `key` to `value`.
24713     *
24714     * @private
24715     * @name set
24716     * @memberOf MapCache
24717     * @param {string} key The key of the value to set.
24718     * @param {*} value The value to set.
24719     * @returns {Object} Returns the map cache instance.
24720     */
24721    function mapCacheSet(key, value) {
24722      var data = getMapData(this, key),
24723          size = data.size;
24724
24725      data.set(key, value);
24726      this.size += data.size == size ? 0 : 1;
24727      return this;
24728    }
24729
24730    // Add methods to `MapCache`.
24731    MapCache.prototype.clear = mapCacheClear;
24732    MapCache.prototype['delete'] = mapCacheDelete;
24733    MapCache.prototype.get = mapCacheGet;
24734    MapCache.prototype.has = mapCacheHas;
24735    MapCache.prototype.set = mapCacheSet;
24736
24737    /*------------------------------------------------------------------------*/
24738
24739    /**
24740     *
24741     * Creates an array cache object to store unique values.
24742     *
24743     * @private
24744     * @constructor
24745     * @param {Array} [values] The values to cache.
24746     */
24747    function SetCache(values) {
24748      var index = -1,
24749          length = values == null ? 0 : values.length;
24750
24751      this.__data__ = new MapCache;
24752      while (++index < length) {
24753        this.add(values[index]);
24754      }
24755    }
24756
24757    /**
24758     * Adds `value` to the array cache.
24759     *
24760     * @private
24761     * @name add
24762     * @memberOf SetCache
24763     * @alias push
24764     * @param {*} value The value to cache.
24765     * @returns {Object} Returns the cache instance.
24766     */
vendor: 3,742 bytes, lines 24767-24903
24767    function setCacheAdd(value) {
24768      this.__data__.set(value, HASH_UNDEFINED);
24769      return this;
24770    }
24771
24772    /**
24773     * Checks if `value` is in the array cache.
24774     *
24775     * @private
24776     * @name has
24777     * @memberOf SetCache
24778     * @param {*} value The value to search for.
24779     * @returns {boolean} Returns `true` if `value` is found, else `false`.
24780     */
24781    function setCacheHas(value) {
24782      return this.__data__.has(value);
24783    }
24784
24785    // Add methods to `SetCache`.
24786    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
24787    SetCache.prototype.has = setCacheHas;
24788
24789    /*------------------------------------------------------------------------*/
24790
24791    /**
24792     * Creates a stack cache object to store key-value pairs.
24793     *
24794     * @private
24795     * @constructor
24796     * @param {Array} [entries] The key-value pairs to cache.
24797     */
24798    function Stack(entries) {
24799      var data = this.__data__ = new ListCache(entries);
24800      this.size = data.size;
24801    }
24802
24803    /**
24804     * Removes all key-value entries from the stack.
24805     *
24806     * @private
24807     * @name clear
24808     * @memberOf Stack
24809     */
24810    function stackClear() {
24811      this.__data__ = new ListCache;
24812      this.size = 0;
24813    }
24814
24815    /**
24816     * Removes `key` and its value from the stack.
24817     *
24818     * @private
24819     * @name delete
24820     * @memberOf Stack
24821     * @param {string} key The key of the value to remove.
24822     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
24823     */
24824    function stackDelete(key) {
24825      var data = this.__data__,
24826          result = data['delete'](key);
24827
24828      this.size = data.size;
24829      return result;
24830    }
24831
24832    /**
24833     * Gets the stack value for `key`.
24834     *
24835     * @private
24836     * @name get
24837     * @memberOf Stack
24838     * @param {string} key The key of the value to get.
24839     * @returns {*} Returns the entry value.
24840     */
24841    function stackGet(key) {
24842      return this.__data__.get(key);
24843    }
24844
24845    /**
24846     * Checks if a stack value for `key` exists.
24847     *
24848     * @private
24849     * @name has
24850     * @memberOf Stack
24851     * @param {string} key The key of the entry to check.
24852     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
24853     */
24854    function stackHas(key) {
24855      return this.__data__.has(key);
24856    }
24857
24858    /**
24859     * Sets the stack `key` to `value`.
24860     *
24861     * @private
24862     * @name set
24863     * @memberOf Stack
24864     * @param {string} key The key of the value to set.
24865     * @param {*} value The value to set.
24866     * @returns {Object} Returns the stack cache instance.
24867     */
24868    function stackSet(key, value) {
24869      var data = this.__data__;
24870      if (data instanceof ListCache) {
24871        var pairs = data.__data__;
24872        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
24873          pairs.push([key, value]);
24874          this.size = ++data.size;
24875          return this;
24876        }
24877        data = this.__data__ = new MapCache(pairs);
24878      }
24879      data.set(key, value);
24880      this.size = data.size;
24881      return this;
24882    }
24883
24884    // Add methods to `Stack`.
24885    Stack.prototype.clear = stackClear;
24886    Stack.prototype['delete'] = stackDelete;
24887    Stack.prototype.get = stackGet;
24888    Stack.prototype.has = stackHas;
24889    Stack.prototype.set = stackSet;
24890
24891    /*------------------------------------------------------------------------*/
24892
24893    /**
24894     * Creates an array of the enumerable property names of the array-like `value`.
24895     *
24896     * @private
24897     * @param {*} value The value to query.
24898     * @param {boolean} inherited Specify returning inherited property names.
24899     * @returns {Array} Returns the array of property names.
24900     */
24901    function arrayLikeKeys(value, inherited) {
24902      var isArr = isArray(value),
24903          isArg = !isArr && isArguments(value),
vendor: 43,113 bytes, lines 24904-26180
24904          isBuff = !isArr && !isArg && isBuffer(value),
24905          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
24906          skipIndexes = isArr || isArg || isBuff || isType,
24907          result = skipIndexes ? baseTimes(value.length, String) : [],
24908          length = result.length;
24909
24910      for (var key in value) {
24911        if ((inherited || hasOwnProperty.call(value, key)) &&
24912            !(skipIndexes && (
24913               // Safari 9 has enumerable `arguments.length` in strict mode.
24914               key == 'length' ||
24915               // Node.js 0.10 has enumerable non-index properties on buffers.
24916               (isBuff && (key == 'offset' || key == 'parent')) ||
24917               // PhantomJS 2 has enumerable non-index properties on typed arrays.
24918               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
24919               // Skip index properties.
24920               isIndex(key, length)
24921            ))) {
24922          result.push(key);
24923        }
24924      }
24925      return result;
24926    }
24927
24928    /**
24929     * A specialized version of `_.sample` for arrays.
24930     *
24931     * @private
24932     * @param {Array} array The array to sample.
24933     * @returns {*} Returns the random element.
24934     */
24935    function arraySample(array) {
24936      var length = array.length;
24937      return length ? array[baseRandom(0, length - 1)] : undefined;
24938    }
24939
24940    /**
24941     * A specialized version of `_.sampleSize` for arrays.
24942     *
24943     * @private
24944     * @param {Array} array The array to sample.
24945     * @param {number} n The number of elements to sample.
24946     * @returns {Array} Returns the random elements.
24947     */
24948    function arraySampleSize(array, n) {
24949      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
24950    }
24951
24952    /**
24953     * A specialized version of `_.shuffle` for arrays.
24954     *
24955     * @private
24956     * @param {Array} array The array to shuffle.
24957     * @returns {Array} Returns the new shuffled array.
24958     */
24959    function arrayShuffle(array) {
24960      return shuffleSelf(copyArray(array));
24961    }
24962
24963    /**
24964     * This function is like `assignValue` except that it doesn't assign
24965     * `undefined` values.
24966     *
24967     * @private
24968     * @param {Object} object The object to modify.
24969     * @param {string} key The key of the property to assign.
24970     * @param {*} value The value to assign.
24971     */
24972    function assignMergeValue(object, key, value) {
24973      if ((value !== undefined && !eq(object[key], value)) ||
24974          (value === undefined && !(key in object))) {
24975        baseAssignValue(object, key, value);
24976      }
24977    }
24978
24979    /**
24980     * Assigns `value` to `key` of `object` if the existing value is not equivalent
24981     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
24982     * for equality comparisons.
24983     *
24984     * @private
24985     * @param {Object} object The object to modify.
24986     * @param {string} key The key of the property to assign.
24987     * @param {*} value The value to assign.
24988     */
24989    function assignValue(object, key, value) {
24990      var objValue = object[key];
24991      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
24992          (value === undefined && !(key in object))) {
24993        baseAssignValue(object, key, value);
24994      }
24995    }
24996
24997    /**
24998     * Gets the index at which the `key` is found in `array` of key-value pairs.
24999     *
25000     * @private
25001     * @param {Array} array The array to inspect.
25002     * @param {*} key The key to search for.
25003     * @returns {number} Returns the index of the matched value, else `-1`.
25004     */
25005    function assocIndexOf(array, key) {
25006      var length = array.length;
25007      while (length--) {
25008        if (eq(array[length][0], key)) {
25009          return length;
25010        }
25011      }
25012      return -1;
25013    }
25014
25015    /**
25016     * Aggregates elements of `collection` on `accumulator` with keys transformed
25017     * by `iteratee` and values set by `setter`.
25018     *
25019     * @private
25020     * @param {Array|Object} collection The collection to iterate over.
25021     * @param {Function} setter The function to set `accumulator` values.
25022     * @param {Function} iteratee The iteratee to transform keys.
25023     * @param {Object} accumulator The initial aggregated object.
25024     * @returns {Function} Returns `accumulator`.
25025     */
25026    function baseAggregator(collection, setter, iteratee, accumulator) {
25027      baseEach(collection, function(value, key, collection) {
25028        setter(accumulator, value, iteratee(value), collection);
25029      });
25030      return accumulator;
25031    }
25032
25033    /**
25034     * The base implementation of `_.assign` without support for multiple sources
25035     * or `customizer` functions.
25036     *
25037     * @private
25038     * @param {Object} object The destination object.
25039     * @param {Object} source The source object.
25040     * @returns {Object} Returns `object`.
25041     */
25042    function baseAssign(object, source) {
25043      return object && copyObject(source, keys(source), object);
25044    }
25045
25046    /**
25047     * The base implementation of `_.assignIn` without support for multiple sources
25048     * or `customizer` functions.
25049     *
25050     * @private
25051     * @param {Object} object The destination object.
25052     * @param {Object} source The source object.
25053     * @returns {Object} Returns `object`.
25054     */
25055    function baseAssignIn(object, source) {
25056      return object && copyObject(source, keysIn(source), object);
25057    }
25058
25059    /**
25060     * The base implementation of `assignValue` and `assignMergeValue` without
25061     * value checks.
25062     *
25063     * @private
25064     * @param {Object} object The object to modify.
25065     * @param {string} key The key of the property to assign.
25066     * @param {*} value The value to assign.
25067     */
25068    function baseAssignValue(object, key, value) {
25069      if (key == '__proto__' && defineProperty) {
25070        defineProperty(object, key, {
25071          'configurable': true,
25072          'enumerable': true,
25073          'value': value,
25074          'writable': true
25075        });
25076      } else {
25077        object[key] = value;
25078      }
25079    }
25080
25081    /**
25082     * The base implementation of `_.at` without support for individual paths.
25083     *
25084     * @private
25085     * @param {Object} object The object to iterate over.
25086     * @param {string[]} paths The property paths to pick.
25087     * @returns {Array} Returns the picked elements.
25088     */
25089    function baseAt(object, paths) {
25090      var index = -1,
25091          length = paths.length,
25092          result = Array(length),
25093          skip = object == null;
25094
25095      while (++index < length) {
25096        result[index] = skip ? undefined : get(object, paths[index]);
25097      }
25098      return result;
25099    }
25100
25101    /**
25102     * The base implementation of `_.clamp` which doesn't coerce arguments.
25103     *
25104     * @private
25105     * @param {number} number The number to clamp.
25106     * @param {number} [lower] The lower bound.
25107     * @param {number} upper The upper bound.
25108     * @returns {number} Returns the clamped number.
25109     */
25110    function baseClamp(number, lower, upper) {
25111      if (number === number) {
25112        if (upper !== undefined) {
25113          number = number <= upper ? number : upper;
25114        }
25115        if (lower !== undefined) {
25116          number = number >= lower ? number : lower;
25117        }
25118      }
25119      return number;
25120    }
25121
25122    /**
25123     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
25124     * traversed objects.
25125     *
25126     * @private
25127     * @param {*} value The value to clone.
25128     * @param {boolean} bitmask The bitmask flags.
25129     *  1 - Deep clone
25130     *  2 - Flatten inherited properties
25131     *  4 - Clone symbols
25132     * @param {Function} [customizer] The function to customize cloning.
25133     * @param {string} [key] The key of `value`.
25134     * @param {Object} [object] The parent object of `value`.
25135     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
25136     * @returns {*} Returns the cloned value.
25137     */
25138    function baseClone(value, bitmask, customizer, key, object, stack) {
25139      var result,
25140          isDeep = bitmask & CLONE_DEEP_FLAG,
25141          isFlat = bitmask & CLONE_FLAT_FLAG,
25142          isFull = bitmask & CLONE_SYMBOLS_FLAG;
25143
25144      if (customizer) {
25145        result = object ? customizer(value, key, object, stack) : customizer(value);
25146      }
25147      if (result !== undefined) {
25148        return result;
25149      }
25150      if (!isObject(value)) {
25151        return value;
25152      }
25153      var isArr = isArray(value);
25154      if (isArr) {
25155        result = initCloneArray(value);
25156        if (!isDeep) {
25157          return copyArray(value, result);
25158        }
25159      } else {
25160        var tag = getTag(value),
25161            isFunc = tag == funcTag || tag == genTag;
25162
25163        if (isBuffer(value)) {
25164          return cloneBuffer(value, isDeep);
25165        }
25166        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
25167          result = (isFlat || isFunc) ? {} : initCloneObject(value);
25168          if (!isDeep) {
25169            return isFlat
25170              ? copySymbolsIn(value, baseAssignIn(result, value))
25171              : copySymbols(value, baseAssign(result, value));
25172          }
25173        } else {
25174          if (!cloneableTags[tag]) {
25175            return object ? value : {};
25176          }
25177          result = initCloneByTag(value, tag, isDeep);
25178        }
25179      }
25180      // Check for circular references and return its corresponding clone.
25181      stack || (stack = new Stack);
25182      var stacked = stack.get(value);
25183      if (stacked) {
25184        return stacked;
25185      }
25186      stack.set(value, result);
25187
25188      if (isSet(value)) {
25189        value.forEach(function(subValue) {
25190          result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
25191        });
25192      } else if (isMap(value)) {
25193        value.forEach(function(subValue, key) {
25194          result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
25195        });
25196      }
25197
25198      var keysFunc = isFull
25199        ? (isFlat ? getAllKeysIn : getAllKeys)
25200        : (isFlat ? keysIn : keys);
25201
25202      var props = isArr ? undefined : keysFunc(value);
25203      arrayEach(props || value, function(subValue, key) {
25204        if (props) {
25205          key = subValue;
25206          subValue = value[key];
25207        }
25208        // Recursively populate clone (susceptible to call stack limits).
25209        assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
25210      });
25211      return result;
25212    }
25213
25214    /**
25215     * The base implementation of `_.conforms` which doesn't clone `source`.
25216     *
25217     * @private
25218     * @param {Object} source The object of property predicates to conform to.
25219     * @returns {Function} Returns the new spec function.
25220     */
25221    function baseConforms(source) {
25222      var props = keys(source);
25223      return function(object) {
25224        return baseConformsTo(object, source, props);
25225      };
25226    }
25227
25228    /**
25229     * The base implementation of `_.conformsTo` which accepts `props` to check.
25230     *
25231     * @private
25232     * @param {Object} object The object to inspect.
25233     * @param {Object} source The object of property predicates to conform to.
25234     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
25235     */
25236    function baseConformsTo(object, source, props) {
25237      var length = props.length;
25238      if (object == null) {
25239        return !length;
25240      }
25241      object = Object(object);
25242      while (length--) {
25243        var key = props[length],
25244            predicate = source[key],
25245            value = object[key];
25246
25247        if ((value === undefined && !(key in object)) || !predicate(value)) {
25248          return false;
25249        }
25250      }
25251      return true;
25252    }
25253
25254    /**
25255     * The base implementation of `_.delay` and `_.defer` which accepts `args`
25256     * to provide to `func`.
25257     *
25258     * @private
25259     * @param {Function} func The function to delay.
25260     * @param {number} wait The number of milliseconds to delay invocation.
25261     * @param {Array} args The arguments to provide to `func`.
25262     * @returns {number|Object} Returns the timer id or timeout object.
25263     */
25264    function baseDelay(func, wait, args) {
25265      if (typeof func != 'function') {
25266        throw new TypeError(FUNC_ERROR_TEXT);
25267      }
25268      return setTimeout(function() { func.apply(undefined, args); }, wait);
25269    }
25270
25271    /**
25272     * The base implementation of methods like `_.difference` without support
25273     * for excluding multiple arrays or iteratee shorthands.
25274     *
25275     * @private
25276     * @param {Array} array The array to inspect.
25277     * @param {Array} values The values to exclude.
25278     * @param {Function} [iteratee] The iteratee invoked per element.
25279     * @param {Function} [comparator] The comparator invoked per element.
25280     * @returns {Array} Returns the new array of filtered values.
25281     */
25282    function baseDifference(array, values, iteratee, comparator) {
25283      var index = -1,
25284          includes = arrayIncludes,
25285          isCommon = true,
25286          length = array.length,
25287          result = [],
25288          valuesLength = values.length;
25289
25290      if (!length) {
25291        return result;
25292      }
25293      if (iteratee) {
25294        values = arrayMap(values, baseUnary(iteratee));
25295      }
25296      if (comparator) {
25297        includes = arrayIncludesWith;
25298        isCommon = false;
25299      }
25300      else if (values.length >= LARGE_ARRAY_SIZE) {
25301        includes = cacheHas;
25302        isCommon = false;
25303        values = new SetCache(values);
25304      }
25305      outer:
25306      while (++index < length) {
25307        var value = array[index],
25308            computed = iteratee == null ? value : iteratee(value);
25309
25310        value = (comparator || value !== 0) ? value : 0;
25311        if (isCommon && computed === computed) {
25312          var valuesIndex = valuesLength;
25313          while (valuesIndex--) {
25314            if (values[valuesIndex] === computed) {
25315              continue outer;
25316            }
25317          }
25318          result.push(value);
25319        }
25320        else if (!includes(values, computed, comparator)) {
25321          result.push(value);
25322        }
25323      }
25324      return result;
25325    }
25326
25327    /**
25328     * The base implementation of `_.forEach` without support for iteratee shorthands.
25329     *
25330     * @private
25331     * @param {Array|Object} collection The collection to iterate over.
25332     * @param {Function} iteratee The function invoked per iteration.
25333     * @returns {Array|Object} Returns `collection`.
25334     */
25335    var baseEach = createBaseEach(baseForOwn);
25336
25337    /**
25338     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
25339     *
25340     * @private
25341     * @param {Array|Object} collection The collection to iterate over.
25342     * @param {Function} iteratee The function invoked per iteration.
25343     * @returns {Array|Object} Returns `collection`.
25344     */
25345    var baseEachRight = createBaseEach(baseForOwnRight, true);
25346
25347    /**
25348     * The base implementation of `_.every` without support for iteratee shorthands.
25349     *
25350     * @private
25351     * @param {Array|Object} collection The collection to iterate over.
25352     * @param {Function} predicate The function invoked per iteration.
25353     * @returns {boolean} Returns `true` if all elements pass the predicate check,
25354     *  else `false`
25355     */
25356    function baseEvery(collection, predicate) {
25357      var result = true;
25358      baseEach(collection, function(value, index, collection) {
25359        result = !!predicate(value, index, collection);
25360        return result;
25361      });
25362      return result;
25363    }
25364
25365    /**
25366     * The base implementation of methods like `_.max` and `_.min` which accepts a
25367     * `comparator` to determine the extremum value.
25368     *
25369     * @private
25370     * @param {Array} array The array to iterate over.
25371     * @param {Function} iteratee The iteratee invoked per iteration.
25372     * @param {Function} comparator The comparator used to compare values.
25373     * @returns {*} Returns the extremum value.
25374     */
25375    function baseExtremum(array, iteratee, comparator) {
25376      var index = -1,
25377          length = array.length;
25378
25379      while (++index < length) {
25380        var value = array[index],
25381            current = iteratee(value);
25382
25383        if (current != null && (computed === undefined
25384              ? (current === current && !isSymbol(current))
25385              : comparator(current, computed)
25386            )) {
25387          var computed = current,
25388              result = value;
25389        }
25390      }
25391      return result;
25392    }
25393
25394    /**
25395     * The base implementation of `_.fill` without an iteratee call guard.
25396     *
25397     * @private
25398     * @param {Array} array The array to fill.
25399     * @param {*} value The value to fill `array` with.
25400     * @param {number} [start=0] The start position.
25401     * @param {number} [end=array.length] The end position.
25402     * @returns {Array} Returns `array`.
25403     */
25404    function baseFill(array, value, start, end) {
25405      var length = array.length;
25406
25407      start = toInteger(start);
25408      if (start < 0) {
25409        start = -start > length ? 0 : (length + start);
25410      }
25411      end = (end === undefined || end > length) ? length : toInteger(end);
25412      if (end < 0) {
25413        end += length;
25414      }
25415      end = start > end ? 0 : toLength(end);
25416      while (start < end) {
25417        array[start++] = value;
25418      }
25419      return array;
25420    }
25421
25422    /**
25423     * The base implementation of `_.filter` without support for iteratee shorthands.
25424     *
25425     * @private
25426     * @param {Array|Object} collection The collection to iterate over.
25427     * @param {Function} predicate The function invoked per iteration.
25428     * @returns {Array} Returns the new filtered array.
25429     */
25430    function baseFilter(collection, predicate) {
25431      var result = [];
25432      baseEach(collection, function(value, index, collection) {
25433        if (predicate(value, index, collection)) {
25434          result.push(value);
25435        }
25436      });
25437      return result;
25438    }
25439
25440    /**
25441     * The base implementation of `_.flatten` with support for restricting flattening.
25442     *
25443     * @private
25444     * @param {Array} array The array to flatten.
25445     * @param {number} depth The maximum recursion depth.
25446     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
25447     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
25448     * @param {Array} [result=[]] The initial result value.
25449     * @returns {Array} Returns the new flattened array.
25450     */
25451    function baseFlatten(array, depth, predicate, isStrict, result) {
25452      var index = -1,
25453          length = array.length;
25454
25455      predicate || (predicate = isFlattenable);
25456      result || (result = []);
25457
25458      while (++index < length) {
25459        var value = array[index];
25460        if (depth > 0 && predicate(value)) {
25461          if (depth > 1) {
25462            // Recursively flatten arrays (susceptible to call stack limits).
25463            baseFlatten(value, depth - 1, predicate, isStrict, result);
25464          } else {
25465            arrayPush(result, value);
25466          }
25467        } else if (!isStrict) {
25468          result[result.length] = value;
25469        }
25470      }
25471      return result;
25472    }
25473
25474    /**
25475     * The base implementation of `baseForOwn` which iterates over `object`
25476     * properties returned by `keysFunc` and invokes `iteratee` for each property.
25477     * Iteratee functions may exit iteration early by explicitly returning `false`.
25478     *
25479     * @private
25480     * @param {Object} object The object to iterate over.
25481     * @param {Function} iteratee The function invoked per iteration.
25482     * @param {Function} keysFunc The function to get the keys of `object`.
25483     * @returns {Object} Returns `object`.
25484     */
25485    var baseFor = createBaseFor();
25486
25487    /**
25488     * This function is like `baseFor` except that it iterates over properties
25489     * in the opposite order.
25490     *
25491     * @private
25492     * @param {Object} object The object to iterate over.
25493     * @param {Function} iteratee The function invoked per iteration.
25494     * @param {Function} keysFunc The function to get the keys of `object`.
25495     * @returns {Object} Returns `object`.
25496     */
25497    var baseForRight = createBaseFor(true);
25498
25499    /**
25500     * The base implementation of `_.forOwn` without support for iteratee shorthands.
25501     *
25502     * @private
25503     * @param {Object} object The object to iterate over.
25504     * @param {Function} iteratee The function invoked per iteration.
25505     * @returns {Object} Returns `object`.
25506     */
25507    function baseForOwn(object, iteratee) {
25508      return object && baseFor(object, iteratee, keys);
25509    }
25510
25511    /**
25512     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
25513     *
25514     * @private
25515     * @param {Object} object The object to iterate over.
25516     * @param {Function} iteratee The function invoked per iteration.
25517     * @returns {Object} Returns `object`.
25518     */
25519    function baseForOwnRight(object, iteratee) {
25520      return object && baseForRight(object, iteratee, keys);
25521    }
25522
25523    /**
25524     * The base implementation of `_.functions` which creates an array of
25525     * `object` function property names filtered from `props`.
25526     *
25527     * @private
25528     * @param {Object} object The object to inspect.
25529     * @param {Array} props The property names to filter.
25530     * @returns {Array} Returns the function names.
25531     */
25532    function baseFunctions(object, props) {
25533      return arrayFilter(props, function(key) {
25534        return isFunction(object[key]);
25535      });
25536    }
25537
25538    /**
25539     * The base implementation of `_.get` without support for default values.
25540     *
25541     * @private
25542     * @param {Object} object The object to query.
25543     * @param {Array|string} path The path of the property to get.
25544     * @returns {*} Returns the resolved value.
25545     */
25546    function baseGet(object, path) {
25547      path = castPath(path, object);
25548
25549      var index = 0,
25550          length = path.length;
25551
25552      while (object != null && index < length) {
25553        object = object[toKey(path[index++])];
25554      }
25555      return (index && index == length) ? object : undefined;
25556    }
25557
25558    /**
25559     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
25560     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
25561     * symbols of `object`.
25562     *
25563     * @private
25564     * @param {Object} object The object to query.
25565     * @param {Function} keysFunc The function to get the keys of `object`.
25566     * @param {Function} symbolsFunc The function to get the symbols of `object`.
25567     * @returns {Array} Returns the array of property names and symbols.
25568     */
25569    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
25570      var result = keysFunc(object);
25571      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
25572    }
25573
25574    /**
25575     * The base implementation of `getTag` without fallbacks for buggy environments.
25576     *
25577     * @private
25578     * @param {*} value The value to query.
25579     * @returns {string} Returns the `toStringTag`.
25580     */
25581    function baseGetTag(value) {
25582      if (value == null) {
25583        return value === undefined ? undefinedTag : nullTag;
25584      }
25585      return (symToStringTag && symToStringTag in Object(value))
25586        ? getRawTag(value)
25587        : objectToString(value);
25588    }
25589
25590    /**
25591     * The base implementation of `_.gt` which doesn't coerce arguments.
25592     *
25593     * @private
25594     * @param {*} value The value to compare.
25595     * @param {*} other The other value to compare.
25596     * @returns {boolean} Returns `true` if `value` is greater than `other`,
25597     *  else `false`.
25598     */
25599    function baseGt(value, other) {
25600      return value > other;
25601    }
25602
25603    /**
25604     * The base implementation of `_.has` without support for deep paths.
25605     *
25606     * @private
25607     * @param {Object} [object] The object to query.
25608     * @param {Array|string} key The key to check.
25609     * @returns {boolean} Returns `true` if `key` exists, else `false`.
25610     */
25611    function baseHas(object, key) {
25612      return object != null && hasOwnProperty.call(object, key);
25613    }
25614
25615    /**
25616     * The base implementation of `_.hasIn` without support for deep paths.
25617     *
25618     * @private
25619     * @param {Object} [object] The object to query.
25620     * @param {Array|string} key The key to check.
25621     * @returns {boolean} Returns `true` if `key` exists, else `false`.
25622     */
25623    function baseHasIn(object, key) {
25624      return object != null && key in Object(object);
25625    }
25626
25627    /**
25628     * The base implementation of `_.inRange` which doesn't coerce arguments.
25629     *
25630     * @private
25631     * @param {number} number The number to check.
25632     * @param {number} start The start of the range.
25633     * @param {number} end The end of the range.
25634     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
25635     */
25636    function baseInRange(number, start, end) {
25637      return number >= nativeMin(start, end) && number < nativeMax(start, end);
25638    }
25639
25640    /**
25641     * The base implementation of methods like `_.intersection`, without support
25642     * for iteratee shorthands, that accepts an array of arrays to inspect.
25643     *
25644     * @private
25645     * @param {Array} arrays The arrays to inspect.
25646     * @param {Function} [iteratee] The iteratee invoked per element.
25647     * @param {Function} [comparator] The comparator invoked per element.
25648     * @returns {Array} Returns the new array of shared values.
25649     */
25650    function baseIntersection(arrays, iteratee, comparator) {
25651      var includes = comparator ? arrayIncludesWith : arrayIncludes,
25652          length = arrays[0].length,
25653          othLength = arrays.length,
25654          othIndex = othLength,
25655          caches = Array(othLength),
25656          maxLength = Infinity,
25657          result = [];
25658
25659      while (othIndex--) {
25660        var array = arrays[othIndex];
25661        if (othIndex && iteratee) {
25662          array = arrayMap(array, baseUnary(iteratee));
25663        }
25664        maxLength = nativeMin(array.length, maxLength);
25665        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
25666          ? new SetCache(othIndex && array)
25667          : undefined;
25668      }
25669      array = arrays[0];
25670
25671      var index = -1,
25672          seen = caches[0];
25673
25674      outer:
25675      while (++index < length && result.length < maxLength) {
25676        var value = array[index],
25677            computed = iteratee ? iteratee(value) : value;
25678
25679        value = (comparator || value !== 0) ? value : 0;
25680        if (!(seen
25681              ? cacheHas(seen, computed)
25682              : includes(result, computed, comparator)
25683            )) {
25684          othIndex = othLength;
25685          while (--othIndex) {
25686            var cache = caches[othIndex];
25687            if (!(cache
25688                  ? cacheHas(cache, computed)
25689                  : includes(arrays[othIndex], computed, comparator))
25690                ) {
25691              continue outer;
25692            }
25693          }
25694          if (seen) {
25695            seen.push(computed);
25696          }
25697          result.push(value);
25698        }
25699      }
25700      return result;
25701    }
25702
25703    /**
25704     * The base implementation of `_.invert` and `_.invertBy` which inverts
25705     * `object` with values transformed by `iteratee` and set by `setter`.
25706     *
25707     * @private
25708     * @param {Object} object The object to iterate over.
25709     * @param {Function} setter The function to set `accumulator` values.
25710     * @param {Function} iteratee The iteratee to transform values.
25711     * @param {Object} accumulator The initial inverted object.
25712     * @returns {Function} Returns `accumulator`.
25713     */
25714    function baseInverter(object, setter, iteratee, accumulator) {
25715      baseForOwn(object, function(value, key, object) {
25716        setter(accumulator, iteratee(value), key, object);
25717      });
25718      return accumulator;
25719    }
25720
25721    /**
25722     * The base implementation of `_.invoke` without support for individual
25723     * method arguments.
25724     *
25725     * @private
25726     * @param {Object} object The object to query.
25727     * @param {Array|string} path The path of the method to invoke.
25728     * @param {Array} args The arguments to invoke the method with.
25729     * @returns {*} Returns the result of the invoked method.
25730     */
25731    function baseInvoke(object, path, args) {
25732      path = castPath(path, object);
25733      object = parent(object, path);
25734      var func = object == null ? object : object[toKey(last(path))];
25735      return func == null ? undefined : apply(func, object, args);
25736    }
25737
25738    /**
25739     * The base implementation of `_.isArguments`.
25740     *
25741     * @private
25742     * @param {*} value The value to check.
25743     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
25744     */
25745    function baseIsArguments(value) {
25746      return isObjectLike(value) && baseGetTag(value) == argsTag;
25747    }
25748
25749    /**
25750     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
25751     *
25752     * @private
25753     * @param {*} value The value to check.
25754     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
25755     */
25756    function baseIsArrayBuffer(value) {
25757      return isObjectLike(value) && baseGetTag(value) == arrayBufferTag;
25758    }
25759
25760    /**
25761     * The base implementation of `_.isDate` without Node.js optimizations.
25762     *
25763     * @private
25764     * @param {*} value The value to check.
25765     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
25766     */
25767    function baseIsDate(value) {
25768      return isObjectLike(value) && baseGetTag(value) == dateTag;
25769    }
25770
25771    /**
25772     * The base implementation of `_.isEqual` which supports partial comparisons
25773     * and tracks traversed objects.
25774     *
25775     * @private
25776     * @param {*} value The value to compare.
25777     * @param {*} other The other value to compare.
25778     * @param {boolean} bitmask The bitmask flags.
25779     *  1 - Unordered comparison
25780     *  2 - Partial comparison
25781     * @param {Function} [customizer] The function to customize comparisons.
25782     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
25783     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
25784     */
25785    function baseIsEqual(value, other, bitmask, customizer, stack) {
25786      if (value === other) {
25787        return true;
25788      }
25789      if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
25790        return value !== value && other !== other;
25791      }
25792      return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
25793    }
25794
25795    /**
25796     * A specialized version of `baseIsEqual` for arrays and objects which performs
25797     * deep comparisons and tracks traversed objects enabling objects with circular
25798     * references to be compared.
25799     *
25800     * @private
25801     * @param {Object} object The object to compare.
25802     * @param {Object} other The other object to compare.
25803     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
25804     * @param {Function} customizer The function to customize comparisons.
25805     * @param {Function} equalFunc The function to determine equivalents of values.
25806     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
25807     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
25808     */
25809    function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
25810      var objIsArr = isArray(object),
25811          othIsArr = isArray(other),
25812          objTag = objIsArr ? arrayTag : getTag(object),
25813          othTag = othIsArr ? arrayTag : getTag(other);
25814
25815      objTag = objTag == argsTag ? objectTag : objTag;
25816      othTag = othTag == argsTag ? objectTag : othTag;
25817
25818      var objIsObj = objTag == objectTag,
25819          othIsObj = othTag == objectTag,
25820          isSameTag = objTag == othTag;
25821
25822      if (isSameTag && isBuffer(object)) {
25823        if (!isBuffer(other)) {
25824          return false;
25825        }
25826        objIsArr = true;
25827        objIsObj = false;
25828      }
25829      if (isSameTag && !objIsObj) {
25830        stack || (stack = new Stack);
25831        return (objIsArr || isTypedArray(object))
25832          ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
25833          : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
25834      }
25835      if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
25836        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
25837            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
25838
25839        if (objIsWrapped || othIsWrapped) {
25840          var objUnwrapped = objIsWrapped ? object.value() : object,
25841              othUnwrapped = othIsWrapped ? other.value() : other;
25842
25843          stack || (stack = new Stack);
25844          return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
25845        }
25846      }
25847      if (!isSameTag) {
25848        return false;
25849      }
25850      stack || (stack = new Stack);
25851      return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
25852    }
25853
25854    /**
25855     * The base implementation of `_.isMap` without Node.js optimizations.
25856     *
25857     * @private
25858     * @param {*} value The value to check.
25859     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
25860     */
25861    function baseIsMap(value) {
25862      return isObjectLike(value) && getTag(value) == mapTag;
25863    }
25864
25865    /**
25866     * The base implementation of `_.isMatch` without support for iteratee shorthands.
25867     *
25868     * @private
25869     * @param {Object} object The object to inspect.
25870     * @param {Object} source The object of property values to match.
25871     * @param {Array} matchData The property names, values, and compare flags to match.
25872     * @param {Function} [customizer] The function to customize comparisons.
25873     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
25874     */
25875    function baseIsMatch(object, source, matchData, customizer) {
25876      var index = matchData.length,
25877          length = index,
25878          noCustomizer = !customizer;
25879
25880      if (object == null) {
25881        return !length;
25882      }
25883      object = Object(object);
25884      while (index--) {
25885        var data = matchData[index];
25886        if ((noCustomizer && data[2])
25887              ? data[1] !== object[data[0]]
25888              : !(data[0] in object)
25889            ) {
25890          return false;
25891        }
25892      }
25893      while (++index < length) {
25894        data = matchData[index];
25895        var key = data[0],
25896            objValue = object[key],
25897            srcValue = data[1];
25898
25899        if (noCustomizer && data[2]) {
25900          if (objValue === undefined && !(key in object)) {
25901            return false;
25902          }
25903        } else {
25904          var stack = new Stack;
25905          if (customizer) {
25906            var result = customizer(objValue, srcValue, key, object, source, stack);
25907          }
25908          if (!(result === undefined
25909                ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
25910                : result
25911              )) {
25912            return false;
25913          }
25914        }
25915      }
25916      return true;
25917    }
25918
25919    /**
25920     * The base implementation of `_.isNative` without bad shim checks.
25921     *
25922     * @private
25923     * @param {*} value The value to check.
25924     * @returns {boolean} Returns `true` if `value` is a native function,
25925     *  else `false`.
25926     */
25927    function baseIsNative(value) {
25928      if (!isObject(value) || isMasked(value)) {
25929        return false;
25930      }
25931      var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
25932      return pattern.test(toSource(value));
25933    }
25934
25935    /**
25936     * The base implementation of `_.isRegExp` without Node.js optimizations.
25937     *
25938     * @private
25939     * @param {*} value The value to check.
25940     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
25941     */
25942    function baseIsRegExp(value) {
25943      return isObjectLike(value) && baseGetTag(value) == regexpTag;
25944    }
25945
25946    /**
25947     * The base implementation of `_.isSet` without Node.js optimizations.
25948     *
25949     * @private
25950     * @param {*} value The value to check.
25951     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
25952     */
25953    function baseIsSet(value) {
25954      return isObjectLike(value) && getTag(value) == setTag;
25955    }
25956
25957    /**
25958     * The base implementation of `_.isTypedArray` without Node.js optimizations.
25959     *
25960     * @private
25961     * @param {*} value The value to check.
25962     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
25963     */
25964    function baseIsTypedArray(value) {
25965      return isObjectLike(value) &&
25966        isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
25967    }
25968
25969    /**
25970     * The base implementation of `_.iteratee`.
25971     *
25972     * @private
25973     * @param {*} [value=_.identity] The value to convert to an iteratee.
25974     * @returns {Function} Returns the iteratee.
25975     */
25976    function baseIteratee(value) {
25977      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
25978      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
25979      if (typeof value == 'function') {
25980        return value;
25981      }
25982      if (value == null) {
25983        return identity;
25984      }
25985      if (typeof value == 'object') {
25986        return isArray(value)
25987          ? baseMatchesProperty(value[0], value[1])
25988          : baseMatches(value);
25989      }
25990      return property(value);
25991    }
25992
25993    /**
25994     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
25995     *
25996     * @private
25997     * @param {Object} object The object to query.
25998     * @returns {Array} Returns the array of property names.
25999     */
26000    function baseKeys(object) {
26001      if (!isPrototype(object)) {
26002        return nativeKeys(object);
26003      }
26004      var result = [];
26005      for (var key in Object(object)) {
26006        if (hasOwnProperty.call(object, key) && key != 'constructor') {
26007          result.push(key);
26008        }
26009      }
26010      return result;
26011    }
26012
26013    /**
26014     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
26015     *
26016     * @private
26017     * @param {Object} object The object to query.
26018     * @returns {Array} Returns the array of property names.
26019     */
26020    function baseKeysIn(object) {
26021      if (!isObject(object)) {
26022        return nativeKeysIn(object);
26023      }
26024      var isProto = isPrototype(object),
26025          result = [];
26026
26027      for (var key in object) {
26028        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
26029          result.push(key);
26030        }
26031      }
26032      return result;
26033    }
26034
26035    /**
26036     * The base implementation of `_.lt` which doesn't coerce arguments.
26037     *
26038     * @private
26039     * @param {*} value The value to compare.
26040     * @param {*} other The other value to compare.
26041     * @returns {boolean} Returns `true` if `value` is less than `other`,
26042     *  else `false`.
26043     */
26044    function baseLt(value, other) {
26045      return value < other;
26046    }
26047
26048    /**
26049     * The base implementation of `_.map` without support for iteratee shorthands.
26050     *
26051     * @private
26052     * @param {Array|Object} collection The collection to iterate over.
26053     * @param {Function} iteratee The function invoked per iteration.
26054     * @returns {Array} Returns the new mapped array.
26055     */
26056    function baseMap(collection, iteratee) {
26057      var index = -1,
26058          result = isArrayLike(collection) ? Array(collection.length) : [];
26059
26060      baseEach(collection, function(value, key, collection) {
26061        result[++index] = iteratee(value, key, collection);
26062      });
26063      return result;
26064    }
26065
26066    /**
26067     * The base implementation of `_.matches` which doesn't clone `source`.
26068     *
26069     * @private
26070     * @param {Object} source The object of property values to match.
26071     * @returns {Function} Returns the new spec function.
26072     */
26073    function baseMatches(source) {
26074      var matchData = getMatchData(source);
26075      if (matchData.length == 1 && matchData[0][2]) {
26076        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
26077      }
26078      return function(object) {
26079        return object === source || baseIsMatch(object, source, matchData);
26080      };
26081    }
26082
26083    /**
26084     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
26085     *
26086     * @private
26087     * @param {string} path The path of the property to get.
26088     * @param {*} srcValue The value to match.
26089     * @returns {Function} Returns the new spec function.
26090     */
26091    function baseMatchesProperty(path, srcValue) {
26092      if (isKey(path) && isStrictComparable(srcValue)) {
26093        return matchesStrictComparable(toKey(path), srcValue);
26094      }
26095      return function(object) {
26096        var objValue = get(object, path);
26097        return (objValue === undefined && objValue === srcValue)
26098          ? hasIn(object, path)
26099          : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);
26100      };
26101    }
26102
26103    /**
26104     * The base implementation of `_.merge` without support for multiple sources.
26105     *
26106     * @private
26107     * @param {Object} object The destination object.
26108     * @param {Object} source The source object.
26109     * @param {number} srcIndex The index of `source`.
26110     * @param {Function} [customizer] The function to customize merged values.
26111     * @param {Object} [stack] Tracks traversed source values and their merged
26112     *  counterparts.
26113     */
26114    function baseMerge(object, source, srcIndex, customizer, stack) {
26115      if (object === source) {
26116        return;
26117      }
26118      baseFor(source, function(srcValue, key) {
26119        stack || (stack = new Stack);
26120        if (isObject(srcValue)) {
26121          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
26122        }
26123        else {
26124          var newValue = customizer
26125            ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
26126            : undefined;
26127
26128          if (newValue === undefined) {
26129            newValue = srcValue;
26130          }
26131          assignMergeValue(object, key, newValue);
26132        }
26133      }, keysIn);
26134    }
26135
26136    /**
26137     * A specialized version of `baseMerge` for arrays and objects which performs
26138     * deep merges and tracks traversed objects enabling objects with circular
26139     * references to be merged.
26140     *
26141     * @private
26142     * @param {Object} object The destination object.
26143     * @param {Object} source The source object.
26144     * @param {string} key The key of the value to merge.
26145     * @param {number} srcIndex The index of `source`.
26146     * @param {Function} mergeFunc The function to merge values.
26147     * @param {Function} [customizer] The function to customize assigned values.
26148     * @param {Object} [stack] Tracks traversed source values and their merged
26149     *  counterparts.
26150     */
26151    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
26152      var objValue = safeGet(object, key),
26153          srcValue = safeGet(source, key),
26154          stacked = stack.get(srcValue);
26155
26156      if (stacked) {
26157        assignMergeValue(object, key, stacked);
26158        return;
26159      }
26160      var newValue = customizer
26161        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
26162        : undefined;
26163
26164      var isCommon = newValue === undefined;
26165
26166      if (isCommon) {
26167        var isArr = isArray(srcValue),
26168            isBuff = !isArr && isBuffer(srcValue),
26169            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
26170
26171        newValue = srcValue;
26172        if (isArr || isBuff || isTyped) {
26173          if (isArray(objValue)) {
26174            newValue = objValue;
26175          }
26176          else if (isArrayLikeObject(objValue)) {
26177            newValue = copyArray(objValue);
26178          }
26179          else if (isBuff) {
26180            isCommon = false;
vendor: 8,178 bytes, lines 26181-26442
26181            newValue = cloneBuffer(srcValue, true);
26182          }
26183          else if (isTyped) {
26184            isCommon = false;
26185            newValue = cloneTypedArray(srcValue, true);
26186          }
26187          else {
26188            newValue = [];
26189          }
26190        }
26191        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
26192          newValue = objValue;
26193          if (isArguments(objValue)) {
26194            newValue = toPlainObject(objValue);
26195          }
26196          else if (!isObject(objValue) || isFunction(objValue)) {
26197            newValue = initCloneObject(srcValue);
26198          }
26199        }
26200        else {
26201          isCommon = false;
26202        }
26203      }
26204      if (isCommon) {
26205        // Recursively merge objects and arrays (susceptible to call stack limits).
26206        stack.set(srcValue, newValue);
26207        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
26208        stack['delete'](srcValue);
26209      }
26210      assignMergeValue(object, key, newValue);
26211    }
26212
26213    /**
26214     * The base implementation of `_.nth` which doesn't coerce arguments.
26215     *
26216     * @private
26217     * @param {Array} array The array to query.
26218     * @param {number} n The index of the element to return.
26219     * @returns {*} Returns the nth element of `array`.
26220     */
26221    function baseNth(array, n) {
26222      var length = array.length;
26223      if (!length) {
26224        return;
26225      }
26226      n += n < 0 ? length : 0;
26227      return isIndex(n, length) ? array[n] : undefined;
26228    }
26229
26230    /**
26231     * The base implementation of `_.orderBy` without param guards.
26232     *
26233     * @private
26234     * @param {Array|Object} collection The collection to iterate over.
26235     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
26236     * @param {string[]} orders The sort orders of `iteratees`.
26237     * @returns {Array} Returns the new sorted array.
26238     */
26239    function baseOrderBy(collection, iteratees, orders) {
26240      if (iteratees.length) {
26241        iteratees = arrayMap(iteratees, function(iteratee) {
26242          if (isArray(iteratee)) {
26243            return function(value) {
26244              return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
26245            };
26246          }
26247          return iteratee;
26248        });
26249      } else {
26250        iteratees = [identity];
26251      }
26252
26253      var index = -1;
26254      iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
26255
26256      var result = baseMap(collection, function(value, key, collection) {
26257        var criteria = arrayMap(iteratees, function(iteratee) {
26258          return iteratee(value);
26259        });
26260        return { 'criteria': criteria, 'index': ++index, 'value': value };
26261      });
26262
26263      return baseSortBy(result, function(object, other) {
26264        return compareMultiple(object, other, orders);
26265      });
26266    }
26267
26268    /**
26269     * The base implementation of `_.pick` without support for individual
26270     * property identifiers.
26271     *
26272     * @private
26273     * @param {Object} object The source object.
26274     * @param {string[]} paths The property paths to pick.
26275     * @returns {Object} Returns the new object.
26276     */
26277    function basePick(object, paths) {
26278      return basePickBy(object, paths, function(value, path) {
26279        return hasIn(object, path);
26280      });
26281    }
26282
26283    /**
26284     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
26285     *
26286     * @private
26287     * @param {Object} object The source object.
26288     * @param {string[]} paths The property paths to pick.
26289     * @param {Function} predicate The function invoked per property.
26290     * @returns {Object} Returns the new object.
26291     */
26292    function basePickBy(object, paths, predicate) {
26293      var index = -1,
26294          length = paths.length,
26295          result = {};
26296
26297      while (++index < length) {
26298        var path = paths[index],
26299            value = baseGet(object, path);
26300
26301        if (predicate(value, path)) {
26302          baseSet(result, castPath(path, object), value);
26303        }
26304      }
26305      return result;
26306    }
26307
26308    /**
26309     * A specialized version of `baseProperty` which supports deep paths.
26310     *
26311     * @private
26312     * @param {Array|string} path The path of the property to get.
26313     * @returns {Function} Returns the new accessor function.
26314     */
26315    function basePropertyDeep(path) {
26316      return function(object) {
26317        return baseGet(object, path);
26318      };
26319    }
26320
26321    /**
26322     * The base implementation of `_.pullAllBy` without support for iteratee
26323     * shorthands.
26324     *
26325     * @private
26326     * @param {Array} array The array to modify.
26327     * @param {Array} values The values to remove.
26328     * @param {Function} [iteratee] The iteratee invoked per element.
26329     * @param {Function} [comparator] The comparator invoked per element.
26330     * @returns {Array} Returns `array`.
26331     */
26332    function basePullAll(array, values, iteratee, comparator) {
26333      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
26334          index = -1,
26335          length = values.length,
26336          seen = array;
26337
26338      if (array === values) {
26339        values = copyArray(values);
26340      }
26341      if (iteratee) {
26342        seen = arrayMap(array, baseUnary(iteratee));
26343      }
26344      while (++index < length) {
26345        var fromIndex = 0,
26346            value = values[index],
26347            computed = iteratee ? iteratee(value) : value;
26348
26349        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
26350          if (seen !== array) {
26351            splice.call(seen, fromIndex, 1);
26352          }
26353          splice.call(array, fromIndex, 1);
26354        }
26355      }
26356      return array;
26357    }
26358
26359    /**
26360     * The base implementation of `_.pullAt` without support for individual
26361     * indexes or capturing the removed elements.
26362     *
26363     * @private
26364     * @param {Array} array The array to modify.
26365     * @param {number[]} indexes The indexes of elements to remove.
26366     * @returns {Array} Returns `array`.
26367     */
26368    function basePullAt(array, indexes) {
26369      var length = array ? indexes.length : 0,
26370          lastIndex = length - 1;
26371
26372      while (length--) {
26373        var index = indexes[length];
26374        if (length == lastIndex || index !== previous) {
26375          var previous = index;
26376          if (isIndex(index)) {
26377            splice.call(array, index, 1);
26378          } else {
26379            baseUnset(array, index);
26380          }
26381        }
26382      }
26383      return array;
26384    }
26385
26386    /**
26387     * The base implementation of `_.random` without support for returning
26388     * floating-point numbers.
26389     *
26390     * @private
26391     * @param {number} lower The lower bound.
26392     * @param {number} upper The upper bound.
26393     * @returns {number} Returns the random number.
26394     */
26395    function baseRandom(lower, upper) {
26396      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
26397    }
26398
26399    /**
26400     * The base implementation of `_.range` and `_.rangeRight` which doesn't
26401     * coerce arguments.
26402     *
26403     * @private
26404     * @param {number} start The start of the range.
26405     * @param {number} end The end of the range.
26406     * @param {number} step The value to increment or decrement by.
26407     * @param {boolean} [fromRight] Specify iterating from right to left.
26408     * @returns {Array} Returns the range of numbers.
26409     */
26410    function baseRange(start, end, step, fromRight) {
26411      var index = -1,
26412          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
26413          result = Array(length);
26414
26415      while (length--) {
26416        result[fromRight ? length : ++index] = start;
26417        start += step;
26418      }
26419      return result;
26420    }
26421
26422    /**
26423     * The base implementation of `_.repeat` which doesn't coerce arguments.
26424     *
26425     * @private
26426     * @param {string} string The string to repeat.
26427     * @param {number} n The number of times to repeat the string.
26428     * @returns {string} Returns the repeated string.
26429     */
26430    function baseRepeat(string, n) {
26431      var result = '';
26432      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
26433        return result;
26434      }
26435      // Leverage the exponentiation by squaring algorithm for a faster repeat.
26436      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
26437      do {
26438        if (n % 2) {
26439          result += string;
26440        }
26441        n = nativeFloor(n / 2);
26442        if (n) {
vendor: 7,562 bytes, lines 26443-26679
26443          string += string;
26444        }
26445      } while (n);
26446
26447      return result;
26448    }
26449
26450    /**
26451     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
26452     *
26453     * @private
26454     * @param {Function} func The function to apply a rest parameter to.
26455     * @param {number} [start=func.length-1] The start position of the rest parameter.
26456     * @returns {Function} Returns the new function.
26457     */
26458    function baseRest(func, start) {
26459      return setToString(overRest(func, start, identity), func + '');
26460    }
26461
26462    /**
26463     * The base implementation of `_.sample`.
26464     *
26465     * @private
26466     * @param {Array|Object} collection The collection to sample.
26467     * @returns {*} Returns the random element.
26468     */
26469    function baseSample(collection) {
26470      return arraySample(values(collection));
26471    }
26472
26473    /**
26474     * The base implementation of `_.sampleSize` without param guards.
26475     *
26476     * @private
26477     * @param {Array|Object} collection The collection to sample.
26478     * @param {number} n The number of elements to sample.
26479     * @returns {Array} Returns the random elements.
26480     */
26481    function baseSampleSize(collection, n) {
26482      var array = values(collection);
26483      return shuffleSelf(array, baseClamp(n, 0, array.length));
26484    }
26485
26486    /**
26487     * The base implementation of `_.set`.
26488     *
26489     * @private
26490     * @param {Object} object The object to modify.
26491     * @param {Array|string} path The path of the property to set.
26492     * @param {*} value The value to set.
26493     * @param {Function} [customizer] The function to customize path creation.
26494     * @returns {Object} Returns `object`.
26495     */
26496    function baseSet(object, path, value, customizer) {
26497      if (!isObject(object)) {
26498        return object;
26499      }
26500      path = castPath(path, object);
26501
26502      var index = -1,
26503          length = path.length,
26504          lastIndex = length - 1,
26505          nested = object;
26506
26507      while (nested != null && ++index < length) {
26508        var key = toKey(path[index]),
26509            newValue = value;
26510
26511        if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
26512          return object;
26513        }
26514
26515        if (index != lastIndex) {
26516          var objValue = nested[key];
26517          newValue = customizer ? customizer(objValue, key, nested) : undefined;
26518          if (newValue === undefined) {
26519            newValue = isObject(objValue)
26520              ? objValue
26521              : (isIndex(path[index + 1]) ? [] : {});
26522          }
26523        }
26524        assignValue(nested, key, newValue);
26525        nested = nested[key];
26526      }
26527      return object;
26528    }
26529
26530    /**
26531     * The base implementation of `setData` without support for hot loop shorting.
26532     *
26533     * @private
26534     * @param {Function} func The function to associate metadata with.
26535     * @param {*} data The metadata.
26536     * @returns {Function} Returns `func`.
26537     */
26538    var baseSetData = !metaMap ? identity : function(func, data) {
26539      metaMap.set(func, data);
26540      return func;
26541    };
26542
26543    /**
26544     * The base implementation of `setToString` without support for hot loop shorting.
26545     *
26546     * @private
26547     * @param {Function} func The function to modify.
26548     * @param {Function} string The `toString` result.
26549     * @returns {Function} Returns `func`.
26550     */
26551    var baseSetToString = !defineProperty ? identity : function(func, string) {
26552      return defineProperty(func, 'toString', {
26553        'configurable': true,
26554        'enumerable': false,
26555        'value': constant(string),
26556        'writable': true
26557      });
26558    };
26559
26560    /**
26561     * The base implementation of `_.shuffle`.
26562     *
26563     * @private
26564     * @param {Array|Object} collection The collection to shuffle.
26565     * @returns {Array} Returns the new shuffled array.
26566     */
26567    function baseShuffle(collection) {
26568      return shuffleSelf(values(collection));
26569    }
26570
26571    /**
26572     * The base implementation of `_.slice` without an iteratee call guard.
26573     *
26574     * @private
26575     * @param {Array} array The array to slice.
26576     * @param {number} [start=0] The start position.
26577     * @param {number} [end=array.length] The end position.
26578     * @returns {Array} Returns the slice of `array`.
26579     */
26580    function baseSlice(array, start, end) {
26581      var index = -1,
26582          length = array.length;
26583
26584      if (start < 0) {
26585        start = -start > length ? 0 : (length + start);
26586      }
26587      end = end > length ? length : end;
26588      if (end < 0) {
26589        end += length;
26590      }
26591      length = start > end ? 0 : ((end - start) >>> 0);
26592      start >>>= 0;
26593
26594      var result = Array(length);
26595      while (++index < length) {
26596        result[index] = array[index + start];
26597      }
26598      return result;
26599    }
26600
26601    /**
26602     * The base implementation of `_.some` without support for iteratee shorthands.
26603     *
26604     * @private
26605     * @param {Array|Object} collection The collection to iterate over.
26606     * @param {Function} predicate The function invoked per iteration.
26607     * @returns {boolean} Returns `true` if any element passes the predicate check,
26608     *  else `false`.
26609     */
26610    function baseSome(collection, predicate) {
26611      var result;
26612
26613      baseEach(collection, function(value, index, collection) {
26614        result = predicate(value, index, collection);
26615        return !result;
26616      });
26617      return !!result;
26618    }
26619
26620    /**
26621     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
26622     * performs a binary search of `array` to determine the index at which `value`
26623     * should be inserted into `array` in order to maintain its sort order.
26624     *
26625     * @private
26626     * @param {Array} array The sorted array to inspect.
26627     * @param {*} value The value to evaluate.
26628     * @param {boolean} [retHighest] Specify returning the highest qualified index.
26629     * @returns {number} Returns the index at which `value` should be inserted
26630     *  into `array`.
26631     */
26632    function baseSortedIndex(array, value, retHighest) {
26633      var low = 0,
26634          high = array == null ? low : array.length;
26635
26636      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
26637        while (low < high) {
26638          var mid = (low + high) >>> 1,
26639              computed = array[mid];
26640
26641          if (computed !== null && !isSymbol(computed) &&
26642              (retHighest ? (computed <= value) : (computed < value))) {
26643            low = mid + 1;
26644          } else {
26645            high = mid;
26646          }
26647        }
26648        return high;
26649      }
26650      return baseSortedIndexBy(array, value, identity, retHighest);
26651    }
26652
26653    /**
26654     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
26655     * which invokes `iteratee` for `value` and each element of `array` to compute
26656     * their sort ranking. The iteratee is invoked with one argument; (value).
26657     *
26658     * @private
26659     * @param {Array} array The sorted array to inspect.
26660     * @param {*} value The value to evaluate.
26661     * @param {Function} iteratee The iteratee invoked per element.
26662     * @param {boolean} [retHighest] Specify returning the highest qualified index.
26663     * @returns {number} Returns the index at which `value` should be inserted
26664     *  into `array`.
26665     */
26666    function baseSortedIndexBy(array, value, iteratee, retHighest) {
26667      var low = 0,
26668          high = array == null ? 0 : array.length;
26669      if (high === 0) {
26670        return 0;
26671      }
26672
26673      value = iteratee(value);
26674      var valIsNaN = value !== value,
26675          valIsNull = value === null,
26676          valIsSymbol = isSymbol(value),
26677          valIsUndefined = value === undefined;
26678
26679      while (low < high) {
vendor: 8,410 bytes, lines 26680-26932
26680        var mid = nativeFloor((low + high) / 2),
26681            computed = iteratee(array[mid]),
26682            othIsDefined = computed !== undefined,
26683            othIsNull = computed === null,
26684            othIsReflexive = computed === computed,
26685            othIsSymbol = isSymbol(computed);
26686
26687        if (valIsNaN) {
26688          var setLow = retHighest || othIsReflexive;
26689        } else if (valIsUndefined) {
26690          setLow = othIsReflexive && (retHighest || othIsDefined);
26691        } else if (valIsNull) {
26692          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
26693        } else if (valIsSymbol) {
26694          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
26695        } else if (othIsNull || othIsSymbol) {
26696          setLow = false;
26697        } else {
26698          setLow = retHighest ? (computed <= value) : (computed < value);
26699        }
26700        if (setLow) {
26701          low = mid + 1;
26702        } else {
26703          high = mid;
26704        }
26705      }
26706      return nativeMin(high, MAX_ARRAY_INDEX);
26707    }
26708
26709    /**
26710     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
26711     * support for iteratee shorthands.
26712     *
26713     * @private
26714     * @param {Array} array The array to inspect.
26715     * @param {Function} [iteratee] The iteratee invoked per element.
26716     * @returns {Array} Returns the new duplicate free array.
26717     */
26718    function baseSortedUniq(array, iteratee) {
26719      var index = -1,
26720          length = array.length,
26721          resIndex = 0,
26722          result = [];
26723
26724      while (++index < length) {
26725        var value = array[index],
26726            computed = iteratee ? iteratee(value) : value;
26727
26728        if (!index || !eq(computed, seen)) {
26729          var seen = computed;
26730          result[resIndex++] = value === 0 ? 0 : value;
26731        }
26732      }
26733      return result;
26734    }
26735
26736    /**
26737     * The base implementation of `_.toNumber` which doesn't ensure correct
26738     * conversions of binary, hexadecimal, or octal string values.
26739     *
26740     * @private
26741     * @param {*} value The value to process.
26742     * @returns {number} Returns the number.
26743     */
26744    function baseToNumber(value) {
26745      if (typeof value == 'number') {
26746        return value;
26747      }
26748      if (isSymbol(value)) {
26749        return NAN;
26750      }
26751      return +value;
26752    }
26753
26754    /**
26755     * The base implementation of `_.toString` which doesn't convert nullish
26756     * values to empty strings.
26757     *
26758     * @private
26759     * @param {*} value The value to process.
26760     * @returns {string} Returns the string.
26761     */
26762    function baseToString(value) {
26763      // Exit early for strings to avoid a performance hit in some environments.
26764      if (typeof value == 'string') {
26765        return value;
26766      }
26767      if (isArray(value)) {
26768        // Recursively convert values (susceptible to call stack limits).
26769        return arrayMap(value, baseToString) + '';
26770      }
26771      if (isSymbol(value)) {
26772        return symbolToString ? symbolToString.call(value) : '';
26773      }
26774      var result = (value + '');
26775      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
26776    }
26777
26778    /**
26779     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
26780     *
26781     * @private
26782     * @param {Array} array The array to inspect.
26783     * @param {Function} [iteratee] The iteratee invoked per element.
26784     * @param {Function} [comparator] The comparator invoked per element.
26785     * @returns {Array} Returns the new duplicate free array.
26786     */
26787    function baseUniq(array, iteratee, comparator) {
26788      var index = -1,
26789          includes = arrayIncludes,
26790          length = array.length,
26791          isCommon = true,
26792          result = [],
26793          seen = result;
26794
26795      if (comparator) {
26796        isCommon = false;
26797        includes = arrayIncludesWith;
26798      }
26799      else if (length >= LARGE_ARRAY_SIZE) {
26800        var set = iteratee ? null : createSet(array);
26801        if (set) {
26802          return setToArray(set);
26803        }
26804        isCommon = false;
26805        includes = cacheHas;
26806        seen = new SetCache;
26807      }
26808      else {
26809        seen = iteratee ? [] : result;
26810      }
26811      outer:
26812      while (++index < length) {
26813        var value = array[index],
26814            computed = iteratee ? iteratee(value) : value;
26815
26816        value = (comparator || value !== 0) ? value : 0;
26817        if (isCommon && computed === computed) {
26818          var seenIndex = seen.length;
26819          while (seenIndex--) {
26820            if (seen[seenIndex] === computed) {
26821              continue outer;
26822            }
26823          }
26824          if (iteratee) {
26825            seen.push(computed);
26826          }
26827          result.push(value);
26828        }
26829        else if (!includes(seen, computed, comparator)) {
26830          if (seen !== result) {
26831            seen.push(computed);
26832          }
26833          result.push(value);
26834        }
26835      }
26836      return result;
26837    }
26838
26839    /**
26840     * The base implementation of `_.unset`.
26841     *
26842     * @private
26843     * @param {Object} object The object to modify.
26844     * @param {Array|string} path The property path to unset.
26845     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
26846     */
26847    function baseUnset(object, path) {
26848      path = castPath(path, object);
26849
26850      // Prevent prototype pollution:
26851      // https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
26852      // https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh
26853      var index = -1,
26854          length = path.length;
26855
26856      if (!length) {
26857        return true;
26858      }
26859
26860      while (++index < length) {
26861        var key = toKey(path[index]);
26862
26863        // Always block "__proto__" anywhere in the path if it's not expected
26864        if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
26865          return false;
26866        }
26867
26868        // Block constructor/prototype as non-terminal traversal keys to prevent
26869        // escaping the object graph into built-in constructors and prototypes.
26870        if ((key === 'constructor' || key === 'prototype') && index < length - 1) {
26871          return false;
26872        }
26873      }
26874
26875      var obj = parent(object, path);
26876      return obj == null || delete obj[toKey(last(path))];
26877    }
26878
26879    /**
26880     * The base implementation of `_.update`.
26881     *
26882     * @private
26883     * @param {Object} object The object to modify.
26884     * @param {Array|string} path The path of the property to update.
26885     * @param {Function} updater The function to produce the updated value.
26886     * @param {Function} [customizer] The function to customize path creation.
26887     * @returns {Object} Returns `object`.
26888     */
26889    function baseUpdate(object, path, updater, customizer) {
26890      return baseSet(object, path, updater(baseGet(object, path)), customizer);
26891    }
26892
26893    /**
26894     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
26895     * without support for iteratee shorthands.
26896     *
26897     * @private
26898     * @param {Array} array The array to query.
26899     * @param {Function} predicate The function invoked per iteration.
26900     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
26901     * @param {boolean} [fromRight] Specify iterating from right to left.
26902     * @returns {Array} Returns the slice of `array`.
26903     */
26904    function baseWhile(array, predicate, isDrop, fromRight) {
26905      var length = array.length,
26906          index = fromRight ? length : -1;
26907
26908      while ((fromRight ? index-- : ++index < length) &&
26909        predicate(array[index], index, array)) {}
26910
26911      return isDrop
26912        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
26913        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
26914    }
26915
26916    /**
26917     * The base implementation of `wrapperValue` which returns the result of
26918     * performing a sequence of actions on the unwrapped `value`, where each
26919     * successive action is supplied the return value of the previous.
26920     *
26921     * @private
26922     * @param {*} value The unwrapped value.
26923     * @param {Array} actions Actions to perform to resolve the unwrapped value.
26924     * @returns {*} Returns the resolved value.
26925     */
26926    function baseWrapperValue(value, actions) {
26927      var result = value;
26928      if (result instanceof LazyWrapper) {
26929        result = result.value();
26930      }
26931      return arrayReduce(actions, function(result, action) {
26932        return action.func.apply(action.thisArg, arrayPush([result], action.args
vendor: 45,119 bytes, lines 26932-28223
26932));
26933      }, result);
26934    }
26935
26936    /**
26937     * The base implementation of methods like `_.xor`, without support for
26938     * iteratee shorthands, that accepts an array of arrays to inspect.
26939     *
26940     * @private
26941     * @param {Array} arrays The arrays to inspect.
26942     * @param {Function} [iteratee] The iteratee invoked per element.
26943     * @param {Function} [comparator] The comparator invoked per element.
26944     * @returns {Array} Returns the new array of values.
26945     */
26946    function baseXor(arrays, iteratee, comparator) {
26947      var length = arrays.length;
26948      if (length < 2) {
26949        return length ? baseUniq(arrays[0]) : [];
26950      }
26951      var index = -1,
26952          result = Array(length);
26953
26954      while (++index < length) {
26955        var array = arrays[index],
26956            othIndex = -1;
26957
26958        while (++othIndex < length) {
26959          if (othIndex != index) {
26960            result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator);
26961          }
26962        }
26963      }
26964      return baseUniq(baseFlatten(result, 1), iteratee, comparator);
26965    }
26966
26967    /**
26968     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
26969     *
26970     * @private
26971     * @param {Array} props The property identifiers.
26972     * @param {Array} values The property values.
26973     * @param {Function} assignFunc The function to assign values.
26974     * @returns {Object} Returns the new object.
26975     */
26976    function baseZipObject(props, values, assignFunc) {
26977      var index = -1,
26978          length = props.length,
26979          valsLength = values.length,
26980          result = {};
26981
26982      while (++index < length) {
26983        var value = index < valsLength ? values[index] : undefined;
26984        assignFunc(result, props[index], value);
26985      }
26986      return result;
26987    }
26988
26989    /**
26990     * Casts `value` to an empty array if it's not an array like object.
26991     *
26992     * @private
26993     * @param {*} value The value to inspect.
26994     * @returns {Array|Object} Returns the cast array-like object.
26995     */
26996    function castArrayLikeObject(value) {
26997      return isArrayLikeObject(value) ? value : [];
26998    }
26999
27000    /**
27001     * Casts `value` to `identity` if it's not a function.
27002     *
27003     * @private
27004     * @param {*} value The value to inspect.
27005     * @returns {Function} Returns cast function.
27006     */
27007    function castFunction(value) {
27008      return typeof value == 'function' ? value : identity;
27009    }
27010
27011    /**
27012     * Casts `value` to a path array if it's not one.
27013     *
27014     * @private
27015     * @param {*} value The value to inspect.
27016     * @param {Object} [object] The object to query keys on.
27017     * @returns {Array} Returns the cast property path array.
27018     */
27019    function castPath(value, object) {
27020      if (isArray(value)) {
27021        return value;
27022      }
27023      return isKey(value, object) ? [value] : stringToPath(toString(value));
27024    }
27025
27026    /**
27027     * A `baseRest` alias which can be replaced with `identity` by module
27028     * replacement plugins.
27029     *
27030     * @private
27031     * @type {Function}
27032     * @param {Function} func The function to apply a rest parameter to.
27033     * @returns {Function} Returns the new function.
27034     */
27035    var castRest = baseRest;
27036
27037    /**
27038     * Casts `array` to a slice if it's needed.
27039     *
27040     * @private
27041     * @param {Array} array The array to inspect.
27042     * @param {number} start The start position.
27043     * @param {number} [end=array.length] The end position.
27044     * @returns {Array} Returns the cast slice.
27045     */
27046    function castSlice(array, start, end) {
27047      var length = array.length;
27048      end = end === undefined ? length : end;
27049      return (!start && end >= length) ? array : baseSlice(array, start, end);
27050    }
27051
27052    /**
27053     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
27054     *
27055     * @private
27056     * @param {number|Object} id The timer id or timeout object of the timer to clear.
27057     */
27058    var clearTimeout = ctxClearTimeout || function(id) {
27059      return root.clearTimeout(id);
27060    };
27061
27062    /**
27063     * Creates a clone of  `buffer`.
27064     *
27065     * @private
27066     * @param {Buffer} buffer The buffer to clone.
27067     * @param {boolean} [isDeep] Specify a deep clone.
27068     * @returns {Buffer} Returns the cloned buffer.
27069     */
27070    function cloneBuffer(buffer, isDeep) {
27071      if (isDeep) {
27072        return buffer.slice();
27073      }
27074      var length = buffer.length,
27075          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
27076
27077      buffer.copy(result);
27078      return result;
27079    }
27080
27081    /**
27082     * Creates a clone of `arrayBuffer`.
27083     *
27084     * @private
27085     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
27086     * @returns {ArrayBuffer} Returns the cloned array buffer.
27087     */
27088    function cloneArrayBuffer(arrayBuffer) {
27089      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
27090      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
27091      return result;
27092    }
27093
27094    /**
27095     * Creates a clone of `dataView`.
27096     *
27097     * @private
27098     * @param {Object} dataView The data view to clone.
27099     * @param {boolean} [isDeep] Specify a deep clone.
27100     * @returns {Object} Returns the cloned data view.
27101     */
27102    function cloneDataView(dataView, isDeep) {
27103      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
27104      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
27105    }
27106
27107    /**
27108     * Creates a clone of `regexp`.
27109     *
27110     * @private
27111     * @param {Object} regexp The regexp to clone.
27112     * @returns {Object} Returns the cloned regexp.
27113     */
27114    function cloneRegExp(regexp) {
27115      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
27116      result.lastIndex = regexp.lastIndex;
27117      return result;
27118    }
27119
27120    /**
27121     * Creates a clone of the `symbol` object.
27122     *
27123     * @private
27124     * @param {Object} symbol The symbol object to clone.
27125     * @returns {Object} Returns the cloned symbol object.
27126     */
27127    function cloneSymbol(symbol) {
27128      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
27129    }
27130
27131    /**
27132     * Creates a clone of `typedArray`.
27133     *
27134     * @private
27135     * @param {Object} typedArray The typed array to clone.
27136     * @param {boolean} [isDeep] Specify a deep clone.
27137     * @returns {Object} Returns the cloned typed array.
27138     */
27139    function cloneTypedArray(typedArray, isDeep) {
27140      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
27141      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
27142    }
27143
27144    /**
27145     * Compares values to sort them in ascending order.
27146     *
27147     * @private
27148     * @param {*} value The value to compare.
27149     * @param {*} other The other value to compare.
27150     * @returns {number} Returns the sort order indicator for `value`.
27151     */
27152    function compareAscending(value, other) {
27153      if (value !== other) {
27154        var valIsDefined = value !== undefined,
27155            valIsNull = value === null,
27156            valIsReflexive = value === value,
27157            valIsSymbol = isSymbol(value);
27158
27159        var othIsDefined = other !== undefined,
27160            othIsNull = other === null,
27161            othIsReflexive = other === other,
27162            othIsSymbol = isSymbol(other);
27163
27164        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
27165            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
27166            (valIsNull && othIsDefined && othIsReflexive) ||
27167            (!valIsDefined && othIsReflexive) ||
27168            !valIsReflexive) {
27169          return 1;
27170        }
27171        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
27172            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
27173            (othIsNull && valIsDefined && valIsReflexive) ||
27174            (!othIsDefined && valIsReflexive) ||
27175            !othIsReflexive) {
27176          return -1;
27177        }
27178      }
27179      return 0;
27180    }
27181
27182    /**
27183     * Used by `_.orderBy` to compare multiple properties of a value to another
27184     * and stable sort them.
27185     *
27186     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
27187     * specify an order of "desc" for descending or "asc" for ascending sort order
27188     * of corresponding values.
27189     *
27190     * @private
27191     * @param {Object} object The object to compare.
27192     * @param {Object} other The other object to compare.
27193     * @param {boolean[]|string[]} orders The order to sort by for each property.
27194     * @returns {number} Returns the sort order indicator for `object`.
27195     */
27196    function compareMultiple(object, other, orders) {
27197      var index = -1,
27198          objCriteria = object.criteria,
27199          othCriteria = other.criteria,
27200          length = objCriteria.length,
27201          ordersLength = orders.length;
27202
27203      while (++index < length) {
27204        var result = compareAscending(objCriteria[index], othCriteria[index]);
27205        if (result) {
27206          if (index >= ordersLength) {
27207            return result;
27208          }
27209          var order = orders[index];
27210          return result * (order == 'desc' ? -1 : 1);
27211        }
27212      }
27213      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
27214      // that causes it, under certain circumstances, to provide the same value for
27215      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
27216      // for more details.
27217      //
27218      // This also ensures a stable sort in V8 and other engines.
27219      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
27220      return object.index - other.index;
27221    }
27222
27223    /**
27224     * Creates an array that is the composition of partially applied arguments,
27225     * placeholders, and provided arguments into a single array of arguments.
27226     *
27227     * @private
27228     * @param {Array} args The provided arguments.
27229     * @param {Array} partials The arguments to prepend to those provided.
27230     * @param {Array} holders The `partials` placeholder indexes.
27231     * @params {boolean} [isCurried] Specify composing for a curried function.
27232     * @returns {Array} Returns the new array of composed arguments.
27233     */
27234    function composeArgs(args, partials, holders, isCurried) {
27235      var argsIndex = -1,
27236          argsLength = args.length,
27237          holdersLength = holders.length,
27238          leftIndex = -1,
27239          leftLength = partials.length,
27240          rangeLength = nativeMax(argsLength - holdersLength, 0),
27241          result = Array(leftLength + rangeLength),
27242          isUncurried = !isCurried;
27243
27244      while (++leftIndex < leftLength) {
27245        result[leftIndex] = partials[leftIndex];
27246      }
27247      while (++argsIndex < holdersLength) {
27248        if (isUncurried || argsIndex < argsLength) {
27249          result[holders[argsIndex]] = args[argsIndex];
27250        }
27251      }
27252      while (rangeLength--) {
27253        result[leftIndex++] = args[argsIndex++];
27254      }
27255      return result;
27256    }
27257
27258    /**
27259     * This function is like `composeArgs` except that the arguments composition
27260     * is tailored for `_.partialRight`.
27261     *
27262     * @private
27263     * @param {Array} args The provided arguments.
27264     * @param {Array} partials The arguments to append to those provided.
27265     * @param {Array} holders The `partials` placeholder indexes.
27266     * @params {boolean} [isCurried] Specify composing for a curried function.
27267     * @returns {Array} Returns the new array of composed arguments.
27268     */
27269    function composeArgsRight(args, partials, holders, isCurried) {
27270      var argsIndex = -1,
27271          argsLength = args.length,
27272          holdersIndex = -1,
27273          holdersLength = holders.length,
27274          rightIndex = -1,
27275          rightLength = partials.length,
27276          rangeLength = nativeMax(argsLength - holdersLength, 0),
27277          result = Array(rangeLength + rightLength),
27278          isUncurried = !isCurried;
27279
27280      while (++argsIndex < rangeLength) {
27281        result[argsIndex] = args[argsIndex];
27282      }
27283      var offset = argsIndex;
27284      while (++rightIndex < rightLength) {
27285        result[offset + rightIndex] = partials[rightIndex];
27286      }
27287      while (++holdersIndex < holdersLength) {
27288        if (isUncurried || argsIndex < argsLength) {
27289          result[offset + holders[holdersIndex]] = args[argsIndex++];
27290        }
27291      }
27292      return result;
27293    }
27294
27295    /**
27296     * Copies the values of `source` to `array`.
27297     *
27298     * @private
27299     * @param {Array} source The array to copy values from.
27300     * @param {Array} [array=[]] The array to copy values to.
27301     * @returns {Array} Returns `array`.
27302     */
27303    function copyArray(source, array) {
27304      var index = -1,
27305          length = source.length;
27306
27307      array || (array = Array(length));
27308      while (++index < length) {
27309        array[index] = source[index];
27310      }
27311      return array;
27312    }
27313
27314    /**
27315     * Copies properties of `source` to `object`.
27316     *
27317     * @private
27318     * @param {Object} source The object to copy properties from.
27319     * @param {Array} props The property identifiers to copy.
27320     * @param {Object} [object={}] The object to copy properties to.
27321     * @param {Function} [customizer] The function to customize copied values.
27322     * @returns {Object} Returns `object`.
27323     */
27324    function copyObject(source, props, object, customizer) {
27325      var isNew = !object;
27326      object || (object = {});
27327
27328      var index = -1,
27329          length = props.length;
27330
27331      while (++index < length) {
27332        var key = props[index];
27333
27334        var newValue = customizer
27335          ? customizer(object[key], source[key], key, object, source)
27336          : undefined;
27337
27338        if (newValue === undefined) {
27339          newValue = source[key];
27340        }
27341        if (isNew) {
27342          baseAssignValue(object, key, newValue);
27343        } else {
27344          assignValue(object, key, newValue);
27345        }
27346      }
27347      return object;
27348    }
27349
27350    /**
27351     * Copies own symbols of `source` to `object`.
27352     *
27353     * @private
27354     * @param {Object} source The object to copy symbols from.
27355     * @param {Object} [object={}] The object to copy symbols to.
27356     * @returns {Object} Returns `object`.
27357     */
27358    function copySymbols(source, object) {
27359      return copyObject(source, getSymbols(source), object);
27360    }
27361
27362    /**
27363     * Copies own and inherited symbols of `source` to `object`.
27364     *
27365     * @private
27366     * @param {Object} source The object to copy symbols from.
27367     * @param {Object} [object={}] The object to copy symbols to.
27368     * @returns {Object} Returns `object`.
27369     */
27370    function copySymbolsIn(source, object) {
27371      return copyObject(source, getSymbolsIn(source), object);
27372    }
27373
27374    /**
27375     * Creates a function like `_.groupBy`.
27376     *
27377     * @private
27378     * @param {Function} setter The function to set accumulator values.
27379     * @param {Function} [initializer] The accumulator object initializer.
27380     * @returns {Function} Returns the new aggregator function.
27381     */
27382    function createAggregator(setter, initializer) {
27383      return function(collection, iteratee) {
27384        var func = isArray(collection) ? arrayAggregator : baseAggregator,
27385            accumulator = initializer ? initializer() : {};
27386
27387        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
27388      };
27389    }
27390
27391    /**
27392     * Creates a function like `_.assign`.
27393     *
27394     * @private
27395     * @param {Function} assigner The function to assign values.
27396     * @returns {Function} Returns the new assigner function.
27397     */
27398    function createAssigner(assigner) {
27399      return baseRest(function(object, sources) {
27400        var index = -1,
27401            length = sources.length,
27402            customizer = length > 1 ? sources[length - 1] : undefined,
27403            guard = length > 2 ? sources[2] : undefined;
27404
27405        customizer = (assigner.length > 3 && typeof customizer == 'function')
27406          ? (length--, customizer)
27407          : undefined;
27408
27409        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
27410          customizer = length < 3 ? undefined : customizer;
27411          length = 1;
27412        }
27413        object = Object(object);
27414        while (++index < length) {
27415          var source = sources[index];
27416          if (source) {
27417            assigner(object, source, index, customizer);
27418          }
27419        }
27420        return object;
27421      });
27422    }
27423
27424    /**
27425     * Creates a `baseEach` or `baseEachRight` function.
27426     *
27427     * @private
27428     * @param {Function} eachFunc The function to iterate over a collection.
27429     * @param {boolean} [fromRight] Specify iterating from right to left.
27430     * @returns {Function} Returns the new base function.
27431     */
27432    function createBaseEach(eachFunc, fromRight) {
27433      return function(collection, iteratee) {
27434        if (collection == null) {
27435          return collection;
27436        }
27437        if (!isArrayLike(collection)) {
27438          return eachFunc(collection, iteratee);
27439        }
27440        var length = collection.length,
27441            index = fromRight ? length : -1,
27442            iterable = Object(collection);
27443
27444        while ((fromRight ? index-- : ++index < length)) {
27445          if (iteratee(iterable[index], index, iterable) === false) {
27446            break;
27447          }
27448        }
27449        return collection;
27450      };
27451    }
27452
27453    /**
27454     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
27455     *
27456     * @private
27457     * @param {boolean} [fromRight] Specify iterating from right to left.
27458     * @returns {Function} Returns the new base function.
27459     */
27460    function createBaseFor(fromRight) {
27461      return function(object, iteratee, keysFunc) {
27462        var index = -1,
27463            iterable = Object(object),
27464            props = keysFunc(object),
27465            length = props.length;
27466
27467        while (length--) {
27468          var key = props[fromRight ? length : ++index];
27469          if (iteratee(iterable[key], key, iterable) === false) {
27470            break;
27471          }
27472        }
27473        return object;
27474      };
27475    }
27476
27477    /**
27478     * Creates a function that wraps `func` to invoke it with the optional `this`
27479     * binding of `thisArg`.
27480     *
27481     * @private
27482     * @param {Function} func The function to wrap.
27483     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
27484     * @param {*} [thisArg] The `this` binding of `func`.
27485     * @returns {Function} Returns the new wrapped function.
27486     */
27487    function createBind(func, bitmask, thisArg) {
27488      var isBind = bitmask & WRAP_BIND_FLAG,
27489          Ctor = createCtor(func);
27490
27491      function wrapper() {
27492        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
27493        return fn.apply(isBind ? thisArg : this, arguments);
27494      }
27495      return wrapper;
27496    }
27497
27498    /**
27499     * Creates a function like `_.lowerFirst`.
27500     *
27501     * @private
27502     * @param {string} methodName The name of the `String` case method to use.
27503     * @returns {Function} Returns the new case function.
27504     */
27505    function createCaseFirst(methodName) {
27506      return function(string) {
27507        string = toString(string);
27508
27509        var strSymbols = hasUnicode(string)
27510          ? stringToArray(string)
27511          : undefined;
27512
27513        var chr = strSymbols
27514          ? strSymbols[0]
27515          : string.charAt(0);
27516
27517        var trailing = strSymbols
27518          ? castSlice(strSymbols, 1).join('')
27519          : string.slice(1);
27520
27521        return chr[methodName]() + trailing;
27522      };
27523    }
27524
27525    /**
27526     * Creates a function like `_.camelCase`.
27527     *
27528     * @private
27529     * @param {Function} callback The function to combine each word.
27530     * @returns {Function} Returns the new compounder function.
27531     */
27532    function createCompounder(callback) {
27533      return function(string) {
27534        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
27535      };
27536    }
27537
27538    /**
27539     * Creates a function that produces an instance of `Ctor` regardless of
27540     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
27541     *
27542     * @private
27543     * @param {Function} Ctor The constructor to wrap.
27544     * @returns {Function} Returns the new wrapped function.
27545     */
27546    function createCtor(Ctor) {
27547      return function() {
27548        // Use a `switch` statement to work with class constructors. See
27549        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
27550        // for more details.
27551        var args = arguments;
27552        switch (args.length) {
27553          case 0: return new Ctor;
27554          case 1: return new Ctor(args[0]);
27555          case 2: return new Ctor(args[0], args[1]);
27556          case 3: return new Ctor(args[0], args[1], args[2]);
27557          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
27558          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
27559          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
27560          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
27561        }
27562        var thisBinding = baseCreate(Ctor.prototype),
27563            result = Ctor.apply(thisBinding, args);
27564
27565        // Mimic the constructor's `return` behavior.
27566        // See https://es5.github.io/#x13.2.2 for more details.
27567        return isObject(result) ? result : thisBinding;
27568      };
27569    }
27570
27571    /**
27572     * Creates a function that wraps `func` to enable currying.
27573     *
27574     * @private
27575     * @param {Function} func The function to wrap.
27576     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
27577     * @param {number} arity The arity of `func`.
27578     * @returns {Function} Returns the new wrapped function.
27579     */
27580    function createCurry(func, bitmask, arity) {
27581      var Ctor = createCtor(func);
27582
27583      function wrapper() {
27584        var length = arguments.length,
27585            args = Array(length),
27586            index = length,
27587            placeholder = getHolder(wrapper);
27588
27589        while (index--) {
27590          args[index] = arguments[index];
27591        }
27592        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
27593          ? []
27594          : replaceHolders(args, placeholder);
27595
27596        length -= holders.length;
27597        if (length < arity) {
27598          return createRecurry(
27599            func, bitmask, createHybrid, wrapper.placeholder, undefined,
27600            args, holders, undefined, undefined, arity - length);
27601        }
27602        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
27603        return apply(fn, this, args);
27604      }
27605      return wrapper;
27606    }
27607
27608    /**
27609     * Creates a `_.find` or `_.findLast` function.
27610     *
27611     * @private
27612     * @param {Function} findIndexFunc The function to find the collection index.
27613     * @returns {Function} Returns the new find function.
27614     */
27615    function createFind(findIndexFunc) {
27616      return function(collection, predicate, fromIndex) {
27617        var iterable = Object(collection);
27618        if (!isArrayLike(collection)) {
27619          var iteratee = getIteratee(predicate, 3);
27620          collection = keys(collection);
27621          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
27622        }
27623        var index = findIndexFunc(collection, predicate, fromIndex);
27624        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
27625      };
27626    }
27627
27628    /**
27629     * Creates a `_.flow` or `_.flowRight` function.
27630     *
27631     * @private
27632     * @param {boolean} [fromRight] Specify iterating from right to left.
27633     * @returns {Function} Returns the new flow function.
27634     */
27635    function createFlow(fromRight) {
27636      return flatRest(function(funcs) {
27637        var length = funcs.length,
27638            index = length,
27639            prereq = LodashWrapper.prototype.thru;
27640
27641        if (fromRight) {
27642          funcs.reverse();
27643        }
27644        while (index--) {
27645          var func = funcs[index];
27646          if (typeof func != 'function') {
27647            throw new TypeError(FUNC_ERROR_TEXT);
27648          }
27649          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
27650            var wrapper = new LodashWrapper([], true);
27651          }
27652        }
27653        index = wrapper ? index : length;
27654        while (++index < length) {
27655          func = funcs[index];
27656
27657          var funcName = getFuncName(func),
27658              data = funcName == 'wrapper' ? getData(func) : undefined;
27659
27660          if (data && isLaziable(data[0]) &&
27661                data[1] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_REARG_FLAG) &&
27662                !data[4].length && data[9] == 1
27663              ) {
27664            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
27665          } else {
27666            wrapper = (func.length == 1 && isLaziable(func))
27667              ? wrapper[funcName]()
27668              : wrapper.thru(func);
27669          }
27670        }
27671        return function() {
27672          var args = arguments,
27673              value = args[0];
27674
27675          if (wrapper && args.length == 1 && isArray(value)) {
27676            return wrapper.plant(value).value();
27677          }
27678          var index = 0,
27679              result = length ? funcs[index].apply(this, args) : value;
27680
27681          while (++index < length) {
27682            result = funcs[index].call(this, result);
27683          }
27684          return result;
27685        };
27686      });
27687    }
27688
27689    /**
27690     * Creates a function that wraps `func` to invoke it with optional `this`
27691     * binding of `thisArg`, partial application, and currying.
27692     *
27693     * @private
27694     * @param {Function|string} func The function or method name to wrap.
27695     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
27696     * @param {*} [thisArg] The `this` binding of `func`.
27697     * @param {Array} [partials] The arguments to prepend to those provided to
27698     *  the new function.
27699     * @param {Array} [holders] The `partials` placeholder indexes.
27700     * @param {Array} [partialsRight] The arguments to append to those provided
27701     *  to the new function.
27702     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
27703     * @param {Array} [argPos] The argument positions of the new function.
27704     * @param {number} [ary] The arity cap of `func`.
27705     * @param {number} [arity] The arity of `func`.
27706     * @returns {Function} Returns the new wrapped function.
27707     */
27708    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
27709      var isAry = bitmask & WRAP_ARY_FLAG,
27710          isBind = bitmask & WRAP_BIND_FLAG,
27711          isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
27712          isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
27713          isFlip = bitmask & WRAP_FLIP_FLAG,
27714          Ctor = isBindKey ? undefined : createCtor(func);
27715
27716      function wrapper() {
27717        var length = arguments.length,
27718            args = Array(length),
27719            index = length;
27720
27721        while (index--) {
27722          args[index] = arguments[index];
27723        }
27724        if (isCurried) {
27725          var placeholder = getHolder(wrapper),
27726              holdersCount = countHolders(args, placeholder);
27727        }
27728        if (partials) {
27729          args = composeArgs(args, partials, holders, isCurried);
27730        }
27731        if (partialsRight) {
27732          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
27733        }
27734        length -= holdersCount;
27735        if (isCurried && length < arity) {
27736          var newHolders = replaceHolders(args, placeholder);
27737          return createRecurry(
27738            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
27739            args, newHolders, argPos, ary, arity - length
27740          );
27741        }
27742        var thisBinding = isBind ? thisArg : this,
27743            fn = isBindKey ? thisBinding[func] : func;
27744
27745        length = args.length;
27746        if (argPos) {
27747          args = reorder(args, argPos);
27748        } else if (isFlip && length > 1) {
27749          args.reverse();
27750        }
27751        if (isAry && ary < length) {
27752          args.length = ary;
27753        }
27754        if (this && this !== root && this instanceof wrapper) {
27755          fn = Ctor || createCtor(fn);
27756        }
27757        return fn.apply(thisBinding, args);
27758      }
27759      return wrapper;
27760    }
27761
27762    /**
27763     * Creates a function like `_.invertBy`.
27764     *
27765     * @private
27766     * @param {Function} setter The function to set accumulator values.
27767     * @param {Function} toIteratee The function to resolve iteratees.
27768     * @returns {Function} Returns the new inverter function.
27769     */
27770    function createInverter(setter, toIteratee) {
27771      return function(object, iteratee) {
27772        return baseInverter(object, setter, toIteratee(iteratee), {});
27773      };
27774    }
27775
27776    /**
27777     * Creates a function that performs a mathematical operation on two values.
27778     *
27779     * @private
27780     * @param {Function} operator The function to perform the operation.
27781     * @param {number} [defaultValue] The value used for `undefined` arguments.
27782     * @returns {Function} Returns the new mathematical operation function.
27783     */
27784    function createMathOperation(operator, defaultValue) {
27785      return function(value, other) {
27786        var result;
27787        if (value === undefined && other === undefined) {
27788          return defaultValue;
27789        }
27790        if (value !== undefined) {
27791          result = value;
27792        }
27793        if (other !== undefined) {
27794          if (result === undefined) {
27795            return other;
27796          }
27797          if (typeof value == 'string' || typeof other == 'string') {
27798            value = baseToString(value);
27799            other = baseToString(other);
27800          } else {
27801            value = baseToNumber(value);
27802            other = baseToNumber(other);
27803          }
27804          result = operator(value, other);
27805        }
27806        return result;
27807      };
27808    }
27809
27810    /**
27811     * Creates a function like `_.over`.
27812     *
27813     * @private
27814     * @param {Function} arrayFunc The function to iterate over iteratees.
27815     * @returns {Function} Returns the new over function.
27816     */
27817    function createOver(arrayFunc) {
27818      return flatRest(function(iteratees) {
27819        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
27820        return baseRest(function(args) {
27821          var thisArg = this;
27822          return arrayFunc(iteratees, function(iteratee) {
27823            return apply(iteratee, thisArg, args);
27824          });
27825        });
27826      });
27827    }
27828
27829    /**
27830     * Creates the padding for `string` based on `length`. The `chars` string
27831     * is truncated if the number of characters exceeds `length`.
27832     *
27833     * @private
27834     * @param {number} length The padding length.
27835     * @param {string} [chars=' '] The string used as padding.
27836     * @returns {string} Returns the padding for `string`.
27837     */
27838    function createPadding(length, chars) {
27839      chars = chars === undefined ? ' ' : baseToString(chars);
27840
27841      var charsLength = chars.length;
27842      if (charsLength < 2) {
27843        return charsLength ? baseRepeat(chars, length) : chars;
27844      }
27845      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
27846      return hasUnicode(chars)
27847        ? castSlice(stringToArray(result), 0, length).join('')
27848        : result.slice(0, length);
27849    }
27850
27851    /**
27852     * Creates a function that wraps `func` to invoke it with the `this` binding
27853     * of `thisArg` and `partials` prepended to the arguments it receives.
27854     *
27855     * @private
27856     * @param {Function} func The function to wrap.
27857     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
27858     * @param {*} thisArg The `this` binding of `func`.
27859     * @param {Array} partials The arguments to prepend to those provided to
27860     *  the new function.
27861     * @returns {Function} Returns the new wrapped function.
27862     */
27863    function createPartial(func, bitmask, thisArg, partials) {
27864      var isBind = bitmask & WRAP_BIND_FLAG,
27865          Ctor = createCtor(func);
27866
27867      function wrapper() {
27868        var argsIndex = -1,
27869            argsLength = arguments.length,
27870            leftIndex = -1,
27871            leftLength = partials.length,
27872            args = Array(leftLength + argsLength),
27873            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
27874
27875        while (++leftIndex < leftLength) {
27876          args[leftIndex] = partials[leftIndex];
27877        }
27878        while (argsLength--) {
27879          args[leftIndex++] = arguments[++argsIndex];
27880        }
27881        return apply(fn, isBind ? thisArg : this, args);
27882      }
27883      return wrapper;
27884    }
27885
27886    /**
27887     * Creates a `_.range` or `_.rangeRight` function.
27888     *
27889     * @private
27890     * @param {boolean} [fromRight] Specify iterating from right to left.
27891     * @returns {Function} Returns the new range function.
27892     */
27893    function createRange(fromRight) {
27894      return function(start, end, step) {
27895        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
27896          end = step = undefined;
27897        }
27898        // Ensure the sign of `-0` is preserved.
27899        start = toFinite(start);
27900        if (end === undefined) {
27901          end = start;
27902          start = 0;
27903        } else {
27904          end = toFinite(end);
27905        }
27906        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
27907        return baseRange(start, end, step, fromRight);
27908      };
27909    }
27910
27911    /**
27912     * Creates a function that performs a relational operation on two values.
27913     *
27914     * @private
27915     * @param {Function} operator The function to perform the operation.
27916     * @returns {Function} Returns the new relational operation function.
27917     */
27918    function createRelationalOperation(operator) {
27919      return function(value, other) {
27920        if (!(typeof value == 'string' && typeof other == 'string')) {
27921          value = toNumber(value);
27922          other = toNumber(other);
27923        }
27924        return operator(value, other);
27925      };
27926    }
27927
27928    /**
27929     * Creates a function that wraps `func` to continue currying.
27930     *
27931     * @private
27932     * @param {Function} func The function to wrap.
27933     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
27934     * @param {Function} wrapFunc The function to create the `func` wrapper.
27935     * @param {*} placeholder The placeholder value.
27936     * @param {*} [thisArg] The `this` binding of `func`.
27937     * @param {Array} [partials] The arguments to prepend to those provided to
27938     *  the new function.
27939     * @param {Array} [holders] The `partials` placeholder indexes.
27940     * @param {Array} [argPos] The argument positions of the new function.
27941     * @param {number} [ary] The arity cap of `func`.
27942     * @param {number} [arity] The arity of `func`.
27943     * @returns {Function} Returns the new wrapped function.
27944     */
27945    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
27946      var isCurry = bitmask & WRAP_CURRY_FLAG,
27947          newHolders = isCurry ? holders : undefined,
27948          newHoldersRight = isCurry ? undefined : holders,
27949          newPartials = isCurry ? partials : undefined,
27950          newPartialsRight = isCurry ? undefined : partials;
27951
27952      bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG);
27953      bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG);
27954
27955      if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
27956        bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG);
27957      }
27958      var newData = [
27959        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
27960        newHoldersRight, argPos, ary, arity
27961      ];
27962
27963      var result = wrapFunc.apply(undefined, newData);
27964      if (isLaziable(func)) {
27965        setData(result, newData);
27966      }
27967      result.placeholder = placeholder;
27968      return setWrapToString(result, func, bitmask);
27969    }
27970
27971    /**
27972     * Creates a function like `_.round`.
27973     *
27974     * @private
27975     * @param {string} methodName The name of the `Math` method to use when rounding.
27976     * @returns {Function} Returns the new round function.
27977     */
27978    function createRound(methodName) {
27979      var func = Math[methodName];
27980      return function(number, precision) {
27981        number = toNumber(number);
27982        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
27983        if (precision && nativeIsFinite(number)) {
27984          // Shift with exponential notation to avoid floating-point issues.
27985          // See [MDN](https://mdn.io/round#Examples) for more details.
27986          var pair = (toString(number) + 'e').split('e'),
27987              value = func(pair[0] + 'e' + (+pair[1] + precision));
27988
27989          pair = (toString(value) + 'e').split('e');
27990          return +(pair[0] + 'e' + (+pair[1] - precision));
27991        }
27992        return func(number);
27993      };
27994    }
27995
27996    /**
27997     * Creates a set object of `values`.
27998     *
27999     * @private
28000     * @param {Array} values The values to add to the set.
28001     * @returns {Object} Returns the new set.
28002     */
28003    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
28004      return new Set(values);
28005    };
28006
28007    /**
28008     * Creates a `_.toPairs` or `_.toPairsIn` function.
28009     *
28010     * @private
28011     * @param {Function} keysFunc The function to get the keys of a given object.
28012     * @returns {Function} Returns the new pairs function.
28013     */
28014    function createToPairs(keysFunc) {
28015      return function(object) {
28016        var tag = getTag(object);
28017        if (tag == mapTag) {
28018          return mapToArray(object);
28019        }
28020        if (tag == setTag) {
28021          return setToPairs(object);
28022        }
28023        return baseToPairs(object, keysFunc(object));
28024      };
28025    }
28026
28027    /**
28028     * Creates a function that either curries or invokes `func` with optional
28029     * `this` binding and partially applied arguments.
28030     *
28031     * @private
28032     * @param {Function|string} func The function or method name to wrap.
28033     * @param {number} bitmask The bitmask flags.
28034     *    1 - `_.bind`
28035     *    2 - `_.bindKey`
28036     *    4 - `_.curry` or `_.curryRight` of a bound function
28037     *    8 - `_.curry`
28038     *   16 - `_.curryRight`
28039     *   32 - `_.partial`
28040     *   64 - `_.partialRight`
28041     *  128 - `_.rearg`
28042     *  256 - `_.ary`
28043     *  512 - `_.flip`
28044     * @param {*} [thisArg] The `this` binding of `func`.
28045     * @param {Array} [partials] The arguments to be partially applied.
28046     * @param {Array} [holders] The `partials` placeholder indexes.
28047     * @param {Array} [argPos] The argument positions of the new function.
28048     * @param {number} [ary] The arity cap of `func`.
28049     * @param {number} [arity] The arity of `func`.
28050     * @returns {Function} Returns the new wrapped function.
28051     */
28052    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
28053      var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
28054      if (!isBindKey && typeof func != 'function') {
28055        throw new TypeError(FUNC_ERROR_TEXT);
28056      }
28057      var length = partials ? partials.length : 0;
28058      if (!length) {
28059        bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
28060        partials = holders = undefined;
28061      }
28062      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
28063      arity = arity === undefined ? arity : toInteger(arity);
28064      length -= holders ? holders.length : 0;
28065
28066      if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
28067        var partialsRight = partials,
28068            holdersRight = holders;
28069
28070        partials = holders = undefined;
28071      }
28072      var data = isBindKey ? undefined : getData(func);
28073
28074      var newData = [
28075        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
28076        argPos, ary, arity
28077      ];
28078
28079      if (data) {
28080        mergeData(newData, data);
28081      }
28082      func = newData[0];
28083      bitmask = newData[1];
28084      thisArg = newData[2];
28085      partials = newData[3];
28086      holders = newData[4];
28087      arity = newData[9] = newData[9] === undefined
28088        ? (isBindKey ? 0 : func.length)
28089        : nativeMax(newData[9] - length, 0);
28090
28091      if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
28092        bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
28093      }
28094      if (!bitmask || bitmask == WRAP_BIND_FLAG) {
28095        var result = createBind(func, bitmask, thisArg);
28096      } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
28097        result = createCurry(func, bitmask, arity);
28098      } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) {
28099        result = createPartial(func, bitmask, thisArg, partials);
28100      } else {
28101        result = createHybrid.apply(undefined, newData);
28102      }
28103      var setter = data ? baseSetData : setData;
28104      return setWrapToString(setter(result, newData), func, bitmask);
28105    }
28106
28107    /**
28108     * Used by `_.defaults` to customize its `_.assignIn` use to assign properties
28109     * of source objects to the destination object for all destination properties
28110     * that resolve to `undefined`.
28111     *
28112     * @private
28113     * @param {*} objValue The destination value.
28114     * @param {*} srcValue The source value.
28115     * @param {string} key The key of the property to assign.
28116     * @param {Object} object The parent object of `objValue`.
28117     * @returns {*} Returns the value to assign.
28118     */
28119    function customDefaultsAssignIn(objValue, srcValue, key, object) {
28120      if (objValue === undefined ||
28121          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
28122        return srcValue;
28123      }
28124      return objValue;
28125    }
28126
28127    /**
28128     * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source
28129     * objects into destination objects that are passed thru.
28130     *
28131     * @private
28132     * @param {*} objValue The destination value.
28133     * @param {*} srcValue The source value.
28134     * @param {string} key The key of the property to merge.
28135     * @param {Object} object The parent object of `objValue`.
28136     * @param {Object} source The parent object of `srcValue`.
28137     * @param {Object} [stack] Tracks traversed source values and their merged
28138     *  counterparts.
28139     * @returns {*} Returns the value to assign.
28140     */
28141    function customDefaultsMerge(objValue, srcValue, key, object, source, stack) {
28142      if (isObject(objValue) && isObject(srcValue)) {
28143        // Recursively merge objects and arrays (susceptible to call stack limits).
28144        stack.set(srcValue, objValue);
28145        baseMerge(objValue, srcValue, undefined, customDefaultsMerge, stack);
28146        stack['delete'](srcValue);
28147      }
28148      return objValue;
28149    }
28150
28151    /**
28152     * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
28153     * objects.
28154     *
28155     * @private
28156     * @param {*} value The value to inspect.
28157     * @param {string} key The key of the property to inspect.
28158     * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
28159     */
28160    function customOmitClone(value) {
28161      return isPlainObject(value) ? undefined : value;
28162    }
28163
28164    /**
28165     * A specialized version of `baseIsEqualDeep` for arrays with support for
28166     * partial deep comparisons.
28167     *
28168     * @private
28169     * @param {Array} array The array to compare.
28170     * @param {Array} other The other array to compare.
28171     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
28172     * @param {Function} customizer The function to customize comparisons.
28173     * @param {Function} equalFunc The function to determine equivalents of values.
28174     * @param {Object} stack Tracks traversed `array` and `other` objects.
28175     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
28176     */
28177    function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
28178      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
28179          arrLength = array.length,
28180          othLength = other.length;
28181
28182      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
28183        return false;
28184      }
28185      // Check that cyclic values are equal.
28186      var arrStacked = stack.get(array);
28187      var othStacked = stack.get(other);
28188      if (arrStacked && othStacked) {
28189        return arrStacked == other && othStacked == array;
28190      }
28191      var index = -1,
28192          result = true,
28193          seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
28194
28195      stack.set(array, other);
28196      stack.set(other, array);
28197
28198      // Ignore non-index properties.
28199      while (++index < arrLength) {
28200        var arrValue = array[index],
28201            othValue = other[index];
28202
28203        if (customizer) {
28204          var compared = isPartial
28205            ? customizer(othValue, arrValue, index, other, array, stack)
28206            : customizer(arrValue, othValue, index, array, other, stack);
28207        }
28208        if (compared !== undefined) {
28209          if (compared) {
28210            continue;
28211          }
28212          result = false;
28213          break;
28214        }
28215        // Recursively compare arrays (susceptible to call stack limits).
28216        if (seen) {
28217          if (!arraySome(other, function(othValue, othIndex) {
28218                if (!cacheHas(seen, othIndex) &&
28219                    (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
28220                  return seen.push(othIndex);
28221                }
28222              })) {
28223            result = false;
vendor: 4,179 bytes, lines 28224-28335
28224            break;
28225          }
28226        } else if (!(
28227              arrValue === othValue ||
28228                equalFunc(arrValue, othValue, bitmask, customizer, stack)
28229            )) {
28230          result = false;
28231          break;
28232        }
28233      }
28234      stack['delete'](array);
28235      stack['delete'](other);
28236      return result;
28237    }
28238
28239    /**
28240     * A specialized version of `baseIsEqualDeep` for comparing objects of
28241     * the same `toStringTag`.
28242     *
28243     * **Note:** This function only supports comparing values with tags of
28244     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
28245     *
28246     * @private
28247     * @param {Object} object The object to compare.
28248     * @param {Object} other The other object to compare.
28249     * @param {string} tag The `toStringTag` of the objects to compare.
28250     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
28251     * @param {Function} customizer The function to customize comparisons.
28252     * @param {Function} equalFunc The function to determine equivalents of values.
28253     * @param {Object} stack Tracks traversed `object` and `other` objects.
28254     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
28255     */
28256    function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
28257      switch (tag) {
28258        case dataViewTag:
28259          if ((object.byteLength != other.byteLength) ||
28260              (object.byteOffset != other.byteOffset)) {
28261            return false;
28262          }
28263          object = object.buffer;
28264          other = other.buffer;
28265
28266        case arrayBufferTag:
28267          if ((object.byteLength != other.byteLength) ||
28268              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
28269            return false;
28270          }
28271          return true;
28272
28273        case boolTag:
28274        case dateTag:
28275        case numberTag:
28276          // Coerce booleans to `1` or `0` and dates to milliseconds.
28277          // Invalid dates are coerced to `NaN`.
28278          return eq(+object, +other);
28279
28280        case errorTag:
28281          return object.name == other.name && object.message == other.message;
28282
28283        case regexpTag:
28284        case stringTag:
28285          // Coerce regexes to strings and treat strings, primitives and objects,
28286          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
28287          // for more details.
28288          return object == (other + '');
28289
28290        case mapTag:
28291          var convert = mapToArray;
28292
28293        case setTag:
28294          var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
28295          convert || (convert = setToArray);
28296
28297          if (object.size != other.size && !isPartial) {
28298            return false;
28299          }
28300          // Assume cyclic values are equal.
28301          var stacked = stack.get(object);
28302          if (stacked) {
28303            return stacked == other;
28304          }
28305          bitmask |= COMPARE_UNORDERED_FLAG;
28306
28307          // Recursively compare objects (susceptible to call stack limits).
28308          stack.set(object, other);
28309          var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
28310          stack['delete'](object);
28311          return result;
28312
28313        case symbolTag:
28314          if (symbolValueOf) {
28315            return symbolValueOf.call(object) == symbolValueOf.call(other);
28316          }
28317      }
28318      return false;
28319    }
28320
28321    /**
28322     * A specialized version of `baseIsEqualDeep` for objects with support for
28323     * partial deep comparisons.
28324     *
28325     * @private
28326     * @param {Object} object The object to compare.
28327     * @param {Object} other The other object to compare.
28328     * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
28329     * @param {Function} customizer The function to customize comparisons.
28330     * @param {Function} equalFunc The function to determine equivalents of values.
28331     * @param {Object} stack Tracks traversed `object` and `other` objects.
28332     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
28333     */
28334    function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
28335      var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
vendor: 9,614 bytes, lines 28336-28643
28336          objProps = getAllKeys(object),
28337          objLength = objProps.length,
28338          othProps = getAllKeys(other),
28339          othLength = othProps.length;
28340
28341      if (objLength != othLength && !isPartial) {
28342        return false;
28343      }
28344      var index = objLength;
28345      while (index--) {
28346        var key = objProps[index];
28347        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
28348          return false;
28349        }
28350      }
28351      // Check that cyclic values are equal.
28352      var objStacked = stack.get(object);
28353      var othStacked = stack.get(other);
28354      if (objStacked && othStacked) {
28355        return objStacked == other && othStacked == object;
28356      }
28357      var result = true;
28358      stack.set(object, other);
28359      stack.set(other, object);
28360
28361      var skipCtor = isPartial;
28362      while (++index < objLength) {
28363        key = objProps[index];
28364        var objValue = object[key],
28365            othValue = other[key];
28366
28367        if (customizer) {
28368          var compared = isPartial
28369            ? customizer(othValue, objValue, key, other, object, stack)
28370            : customizer(objValue, othValue, key, object, other, stack);
28371        }
28372        // Recursively compare objects (susceptible to call stack limits).
28373        if (!(compared === undefined
28374              ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
28375              : compared
28376            )) {
28377          result = false;
28378          break;
28379        }
28380        skipCtor || (skipCtor = key == 'constructor');
28381      }
28382      if (result && !skipCtor) {
28383        var objCtor = object.constructor,
28384            othCtor = other.constructor;
28385
28386        // Non `Object` object instances with different constructors are not equal.
28387        if (objCtor != othCtor &&
28388            ('constructor' in object && 'constructor' in other) &&
28389            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
28390              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
28391          result = false;
28392        }
28393      }
28394      stack['delete'](object);
28395      stack['delete'](other);
28396      return result;
28397    }
28398
28399    /**
28400     * A specialized version of `baseRest` which flattens the rest array.
28401     *
28402     * @private
28403     * @param {Function} func The function to apply a rest parameter to.
28404     * @returns {Function} Returns the new function.
28405     */
28406    function flatRest(func) {
28407      return setToString(overRest(func, undefined, flatten), func + '');
28408    }
28409
28410    /**
28411     * Creates an array of own enumerable property names and symbols of `object`.
28412     *
28413     * @private
28414     * @param {Object} object The object to query.
28415     * @returns {Array} Returns the array of property names and symbols.
28416     */
28417    function getAllKeys(object) {
28418      return baseGetAllKeys(object, keys, getSymbols);
28419    }
28420
28421    /**
28422     * Creates an array of own and inherited enumerable property names and
28423     * symbols of `object`.
28424     *
28425     * @private
28426     * @param {Object} object The object to query.
28427     * @returns {Array} Returns the array of property names and symbols.
28428     */
28429    function getAllKeysIn(object) {
28430      return baseGetAllKeys(object, keysIn, getSymbolsIn);
28431    }
28432
28433    /**
28434     * Gets metadata for `func`.
28435     *
28436     * @private
28437     * @param {Function} func The function to query.
28438     * @returns {*} Returns the metadata for `func`.
28439     */
28440    var getData = !metaMap ? noop : function(func) {
28441      return metaMap.get(func);
28442    };
28443
28444    /**
28445     * Gets the name of `func`.
28446     *
28447     * @private
28448     * @param {Function} func The function to query.
28449     * @returns {string} Returns the function name.
28450     */
28451    function getFuncName(func) {
28452      var result = (func.name + ''),
28453          array = realNames[result],
28454          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
28455
28456      while (length--) {
28457        var data = array[length],
28458            otherFunc = data.func;
28459        if (otherFunc == null || otherFunc == func) {
28460          return data.name;
28461        }
28462      }
28463      return result;
28464    }
28465
28466    /**
28467     * Gets the argument placeholder value for `func`.
28468     *
28469     * @private
28470     * @param {Function} func The function to inspect.
28471     * @returns {*} Returns the placeholder value.
28472     */
28473    function getHolder(func) {
28474      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
28475      return object.placeholder;
28476    }
28477
28478    /**
28479     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
28480     * this function returns the custom method, otherwise it returns `baseIteratee`.
28481     * If arguments are provided, the chosen function is invoked with them and
28482     * its result is returned.
28483     *
28484     * @private
28485     * @param {*} [value] The value to convert to an iteratee.
28486     * @param {number} [arity] The arity of the created iteratee.
28487     * @returns {Function} Returns the chosen function or its result.
28488     */
28489    function getIteratee() {
28490      var result = lodash.iteratee || iteratee;
28491      result = result === iteratee ? baseIteratee : result;
28492      return arguments.length ? result(arguments[0], arguments[1]) : result;
28493    }
28494
28495    /**
28496     * Gets the data for `map`.
28497     *
28498     * @private
28499     * @param {Object} map The map to query.
28500     * @param {string} key The reference key.
28501     * @returns {*} Returns the map data.
28502     */
28503    function getMapData(map, key) {
28504      var data = map.__data__;
28505      return isKeyable(key)
28506        ? data[typeof key == 'string' ? 'string' : 'hash']
28507        : data.map;
28508    }
28509
28510    /**
28511     * Gets the property names, values, and compare flags of `object`.
28512     *
28513     * @private
28514     * @param {Object} object The object to query.
28515     * @returns {Array} Returns the match data of `object`.
28516     */
28517    function getMatchData(object) {
28518      var result = keys(object),
28519          length = result.length;
28520
28521      while (length--) {
28522        var key = result[length],
28523            value = object[key];
28524
28525        result[length] = [key, value, isStrictComparable(value)];
28526      }
28527      return result;
28528    }
28529
28530    /**
28531     * Gets the native function at `key` of `object`.
28532     *
28533     * @private
28534     * @param {Object} object The object to query.
28535     * @param {string} key The key of the method to get.
28536     * @returns {*} Returns the function if it's native, else `undefined`.
28537     */
28538    function getNative(object, key) {
28539      var value = getValue(object, key);
28540      return baseIsNative(value) ? value : undefined;
28541    }
28542
28543    /**
28544     * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
28545     *
28546     * @private
28547     * @param {*} value The value to query.
28548     * @returns {string} Returns the raw `toStringTag`.
28549     */
28550    function getRawTag(value) {
28551      var isOwn = hasOwnProperty.call(value, symToStringTag),
28552          tag = value[symToStringTag];
28553
28554      try {
28555        value[symToStringTag] = undefined;
28556        var unmasked = true;
28557      } catch (e) {}
28558
28559      var result = nativeObjectToString.call(value);
28560      if (unmasked) {
28561        if (isOwn) {
28562          value[symToStringTag] = tag;
28563        } else {
28564          delete value[symToStringTag];
28565        }
28566      }
28567      return result;
28568    }
28569
28570    /**
28571     * Creates an array of the own enumerable symbols of `object`.
28572     *
28573     * @private
28574     * @param {Object} object The object to query.
28575     * @returns {Array} Returns the array of symbols.
28576     */
28577    var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
28578      if (object == null) {
28579        return [];
28580      }
28581      object = Object(object);
28582      return arrayFilter(nativeGetSymbols(object), function(symbol) {
28583        return propertyIsEnumerable.call(object, symbol);
28584      });
28585    };
28586
28587    /**
28588     * Creates an array of the own and inherited enumerable symbols of `object`.
28589     *
28590     * @private
28591     * @param {Object} object The object to query.
28592     * @returns {Array} Returns the array of symbols.
28593     */
28594    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
28595      var result = [];
28596      while (object) {
28597        arrayPush(result, getSymbols(object));
28598        object = getPrototype(object);
28599      }
28600      return result;
28601    };
28602
28603    /**
28604     * Gets the `toStringTag` of `value`.
28605     *
28606     * @private
28607     * @param {*} value The value to query.
28608     * @returns {string} Returns the `toStringTag`.
28609     */
28610    var getTag = baseGetTag;
28611
28612    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
28613    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
28614        (Map && getTag(new Map) != mapTag) ||
28615        (Promise && getTag(Promise.resolve()) != promiseTag) ||
28616        (Set && getTag(new Set) != setTag) ||
28617        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
28618      getTag = function(value) {
28619        var result = baseGetTag(value),
28620            Ctor = result == objectTag ? value.constructor : undefined,
28621            ctorString = Ctor ? toSource(Ctor) : '';
28622
28623        if (ctorString) {
28624          switch (ctorString) {
28625            case dataViewCtorString: return dataViewTag;
28626            case mapCtorString: return mapTag;
28627            case promiseCtorString: return promiseTag;
28628            case setCtorString: return setTag;
28629            case weakMapCtorString: return weakMapTag;
28630          }
28631        }
28632        return result;
28633      };
28634    }
28635
28636    /**
28637     * Gets the view, applying any `transforms` to the `start` and `end` positions.
28638     *
28639     * @private
28640     * @param {number} start The start of the view.
28641     * @param {number} end The end of the view.
28642     * @param {Array} transforms The transformations to apply to the view.
28643     * @returns {Object}
vendor: 6,432 bytes, lines 28643-28848
28643 Returns an object containing the `start` and `end`
28644     *  positions of the view.
28645     */
28646    function getView(start, end, transforms) {
28647      var index = -1,
28648          length = transforms.length;
28649
28650      while (++index < length) {
28651        var data = transforms[index],
28652            size = data.size;
28653
28654        switch (data.type) {
28655          case 'drop':      start += size; break;
28656          case 'dropRight': end -= size; break;
28657          case 'take':      end = nativeMin(end, start + size); break;
28658          case 'takeRight': start = nativeMax(start, end - size); break;
28659        }
28660      }
28661      return { 'start': start, 'end': end };
28662    }
28663
28664    /**
28665     * Extracts wrapper details from the `source` body comment.
28666     *
28667     * @private
28668     * @param {string} source The source to inspect.
28669     * @returns {Array} Returns the wrapper details.
28670     */
28671    function getWrapDetails(source) {
28672      var match = source.match(reWrapDetails);
28673      return match ? match[1].split(reSplitDetails) : [];
28674    }
28675
28676    /**
28677     * Checks if `path` exists on `object`.
28678     *
28679     * @private
28680     * @param {Object} object The object to query.
28681     * @param {Array|string} path The path to check.
28682     * @param {Function} hasFunc The function to check properties.
28683     * @returns {boolean} Returns `true` if `path` exists, else `false`.
28684     */
28685    function hasPath(object, path, hasFunc) {
28686      path = castPath(path, object);
28687
28688      var index = -1,
28689          length = path.length,
28690          result = false;
28691
28692      while (++index < length) {
28693        var key = toKey(path[index]);
28694        if (!(result = object != null && hasFunc(object, key))) {
28695          break;
28696        }
28697        object = object[key];
28698      }
28699      if (result || ++index != length) {
28700        return result;
28701      }
28702      length = object == null ? 0 : object.length;
28703      return !!length && isLength(length) && isIndex(key, length) &&
28704        (isArray(object) || isArguments(object));
28705    }
28706
28707    /**
28708     * Initializes an array clone.
28709     *
28710     * @private
28711     * @param {Array} array The array to clone.
28712     * @returns {Array} Returns the initialized clone.
28713     */
28714    function initCloneArray(array) {
28715      var length = array.length,
28716          result = new array.constructor(length);
28717
28718      // Add properties assigned by `RegExp#exec`.
28719      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
28720        result.index = array.index;
28721        result.input = array.input;
28722      }
28723      return result;
28724    }
28725
28726    /**
28727     * Initializes an object clone.
28728     *
28729     * @private
28730     * @param {Object} object The object to clone.
28731     * @returns {Object} Returns the initialized clone.
28732     */
28733    function initCloneObject(object) {
28734      return (typeof object.constructor == 'function' && !isPrototype(object))
28735        ? baseCreate(getPrototype(object))
28736        : {};
28737    }
28738
28739    /**
28740     * Initializes an object clone based on its `toStringTag`.
28741     *
28742     * **Note:** This function only supports cloning values with tags of
28743     * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
28744     *
28745     * @private
28746     * @param {Object} object The object to clone.
28747     * @param {string} tag The `toStringTag` of the object to clone.
28748     * @param {boolean} [isDeep] Specify a deep clone.
28749     * @returns {Object} Returns the initialized clone.
28750     */
28751    function initCloneByTag(object, tag, isDeep) {
28752      var Ctor = object.constructor;
28753      switch (tag) {
28754        case arrayBufferTag:
28755          return cloneArrayBuffer(object);
28756
28757        case boolTag:
28758        case dateTag:
28759          return new Ctor(+object);
28760
28761        case dataViewTag:
28762          return cloneDataView(object, isDeep);
28763
28764        case float32Tag: case float64Tag:
28765        case int8Tag: case int16Tag: case int32Tag:
28766        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
28767          return cloneTypedArray(object, isDeep);
28768
28769        case mapTag:
28770          return new Ctor;
28771
28772        case numberTag:
28773        case stringTag:
28774          return new Ctor(object);
28775
28776        case regexpTag:
28777          return cloneRegExp(object);
28778
28779        case setTag:
28780          return new Ctor;
28781
28782        case symbolTag:
28783          return cloneSymbol(object);
28784      }
28785    }
28786
28787    /**
28788     * Inserts wrapper `details` in a comment at the top of the `source` body.
28789     *
28790     * @private
28791     * @param {string} source The source to modify.
28792     * @returns {Array} details The details to insert.
28793     * @returns {string} Returns the modified source.
28794     */
28795    function insertWrapDetails(source, details) {
28796      var length = details.length;
28797      if (!length) {
28798        return source;
28799      }
28800      var lastIndex = length - 1;
28801      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
28802      details = details.join(length > 2 ? ', ' : ' ');
28803      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
28804    }
28805
28806    /**
28807     * Checks if `value` is a flattenable `arguments` object or array.
28808     *
28809     * @private
28810     * @param {*} value The value to check.
28811     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
28812     */
28813    function isFlattenable(value) {
28814      return isArray(value) || isArguments(value) ||
28815        !!(spreadableSymbol && value && value[spreadableSymbol]);
28816    }
28817
28818    /**
28819     * Checks if `value` is a valid array-like index.
28820     *
28821     * @private
28822     * @param {*} value The value to check.
28823     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
28824     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
28825     */
28826    function isIndex(value, length) {
28827      var type = typeof value;
28828      length = length == null ? MAX_SAFE_INTEGER : length;
28829
28830      return !!length &&
28831        (type == 'number' ||
28832          (type != 'symbol' && reIsUint.test(value))) &&
28833            (value > -1 && value % 1 == 0 && value < length);
28834    }
28835
28836    /**
28837     * Checks if the given arguments are from an iteratee call.
28838     *
28839     * @private
28840     * @param {*} value The potential iteratee value argument.
28841     * @param {*} index The potential iteratee index or key argument.
28842     * @param {*} object The potential iteratee object argument.
28843     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
28844     *  else `false`.
28845     */
28846    function isIterateeCall(value, index, object) {
28847      if (!isObject(object)) {
28848        return false;
vendor: 14,387 bytes, lines 28849-29295
28849      }
28850      var type = typeof index;
28851      if (type == 'number'
28852            ? (isArrayLike(object) && isIndex(index, object.length))
28853            : (type == 'string' && index in object)
28854          ) {
28855        return eq(object[index], value);
28856      }
28857      return false;
28858    }
28859
28860    /**
28861     * Checks if `value` is a property name and not a property path.
28862     *
28863     * @private
28864     * @param {*} value The value to check.
28865     * @param {Object} [object] The object to query keys on.
28866     * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
28867     */
28868    function isKey(value, object) {
28869      if (isArray(value)) {
28870        return false;
28871      }
28872      var type = typeof value;
28873      if (type == 'number' || type == 'symbol' || type == 'boolean' ||
28874          value == null || isSymbol(value)) {
28875        return true;
28876      }
28877      return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
28878        (object != null && value in Object(object));
28879    }
28880
28881    /**
28882     * Checks if `value` is suitable for use as unique object key.
28883     *
28884     * @private
28885     * @param {*} value The value to check.
28886     * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
28887     */
28888    function isKeyable(value) {
28889      var type = typeof value;
28890      return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
28891        ? (value !== '__proto__')
28892        : (value === null);
28893    }
28894
28895    /**
28896     * Checks if `func` has a lazy counterpart.
28897     *
28898     * @private
28899     * @param {Function} func The function to check.
28900     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
28901     *  else `false`.
28902     */
28903    function isLaziable(func) {
28904      var funcName = getFuncName(func),
28905          other = lodash[funcName];
28906
28907      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
28908        return false;
28909      }
28910      if (func === other) {
28911        return true;
28912      }
28913      var data = getData(other);
28914      return !!data && func === data[0];
28915    }
28916
28917    /**
28918     * Checks if `func` has its source masked.
28919     *
28920     * @private
28921     * @param {Function} func The function to check.
28922     * @returns {boolean} Returns `true` if `func` is masked, else `false`.
28923     */
28924    function isMasked(func) {
28925      return !!maskSrcKey && (maskSrcKey in func);
28926    }
28927
28928    /**
28929     * Checks if `func` is capable of being masked.
28930     *
28931     * @private
28932     * @param {*} value The value to check.
28933     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
28934     */
28935    var isMaskable = coreJsData ? isFunction : stubFalse;
28936
28937    /**
28938     * Checks if `value` is likely a prototype object.
28939     *
28940     * @private
28941     * @param {*} value The value to check.
28942     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
28943     */
28944    function isPrototype(value) {
28945      var Ctor = value && value.constructor,
28946          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
28947
28948      return value === proto;
28949    }
28950
28951    /**
28952     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
28953     *
28954     * @private
28955     * @param {*} value The value to check.
28956     * @returns {boolean} Returns `true` if `value` if suitable for strict
28957     *  equality comparisons, else `false`.
28958     */
28959    function isStrictComparable(value) {
28960      return value === value && !isObject(value);
28961    }
28962
28963    /**
28964     * A specialized version of `matchesProperty` for source values suitable
28965     * for strict equality comparisons, i.e. `===`.
28966     *
28967     * @private
28968     * @param {string} key The key of the property to get.
28969     * @param {*} srcValue The value to match.
28970     * @returns {Function} Returns the new spec function.
28971     */
28972    function matchesStrictComparable(key, srcValue) {
28973      return function(object) {
28974        if (object == null) {
28975          return false;
28976        }
28977        return object[key] === srcValue &&
28978          (srcValue !== undefined || (key in Object(object)));
28979      };
28980    }
28981
28982    /**
28983     * A specialized version of `_.memoize` which clears the memoized function's
28984     * cache when it exceeds `MAX_MEMOIZE_SIZE`.
28985     *
28986     * @private
28987     * @param {Function} func The function to have its output memoized.
28988     * @returns {Function} Returns the new memoized function.
28989     */
28990    function memoizeCapped(func) {
28991      var result = memoize(func, function(key) {
28992        if (cache.size === MAX_MEMOIZE_SIZE) {
28993          cache.clear();
28994        }
28995        return key;
28996      });
28997
28998      var cache = result.cache;
28999      return result;
29000    }
29001
29002    /**
29003     * Merges the function metadata of `source` into `data`.
29004     *
29005     * Merging metadata reduces the number of wrappers used to invoke a function.
29006     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
29007     * may be applied regardless of execution order. Methods like `_.ary` and
29008     * `_.rearg` modify function arguments, making the order in which they are
29009     * executed important, preventing the merging of metadata. However, we make
29010     * an exception for a safe combined case where curried functions have `_.ary`
29011     * and or `_.rearg` applied.
29012     *
29013     * @private
29014     * @param {Array} data The destination metadata.
29015     * @param {Array} source The source metadata.
29016     * @returns {Array} Returns `data`.
29017     */
29018    function mergeData(data, source) {
29019      var bitmask = data[1],
29020          srcBitmask = source[1],
29021          newBitmask = bitmask | srcBitmask,
29022          isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG);
29023
29024      var isCombo =
29025        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) ||
29026        ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) ||
29027        ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG));
29028
29029      // Exit early if metadata can't be merged.
29030      if (!(isCommon || isCombo)) {
29031        return data;
29032      }
29033      // Use source `thisArg` if available.
29034      if (srcBitmask & WRAP_BIND_FLAG) {
29035        data[2] = source[2];
29036        // Set when currying a bound function.
29037        newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG;
29038      }
29039      // Compose partial arguments.
29040      var value = source[3];
29041      if (value) {
29042        var partials = data[3];
29043        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
29044        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
29045      }
29046      // Compose partial right arguments.
29047      value = source[5];
29048      if (value) {
29049        partials = data[5];
29050        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
29051        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
29052      }
29053      // Use source `argPos` if available.
29054      value = source[7];
29055      if (value) {
29056        data[7] = value;
29057      }
29058      // Use source `ary` if it's smaller.
29059      if (srcBitmask & WRAP_ARY_FLAG) {
29060        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
29061      }
29062      // Use source `arity` if one is not provided.
29063      if (data[9] == null) {
29064        data[9] = source[9];
29065      }
29066      // Use source `func` and merge bitmasks.
29067      data[0] = source[0];
29068      data[1] = newBitmask;
29069
29070      return data;
29071    }
29072
29073    /**
29074     * This function is like
29075     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
29076     * except that it includes inherited enumerable properties.
29077     *
29078     * @private
29079     * @param {Object} object The object to query.
29080     * @returns {Array} Returns the array of property names.
29081     */
29082    function nativeKeysIn(object) {
29083      var result = [];
29084      if (object != null) {
29085        for (var key in Object(object)) {
29086          result.push(key);
29087        }
29088      }
29089      return result;
29090    }
29091
29092    /**
29093     * Converts `value` to a string using `Object.prototype.toString`.
29094     *
29095     * @private
29096     * @param {*} value The value to convert.
29097     * @returns {string} Returns the converted string.
29098     */
29099    function objectToString(value) {
29100      return nativeObjectToString.call(value);
29101    }
29102
29103    /**
29104     * A specialized version of `baseRest` which transforms the rest array.
29105     *
29106     * @private
29107     * @param {Function} func The function to apply a rest parameter to.
29108     * @param {number} [start=func.length-1] The start position of the rest parameter.
29109     * @param {Function} transform The rest array transform.
29110     * @returns {Function} Returns the new function.
29111     */
29112    function overRest(func, start, transform) {
29113      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
29114      return function() {
29115        var args = arguments,
29116            index = -1,
29117            length = nativeMax(args.length - start, 0),
29118            array = Array(length);
29119
29120        while (++index < length) {
29121          array[index] = args[start + index];
29122        }
29123        index = -1;
29124        var otherArgs = Array(start + 1);
29125        while (++index < start) {
29126          otherArgs[index] = args[index];
29127        }
29128        otherArgs[start] = transform(array);
29129        return apply(func, this, otherArgs);
29130      };
29131    }
29132
29133    /**
29134     * Gets the parent value at `path` of `object`.
29135     *
29136     * @private
29137     * @param {Object} object The object to query.
29138     * @param {Array} path The path to get the parent value of.
29139     * @returns {*} Returns the parent value.
29140     */
29141    function parent(object, path) {
29142      return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
29143    }
29144
29145    /**
29146     * Reorder `array` according to the specified indexes where the element at
29147     * the first index is assigned as the first element, the element at
29148     * the second index is assigned as the second element, and so on.
29149     *
29150     * @private
29151     * @param {Array} array The array to reorder.
29152     * @param {Array} indexes The arranged array indexes.
29153     * @returns {Array} Returns `array`.
29154     */
29155    function reorder(array, indexes) {
29156      var arrLength = array.length,
29157          length = nativeMin(indexes.length, arrLength),
29158          oldArray = copyArray(array);
29159
29160      while (length--) {
29161        var index = indexes[length];
29162        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
29163      }
29164      return array;
29165    }
29166
29167    /**
29168     * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
29169     *
29170     * @private
29171     * @param {Object} object The object to query.
29172     * @param {string} key The key of the property to get.
29173     * @returns {*} Returns the property value.
29174     */
29175    function safeGet(object, key) {
29176      if (key === 'constructor' && typeof object[key] === 'function') {
29177        return;
29178      }
29179
29180      if (key == '__proto__') {
29181        return;
29182      }
29183
29184      return object[key];
29185    }
29186
29187    /**
29188     * Sets metadata for `func`.
29189     *
29190     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
29191     * period of time, it will trip its breaker and transition to an identity
29192     * function to avoid garbage collection pauses in V8. See
29193     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
29194     * for more details.
29195     *
29196     * @private
29197     * @param {Function} func The function to associate metadata with.
29198     * @param {*} data The metadata.
29199     * @returns {Function} Returns `func`.
29200     */
29201    var setData = shortOut(baseSetData);
29202
29203    /**
29204     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
29205     *
29206     * @private
29207     * @param {Function} func The function to delay.
29208     * @param {number} wait The number of milliseconds to delay invocation.
29209     * @returns {number|Object} Returns the timer id or timeout object.
29210     */
29211    var setTimeout = ctxSetTimeout || function(func, wait) {
29212      return root.setTimeout(func, wait);
29213    };
29214
29215    /**
29216     * Sets the `toString` method of `func` to return `string`.
29217     *
29218     * @private
29219     * @param {Function} func The function to modify.
29220     * @param {Function} string The `toString` result.
29221     * @returns {Function} Returns `func`.
29222     */
29223    var setToString = shortOut(baseSetToString);
29224
29225    /**
29226     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
29227     * with wrapper details in a comment at the top of the source body.
29228     *
29229     * @private
29230     * @param {Function} wrapper The function to modify.
29231     * @param {Function} reference The reference function.
29232     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
29233     * @returns {Function} Returns `wrapper`.
29234     */
29235    function setWrapToString(wrapper, reference, bitmask) {
29236      var source = (reference + '');
29237      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
29238    }
29239
29240    /**
29241     * Creates a function that'll short out and invoke `identity` instead
29242     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
29243     * milliseconds.
29244     *
29245     * @private
29246     * @param {Function} func The function to restrict.
29247     * @returns {Function} Returns the new shortable function.
29248     */
29249    function shortOut(func) {
29250      var count = 0,
29251          lastCalled = 0;
29252
29253      return function() {
29254        var stamp = nativeNow(),
29255            remaining = HOT_SPAN - (stamp - lastCalled);
29256
29257        lastCalled = stamp;
29258        if (remaining > 0) {
29259          if (++count >= HOT_COUNT) {
29260            return arguments[0];
29261          }
29262        } else {
29263          count = 0;
29264        }
29265        return func.apply(undefined, arguments);
29266      };
29267    }
29268
29269    /**
29270     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
29271     *
29272     * @private
29273     * @param {Array} array The array to shuffle.
29274     * @param {number} [size=array.length] The size of `array`.
29275     * @returns {Array} Returns `array`.
29276     */
29277    function shuffleSelf(array, size) {
29278      var index = -1,
29279          length = array.length,
29280          lastIndex = length - 1;
29281
29282      size = size === undefined ? length : size;
29283      while (++index < size) {
29284        var rand = baseRandom(index, lastIndex),
29285            value = array[rand];
29286
29287        array[rand] = array[index];
29288        array[index] = value;
29289      }
29290      array.length = size;
29291      return array;
29292    }
29293
29294    /**
29295     * Converts `string` to a property path array.
vendor: 1,775 bytes, lines 29296-29356
29296     *
29297     * @private
29298     * @param {string} string The string to convert.
29299     * @returns {Array} Returns the property path array.
29300     */
29301    var stringToPath = memoizeCapped(function(string) {
29302      var result = [];
29303      if (string.charCodeAt(0) === 46 /* . */) {
29304        result.push('');
29305      }
29306      string.replace(rePropName, function(match, number, quote, subString) {
29307        result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
29308      });
29309      return result;
29310    });
29311
29312    /**
29313     * Converts `value` to a string key if it's not a string or symbol.
29314     *
29315     * @private
29316     * @param {*} value The value to inspect.
29317     * @returns {string|symbol} Returns the key.
29318     */
29319    function toKey(value) {
29320      if (typeof value == 'string' || isSymbol(value)) {
29321        return value;
29322      }
29323      var result = (value + '');
29324      return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
29325    }
29326
29327    /**
29328     * Converts `func` to its source code.
29329     *
29330     * @private
29331     * @param {Function} func The function to convert.
29332     * @returns {string} Returns the source code.
29333     */
29334    function toSource(func) {
29335      if (func != null) {
29336        try {
29337          return funcToString.call(func);
29338        } catch (e) {}
29339        try {
29340          return (func + '');
29341        } catch (e) {}
29342      }
29343      return '';
29344    }
29345
29346    /**
29347     * Updates wrapper `details` based on `bitmask` flags.
29348     *
29349     * @private
29350     * @returns {Array} details The details to modify.
29351     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
29352     * @returns {Array} Returns `details`.
29353     */
29354    function updateWrapDetails(details, bitmask) {
29355      arrayEach(wrapFlags, function(pair) {
29356        var value = '_.' + pair[0];
vendor: 7,345 bytes, lines 29357-29584
29357        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
29358          details.push(value);
29359        }
29360      });
29361      return details.sort();
29362    }
29363
29364    /**
29365     * Creates a clone of `wrapper`.
29366     *
29367     * @private
29368     * @param {Object} wrapper The wrapper to clone.
29369     * @returns {Object} Returns the cloned wrapper.
29370     */
29371    function wrapperClone(wrapper) {
29372      if (wrapper instanceof LazyWrapper) {
29373        return wrapper.clone();
29374      }
29375      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
29376      result.__actions__ = copyArray(wrapper.__actions__);
29377      result.__index__  = wrapper.__index__;
29378      result.__values__ = wrapper.__values__;
29379      return result;
29380    }
29381
29382    /*------------------------------------------------------------------------*/
29383
29384    /**
29385     * Creates an array of elements split into groups the length of `size`.
29386     * If `array` can't be split evenly, the final chunk will be the remaining
29387     * elements.
29388     *
29389     * @static
29390     * @memberOf _
29391     * @since 3.0.0
29392     * @category Array
29393     * @param {Array} array The array to process.
29394     * @param {number} [size=1] The length of each chunk
29395     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
29396     * @returns {Array} Returns the new array of chunks.
29397     * @example
29398     *
29399     * _.chunk(['a', 'b', 'c', 'd'], 2);
29400     * // => [['a', 'b'], ['c', 'd']]
29401     *
29402     * _.chunk(['a', 'b', 'c', 'd'], 3);
29403     * // => [['a', 'b', 'c'], ['d']]
29404     */
29405    function chunk(array, size, guard) {
29406      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
29407        size = 1;
29408      } else {
29409        size = nativeMax(toInteger(size), 0);
29410      }
29411      var length = array == null ? 0 : array.length;
29412      if (!length || size < 1) {
29413        return [];
29414      }
29415      var index = 0,
29416          resIndex = 0,
29417          result = Array(nativeCeil(length / size));
29418
29419      while (index < length) {
29420        result[resIndex++] = baseSlice(array, index, (index += size));
29421      }
29422      return result;
29423    }
29424
29425    /**
29426     * Creates an array with all falsey values removed. The values `false`, `null`,
29427     * `0`, `-0`, `0n`, `""`, `undefined`, and `NaN` are falsy.
29428     *
29429     * @static
29430     * @memberOf _
29431     * @since 0.1.0
29432     * @category Array
29433     * @param {Array} array The array to compact.
29434     * @returns {Array} Returns the new array of filtered values.
29435     * @example
29436     *
29437     * _.compact([0, 1, false, 2, '', 3]);
29438     * // => [1, 2, 3]
29439     */
29440    function compact(array) {
29441      var index = -1,
29442          length = array == null ? 0 : array.length,
29443          resIndex = 0,
29444          result = [];
29445
29446      while (++index < length) {
29447        var value = array[index];
29448        if (value) {
29449          result[resIndex++] = value;
29450        }
29451      }
29452      return result;
29453    }
29454
29455    /**
29456     * Creates a new array concatenating `array` with any additional arrays
29457     * and/or values.
29458     *
29459     * @static
29460     * @memberOf _
29461     * @since 4.0.0
29462     * @category Array
29463     * @param {Array} array The array to concatenate.
29464     * @param {...*} [values] The values to concatenate.
29465     * @returns {Array} Returns the new concatenated array.
29466     * @example
29467     *
29468     * var array = [1];
29469     * var other = _.concat(array, 2, [3], [[4]]);
29470     *
29471     * console.log(other);
29472     * // => [1, 2, 3, [4]]
29473     *
29474     * console.log(array);
29475     * // => [1]
29476     */
29477    function concat() {
29478      var length = arguments.length;
29479      if (!length) {
29480        return [];
29481      }
29482      var args = Array(length - 1),
29483          array = arguments[0],
29484          index = length;
29485
29486      while (index--) {
29487        args[index - 1] = arguments[index];
29488      }
29489      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
29490    }
29491
29492    /**
29493     * Creates an array of `array` values not included in the other given arrays
29494     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
29495     * for equality comparisons. The order and references of result values are
29496     * determined by the first array.
29497     *
29498     * **Note:** Unlike `_.pullAll`, this method returns a new array.
29499     *
29500     * @static
29501     * @memberOf _
29502     * @since 0.1.0
29503     * @category Array
29504     * @param {Array} array The array to inspect.
29505     * @param {...Array} [values] The values to exclude.
29506     * @returns {Array} Returns the new array of filtered values.
29507     * @see _.without, _.xor
29508     * @example
29509     *
29510     * _.difference([2, 1], [2, 3]);
29511     * // => [1]
29512     */
29513    var difference = baseRest(function(array, values) {
29514      return isArrayLikeObject(array)
29515        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
29516        : [];
29517    });
29518
29519    /**
29520     * This method is like `_.difference` except that it accepts `iteratee` which
29521     * is invoked for each element of `array` and `values` to generate the criterion
29522     * by which they're compared. The order and references of result values are
29523     * determined by the first array. The iteratee is invoked with one argument:
29524     * (value).
29525     *
29526     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
29527     *
29528     * @static
29529     * @memberOf _
29530     * @since 4.0.0
29531     * @category Array
29532     * @param {Array} array The array to inspect.
29533     * @param {...Array} [values] The values to exclude.
29534     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
29535     * @returns {Array} Returns the new array of filtered values.
29536     * @example
29537     *
29538     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
29539     * // => [1.2]
29540     *
29541     * // The `_.property` iteratee shorthand.
29542     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
29543     * // => [{ 'x': 2 }]
29544     */
29545    var differenceBy = baseRest(function(array, values) {
29546      var iteratee = last(values);
29547      if (isArrayLikeObject(iteratee)) {
29548        iteratee = undefined;
29549      }
29550      return isArrayLikeObject(array)
29551        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
29552        : [];
29553    });
29554
29555    /**
29556     * This method is like `_.difference` except that it accepts `comparator`
29557     * which is invoked to compare elements of `array` to `values`. The order and
29558     * references of result values are determined by the first array. The comparator
29559     * is invoked with two arguments: (arrVal, othVal).
29560     *
29561     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
29562     *
29563     * @static
29564     * @memberOf _
29565     * @since 4.0.0
29566     * @category Array
29567     * @param {Array} array The array to inspect.
29568     * @param {...Array} [values] The values to exclude.
29569     * @param {Function} [comparator] The comparator invoked per element.
29570     * @returns {Array} Returns the new array of filtered values.
29571     * @example
29572     *
29573     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
29574     *
29575     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
29576     * // => [{ 'x': 2, 'y': 1 }]
29577     */
29578    var differenceWith = baseRest(function(array, values) {
29579      var comparator = last(values);
29580      if (isArrayLikeObject(comparator)) {
29581        comparator = undefined;
29582      }
29583      return isArrayLikeObject(array)
29584        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, c
vendor: 10,912 bytes, lines 29584-29945
29584omparator)
29585        : [];
29586    });
29587
29588    /**
29589     * Creates a slice of `array` with `n` elements dropped from the beginning.
29590     *
29591     * @static
29592     * @memberOf _
29593     * @since 0.5.0
29594     * @category Array
29595     * @param {Array} array The array to query.
29596     * @param {number} [n=1] The number of elements to drop.
29597     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
29598     * @returns {Array} Returns the slice of `array`.
29599     * @example
29600     *
29601     * _.drop([1, 2, 3]);
29602     * // => [2, 3]
29603     *
29604     * _.drop([1, 2, 3], 2);
29605     * // => [3]
29606     *
29607     * _.drop([1, 2, 3], 5);
29608     * // => []
29609     *
29610     * _.drop([1, 2, 3], 0);
29611     * // => [1, 2, 3]
29612     */
29613    function drop(array, n, guard) {
29614      var length = array == null ? 0 : array.length;
29615      if (!length) {
29616        return [];
29617      }
29618      n = (guard || n === undefined) ? 1 : toInteger(n);
29619      return baseSlice(array, n < 0 ? 0 : n, length);
29620    }
29621
29622    /**
29623     * Creates a slice of `array` with `n` elements dropped from the end.
29624     *
29625     * @static
29626     * @memberOf _
29627     * @since 3.0.0
29628     * @category Array
29629     * @param {Array} array The array to query.
29630     * @param {number} [n=1] The number of elements to drop.
29631     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
29632     * @returns {Array} Returns the slice of `array`.
29633     * @example
29634     *
29635     * _.dropRight([1, 2, 3]);
29636     * // => [1, 2]
29637     *
29638     * _.dropRight([1, 2, 3], 2);
29639     * // => [1]
29640     *
29641     * _.dropRight([1, 2, 3], 5);
29642     * // => []
29643     *
29644     * _.dropRight([1, 2, 3], 0);
29645     * // => [1, 2, 3]
29646     */
29647    function dropRight(array, n, guard) {
29648      var length = array == null ? 0 : array.length;
29649      if (!length) {
29650        return [];
29651      }
29652      n = (guard || n === undefined) ? 1 : toInteger(n);
29653      n = length - n;
29654      return baseSlice(array, 0, n < 0 ? 0 : n);
29655    }
29656
29657    /**
29658     * Creates a slice of `array` excluding elements dropped from the end.
29659     * Elements are dropped until `predicate` returns falsey. The predicate is
29660     * invoked with three arguments: (value, index, array).
29661     *
29662     * @static
29663     * @memberOf _
29664     * @since 3.0.0
29665     * @category Array
29666     * @param {Array} array The array to query.
29667     * @param {Function} [predicate=_.identity] The function invoked per iteration.
29668     * @returns {Array} Returns the slice of `array`.
29669     * @example
29670     *
29671     * var users = [
29672     *   { 'user': 'barney',  'active': true },
29673     *   { 'user': 'fred',    'active': false },
29674     *   { 'user': 'pebbles', 'active': false }
29675     * ];
29676     *
29677     * _.dropRightWhile(users, function(o) { return !o.active; });
29678     * // => objects for ['barney']
29679     *
29680     * // The `_.matches` iteratee shorthand.
29681     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
29682     * // => objects for ['barney', 'fred']
29683     *
29684     * // The `_.matchesProperty` iteratee shorthand.
29685     * _.dropRightWhile(users, ['active', false]);
29686     * // => objects for ['barney']
29687     *
29688     * // The `_.property` iteratee shorthand.
29689     * _.dropRightWhile(users, 'active');
29690     * // => objects for ['barney', 'fred', 'pebbles']
29691     */
29692    function dropRightWhile(array, predicate) {
29693      return (array && array.length)
29694        ? baseWhile(array, getIteratee(predicate, 3), true, true)
29695        : [];
29696    }
29697
29698    /**
29699     * Creates a slice of `array` excluding elements dropped from the beginning.
29700     * Elements are dropped until `predicate` returns falsey. The predicate is
29701     * invoked with three arguments: (value, index, array).
29702     *
29703     * @static
29704     * @memberOf _
29705     * @since 3.0.0
29706     * @category Array
29707     * @param {Array} array The array to query.
29708     * @param {Function} [predicate=_.identity] The function invoked per iteration.
29709     * @returns {Array} Returns the slice of `array`.
29710     * @example
29711     *
29712     * var users = [
29713     *   { 'user': 'barney',  'active': false },
29714     *   { 'user': 'fred',    'active': false },
29715     *   { 'user': 'pebbles', 'active': true }
29716     * ];
29717     *
29718     * _.dropWhile(users, function(o) { return !o.active; });
29719     * // => objects for ['pebbles']
29720     *
29721     * // The `_.matches` iteratee shorthand.
29722     * _.dropWhile(users, { 'user': 'barney', 'active': false });
29723     * // => objects for ['fred', 'pebbles']
29724     *
29725     * // The `_.matchesProperty` iteratee shorthand.
29726     * _.dropWhile(users, ['active', false]);
29727     * // => objects for ['pebbles']
29728     *
29729     * // The `_.property` iteratee shorthand.
29730     * _.dropWhile(users, 'active');
29731     * // => objects for ['barney', 'fred', 'pebbles']
29732     */
29733    function dropWhile(array, predicate) {
29734      return (array && array.length)
29735        ? baseWhile(array, getIteratee(predicate, 3), true)
29736        : [];
29737    }
29738
29739    /**
29740     * Fills elements of `array` with `value` from `start` up to, but not
29741     * including, `end`.
29742     *
29743     * **Note:** This method mutates `array`.
29744     *
29745     * @static
29746     * @memberOf _
29747     * @since 3.2.0
29748     * @category Array
29749     * @param {Array} array The array to fill.
29750     * @param {*} value The value to fill `array` with.
29751     * @param {number} [start=0] The start position.
29752     * @param {number} [end=array.length] The end position.
29753     * @returns {Array} Returns `array`.
29754     * @example
29755     *
29756     * var array = [1, 2, 3];
29757     *
29758     * _.fill(array, 'a');
29759     * console.log(array);
29760     * // => ['a', 'a', 'a']
29761     *
29762     * _.fill(Array(3), 2);
29763     * // => [2, 2, 2]
29764     *
29765     * _.fill([4, 6, 8, 10], '*', 1, 3);
29766     * // => [4, '*', '*', 10]
29767     */
29768    function fill(array, value, start, end) {
29769      var length = array == null ? 0 : array.length;
29770      if (!length) {
29771        return [];
29772      }
29773      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
29774        start = 0;
29775        end = length;
29776      }
29777      return baseFill(array, value, start, end);
29778    }
29779
29780    /**
29781     * This method is like `_.find` except that it returns the index of the first
29782     * element `predicate` returns truthy for instead of the element itself.
29783     *
29784     * @static
29785     * @memberOf _
29786     * @since 1.1.0
29787     * @category Array
29788     * @param {Array} array The array to inspect.
29789     * @param {Function} [predicate=_.identity] The function invoked per iteration.
29790     * @param {number} [fromIndex=0] The index to search from.
29791     * @returns {number} Returns the index of the found element, else `-1`.
29792     * @example
29793     *
29794     * var users = [
29795     *   { 'user': 'barney',  'active': false },
29796     *   { 'user': 'fred',    'active': false },
29797     *   { 'user': 'pebbles', 'active': true }
29798     * ];
29799     *
29800     * _.findIndex(users, function(o) { return o.user == 'barney'; });
29801     * // => 0
29802     *
29803     * // The `_.matches` iteratee shorthand.
29804     * _.findIndex(users, { 'user': 'fred', 'active': false });
29805     * // => 1
29806     *
29807     * // The `_.matchesProperty` iteratee shorthand.
29808     * _.findIndex(users, ['active', false]);
29809     * // => 0
29810     *
29811     * // The `_.property` iteratee shorthand.
29812     * _.findIndex(users, 'active');
29813     * // => 2
29814     */
29815    function findIndex(array, predicate, fromIndex) {
29816      var length = array == null ? 0 : array.length;
29817      if (!length) {
29818        return -1;
29819      }
29820      var index = fromIndex == null ? 0 : toInteger(fromIndex);
29821      if (index < 0) {
29822        index = nativeMax(length + index, 0);
29823      }
29824      return baseFindIndex(array, getIteratee(predicate, 3), index);
29825    }
29826
29827    /**
29828     * This method is like `_.findIndex` except that it iterates over elements
29829     * of `collection` from right to left.
29830     *
29831     * @static
29832     * @memberOf _
29833     * @since 2.0.0
29834     * @category Array
29835     * @param {Array} array The array to inspect.
29836     * @param {Function} [predicate=_.identity] The function invoked per iteration.
29837     * @param {number} [fromIndex=array.length-1] The index to search from.
29838     * @returns {number} Returns the index of the found element, else `-1`.
29839     * @example
29840     *
29841     * var users = [
29842     *   { 'user': 'barney',  'active': true },
29843     *   { 'user': 'fred',    'active': false },
29844     *   { 'user': 'pebbles', 'active': false }
29845     * ];
29846     *
29847     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
29848     * // => 2
29849     *
29850     * // The `_.matches` iteratee shorthand.
29851     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
29852     * // => 0
29853     *
29854     * // The `_.matchesProperty` iteratee shorthand.
29855     * _.findLastIndex(users, ['active', false]);
29856     * // => 2
29857     *
29858     * // The `_.property` iteratee shorthand.
29859     * _.findLastIndex(users, 'active');
29860     * // => 0
29861     */
29862    function findLastIndex(array, predicate, fromIndex) {
29863      var length = array == null ? 0 : array.length;
29864      if (!length) {
29865        return -1;
29866      }
29867      var index = length - 1;
29868      if (fromIndex !== undefined) {
29869        index = toInteger(fromIndex);
29870        index = fromIndex < 0
29871          ? nativeMax(length + index, 0)
29872          : nativeMin(index, length - 1);
29873      }
29874      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
29875    }
29876
29877    /**
29878     * Flattens `array` a single level deep.
29879     *
29880     * @static
29881     * @memberOf _
29882     * @since 0.1.0
29883     * @category Array
29884     * @param {Array} array The array to flatten.
29885     * @returns {Array} Returns the new flattened array.
29886     * @example
29887     *
29888     * _.flatten([1, [2, [3, [4]], 5]]);
29889     * // => [1, 2, [3, [4]], 5]
29890     */
29891    function flatten(array) {
29892      var length = array == null ? 0 : array.length;
29893      return length ? baseFlatten(array, 1) : [];
29894    }
29895
29896    /**
29897     * Recursively flattens `array`.
29898     *
29899     * @static
29900     * @memberOf _
29901     * @since 3.0.0
29902     * @category Array
29903     * @param {Array} array The array to flatten.
29904     * @returns {Array} Returns the new flattened array.
29905     * @example
29906     *
29907     * _.flattenDeep([1, [2, [3, [4]], 5]]);
29908     * // => [1, 2, 3, 4, 5]
29909     */
29910    function flattenDeep(array) {
29911      var length = array == null ? 0 : array.length;
29912      return length ? baseFlatten(array, INFINITY) : [];
29913    }
29914
29915    /**
29916     * Recursively flatten `array` up to `depth` times.
29917     *
29918     * @static
29919     * @memberOf _
29920     * @since 4.4.0
29921     * @category Array
29922     * @param {Array} array The array to flatten.
29923     * @param {number} [depth=1] The maximum recursion depth.
29924     * @returns {Array} Returns the new flattened array.
29925     * @example
29926     *
29927     * var array = [1, [2, [3, [4]], 5]];
29928     *
29929     * _.flattenDepth(array, 1);
29930     * // => [1, 2, [3, [4]], 5]
29931     *
29932     * _.flattenDepth(array, 2);
29933     * // => [1, 2, 3, [4], 5]
29934     */
29935    function flattenDepth(array, depth) {
29936      var length = array == null ? 0 : array.length;
29937      if (!length) {
29938        return [];
29939      }
29940      depth = depth === undefined ? 1 : toInteger(depth);
29941      return baseFlatten(array, depth);
29942    }
29943
29944    /**
29945     * The inverse of `_.toPairs`;
vendor: 6,026 bytes, lines 29945-30137
29945 this method returns an object composed
29946     * from key-value `pairs`.
29947     *
29948     * @static
29949     * @memberOf _
29950     * @since 4.0.0
29951     * @category Array
29952     * @param {Array} pairs The key-value pairs.
29953     * @returns {Object} Returns the new object.
29954     * @example
29955     *
29956     * _.fromPairs([['a', 1], ['b', 2]]);
29957     * // => { 'a': 1, 'b': 2 }
29958     */
29959    function fromPairs(pairs) {
29960      var index = -1,
29961          length = pairs == null ? 0 : pairs.length,
29962          result = {};
29963
29964      while (++index < length) {
29965        var pair = pairs[index];
29966        baseAssignValue(result, pair[0], pair[1]);
29967      }
29968      return result;
29969    }
29970
29971    /**
29972     * Gets the first element of `array`.
29973     *
29974     * @static
29975     * @memberOf _
29976     * @since 0.1.0
29977     * @alias first
29978     * @category Array
29979     * @param {Array} array The array to query.
29980     * @returns {*} Returns the first element of `array`.
29981     * @example
29982     *
29983     * _.head([1, 2, 3]);
29984     * // => 1
29985     *
29986     * _.head([]);
29987     * // => undefined
29988     */
29989    function head(array) {
29990      return (array && array.length) ? array[0] : undefined;
29991    }
29992
29993    /**
29994     * Gets the index at which the first occurrence of `value` is found in `array`
29995     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
29996     * for equality comparisons. If `fromIndex` is negative, it's used as the
29997     * offset from the end of `array`.
29998     *
29999     * @static
30000     * @memberOf _
30001     * @since 0.1.0
30002     * @category Array
30003     * @param {Array} array The array to inspect.
30004     * @param {*} value The value to search for.
30005     * @param {number} [fromIndex=0] The index to search from.
30006     * @returns {number} Returns the index of the matched value, else `-1`.
30007     * @example
30008     *
30009     * _.indexOf([1, 2, 1, 2], 2);
30010     * // => 1
30011     *
30012     * // Search from the `fromIndex`.
30013     * _.indexOf([1, 2, 1, 2], 2, 2);
30014     * // => 3
30015     */
30016    function indexOf(array, value, fromIndex) {
30017      var length = array == null ? 0 : array.length;
30018      if (!length) {
30019        return -1;
30020      }
30021      var index = fromIndex == null ? 0 : toInteger(fromIndex);
30022      if (index < 0) {
30023        index = nativeMax(length + index, 0);
30024      }
30025      return baseIndexOf(array, value, index);
30026    }
30027
30028    /**
30029     * Gets all but the last element of `array`.
30030     *
30031     * @static
30032     * @memberOf _
30033     * @since 0.1.0
30034     * @category Array
30035     * @param {Array} array The array to query.
30036     * @returns {Array} Returns the slice of `array`.
30037     * @example
30038     *
30039     * _.initial([1, 2, 3]);
30040     * // => [1, 2]
30041     */
30042    function initial(array) {
30043      var length = array == null ? 0 : array.length;
30044      return length ? baseSlice(array, 0, -1) : [];
30045    }
30046
30047    /**
30048     * Creates an array of unique values that are included in all given arrays
30049     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
30050     * for equality comparisons. The order and references of result values are
30051     * determined by the first array.
30052     *
30053     * @static
30054     * @memberOf _
30055     * @since 0.1.0
30056     * @category Array
30057     * @param {...Array} [arrays] The arrays to inspect.
30058     * @returns {Array} Returns the new array of intersecting values.
30059     * @example
30060     *
30061     * _.intersection([2, 1], [2, 3]);
30062     * // => [2]
30063     */
30064    var intersection = baseRest(function(arrays) {
30065      var mapped = arrayMap(arrays, castArrayLikeObject);
30066      return (mapped.length && mapped[0] === arrays[0])
30067        ? baseIntersection(mapped)
30068        : [];
30069    });
30070
30071    /**
30072     * This method is like `_.intersection` except that it accepts `iteratee`
30073     * which is invoked for each element of each `arrays` to generate the criterion
30074     * by which they're compared. The order and references of result values are
30075     * determined by the first array. The iteratee is invoked with one argument:
30076     * (value).
30077     *
30078     * @static
30079     * @memberOf _
30080     * @since 4.0.0
30081     * @category Array
30082     * @param {...Array} [arrays] The arrays to inspect.
30083     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
30084     * @returns {Array} Returns the new array of intersecting values.
30085     * @example
30086     *
30087     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
30088     * // => [2.1]
30089     *
30090     * // The `_.property` iteratee shorthand.
30091     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
30092     * // => [{ 'x': 1 }]
30093     */
30094    var intersectionBy = baseRest(function(arrays) {
30095      var iteratee = last(arrays),
30096          mapped = arrayMap(arrays, castArrayLikeObject);
30097
30098      if (iteratee === last(mapped)) {
30099        iteratee = undefined;
30100      } else {
30101        mapped.pop();
30102      }
30103      return (mapped.length && mapped[0] === arrays[0])
30104        ? baseIntersection(mapped, getIteratee(iteratee, 2))
30105        : [];
30106    });
30107
30108    /**
30109     * This method is like `_.intersection` except that it accepts `comparator`
30110     * which is invoked to compare elements of `arrays`. The order and references
30111     * of result values are determined by the first array. The comparator is
30112     * invoked with two arguments: (arrVal, othVal).
30113     *
30114     * @static
30115     * @memberOf _
30116     * @since 4.0.0
30117     * @category Array
30118     * @param {...Array} [arrays] The arrays to inspect.
30119     * @param {Function} [comparator] The comparator invoked per element.
30120     * @returns {Array} Returns the new array of intersecting values.
30121     * @example
30122     *
30123     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
30124     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
30125     *
30126     * _.intersectionWith(objects, others, _.isEqual);
30127     * // => [{ 'x': 1, 'y': 2 }]
30128     */
30129    var intersectionWith = baseRest(function(arrays) {
30130      var comparator = last(arrays),
30131          mapped = arrayMap(arrays, castArrayLikeObject);
30132
30133      comparator = typeof comparator == 'function' ? comparator : undefined;
30134      if (comparator) {
30135        mapped.pop();
30136      }
30137      return (mapped.length && mapped[0] === arrays[0])
vendor: 56,125 bytes, lines 30138-31940
30138        ? baseIntersection(mapped, undefined, comparator)
30139        : [];
30140    });
30141
30142    /**
30143     * Converts all elements in `array` into a string separated by `separator`.
30144     *
30145     * @static
30146     * @memberOf _
30147     * @since 4.0.0
30148     * @category Array
30149     * @param {Array} array The array to convert.
30150     * @param {string} [separator=','] The element separator.
30151     * @returns {string} Returns the joined string.
30152     * @example
30153     *
30154     * _.join(['a', 'b', 'c'], '~');
30155     * // => 'a~b~c'
30156     */
30157    function join(array, separator) {
30158      return array == null ? '' : nativeJoin.call(array, separator);
30159    }
30160
30161    /**
30162     * Gets the last element of `array`.
30163     *
30164     * @static
30165     * @memberOf _
30166     * @since 0.1.0
30167     * @category Array
30168     * @param {Array} array The array to query.
30169     * @returns {*} Returns the last element of `array`.
30170     * @example
30171     *
30172     * _.last([1, 2, 3]);
30173     * // => 3
30174     */
30175    function last(array) {
30176      var length = array == null ? 0 : array.length;
30177      return length ? array[length - 1] : undefined;
30178    }
30179
30180    /**
30181     * This method is like `_.indexOf` except that it iterates over elements of
30182     * `array` from right to left.
30183     *
30184     * @static
30185     * @memberOf _
30186     * @since 0.1.0
30187     * @category Array
30188     * @param {Array} array The array to inspect.
30189     * @param {*} value The value to search for.
30190     * @param {number} [fromIndex=array.length-1] The index to search from.
30191     * @returns {number} Returns the index of the matched value, else `-1`.
30192     * @example
30193     *
30194     * _.lastIndexOf([1, 2, 1, 2], 2);
30195     * // => 3
30196     *
30197     * // Search from the `fromIndex`.
30198     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
30199     * // => 1
30200     */
30201    function lastIndexOf(array, value, fromIndex) {
30202      var length = array == null ? 0 : array.length;
30203      if (!length) {
30204        return -1;
30205      }
30206      var index = length;
30207      if (fromIndex !== undefined) {
30208        index = toInteger(fromIndex);
30209        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
30210      }
30211      return value === value
30212        ? strictLastIndexOf(array, value, index)
30213        : baseFindIndex(array, baseIsNaN, index, true);
30214    }
30215
30216    /**
30217     * Gets the element at index `n` of `array`. If `n` is negative, the nth
30218     * element from the end is returned.
30219     *
30220     * @static
30221     * @memberOf _
30222     * @since 4.11.0
30223     * @category Array
30224     * @param {Array} array The array to query.
30225     * @param {number} [n=0] The index of the element to return.
30226     * @returns {*} Returns the nth element of `array`.
30227     * @example
30228     *
30229     * var array = ['a', 'b', 'c', 'd'];
30230     *
30231     * _.nth(array, 1);
30232     * // => 'b'
30233     *
30234     * _.nth(array, -2);
30235     * // => 'c';
30236     */
30237    function nth(array, n) {
30238      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
30239    }
30240
30241    /**
30242     * Removes all given values from `array` using
30243     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
30244     * for equality comparisons.
30245     *
30246     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
30247     * to remove elements from an array by predicate.
30248     *
30249     * @static
30250     * @memberOf _
30251     * @since 2.0.0
30252     * @category Array
30253     * @param {Array} array The array to modify.
30254     * @param {...*} [values] The values to remove.
30255     * @returns {Array} Returns `array`.
30256     * @example
30257     *
30258     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
30259     *
30260     * _.pull(array, 'a', 'c');
30261     * console.log(array);
30262     * // => ['b', 'b']
30263     */
30264    var pull = baseRest(pullAll);
30265
30266    /**
30267     * This method is like `_.pull` except that it accepts an array of values to remove.
30268     *
30269     * **Note:** Unlike `_.difference`, this method mutates `array`.
30270     *
30271     * @static
30272     * @memberOf _
30273     * @since 4.0.0
30274     * @category Array
30275     * @param {Array} array The array to modify.
30276     * @param {Array} values The values to remove.
30277     * @returns {Array} Returns `array`.
30278     * @example
30279     *
30280     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
30281     *
30282     * _.pullAll(array, ['a', 'c']);
30283     * console.log(array);
30284     * // => ['b', 'b']
30285     */
30286    function pullAll(array, values) {
30287      return (array && array.length && values && values.length)
30288        ? basePullAll(array, values)
30289        : array;
30290    }
30291
30292    /**
30293     * This method is like `_.pullAll` except that it accepts `iteratee` which is
30294     * invoked for each element of `array` and `values` to generate the criterion
30295     * by which they're compared. The iteratee is invoked with one argument: (value).
30296     *
30297     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
30298     *
30299     * @static
30300     * @memberOf _
30301     * @since 4.0.0
30302     * @category Array
30303     * @param {Array} array The array to modify.
30304     * @param {Array} values The values to remove.
30305     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
30306     * @returns {Array} Returns `array`.
30307     * @example
30308     *
30309     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
30310     *
30311     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
30312     * console.log(array);
30313     * // => [{ 'x': 2 }]
30314     */
30315    function pullAllBy(array, values, iteratee) {
30316      return (array && array.length && values && values.length)
30317        ? basePullAll(array, values, getIteratee(iteratee, 2))
30318        : array;
30319    }
30320
30321    /**
30322     * This method is like `_.pullAll` except that it accepts `comparator` which
30323     * is invoked to compare elements of `array` to `values`. The comparator is
30324     * invoked with two arguments: (arrVal, othVal).
30325     *
30326     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
30327     *
30328     * @static
30329     * @memberOf _
30330     * @since 4.6.0
30331     * @category Array
30332     * @param {Array} array The array to modify.
30333     * @param {Array} values The values to remove.
30334     * @param {Function} [comparator] The comparator invoked per element.
30335     * @returns {Array} Returns `array`.
30336     * @example
30337     *
30338     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
30339     *
30340     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
30341     * console.log(array);
30342     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
30343     */
30344    function pullAllWith(array, values, comparator) {
30345      return (array && array.length && values && values.length)
30346        ? basePullAll(array, values, undefined, comparator)
30347        : array;
30348    }
30349
30350    /**
30351     * Removes elements from `array` corresponding to `indexes` and returns an
30352     * array of removed elements.
30353     *
30354     * **Note:** Unlike `_.at`, this method mutates `array`.
30355     *
30356     * @static
30357     * @memberOf _
30358     * @since 3.0.0
30359     * @category Array
30360     * @param {Array} array The array to modify.
30361     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
30362     * @returns {Array} Returns the new array of removed elements.
30363     * @example
30364     *
30365     * var array = ['a', 'b', 'c', 'd'];
30366     * var pulled = _.pullAt(array, [1, 3]);
30367     *
30368     * console.log(array);
30369     * // => ['a', 'c']
30370     *
30371     * console.log(pulled);
30372     * // => ['b', 'd']
30373     */
30374    var pullAt = flatRest(function(array, indexes) {
30375      var length = array == null ? 0 : array.length,
30376          result = baseAt(array, indexes);
30377
30378      basePullAt(array, arrayMap(indexes, function(index) {
30379        return isIndex(index, length) ? +index : index;
30380      }).sort(compareAscending));
30381
30382      return result;
30383    });
30384
30385    /**
30386     * Removes all elements from `array` that `predicate` returns truthy for
30387     * and returns an array of the removed elements. The predicate is invoked
30388     * with three arguments: (value, index, array).
30389     *
30390     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
30391     * to pull elements from an array by value.
30392     *
30393     * @static
30394     * @memberOf _
30395     * @since 2.0.0
30396     * @category Array
30397     * @param {Array} array The array to modify.
30398     * @param {Function} [predicate=_.identity] The function invoked per iteration.
30399     * @returns {Array} Returns the new array of removed elements.
30400     * @example
30401     *
30402     * var array = [1, 2, 3, 4];
30403     * var evens = _.remove(array, function(n) {
30404     *   return n % 2 == 0;
30405     * });
30406     *
30407     * console.log(array);
30408     * // => [1, 3]
30409     *
30410     * console.log(evens);
30411     * // => [2, 4]
30412     */
30413    function remove(array, predicate) {
30414      var result = [];
30415      if (!(array && array.length)) {
30416        return result;
30417      }
30418      var index = -1,
30419          indexes = [],
30420          length = array.length;
30421
30422      predicate = getIteratee(predicate, 3);
30423      while (++index < length) {
30424        var value = array[index];
30425        if (predicate(value, index, array)) {
30426          result.push(value);
30427          indexes.push(index);
30428        }
30429      }
30430      basePullAt(array, indexes);
30431      return result;
30432    }
30433
30434    /**
30435     * Reverses `array` so that the first element becomes the last, the second
30436     * element becomes the second to last, and so on.
30437     *
30438     * **Note:** This method mutates `array` and is based on
30439     * [`Array#reverse`](https://mdn.io/Array/reverse).
30440     *
30441     * @static
30442     * @memberOf _
30443     * @since 4.0.0
30444     * @category Array
30445     * @param {Array} array The array to modify.
30446     * @returns {Array} Returns `array`.
30447     * @example
30448     *
30449     * var array = [1, 2, 3];
30450     *
30451     * _.reverse(array);
30452     * // => [3, 2, 1]
30453     *
30454     * console.log(array);
30455     * // => [3, 2, 1]
30456     */
30457    function reverse(array) {
30458      return array == null ? array : nativeReverse.call(array);
30459    }
30460
30461    /**
30462     * Creates a slice of `array` from `start` up to, but not including, `end`.
30463     *
30464     * **Note:** This method is used instead of
30465     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
30466     * returned.
30467     *
30468     * @static
30469     * @memberOf _
30470     * @since 3.0.0
30471     * @category Array
30472     * @param {Array} array The array to slice.
30473     * @param {number} [start=0] The start position.
30474     * @param {number} [end=array.length] The end position.
30475     * @returns {Array} Returns the slice of `array`.
30476     */
30477    function slice(array, start, end) {
30478      var length = array == null ? 0 : array.length;
30479      if (!length) {
30480        return [];
30481      }
30482      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
30483        start = 0;
30484        end = length;
30485      }
30486      else {
30487        start = start == null ? 0 : toInteger(start);
30488        end = end === undefined ? length : toInteger(end);
30489      }
30490      return baseSlice(array, start, end);
30491    }
30492
30493    /**
30494     * Uses a binary search to determine the lowest index at which `value`
30495     * should be inserted into `array` in order to maintain its sort order.
30496     *
30497     * @static
30498     * @memberOf _
30499     * @since 0.1.0
30500     * @category Array
30501     * @param {Array} array The sorted array to inspect.
30502     * @param {*} value The value to evaluate.
30503     * @returns {number} Returns the index at which `value` should be inserted
30504     *  into `array`.
30505     * @example
30506     *
30507     * _.sortedIndex([30, 50], 40);
30508     * // => 1
30509     */
30510    function sortedIndex(array, value) {
30511      return baseSortedIndex(array, value);
30512    }
30513
30514    /**
30515     * This method is like `_.sortedIndex` except that it accepts `iteratee`
30516     * which is invoked for `value` and each element of `array` to compute their
30517     * sort ranking. The iteratee is invoked with one argument: (value).
30518     *
30519     * @static
30520     * @memberOf _
30521     * @since 4.0.0
30522     * @category Array
30523     * @param {Array} array The sorted array to inspect.
30524     * @param {*} value The value to evaluate.
30525     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
30526     * @returns {number} Returns the index at which `value` should be inserted
30527     *  into `array`.
30528     * @example
30529     *
30530     * var objects = [{ 'x': 4 }, { 'x': 5 }];
30531     *
30532     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
30533     * // => 0
30534     *
30535     * // The `_.property` iteratee shorthand.
30536     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
30537     * // => 0
30538     */
30539    function sortedIndexBy(array, value, iteratee) {
30540      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
30541    }
30542
30543    /**
30544     * This method is like `_.indexOf` except that it performs a binary
30545     * search on a sorted `array`.
30546     *
30547     * @static
30548     * @memberOf _
30549     * @since 4.0.0
30550     * @category Array
30551     * @param {Array} array The array to inspect.
30552     * @param {*} value The value to search for.
30553     * @returns {number} Returns the index of the matched value, else `-1`.
30554     * @example
30555     *
30556     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
30557     * // => 1
30558     */
30559    function sortedIndexOf(array, value) {
30560      var length = array == null ? 0 : array.length;
30561      if (length) {
30562        var index = baseSortedIndex(array, value);
30563        if (index < length && eq(array[index], value)) {
30564          return index;
30565        }
30566      }
30567      return -1;
30568    }
30569
30570    /**
30571     * This method is like `_.sortedIndex` except that it returns the highest
30572     * index at which `value` should be inserted into `array` in order to
30573     * maintain its sort order.
30574     *
30575     * @static
30576     * @memberOf _
30577     * @since 3.0.0
30578     * @category Array
30579     * @param {Array} array The sorted array to inspect.
30580     * @param {*} value The value to evaluate.
30581     * @returns {number} Returns the index at which `value` should be inserted
30582     *  into `array`.
30583     * @example
30584     *
30585     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
30586     * // => 4
30587     */
30588    function sortedLastIndex(array, value) {
30589      return baseSortedIndex(array, value, true);
30590    }
30591
30592    /**
30593     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
30594     * which is invoked for `value` and each element of `array` to compute their
30595     * sort ranking. The iteratee is invoked with one argument: (value).
30596     *
30597     * @static
30598     * @memberOf _
30599     * @since 4.0.0
30600     * @category Array
30601     * @param {Array} array The sorted array to inspect.
30602     * @param {*} value The value to evaluate.
30603     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
30604     * @returns {number} Returns the index at which `value` should be inserted
30605     *  into `array`.
30606     * @example
30607     *
30608     * var objects = [{ 'x': 4 }, { 'x': 5 }];
30609     *
30610     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
30611     * // => 1
30612     *
30613     * // The `_.property` iteratee shorthand.
30614     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
30615     * // => 1
30616     */
30617    function sortedLastIndexBy(array, value, iteratee) {
30618      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
30619    }
30620
30621    /**
30622     * This method is like `_.lastIndexOf` except that it performs a binary
30623     * search on a sorted `array`.
30624     *
30625     * @static
30626     * @memberOf _
30627     * @since 4.0.0
30628     * @category Array
30629     * @param {Array} array The array to inspect.
30630     * @param {*} value The value to search for.
30631     * @returns {number} Returns the index of the matched value, else `-1`.
30632     * @example
30633     *
30634     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
30635     * // => 3
30636     */
30637    function sortedLastIndexOf(array, value) {
30638      var length = array == null ? 0 : array.length;
30639      if (length) {
30640        var index = baseSortedIndex(array, value, true) - 1;
30641        if (eq(array[index], value)) {
30642          return index;
30643        }
30644      }
30645      return -1;
30646    }
30647
30648    /**
30649     * This method is like `_.uniq` except that it's designed and optimized
30650     * for sorted arrays.
30651     *
30652     * @static
30653     * @memberOf _
30654     * @since 4.0.0
30655     * @category Array
30656     * @param {Array} array The array to inspect.
30657     * @returns {Array} Returns the new duplicate free array.
30658     * @example
30659     *
30660     * _.sortedUniq([1, 1, 2]);
30661     * // => [1, 2]
30662     */
30663    function sortedUniq(array) {
30664      return (array && array.length)
30665        ? baseSortedUniq(array)
30666        : [];
30667    }
30668
30669    /**
30670     * This method is like `_.uniqBy` except that it's designed and optimized
30671     * for sorted arrays.
30672     *
30673     * @static
30674     * @memberOf _
30675     * @since 4.0.0
30676     * @category Array
30677     * @param {Array} array The array to inspect.
30678     * @param {Function} [iteratee] The iteratee invoked per element.
30679     * @returns {Array} Returns the new duplicate free array.
30680     * @example
30681     *
30682     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
30683     * // => [1.1, 2.3]
30684     */
30685    function sortedUniqBy(array, iteratee) {
30686      return (array && array.length)
30687        ? baseSortedUniq(array, getIteratee(iteratee, 2))
30688        : [];
30689    }
30690
30691    /**
30692     * Gets all but the first element of `array`.
30693     *
30694     * @static
30695     * @memberOf _
30696     * @since 4.0.0
30697     * @category Array
30698     * @param {Array} array The array to query.
30699     * @returns {Array} Returns the slice of `array`.
30700     * @example
30701     *
30702     * _.tail([1, 2, 3]);
30703     * // => [2, 3]
30704     */
30705    function tail(array) {
30706      var length = array == null ? 0 : array.length;
30707      return length ? baseSlice(array, 1, length) : [];
30708    }
30709
30710    /**
30711     * Creates a slice of `array` with `n` elements taken from the beginning.
30712     *
30713     * @static
30714     * @memberOf _
30715     * @since 0.1.0
30716     * @category Array
30717     * @param {Array} array The array to query.
30718     * @param {number} [n=1] The number of elements to take.
30719     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
30720     * @returns {Array} Returns the slice of `array`.
30721     * @example
30722     *
30723     * _.take([1, 2, 3]);
30724     * // => [1]
30725     *
30726     * _.take([1, 2, 3], 2);
30727     * // => [1, 2]
30728     *
30729     * _.take([1, 2, 3], 5);
30730     * // => [1, 2, 3]
30731     *
30732     * _.take([1, 2, 3], 0);
30733     * // => []
30734     */
30735    function take(array, n, guard) {
30736      if (!(array && array.length)) {
30737        return [];
30738      }
30739      n = (guard || n === undefined) ? 1 : toInteger(n);
30740      return baseSlice(array, 0, n < 0 ? 0 : n);
30741    }
30742
30743    /**
30744     * Creates a slice of `array` with `n` elements taken from the end.
30745     *
30746     * @static
30747     * @memberOf _
30748     * @since 3.0.0
30749     * @category Array
30750     * @param {Array} array The array to query.
30751     * @param {number} [n=1] The number of elements to take.
30752     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
30753     * @returns {Array} Returns the slice of `array`.
30754     * @example
30755     *
30756     * _.takeRight([1, 2, 3]);
30757     * // => [3]
30758     *
30759     * _.takeRight([1, 2, 3], 2);
30760     * // => [2, 3]
30761     *
30762     * _.takeRight([1, 2, 3], 5);
30763     * // => [1, 2, 3]
30764     *
30765     * _.takeRight([1, 2, 3], 0);
30766     * // => []
30767     */
30768    function takeRight(array, n, guard) {
30769      var length = array == null ? 0 : array.length;
30770      if (!length) {
30771        return [];
30772      }
30773      n = (guard || n === undefined) ? 1 : toInteger(n);
30774      n = length - n;
30775      return baseSlice(array, n < 0 ? 0 : n, length);
30776    }
30777
30778    /**
30779     * Creates a slice of `array` with elements taken from the end. Elements are
30780     * taken until `predicate` returns falsey. The predicate is invoked with
30781     * three arguments: (value, index, array).
30782     *
30783     * @static
30784     * @memberOf _
30785     * @since 3.0.0
30786     * @category Array
30787     * @param {Array} array The array to query.
30788     * @param {Function} [predicate=_.identity] The function invoked per iteration.
30789     * @returns {Array} Returns the slice of `array`.
30790     * @example
30791     *
30792     * var users = [
30793     *   { 'user': 'barney',  'active': true },
30794     *   { 'user': 'fred',    'active': false },
30795     *   { 'user': 'pebbles', 'active': false }
30796     * ];
30797     *
30798     * _.takeRightWhile(users, function(o) { return !o.active; });
30799     * // => objects for ['fred', 'pebbles']
30800     *
30801     * // The `_.matches` iteratee shorthand.
30802     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
30803     * // => objects for ['pebbles']
30804     *
30805     * // The `_.matchesProperty` iteratee shorthand.
30806     * _.takeRightWhile(users, ['active', false]);
30807     * // => objects for ['fred', 'pebbles']
30808     *
30809     * // The `_.property` iteratee shorthand.
30810     * _.takeRightWhile(users, 'active');
30811     * // => []
30812     */
30813    function takeRightWhile(array, predicate) {
30814      return (array && array.length)
30815        ? baseWhile(array, getIteratee(predicate, 3), false, true)
30816        : [];
30817    }
30818
30819    /**
30820     * Creates a slice of `array` with elements taken from the beginning. Elements
30821     * are taken until `predicate` returns falsey. The predicate is invoked with
30822     * three arguments: (value, index, array).
30823     *
30824     * @static
30825     * @memberOf _
30826     * @since 3.0.0
30827     * @category Array
30828     * @param {Array} array The array to query.
30829     * @param {Function} [predicate=_.identity] The function invoked per iteration.
30830     * @returns {Array} Returns the slice of `array`.
30831     * @example
30832     *
30833     * var users = [
30834     *   { 'user': 'barney',  'active': false },
30835     *   { 'user': 'fred',    'active': false },
30836     *   { 'user': 'pebbles', 'active': true }
30837     * ];
30838     *
30839     * _.takeWhile(users, function(o) { return !o.active; });
30840     * // => objects for ['barney', 'fred']
30841     *
30842     * // The `_.matches` iteratee shorthand.
30843     * _.takeWhile(users, { 'user': 'barney', 'active': false });
30844     * // => objects for ['barney']
30845     *
30846     * // The `_.matchesProperty` iteratee shorthand.
30847     * _.takeWhile(users, ['active', false]);
30848     * // => objects for ['barney', 'fred']
30849     *
30850     * // The `_.property` iteratee shorthand.
30851     * _.takeWhile(users, 'active');
30852     * // => []
30853     */
30854    function takeWhile(array, predicate) {
30855      return (array && array.length)
30856        ? baseWhile(array, getIteratee(predicate, 3))
30857        : [];
30858    }
30859
30860    /**
30861     * Creates an array of unique values, in order, from all given arrays using
30862     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
30863     * for equality comparisons.
30864     *
30865     * @static
30866     * @memberOf _
30867     * @since 0.1.0
30868     * @category Array
30869     * @param {...Array} [arrays] The arrays to inspect.
30870     * @returns {Array} Returns the new array of combined values.
30871     * @example
30872     *
30873     * _.union([2], [1, 2]);
30874     * // => [2, 1]
30875     */
30876    var union = baseRest(function(arrays) {
30877      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
30878    });
30879
30880    /**
30881     * This method is like `_.union` except that it accepts `iteratee` which is
30882     * invoked for each element of each `arrays` to generate the criterion by
30883     * which uniqueness is computed. Result values are chosen from the first
30884     * array in which the value occurs. The iteratee is invoked with one argument:
30885     * (value).
30886     *
30887     * @static
30888     * @memberOf _
30889     * @since 4.0.0
30890     * @category Array
30891     * @param {...Array} [arrays] The arrays to inspect.
30892     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
30893     * @returns {Array} Returns the new array of combined values.
30894     * @example
30895     *
30896     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
30897     * // => [2.1, 1.2]
30898     *
30899     * // The `_.property` iteratee shorthand.
30900     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
30901     * // => [{ 'x': 1 }, { 'x': 2 }]
30902     */
30903    var unionBy = baseRest(function(arrays) {
30904      var iteratee = last(arrays);
30905      if (isArrayLikeObject(iteratee)) {
30906        iteratee = undefined;
30907      }
30908      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
30909    });
30910
30911    /**
30912     * This method is like `_.union` except that it accepts `comparator` which
30913     * is invoked to compare elements of `arrays`. Result values are chosen from
30914     * the first array in which the value occurs. The comparator is invoked
30915     * with two arguments: (arrVal, othVal).
30916     *
30917     * @static
30918     * @memberOf _
30919     * @since 4.0.0
30920     * @category Array
30921     * @param {...Array} [arrays] The arrays to inspect.
30922     * @param {Function} [comparator] The comparator invoked per element.
30923     * @returns {Array} Returns the new array of combined values.
30924     * @example
30925     *
30926     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
30927     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
30928     *
30929     * _.unionWith(objects, others, _.isEqual);
30930     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
30931     */
30932    var unionWith = baseRest(function(arrays) {
30933      var comparator = last(arrays);
30934      comparator = typeof comparator == 'function' ? comparator : undefined;
30935      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
30936    });
30937
30938    /**
30939     * Creates a duplicate-free version of an array, using
30940     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
30941     * for equality comparisons, in which only the first occurrence of each element
30942     * is kept. The order of result values is determined by the order they occur
30943     * in the array.
30944     *
30945     * @static
30946     * @memberOf _
30947     * @since 0.1.0
30948     * @category Array
30949     * @param {Array} array The array to inspect.
30950     * @returns {Array} Returns the new duplicate free array.
30951     * @example
30952     *
30953     * _.uniq([2, 1, 2]);
30954     * // => [2, 1]
30955     */
30956    function uniq(array) {
30957      return (array && array.length) ? baseUniq(array) : [];
30958    }
30959
30960    /**
30961     * This method is like `_.uniq` except that it accepts `iteratee` which is
30962     * invoked for each element in `array` to generate the criterion by which
30963     * uniqueness is computed. The order of result values is determined by the
30964     * order they occur in the array. The iteratee is invoked with one argument:
30965     * (value).
30966     *
30967     * @static
30968     * @memberOf _
30969     * @since 4.0.0
30970     * @category Array
30971     * @param {Array} array The array to inspect.
30972     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
30973     * @returns {Array} Returns the new duplicate free array.
30974     * @example
30975     *
30976     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
30977     * // => [2.1, 1.2]
30978     *
30979     * // The `_.property` iteratee shorthand.
30980     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
30981     * // => [{ 'x': 1 }, { 'x': 2 }]
30982     */
30983    function uniqBy(array, iteratee) {
30984      return (array && array.length) ? baseUniq(array, getIteratee(iteratee, 2)) : [];
30985    }
30986
30987    /**
30988     * This method is like `_.uniq` except that it accepts `comparator` which
30989     * is invoked to compare elements of `array`. The order of result values is
30990     * determined by the order they occur in the array.The comparator is invoked
30991     * with two arguments: (arrVal, othVal).
30992     *
30993     * @static
30994     * @memberOf _
30995     * @since 4.0.0
30996     * @category Array
30997     * @param {Array} array The array to inspect.
30998     * @param {Function} [comparator] The comparator invoked per element.
30999     * @returns {Array} Returns the new duplicate free array.
31000     * @example
31001     *
31002     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
31003     *
31004     * _.uniqWith(objects, _.isEqual);
31005     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
31006     */
31007    function uniqWith(array, comparator) {
31008      comparator = typeof comparator == 'function' ? comparator : undefined;
31009      return (array && array.length) ? baseUniq(array, undefined, comparator) : [];
31010    }
31011
31012    /**
31013     * This method is like `_.zip` except that it accepts an array of grouped
31014     * elements and creates an array regrouping the elements to their pre-zip
31015     * configuration.
31016     *
31017     * @static
31018     * @memberOf _
31019     * @since 1.2.0
31020     * @category Array
31021     * @param {Array} array The array of grouped elements to process.
31022     * @returns {Array} Returns the new array of regrouped elements.
31023     * @example
31024     *
31025     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
31026     * // => [['a', 1, true], ['b', 2, false]]
31027     *
31028     * _.unzip(zipped);
31029     * // => [['a', 'b'], [1, 2], [true, false]]
31030     */
31031    function unzip(array) {
31032      if (!(array && array.length)) {
31033        return [];
31034      }
31035      var length = 0;
31036      array = arrayFilter(array, function(group) {
31037        if (isArrayLikeObject(group)) {
31038          length = nativeMax(group.length, length);
31039          return true;
31040        }
31041      });
31042      return baseTimes(length, function(index) {
31043        return arrayMap(array, baseProperty(index));
31044      });
31045    }
31046
31047    /**
31048     * This method is like `_.unzip` except that it accepts `iteratee` to specify
31049     * how regrouped values should be combined. The iteratee is invoked with the
31050     * elements of each group: (...group).
31051     *
31052     * @static
31053     * @memberOf _
31054     * @since 3.8.0
31055     * @category Array
31056     * @param {Array} array The array of grouped elements to process.
31057     * @param {Function} [iteratee=_.identity] The function to combine
31058     *  regrouped values.
31059     * @returns {Array} Returns the new array of regrouped elements.
31060     * @example
31061     *
31062     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
31063     * // => [[1, 10, 100], [2, 20, 200]]
31064     *
31065     * _.unzipWith(zipped, _.add);
31066     * // => [3, 30, 300]
31067     */
31068    function unzipWith(array, iteratee) {
31069      if (!(array && array.length)) {
31070        return [];
31071      }
31072      var result = unzip(array);
31073      if (iteratee == null) {
31074        return result;
31075      }
31076      return arrayMap(result, function(group) {
31077        return apply(iteratee, undefined, group);
31078      });
31079    }
31080
31081    /**
31082     * Creates an array excluding all given values using
31083     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
31084     * for equality comparisons.
31085     *
31086     * **Note:** Unlike `_.pull`, this method returns a new array.
31087     *
31088     * @static
31089     * @memberOf _
31090     * @since 0.1.0
31091     * @category Array
31092     * @param {Array} array The array to inspect.
31093     * @param {...*} [values] The values to exclude.
31094     * @returns {Array} Returns the new array of filtered values.
31095     * @see _.difference, _.xor
31096     * @example
31097     *
31098     * _.without([2, 1, 2, 3], 1, 2);
31099     * // => [3]
31100     */
31101    var without = baseRest(function(array, values) {
31102      return isArrayLikeObject(array)
31103        ? baseDifference(array, values)
31104        : [];
31105    });
31106
31107    /**
31108     * Creates an array of unique values that is the
31109     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
31110     * of the given arrays. The order of result values is determined by the order
31111     * they occur in the arrays.
31112     *
31113     * @static
31114     * @memberOf _
31115     * @since 2.4.0
31116     * @category Array
31117     * @param {...Array} [arrays] The arrays to inspect.
31118     * @returns {Array} Returns the new array of filtered values.
31119     * @see _.difference, _.without
31120     * @example
31121     *
31122     * _.xor([2, 1], [2, 3]);
31123     * // => [1, 3]
31124     */
31125    var xor = baseRest(function(arrays) {
31126      return baseXor(arrayFilter(arrays, isArrayLikeObject));
31127    });
31128
31129    /**
31130     * This method is like `_.xor` except that it accepts `iteratee` which is
31131     * invoked for each element of each `arrays` to generate the criterion by
31132     * which by which they're compared. The order of result values is determined
31133     * by the order they occur in the arrays. The iteratee is invoked with one
31134     * argument: (value).
31135     *
31136     * @static
31137     * @memberOf _
31138     * @since 4.0.0
31139     * @category Array
31140     * @param {...Array} [arrays] The arrays to inspect.
31141     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
31142     * @returns {Array} Returns the new array of filtered values.
31143     * @example
31144     *
31145     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
31146     * // => [1.2, 3.4]
31147     *
31148     * // The `_.property` iteratee shorthand.
31149     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
31150     * // => [{ 'x': 2 }]
31151     */
31152    var xorBy = baseRest(function(arrays) {
31153      var iteratee = last(arrays);
31154      if (isArrayLikeObject(iteratee)) {
31155        iteratee = undefined;
31156      }
31157      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
31158    });
31159
31160    /**
31161     * This method is like `_.xor` except that it accepts `comparator` which is
31162     * invoked to compare elements of `arrays`. The order of result values is
31163     * determined by the order they occur in the arrays. The comparator is invoked
31164     * with two arguments: (arrVal, othVal).
31165     *
31166     * @static
31167     * @memberOf _
31168     * @since 4.0.0
31169     * @category Array
31170     * @param {...Array} [arrays] The arrays to inspect.
31171     * @param {Function} [comparator] The comparator invoked per element.
31172     * @returns {Array} Returns the new array of filtered values.
31173     * @example
31174     *
31175     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
31176     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
31177     *
31178     * _.xorWith(objects, others, _.isEqual);
31179     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
31180     */
31181    var xorWith = baseRest(function(arrays) {
31182      var comparator = last(arrays);
31183      comparator = typeof comparator == 'function' ? comparator : undefined;
31184      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
31185    });
31186
31187    /**
31188     * Creates an array of grouped elements, the first of which contains the
31189     * first elements of the given arrays, the second of which contains the
31190     * second elements of the given arrays, and so on.
31191     *
31192     * @static
31193     * @memberOf _
31194     * @since 0.1.0
31195     * @category Array
31196     * @param {...Array} [arrays] The arrays to process.
31197     * @returns {Array} Returns the new array of grouped elements.
31198     * @example
31199     *
31200     * _.zip(['a', 'b'], [1, 2], [true, false]);
31201     * // => [['a', 1, true], ['b', 2, false]]
31202     */
31203    var zip = baseRest(unzip);
31204
31205    /**
31206     * This method is like `_.fromPairs` except that it accepts two arrays,
31207     * one of property identifiers and one of corresponding values.
31208     *
31209     * @static
31210     * @memberOf _
31211     * @since 0.4.0
31212     * @category Array
31213     * @param {Array} [props=[]] The property identifiers.
31214     * @param {Array} [values=[]] The property values.
31215     * @returns {Object} Returns the new object.
31216     * @example
31217     *
31218     * _.zipObject(['a', 'b'], [1, 2]);
31219     * // => { 'a': 1, 'b': 2 }
31220     */
31221    function zipObject(props, values) {
31222      return baseZipObject(props || [], values || [], assignValue);
31223    }
31224
31225    /**
31226     * This method is like `_.zipObject` except that it supports property paths.
31227     *
31228     * @static
31229     * @memberOf _
31230     * @since 4.1.0
31231     * @category Array
31232     * @param {Array} [props=[]] The property identifiers.
31233     * @param {Array} [values=[]] The property values.
31234     * @returns {Object} Returns the new object.
31235     * @example
31236     *
31237     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
31238     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
31239     */
31240    function zipObjectDeep(props, values) {
31241      return baseZipObject(props || [], values || [], baseSet);
31242    }
31243
31244    /**
31245     * This method is like `_.zip` except that it accepts `iteratee` to specify
31246     * how grouped values should be combined. The iteratee is invoked with the
31247     * elements of each group: (...group).
31248     *
31249     * @static
31250     * @memberOf _
31251     * @since 3.8.0
31252     * @category Array
31253     * @param {...Array} [arrays] The arrays to process.
31254     * @param {Function} [iteratee=_.identity] The function to combine
31255     *  grouped values.
31256     * @returns {Array} Returns the new array of grouped elements.
31257     * @example
31258     *
31259     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
31260     *   return a + b + c;
31261     * });
31262     * // => [111, 222]
31263     */
31264    var zipWith = baseRest(function(arrays) {
31265      var length = arrays.length,
31266          iteratee = length > 1 ? arrays[length - 1] : undefined;
31267
31268      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
31269      return unzipWith(arrays, iteratee);
31270    });
31271
31272    /*------------------------------------------------------------------------*/
31273
31274    /**
31275     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
31276     * chain sequences enabled. The result of such sequences must be unwrapped
31277     * with `_#value`.
31278     *
31279     * @static
31280     * @memberOf _
31281     * @since 1.3.0
31282     * @category Seq
31283     * @param {*} value The value to wrap.
31284     * @returns {Object} Returns the new `lodash` wrapper instance.
31285     * @example
31286     *
31287     * var users = [
31288     *   { 'user': 'barney',  'age': 36 },
31289     *   { 'user': 'fred',    'age': 40 },
31290     *   { 'user': 'pebbles', 'age': 1 }
31291     * ];
31292     *
31293     * var youngest = _
31294     *   .chain(users)
31295     *   .sortBy('age')
31296     *   .map(function(o) {
31297     *     return o.user + ' is ' + o.age;
31298     *   })
31299     *   .head()
31300     *   .value();
31301     * // => 'pebbles is 1'
31302     */
31303    function chain(value) {
31304      var result = lodash(value);
31305      result.__chain__ = true;
31306      return result;
31307    }
31308
31309    /**
31310     * This method invokes `interceptor` and returns `value`. The interceptor
31311     * is invoked with one argument; (value). The purpose of this method is to
31312     * "tap into" a method chain sequence in order to modify intermediate results.
31313     *
31314     * @static
31315     * @memberOf _
31316     * @since 0.1.0
31317     * @category Seq
31318     * @param {*} value The value to provide to `interceptor`.
31319     * @param {Function} interceptor The function to invoke.
31320     * @returns {*} Returns `value`.
31321     * @example
31322     *
31323     * _([1, 2, 3])
31324     *  .tap(function(array) {
31325     *    // Mutate input array.
31326     *    array.pop();
31327     *  })
31328     *  .reverse()
31329     *  .value();
31330     * // => [2, 1]
31331     */
31332    function tap(value, interceptor) {
31333      interceptor(value);
31334      return value;
31335    }
31336
31337    /**
31338     * This method is like `_.tap` except that it returns the result of `interceptor`.
31339     * The purpose of this method is to "pass thru" values replacing intermediate
31340     * results in a method chain sequence.
31341     *
31342     * @static
31343     * @memberOf _
31344     * @since 3.0.0
31345     * @category Seq
31346     * @param {*} value The value to provide to `interceptor`.
31347     * @param {Function} interceptor The function to invoke.
31348     * @returns {*} Returns the result of `interceptor`.
31349     * @example
31350     *
31351     * _('  abc  ')
31352     *  .chain()
31353     *  .trim()
31354     *  .thru(function(value) {
31355     *    return [value];
31356     *  })
31357     *  .value();
31358     * // => ['abc']
31359     */
31360    function thru(value, interceptor) {
31361      return interceptor(value);
31362    }
31363
31364    /**
31365     * This method is the wrapper version of `_.at`.
31366     *
31367     * @name at
31368     * @memberOf _
31369     * @since 1.0.0
31370     * @category Seq
31371     * @param {...(string|string[])} [paths] The property paths to pick.
31372     * @returns {Object} Returns the new `lodash` wrapper instance.
31373     * @example
31374     *
31375     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
31376     *
31377     * _(object).at(['a[0].b.c', 'a[1]']).value();
31378     * // => [3, 4]
31379     */
31380    var wrapperAt = flatRest(function(paths) {
31381      var length = paths.length,
31382          start = length ? paths[0] : 0,
31383          value = this.__wrapped__,
31384          interceptor = function(object) { return baseAt(object, paths); };
31385
31386      if (length > 1 || this.__actions__.length ||
31387          !(value instanceof LazyWrapper) || !isIndex(start)) {
31388        return this.thru(interceptor);
31389      }
31390      value = value.slice(start, +start + (length ? 1 : 0));
31391      value.__actions__.push({
31392        'func': thru,
31393        'args': [interceptor],
31394        'thisArg': undefined
31395      });
31396      return new LodashWrapper(value, this.__chain__).thru(function(array) {
31397        if (length && !array.length) {
31398          array.push(undefined);
31399        }
31400        return array;
31401      });
31402    });
31403
31404    /**
31405     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
31406     *
31407     * @name chain
31408     * @memberOf _
31409     * @since 0.1.0
31410     * @category Seq
31411     * @returns {Object} Returns the new `lodash` wrapper instance.
31412     * @example
31413     *
31414     * var users = [
31415     *   { 'user': 'barney', 'age': 36 },
31416     *   { 'user': 'fred',   'age': 40 }
31417     * ];
31418     *
31419     * // A sequence without explicit chaining.
31420     * _(users).head();
31421     * // => { 'user': 'barney', 'age': 36 }
31422     *
31423     * // A sequence with explicit chaining.
31424     * _(users)
31425     *   .chain()
31426     *   .head()
31427     *   .pick('user')
31428     *   .value();
31429     * // => { 'user': 'barney' }
31430     */
31431    function wrapperChain() {
31432      return chain(this);
31433    }
31434
31435    /**
31436     * Executes the chain sequence and returns the wrapped result.
31437     *
31438     * @name commit
31439     * @memberOf _
31440     * @since 3.2.0
31441     * @category Seq
31442     * @returns {Object} Returns the new `lodash` wrapper instance.
31443     * @example
31444     *
31445     * var array = [1, 2];
31446     * var wrapped = _(array).push(3);
31447     *
31448     * console.log(array);
31449     * // => [1, 2]
31450     *
31451     * wrapped = wrapped.commit();
31452     * console.log(array);
31453     * // => [1, 2, 3]
31454     *
31455     * wrapped.last();
31456     * // => 3
31457     *
31458     * console.log(array);
31459     * // => [1, 2, 3]
31460     */
31461    function wrapperCommit() {
31462      return new LodashWrapper(this.value(), this.__chain__);
31463    }
31464
31465    /**
31466     * Gets the next value on a wrapped object following the
31467     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
31468     *
31469     * @name next
31470     * @memberOf _
31471     * @since 4.0.0
31472     * @category Seq
31473     * @returns {Object} Returns the next iterator value.
31474     * @example
31475     *
31476     * var wrapped = _([1, 2]);
31477     *
31478     * wrapped.next();
31479     * // => { 'done': false, 'value': 1 }
31480     *
31481     * wrapped.next();
31482     * // => { 'done': false, 'value': 2 }
31483     *
31484     * wrapped.next();
31485     * // => { 'done': true, 'value': undefined }
31486     */
31487    function wrapperNext() {
31488      if (this.__values__ === undefined) {
31489        this.__values__ = toArray(this.value());
31490      }
31491      var done = this.__index__ >= this.__values__.length,
31492          value = done ? undefined : this.__values__[this.__index__++];
31493
31494      return { 'done': done, 'value': value };
31495    }
31496
31497    /**
31498     * Enables the wrapper to be iterable.
31499     *
31500     * @name Symbol.iterator
31501     * @memberOf _
31502     * @since 4.0.0
31503     * @category Seq
31504     * @returns {Object} Returns the wrapper object.
31505     * @example
31506     *
31507     * var wrapped = _([1, 2]);
31508     *
31509     * wrapped[Symbol.iterator]() === wrapped;
31510     * // => true
31511     *
31512     * Array.from(wrapped);
31513     * // => [1, 2]
31514     */
31515    function wrapperToIterator() {
31516      return this;
31517    }
31518
31519    /**
31520     * Creates a clone of the chain sequence planting `value` as the wrapped value.
31521     *
31522     * @name plant
31523     * @memberOf _
31524     * @since 3.2.0
31525     * @category Seq
31526     * @param {*} value The value to plant.
31527     * @returns {Object} Returns the new `lodash` wrapper instance.
31528     * @example
31529     *
31530     * function square(n) {
31531     *   return n * n;
31532     * }
31533     *
31534     * var wrapped = _([1, 2]).map(square);
31535     * var other = wrapped.plant([3, 4]);
31536     *
31537     * other.value();
31538     * // => [9, 16]
31539     *
31540     * wrapped.value();
31541     * // => [1, 4]
31542     */
31543    function wrapperPlant(value) {
31544      var result,
31545          parent = this;
31546
31547      while (parent instanceof baseLodash) {
31548        var clone = wrapperClone(parent);
31549        clone.__index__ = 0;
31550        clone.__values__ = undefined;
31551        if (result) {
31552          previous.__wrapped__ = clone;
31553        } else {
31554          result = clone;
31555        }
31556        var previous = clone;
31557        parent = parent.__wrapped__;
31558      }
31559      previous.__wrapped__ = value;
31560      return result;
31561    }
31562
31563    /**
31564     * This method is the wrapper version of `_.reverse`.
31565     *
31566     * **Note:** This method mutates the wrapped array.
31567     *
31568     * @name reverse
31569     * @memberOf _
31570     * @since 0.1.0
31571     * @category Seq
31572     * @returns {Object} Returns the new `lodash` wrapper instance.
31573     * @example
31574     *
31575     * var array = [1, 2, 3];
31576     *
31577     * _(array).reverse().value()
31578     * // => [3, 2, 1]
31579     *
31580     * console.log(array);
31581     * // => [3, 2, 1]
31582     */
31583    function wrapperReverse() {
31584      var value = this.__wrapped__;
31585      if (value instanceof LazyWrapper) {
31586        var wrapped = value;
31587        if (this.__actions__.length) {
31588          wrapped = new LazyWrapper(this);
31589        }
31590        wrapped = wrapped.reverse();
31591        wrapped.__actions__.push({
31592          'func': thru,
31593          'args': [reverse],
31594          'thisArg': undefined
31595        });
31596        return new LodashWrapper(wrapped, this.__chain__);
31597      }
31598      return this.thru(reverse);
31599    }
31600
31601    /**
31602     * Executes the chain sequence to resolve the unwrapped value.
31603     *
31604     * @name value
31605     * @memberOf _
31606     * @since 0.1.0
31607     * @alias toJSON, valueOf
31608     * @category Seq
31609     * @returns {*} Returns the resolved unwrapped value.
31610     * @example
31611     *
31612     * _([1, 2, 3]).value();
31613     * // => [1, 2, 3]
31614     */
31615    function wrapperValue() {
31616      return baseWrapperValue(this.__wrapped__, this.__actions__);
31617    }
31618
31619    /*------------------------------------------------------------------------*/
31620
31621    /**
31622     * Creates an object composed of keys generated from the results of running
31623     * each element of `collection` thru `iteratee`. The corresponding value of
31624     * each key is the number of times the key was returned by `iteratee`. The
31625     * iteratee is invoked with one argument: (value).
31626     *
31627     * @static
31628     * @memberOf _
31629     * @since 0.5.0
31630     * @category Collection
31631     * @param {Array|Object} collection The collection to iterate over.
31632     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
31633     * @returns {Object} Returns the composed aggregate object.
31634     * @example
31635     *
31636     * _.countBy([6.1, 4.2, 6.3], Math.floor);
31637     * // => { '4': 1, '6': 2 }
31638     *
31639     * // The `_.property` iteratee shorthand.
31640     * _.countBy(['one', 'two', 'three'], 'length');
31641     * // => { '3': 2, '5': 1 }
31642     */
31643    var countBy = createAggregator(function(result, value, key) {
31644      if (hasOwnProperty.call(result, key)) {
31645        ++result[key];
31646      } else {
31647        baseAssignValue(result, key, 1);
31648      }
31649    });
31650
31651    /**
31652     * Checks if `predicate` returns truthy for **all** elements of `collection`.
31653     * Iteration is stopped once `predicate` returns falsey. The predicate is
31654     * invoked with three arguments: (value, index|key, collection).
31655     *
31656     * **Note:** This method returns `true` for
31657     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
31658     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
31659     * elements of empty collections.
31660     *
31661     * @static
31662     * @memberOf _
31663     * @since 0.1.0
31664     * @category Collection
31665     * @param {Array|Object} collection The collection to iterate over.
31666     * @param {Function} [predicate=_.identity] The function invoked per iteration.
31667     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
31668     * @returns {boolean} Returns `true` if all elements pass the predicate check,
31669     *  else `false`.
31670     * @example
31671     *
31672     * _.every([true, 1, null, 'yes'], Boolean);
31673     * // => false
31674     *
31675     * var users = [
31676     *   { 'user': 'barney', 'age': 36, 'active': false },
31677     *   { 'user': 'fred',   'age': 40, 'active': false }
31678     * ];
31679     *
31680     * // The `_.matches` iteratee shorthand.
31681     * _.every(users, { 'user': 'barney', 'active': false });
31682     * // => false
31683     *
31684     * // The `_.matchesProperty` iteratee shorthand.
31685     * _.every(users, ['active', false]);
31686     * // => true
31687     *
31688     * // The `_.property` iteratee shorthand.
31689     * _.every(users, 'active');
31690     * // => false
31691     */
31692    function every(collection, predicate, guard) {
31693      var func = isArray(collection) ? arrayEvery : baseEvery;
31694      if (guard && isIterateeCall(collection, predicate, guard)) {
31695        predicate = undefined;
31696      }
31697      return func(collection, getIteratee(predicate, 3));
31698    }
31699
31700    /**
31701     * Iterates over elements of `collection`, returning an array of all elements
31702     * `predicate` returns truthy for. The predicate is invoked with three
31703     * arguments: (value, index|key, collection).
31704     *
31705     * **Note:** Unlike `_.remove`, this method returns a new array.
31706     *
31707     * @static
31708     * @memberOf _
31709     * @since 0.1.0
31710     * @category Collection
31711     * @param {Array|Object} collection The collection to iterate over.
31712     * @param {Function} [predicate=_.identity] The function invoked per iteration.
31713     * @returns {Array} Returns the new filtered array.
31714     * @see _.reject
31715     * @example
31716     *
31717     * var users = [
31718     *   { 'user': 'barney', 'age': 36, 'active': true },
31719     *   { 'user': 'fred',   'age': 40, 'active': false }
31720     * ];
31721     *
31722     * _.filter(users, function(o) { return !o.active; });
31723     * // => objects for ['fred']
31724     *
31725     * // The `_.matches` iteratee shorthand.
31726     * _.filter(users, { 'age': 36, 'active': true });
31727     * // => objects for ['barney']
31728     *
31729     * // The `_.matchesProperty` iteratee shorthand.
31730     * _.filter(users, ['active', false]);
31731     * // => objects for ['fred']
31732     *
31733     * // The `_.property` iteratee shorthand.
31734     * _.filter(users, 'active');
31735     * // => objects for ['barney']
31736     *
31737     * // Combining several predicates using `_.overEvery` or `_.overSome`.
31738     * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
31739     * // => objects for ['fred', 'barney']
31740     */
31741    function filter(collection, predicate) {
31742      var func = isArray(collection) ? arrayFilter : baseFilter;
31743      return func(collection, getIteratee(predicate, 3));
31744    }
31745
31746    /**
31747     * Iterates over elements of `collection`, returning the first element
31748     * `predicate` returns truthy for. The predicate is invoked with three
31749     * arguments: (value, index|key, collection).
31750     *
31751     * @static
31752     * @memberOf _
31753     * @since 0.1.0
31754     * @category Collection
31755     * @param {Array|Object} collection The collection to inspect.
31756     * @param {Function} [predicate=_.identity] The function invoked per iteration.
31757     * @param {number} [fromIndex=0] The index to search from.
31758     * @returns {*} Returns the matched element, else `undefined`.
31759     * @example
31760     *
31761     * var users = [
31762     *   { 'user': 'barney',  'age': 36, 'active': true },
31763     *   { 'user': 'fred',    'age': 40, 'active': false },
31764     *   { 'user': 'pebbles', 'age': 1,  'active': true }
31765     * ];
31766     *
31767     * _.find(users, function(o) { return o.age < 40; });
31768     * // => object for 'barney'
31769     *
31770     * // The `_.matches` iteratee shorthand.
31771     * _.find(users, { 'age': 1, 'active': true });
31772     * // => object for 'pebbles'
31773     *
31774     * // The `_.matchesProperty` iteratee shorthand.
31775     * _.find(users, ['active', false]);
31776     * // => object for 'fred'
31777     *
31778     * // The `_.property` iteratee shorthand.
31779     * _.find(users, 'active');
31780     * // => object for 'barney'
31781     */
31782    var find = createFind(findIndex);
31783
31784    /**
31785     * This method is like `_.find` except that it iterates over elements of
31786     * `collection` from right to left.
31787     *
31788     * @static
31789     * @memberOf _
31790     * @since 2.0.0
31791     * @category Collection
31792     * @param {Array|Object} collection The collection to inspect.
31793     * @param {Function} [predicate=_.identity] The function invoked per iteration.
31794     * @param {number} [fromIndex=collection.length-1] The index to search from.
31795     * @returns {*} Returns the matched element, else `undefined`.
31796     * @example
31797     *
31798     * _.findLast([1, 2, 3, 4], function(n) {
31799     *   return n % 2 == 1;
31800     * });
31801     * // => 3
31802     */
31803    var findLast = createFind(findLastIndex);
31804
31805    /**
31806     * Creates a flattened array of values by running each element in `collection`
31807     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
31808     * with three arguments: (value, index|key, collection).
31809     *
31810     * @static
31811     * @memberOf _
31812     * @since 4.0.0
31813     * @category Collection
31814     * @param {Array|Object} collection The collection to iterate over.
31815     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31816     * @returns {Array} Returns the new flattened array.
31817     * @example
31818     *
31819     * function duplicate(n) {
31820     *   return [n, n];
31821     * }
31822     *
31823     * _.flatMap([1, 2], duplicate);
31824     * // => [1, 1, 2, 2]
31825     */
31826    function flatMap(collection, iteratee) {
31827      return baseFlatten(map(collection, iteratee), 1);
31828    }
31829
31830    /**
31831     * This method is like `_.flatMap` except that it recursively flattens the
31832     * mapped results.
31833     *
31834     * @static
31835     * @memberOf _
31836     * @since 4.7.0
31837     * @category Collection
31838     * @param {Array|Object} collection The collection to iterate over.
31839     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31840     * @returns {Array} Returns the new flattened array.
31841     * @example
31842     *
31843     * function duplicate(n) {
31844     *   return [[[n, n]]];
31845     * }
31846     *
31847     * _.flatMapDeep([1, 2], duplicate);
31848     * // => [1, 1, 2, 2]
31849     */
31850    function flatMapDeep(collection, iteratee) {
31851      return baseFlatten(map(collection, iteratee), INFINITY);
31852    }
31853
31854    /**
31855     * This method is like `_.flatMap` except that it recursively flattens the
31856     * mapped results up to `depth` times.
31857     *
31858     * @static
31859     * @memberOf _
31860     * @since 4.7.0
31861     * @category Collection
31862     * @param {Array|Object} collection The collection to iterate over.
31863     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31864     * @param {number} [depth=1] The maximum recursion depth.
31865     * @returns {Array} Returns the new flattened array.
31866     * @example
31867     *
31868     * function duplicate(n) {
31869     *   return [[[n, n]]];
31870     * }
31871     *
31872     * _.flatMapDepth([1, 2], duplicate, 2);
31873     * // => [[1, 1], [2, 2]]
31874     */
31875    function flatMapDepth(collection, iteratee, depth) {
31876      depth = depth === undefined ? 1 : toInteger(depth);
31877      return baseFlatten(map(collection, iteratee), depth);
31878    }
31879
31880    /**
31881     * Iterates over elements of `collection` and invokes `iteratee` for each element.
31882     * The iteratee is invoked with three arguments: (value, index|key, collection).
31883     * Iteratee functions may exit iteration early by explicitly returning `false`.
31884     *
31885     * **Note:** As with other "Collections" methods, objects with a "length"
31886     * property are iterated like arrays. To avoid this behavior use `_.forIn`
31887     * or `_.forOwn` for object iteration.
31888     *
31889     * @static
31890     * @memberOf _
31891     * @since 0.1.0
31892     * @alias each
31893     * @category Collection
31894     * @param {Array|Object} collection The collection to iterate over.
31895     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31896     * @returns {Array|Object} Returns `collection`.
31897     * @see _.forEachRight
31898     * @example
31899     *
31900     * _.forEach([1, 2], function(value) {
31901     *   console.log(value);
31902     * });
31903     * // => Logs `1` then `2`.
31904     *
31905     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
31906     *   console.log(key);
31907     * });
31908     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
31909     */
31910    function forEach(collection, iteratee) {
31911      var func = isArray(collection) ? arrayEach : baseEach;
31912      return func(collection, getIteratee(iteratee, 3));
31913    }
31914
31915    /**
31916     * This method is like `_.forEach` except that it iterates over elements of
31917     * `collection` from right to left.
31918     *
31919     * @static
31920     * @memberOf _
31921     * @since 2.0.0
31922     * @alias eachRight
31923     * @category Collection
31924     * @param {Array|Object} collection The collection to iterate over.
31925     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31926     * @returns {Array|Object} Returns `collection`.
31927     * @see _.forEach
31928     * @example
31929     *
31930     * _.forEachRight([1, 2], function(value) {
31931     *   console.log(value);
31932     * });
31933     * // => Logs `2` then `1`.
31934     */
31935    function forEachRight(collection, iteratee) {
31936      var func = isArray(collection) ? arrayEachRight : baseEachRight;
31937      return func(collection, getIteratee(iteratee, 3));
31938    }
31939
31940    /**
vendor: 4,136 bytes, lines 31941-32048
31941     * Creates an object composed of keys generated from the results of running
31942     * each element of `collection` thru `iteratee`. The order of grouped values
31943     * is determined by the order they occur in `collection`. The corresponding
31944     * value of each key is an array of elements responsible for generating the
31945     * key. The iteratee is invoked with one argument: (value).
31946     *
31947     * @static
31948     * @memberOf _
31949     * @since 0.1.0
31950     * @category Collection
31951     * @param {Array|Object} collection The collection to iterate over.
31952     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
31953     * @returns {Object} Returns the composed aggregate object.
31954     * @example
31955     *
31956     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
31957     * // => { '4': [4.2], '6': [6.1, 6.3] }
31958     *
31959     * // The `_.property` iteratee shorthand.
31960     * _.groupBy(['one', 'two', 'three'], 'length');
31961     * // => { '3': ['one', 'two'], '5': ['three'] }
31962     */
31963    var groupBy = createAggregator(function(result, value, key) {
31964      if (hasOwnProperty.call(result, key)) {
31965        result[key].push(value);
31966      } else {
31967        baseAssignValue(result, key, [value]);
31968      }
31969    });
31970
31971    /**
31972     * Checks if `value` is in `collection`. If `collection` is a string, it's
31973     * checked for a substring of `value`, otherwise
31974     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
31975     * is used for equality comparisons. If `fromIndex` is negative, it's used as
31976     * the offset from the end of `collection`.
31977     *
31978     * @static
31979     * @memberOf _
31980     * @since 0.1.0
31981     * @category Collection
31982     * @param {Array|Object|string} collection The collection to inspect.
31983     * @param {*} value The value to search for.
31984     * @param {number} [fromIndex=0] The index to search from.
31985     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
31986     * @returns {boolean} Returns `true` if `value` is found, else `false`.
31987     * @example
31988     *
31989     * _.includes([1, 2, 3], 1);
31990     * // => true
31991     *
31992     * _.includes([1, 2, 3], 1, 2);
31993     * // => false
31994     *
31995     * _.includes({ 'a': 1, 'b': 2 }, 1);
31996     * // => true
31997     *
31998     * _.includes('abcd', 'bc');
31999     * // => true
32000     */
32001    function includes(collection, value, fromIndex, guard) {
32002      collection = isArrayLike(collection) ? collection : values(collection);
32003      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
32004
32005      var length = collection.length;
32006      if (fromIndex < 0) {
32007        fromIndex = nativeMax(length + fromIndex, 0);
32008      }
32009      return isString(collection)
32010        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
32011        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
32012    }
32013
32014    /**
32015     * Invokes the method at `path` of each element in `collection`, returning
32016     * an array of the results of each invoked method. Any additional arguments
32017     * are provided to each invoked method. If `path` is a function, it's invoked
32018     * for, and `this` bound to, each element in `collection`.
32019     *
32020     * @static
32021     * @memberOf _
32022     * @since 4.0.0
32023     * @category Collection
32024     * @param {Array|Object} collection The collection to iterate over.
32025     * @param {Array|Function|string} path The path of the method to invoke or
32026     *  the function invoked per iteration.
32027     * @param {...*} [args] The arguments to invoke each method with.
32028     * @returns {Array} Returns the array of results.
32029     * @example
32030     *
32031     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
32032     * // => [[1, 5, 7], [1, 2, 3]]
32033     *
32034     * _.invokeMap([123, 456], String.prototype.split, '');
32035     * // => [['1', '2', '3'], ['4', '5', '6']]
32036     */
32037    var invokeMap = baseRest(function(collection, path, args) {
32038      var index = -1,
32039          isFunc = typeof path == 'function',
32040          result = isArrayLike(collection) ? Array(collection.length) : [];
32041
32042      baseEach(collection, function(value) {
32043        result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
32044      });
32045      return result;
32046    });
32047
32048    /**
vendor: 68,500 bytes, lines 32049-34163
32049     * Creates an object composed of keys generated from the results of running
32050     * each element of `collection` thru `iteratee`. The corresponding value of
32051     * each key is the last element responsible for generating the key. The
32052     * iteratee is invoked with one argument: (value).
32053     *
32054     * @static
32055     * @memberOf _
32056     * @since 4.0.0
32057     * @category Collection
32058     * @param {Array|Object} collection The collection to iterate over.
32059     * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
32060     * @returns {Object} Returns the composed aggregate object.
32061     * @example
32062     *
32063     * var array = [
32064     *   { 'dir': 'left', 'code': 97 },
32065     *   { 'dir': 'right', 'code': 100 }
32066     * ];
32067     *
32068     * _.keyBy(array, function(o) {
32069     *   return String.fromCharCode(o.code);
32070     * });
32071     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
32072     *
32073     * _.keyBy(array, 'dir');
32074     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
32075     */
32076    var keyBy = createAggregator(function(result, value, key) {
32077      baseAssignValue(result, key, value);
32078    });
32079
32080    /**
32081     * Creates an array of values by running each element in `collection` thru
32082     * `iteratee`. The iteratee is invoked with three arguments:
32083     * (value, index|key, collection).
32084     *
32085     * Many lodash methods are guarded to work as iteratees for methods like
32086     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
32087     *
32088     * The guarded methods are:
32089     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
32090     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
32091     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
32092     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
32093     *
32094     * @static
32095     * @memberOf _
32096     * @since 0.1.0
32097     * @category Collection
32098     * @param {Array|Object} collection The collection to iterate over.
32099     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
32100     * @returns {Array} Returns the new mapped array.
32101     * @example
32102     *
32103     * function square(n) {
32104     *   return n * n;
32105     * }
32106     *
32107     * _.map([4, 8], square);
32108     * // => [16, 64]
32109     *
32110     * _.map({ 'a': 4, 'b': 8 }, square);
32111     * // => [16, 64] (iteration order is not guaranteed)
32112     *
32113     * var users = [
32114     *   { 'user': 'barney' },
32115     *   { 'user': 'fred' }
32116     * ];
32117     *
32118     * // The `_.property` iteratee shorthand.
32119     * _.map(users, 'user');
32120     * // => ['barney', 'fred']
32121     */
32122    function map(collection, iteratee) {
32123      var func = isArray(collection) ? arrayMap : baseMap;
32124      return func(collection, getIteratee(iteratee, 3));
32125    }
32126
32127    /**
32128     * This method is like `_.sortBy` except that it allows specifying the sort
32129     * orders of the iteratees to sort by. If `orders` is unspecified, all values
32130     * are sorted in ascending order. Otherwise, specify an order of "desc" for
32131     * descending or "asc" for ascending sort order of corresponding values.
32132     *
32133     * @static
32134     * @memberOf _
32135     * @since 4.0.0
32136     * @category Collection
32137     * @param {Array|Object} collection The collection to iterate over.
32138     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
32139     *  The iteratees to sort by.
32140     * @param {string[]} [orders] The sort orders of `iteratees`.
32141     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
32142     * @returns {Array} Returns the new sorted array.
32143     * @example
32144     *
32145     * var users = [
32146     *   { 'user': 'fred',   'age': 48 },
32147     *   { 'user': 'barney', 'age': 34 },
32148     *   { 'user': 'fred',   'age': 40 },
32149     *   { 'user': 'barney', 'age': 36 }
32150     * ];
32151     *
32152     * // Sort by `user` in ascending order and by `age` in descending order.
32153     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
32154     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
32155     */
32156    function orderBy(collection, iteratees, orders, guard) {
32157      if (collection == null) {
32158        return [];
32159      }
32160      if (!isArray(iteratees)) {
32161        iteratees = iteratees == null ? [] : [iteratees];
32162      }
32163      orders = guard ? undefined : orders;
32164      if (!isArray(orders)) {
32165        orders = orders == null ? [] : [orders];
32166      }
32167      return baseOrderBy(collection, iteratees, orders);
32168    }
32169
32170    /**
32171     * Creates an array of elements split into two groups, the first of which
32172     * contains elements `predicate` returns truthy for, the second of which
32173     * contains elements `predicate` returns falsey for. The predicate is
32174     * invoked with one argument: (value).
32175     *
32176     * @static
32177     * @memberOf _
32178     * @since 3.0.0
32179     * @category Collection
32180     * @param {Array|Object} collection The collection to iterate over.
32181     * @param {Function} [predicate=_.identity] The function invoked per iteration.
32182     * @returns {Array} Returns the array of grouped elements.
32183     * @example
32184     *
32185     * var users = [
32186     *   { 'user': 'barney',  'age': 36, 'active': false },
32187     *   { 'user': 'fred',    'age': 40, 'active': true },
32188     *   { 'user': 'pebbles', 'age': 1,  'active': false }
32189     * ];
32190     *
32191     * _.partition(users, function(o) { return o.active; });
32192     * // => objects for [['fred'], ['barney', 'pebbles']]
32193     *
32194     * // The `_.matches` iteratee shorthand.
32195     * _.partition(users, { 'age': 1, 'active': false });
32196     * // => objects for [['pebbles'], ['barney', 'fred']]
32197     *
32198     * // The `_.matchesProperty` iteratee shorthand.
32199     * _.partition(users, ['active', false]);
32200     * // => objects for [['barney', 'pebbles'], ['fred']]
32201     *
32202     * // The `_.property` iteratee shorthand.
32203     * _.partition(users, 'active');
32204     * // => objects for [['fred'], ['barney', 'pebbles']]
32205     */
32206    var partition = createAggregator(function(result, value, key) {
32207      result[key ? 0 : 1].push(value);
32208    }, function() { return [[], []]; });
32209
32210    /**
32211     * Reduces `collection` to a value which is the accumulated result of running
32212     * each element in `collection` thru `iteratee`, where each successive
32213     * invocation is supplied the return value of the previous. If `accumulator`
32214     * is not given, the first element of `collection` is used as the initial
32215     * value. The iteratee is invoked with four arguments:
32216     * (accumulator, value, index|key, collection).
32217     *
32218     * Many lodash methods are guarded to work as iteratees for methods like
32219     * `_.reduce`, `_.reduceRight`, and `_.transform`.
32220     *
32221     * The guarded methods are:
32222     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
32223     * and `sortBy`
32224     *
32225     * @static
32226     * @memberOf _
32227     * @since 0.1.0
32228     * @category Collection
32229     * @param {Array|Object} collection The collection to iterate over.
32230     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
32231     * @param {*} [accumulator] The initial value.
32232     * @returns {*} Returns the accumulated value.
32233     * @see _.reduceRight
32234     * @example
32235     *
32236     * _.reduce([1, 2], function(sum, n) {
32237     *   return sum + n;
32238     * }, 0);
32239     * // => 3
32240     *
32241     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
32242     *   (result[value] || (result[value] = [])).push(key);
32243     *   return result;
32244     * }, {});
32245     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
32246     */
32247    function reduce(collection, iteratee, accumulator) {
32248      var func = isArray(collection) ? arrayReduce : baseReduce,
32249          initAccum = arguments.length < 3;
32250
32251      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
32252    }
32253
32254    /**
32255     * This method is like `_.reduce` except that it iterates over elements of
32256     * `collection` from right to left.
32257     *
32258     * @static
32259     * @memberOf _
32260     * @since 0.1.0
32261     * @category Collection
32262     * @param {Array|Object} collection The collection to iterate over.
32263     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
32264     * @param {*} [accumulator] The initial value.
32265     * @returns {*} Returns the accumulated value.
32266     * @see _.reduce
32267     * @example
32268     *
32269     * var array = [[0, 1], [2, 3], [4, 5]];
32270     *
32271     * _.reduceRight(array, function(flattened, other) {
32272     *   return flattened.concat(other);
32273     * }, []);
32274     * // => [4, 5, 2, 3, 0, 1]
32275     */
32276    function reduceRight(collection, iteratee, accumulator) {
32277      var func = isArray(collection) ? arrayReduceRight : baseReduce,
32278          initAccum = arguments.length < 3;
32279
32280      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
32281    }
32282
32283    /**
32284     * The opposite of `_.filter`; this method returns the elements of `collection`
32285     * that `predicate` does **not** return truthy for.
32286     *
32287     * @static
32288     * @memberOf _
32289     * @since 0.1.0
32290     * @category Collection
32291     * @param {Array|Object} collection The collection to iterate over.
32292     * @param {Function} [predicate=_.identity] The function invoked per iteration.
32293     * @returns {Array} Returns the new filtered array.
32294     * @see _.filter
32295     * @example
32296     *
32297     * var users = [
32298     *   { 'user': 'barney', 'age': 36, 'active': false },
32299     *   { 'user': 'fred',   'age': 40, 'active': true }
32300     * ];
32301     *
32302     * _.reject(users, function(o) { return !o.active; });
32303     * // => objects for ['fred']
32304     *
32305     * // The `_.matches` iteratee shorthand.
32306     * _.reject(users, { 'age': 40, 'active': true });
32307     * // => objects for ['barney']
32308     *
32309     * // The `_.matchesProperty` iteratee shorthand.
32310     * _.reject(users, ['active', false]);
32311     * // => objects for ['fred']
32312     *
32313     * // The `_.property` iteratee shorthand.
32314     * _.reject(users, 'active');
32315     * // => objects for ['barney']
32316     */
32317    function reject(collection, predicate) {
32318      var func = isArray(collection) ? arrayFilter : baseFilter;
32319      return func(collection, negate(getIteratee(predicate, 3)));
32320    }
32321
32322    /**
32323     * Gets a random element from `collection`.
32324     *
32325     * @static
32326     * @memberOf _
32327     * @since 2.0.0
32328     * @category Collection
32329     * @param {Array|Object} collection The collection to sample.
32330     * @returns {*} Returns the random element.
32331     * @example
32332     *
32333     * _.sample([1, 2, 3, 4]);
32334     * // => 2
32335     */
32336    function sample(collection) {
32337      var func = isArray(collection) ? arraySample : baseSample;
32338      return func(collection);
32339    }
32340
32341    /**
32342     * Gets `n` random elements at unique keys from `collection` up to the
32343     * size of `collection`.
32344     *
32345     * @static
32346     * @memberOf _
32347     * @since 4.0.0
32348     * @category Collection
32349     * @param {Array|Object} collection The collection to sample.
32350     * @param {number} [n=1] The number of elements to sample.
32351     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
32352     * @returns {Array} Returns the random elements.
32353     * @example
32354     *
32355     * _.sampleSize([1, 2, 3], 2);
32356     * // => [3, 1]
32357     *
32358     * _.sampleSize([1, 2, 3], 4);
32359     * // => [2, 3, 1]
32360     */
32361    function sampleSize(collection, n, guard) {
32362      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
32363        n = 1;
32364      } else {
32365        n = toInteger(n);
32366      }
32367      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
32368      return func(collection, n);
32369    }
32370
32371    /**
32372     * Creates an array of shuffled values, using a version of the
32373     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
32374     *
32375     * @static
32376     * @memberOf _
32377     * @since 0.1.0
32378     * @category Collection
32379     * @param {Array|Object} collection The collection to shuffle.
32380     * @returns {Array} Returns the new shuffled array.
32381     * @example
32382     *
32383     * _.shuffle([1, 2, 3, 4]);
32384     * // => [4, 1, 3, 2]
32385     */
32386    function shuffle(collection) {
32387      var func = isArray(collection) ? arrayShuffle : baseShuffle;
32388      return func(collection);
32389    }
32390
32391    /**
32392     * Gets the size of `collection` by returning its length for array-like
32393     * values or the number of own enumerable string keyed properties for objects.
32394     *
32395     * @static
32396     * @memberOf _
32397     * @since 0.1.0
32398     * @category Collection
32399     * @param {Array|Object|string} collection The collection to inspect.
32400     * @returns {number} Returns the collection size.
32401     * @example
32402     *
32403     * _.size([1, 2, 3]);
32404     * // => 3
32405     *
32406     * _.size({ 'a': 1, 'b': 2 });
32407     * // => 2
32408     *
32409     * _.size('pebbles');
32410     * // => 7
32411     */
32412    function size(collection) {
32413      if (collection == null) {
32414        return 0;
32415      }
32416      if (isArrayLike(collection)) {
32417        return isString(collection) ? stringSize(collection) : collection.length;
32418      }
32419      var tag = getTag(collection);
32420      if (tag == mapTag || tag == setTag) {
32421        return collection.size;
32422      }
32423      return baseKeys(collection).length;
32424    }
32425
32426    /**
32427     * Checks if `predicate` returns truthy for **any** element of `collection`.
32428     * Iteration is stopped once `predicate` returns truthy. The predicate is
32429     * invoked with three arguments: (value, index|key, collection).
32430     *
32431     * @static
32432     * @memberOf _
32433     * @since 0.1.0
32434     * @category Collection
32435     * @param {Array|Object} collection The collection to iterate over.
32436     * @param {Function} [predicate=_.identity] The function invoked per iteration.
32437     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
32438     * @returns {boolean} Returns `true` if any element passes the predicate check,
32439     *  else `false`.
32440     * @example
32441     *
32442     * _.some([null, 0, 'yes', false], Boolean);
32443     * // => true
32444     *
32445     * var users = [
32446     *   { 'user': 'barney', 'active': true },
32447     *   { 'user': 'fred',   'active': false }
32448     * ];
32449     *
32450     * // The `_.matches` iteratee shorthand.
32451     * _.some(users, { 'user': 'barney', 'active': false });
32452     * // => false
32453     *
32454     * // The `_.matchesProperty` iteratee shorthand.
32455     * _.some(users, ['active', false]);
32456     * // => true
32457     *
32458     * // The `_.property` iteratee shorthand.
32459     * _.some(users, 'active');
32460     * // => true
32461     */
32462    function some(collection, predicate, guard) {
32463      var func = isArray(collection) ? arraySome : baseSome;
32464      if (guard && isIterateeCall(collection, predicate, guard)) {
32465        predicate = undefined;
32466      }
32467      return func(collection, getIteratee(predicate, 3));
32468    }
32469
32470    /**
32471     * Creates an array of elements, sorted in ascending order by the results of
32472     * running each element in a collection thru each iteratee. This method
32473     * performs a stable sort, that is, it preserves the original sort order of
32474     * equal elements. The iteratees are invoked with one argument: (value).
32475     *
32476     * @static
32477     * @memberOf _
32478     * @since 0.1.0
32479     * @category Collection
32480     * @param {Array|Object} collection The collection to iterate over.
32481     * @param {...(Function|Function[])} [iteratees=[_.identity]]
32482     *  The iteratees to sort by.
32483     * @returns {Array} Returns the new sorted array.
32484     * @example
32485     *
32486     * var users = [
32487     *   { 'user': 'fred',   'age': 48 },
32488     *   { 'user': 'barney', 'age': 36 },
32489     *   { 'user': 'fred',   'age': 30 },
32490     *   { 'user': 'barney', 'age': 34 }
32491     * ];
32492     *
32493     * _.sortBy(users, [function(o) { return o.user; }]);
32494     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
32495     *
32496     * _.sortBy(users, ['user', 'age']);
32497     * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
32498     */
32499    var sortBy = baseRest(function(collection, iteratees) {
32500      if (collection == null) {
32501        return [];
32502      }
32503      var length = iteratees.length;
32504      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
32505        iteratees = [];
32506      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
32507        iteratees = [iteratees[0]];
32508      }
32509      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
32510    });
32511
32512    /*------------------------------------------------------------------------*/
32513
32514    /**
32515     * Gets the timestamp of the number of milliseconds that have elapsed since
32516     * the Unix epoch (1 January 1970 00:00:00 UTC).
32517     *
32518     * @static
32519     * @memberOf _
32520     * @since 2.4.0
32521     * @category Date
32522     * @returns {number} Returns the timestamp.
32523     * @example
32524     *
32525     * _.defer(function(stamp) {
32526     *   console.log(_.now() - stamp);
32527     * }, _.now());
32528     * // => Logs the number of milliseconds it took for the deferred invocation.
32529     */
32530    var now = ctxNow || function() {
32531      return root.Date.now();
32532    };
32533
32534    /*------------------------------------------------------------------------*/
32535
32536    /**
32537     * The opposite of `_.before`; this method creates a function that invokes
32538     * `func` once it's called `n` or more times.
32539     *
32540     * @static
32541     * @memberOf _
32542     * @since 0.1.0
32543     * @category Function
32544     * @param {number} n The number of calls before `func` is invoked.
32545     * @param {Function} func The function to restrict.
32546     * @returns {Function} Returns the new restricted function.
32547     * @example
32548     *
32549     * var saves = ['profile', 'settings'];
32550     *
32551     * var done = _.after(saves.length, function() {
32552     *   console.log('done saving!');
32553     * });
32554     *
32555     * _.forEach(saves, function(type) {
32556     *   asyncSave({ 'type': type, 'complete': done });
32557     * });
32558     * // => Logs 'done saving!' after the two async saves have completed.
32559     */
32560    function after(n, func) {
32561      if (typeof func != 'function') {
32562        throw new TypeError(FUNC_ERROR_TEXT);
32563      }
32564      n = toInteger(n);
32565      return function() {
32566        if (--n < 1) {
32567          return func.apply(this, arguments);
32568        }
32569      };
32570    }
32571
32572    /**
32573     * Creates a function that invokes `func`, with up to `n` arguments,
32574     * ignoring any additional arguments.
32575     *
32576     * @static
32577     * @memberOf _
32578     * @since 3.0.0
32579     * @category Function
32580     * @param {Function} func The function to cap arguments for.
32581     * @param {number} [n=func.length] The arity cap.
32582     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
32583     * @returns {Function} Returns the new capped function.
32584     * @example
32585     *
32586     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
32587     * // => [6, 8, 10]
32588     */
32589    function ary(func, n, guard) {
32590      n = guard ? undefined : n;
32591      n = (func && n == null) ? func.length : n;
32592      return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
32593    }
32594
32595    /**
32596     * Creates a function that invokes `func`, with the `this` binding and arguments
32597     * of the created function, while it's called less than `n` times. Subsequent
32598     * calls to the created function return the result of the last `func` invocation.
32599     *
32600     * @static
32601     * @memberOf _
32602     * @since 3.0.0
32603     * @category Function
32604     * @param {number} n The number of calls at which `func` is no longer invoked.
32605     * @param {Function} func The function to restrict.
32606     * @returns {Function} Returns the new restricted function.
32607     * @example
32608     *
32609     * jQuery(element).on('click', _.before(5, addContactToList));
32610     * // => Allows adding up to 4 contacts to the list.
32611     */
32612    function before(n, func) {
32613      var result;
32614      if (typeof func != 'function') {
32615        throw new TypeError(FUNC_ERROR_TEXT);
32616      }
32617      n = toInteger(n);
32618      return function() {
32619        if (--n > 0) {
32620          result = func.apply(this, arguments);
32621        }
32622        if (n <= 1) {
32623          func = undefined;
32624        }
32625        return result;
32626      };
32627    }
32628
32629    /**
32630     * Creates a function that invokes `func` with the `this` binding of `thisArg`
32631     * and `partials` prepended to the arguments it receives.
32632     *
32633     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
32634     * may be used as a placeholder for partially applied arguments.
32635     *
32636     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
32637     * property of bound functions.
32638     *
32639     * @static
32640     * @memberOf _
32641     * @since 0.1.0
32642     * @category Function
32643     * @param {Function} func The function to bind.
32644     * @param {*} thisArg The `this` binding of `func`.
32645     * @param {...*} [partials] The arguments to be partially applied.
32646     * @returns {Function} Returns the new bound function.
32647     * @example
32648     *
32649     * function greet(greeting, punctuation) {
32650     *   return greeting + ' ' + this.user + punctuation;
32651     * }
32652     *
32653     * var object = { 'user': 'fred' };
32654     *
32655     * var bound = _.bind(greet, object, 'hi');
32656     * bound('!');
32657     * // => 'hi fred!'
32658     *
32659     * // Bound with placeholders.
32660     * var bound = _.bind(greet, object, _, '!');
32661     * bound('hi');
32662     * // => 'hi fred!'
32663     */
32664    var bind = baseRest(function(func, thisArg, partials) {
32665      var bitmask = WRAP_BIND_FLAG;
32666      if (partials.length) {
32667        var holders = replaceHolders(partials, getHolder(bind));
32668        bitmask |= WRAP_PARTIAL_FLAG;
32669      }
32670      return createWrap(func, bitmask, thisArg, partials, holders);
32671    });
32672
32673    /**
32674     * Creates a function that invokes the method at `object[key]` with `partials`
32675     * prepended to the arguments it receives.
32676     *
32677     * This method differs from `_.bind` by allowing bound functions to reference
32678     * methods that may be redefined or don't yet exist. See
32679     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
32680     * for more details.
32681     *
32682     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
32683     * builds, may be used as a placeholder for partially applied arguments.
32684     *
32685     * @static
32686     * @memberOf _
32687     * @since 0.10.0
32688     * @category Function
32689     * @param {Object} object The object to invoke the method on.
32690     * @param {string} key The key of the method.
32691     * @param {...*} [partials] The arguments to be partially applied.
32692     * @returns {Function} Returns the new bound function.
32693     * @example
32694     *
32695     * var object = {
32696     *   'user': 'fred',
32697     *   'greet': function(greeting, punctuation) {
32698     *     return greeting + ' ' + this.user + punctuation;
32699     *   }
32700     * };
32701     *
32702     * var bound = _.bindKey(object, 'greet', 'hi');
32703     * bound('!');
32704     * // => 'hi fred!'
32705     *
32706     * object.greet = function(greeting, punctuation) {
32707     *   return greeting + 'ya ' + this.user + punctuation;
32708     * };
32709     *
32710     * bound('!');
32711     * // => 'hiya fred!'
32712     *
32713     * // Bound with placeholders.
32714     * var bound = _.bindKey(object, 'greet', _, '!');
32715     * bound('hi');
32716     * // => 'hiya fred!'
32717     */
32718    var bindKey = baseRest(function(object, key, partials) {
32719      var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
32720      if (partials.length) {
32721        var holders = replaceHolders(partials, getHolder(bindKey));
32722        bitmask |= WRAP_PARTIAL_FLAG;
32723      }
32724      return createWrap(key, bitmask, object, partials, holders);
32725    });
32726
32727    /**
32728     * Creates a function that accepts arguments of `func` and either invokes
32729     * `func` returning its result, if at least `arity` number of arguments have
32730     * been provided, or returns a function that accepts the remaining `func`
32731     * arguments, and so on. The arity of `func` may be specified if `func.length`
32732     * is not sufficient.
32733     *
32734     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
32735     * may be used as a placeholder for provided arguments.
32736     *
32737     * **Note:** This method doesn't set the "length" property of curried functions.
32738     *
32739     * @static
32740     * @memberOf _
32741     * @since 2.0.0
32742     * @category Function
32743     * @param {Function} func The function to curry.
32744     * @param {number} [arity=func.length] The arity of `func`.
32745     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
32746     * @returns {Function} Returns the new curried function.
32747     * @example
32748     *
32749     * var abc = function(a, b, c) {
32750     *   return [a, b, c];
32751     * };
32752     *
32753     * var curried = _.curry(abc);
32754     *
32755     * curried(1)(2)(3);
32756     * // => [1, 2, 3]
32757     *
32758     * curried(1, 2)(3);
32759     * // => [1, 2, 3]
32760     *
32761     * curried(1, 2, 3);
32762     * // => [1, 2, 3]
32763     *
32764     * // Curried with placeholders.
32765     * curried(1)(_, 3)(2);
32766     * // => [1, 2, 3]
32767     */
32768    function curry(func, arity, guard) {
32769      arity = guard ? undefined : arity;
32770      var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
32771      result.placeholder = curry.placeholder;
32772      return result;
32773    }
32774
32775    /**
32776     * This method is like `_.curry` except that arguments are applied to `func`
32777     * in the manner of `_.partialRight` instead of `_.partial`.
32778     *
32779     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
32780     * builds, may be used as a placeholder for provided arguments.
32781     *
32782     * **Note:** This method doesn't set the "length" property of curried functions.
32783     *
32784     * @static
32785     * @memberOf _
32786     * @since 3.0.0
32787     * @category Function
32788     * @param {Function} func The function to curry.
32789     * @param {number} [arity=func.length] The arity of `func`.
32790     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
32791     * @returns {Function} Returns the new curried function.
32792     * @example
32793     *
32794     * var abc = function(a, b, c) {
32795     *   return [a, b, c];
32796     * };
32797     *
32798     * var curried = _.curryRight(abc);
32799     *
32800     * curried(3)(2)(1);
32801     * // => [1, 2, 3]
32802     *
32803     * curried(2, 3)(1);
32804     * // => [1, 2, 3]
32805     *
32806     * curried(1, 2, 3);
32807     * // => [1, 2, 3]
32808     *
32809     * // Curried with placeholders.
32810     * curried(3)(1, _)(2);
32811     * // => [1, 2, 3]
32812     */
32813    function curryRight(func, arity, guard) {
32814      arity = guard ? undefined : arity;
32815      var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
32816      result.placeholder = curryRight.placeholder;
32817      return result;
32818    }
32819
32820    /**
32821     * Creates a debounced function that delays invoking `func` until after `wait`
32822     * milliseconds have elapsed since the last time the debounced function was
32823     * invoked. The debounced function comes with a `cancel` method to cancel
32824     * delayed `func` invocations and a `flush` method to immediately invoke them.
32825     * Provide `options` to indicate whether `func` should be invoked on the
32826     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
32827     * with the last arguments provided to the debounced function. Subsequent
32828     * calls to the debounced function return the result of the last `func`
32829     * invocation.
32830     *
32831     * **Note:** If `leading` and `trailing` options are `true`, `func` is
32832     * invoked on the trailing edge of the timeout only if the debounced function
32833     * is invoked more than once during the `wait` timeout.
32834     *
32835     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
32836     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
32837     *
32838     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
32839     * for details over the differences between `_.debounce` and `_.throttle`.
32840     *
32841     * @static
32842     * @memberOf _
32843     * @since 0.1.0
32844     * @category Function
32845     * @param {Function} func The function to debounce.
32846     * @param {number} [wait=0] The number of milliseconds to delay.
32847     * @param {Object} [options={}] The options object.
32848     * @param {boolean} [options.leading=false]
32849     *  Specify invoking on the leading edge of the timeout.
32850     * @param {number} [options.maxWait]
32851     *  The maximum time `func` is allowed to be delayed before it's invoked.
32852     * @param {boolean} [options.trailing=true]
32853     *  Specify invoking on the trailing edge of the timeout.
32854     * @returns {Function} Returns the new debounced function.
32855     * @example
32856     *
32857     * // Avoid costly calculations while the window size is in flux.
32858     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
32859     *
32860     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
32861     * jQuery(element).on('click', _.debounce(sendMail, 300, {
32862     *   'leading': true,
32863     *   'trailing': false
32864     * }));
32865     *
32866     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
32867     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
32868     * var source = new EventSource('/stream');
32869     * jQuery(source).on('message', debounced);
32870     *
32871     * // Cancel the trailing debounced invocation.
32872     * jQuery(window).on('popstate', debounced.cancel);
32873     */
32874    function debounce(func, wait, options) {
32875      var lastArgs,
32876          lastThis,
32877          maxWait,
32878          result,
32879          timerId,
32880          lastCallTime,
32881          lastInvokeTime = 0,
32882          leading = false,
32883          maxing = false,
32884          trailing = true;
32885
32886      if (typeof func != 'function') {
32887        throw new TypeError(FUNC_ERROR_TEXT);
32888      }
32889      wait = toNumber(wait) || 0;
32890      if (isObject(options)) {
32891        leading = !!options.leading;
32892        maxing = 'maxWait' in options;
32893        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
32894        trailing = 'trailing' in options ? !!options.trailing : trailing;
32895      }
32896
32897      function invokeFunc(time) {
32898        var args = lastArgs,
32899            thisArg = lastThis;
32900
32901        lastArgs = lastThis = undefined;
32902        lastInvokeTime = time;
32903        result = func.apply(thisArg, args);
32904        return result;
32905      }
32906
32907      function leadingEdge(time) {
32908        // Reset any `maxWait` timer.
32909        lastInvokeTime = time;
32910        // Start the timer for the trailing edge.
32911        timerId = setTimeout(timerExpired, wait);
32912        // Invoke the leading edge.
32913        return leading ? invokeFunc(time) : result;
32914      }
32915
32916      function remainingWait(time) {
32917        var timeSinceLastCall = time - lastCallTime,
32918            timeSinceLastInvoke = time - lastInvokeTime,
32919            timeWaiting = wait - timeSinceLastCall;
32920
32921        return maxing
32922          ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
32923          : timeWaiting;
32924      }
32925
32926      function shouldInvoke(time) {
32927        var timeSinceLastCall = time - lastCallTime,
32928            timeSinceLastInvoke = time - lastInvokeTime;
32929
32930        // Either this is the first call, activity has stopped and we're at the
32931        // trailing edge, the system time has gone backwards and we're treating
32932        // it as the trailing edge, or we've hit the `maxWait` limit.
32933        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
32934          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
32935      }
32936
32937      function timerExpired() {
32938        var time = now();
32939        if (shouldInvoke(time)) {
32940          return trailingEdge(time);
32941        }
32942        // Restart the timer.
32943        timerId = setTimeout(timerExpired, remainingWait(time));
32944      }
32945
32946      function trailingEdge(time) {
32947        timerId = undefined;
32948
32949        // Only invoke if we have `lastArgs` which means `func` has been
32950        // debounced at least once.
32951        if (trailing && lastArgs) {
32952          return invokeFunc(time);
32953        }
32954        lastArgs = lastThis = undefined;
32955        return result;
32956      }
32957
32958      function cancel() {
32959        if (timerId !== undefined) {
32960          clearTimeout(timerId);
32961        }
32962        lastInvokeTime = 0;
32963        lastArgs = lastCallTime = lastThis = timerId = undefined;
32964      }
32965
32966      function flush() {
32967        return timerId === undefined ? result : trailingEdge(now());
32968      }
32969
32970      function debounced() {
32971        var time = now(),
32972            isInvoking = shouldInvoke(time);
32973
32974        lastArgs = arguments;
32975        lastThis = this;
32976        lastCallTime = time;
32977
32978        if (isInvoking) {
32979          if (timerId === undefined) {
32980            return leadingEdge(lastCallTime);
32981          }
32982          if (maxing) {
32983            // Handle invocations in a tight loop.
32984            clearTimeout(timerId);
32985            timerId = setTimeout(timerExpired, wait);
32986            return invokeFunc(lastCallTime);
32987          }
32988        }
32989        if (timerId === undefined) {
32990          timerId = setTimeout(timerExpired, wait);
32991        }
32992        return result;
32993      }
32994      debounced.cancel = cancel;
32995      debounced.flush = flush;
32996      return debounced;
32997    }
32998
32999    /**
33000     * Defers invoking the `func` until the current call stack has cleared. Any
33001     * additional arguments are provided to `func` when it's invoked.
33002     *
33003     * @static
33004     * @memberOf _
33005     * @since 0.1.0
33006     * @category Function
33007     * @param {Function} func The function to defer.
33008     * @param {...*} [args] The arguments to invoke `func` with.
33009     * @returns {number} Returns the timer id.
33010     * @example
33011     *
33012     * _.defer(function(text) {
33013     *   console.log(text);
33014     * }, 'deferred');
33015     * // => Logs 'deferred' after one millisecond.
33016     */
33017    var defer = baseRest(function(func, args) {
33018      return baseDelay(func, 1, args);
33019    });
33020
33021    /**
33022     * Invokes `func` after `wait` milliseconds. Any additional arguments are
33023     * provided to `func` when it's invoked.
33024     *
33025     * @static
33026     * @memberOf _
33027     * @since 0.1.0
33028     * @category Function
33029     * @param {Function} func The function to delay.
33030     * @param {number} wait The number of milliseconds to delay invocation.
33031     * @param {...*} [args] The arguments to invoke `func` with.
33032     * @returns {number} Returns the timer id.
33033     * @example
33034     *
33035     * _.delay(function(text) {
33036     *   console.log(text);
33037     * }, 1000, 'later');
33038     * // => Logs 'later' after one second.
33039     */
33040    var delay = baseRest(function(func, wait, args) {
33041      return baseDelay(func, toNumber(wait) || 0, args);
33042    });
33043
33044    /**
33045     * Creates a function that invokes `func` with arguments reversed.
33046     *
33047     * @static
33048     * @memberOf _
33049     * @since 4.0.0
33050     * @category Function
33051     * @param {Function} func The function to flip arguments for.
33052     * @returns {Function} Returns the new flipped function.
33053     * @example
33054     *
33055     * var flipped = _.flip(function() {
33056     *   return _.toArray(arguments);
33057     * });
33058     *
33059     * flipped('a', 'b', 'c', 'd');
33060     * // => ['d', 'c', 'b', 'a']
33061     */
33062    function flip(func) {
33063      return createWrap(func, WRAP_FLIP_FLAG);
33064    }
33065
33066    /**
33067     * Creates a function that memoizes the result of `func`. If `resolver` is
33068     * provided, it determines the cache key for storing the result based on the
33069     * arguments provided to the memoized function. By default, the first argument
33070     * provided to the memoized function is used as the map cache key. The `func`
33071     * is invoked with the `this` binding of the memoized function.
33072     *
33073     * **Note:** The cache is exposed as the `cache` property on the memoized
33074     * function. Its creation may be customized by replacing the `_.memoize.Cache`
33075     * constructor with one whose instances implement the
33076     * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
33077     * method interface of `clear`, `delete`, `get`, `has`, and `set`.
33078     *
33079     * @static
33080     * @memberOf _
33081     * @since 0.1.0
33082     * @category Function
33083     * @param {Function} func The function to have its output memoized.
33084     * @param {Function} [resolver] The function to resolve the cache key.
33085     * @returns {Function} Returns the new memoized function.
33086     * @example
33087     *
33088     * var object = { 'a': 1, 'b': 2 };
33089     * var other = { 'c': 3, 'd': 4 };
33090     *
33091     * var values = _.memoize(_.values);
33092     * values(object);
33093     * // => [1, 2]
33094     *
33095     * values(other);
33096     * // => [3, 4]
33097     *
33098     * object.a = 2;
33099     * values(object);
33100     * // => [1, 2]
33101     *
33102     * // Modify the result cache.
33103     * values.cache.set(object, ['a', 'b']);
33104     * values(object);
33105     * // => ['a', 'b']
33106     *
33107     * // Replace `_.memoize.Cache`.
33108     * _.memoize.Cache = WeakMap;
33109     */
33110    function memoize(func, resolver) {
33111      if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
33112        throw new TypeError(FUNC_ERROR_TEXT);
33113      }
33114      var memoized = function() {
33115        var args = arguments,
33116            key = resolver ? resolver.apply(this, args) : args[0],
33117            cache = memoized.cache;
33118
33119        if (cache.has(key)) {
33120          return cache.get(key);
33121        }
33122        var result = func.apply(this, args);
33123        memoized.cache = cache.set(key, result) || cache;
33124        return result;
33125      };
33126      memoized.cache = new (memoize.Cache || MapCache);
33127      return memoized;
33128    }
33129
33130    // Expose `MapCache`.
33131    memoize.Cache = MapCache;
33132
33133    /**
33134     * Creates a function that negates the result of the predicate `func`. The
33135     * `func` predicate is invoked with the `this` binding and arguments of the
33136     * created function.
33137     *
33138     * @static
33139     * @memberOf _
33140     * @since 3.0.0
33141     * @category Function
33142     * @param {Function} predicate The predicate to negate.
33143     * @returns {Function} Returns the new negated function.
33144     * @example
33145     *
33146     * function isEven(n) {
33147     *   return n % 2 == 0;
33148     * }
33149     *
33150     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
33151     * // => [1, 3, 5]
33152     */
33153    function negate(predicate) {
33154      if (typeof predicate != 'function') {
33155        throw new TypeError(FUNC_ERROR_TEXT);
33156      }
33157      return function() {
33158        var args = arguments;
33159        switch (args.length) {
33160          case 0: return !predicate.call(this);
33161          case 1: return !predicate.call(this, args[0]);
33162          case 2: return !predicate.call(this, args[0], args[1]);
33163          case 3: return !predicate.call(this, args[0], args[1], args[2]);
33164        }
33165        return !predicate.apply(this, args);
33166      };
33167    }
33168
33169    /**
33170     * Creates a function that is restricted to invoking `func` once. Repeat calls
33171     * to the function return the value of the first invocation. The `func` is
33172     * invoked with the `this` binding and arguments of the created function.
33173     *
33174     * @static
33175     * @memberOf _
33176     * @since 0.1.0
33177     * @category Function
33178     * @param {Function} func The function to restrict.
33179     * @returns {Function} Returns the new restricted function.
33180     * @example
33181     *
33182     * var initialize = _.once(createApplication);
33183     * initialize();
33184     * initialize();
33185     * // => `createApplication` is invoked once
33186     */
33187    function once(func) {
33188      return before(2, func);
33189    }
33190
33191    /**
33192     * Creates a function that invokes `func` with its arguments transformed.
33193     *
33194     * @static
33195     * @since 4.0.0
33196     * @memberOf _
33197     * @category Function
33198     * @param {Function} func The function to wrap.
33199     * @param {...(Function|Function[])} [transforms=[_.identity]]
33200     *  The argument transforms.
33201     * @returns {Function} Returns the new function.
33202     * @example
33203     *
33204     * function doubled(n) {
33205     *   return n * 2;
33206     * }
33207     *
33208     * function square(n) {
33209     *   return n * n;
33210     * }
33211     *
33212     * var func = _.overArgs(function(x, y) {
33213     *   return [x, y];
33214     * }, [square, doubled]);
33215     *
33216     * func(9, 3);
33217     * // => [81, 6]
33218     *
33219     * func(10, 5);
33220     * // => [100, 10]
33221     */
33222    var overArgs = castRest(function(func, transforms) {
33223      transforms = (transforms.length == 1 && isArray(transforms[0]))
33224        ? arrayMap(transforms[0], baseUnary(getIteratee()))
33225        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
33226
33227      var funcsLength = transforms.length;
33228      return baseRest(function(args) {
33229        var index = -1,
33230            length = nativeMin(args.length, funcsLength);
33231
33232        while (++index < length) {
33233          args[index] = transforms[index].call(this, args[index]);
33234        }
33235        return apply(func, this, args);
33236      });
33237    });
33238
33239    /**
33240     * Creates a function that invokes `func` with `partials` prepended to the
33241     * arguments it receives. This method is like `_.bind` except it does **not**
33242     * alter the `this` binding.
33243     *
33244     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
33245     * builds, may be used as a placeholder for partially applied arguments.
33246     *
33247     * **Note:** This method doesn't set the "length" property of partially
33248     * applied functions.
33249     *
33250     * @static
33251     * @memberOf _
33252     * @since 0.2.0
33253     * @category Function
33254     * @param {Function} func The function to partially apply arguments to.
33255     * @param {...*} [partials] The arguments to be partially applied.
33256     * @returns {Function} Returns the new partially applied function.
33257     * @example
33258     *
33259     * function greet(greeting, name) {
33260     *   return greeting + ' ' + name;
33261     * }
33262     *
33263     * var sayHelloTo = _.partial(greet, 'hello');
33264     * sayHelloTo('fred');
33265     * // => 'hello fred'
33266     *
33267     * // Partially applied with placeholders.
33268     * var greetFred = _.partial(greet, _, 'fred');
33269     * greetFred('hi');
33270     * // => 'hi fred'
33271     */
33272    var partial = baseRest(function(func, partials) {
33273      var holders = replaceHolders(partials, getHolder(partial));
33274      return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
33275    });
33276
33277    /**
33278     * This method is like `_.partial` except that partially applied arguments
33279     * are appended to the arguments it receives.
33280     *
33281     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
33282     * builds, may be used as a placeholder for partially applied arguments.
33283     *
33284     * **Note:** This method doesn't set the "length" property of partially
33285     * applied functions.
33286     *
33287     * @static
33288     * @memberOf _
33289     * @since 1.0.0
33290     * @category Function
33291     * @param {Function} func The function to partially apply arguments to.
33292     * @param {...*} [partials] The arguments to be partially applied.
33293     * @returns {Function} Returns the new partially applied function.
33294     * @example
33295     *
33296     * function greet(greeting, name) {
33297     *   return greeting + ' ' + name;
33298     * }
33299     *
33300     * var greetFred = _.partialRight(greet, 'fred');
33301     * greetFred('hi');
33302     * // => 'hi fred'
33303     *
33304     * // Partially applied with placeholders.
33305     * var sayHelloTo = _.partialRight(greet, 'hello', _);
33306     * sayHelloTo('fred');
33307     * // => 'hello fred'
33308     */
33309    var partialRight = baseRest(function(func, partials) {
33310      var holders = replaceHolders(partials, getHolder(partialRight));
33311      return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
33312    });
33313
33314    /**
33315     * Creates a function that invokes `func` with arguments arranged according
33316     * to the specified `indexes` where the argument value at the first index is
33317     * provided as the first argument, the argument value at the second index is
33318     * provided as the second argument, and so on.
33319     *
33320     * @static
33321     * @memberOf _
33322     * @since 3.0.0
33323     * @category Function
33324     * @param {Function} func The function to rearrange arguments for.
33325     * @param {...(number|number[])} indexes The arranged argument indexes.
33326     * @returns {Function} Returns the new function.
33327     * @example
33328     *
33329     * var rearged = _.rearg(function(a, b, c) {
33330     *   return [a, b, c];
33331     * }, [2, 0, 1]);
33332     *
33333     * rearged('b', 'c', 'a')
33334     * // => ['a', 'b', 'c']
33335     */
33336    var rearg = flatRest(function(func, indexes) {
33337      return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
33338    });
33339
33340    /**
33341     * Creates a function that invokes `func` with the `this` binding of the
33342     * created function and arguments from `start` and beyond provided as
33343     * an array.
33344     *
33345     * **Note:** This method is based on the
33346     * [rest parameter](https://mdn.io/rest_parameters).
33347     *
33348     * @static
33349     * @memberOf _
33350     * @since 4.0.0
33351     * @category Function
33352     * @param {Function} func The function to apply a rest parameter to.
33353     * @param {number} [start=func.length-1] The start position of the rest parameter.
33354     * @returns {Function} Returns the new function.
33355     * @example
33356     *
33357     * var say = _.rest(function(what, names) {
33358     *   return what + ' ' + _.initial(names).join(', ') +
33359     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
33360     * });
33361     *
33362     * say('hello', 'fred', 'barney', 'pebbles');
33363     * // => 'hello fred, barney, & pebbles'
33364     */
33365    function rest(func, start) {
33366      if (typeof func != 'function') {
33367        throw new TypeError(FUNC_ERROR_TEXT);
33368      }
33369      start = start === undefined ? start : toInteger(start);
33370      return baseRest(func, start);
33371    }
33372
33373    /**
33374     * Creates a function that invokes `func` with the `this` binding of the
33375     * create function and an array of arguments much like
33376     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
33377     *
33378     * **Note:** This method is based on the
33379     * [spread operator](https://mdn.io/spread_operator).
33380     *
33381     * @static
33382     * @memberOf _
33383     * @since 3.2.0
33384     * @category Function
33385     * @param {Function} func The function to spread arguments over.
33386     * @param {number} [start=0] The start position of the spread.
33387     * @returns {Function} Returns the new function.
33388     * @example
33389     *
33390     * var say = _.spread(function(who, what) {
33391     *   return who + ' says ' + what;
33392     * });
33393     *
33394     * say(['fred', 'hello']);
33395     * // => 'fred says hello'
33396     *
33397     * var numbers = Promise.all([
33398     *   Promise.resolve(40),
33399     *   Promise.resolve(36)
33400     * ]);
33401     *
33402     * numbers.then(_.spread(function(x, y) {
33403     *   return x + y;
33404     * }));
33405     * // => a Promise of 76
33406     */
33407    function spread(func, start) {
33408      if (typeof func != 'function') {
33409        throw new TypeError(FUNC_ERROR_TEXT);
33410      }
33411      start = start == null ? 0 : nativeMax(toInteger(start), 0);
33412      return baseRest(function(args) {
33413        var array = args[start],
33414            otherArgs = castSlice(args, 0, start);
33415
33416        if (array) {
33417          arrayPush(otherArgs, array);
33418        }
33419        return apply(func, this, otherArgs);
33420      });
33421    }
33422
33423    /**
33424     * Creates a throttled function that only invokes `func` at most once per
33425     * every `wait` milliseconds. The throttled function comes with a `cancel`
33426     * method to cancel delayed `func` invocations and a `flush` method to
33427     * immediately invoke them. Provide `options` to indicate whether `func`
33428     * should be invoked on the leading and/or trailing edge of the `wait`
33429     * timeout. The `func` is invoked with the last arguments provided to the
33430     * throttled function. Subsequent calls to the throttled function return the
33431     * result of the last `func` invocation.
33432     *
33433     * **Note:** If `leading` and `trailing` options are `true`, `func` is
33434     * invoked on the trailing edge of the timeout only if the throttled function
33435     * is invoked more than once during the `wait` timeout.
33436     *
33437     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
33438     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
33439     *
33440     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
33441     * for details over the differences between `_.throttle` and `_.debounce`.
33442     *
33443     * @static
33444     * @memberOf _
33445     * @since 0.1.0
33446     * @category Function
33447     * @param {Function} func The function to throttle.
33448     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
33449     * @param {Object} [options={}] The options object.
33450     * @param {boolean} [options.leading=true]
33451     *  Specify invoking on the leading edge of the timeout.
33452     * @param {boolean} [options.trailing=true]
33453     *  Specify invoking on the trailing edge of the timeout.
33454     * @returns {Function} Returns the new throttled function.
33455     * @example
33456     *
33457     * // Avoid excessively updating the position while scrolling.
33458     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
33459     *
33460     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
33461     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
33462     * jQuery(element).on('click', throttled);
33463     *
33464     * // Cancel the trailing throttled invocation.
33465     * jQuery(window).on('popstate', throttled.cancel);
33466     */
33467    function throttle(func, wait, options) {
33468      var leading = true,
33469          trailing = true;
33470
33471      if (typeof func != 'function') {
33472        throw new TypeError(FUNC_ERROR_TEXT);
33473      }
33474      if (isObject(options)) {
33475        leading = 'leading' in options ? !!options.leading : leading;
33476        trailing = 'trailing' in options ? !!options.trailing : trailing;
33477      }
33478      return debounce(func, wait, {
33479        'leading': leading,
33480        'maxWait': wait,
33481        'trailing': trailing
33482      });
33483    }
33484
33485    /**
33486     * Creates a function that accepts up to one argument, ignoring any
33487     * additional arguments.
33488     *
33489     * @static
33490     * @memberOf _
33491     * @since 4.0.0
33492     * @category Function
33493     * @param {Function} func The function to cap arguments for.
33494     * @returns {Function} Returns the new capped function.
33495     * @example
33496     *
33497     * _.map(['6', '8', '10'], _.unary(parseInt));
33498     * // => [6, 8, 10]
33499     */
33500    function unary(func) {
33501      return ary(func, 1);
33502    }
33503
33504    /**
33505     * Creates a function that provides `value` to `wrapper` as its first
33506     * argument. Any additional arguments provided to the function are appended
33507     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
33508     * binding of the created function.
33509     *
33510     * @static
33511     * @memberOf _
33512     * @since 0.1.0
33513     * @category Function
33514     * @param {*} value The value to wrap.
33515     * @param {Function} [wrapper=identity] The wrapper function.
33516     * @returns {Function} Returns the new function.
33517     * @example
33518     *
33519     * var p = _.wrap(_.escape, function(func, text) {
33520     *   return '<p>' + func(text) + '</p>';
33521     * });
33522     *
33523     * p('fred, barney, & pebbles');
33524     * // => '<p>fred, barney, &amp; pebbles</p>'
33525     */
33526    function wrap(value, wrapper) {
33527      return partial(castFunction(wrapper), value);
33528    }
33529
33530    /*------------------------------------------------------------------------*/
33531
33532    /**
33533     * Casts `value` as an array if it's not one.
33534     *
33535     * @static
33536     * @memberOf _
33537     * @since 4.4.0
33538     * @category Lang
33539     * @param {*} value The value to inspect.
33540     * @returns {Array} Returns the cast array.
33541     * @example
33542     *
33543     * _.castArray(1);
33544     * // => [1]
33545     *
33546     * _.castArray({ 'a': 1 });
33547     * // => [{ 'a': 1 }]
33548     *
33549     * _.castArray('abc');
33550     * // => ['abc']
33551     *
33552     * _.castArray(null);
33553     * // => [null]
33554     *
33555     * _.castArray(undefined);
33556     * // => [undefined]
33557     *
33558     * _.castArray();
33559     * // => []
33560     *
33561     * var array = [1, 2, 3];
33562     * console.log(_.castArray(array) === array);
33563     * // => true
33564     */
33565    function castArray() {
33566      if (!arguments.length) {
33567        return [];
33568      }
33569      var value = arguments[0];
33570      return isArray(value) ? value : [value];
33571    }
33572
33573    /**
33574     * Creates a shallow clone of `value`.
33575     *
33576     * **Note:** This method is loosely based on the
33577     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
33578     * and supports cloning arrays, array buffers, booleans, date objects, maps,
33579     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
33580     * arrays. The own enumerable properties of `arguments` objects are cloned
33581     * as plain objects. An empty object is returned for uncloneable values such
33582     * as error objects, functions, DOM nodes, and WeakMaps.
33583     *
33584     * @static
33585     * @memberOf _
33586     * @since 0.1.0
33587     * @category Lang
33588     * @param {*} value The value to clone.
33589     * @returns {*} Returns the cloned value.
33590     * @see _.cloneDeep
33591     * @example
33592     *
33593     * var objects = [{ 'a': 1 }, { 'b': 2 }];
33594     *
33595     * var shallow = _.clone(objects);
33596     * console.log(shallow[0] === objects[0]);
33597     * // => true
33598     */
33599    function clone(value) {
33600      return baseClone(value, CLONE_SYMBOLS_FLAG);
33601    }
33602
33603    /**
33604     * This method is like `_.clone` except that it accepts `customizer` which
33605     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
33606     * cloning is handled by the method instead. The `customizer` is invoked with
33607     * up to four arguments; (value [, index|key, object, stack]).
33608     *
33609     * @static
33610     * @memberOf _
33611     * @since 4.0.0
33612     * @category Lang
33613     * @param {*} value The value to clone.
33614     * @param {Function} [customizer] The function to customize cloning.
33615     * @returns {*} Returns the cloned value.
33616     * @see _.cloneDeepWith
33617     * @example
33618     *
33619     * function customizer(value) {
33620     *   if (_.isElement(value)) {
33621     *     return value.cloneNode(false);
33622     *   }
33623     * }
33624     *
33625     * var el = _.cloneWith(document.body, customizer);
33626     *
33627     * console.log(el === document.body);
33628     * // => false
33629     * console.log(el.nodeName);
33630     * // => 'BODY'
33631     * console.log(el.childNodes.length);
33632     * // => 0
33633     */
33634    function cloneWith(value, customizer) {
33635      customizer = typeof customizer == 'function' ? customizer : undefined;
33636      return baseClone(value, CLONE_SYMBOLS_FLAG, customizer);
33637    }
33638
33639    /**
33640     * This method is like `_.clone` except that it recursively clones `value`.
33641     *
33642     * @static
33643     * @memberOf _
33644     * @since 1.0.0
33645     * @category Lang
33646     * @param {*} value The value to recursively clone.
33647     * @returns {*} Returns the deep cloned value.
33648     * @see _.clone
33649     * @example
33650     *
33651     * var objects = [{ 'a': 1 }, { 'b': 2 }];
33652     *
33653     * var deep = _.cloneDeep(objects);
33654     * console.log(deep[0] === objects[0]);
33655     * // => false
33656     */
33657    function cloneDeep(value) {
33658      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG);
33659    }
33660
33661    /**
33662     * This method is like `_.cloneWith` except that it recursively clones `value`.
33663     *
33664     * @static
33665     * @memberOf _
33666     * @since 4.0.0
33667     * @category Lang
33668     * @param {*} value The value to recursively clone.
33669     * @param {Function} [customizer] The function to customize cloning.
33670     * @returns {*} Returns the deep cloned value.
33671     * @see _.cloneWith
33672     * @example
33673     *
33674     * function customizer(value) {
33675     *   if (_.isElement(value)) {
33676     *     return value.cloneNode(true);
33677     *   }
33678     * }
33679     *
33680     * var el = _.cloneDeepWith(document.body, customizer);
33681     *
33682     * console.log(el === document.body);
33683     * // => false
33684     * console.log(el.nodeName);
33685     * // => 'BODY'
33686     * console.log(el.childNodes.length);
33687     * // => 20
33688     */
33689    function cloneDeepWith(value, customizer) {
33690      customizer = typeof customizer == 'function' ? customizer : undefined;
33691      return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
33692    }
33693
33694    /**
33695     * Checks if `object` conforms to `source` by invoking the predicate
33696     * properties of `source` with the corresponding property values of `object`.
33697     *
33698     * **Note:** This method is equivalent to `_.conforms` when `source` is
33699     * partially applied.
33700     *
33701     * @static
33702     * @memberOf _
33703     * @since 4.14.0
33704     * @category Lang
33705     * @param {Object} object The object to inspect.
33706     * @param {Object} source The object of property predicates to conform to.
33707     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
33708     * @example
33709     *
33710     * var object = { 'a': 1, 'b': 2 };
33711     *
33712     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
33713     * // => true
33714     *
33715     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
33716     * // => false
33717     */
33718    function conformsTo(object, source) {
33719      return source == null || baseConformsTo(object, source, keys(source));
33720    }
33721
33722    /**
33723     * Performs a
33724     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
33725     * comparison between two values to determine if they are equivalent.
33726     *
33727     * @static
33728     * @memberOf _
33729     * @since 4.0.0
33730     * @category Lang
33731     * @param {*} value The value to compare.
33732     * @param {*} other The other value to compare.
33733     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
33734     * @example
33735     *
33736     * var object = { 'a': 1 };
33737     * var other = { 'a': 1 };
33738     *
33739     * _.eq(object, object);
33740     * // => true
33741     *
33742     * _.eq(object, other);
33743     * // => false
33744     *
33745     * _.eq('a', 'a');
33746     * // => true
33747     *
33748     * _.eq('a', Object('a'));
33749     * // => false
33750     *
33751     * _.eq(NaN, NaN);
33752     * // => true
33753     */
33754    function eq(value, other) {
33755      return value === other || (value !== value && other !== other);
33756    }
33757
33758    /**
33759     * Checks if `value` is greater than `other`.
33760     *
33761     * @static
33762     * @memberOf _
33763     * @since 3.9.0
33764     * @category Lang
33765     * @param {*} value The value to compare.
33766     * @param {*} other The other value to compare.
33767     * @returns {boolean} Returns `true` if `value` is greater than `other`,
33768     *  else `false`.
33769     * @see _.lt
33770     * @example
33771     *
33772     * _.gt(3, 1);
33773     * // => true
33774     *
33775     * _.gt(3, 3);
33776     * // => false
33777     *
33778     * _.gt(1, 3);
33779     * // => false
33780     */
33781    var gt = createRelationalOperation(baseGt);
33782
33783    /**
33784     * Checks if `value` is greater than or equal to `other`.
33785     *
33786     * @static
33787     * @memberOf _
33788     * @since 3.9.0
33789     * @category Lang
33790     * @param {*} value The value to compare.
33791     * @param {*} other The other value to compare.
33792     * @returns {boolean} Returns `true` if `value` is greater than or equal to
33793     *  `other`, else `false`.
33794     * @see _.lte
33795     * @example
33796     *
33797     * _.gte(3, 1);
33798     * // => true
33799     *
33800     * _.gte(3, 3);
33801     * // => true
33802     *
33803     * _.gte(1, 3);
33804     * // => false
33805     */
33806    var gte = createRelationalOperation(function(value, other) {
33807      return value >= other;
33808    });
33809
33810    /**
33811     * Checks if `value` is likely an `arguments` object.
33812     *
33813     * @static
33814     * @memberOf _
33815     * @since 0.1.0
33816     * @category Lang
33817     * @param {*} value The value to check.
33818     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
33819     *  else `false`.
33820     * @example
33821     *
33822     * _.isArguments(function() { return arguments; }());
33823     * // => true
33824     *
33825     * _.isArguments([1, 2, 3]);
33826     * // => false
33827     */
33828    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
33829      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
33830        !propertyIsEnumerable.call(value, 'callee');
33831    };
33832
33833    /**
33834     * Checks if `value` is classified as an `Array` object.
33835     *
33836     * @static
33837     * @memberOf _
33838     * @since 0.1.0
33839     * @category Lang
33840     * @param {*} value The value to check.
33841     * @returns {boolean} Returns `true` if `value` is an array, else `false`.
33842     * @example
33843     *
33844     * _.isArray([1, 2, 3]);
33845     * // => true
33846     *
33847     * _.isArray(document.body.children);
33848     * // => false
33849     *
33850     * _.isArray('abc');
33851     * // => false
33852     *
33853     * _.isArray(_.noop);
33854     * // => false
33855     */
33856    var isArray = Array.isArray;
33857
33858    /**
33859     * Checks if `value` is classified as an `ArrayBuffer` object.
33860     *
33861     * @static
33862     * @memberOf _
33863     * @since 4.3.0
33864     * @category Lang
33865     * @param {*} value The value to check.
33866     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
33867     * @example
33868     *
33869     * _.isArrayBuffer(new ArrayBuffer(2));
33870     * // => true
33871     *
33872     * _.isArrayBuffer(new Array(2));
33873     * // => false
33874     */
33875    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
33876
33877    /**
33878     * Checks if `value` is array-like. A value is considered array-like if it's
33879     * not a function and has a `value.length` that's an integer greater than or
33880     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
33881     *
33882     * @static
33883     * @memberOf _
33884     * @since 4.0.0
33885     * @category Lang
33886     * @param {*} value The value to check.
33887     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
33888     * @example
33889     *
33890     * _.isArrayLike([1, 2, 3]);
33891     * // => true
33892     *
33893     * _.isArrayLike(document.body.children);
33894     * // => true
33895     *
33896     * _.isArrayLike('abc');
33897     * // => true
33898     *
33899     * _.isArrayLike(_.noop);
33900     * // => false
33901     */
33902    function isArrayLike(value) {
33903      return value != null && isLength(value.length) && !isFunction(value);
33904    }
33905
33906    /**
33907     * This method is like `_.isArrayLike` except that it also checks if `value`
33908     * is an object.
33909     *
33910     * @static
33911     * @memberOf _
33912     * @since 4.0.0
33913     * @category Lang
33914     * @param {*} value The value to check.
33915     * @returns {boolean} Returns `true` if `value` is an array-like object,
33916     *  else `false`.
33917     * @example
33918     *
33919     * _.isArrayLikeObject([1, 2, 3]);
33920     * // => true
33921     *
33922     * _.isArrayLikeObject(document.body.children);
33923     * // => true
33924     *
33925     * _.isArrayLikeObject('abc');
33926     * // => false
33927     *
33928     * _.isArrayLikeObject(_.noop);
33929     * // => false
33930     */
33931    function isArrayLikeObject(value) {
33932      return isObjectLike(value) && isArrayLike(value);
33933    }
33934
33935    /**
33936     * Checks if `value` is classified as a boolean primitive or object.
33937     *
33938     * @static
33939     * @memberOf _
33940     * @since 0.1.0
33941     * @category Lang
33942     * @param {*} value The value to check.
33943     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
33944     * @example
33945     *
33946     * _.isBoolean(false);
33947     * // => true
33948     *
33949     * _.isBoolean(null);
33950     * // => false
33951     */
33952    function isBoolean(value) {
33953      return value === true || value === false ||
33954        (isObjectLike(value) && baseGetTag(value) == boolTag);
33955    }
33956
33957    /**
33958     * Checks if `value` is a buffer.
33959     *
33960     * @static
33961     * @memberOf _
33962     * @since 4.3.0
33963     * @category Lang
33964     * @param {*} value The value to check.
33965     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
33966     * @example
33967     *
33968     * _.isBuffer(new Buffer(2));
33969     * // => true
33970     *
33971     * _.isBuffer(new Uint8Array(2));
33972     * // => false
33973     */
33974    var isBuffer = nativeIsBuffer || stubFalse;
33975
33976    /**
33977     * Checks if `value` is classified as a `Date` object.
33978     *
33979     * @static
33980     * @memberOf _
33981     * @since 0.1.0
33982     * @category Lang
33983     * @param {*} value The value to check.
33984     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
33985     * @example
33986     *
33987     * _.isDate(new Date);
33988     * // => true
33989     *
33990     * _.isDate('Mon April 23 2012');
33991     * // => false
33992     */
33993    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
33994
33995    /**
33996     * Checks if `value` is likely a DOM element.
33997     *
33998     * @static
33999     * @memberOf _
34000     * @since 0.1.0
34001     * @category Lang
34002     * @param {*} value The value to check.
34003     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
34004     * @example
34005     *
34006     * _.isElement(document.body);
34007     * // => true
34008     *
34009     * _.isElement('<body>');
34010     * // => false
34011     */
34012    function isElement(value) {
34013      return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value);
34014    }
34015
34016    /**
34017     * Checks if `value` is an empty object, collection, map, or set.
34018     *
34019     * Objects are considered empty if they have no own enumerable string keyed
34020     * properties.
34021     *
34022     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
34023     * jQuery-like collections are considered empty if they have a `length` of `0`.
34024     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
34025     *
34026     * @static
34027     * @memberOf _
34028     * @since 0.1.0
34029     * @category Lang
34030     * @param {*} value The value to check.
34031     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
34032     * @example
34033     *
34034     * _.isEmpty(null);
34035     * // => true
34036     *
34037     * _.isEmpty(true);
34038     * // => true
34039     *
34040     * _.isEmpty(1);
34041     * // => true
34042     *
34043     * _.isEmpty([1, 2, 3]);
34044     * // => false
34045     *
34046     * _.isEmpty({ 'a': 1 });
34047     * // => false
34048     */
34049    function isEmpty(value) {
34050      if (value == null) {
34051        return true;
34052      }
34053      if (isArrayLike(value) &&
34054          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
34055            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
34056        return !value.length;
34057      }
34058      var tag = getTag(value);
34059      if (tag == mapTag || tag == setTag) {
34060        return !value.size;
34061      }
34062      if (isPrototype(value)) {
34063        return !baseKeys(value).length;
34064      }
34065      for (var key in value) {
34066        if (hasOwnProperty.call(value, key)) {
34067          return false;
34068        }
34069      }
34070      return true;
34071    }
34072
34073    /**
34074     * Performs a deep comparison between two values to determine if they are
34075     * equivalent.
34076     *
34077     * **Note:** This method supports comparing arrays, array buffers, booleans,
34078     * date objects, error objects, maps, numbers, `Object` objects, regexes,
34079     * sets, strings, symbols, and typed arrays. `Object` objects are compared
34080     * by their own, not inherited, enumerable properties. Functions and DOM
34081     * nodes are compared by strict equality, i.e. `===`.
34082     *
34083     * @static
34084     * @memberOf _
34085     * @since 0.1.0
34086     * @category Lang
34087     * @param {*} value The value to compare.
34088     * @param {*} other The other value to compare.
34089     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
34090     * @example
34091     *
34092     * var object = { 'a': 1 };
34093     * var other = { 'a': 1 };
34094     *
34095     * _.isEqual(object, other);
34096     * // => true
34097     *
34098     * object === other;
34099     * // => false
34100     */
34101    function isEqual(value, other) {
34102      return baseIsEqual(value, other);
34103    }
34104
34105    /**
34106     * This method is like `_.isEqual` except that it accepts `customizer` which
34107     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
34108     * are handled by the method instead. The `customizer` is invoked with up to
34109     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
34110     *
34111     * @static
34112     * @memberOf _
34113     * @since 4.0.0
34114     * @category Lang
34115     * @param {*} value The value to compare.
34116     * @param {*} other The other value to compare.
34117     * @param {Function} [customizer] The function to customize comparisons.
34118     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
34119     * @example
34120     *
34121     * function isGreeting(value) {
34122     *   return /^h(?:i|ello)$/.test(value);
34123     * }
34124     *
34125     * function customizer(objValue, othValue) {
34126     *   if (isGreeting(objValue) && isGreeting(othValue)) {
34127     *     return true;
34128     *   }
34129     * }
34130     *
34131     * var array = ['hello', 'goodbye'];
34132     * var other = ['hi', 'goodbye'];
34133     *
34134     * _.isEqualWith(array, other, customizer);
34135     * // => true
34136     */
34137    function isEqualWith(value, other, customizer) {
34138      customizer = typeof customizer == 'function' ? customizer : undefined;
34139      var result = customizer ? customizer(value, other) : undefined;
34140      return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
34141    }
34142
34143    /**
34144     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
34145     * `SyntaxError`, `TypeError`, or `URIError` object.
34146     *
34147     * @static
34148     * @memberOf _
34149     * @since 3.0.0
34150     * @category Lang
34151     * @param {*} value The value to check.
34152     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
34153     * @example
34154     *
34155     * _.isError(new Error);
34156     * // => true
34157     *
34158     * _.isError(Error);
34159     * // => false
34160     */
34161    function isError(value) {
34162      if (!isObjectLike(value)) {
34163        return false;
vendor: 6,607 bytes, lines 34164-34401
34164      }
34165      var tag = baseGetTag(value);
34166      return tag == errorTag || tag == domExcTag ||
34167        (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
34168    }
34169
34170    /**
34171     * Checks if `value` is a finite primitive number.
34172     *
34173     * **Note:** This method is based on
34174     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
34175     *
34176     * @static
34177     * @memberOf _
34178     * @since 0.1.0
34179     * @category Lang
34180     * @param {*} value The value to check.
34181     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
34182     * @example
34183     *
34184     * _.isFinite(3);
34185     * // => true
34186     *
34187     * _.isFinite(Number.MIN_VALUE);
34188     * // => true
34189     *
34190     * _.isFinite(Infinity);
34191     * // => false
34192     *
34193     * _.isFinite('3');
34194     * // => false
34195     */
34196    function isFinite(value) {
34197      return typeof value == 'number' && nativeIsFinite(value);
34198    }
34199
34200    /**
34201     * Checks if `value` is classified as a `Function` object.
34202     *
34203     * @static
34204     * @memberOf _
34205     * @since 0.1.0
34206     * @category Lang
34207     * @param {*} value The value to check.
34208     * @returns {boolean} Returns `true` if `value` is a function, else `false`.
34209     * @example
34210     *
34211     * _.isFunction(_);
34212     * // => true
34213     *
34214     * _.isFunction(/abc/);
34215     * // => false
34216     */
34217    function isFunction(value) {
34218      if (!isObject(value)) {
34219        return false;
34220      }
34221      // The use of `Object#toString` avoids issues with the `typeof` operator
34222      // in Safari 9 which returns 'object' for typed arrays and other constructors.
34223      var tag = baseGetTag(value);
34224      return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
34225    }
34226
34227    /**
34228     * Checks if `value` is an integer.
34229     *
34230     * **Note:** This method is based on
34231     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
34232     *
34233     * @static
34234     * @memberOf _
34235     * @since 4.0.0
34236     * @category Lang
34237     * @param {*} value The value to check.
34238     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
34239     * @example
34240     *
34241     * _.isInteger(3);
34242     * // => true
34243     *
34244     * _.isInteger(Number.MIN_VALUE);
34245     * // => false
34246     *
34247     * _.isInteger(Infinity);
34248     * // => false
34249     *
34250     * _.isInteger('3');
34251     * // => false
34252     */
34253    function isInteger(value) {
34254      return typeof value == 'number' && value == toInteger(value);
34255    }
34256
34257    /**
34258     * Checks if `value` is a valid array-like length.
34259     *
34260     * **Note:** This method is loosely based on
34261     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
34262     *
34263     * @static
34264     * @memberOf _
34265     * @since 4.0.0
34266     * @category Lang
34267     * @param {*} value The value to check.
34268     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
34269     * @example
34270     *
34271     * _.isLength(3);
34272     * // => true
34273     *
34274     * _.isLength(Number.MIN_VALUE);
34275     * // => false
34276     *
34277     * _.isLength(Infinity);
34278     * // => false
34279     *
34280     * _.isLength('3');
34281     * // => false
34282     */
34283    function isLength(value) {
34284      return typeof value == 'number' &&
34285        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
34286    }
34287
34288    /**
34289     * Checks if `value` is the
34290     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
34291     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
34292     *
34293     * @static
34294     * @memberOf _
34295     * @since 0.1.0
34296     * @category Lang
34297     * @param {*} value The value to check.
34298     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
34299     * @example
34300     *
34301     * _.isObject({});
34302     * // => true
34303     *
34304     * _.isObject([1, 2, 3]);
34305     * // => true
34306     *
34307     * _.isObject(_.noop);
34308     * // => true
34309     *
34310     * _.isObject(null);
34311     * // => false
34312     */
34313    function isObject(value) {
34314      var type = typeof value;
34315      return value != null && (type == 'object' || type == 'function');
34316    }
34317
34318    /**
34319     * Checks if `value` is object-like. A value is object-like if it's not `null`
34320     * and has a `typeof` result of "object".
34321     *
34322     * @static
34323     * @memberOf _
34324     * @since 4.0.0
34325     * @category Lang
34326     * @param {*} value The value to check.
34327     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
34328     * @example
34329     *
34330     * _.isObjectLike({});
34331     * // => true
34332     *
34333     * _.isObjectLike([1, 2, 3]);
34334     * // => true
34335     *
34336     * _.isObjectLike(_.noop);
34337     * // => false
34338     *
34339     * _.isObjectLike(null);
34340     * // => false
34341     */
34342    function isObjectLike(value) {
34343      return value != null && typeof value == 'object';
34344    }
34345
34346    /**
34347     * Checks if `value` is classified as a `Map` object.
34348     *
34349     * @static
34350     * @memberOf _
34351     * @since 4.3.0
34352     * @category Lang
34353     * @param {*} value The value to check.
34354     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
34355     * @example
34356     *
34357     * _.isMap(new Map);
34358     * // => true
34359     *
34360     * _.isMap(new WeakMap);
34361     * // => false
34362     */
34363    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
34364
34365    /**
34366     * Performs a partial deep comparison between `object` and `source` to
34367     * determine if `object` contains equivalent property values.
34368     *
34369     * **Note:** This method is equivalent to `_.matches` when `source` is
34370     * partially applied.
34371     *
34372     * Partial comparisons will match empty array and empty object `source`
34373     * values against any array or object value, respectively. See `_.isEqual`
34374     * for a list of supported value comparisons.
34375     *
34376     * @static
34377     * @memberOf _
34378     * @since 3.0.0
34379     * @category Lang
34380     * @param {Object} object The object to inspect.
34381     * @param {Object} source The object of property values to match.
34382     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
34383     * @example
34384     *
34385     * var object = { 'a': 1, 'b': 2 };
34386     *
34387     * _.isMatch(object, { 'b': 2 });
34388     * // => true
34389     *
34390     * _.isMatch(object, { 'b': 1 });
34391     * // => false
34392     */
34393    function isMatch(object, source) {
34394      return object === source || baseIsMatch(object, source, getMatchData(source));
34395    }
34396
34397    /**
34398     * This method is like `_.isMatch` except that it accepts `customizer` which
34399     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
34400     * are handled by the method instead. The `customizer` is invoked with five
34401     * arguments: (objValue, srcValue, index|key, object, source).
vendor: 12,241 bytes, lines 34402-34867
34402     *
34403     * @static
34404     * @memberOf _
34405     * @since 4.0.0
34406     * @category Lang
34407     * @param {Object} object The object to inspect.
34408     * @param {Object} source The object of property values to match.
34409     * @param {Function} [customizer] The function to customize comparisons.
34410     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
34411     * @example
34412     *
34413     * function isGreeting(value) {
34414     *   return /^h(?:i|ello)$/.test(value);
34415     * }
34416     *
34417     * function customizer(objValue, srcValue) {
34418     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
34419     *     return true;
34420     *   }
34421     * }
34422     *
34423     * var object = { 'greeting': 'hello' };
34424     * var source = { 'greeting': 'hi' };
34425     *
34426     * _.isMatchWith(object, source, customizer);
34427     * // => true
34428     */
34429    function isMatchWith(object, source, customizer) {
34430      customizer = typeof customizer == 'function' ? customizer : undefined;
34431      return baseIsMatch(object, source, getMatchData(source), customizer);
34432    }
34433
34434    /**
34435     * Checks if `value` is `NaN`.
34436     *
34437     * **Note:** This method is based on
34438     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
34439     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
34440     * `undefined` and other non-number values.
34441     *
34442     * @static
34443     * @memberOf _
34444     * @since 0.1.0
34445     * @category Lang
34446     * @param {*} value The value to check.
34447     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
34448     * @example
34449     *
34450     * _.isNaN(NaN);
34451     * // => true
34452     *
34453     * _.isNaN(new Number(NaN));
34454     * // => true
34455     *
34456     * isNaN(undefined);
34457     * // => true
34458     *
34459     * _.isNaN(undefined);
34460     * // => false
34461     */
34462    function isNaN(value) {
34463      // An `NaN` primitive is the only value that is not equal to itself.
34464      // Perform the `toStringTag` check first to avoid errors with some
34465      // ActiveX objects in IE.
34466      return isNumber(value) && value != +value;
34467    }
34468
34469    /**
34470     * Checks if `value` is a pristine native function.
34471     *
34472     * **Note:** This method can't reliably detect native functions in the presence
34473     * of the core-js package because core-js circumvents this kind of detection.
34474     * Despite multiple requests, the core-js maintainer has made it clear: any
34475     * attempt to fix the detection will be obstructed. As a result, we're left
34476     * with little choice but to throw an error. Unfortunately, this also affects
34477     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
34478     * which rely on core-js.
34479     *
34480     * @static
34481     * @memberOf _
34482     * @since 3.0.0
34483     * @category Lang
34484     * @param {*} value The value to check.
34485     * @returns {boolean} Returns `true` if `value` is a native function,
34486     *  else `false`.
34487     * @example
34488     *
34489     * _.isNative(Array.prototype.push);
34490     * // => true
34491     *
34492     * _.isNative(_);
34493     * // => false
34494     */
34495    function isNative(value) {
34496      if (isMaskable(value)) {
34497        throw new Error(CORE_ERROR_TEXT);
34498      }
34499      return baseIsNative(value);
34500    }
34501
34502    /**
34503     * Checks if `value` is `null`.
34504     *
34505     * @static
34506     * @memberOf _
34507     * @since 0.1.0
34508     * @category Lang
34509     * @param {*} value The value to check.
34510     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
34511     * @example
34512     *
34513     * _.isNull(null);
34514     * // => true
34515     *
34516     * _.isNull(void 0);
34517     * // => false
34518     */
34519    function isNull(value) {
34520      return value === null;
34521    }
34522
34523    /**
34524     * Checks if `value` is `null` or `undefined`.
34525     *
34526     * @static
34527     * @memberOf _
34528     * @since 4.0.0
34529     * @category Lang
34530     * @param {*} value The value to check.
34531     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
34532     * @example
34533     *
34534     * _.isNil(null);
34535     * // => true
34536     *
34537     * _.isNil(void 0);
34538     * // => true
34539     *
34540     * _.isNil(NaN);
34541     * // => false
34542     */
34543    function isNil(value) {
34544      return value == null;
34545    }
34546
34547    /**
34548     * Checks if `value` is classified as a `Number` primitive or object.
34549     *
34550     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
34551     * classified as numbers, use the `_.isFinite` method.
34552     *
34553     * @static
34554     * @memberOf _
34555     * @since 0.1.0
34556     * @category Lang
34557     * @param {*} value The value to check.
34558     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
34559     * @example
34560     *
34561     * _.isNumber(3);
34562     * // => true
34563     *
34564     * _.isNumber(Number.MIN_VALUE);
34565     * // => true
34566     *
34567     * _.isNumber(Infinity);
34568     * // => true
34569     *
34570     * _.isNumber('3');
34571     * // => false
34572     */
34573    function isNumber(value) {
34574      return typeof value == 'number' ||
34575        (isObjectLike(value) && baseGetTag(value) == numberTag);
34576    }
34577
34578    /**
34579     * Checks if `value` is a plain object, that is, an object created by the
34580     * `Object` constructor or one with a `[[Prototype]]` of `null`.
34581     *
34582     * @static
34583     * @memberOf _
34584     * @since 0.8.0
34585     * @category Lang
34586     * @param {*} value The value to check.
34587     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
34588     * @example
34589     *
34590     * function Foo() {
34591     *   this.a = 1;
34592     * }
34593     *
34594     * _.isPlainObject(new Foo);
34595     * // => false
34596     *
34597     * _.isPlainObject([1, 2, 3]);
34598     * // => false
34599     *
34600     * _.isPlainObject({ 'x': 0, 'y': 0 });
34601     * // => true
34602     *
34603     * _.isPlainObject(Object.create(null));
34604     * // => true
34605     */
34606    function isPlainObject(value) {
34607      if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
34608        return false;
34609      }
34610      var proto = getPrototype(value);
34611      if (proto === null) {
34612        return true;
34613      }
34614      var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
34615      return typeof Ctor == 'function' && Ctor instanceof Ctor &&
34616        funcToString.call(Ctor) == objectCtorString;
34617    }
34618
34619    /**
34620     * Checks if `value` is classified as a `RegExp` object.
34621     *
34622     * @static
34623     * @memberOf _
34624     * @since 0.1.0
34625     * @category Lang
34626     * @param {*} value The value to check.
34627     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
34628     * @example
34629     *
34630     * _.isRegExp(/abc/);
34631     * // => true
34632     *
34633     * _.isRegExp('/abc/');
34634     * // => false
34635     */
34636    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
34637
34638    /**
34639     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
34640     * double precision number which isn't the result of a rounded unsafe integer.
34641     *
34642     * **Note:** This method is based on
34643     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
34644     *
34645     * @static
34646     * @memberOf _
34647     * @since 4.0.0
34648     * @category Lang
34649     * @param {*} value The value to check.
34650     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
34651     * @example
34652     *
34653     * _.isSafeInteger(3);
34654     * // => true
34655     *
34656     * _.isSafeInteger(Number.MIN_VALUE);
34657     * // => false
34658     *
34659     * _.isSafeInteger(Infinity);
34660     * // => false
34661     *
34662     * _.isSafeInteger('3');
34663     * // => false
34664     */
34665    function isSafeInteger(value) {
34666      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
34667    }
34668
34669    /**
34670     * Checks if `value` is classified as a `Set` object.
34671     *
34672     * @static
34673     * @memberOf _
34674     * @since 4.3.0
34675     * @category Lang
34676     * @param {*} value The value to check.
34677     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
34678     * @example
34679     *
34680     * _.isSet(new Set);
34681     * // => true
34682     *
34683     * _.isSet(new WeakSet);
34684     * // => false
34685     */
34686    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
34687
34688    /**
34689     * Checks if `value` is classified as a `String` primitive or object.
34690     *
34691     * @static
34692     * @since 0.1.0
34693     * @memberOf _
34694     * @category Lang
34695     * @param {*} value The value to check.
34696     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
34697     * @example
34698     *
34699     * _.isString('abc');
34700     * // => true
34701     *
34702     * _.isString(1);
34703     * // => false
34704     */
34705    function isString(value) {
34706      return typeof value == 'string' ||
34707        (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
34708    }
34709
34710    /**
34711     * Checks if `value` is classified as a `Symbol` primitive or object.
34712     *
34713     * @static
34714     * @memberOf _
34715     * @since 4.0.0
34716     * @category Lang
34717     * @param {*} value The value to check.
34718     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
34719     * @example
34720     *
34721     * _.isSymbol(Symbol.iterator);
34722     * // => true
34723     *
34724     * _.isSymbol('abc');
34725     * // => false
34726     */
34727    function isSymbol(value) {
34728      return typeof value == 'symbol' ||
34729        (isObjectLike(value) && baseGetTag(value) == symbolTag);
34730    }
34731
34732    /**
34733     * Checks if `value` is classified as a typed array.
34734     *
34735     * @static
34736     * @memberOf _
34737     * @since 3.0.0
34738     * @category Lang
34739     * @param {*} value The value to check.
34740     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
34741     * @example
34742     *
34743     * _.isTypedArray(new Uint8Array);
34744     * // => true
34745     *
34746     * _.isTypedArray([]);
34747     * // => false
34748     */
34749    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
34750
34751    /**
34752     * Checks if `value` is `undefined`.
34753     *
34754     * @static
34755     * @since 0.1.0
34756     * @memberOf _
34757     * @category Lang
34758     * @param {*} value The value to check.
34759     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
34760     * @example
34761     *
34762     * _.isUndefined(void 0);
34763     * // => true
34764     *
34765     * _.isUndefined(null);
34766     * // => false
34767     */
34768    function isUndefined(value) {
34769      return value === undefined;
34770    }
34771
34772    /**
34773     * Checks if `value` is classified as a `WeakMap` object.
34774     *
34775     * @static
34776     * @memberOf _
34777     * @since 4.3.0
34778     * @category Lang
34779     * @param {*} value The value to check.
34780     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
34781     * @example
34782     *
34783     * _.isWeakMap(new WeakMap);
34784     * // => true
34785     *
34786     * _.isWeakMap(new Map);
34787     * // => false
34788     */
34789    function isWeakMap(value) {
34790      return isObjectLike(value) && getTag(value) == weakMapTag;
34791    }
34792
34793    /**
34794     * Checks if `value` is classified as a `WeakSet` object.
34795     *
34796     * @static
34797     * @memberOf _
34798     * @since 4.3.0
34799     * @category Lang
34800     * @param {*} value The value to check.
34801     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
34802     * @example
34803     *
34804     * _.isWeakSet(new WeakSet);
34805     * // => true
34806     *
34807     * _.isWeakSet(new Set);
34808     * // => false
34809     */
34810    function isWeakSet(value) {
34811      return isObjectLike(value) && baseGetTag(value) == weakSetTag;
34812    }
34813
34814    /**
34815     * Checks if `value` is less than `other`.
34816     *
34817     * @static
34818     * @memberOf _
34819     * @since 3.9.0
34820     * @category Lang
34821     * @param {*} value The value to compare.
34822     * @param {*} other The other value to compare.
34823     * @returns {boolean} Returns `true` if `value` is less than `other`,
34824     *  else `false`.
34825     * @see _.gt
34826     * @example
34827     *
34828     * _.lt(1, 3);
34829     * // => true
34830     *
34831     * _.lt(3, 3);
34832     * // => false
34833     *
34834     * _.lt(3, 1);
34835     * // => false
34836     */
34837    var lt = createRelationalOperation(baseLt);
34838
34839    /**
34840     * Checks if `value` is less than or equal to `other`.
34841     *
34842     * @static
34843     * @memberOf _
34844     * @since 3.9.0
34845     * @category Lang
34846     * @param {*} value The value to compare.
34847     * @param {*} other The other value to compare.
34848     * @returns {boolean} Returns `true` if `value` is less than or equal to
34849     *  `other`, else `false`.
34850     * @see _.gte
34851     * @example
34852     *
34853     * _.lte(1, 3);
34854     * // => true
34855     *
34856     * _.lte(3, 3);
34857     * // => true
34858     *
34859     * _.lte(3, 1);
34860     * // => false
34861     */
34862    var lte = createRelationalOperation(function(value, other) {
34863      return value <= other;
34864    });
34865
34866    /**
34867     * Converts `value` to an array.
vendor: 11,756 bytes, lines 34868-35297
34868     *
34869     * @static
34870     * @since 0.1.0
34871     * @memberOf _
34872     * @category Lang
34873     * @param {*} value The value to convert.
34874     * @returns {Array} Returns the converted array.
34875     * @example
34876     *
34877     * _.toArray({ 'a': 1, 'b': 2 });
34878     * // => [1, 2]
34879     *
34880     * _.toArray('abc');
34881     * // => ['a', 'b', 'c']
34882     *
34883     * _.toArray(1);
34884     * // => []
34885     *
34886     * _.toArray(null);
34887     * // => []
34888     */
34889    function toArray(value) {
34890      if (!value) {
34891        return [];
34892      }
34893      if (isArrayLike(value)) {
34894        return isString(value) ? stringToArray(value) : copyArray(value);
34895      }
34896      if (symIterator && value[symIterator]) {
34897        return iteratorToArray(value[symIterator]());
34898      }
34899      var tag = getTag(value),
34900          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
34901
34902      return func(value);
34903    }
34904
34905    /**
34906     * Converts `value` to a finite number.
34907     *
34908     * @static
34909     * @memberOf _
34910     * @since 4.12.0
34911     * @category Lang
34912     * @param {*} value The value to convert.
34913     * @returns {number} Returns the converted number.
34914     * @example
34915     *
34916     * _.toFinite(3.2);
34917     * // => 3.2
34918     *
34919     * _.toFinite(Number.MIN_VALUE);
34920     * // => 5e-324
34921     *
34922     * _.toFinite(Infinity);
34923     * // => 1.7976931348623157e+308
34924     *
34925     * _.toFinite('3.2');
34926     * // => 3.2
34927     */
34928    function toFinite(value) {
34929      if (!value) {
34930        return value === 0 ? value : 0;
34931      }
34932      value = toNumber(value);
34933      if (value === INFINITY || value === -INFINITY) {
34934        var sign = (value < 0 ? -1 : 1);
34935        return sign * MAX_INTEGER;
34936      }
34937      return value === value ? value : 0;
34938    }
34939
34940    /**
34941     * Converts `value` to an integer.
34942     *
34943     * **Note:** This method is loosely based on
34944     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
34945     *
34946     * @static
34947     * @memberOf _
34948     * @since 4.0.0
34949     * @category Lang
34950     * @param {*} value The value to convert.
34951     * @returns {number} Returns the converted integer.
34952     * @example
34953     *
34954     * _.toInteger(3.2);
34955     * // => 3
34956     *
34957     * _.toInteger(Number.MIN_VALUE);
34958     * // => 0
34959     *
34960     * _.toInteger(Infinity);
34961     * // => 1.7976931348623157e+308
34962     *
34963     * _.toInteger('3.2');
34964     * // => 3
34965     */
34966    function toInteger(value) {
34967      var result = toFinite(value),
34968          remainder = result % 1;
34969
34970      return result === result ? (remainder ? result - remainder : result) : 0;
34971    }
34972
34973    /**
34974     * Converts `value` to an integer suitable for use as the length of an
34975     * array-like object.
34976     *
34977     * **Note:** This method is based on
34978     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
34979     *
34980     * @static
34981     * @memberOf _
34982     * @since 4.0.0
34983     * @category Lang
34984     * @param {*} value The value to convert.
34985     * @returns {number} Returns the converted integer.
34986     * @example
34987     *
34988     * _.toLength(3.2);
34989     * // => 3
34990     *
34991     * _.toLength(Number.MIN_VALUE);
34992     * // => 0
34993     *
34994     * _.toLength(Infinity);
34995     * // => 4294967295
34996     *
34997     * _.toLength('3.2');
34998     * // => 3
34999     */
35000    function toLength(value) {
35001      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
35002    }
35003
35004    /**
35005     * Converts `value` to a number.
35006     *
35007     * @static
35008     * @memberOf _
35009     * @since 4.0.0
35010     * @category Lang
35011     * @param {*} value The value to process.
35012     * @returns {number} Returns the number.
35013     * @example
35014     *
35015     * _.toNumber(3.2);
35016     * // => 3.2
35017     *
35018     * _.toNumber(Number.MIN_VALUE);
35019     * // => 5e-324
35020     *
35021     * _.toNumber(Infinity);
35022     * // => Infinity
35023     *
35024     * _.toNumber('3.2');
35025     * // => 3.2
35026     */
35027    function toNumber(value) {
35028      if (typeof value == 'number') {
35029        return value;
35030      }
35031      if (isSymbol(value)) {
35032        return NAN;
35033      }
35034      if (isObject(value)) {
35035        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
35036        value = isObject(other) ? (other + '') : other;
35037      }
35038      if (typeof value != 'string') {
35039        return value === 0 ? value : +value;
35040      }
35041      value = baseTrim(value);
35042      var isBinary = reIsBinary.test(value);
35043      return (isBinary || reIsOctal.test(value))
35044        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
35045        : (reIsBadHex.test(value) ? NAN : +value);
35046    }
35047
35048    /**
35049     * Converts `value` to a plain object flattening inherited enumerable string
35050     * keyed properties of `value` to own properties of the plain object.
35051     *
35052     * @static
35053     * @memberOf _
35054     * @since 3.0.0
35055     * @category Lang
35056     * @param {*} value The value to convert.
35057     * @returns {Object} Returns the converted plain object.
35058     * @example
35059     *
35060     * function Foo() {
35061     *   this.b = 2;
35062     * }
35063     *
35064     * Foo.prototype.c = 3;
35065     *
35066     * _.assign({ 'a': 1 }, new Foo);
35067     * // => { 'a': 1, 'b': 2 }
35068     *
35069     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
35070     * // => { 'a': 1, 'b': 2, 'c': 3 }
35071     */
35072    function toPlainObject(value) {
35073      return copyObject(value, keysIn(value));
35074    }
35075
35076    /**
35077     * Converts `value` to a safe integer. A safe integer can be compared and
35078     * represented correctly.
35079     *
35080     * @static
35081     * @memberOf _
35082     * @since 4.0.0
35083     * @category Lang
35084     * @param {*} value The value to convert.
35085     * @returns {number} Returns the converted integer.
35086     * @example
35087     *
35088     * _.toSafeInteger(3.2);
35089     * // => 3
35090     *
35091     * _.toSafeInteger(Number.MIN_VALUE);
35092     * // => 0
35093     *
35094     * _.toSafeInteger(Infinity);
35095     * // => 9007199254740991
35096     *
35097     * _.toSafeInteger('3.2');
35098     * // => 3
35099     */
35100    function toSafeInteger(value) {
35101      return value
35102        ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER)
35103        : (value === 0 ? value : 0);
35104    }
35105
35106    /**
35107     * Converts `value` to a string. An empty string is returned for `null`
35108     * and `undefined` values. The sign of `-0` is preserved.
35109     *
35110     * @static
35111     * @memberOf _
35112     * @since 4.0.0
35113     * @category Lang
35114     * @param {*} value The value to convert.
35115     * @returns {string} Returns the converted string.
35116     * @example
35117     *
35118     * _.toString(null);
35119     * // => ''
35120     *
35121     * _.toString(-0);
35122     * // => '-0'
35123     *
35124     * _.toString([1, 2, 3]);
35125     * // => '1,2,3'
35126     */
35127    function toString(value) {
35128      return value == null ? '' : baseToString(value);
35129    }
35130
35131    /*------------------------------------------------------------------------*/
35132
35133    /**
35134     * Assigns own enumerable string keyed properties of source objects to the
35135     * destination object. Source objects are applied from left to right.
35136     * Subsequent sources overwrite property assignments of previous sources.
35137     *
35138     * **Note:** This method mutates `object` and is loosely based on
35139     * [`Object.assign`](https://mdn.io/Object/assign).
35140     *
35141     * @static
35142     * @memberOf _
35143     * @since 0.10.0
35144     * @category Object
35145     * @param {Object} object The destination object.
35146     * @param {...Object} [sources] The source objects.
35147     * @returns {Object} Returns `object`.
35148     * @see _.assignIn
35149     * @example
35150     *
35151     * function Foo() {
35152     *   this.a = 1;
35153     * }
35154     *
35155     * function Bar() {
35156     *   this.c = 3;
35157     * }
35158     *
35159     * Foo.prototype.b = 2;
35160     * Bar.prototype.d = 4;
35161     *
35162     * _.assign({ 'a': 0 }, new Foo, new Bar);
35163     * // => { 'a': 1, 'c': 3 }
35164     */
35165    var assign = createAssigner(function(object, source) {
35166      if (isPrototype(source) || isArrayLike(source)) {
35167        copyObject(source, keys(source), object);
35168        return;
35169      }
35170      for (var key in source) {
35171        if (hasOwnProperty.call(source, key)) {
35172          assignValue(object, key, source[key]);
35173        }
35174      }
35175    });
35176
35177    /**
35178     * This method is like `_.assign` except that it iterates over own and
35179     * inherited source properties.
35180     *
35181     * **Note:** This method mutates `object`.
35182     *
35183     * @static
35184     * @memberOf _
35185     * @since 4.0.0
35186     * @alias extend
35187     * @category Object
35188     * @param {Object} object The destination object.
35189     * @param {...Object} [sources] The source objects.
35190     * @returns {Object} Returns `object`.
35191     * @see _.assign
35192     * @example
35193     *
35194     * function Foo() {
35195     *   this.a = 1;
35196     * }
35197     *
35198     * function Bar() {
35199     *   this.c = 3;
35200     * }
35201     *
35202     * Foo.prototype.b = 2;
35203     * Bar.prototype.d = 4;
35204     *
35205     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
35206     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
35207     */
35208    var assignIn = createAssigner(function(object, source) {
35209      copyObject(source, keysIn(source), object);
35210    });
35211
35212    /**
35213     * This method is like `_.assignIn` except that it accepts `customizer`
35214     * which is invoked to produce the assigned values. If `customizer` returns
35215     * `undefined`, assignment is handled by the method instead. The `customizer`
35216     * is invoked with five arguments: (objValue, srcValue, key, object, source).
35217     *
35218     * **Note:** This method mutates `object`.
35219     *
35220     * @static
35221     * @memberOf _
35222     * @since 4.0.0
35223     * @alias extendWith
35224     * @category Object
35225     * @param {Object} object The destination object.
35226     * @param {...Object} sources The source objects.
35227     * @param {Function} [customizer] The function to customize assigned values.
35228     * @returns {Object} Returns `object`.
35229     * @see _.assignWith
35230     * @example
35231     *
35232     * function customizer(objValue, srcValue) {
35233     *   return _.isUndefined(objValue) ? srcValue : objValue;
35234     * }
35235     *
35236     * var defaults = _.partialRight(_.assignInWith, customizer);
35237     *
35238     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
35239     * // => { 'a': 1, 'b': 2 }
35240     */
35241    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
35242      copyObject(source, keysIn(source), object, customizer);
35243    });
35244
35245    /**
35246     * This method is like `_.assign` except that it accepts `customizer`
35247     * which is invoked to produce the assigned values. If `customizer` returns
35248     * `undefined`, assignment is handled by the method instead. The `customizer`
35249     * is invoked with five arguments: (objValue, srcValue, key, object, source).
35250     *
35251     * **Note:** This method mutates `object`.
35252     *
35253     * @static
35254     * @memberOf _
35255     * @since 4.0.0
35256     * @category Object
35257     * @param {Object} object The destination object.
35258     * @param {...Object} sources The source objects.
35259     * @param {Function} [customizer] The function to customize assigned values.
35260     * @returns {Object} Returns `object`.
35261     * @see _.assignInWith
35262     * @example
35263     *
35264     * function customizer(objValue, srcValue) {
35265     *   return _.isUndefined(objValue) ? srcValue : objValue;
35266     * }
35267     *
35268     * var defaults = _.partialRight(_.assignWith, customizer);
35269     *
35270     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
35271     * // => { 'a': 1, 'b': 2 }
35272     */
35273    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
35274      copyObject(source, keys(source), object, customizer);
35275    });
35276
35277    /**
35278     * Creates an array of values corresponding to `paths` of `object`.
35279     *
35280     * @static
35281     * @memberOf _
35282     * @since 1.0.0
35283     * @category Object
35284     * @param {Object} object The object to iterate over.
35285     * @param {...(string|string[])} [paths] The property paths to pick.
35286     * @returns {Array} Returns the picked values.
35287     * @example
35288     *
35289     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
35290     *
35291     * _.at(object, ['a[0].b.c', 'a[1]']);
35292     * // => [3, 4]
35293     */
35294    var at = flatRest(baseAt);
35295
35296    /**
35297     * Creates an object that inherits from the `prototype` object. If a
vendor: 13,619 bytes, lines 35298-35762
35298     * `properties` object is given, its own enumerable string keyed properties
35299     * are assigned to the created object.
35300     *
35301     * @static
35302     * @memberOf _
35303     * @since 2.3.0
35304     * @category Object
35305     * @param {Object} prototype The object to inherit from.
35306     * @param {Object} [properties] The properties to assign to the object.
35307     * @returns {Object} Returns the new object.
35308     * @example
35309     *
35310     * function Shape() {
35311     *   this.x = 0;
35312     *   this.y = 0;
35313     * }
35314     *
35315     * function Circle() {
35316     *   Shape.call(this);
35317     * }
35318     *
35319     * Circle.prototype = _.create(Shape.prototype, {
35320     *   'constructor': Circle
35321     * });
35322     *
35323     * var circle = new Circle;
35324     * circle instanceof Circle;
35325     * // => true
35326     *
35327     * circle instanceof Shape;
35328     * // => true
35329     */
35330    function create(prototype, properties) {
35331      var result = baseCreate(prototype);
35332      return properties == null ? result : baseAssign(result, properties);
35333    }
35334
35335    /**
35336     * Assigns own and inherited enumerable string keyed properties of source
35337     * objects to the destination object for all destination properties that
35338     * resolve to `undefined`. Source objects are applied from left to right.
35339     * Once a property is set, additional values of the same property are ignored.
35340     *
35341     * **Note:** This method mutates `object`.
35342     *
35343     * @static
35344     * @since 0.1.0
35345     * @memberOf _
35346     * @category Object
35347     * @param {Object} object The destination object.
35348     * @param {...Object} [sources] The source objects.
35349     * @returns {Object} Returns `object`.
35350     * @see _.defaultsDeep
35351     * @example
35352     *
35353     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
35354     * // => { 'a': 1, 'b': 2 }
35355     */
35356    var defaults = baseRest(function(object, sources) {
35357      object = Object(object);
35358
35359      var index = -1;
35360      var length = sources.length;
35361      var guard = length > 2 ? sources[2] : undefined;
35362
35363      if (guard && isIterateeCall(sources[0], sources[1], guard)) {
35364        length = 1;
35365      }
35366
35367      while (++index < length) {
35368        var source = sources[index];
35369        var props = keysIn(source);
35370        var propsIndex = -1;
35371        var propsLength = props.length;
35372
35373        while (++propsIndex < propsLength) {
35374          var key = props[propsIndex];
35375          var value = object[key];
35376
35377          if (value === undefined ||
35378              (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) {
35379            object[key] = source[key];
35380          }
35381        }
35382      }
35383
35384      return object;
35385    });
35386
35387    /**
35388     * This method is like `_.defaults` except that it recursively assigns
35389     * default properties.
35390     *
35391     * **Note:** This method mutates `object`.
35392     *
35393     * @static
35394     * @memberOf _
35395     * @since 3.10.0
35396     * @category Object
35397     * @param {Object} object The destination object.
35398     * @param {...Object} [sources] The source objects.
35399     * @returns {Object} Returns `object`.
35400     * @see _.defaults
35401     * @example
35402     *
35403     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
35404     * // => { 'a': { 'b': 2, 'c': 3 } }
35405     */
35406    var defaultsDeep = baseRest(function(args) {
35407      args.push(undefined, customDefaultsMerge);
35408      return apply(mergeWith, undefined, args);
35409    });
35410
35411    /**
35412     * This method is like `_.find` except that it returns the key of the first
35413     * element `predicate` returns truthy for instead of the element itself.
35414     *
35415     * @static
35416     * @memberOf _
35417     * @since 1.1.0
35418     * @category Object
35419     * @param {Object} object The object to inspect.
35420     * @param {Function} [predicate=_.identity] The function invoked per iteration.
35421     * @returns {string|undefined} Returns the key of the matched element,
35422     *  else `undefined`.
35423     * @example
35424     *
35425     * var users = {
35426     *   'barney':  { 'age': 36, 'active': true },
35427     *   'fred':    { 'age': 40, 'active': false },
35428     *   'pebbles': { 'age': 1,  'active': true }
35429     * };
35430     *
35431     * _.findKey(users, function(o) { return o.age < 40; });
35432     * // => 'barney' (iteration order is not guaranteed)
35433     *
35434     * // The `_.matches` iteratee shorthand.
35435     * _.findKey(users, { 'age': 1, 'active': true });
35436     * // => 'pebbles'
35437     *
35438     * // The `_.matchesProperty` iteratee shorthand.
35439     * _.findKey(users, ['active', false]);
35440     * // => 'fred'
35441     *
35442     * // The `_.property` iteratee shorthand.
35443     * _.findKey(users, 'active');
35444     * // => 'barney'
35445     */
35446    function findKey(object, predicate) {
35447      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
35448    }
35449
35450    /**
35451     * This method is like `_.findKey` except that it iterates over elements of
35452     * a collection in the opposite order.
35453     *
35454     * @static
35455     * @memberOf _
35456     * @since 2.0.0
35457     * @category Object
35458     * @param {Object} object The object to inspect.
35459     * @param {Function} [predicate=_.identity] The function invoked per iteration.
35460     * @returns {string|undefined} Returns the key of the matched element,
35461     *  else `undefined`.
35462     * @example
35463     *
35464     * var users = {
35465     *   'barney':  { 'age': 36, 'active': true },
35466     *   'fred':    { 'age': 40, 'active': false },
35467     *   'pebbles': { 'age': 1,  'active': true }
35468     * };
35469     *
35470     * _.findLastKey(users, function(o) { return o.age < 40; });
35471     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
35472     *
35473     * // The `_.matches` iteratee shorthand.
35474     * _.findLastKey(users, { 'age': 36, 'active': true });
35475     * // => 'barney'
35476     *
35477     * // The `_.matchesProperty` iteratee shorthand.
35478     * _.findLastKey(users, ['active', false]);
35479     * // => 'fred'
35480     *
35481     * // The `_.property` iteratee shorthand.
35482     * _.findLastKey(users, 'active');
35483     * // => 'pebbles'
35484     */
35485    function findLastKey(object, predicate) {
35486      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
35487    }
35488
35489    /**
35490     * Iterates over own and inherited enumerable string keyed properties of an
35491     * object and invokes `iteratee` for each property. The iteratee is invoked
35492     * with three arguments: (value, key, object). Iteratee functions may exit
35493     * iteration early by explicitly returning `false`.
35494     *
35495     * @static
35496     * @memberOf _
35497     * @since 0.3.0
35498     * @category Object
35499     * @param {Object} object The object to iterate over.
35500     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
35501     * @returns {Object} Returns `object`.
35502     * @see _.forInRight
35503     * @example
35504     *
35505     * function Foo() {
35506     *   this.a = 1;
35507     *   this.b = 2;
35508     * }
35509     *
35510     * Foo.prototype.c = 3;
35511     *
35512     * _.forIn(new Foo, function(value, key) {
35513     *   console.log(key);
35514     * });
35515     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
35516     */
35517    function forIn(object, iteratee) {
35518      return object == null
35519        ? object
35520        : baseFor(object, getIteratee(iteratee, 3), keysIn);
35521    }
35522
35523    /**
35524     * This method is like `_.forIn` except that it iterates over properties of
35525     * `object` in the opposite order.
35526     *
35527     * @static
35528     * @memberOf _
35529     * @since 2.0.0
35530     * @category Object
35531     * @param {Object} object The object to iterate over.
35532     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
35533     * @returns {Object} Returns `object`.
35534     * @see _.forIn
35535     * @example
35536     *
35537     * function Foo() {
35538     *   this.a = 1;
35539     *   this.b = 2;
35540     * }
35541     *
35542     * Foo.prototype.c = 3;
35543     *
35544     * _.forInRight(new Foo, function(value, key) {
35545     *   console.log(key);
35546     * });
35547     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
35548     */
35549    function forInRight(object, iteratee) {
35550      return object == null
35551        ? object
35552        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
35553    }
35554
35555    /**
35556     * Iterates over own enumerable string keyed properties of an object and
35557     * invokes `iteratee` for each property. The iteratee is invoked with three
35558     * arguments: (value, key, object). Iteratee functions may exit iteration
35559     * early by explicitly returning `false`.
35560     *
35561     * @static
35562     * @memberOf _
35563     * @since 0.3.0
35564     * @category Object
35565     * @param {Object} object The object to iterate over.
35566     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
35567     * @returns {Object} Returns `object`.
35568     * @see _.forOwnRight
35569     * @example
35570     *
35571     * function Foo() {
35572     *   this.a = 1;
35573     *   this.b = 2;
35574     * }
35575     *
35576     * Foo.prototype.c = 3;
35577     *
35578     * _.forOwn(new Foo, function(value, key) {
35579     *   console.log(key);
35580     * });
35581     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
35582     */
35583    function forOwn(object, iteratee) {
35584      return object && baseForOwn(object, getIteratee(iteratee, 3));
35585    }
35586
35587    /**
35588     * This method is like `_.forOwn` except that it iterates over properties of
35589     * `object` in the opposite order.
35590     *
35591     * @static
35592     * @memberOf _
35593     * @since 2.0.0
35594     * @category Object
35595     * @param {Object} object The object to iterate over.
35596     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
35597     * @returns {Object} Returns `object`.
35598     * @see _.forOwn
35599     * @example
35600     *
35601     * function Foo() {
35602     *   this.a = 1;
35603     *   this.b = 2;
35604     * }
35605     *
35606     * Foo.prototype.c = 3;
35607     *
35608     * _.forOwnRight(new Foo, function(value, key) {
35609     *   console.log(key);
35610     * });
35611     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
35612     */
35613    function forOwnRight(object, iteratee) {
35614      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
35615    }
35616
35617    /**
35618     * Creates an array of function property names from own enumerable properties
35619     * of `object`.
35620     *
35621     * @static
35622     * @since 0.1.0
35623     * @memberOf _
35624     * @category Object
35625     * @param {Object} object The object to inspect.
35626     * @returns {Array} Returns the function names.
35627     * @see _.functionsIn
35628     * @example
35629     *
35630     * function Foo() {
35631     *   this.a = _.constant('a');
35632     *   this.b = _.constant('b');
35633     * }
35634     *
35635     * Foo.prototype.c = _.constant('c');
35636     *
35637     * _.functions(new Foo);
35638     * // => ['a', 'b']
35639     */
35640    function functions(object) {
35641      return object == null ? [] : baseFunctions(object, keys(object));
35642    }
35643
35644    /**
35645     * Creates an array of function property names from own and inherited
35646     * enumerable properties of `object`.
35647     *
35648     * @static
35649     * @memberOf _
35650     * @since 4.0.0
35651     * @category Object
35652     * @param {Object} object The object to inspect.
35653     * @returns {Array} Returns the function names.
35654     * @see _.functions
35655     * @example
35656     *
35657     * function Foo() {
35658     *   this.a = _.constant('a');
35659     *   this.b = _.constant('b');
35660     * }
35661     *
35662     * Foo.prototype.c = _.constant('c');
35663     *
35664     * _.functionsIn(new Foo);
35665     * // => ['a', 'b', 'c']
35666     */
35667    function functionsIn(object) {
35668      return object == null ? [] : baseFunctions(object, keysIn(object));
35669    }
35670
35671    /**
35672     * Gets the value at `path` of `object`. If the resolved value is
35673     * `undefined`, the `defaultValue` is returned in its place.
35674     *
35675     * @static
35676     * @memberOf _
35677     * @since 3.7.0
35678     * @category Object
35679     * @param {Object} object The object to query.
35680     * @param {Array|string} path The path of the property to get.
35681     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
35682     * @returns {*} Returns the resolved value.
35683     * @example
35684     *
35685     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
35686     *
35687     * _.get(object, 'a[0].b.c');
35688     * // => 3
35689     *
35690     * _.get(object, ['a', '0', 'b', 'c']);
35691     * // => 3
35692     *
35693     * _.get(object, 'a.b.c', 'default');
35694     * // => 'default'
35695     */
35696    function get(object, path, defaultValue) {
35697      var result = object == null ? undefined : baseGet(object, path);
35698      return result === undefined ? defaultValue : result;
35699    }
35700
35701    /**
35702     * Checks if `path` is a direct property of `object`.
35703     *
35704     * @static
35705     * @since 0.1.0
35706     * @memberOf _
35707     * @category Object
35708     * @param {Object} object The object to query.
35709     * @param {Array|string} path The path to check.
35710     * @returns {boolean} Returns `true` if `path` exists, else `false`.
35711     * @example
35712     *
35713     * var object = { 'a': { 'b': 2 } };
35714     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
35715     *
35716     * _.has(object, 'a');
35717     * // => true
35718     *
35719     * _.has(object, 'a.b');
35720     * // => true
35721     *
35722     * _.has(object, ['a', 'b']);
35723     * // => true
35724     *
35725     * _.has(other, 'a');
35726     * // => false
35727     */
35728    function has(object, path) {
35729      return object != null && hasPath(object, path, baseHas);
35730    }
35731
35732    /**
35733     * Checks if `path` is a direct or inherited property of `object`.
35734     *
35735     * @static
35736     * @memberOf _
35737     * @since 4.0.0
35738     * @category Object
35739     * @param {Object} object The object to query.
35740     * @param {Array|string} path The path to check.
35741     * @returns {boolean} Returns `true` if `path` exists, else `false`.
35742     * @example
35743     *
35744     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
35745     *
35746     * _.hasIn(object, 'a');
35747     * // => true
35748     *
35749     * _.hasIn(object, 'a.b');
35750     * // => true
35751     *
35752     * _.hasIn(object, ['a', 'b']);
35753     * // => true
35754     *
35755     * _.hasIn(object, 'b');
35756     * // => false
35757     */
35758    function hasIn(object, path) {
35759      return object != null && hasPath(object, path, baseHasIn);
35760    }
35761
35762    /**
vendor: 11,848 bytes, lines 35763-36133
35763     * Creates an object composed of the inverted keys and values of `object`.
35764     * If `object` contains duplicate values, subsequent values overwrite
35765     * property assignments of previous values.
35766     *
35767     * @static
35768     * @memberOf _
35769     * @since 0.7.0
35770     * @category Object
35771     * @param {Object} object The object to invert.
35772     * @returns {Object} Returns the new inverted object.
35773     * @example
35774     *
35775     * var object = { 'a': 1, 'b': 2, 'c': 1 };
35776     *
35777     * _.invert(object);
35778     * // => { '1': 'c', '2': 'b' }
35779     */
35780    var invert = createInverter(function(result, value, key) {
35781      if (value != null &&
35782          typeof value.toString != 'function') {
35783        value = nativeObjectToString.call(value);
35784      }
35785
35786      result[value] = key;
35787    }, constant(identity));
35788
35789    /**
35790     * This method is like `_.invert` except that the inverted object is generated
35791     * from the results of running each element of `object` thru `iteratee`. The
35792     * corresponding inverted value of each inverted key is an array of keys
35793     * responsible for generating the inverted value. The iteratee is invoked
35794     * with one argument: (value).
35795     *
35796     * @static
35797     * @memberOf _
35798     * @since 4.1.0
35799     * @category Object
35800     * @param {Object} object The object to invert.
35801     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
35802     * @returns {Object} Returns the new inverted object.
35803     * @example
35804     *
35805     * var object = { 'a': 1, 'b': 2, 'c': 1 };
35806     *
35807     * _.invertBy(object);
35808     * // => { '1': ['a', 'c'], '2': ['b'] }
35809     *
35810     * _.invertBy(object, function(value) {
35811     *   return 'group' + value;
35812     * });
35813     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
35814     */
35815    var invertBy = createInverter(function(result, value, key) {
35816      if (value != null &&
35817          typeof value.toString != 'function') {
35818        value = nativeObjectToString.call(value);
35819      }
35820
35821      if (hasOwnProperty.call(result, value)) {
35822        result[value].push(key);
35823      } else {
35824        result[value] = [key];
35825      }
35826    }, getIteratee);
35827
35828    /**
35829     * Invokes the method at `path` of `object`.
35830     *
35831     * @static
35832     * @memberOf _
35833     * @since 4.0.0
35834     * @category Object
35835     * @param {Object} object The object to query.
35836     * @param {Array|string} path The path of the method to invoke.
35837     * @param {...*} [args] The arguments to invoke the method with.
35838     * @returns {*} Returns the result of the invoked method.
35839     * @example
35840     *
35841     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
35842     *
35843     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
35844     * // => [2, 3]
35845     */
35846    var invoke = baseRest(baseInvoke);
35847
35848    /**
35849     * Creates an array of the own enumerable property names of `object`.
35850     *
35851     * **Note:** Non-object values are coerced to objects. See the
35852     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
35853     * for more details.
35854     *
35855     * @static
35856     * @since 0.1.0
35857     * @memberOf _
35858     * @category Object
35859     * @param {Object} object The object to query.
35860     * @returns {Array} Returns the array of property names.
35861     * @example
35862     *
35863     * function Foo() {
35864     *   this.a = 1;
35865     *   this.b = 2;
35866     * }
35867     *
35868     * Foo.prototype.c = 3;
35869     *
35870     * _.keys(new Foo);
35871     * // => ['a', 'b'] (iteration order is not guaranteed)
35872     *
35873     * _.keys('hi');
35874     * // => ['0', '1']
35875     */
35876    function keys(object) {
35877      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
35878    }
35879
35880    /**
35881     * Creates an array of the own and inherited enumerable property names of `object`.
35882     *
35883     * **Note:** Non-object values are coerced to objects.
35884     *
35885     * @static
35886     * @memberOf _
35887     * @since 3.0.0
35888     * @category Object
35889     * @param {Object} object The object to query.
35890     * @returns {Array} Returns the array of property names.
35891     * @example
35892     *
35893     * function Foo() {
35894     *   this.a = 1;
35895     *   this.b = 2;
35896     * }
35897     *
35898     * Foo.prototype.c = 3;
35899     *
35900     * _.keysIn(new Foo);
35901     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
35902     */
35903    function keysIn(object) {
35904      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
35905    }
35906
35907    /**
35908     * The opposite of `_.mapValues`; this method creates an object with the
35909     * same values as `object` and keys generated by running each own enumerable
35910     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
35911     * with three arguments: (value, key, object).
35912     *
35913     * @static
35914     * @memberOf _
35915     * @since 3.8.0
35916     * @category Object
35917     * @param {Object} object The object to iterate over.
35918     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
35919     * @returns {Object} Returns the new mapped object.
35920     * @see _.mapValues
35921     * @example
35922     *
35923     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
35924     *   return key + value;
35925     * });
35926     * // => { 'a1': 1, 'b2': 2 }
35927     */
35928    function mapKeys(object, iteratee) {
35929      var result = {};
35930      iteratee = getIteratee(iteratee, 3);
35931
35932      baseForOwn(object, function(value, key, object) {
35933        baseAssignValue(result, iteratee(value, key, object), value);
35934      });
35935      return result;
35936    }
35937
35938    /**
35939     * Creates an object with the same keys as `object` and values generated
35940     * by running each own enumerable string keyed property of `object` thru
35941     * `iteratee`. The iteratee is invoked with three arguments:
35942     * (value, key, object).
35943     *
35944     * @static
35945     * @memberOf _
35946     * @since 2.4.0
35947     * @category Object
35948     * @param {Object} object The object to iterate over.
35949     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
35950     * @returns {Object} Returns the new mapped object.
35951     * @see _.mapKeys
35952     * @example
35953     *
35954     * var users = {
35955     *   'fred':    { 'user': 'fred',    'age': 40 },
35956     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
35957     * };
35958     *
35959     * _.mapValues(users, function(o) { return o.age; });
35960     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
35961     *
35962     * // The `_.property` iteratee shorthand.
35963     * _.mapValues(users, 'age');
35964     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
35965     */
35966    function mapValues(object, iteratee) {
35967      var result = {};
35968      iteratee = getIteratee(iteratee, 3);
35969
35970      baseForOwn(object, function(value, key, object) {
35971        baseAssignValue(result, key, iteratee(value, key, object));
35972      });
35973      return result;
35974    }
35975
35976    /**
35977     * This method is like `_.assign` except that it recursively merges own and
35978     * inherited enumerable string keyed properties of source objects into the
35979     * destination object. Source properties that resolve to `undefined` are
35980     * skipped if a destination value exists. Array and plain object properties
35981     * are merged recursively. Other objects and value types are overridden by
35982     * assignment. Source objects are applied from left to right. Subsequent
35983     * sources overwrite property assignments of previous sources.
35984     *
35985     * **Note:** This method mutates `object`.
35986     *
35987     * @static
35988     * @memberOf _
35989     * @since 0.5.0
35990     * @category Object
35991     * @param {Object} object The destination object.
35992     * @param {...Object} [sources] The source objects.
35993     * @returns {Object} Returns `object`.
35994     * @example
35995     *
35996     * var object = {
35997     *   'a': [{ 'b': 2 }, { 'd': 4 }]
35998     * };
35999     *
36000     * var other = {
36001     *   'a': [{ 'c': 3 }, { 'e': 5 }]
36002     * };
36003     *
36004     * _.merge(object, other);
36005     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
36006     */
36007    var merge = createAssigner(function(object, source, srcIndex) {
36008      baseMerge(object, source, srcIndex);
36009    });
36010
36011    /**
36012     * This method is like `_.merge` except that it accepts `customizer` which
36013     * is invoked to produce the merged values of the destination and source
36014     * properties. If `customizer` returns `undefined`, merging is handled by the
36015     * method instead. The `customizer` is invoked with six arguments:
36016     * (objValue, srcValue, key, object, source, stack).
36017     *
36018     * **Note:** This method mutates `object`.
36019     *
36020     * @static
36021     * @memberOf _
36022     * @since 4.0.0
36023     * @category Object
36024     * @param {Object} object The destination object.
36025     * @param {...Object} sources The source objects.
36026     * @param {Function} customizer The function to customize assigned values.
36027     * @returns {Object} Returns `object`.
36028     * @example
36029     *
36030     * function customizer(objValue, srcValue) {
36031     *   if (_.isArray(objValue)) {
36032     *     return objValue.concat(srcValue);
36033     *   }
36034     * }
36035     *
36036     * var object = { 'a': [1], 'b': [2] };
36037     * var other = { 'a': [3], 'b': [4] };
36038     *
36039     * _.mergeWith(object, other, customizer);
36040     * // => { 'a': [1, 3], 'b': [2, 4] }
36041     */
36042    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
36043      baseMerge(object, source, srcIndex, customizer);
36044    });
36045
36046    /**
36047     * The opposite of `_.pick`; this method creates an object composed of the
36048     * own and inherited enumerable property paths of `object` that are not omitted.
36049     *
36050     * **Note:** This method is considerably slower than `_.pick`.
36051     *
36052     * @static
36053     * @since 0.1.0
36054     * @memberOf _
36055     * @category Object
36056     * @param {Object} object The source object.
36057     * @param {...(string|string[])} [paths] The property paths to omit.
36058     * @returns {Object} Returns the new object.
36059     * @example
36060     *
36061     * var object = { 'a': 1, 'b': '2', 'c': 3 };
36062     *
36063     * _.omit(object, ['a', 'c']);
36064     * // => { 'b': '2' }
36065     */
36066    var omit = flatRest(function(object, paths) {
36067      var result = {};
36068      if (object == null) {
36069        return result;
36070      }
36071      var isDeep = false;
36072      paths = arrayMap(paths, function(path) {
36073        path = castPath(path, object);
36074        isDeep || (isDeep = path.length > 1);
36075        return path;
36076      });
36077      copyObject(object, getAllKeysIn(object), result);
36078      if (isDeep) {
36079        result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
36080      }
36081      var length = paths.length;
36082      while (length--) {
36083        baseUnset(result, paths[length]);
36084      }
36085      return result;
36086    });
36087
36088    /**
36089     * The opposite of `_.pickBy`; this method creates an object composed of
36090     * the own and inherited enumerable string keyed properties of `object` that
36091     * `predicate` doesn't return truthy for. The predicate is invoked with two
36092     * arguments: (value, key).
36093     *
36094     * @static
36095     * @memberOf _
36096     * @since 4.0.0
36097     * @category Object
36098     * @param {Object} object The source object.
36099     * @param {Function} [predicate=_.identity] The function invoked per property.
36100     * @returns {Object} Returns the new object.
36101     * @example
36102     *
36103     * var object = { 'a': 1, 'b': '2', 'c': 3 };
36104     *
36105     * _.omitBy(object, _.isNumber);
36106     * // => { 'b': '2' }
36107     */
36108    function omitBy(object, predicate) {
36109      return pickBy(object, negate(getIteratee(predicate)));
36110    }
36111
36112    /**
36113     * Creates an object composed of the picked `object` properties.
36114     *
36115     * @static
36116     * @since 0.1.0
36117     * @memberOf _
36118     * @category Object
36119     * @param {Object} object The source object.
36120     * @param {...(string|string[])} [paths] The property paths to pick.
36121     * @returns {Object} Returns the new object.
36122     * @example
36123     *
36124     * var object = { 'a': 1, 'b': '2', 'c': 3 };
36125     *
36126     * _.pick(object, ['a', 'c']);
36127     * // => { 'a': 1, 'c': 3 }
36128     */
36129    var pick = flatRest(function(object, paths) {
36130      return object == null ? {} : basePick(object, paths);
36131    });
36132
36133    /**
vendor: 11,160 bytes, lines 36134-36472
36134     * Creates an object composed of the `object` properties `predicate` returns
36135     * truthy for. The predicate is invoked with two arguments: (value, key).
36136     *
36137     * @static
36138     * @memberOf _
36139     * @since 4.0.0
36140     * @category Object
36141     * @param {Object} object The source object.
36142     * @param {Function} [predicate=_.identity] The function invoked per property.
36143     * @returns {Object} Returns the new object.
36144     * @example
36145     *
36146     * var object = { 'a': 1, 'b': '2', 'c': 3 };
36147     *
36148     * _.pickBy(object, _.isNumber);
36149     * // => { 'a': 1, 'c': 3 }
36150     */
36151    function pickBy(object, predicate) {
36152      if (object == null) {
36153        return {};
36154      }
36155      var props = arrayMap(getAllKeysIn(object), function(prop) {
36156        return [prop];
36157      });
36158      predicate = getIteratee(predicate);
36159      return basePickBy(object, props, function(value, path) {
36160        return predicate(value, path[0]);
36161      });
36162    }
36163
36164    /**
36165     * This method is like `_.get` except that if the resolved value is a
36166     * function it's invoked with the `this` binding of its parent object and
36167     * its result is returned.
36168     *
36169     * @static
36170     * @since 0.1.0
36171     * @memberOf _
36172     * @category Object
36173     * @param {Object} object The object to query.
36174     * @param {Array|string} path The path of the property to resolve.
36175     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
36176     * @returns {*} Returns the resolved value.
36177     * @example
36178     *
36179     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
36180     *
36181     * _.result(object, 'a[0].b.c1');
36182     * // => 3
36183     *
36184     * _.result(object, 'a[0].b.c2');
36185     * // => 4
36186     *
36187     * _.result(object, 'a[0].b.c3', 'default');
36188     * // => 'default'
36189     *
36190     * _.result(object, 'a[0].b.c3', _.constant('default'));
36191     * // => 'default'
36192     */
36193    function result(object, path, defaultValue) {
36194      path = castPath(path, object);
36195
36196      var index = -1,
36197          length = path.length;
36198
36199      // Ensure the loop is entered when path is empty.
36200      if (!length) {
36201        length = 1;
36202        object = undefined;
36203      }
36204      while (++index < length) {
36205        var value = object == null ? undefined : object[toKey(path[index])];
36206        if (value === undefined) {
36207          index = length;
36208          value = defaultValue;
36209        }
36210        object = isFunction(value) ? value.call(object) : value;
36211      }
36212      return object;
36213    }
36214
36215    /**
36216     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
36217     * it's created. Arrays are created for missing index properties while objects
36218     * are created for all other missing properties. Use `_.setWith` to customize
36219     * `path` creation.
36220     *
36221     * **Note:** This method mutates `object`.
36222     *
36223     * @static
36224     * @memberOf _
36225     * @since 3.7.0
36226     * @category Object
36227     * @param {Object} object The object to modify.
36228     * @param {Array|string} path The path of the property to set.
36229     * @param {*} value The value to set.
36230     * @returns {Object} Returns `object`.
36231     * @example
36232     *
36233     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
36234     *
36235     * _.set(object, 'a[0].b.c', 4);
36236     * console.log(object.a[0].b.c);
36237     * // => 4
36238     *
36239     * _.set(object, ['x', '0', 'y', 'z'], 5);
36240     * console.log(object.x[0].y.z);
36241     * // => 5
36242     */
36243    function set(object, path, value) {
36244      return object == null ? object : baseSet(object, path, value);
36245    }
36246
36247    /**
36248     * This method is like `_.set` except that it accepts `customizer` which is
36249     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
36250     * path creation is handled by the method instead. The `customizer` is invoked
36251     * with three arguments: (nsValue, key, nsObject).
36252     *
36253     * **Note:** This method mutates `object`.
36254     *
36255     * @static
36256     * @memberOf _
36257     * @since 4.0.0
36258     * @category Object
36259     * @param {Object} object The object to modify.
36260     * @param {Array|string} path The path of the property to set.
36261     * @param {*} value The value to set.
36262     * @param {Function} [customizer] The function to customize assigned values.
36263     * @returns {Object} Returns `object`.
36264     * @example
36265     *
36266     * var object = {};
36267     *
36268     * _.setWith(object, '[0][1]', 'a', Object);
36269     * // => { '0': { '1': 'a' } }
36270     */
36271    function setWith(object, path, value, customizer) {
36272      customizer = typeof customizer == 'function' ? customizer : undefined;
36273      return object == null ? object : baseSet(object, path, value, customizer);
36274    }
36275
36276    /**
36277     * Creates an array of own enumerable string keyed-value pairs for `object`
36278     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
36279     * entries are returned.
36280     *
36281     * @static
36282     * @memberOf _
36283     * @since 4.0.0
36284     * @alias entries
36285     * @category Object
36286     * @param {Object} object The object to query.
36287     * @returns {Array} Returns the key-value pairs.
36288     * @example
36289     *
36290     * function Foo() {
36291     *   this.a = 1;
36292     *   this.b = 2;
36293     * }
36294     *
36295     * Foo.prototype.c = 3;
36296     *
36297     * _.toPairs(new Foo);
36298     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
36299     */
36300    var toPairs = createToPairs(keys);
36301
36302    /**
36303     * Creates an array of own and inherited enumerable string keyed-value pairs
36304     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
36305     * or set, its entries are returned.
36306     *
36307     * @static
36308     * @memberOf _
36309     * @since 4.0.0
36310     * @alias entriesIn
36311     * @category Object
36312     * @param {Object} object The object to query.
36313     * @returns {Array} Returns the key-value pairs.
36314     * @example
36315     *
36316     * function Foo() {
36317     *   this.a = 1;
36318     *   this.b = 2;
36319     * }
36320     *
36321     * Foo.prototype.c = 3;
36322     *
36323     * _.toPairsIn(new Foo);
36324     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
36325     */
36326    var toPairsIn = createToPairs(keysIn);
36327
36328    /**
36329     * An alternative to `_.reduce`; this method transforms `object` to a new
36330     * `accumulator` object which is the result of running each of its own
36331     * enumerable string keyed properties thru `iteratee`, with each invocation
36332     * potentially mutating the `accumulator` object. If `accumulator` is not
36333     * provided, a new object with the same `[[Prototype]]` will be used. The
36334     * iteratee is invoked with four arguments: (accumulator, value, key, object).
36335     * Iteratee functions may exit iteration early by explicitly returning `false`.
36336     *
36337     * @static
36338     * @memberOf _
36339     * @since 1.3.0
36340     * @category Object
36341     * @param {Object} object The object to iterate over.
36342     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
36343     * @param {*} [accumulator] The custom accumulator value.
36344     * @returns {*} Returns the accumulated value.
36345     * @example
36346     *
36347     * _.transform([2, 3, 4], function(result, n) {
36348     *   result.push(n *= n);
36349     *   return n % 2 == 0;
36350     * }, []);
36351     * // => [4, 9]
36352     *
36353     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
36354     *   (result[value] || (result[value] = [])).push(key);
36355     * }, {});
36356     * // => { '1': ['a', 'c'], '2': ['b'] }
36357     */
36358    function transform(object, iteratee, accumulator) {
36359      var isArr = isArray(object),
36360          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
36361
36362      iteratee = getIteratee(iteratee, 4);
36363      if (accumulator == null) {
36364        var Ctor = object && object.constructor;
36365        if (isArrLike) {
36366          accumulator = isArr ? new Ctor : [];
36367        }
36368        else if (isObject(object)) {
36369          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
36370        }
36371        else {
36372          accumulator = {};
36373        }
36374      }
36375      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
36376        return iteratee(accumulator, value, index, object);
36377      });
36378      return accumulator;
36379    }
36380
36381    /**
36382     * Removes the property at `path` of `object`.
36383     *
36384     * **Note:** This method mutates `object`.
36385     *
36386     * @static
36387     * @memberOf _
36388     * @since 4.0.0
36389     * @category Object
36390     * @param {Object} object The object to modify.
36391     * @param {Array|string} path The path of the property to unset.
36392     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
36393     * @example
36394     *
36395     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
36396     * _.unset(object, 'a[0].b.c');
36397     * // => true
36398     *
36399     * console.log(object);
36400     * // => { 'a': [{ 'b': {} }] };
36401     *
36402     * _.unset(object, ['a', '0', 'b', 'c']);
36403     * // => true
36404     *
36405     * console.log(object);
36406     * // => { 'a': [{ 'b': {} }] };
36407     */
36408    function unset(object, path) {
36409      return object == null ? true : baseUnset(object, path);
36410    }
36411
36412    /**
36413     * This method is like `_.set` except that accepts `updater` to produce the
36414     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
36415     * is invoked with one argument: (value).
36416     *
36417     * **Note:** This method mutates `object`.
36418     *
36419     * @static
36420     * @memberOf _
36421     * @since 4.6.0
36422     * @category Object
36423     * @param {Object} object The object to modify.
36424     * @param {Array|string} path The path of the property to set.
36425     * @param {Function} updater The function to produce the updated value.
36426     * @returns {Object} Returns `object`.
36427     * @example
36428     *
36429     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
36430     *
36431     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
36432     * console.log(object.a[0].b.c);
36433     * // => 9
36434     *
36435     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
36436     * console.log(object.x[0].y.z);
36437     * // => 0
36438     */
36439    function update(object, path, updater) {
36440      return object == null ? object : baseUpdate(object, path, castFunction(updater));
36441    }
36442
36443    /**
36444     * This method is like `_.update` except that it accepts `customizer` which is
36445     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
36446     * path creation is handled by the method instead. The `customizer` is invoked
36447     * with three arguments: (nsValue, key, nsObject).
36448     *
36449     * **Note:** This method mutates `object`.
36450     *
36451     * @static
36452     * @memberOf _
36453     * @since 4.6.0
36454     * @category Object
36455     * @param {Object} object The object to modify.
36456     * @param {Array|string} path The path of the property to set.
36457     * @param {Function} updater The function to produce the updated value.
36458     * @param {Function} [customizer] The function to customize assigned values.
36459     * @returns {Object} Returns `object`.
36460     * @example
36461     *
36462     * var object = {};
36463     *
36464     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
36465     * // => { '0': { '1': 'a' } }
36466     */
36467    function updateWith(object, path, updater, customizer) {
36468      customizer = typeof customizer == 'function' ? customizer : undefined;
36469      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
36470    }
36471
36472    /**
vendor: 1,263 bytes, lines 36473-36522
36473     * Creates an array of the own enumerable string keyed property values of `object`.
36474     *
36475     * **Note:** Non-object values are coerced to objects.
36476     *
36477     * @static
36478     * @since 0.1.0
36479     * @memberOf _
36480     * @category Object
36481     * @param {Object} object The object to query.
36482     * @returns {Array} Returns the array of property values.
36483     * @example
36484     *
36485     * function Foo() {
36486     *   this.a = 1;
36487     *   this.b = 2;
36488     * }
36489     *
36490     * Foo.prototype.c = 3;
36491     *
36492     * _.values(new Foo);
36493     * // => [1, 2] (iteration order is not guaranteed)
36494     *
36495     * _.values('hi');
36496     * // => ['h', 'i']
36497     */
36498    function values(object) {
36499      return object == null ? [] : baseValues(object, keys(object));
36500    }
36501
36502    /**
36503     * Creates an array of the own and inherited enumerable string keyed property
36504     * values of `object`.
36505     *
36506     * **Note:** Non-object values are coerced to objects.
36507     *
36508     * @static
36509     * @memberOf _
36510     * @since 3.0.0
36511     * @category Object
36512     * @param {Object} object The object to query.
36513     * @returns {Array} Returns the array of property values.
36514     * @example
36515     *
36516     * function Foo() {
36517     *   this.a = 1;
36518     *   this.b = 2;
36519     * }
36520     *
36521     * Foo.prototype.c = 3;
36522     *
vendor: 5,617 bytes, lines 36523-36717
36523     * _.valuesIn(new Foo);
36524     * // => [1, 2, 3] (iteration order is not guaranteed)
36525     */
36526    function valuesIn(object) {
36527      return object == null ? [] : baseValues(object, keysIn(object));
36528    }
36529
36530    /*------------------------------------------------------------------------*/
36531
36532    /**
36533     * Clamps `number` within the inclusive `lower` and `upper` bounds.
36534     *
36535     * @static
36536     * @memberOf _
36537     * @since 4.0.0
36538     * @category Number
36539     * @param {number} number The number to clamp.
36540     * @param {number} [lower] The lower bound.
36541     * @param {number} upper The upper bound.
36542     * @returns {number} Returns the clamped number.
36543     * @example
36544     *
36545     * _.clamp(-10, -5, 5);
36546     * // => -5
36547     *
36548     * _.clamp(10, -5, 5);
36549     * // => 5
36550     */
36551    function clamp(number, lower, upper) {
36552      if (upper === undefined) {
36553        upper = lower;
36554        lower = undefined;
36555      }
36556      if (upper !== undefined) {
36557        upper = toNumber(upper);
36558        upper = upper === upper ? upper : 0;
36559      }
36560      if (lower !== undefined) {
36561        lower = toNumber(lower);
36562        lower = lower === lower ? lower : 0;
36563      }
36564      return baseClamp(toNumber(number), lower, upper);
36565    }
36566
36567    /**
36568     * Checks if `n` is between `start` and up to, but not including, `end`. If
36569     * `end` is not specified, it's set to `start` with `start` then set to `0`.
36570     * If `start` is greater than `end` the params are swapped to support
36571     * negative ranges.
36572     *
36573     * @static
36574     * @memberOf _
36575     * @since 3.3.0
36576     * @category Number
36577     * @param {number} number The number to check.
36578     * @param {number} [start=0] The start of the range.
36579     * @param {number} end The end of the range.
36580     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
36581     * @see _.range, _.rangeRight
36582     * @example
36583     *
36584     * _.inRange(3, 2, 4);
36585     * // => true
36586     *
36587     * _.inRange(4, 8);
36588     * // => true
36589     *
36590     * _.inRange(4, 2);
36591     * // => false
36592     *
36593     * _.inRange(2, 2);
36594     * // => false
36595     *
36596     * _.inRange(1.2, 2);
36597     * // => true
36598     *
36599     * _.inRange(5.2, 4);
36600     * // => false
36601     *
36602     * _.inRange(-3, -2, -6);
36603     * // => true
36604     */
36605    function inRange(number, start, end) {
36606      start = toFinite(start);
36607      if (end === undefined) {
36608        end = start;
36609        start = 0;
36610      } else {
36611        end = toFinite(end);
36612      }
36613      number = toNumber(number);
36614      return baseInRange(number, start, end);
36615    }
36616
36617    /**
36618     * Produces a random number between the inclusive `lower` and `upper` bounds.
36619     * If only one argument is provided a number between `0` and the given number
36620     * is returned. If `floating` is `true`, or either `lower` or `upper` are
36621     * floats, a floating-point number is returned instead of an integer.
36622     *
36623     * **Note:** JavaScript follows the IEEE-754 standard for resolving
36624     * floating-point values which can produce unexpected results.
36625     *
36626     * **Note:** If `lower` is greater than `upper`, the values are swapped.
36627     *
36628     * @static
36629     * @memberOf _
36630     * @since 0.7.0
36631     * @category Number
36632     * @param {number} [lower=0] The lower bound.
36633     * @param {number} [upper=1] The upper bound.
36634     * @param {boolean} [floating] Specify returning a floating-point number.
36635     * @returns {number} Returns the random number.
36636     * @example
36637     *
36638     * _.random(0, 5);
36639     * // => an integer between 0 and 5
36640     *
36641     * // when lower is greater than upper the values are swapped
36642     * _.random(5, 0);
36643     * // => an integer between 0 and 5
36644     *
36645     * _.random(5);
36646     * // => also an integer between 0 and 5
36647     *
36648     * _.random(-5);
36649     * // => an integer between -5 and 0
36650     *
36651     * _.random(5, true);
36652     * // => a floating-point number between 0 and 5
36653     *
36654     * _.random(1.2, 5.2);
36655     * // => a floating-point number between 1.2 and 5.2
36656     */
36657    function random(lower, upper, floating) {
36658      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
36659        upper = floating = undefined;
36660      }
36661      if (floating === undefined) {
36662        if (typeof upper == 'boolean') {
36663          floating = upper;
36664          upper = undefined;
36665        }
36666        else if (typeof lower == 'boolean') {
36667          floating = lower;
36668          lower = undefined;
36669        }
36670      }
36671      if (lower === undefined && upper === undefined) {
36672        lower = 0;
36673        upper = 1;
36674      }
36675      else {
36676        lower = toFinite(lower);
36677        if (upper === undefined) {
36678          upper = lower;
36679          lower = 0;
36680        } else {
36681          upper = toFinite(upper);
36682        }
36683      }
36684      if (lower > upper) {
36685        var temp = lower;
36686        lower = upper;
36687        upper = temp;
36688      }
36689      if (floating || lower % 1 || upper % 1) {
36690        var rand = nativeRandom();
36691        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
36692      }
36693      return baseRandom(lower, upper);
36694    }
36695
36696    /*------------------------------------------------------------------------*/
36697
36698    /**
36699     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
36700     *
36701     * @static
36702     * @memberOf _
36703     * @since 3.0.0
36704     * @category String
36705     * @param {string} [string=''] The string to convert.
36706     * @returns {string} Returns the camel cased string.
36707     * @example
36708     *
36709     * _.camelCase('Foo Bar');
36710     * // => 'fooBar'
36711     *
36712     * _.camelCase('--foo-bar--');
36713     * // => 'fooBar'
36714     *
36715     * _.camelCase('__FOO_BAR__');
36716     * // => 'fooBar'
36717     */
vendor: 4,351 bytes, lines 36718-36852
36718    var camelCase = createCompounder(function(result, word, index) {
36719      word = word.toLowerCase();
36720      return result + (index ? capitalize(word) : word);
36721    });
36722
36723    /**
36724     * Converts the first character of `string` to upper case and the remaining
36725     * to lower case.
36726     *
36727     * @static
36728     * @memberOf _
36729     * @since 3.0.0
36730     * @category String
36731     * @param {string} [string=''] The string to capitalize.
36732     * @returns {string} Returns the capitalized string.
36733     * @example
36734     *
36735     * _.capitalize('FRED');
36736     * // => 'Fred'
36737     */
36738    function capitalize(string) {
36739      return upperFirst(toString(string).toLowerCase());
36740    }
36741
36742    /**
36743     * Deburrs `string` by converting
36744     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
36745     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
36746     * letters to basic Latin letters and removing
36747     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
36748     *
36749     * @static
36750     * @memberOf _
36751     * @since 3.0.0
36752     * @category String
36753     * @param {string} [string=''] The string to deburr.
36754     * @returns {string} Returns the deburred string.
36755     * @example
36756     *
36757     * _.deburr('déjà vu');
36758     * // => 'deja vu'
36759     */
36760    function deburr(string) {
36761      string = toString(string);
36762      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
36763    }
36764
36765    /**
36766     * Checks if `string` ends with the given target string.
36767     *
36768     * @static
36769     * @memberOf _
36770     * @since 3.0.0
36771     * @category String
36772     * @param {string} [string=''] The string to inspect.
36773     * @param {string} [target] The string to search for.
36774     * @param {number} [position=string.length] The position to search up to.
36775     * @returns {boolean} Returns `true` if `string` ends with `target`,
36776     *  else `false`.
36777     * @example
36778     *
36779     * _.endsWith('abc', 'c');
36780     * // => true
36781     *
36782     * _.endsWith('abc', 'b');
36783     * // => false
36784     *
36785     * _.endsWith('abc', 'b', 2);
36786     * // => true
36787     */
36788    function endsWith(string, target, position) {
36789      string = toString(string);
36790      target = baseToString(target);
36791
36792      var length = string.length;
36793      position = position === undefined
36794        ? length
36795        : baseClamp(toInteger(position), 0, length);
36796
36797      var end = position;
36798      position -= target.length;
36799      return position >= 0 && string.slice(position, end) == target;
36800    }
36801
36802    /**
36803     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
36804     * corresponding HTML entities.
36805     *
36806     * **Note:** No other characters are escaped. To escape additional
36807     * characters use a third-party library like [_he_](https://mths.be/he).
36808     *
36809     * Though the ">" character is escaped for symmetry, characters like
36810     * ">" and "/" don't need escaping in HTML and have no special meaning
36811     * unless they're part of a tag or unquoted attribute value. See
36812     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
36813     * (under "semi-related fun fact") for more details.
36814     *
36815     * When working with HTML you should always
36816     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
36817     * XSS vectors.
36818     *
36819     * @static
36820     * @since 0.1.0
36821     * @memberOf _
36822     * @category String
36823     * @param {string} [string=''] The string to escape.
36824     * @returns {string} Returns the escaped string.
36825     * @example
36826     *
36827     * _.escape('fred, barney, & pebbles');
36828     * // => 'fred, barney, &amp; pebbles'
36829     */
36830    function escape(string) {
36831      string = toString(string);
36832      return (string && reHasUnescapedHtml.test(string))
36833        ? string.replace(reUnescapedHtml, escapeHtmlChar)
36834        : string;
36835    }
36836
36837    /**
36838     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
36839     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
36840     *
36841     * @static
36842     * @memberOf _
36843     * @since 3.0.0
36844     * @category String
36845     * @param {string} [string=''] The string to escape.
36846     * @returns {string} Returns the escaped string.
36847     * @example
36848     *
36849     * _.escapeRegExp('[lodash](https://lodash.com/)');
36850     * // => '\[lodash\]\(https://lodash\.com/\)'
36851     */
36852    function escapeRegExp(string) {
vendor: 4,658 bytes, lines 36853-37022
36853      string = toString(string);
36854      return (string && reHasRegExpChar.test(string))
36855        ? string.replace(reRegExpChar, '\\$&')
36856        : string;
36857    }
36858
36859    /**
36860     * Converts `string` to
36861     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
36862     *
36863     * @static
36864     * @memberOf _
36865     * @since 3.0.0
36866     * @category String
36867     * @param {string} [string=''] The string to convert.
36868     * @returns {string} Returns the kebab cased string.
36869     * @example
36870     *
36871     * _.kebabCase('Foo Bar');
36872     * // => 'foo-bar'
36873     *
36874     * _.kebabCase('fooBar');
36875     * // => 'foo-bar'
36876     *
36877     * _.kebabCase('__FOO_BAR__');
36878     * // => 'foo-bar'
36879     */
36880    var kebabCase = createCompounder(function(result, word, index) {
36881      return result + (index ? '-' : '') + word.toLowerCase();
36882    });
36883
36884    /**
36885     * Converts `string`, as space separated words, to lower case.
36886     *
36887     * @static
36888     * @memberOf _
36889     * @since 4.0.0
36890     * @category String
36891     * @param {string} [string=''] The string to convert.
36892     * @returns {string} Returns the lower cased string.
36893     * @example
36894     *
36895     * _.lowerCase('--Foo-Bar--');
36896     * // => 'foo bar'
36897     *
36898     * _.lowerCase('fooBar');
36899     * // => 'foo bar'
36900     *
36901     * _.lowerCase('__FOO_BAR__');
36902     * // => 'foo bar'
36903     */
36904    var lowerCase = createCompounder(function(result, word, index) {
36905      return result + (index ? ' ' : '') + word.toLowerCase();
36906    });
36907
36908    /**
36909     * Converts the first character of `string` to lower case.
36910     *
36911     * @static
36912     * @memberOf _
36913     * @since 4.0.0
36914     * @category String
36915     * @param {string} [string=''] The string to convert.
36916     * @returns {string} Returns the converted string.
36917     * @example
36918     *
36919     * _.lowerFirst('Fred');
36920     * // => 'fred'
36921     *
36922     * _.lowerFirst('FRED');
36923     * // => 'fRED'
36924     */
36925    var lowerFirst = createCaseFirst('toLowerCase');
36926
36927    /**
36928     * Pads `string` on the left and right sides if it's shorter than `length`.
36929     * Padding characters are truncated if they can't be evenly divided by `length`.
36930     *
36931     * @static
36932     * @memberOf _
36933     * @since 3.0.0
36934     * @category String
36935     * @param {string} [string=''] The string to pad.
36936     * @param {number} [length=0] The padding length.
36937     * @param {string} [chars=' '] The string used as padding.
36938     * @returns {string} Returns the padded string.
36939     * @example
36940     *
36941     * _.pad('abc', 8);
36942     * // => '  abc   '
36943     *
36944     * _.pad('abc', 8, '_-');
36945     * // => '_-abc_-_'
36946     *
36947     * _.pad('abc', 3);
36948     * // => 'abc'
36949     */
36950    function pad(string, length, chars) {
36951      string = toString(string);
36952      length = toInteger(length);
36953
36954      var strLength = length ? stringSize(string) : 0;
36955      if (!length || strLength >= length) {
36956        return string;
36957      }
36958      var mid = (length - strLength) / 2;
36959      return (
36960        createPadding(nativeFloor(mid), chars) +
36961        string +
36962        createPadding(nativeCeil(mid), chars)
36963      );
36964    }
36965
36966    /**
36967     * Pads `string` on the right side if it's shorter than `length`. Padding
36968     * characters are truncated if they exceed `length`.
36969     *
36970     * @static
36971     * @memberOf _
36972     * @since 4.0.0
36973     * @category String
36974     * @param {string} [string=''] The string to pad.
36975     * @param {number} [length=0] The padding length.
36976     * @param {string} [chars=' '] The string used as padding.
36977     * @returns {string} Returns the padded string.
36978     * @example
36979     *
36980     * _.padEnd('abc', 6);
36981     * // => 'abc   '
36982     *
36983     * _.padEnd('abc', 6, '_-');
36984     * // => 'abc_-_'
36985     *
36986     * _.padEnd('abc', 3);
36987     * // => 'abc'
36988     */
36989    function padEnd(string, length, chars) {
36990      string = toString(string);
36991      length = toInteger(length);
36992
36993      var strLength = length ? stringSize(string) : 0;
36994      return (length && strLength < length)
36995        ? (string + createPadding(length - strLength, chars))
36996        : string;
36997    }
36998
36999    /**
37000     * Pads `string` on the left side if it's shorter than `length`. Padding
37001     * characters are truncated if they exceed `length`.
37002     *
37003     * @static
37004     * @memberOf _
37005     * @since 4.0.0
37006     * @category String
37007     * @param {string} [string=''] The string to pad.
37008     * @param {number} [length=0] The padding length.
37009     * @param {string} [chars=' '] The string used as padding.
37010     * @returns {string} Returns the padded string.
37011     * @example
37012     *
37013     * _.padStart('abc', 6);
37014     * // => '   abc'
37015     *
37016     * _.padStart('abc', 6, '_-');
37017     * // => '_-_abc'
37018     *
37019     * _.padStart('abc', 3);
37020     * // => 'abc'
37021     */
37022    function padStart(string, length, chars) {
vendor: 2,753 bytes, lines 37023-37113
37023      string = toString(string);
37024      length = toInteger(length);
37025
37026      var strLength = length ? stringSize(string) : 0;
37027      return (length && strLength < length)
37028        ? (createPadding(length - strLength, chars) + string)
37029        : string;
37030    }
37031
37032    /**
37033     * Converts `string` to an integer of the specified radix. If `radix` is
37034     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
37035     * hexadecimal, in which case a `radix` of `16` is used.
37036     *
37037     * **Note:** This method aligns with the
37038     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
37039     *
37040     * @static
37041     * @memberOf _
37042     * @since 1.1.0
37043     * @category String
37044     * @param {string} string The string to convert.
37045     * @param {number} [radix=10] The radix to interpret `value` by.
37046     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37047     * @returns {number} Returns the converted integer.
37048     * @example
37049     *
37050     * _.parseInt('08');
37051     * // => 8
37052     *
37053     * _.map(['6', '08', '10'], _.parseInt);
37054     * // => [6, 8, 10]
37055     */
37056    function parseInt(string, radix, guard) {
37057      if (guard || radix == null) {
37058        radix = 0;
37059      } else if (radix) {
37060        radix = +radix;
37061      }
37062      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
37063    }
37064
37065    /**
37066     * Repeats the given string `n` times.
37067     *
37068     * @static
37069     * @memberOf _
37070     * @since 3.0.0
37071     * @category String
37072     * @param {string} [string=''] The string to repeat.
37073     * @param {number} [n=1] The number of times to repeat the string.
37074     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37075     * @returns {string} Returns the repeated string.
37076     * @example
37077     *
37078     * _.repeat('*', 3);
37079     * // => '***'
37080     *
37081     * _.repeat('abc', 2);
37082     * // => 'abcabc'
37083     *
37084     * _.repeat('abc', 0);
37085     * // => ''
37086     */
37087    function repeat(string, n, guard) {
37088      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
37089        n = 1;
37090      } else {
37091        n = toInteger(n);
37092      }
37093      return baseRepeat(toString(string), n);
37094    }
37095
37096    /**
37097     * Replaces matches for `pattern` in `string` with `replacement`.
37098     *
37099     * **Note:** This method is based on
37100     * [`String#replace`](https://mdn.io/String/replace).
37101     *
37102     * @static
37103     * @memberOf _
37104     * @since 4.0.0
37105     * @category String
37106     * @param {string} [string=''] The string to modify.
37107     * @param {RegExp|string} pattern The pattern to replace.
37108     * @param {Function|string} replacement The match replacement.
37109     * @returns {string} Returns the modified string.
37110     * @example
37111     *
37112     * _.replace('Hi Fred', 'Fred', 'Barney');
37113     * // =>
vendor: 11,956 bytes, lines 37113-37427
37113 'Hi Barney'
37114     */
37115    function replace() {
37116      var args = arguments,
37117          string = toString(args[0]);
37118
37119      return args.length < 3 ? string : string.replace(args[1], args[2]);
37120    }
37121
37122    /**
37123     * Converts `string` to
37124     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
37125     *
37126     * @static
37127     * @memberOf _
37128     * @since 3.0.0
37129     * @category String
37130     * @param {string} [string=''] The string to convert.
37131     * @returns {string} Returns the snake cased string.
37132     * @example
37133     *
37134     * _.snakeCase('Foo Bar');
37135     * // => 'foo_bar'
37136     *
37137     * _.snakeCase('fooBar');
37138     * // => 'foo_bar'
37139     *
37140     * _.snakeCase('--FOO-BAR--');
37141     * // => 'foo_bar'
37142     */
37143    var snakeCase = createCompounder(function(result, word, index) {
37144      return result + (index ? '_' : '') + word.toLowerCase();
37145    });
37146
37147    /**
37148     * Splits `string` by `separator`.
37149     *
37150     * **Note:** This method is based on
37151     * [`String#split`](https://mdn.io/String/split).
37152     *
37153     * @static
37154     * @memberOf _
37155     * @since 4.0.0
37156     * @category String
37157     * @param {string} [string=''] The string to split.
37158     * @param {RegExp|string} separator The separator pattern to split by.
37159     * @param {number} [limit] The length to truncate results to.
37160     * @returns {Array} Returns the string segments.
37161     * @example
37162     *
37163     * _.split('a-b-c', '-', 2);
37164     * // => ['a', 'b']
37165     */
37166    function split(string, separator, limit) {
37167      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
37168        separator = limit = undefined;
37169      }
37170      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
37171      if (!limit) {
37172        return [];
37173      }
37174      string = toString(string);
37175      if (string && (
37176            typeof separator == 'string' ||
37177            (separator != null && !isRegExp(separator))
37178          )) {
37179        separator = baseToString(separator);
37180        if (!separator && hasUnicode(string)) {
37181          return castSlice(stringToArray(string), 0, limit);
37182        }
37183      }
37184      return string.split(separator, limit);
37185    }
37186
37187    /**
37188     * Converts `string` to
37189     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
37190     *
37191     * @static
37192     * @memberOf _
37193     * @since 3.1.0
37194     * @category String
37195     * @param {string} [string=''] The string to convert.
37196     * @returns {string} Returns the start cased string.
37197     * @example
37198     *
37199     * _.startCase('--foo-bar--');
37200     * // => 'Foo Bar'
37201     *
37202     * _.startCase('fooBar');
37203     * // => 'Foo Bar'
37204     *
37205     * _.startCase('__FOO_BAR__');
37206     * // => 'FOO BAR'
37207     */
37208    var startCase = createCompounder(function(result, word, index) {
37209      return result + (index ? ' ' : '') + upperFirst(word);
37210    });
37211
37212    /**
37213     * Checks if `string` starts with the given target string.
37214     *
37215     * @static
37216     * @memberOf _
37217     * @since 3.0.0
37218     * @category String
37219     * @param {string} [string=''] The string to inspect.
37220     * @param {string} [target] The string to search for.
37221     * @param {number} [position=0] The position to search from.
37222     * @returns {boolean} Returns `true` if `string` starts with `target`,
37223     *  else `false`.
37224     * @example
37225     *
37226     * _.startsWith('abc', 'a');
37227     * // => true
37228     *
37229     * _.startsWith('abc', 'b');
37230     * // => false
37231     *
37232     * _.startsWith('abc', 'b', 1);
37233     * // => true
37234     */
37235    function startsWith(string, target, position) {
37236      string = toString(string);
37237      position = position == null
37238        ? 0
37239        : baseClamp(toInteger(position), 0, string.length);
37240
37241      target = baseToString(target);
37242      return string.slice(position, position + target.length) == target;
37243    }
37244
37245    /**
37246     * Creates a compiled template function that can interpolate data properties
37247     * in "interpolate" delimiters, HTML-escape interpolated data properties in
37248     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
37249     * properties may be accessed as free variables in the template. If a setting
37250     * object is given, it takes precedence over `_.templateSettings` values.
37251     *
37252     * **Security:** `_.template` is insecure and should not be used. It will be
37253     * removed in Lodash v5. Avoid untrusted input. See
37254     * [threat model](https://github.com/lodash/lodash/blob/main/threat-model.md).
37255     *
37256     * **Note:** In the development build `_.template` utilizes
37257     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
37258     * for easier debugging.
37259     *
37260     * For more information on precompiling templates see
37261     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
37262     *
37263     * For more information on Chrome extension sandboxes see
37264     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
37265     *
37266     * @static
37267     * @since 0.1.0
37268     * @memberOf _
37269     * @category String
37270     * @param {string} [string=''] The template string.
37271     * @param {Object} [options={}] The options object.
37272     * @param {RegExp} [options.escape=_.templateSettings.escape]
37273     *  The HTML "escape" delimiter.
37274     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
37275     *  The "evaluate" delimiter.
37276     * @param {Object} [options.imports=_.templateSettings.imports]
37277     *  An object to import into the template as free variables.
37278     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
37279     *  The "interpolate" delimiter.
37280     * @param {string} [options.sourceURL='lodash.templateSources[n]']
37281     *  The sourceURL of the compiled template.
37282     * @param {string} [options.variable='obj']
37283     *  The data object variable name.
37284     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37285     * @returns {Function} Returns the compiled template function.
37286     * @example
37287     *
37288     * // Use the "interpolate" delimiter to create a compiled template.
37289     * var compiled = _.template('hello <%= user %>!');
37290     * compiled({ 'user': 'fred' });
37291     * // => 'hello fred!'
37292     *
37293     * // Use the HTML "escape" delimiter to escape data property values.
37294     * var compiled = _.template('<b><%- value %></b>');
37295     * compiled({ 'value': '<script>' });
37296     * // => '<b>&lt;script&gt;</b>'
37297     *
37298     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
37299     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
37300     * compiled({ 'users': ['fred', 'barney'] });
37301     * // => '<li>fred</li><li>barney</li>'
37302     *
37303     * // Use the internal `print` function in "evaluate" delimiters.
37304     * var compiled = _.template('<% print("hello " + user); %>!');
37305     * compiled({ 'user': 'barney' });
37306     * // => 'hello barney!'
37307     *
37308     * // Use the ES template literal delimiter as an "interpolate" delimiter.
37309     * // Disable support by replacing the "interpolate" delimiter.
37310     * var compiled = _.template('hello ${ user }!');
37311     * compiled({ 'user': 'pebbles' });
37312     * // => 'hello pebbles!'
37313     *
37314     * // Use backslashes to treat delimiters as plain text.
37315     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
37316     * compiled({ 'value': 'ignored' });
37317     * // => '<%- value %>'
37318     *
37319     * // Use the `imports` option to import `jQuery` as `jq`.
37320     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
37321     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
37322     * compiled({ 'users': ['fred', 'barney'] });
37323     * // => '<li>fred</li><li>barney</li>'
37324     *
37325     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
37326     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
37327     * compiled(data);
37328     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
37329     *
37330     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
37331     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
37332     * compiled.source;
37333     * // => function(data) {
37334     * //   var __t, __p = '';
37335     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
37336     * //   return __p;
37337     * // }
37338     *
37339     * // Use custom template delimiters.
37340     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
37341     * var compiled = _.template('hello {{ user }}!');
37342     * compiled({ 'user': 'mustache' });
37343     * // => 'hello mustache!'
37344     *
37345     * // Use the `source` property to inline compiled templates for meaningful
37346     * // line numbers in error messages and stack traces.
37347     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
37348     *   var JST = {\
37349     *     "main": ' + _.template(mainText).source + '\
37350     *   };\
37351     * ');
37352     */
37353    function template(string, options, guard) {
37354      // Based on John Resig's `tmpl` implementation
37355      // (http://ejohn.org/blog/javascript-micro-templating/)
37356      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
37357      var settings = lodash.templateSettings;
37358
37359      if (guard && isIterateeCall(string, options, guard)) {
37360        options = undefined;
37361      }
37362      string = toString(string);
37363      options = assignWith({}, options, settings, customDefaultsAssignIn);
37364
37365      var imports = assignWith({}, options.imports, settings.imports, customDefaultsAssignIn),
37366          importsKeys = keys(imports),
37367          importsValues = baseValues(imports, importsKeys);
37368
37369      arrayEach(importsKeys, function(key) {
37370        if (reForbiddenIdentifierChars.test(key)) {
37371          throw new Error(INVALID_TEMPL_IMPORTS_ERROR_TEXT);
37372        }
37373      });
37374
37375      var isEscaping,
37376          isEvaluating,
37377          index = 0,
37378          interpolate = options.interpolate || reNoMatch,
37379          source = "__p += '";
37380
37381      // Compile the regexp to match each delimiter.
37382      var reDelimiters = RegExp(
37383        (options.escape || reNoMatch).source + '|' +
37384        interpolate.source + '|' +
37385        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
37386        (options.evaluate || reNoMatch).source + '|$'
37387      , 'g');
37388
37389      // Use a sourceURL for easier debugging.
37390      // The sourceURL gets injected into the source that's eval-ed, so be careful
37391      // to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in
37392      // and escape the comment, thus injecting code that gets evaled.
37393      var sourceURL = '//# sourceURL=' +
37394        (hasOwnProperty.call(options, 'sourceURL')
37395          ? (options.sourceURL + '').replace(/\s/g, ' ')
37396          : ('lodash.templateSources[' + (++templateCounter) + ']')
37397        ) + '\n';
37398
37399      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
37400        interpolateValue || (interpolateValue = esTemplateValue);
37401
37402        // Escape characters that can't be included in string literals.
37403        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
37404
37405        // Replace delimiters with snippets.
37406        if (escapeValue) {
37407          isEscaping = true;
37408          source += "' +\n__e(" + escapeValue + ") +\n'";
37409        }
37410        if (evaluateValue) {
37411          isEvaluating = true;
37412          source += "';\n" + evaluateValue + ";\n__p += '";
37413        }
37414        if (interpolateValue) {
37415          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
37416        }
37417        index = offset + match.length;
37418
37419        // The JS engine embedded in Adobe products needs `match` returned in
37420        // order to produce the correct `offset` value.
37421        return match;
37422      });
37423
37424      source += "';\n";
37425
37426      // If `variable` is not specified wrap a with-statement around the generated
37427      // code to add the data object to the top of the scope chain.
vendor: 15,520 bytes, lines 37428-37930
37428      var variable = hasOwnProperty.call(options, 'variable') && options.variable;
37429      if (!variable) {
37430        source = 'with (obj) {\n' + source + '\n}\n';
37431      }
37432      // Throw an error if a forbidden character was found in `variable`, to prevent
37433      // potential command injection attacks.
37434      else if (reForbiddenIdentifierChars.test(variable)) {
37435        throw new Error(INVALID_TEMPL_VAR_ERROR_TEXT);
37436      }
37437
37438      // Cleanup code by stripping empty strings.
37439      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
37440        .replace(reEmptyStringMiddle, '$1')
37441        .replace(reEmptyStringTrailing, '$1;');
37442
37443      // Frame code as the function body.
37444      source = 'function(' + (variable || 'obj') + ') {\n' +
37445        (variable
37446          ? ''
37447          : 'obj || (obj = {});\n'
37448        ) +
37449        "var __t, __p = ''" +
37450        (isEscaping
37451           ? ', __e = _.escape'
37452           : ''
37453        ) +
37454        (isEvaluating
37455          ? ', __j = Array.prototype.join;\n' +
37456            "function print() { __p += __j.call(arguments, '') }\n"
37457          : ';\n'
37458        ) +
37459        source +
37460        'return __p\n}';
37461
37462      var result = attempt(function() {
37463        return Function(importsKeys, sourceURL + 'return ' + source)
37464          .apply(undefined, importsValues);
37465      });
37466
37467      // Provide the compiled function's source by its `toString` method or
37468      // the `source` property as a convenience for inlining compiled templates.
37469      result.source = source;
37470      if (isError(result)) {
37471        throw result;
37472      }
37473      return result;
37474    }
37475
37476    /**
37477     * Converts `string`, as a whole, to lower case just like
37478     * [String#toLowerCase](https://mdn.io/toLowerCase).
37479     *
37480     * @static
37481     * @memberOf _
37482     * @since 4.0.0
37483     * @category String
37484     * @param {string} [string=''] The string to convert.
37485     * @returns {string} Returns the lower cased string.
37486     * @example
37487     *
37488     * _.toLower('--Foo-Bar--');
37489     * // => '--foo-bar--'
37490     *
37491     * _.toLower('fooBar');
37492     * // => 'foobar'
37493     *
37494     * _.toLower('__FOO_BAR__');
37495     * // => '__foo_bar__'
37496     */
37497    function toLower(value) {
37498      return toString(value).toLowerCase();
37499    }
37500
37501    /**
37502     * Converts `string`, as a whole, to upper case just like
37503     * [String#toUpperCase](https://mdn.io/toUpperCase).
37504     *
37505     * @static
37506     * @memberOf _
37507     * @since 4.0.0
37508     * @category String
37509     * @param {string} [string=''] The string to convert.
37510     * @returns {string} Returns the upper cased string.
37511     * @example
37512     *
37513     * _.toUpper('--foo-bar--');
37514     * // => '--FOO-BAR--'
37515     *
37516     * _.toUpper('fooBar');
37517     * // => 'FOOBAR'
37518     *
37519     * _.toUpper('__foo_bar__');
37520     * // => '__FOO_BAR__'
37521     */
37522    function toUpper(value) {
37523      return toString(value).toUpperCase();
37524    }
37525
37526    /**
37527     * Removes leading and trailing whitespace or specified characters from `string`.
37528     *
37529     * @static
37530     * @memberOf _
37531     * @since 3.0.0
37532     * @category String
37533     * @param {string} [string=''] The string to trim.
37534     * @param {string} [chars=whitespace] The characters to trim.
37535     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37536     * @returns {string} Returns the trimmed string.
37537     * @example
37538     *
37539     * _.trim('  abc  ');
37540     * // => 'abc'
37541     *
37542     * _.trim('-_-abc-_-', '_-');
37543     * // => 'abc'
37544     *
37545     * _.map(['  foo  ', '  bar  '], _.trim);
37546     * // => ['foo', 'bar']
37547     */
37548    function trim(string, chars, guard) {
37549      string = toString(string);
37550      if (string && (guard || chars === undefined)) {
37551        return baseTrim(string);
37552      }
37553      if (!string || !(chars = baseToString(chars))) {
37554        return string;
37555      }
37556      var strSymbols = stringToArray(string),
37557          chrSymbols = stringToArray(chars),
37558          start = charsStartIndex(strSymbols, chrSymbols),
37559          end = charsEndIndex(strSymbols, chrSymbols) + 1;
37560
37561      return castSlice(strSymbols, start, end).join('');
37562    }
37563
37564    /**
37565     * Removes trailing whitespace or specified characters from `string`.
37566     *
37567     * @static
37568     * @memberOf _
37569     * @since 4.0.0
37570     * @category String
37571     * @param {string} [string=''] The string to trim.
37572     * @param {string} [chars=whitespace] The characters to trim.
37573     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37574     * @returns {string} Returns the trimmed string.
37575     * @example
37576     *
37577     * _.trimEnd('  abc  ');
37578     * // => '  abc'
37579     *
37580     * _.trimEnd('-_-abc-_-', '_-');
37581     * // => '-_-abc'
37582     */
37583    function trimEnd(string, chars, guard) {
37584      string = toString(string);
37585      if (string && (guard || chars === undefined)) {
37586        return string.slice(0, trimmedEndIndex(string) + 1);
37587      }
37588      if (!string || !(chars = baseToString(chars))) {
37589        return string;
37590      }
37591      var strSymbols = stringToArray(string),
37592          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
37593
37594      return castSlice(strSymbols, 0, end).join('');
37595    }
37596
37597    /**
37598     * Removes leading whitespace or specified characters from `string`.
37599     *
37600     * @static
37601     * @memberOf _
37602     * @since 4.0.0
37603     * @category String
37604     * @param {string} [string=''] The string to trim.
37605     * @param {string} [chars=whitespace] The characters to trim.
37606     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37607     * @returns {string} Returns the trimmed string.
37608     * @example
37609     *
37610     * _.trimStart('  abc  ');
37611     * // => 'abc  '
37612     *
37613     * _.trimStart('-_-abc-_-', '_-');
37614     * // => 'abc-_-'
37615     */
37616    function trimStart(string, chars, guard) {
37617      string = toString(string);
37618      if (string && (guard || chars === undefined)) {
37619        return string.replace(reTrimStart, '');
37620      }
37621      if (!string || !(chars = baseToString(chars))) {
37622        return string;
37623      }
37624      var strSymbols = stringToArray(string),
37625          start = charsStartIndex(strSymbols, stringToArray(chars));
37626
37627      return castSlice(strSymbols, start).join('');
37628    }
37629
37630    /**
37631     * Truncates `string` if it's longer than the given maximum string length.
37632     * The last characters of the truncated string are replaced with the omission
37633     * string which defaults to "...".
37634     *
37635     * @static
37636     * @memberOf _
37637     * @since 4.0.0
37638     * @category String
37639     * @param {string} [string=''] The string to truncate.
37640     * @param {Object} [options={}] The options object.
37641     * @param {number} [options.length=30] The maximum string length.
37642     * @param {string} [options.omission='...'] The string to indicate text is omitted.
37643     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
37644     * @returns {string} Returns the truncated string.
37645     * @example
37646     *
37647     * _.truncate('hi-diddly-ho there, neighborino');
37648     * // => 'hi-diddly-ho there, neighbo...'
37649     *
37650     * _.truncate('hi-diddly-ho there, neighborino', {
37651     *   'length': 24,
37652     *   'separator': ' '
37653     * });
37654     * // => 'hi-diddly-ho there,...'
37655     *
37656     * _.truncate('hi-diddly-ho there, neighborino', {
37657     *   'length': 24,
37658     *   'separator': /,? +/
37659     * });
37660     * // => 'hi-diddly-ho there...'
37661     *
37662     * _.truncate('hi-diddly-ho there, neighborino', {
37663     *   'omission': ' [...]'
37664     * });
37665     * // => 'hi-diddly-ho there, neig [...]'
37666     */
37667    function truncate(string, options) {
37668      var length = DEFAULT_TRUNC_LENGTH,
37669          omission = DEFAULT_TRUNC_OMISSION;
37670
37671      if (isObject(options)) {
37672        var separator = 'separator' in options ? options.separator : separator;
37673        length = 'length' in options ? toInteger(options.length) : length;
37674        omission = 'omission' in options ? baseToString(options.omission) : omission;
37675      }
37676      string = toString(string);
37677
37678      var strLength = string.length;
37679      if (hasUnicode(string)) {
37680        var strSymbols = stringToArray(string);
37681        strLength = strSymbols.length;
37682      }
37683      if (length >= strLength) {
37684        return string;
37685      }
37686      var end = length - stringSize(omission);
37687      if (end < 1) {
37688        return omission;
37689      }
37690      var result = strSymbols
37691        ? castSlice(strSymbols, 0, end).join('')
37692        : string.slice(0, end);
37693
37694      if (separator === undefined) {
37695        return result + omission;
37696      }
37697      if (strSymbols) {
37698        end += (result.length - end);
37699      }
37700      if (isRegExp(separator)) {
37701        if (string.slice(end).search(separator)) {
37702          var match,
37703              substring = result;
37704
37705          if (!separator.global) {
37706            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
37707          }
37708          separator.lastIndex = 0;
37709          while ((match = separator.exec(substring))) {
37710            var newEnd = match.index;
37711          }
37712          result = result.slice(0, newEnd === undefined ? end : newEnd);
37713        }
37714      } else if (string.indexOf(baseToString(separator), end) != end) {
37715        var index = result.lastIndexOf(separator);
37716        if (index > -1) {
37717          result = result.slice(0, index);
37718        }
37719      }
37720      return result + omission;
37721    }
37722
37723    /**
37724     * The inverse of `_.escape`; this method converts the HTML entities
37725     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
37726     * their corresponding characters.
37727     *
37728     * **Note:** No other HTML entities are unescaped. To unescape additional
37729     * HTML entities use a third-party library like [_he_](https://mths.be/he).
37730     *
37731     * @static
37732     * @memberOf _
37733     * @since 0.6.0
37734     * @category String
37735     * @param {string} [string=''] The string to unescape.
37736     * @returns {string} Returns the unescaped string.
37737     * @example
37738     *
37739     * _.unescape('fred, barney, &amp; pebbles');
37740     * // => 'fred, barney, & pebbles'
37741     */
37742    function unescape(string) {
37743      string = toString(string);
37744      return (string && reHasEscapedHtml.test(string))
37745        ? string.replace(reEscapedHtml, unescapeHtmlChar)
37746        : string;
37747    }
37748
37749    /**
37750     * Converts `string`, as space separated words, to upper case.
37751     *
37752     * @static
37753     * @memberOf _
37754     * @since 4.0.0
37755     * @category String
37756     * @param {string} [string=''] The string to convert.
37757     * @returns {string} Returns the upper cased string.
37758     * @example
37759     *
37760     * _.upperCase('--foo-bar');
37761     * // => 'FOO BAR'
37762     *
37763     * _.upperCase('fooBar');
37764     * // => 'FOO BAR'
37765     *
37766     * _.upperCase('__foo_bar__');
37767     * // => 'FOO BAR'
37768     */
37769    var upperCase = createCompounder(function(result, word, index) {
37770      return result + (index ? ' ' : '') + word.toUpperCase();
37771    });
37772
37773    /**
37774     * Converts the first character of `string` to upper case.
37775     *
37776     * @static
37777     * @memberOf _
37778     * @since 4.0.0
37779     * @category String
37780     * @param {string} [string=''] The string to convert.
37781     * @returns {string} Returns the converted string.
37782     * @example
37783     *
37784     * _.upperFirst('fred');
37785     * // => 'Fred'
37786     *
37787     * _.upperFirst('FRED');
37788     * // => 'FRED'
37789     */
37790    var upperFirst = createCaseFirst('toUpperCase');
37791
37792    /**
37793     * Splits `string` into an array of its words.
37794     *
37795     * @static
37796     * @memberOf _
37797     * @since 3.0.0
37798     * @category String
37799     * @param {string} [string=''] The string to inspect.
37800     * @param {RegExp|string} [pattern] The pattern to match words.
37801     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
37802     * @returns {Array} Returns the words of `string`.
37803     * @example
37804     *
37805     * _.words('fred, barney, & pebbles');
37806     * // => ['fred', 'barney', 'pebbles']
37807     *
37808     * _.words('fred, barney, & pebbles', /[^, ]+/g);
37809     * // => ['fred', 'barney', '&', 'pebbles']
37810     */
37811    function words(string, pattern, guard) {
37812      string = toString(string);
37813      pattern = guard ? undefined : pattern;
37814
37815      if (pattern === undefined) {
37816        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
37817      }
37818      return string.match(pattern) || [];
37819    }
37820
37821    /*------------------------------------------------------------------------*/
37822
37823    /**
37824     * Attempts to invoke `func`, returning either the result or the caught error
37825     * object. Any additional arguments are provided to `func` when it's invoked.
37826     *
37827     * @static
37828     * @memberOf _
37829     * @since 3.0.0
37830     * @category Util
37831     * @param {Function} func The function to attempt.
37832     * @param {...*} [args] The arguments to invoke `func` with.
37833     * @returns {*} Returns the `func` result or error object.
37834     * @example
37835     *
37836     * // Avoid throwing errors for invalid selectors.
37837     * var elements = _.attempt(function(selector) {
37838     *   return document.querySelectorAll(selector);
37839     * }, '>_>');
37840     *
37841     * if (_.isError(elements)) {
37842     *   elements = [];
37843     * }
37844     */
37845    var attempt = baseRest(function(func, args) {
37846      try {
37847        return apply(func, undefined, args);
37848      } catch (e) {
37849        return isError(e) ? e : new Error(e);
37850      }
37851    });
37852
37853    /**
37854     * Binds methods of an object to the object itself, overwriting the existing
37855     * method.
37856     *
37857     * **Note:** This method doesn't set the "length" property of bound functions.
37858     *
37859     * @static
37860     * @since 0.1.0
37861     * @memberOf _
37862     * @category Util
37863     * @param {Object} object The object to bind and assign the bound methods to.
37864     * @param {...(string|string[])} methodNames The object method names to bind.
37865     * @returns {Object} Returns `object`.
37866     * @example
37867     *
37868     * var view = {
37869     *   'label': 'docs',
37870     *   'click': function() {
37871     *     console.log('clicked ' + this.label);
37872     *   }
37873     * };
37874     *
37875     * _.bindAll(view, ['click']);
37876     * jQuery(element).on('click', view.click);
37877     * // => Logs 'clicked docs' when clicked.
37878     */
37879    var bindAll = flatRest(function(object, methodNames) {
37880      arrayEach(methodNames, function(key) {
37881        key = toKey(key);
37882        baseAssignValue(object, key, bind(object[key], object));
37883      });
37884      return object;
37885    });
37886
37887    /**
37888     * Creates a function that iterates over `pairs` and invokes the corresponding
37889     * function of the first predicate to return truthy. The predicate-function
37890     * pairs are invoked with the `this` binding and arguments of the created
37891     * function.
37892     *
37893     * @static
37894     * @memberOf _
37895     * @since 4.0.0
37896     * @category Util
37897     * @param {Array} pairs The predicate-function pairs.
37898     * @returns {Function} Returns the new composite function.
37899     * @example
37900     *
37901     * var func = _.cond([
37902     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
37903     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
37904     *   [_.stubTrue,                      _.constant('no match')]
37905     * ]);
37906     *
37907     * func({ 'a': 1, 'b': 2 });
37908     * // => 'matches A'
37909     *
37910     * func({ 'a': 0, 'b': 1 });
37911     * // => 'matches B'
37912     *
37913     * func({ 'a': '1', 'b': '2' });
37914     * // => 'no match'
37915     */
37916    function cond(pairs) {
37917      var length = pairs == null ? 0 : pairs.length,
37918          toIteratee = getIteratee();
37919
37920      pairs = !length ? [] : arrayMap(pairs, function(pair) {
37921        if (typeof pair[1] != 'function') {
37922          throw new TypeError(FUNC_ERROR_TEXT);
37923        }
37924        return [toIteratee(pair[0]), pair[1]];
37925      });
37926
37927      return baseRest(function(args) {
37928        var index = -1;
37929        while (++index < length) {
37930          var pair = pairs[index];
vendor: 10,296 bytes, lines 37931-38263
37931          if (apply(pair[0], this, args)) {
37932            return apply(pair[1], this, args);
37933          }
37934        }
37935      });
37936    }
37937
37938    /**
37939     * Creates a function that invokes the predicate properties of `source` with
37940     * the corresponding property values of a given object, returning `true` if
37941     * all predicates return truthy, else `false`.
37942     *
37943     * **Note:** The created function is equivalent to `_.conformsTo` with
37944     * `source` partially applied.
37945     *
37946     * @static
37947     * @memberOf _
37948     * @since 4.0.0
37949     * @category Util
37950     * @param {Object} source The object of property predicates to conform to.
37951     * @returns {Function} Returns the new spec function.
37952     * @example
37953     *
37954     * var objects = [
37955     *   { 'a': 2, 'b': 1 },
37956     *   { 'a': 1, 'b': 2 }
37957     * ];
37958     *
37959     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
37960     * // => [{ 'a': 1, 'b': 2 }]
37961     */
37962    function conforms(source) {
37963      return baseConforms(baseClone(source, CLONE_DEEP_FLAG));
37964    }
37965
37966    /**
37967     * Creates a function that returns `value`.
37968     *
37969     * @static
37970     * @memberOf _
37971     * @since 2.4.0
37972     * @category Util
37973     * @param {*} value The value to return from the new function.
37974     * @returns {Function} Returns the new constant function.
37975     * @example
37976     *
37977     * var objects = _.times(2, _.constant({ 'a': 1 }));
37978     *
37979     * console.log(objects);
37980     * // => [{ 'a': 1 }, { 'a': 1 }]
37981     *
37982     * console.log(objects[0] === objects[1]);
37983     * // => true
37984     */
37985    function constant(value) {
37986      return function() {
37987        return value;
37988      };
37989    }
37990
37991    /**
37992     * Checks `value` to determine whether a default value should be returned in
37993     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
37994     * or `undefined`.
37995     *
37996     * @static
37997     * @memberOf _
37998     * @since 4.14.0
37999     * @category Util
38000     * @param {*} value The value to check.
38001     * @param {*} defaultValue The default value.
38002     * @returns {*} Returns the resolved value.
38003     * @example
38004     *
38005     * _.defaultTo(1, 10);
38006     * // => 1
38007     *
38008     * _.defaultTo(undefined, 10);
38009     * // => 10
38010     */
38011    function defaultTo(value, defaultValue) {
38012      return (value == null || value !== value) ? defaultValue : value;
38013    }
38014
38015    /**
38016     * Creates a function that returns the result of invoking the given functions
38017     * with the `this` binding of the created function, where each successive
38018     * invocation is supplied the return value of the previous.
38019     *
38020     * @static
38021     * @memberOf _
38022     * @since 3.0.0
38023     * @category Util
38024     * @param {...(Function|Function[])} [funcs] The functions to invoke.
38025     * @returns {Function} Returns the new composite function.
38026     * @see _.flowRight
38027     * @example
38028     *
38029     * function square(n) {
38030     *   return n * n;
38031     * }
38032     *
38033     * var addSquare = _.flow([_.add, square]);
38034     * addSquare(1, 2);
38035     * // => 9
38036     */
38037    var flow = createFlow();
38038
38039    /**
38040     * This method is like `_.flow` except that it creates a function that
38041     * invokes the given functions from right to left.
38042     *
38043     * @static
38044     * @since 3.0.0
38045     * @memberOf _
38046     * @category Util
38047     * @param {...(Function|Function[])} [funcs] The functions to invoke.
38048     * @returns {Function} Returns the new composite function.
38049     * @see _.flow
38050     * @example
38051     *
38052     * function square(n) {
38053     *   return n * n;
38054     * }
38055     *
38056     * var addSquare = _.flowRight([square, _.add]);
38057     * addSquare(1, 2);
38058     * // => 9
38059     */
38060    var flowRight = createFlow(true);
38061
38062    /**
38063     * This method returns the first argument it receives.
38064     *
38065     * @static
38066     * @since 0.1.0
38067     * @memberOf _
38068     * @category Util
38069     * @param {*} value Any value.
38070     * @returns {*} Returns `value`.
38071     * @example
38072     *
38073     * var object = { 'a': 1 };
38074     *
38075     * console.log(_.identity(object) === object);
38076     * // => true
38077     */
38078    function identity(value) {
38079      return value;
38080    }
38081
38082    /**
38083     * Creates a function that invokes `func` with the arguments of the created
38084     * function. If `func` is a property name, the created function returns the
38085     * property value for a given element. If `func` is an array or object, the
38086     * created function returns `true` for elements that contain the equivalent
38087     * source properties, otherwise it returns `false`.
38088     *
38089     * @static
38090     * @since 4.0.0
38091     * @memberOf _
38092     * @category Util
38093     * @param {*} [func=_.identity] The value to convert to a callback.
38094     * @returns {Function} Returns the callback.
38095     * @example
38096     *
38097     * var users = [
38098     *   { 'user': 'barney', 'age': 36, 'active': true },
38099     *   { 'user': 'fred',   'age': 40, 'active': false }
38100     * ];
38101     *
38102     * // The `_.matches` iteratee shorthand.
38103     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
38104     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
38105     *
38106     * // The `_.matchesProperty` iteratee shorthand.
38107     * _.filter(users, _.iteratee(['user', 'fred']));
38108     * // => [{ 'user': 'fred', 'age': 40 }]
38109     *
38110     * // The `_.property` iteratee shorthand.
38111     * _.map(users, _.iteratee('user'));
38112     * // => ['barney', 'fred']
38113     *
38114     * // Create custom iteratee shorthands.
38115     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
38116     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
38117     *     return func.test(string);
38118     *   };
38119     * });
38120     *
38121     * _.filter(['abc', 'def'], /ef/);
38122     * // => ['def']
38123     */
38124    function iteratee(func) {
38125      return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
38126    }
38127
38128    /**
38129     * Creates a function that performs a partial deep comparison between a given
38130     * object and `source`, returning `true` if the given object has equivalent
38131     * property values, else `false`.
38132     *
38133     * **Note:** The created function is equivalent to `_.isMatch` with `source`
38134     * partially applied.
38135     *
38136     * Partial comparisons will match empty array and empty object `source`
38137     * values against any array or object value, respectively. See `_.isEqual`
38138     * for a list of supported value comparisons.
38139     *
38140     * **Note:** Multiple values can be checked by combining several matchers
38141     * using `_.overSome`
38142     *
38143     * @static
38144     * @memberOf _
38145     * @since 3.0.0
38146     * @category Util
38147     * @param {Object} source The object of property values to match.
38148     * @returns {Function} Returns the new spec function.
38149     * @example
38150     *
38151     * var objects = [
38152     *   { 'a': 1, 'b': 2, 'c': 3 },
38153     *   { 'a': 4, 'b': 5, 'c': 6 }
38154     * ];
38155     *
38156     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
38157     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
38158     *
38159     * // Checking for several possible values
38160     * _.filter(objects, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })]));
38161     * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
38162     */
38163    function matches(source) {
38164      return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
38165    }
38166
38167    /**
38168     * Creates a function that performs a partial deep comparison between the
38169     * value at `path` of a given object to `srcValue`, returning `true` if the
38170     * object value is equivalent, else `false`.
38171     *
38172     * **Note:** Partial comparisons will match empty array and empty object
38173     * `srcValue` values against any array or object value, respectively. See
38174     * `_.isEqual` for a list of supported value comparisons.
38175     *
38176     * **Note:** Multiple values can be checked by combining several matchers
38177     * using `_.overSome`
38178     *
38179     * @static
38180     * @memberOf _
38181     * @since 3.2.0
38182     * @category Util
38183     * @param {Array|string} path The path of the property to get.
38184     * @param {*} srcValue The value to match.
38185     * @returns {Function} Returns the new spec function.
38186     * @example
38187     *
38188     * var objects = [
38189     *   { 'a': 1, 'b': 2, 'c': 3 },
38190     *   { 'a': 4, 'b': 5, 'c': 6 }
38191     * ];
38192     *
38193     * _.find(objects, _.matchesProperty('a', 4));
38194     * // => { 'a': 4, 'b': 5, 'c': 6 }
38195     *
38196     * // Checking for several possible values
38197     * _.filter(objects, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)]));
38198     * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }]
38199     */
38200    function matchesProperty(path, srcValue) {
38201      return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
38202    }
38203
38204    /**
38205     * Creates a function that invokes the method at `path` of a given object.
38206     * Any additional arguments are provided to the invoked method.
38207     *
38208     * @static
38209     * @memberOf _
38210     * @since 3.7.0
38211     * @category Util
38212     * @param {Array|string} path The path of the method to invoke.
38213     * @param {...*} [args] The arguments to invoke the method with.
38214     * @returns {Function} Returns the new invoker function.
38215     * @example
38216     *
38217     * var objects = [
38218     *   { 'a': { 'b': _.constant(2) } },
38219     *   { 'a': { 'b': _.constant(1) } }
38220     * ];
38221     *
38222     * _.map(objects, _.method('a.b'));
38223     * // => [2, 1]
38224     *
38225     * _.map(objects, _.method(['a', 'b']));
38226     * // => [2, 1]
38227     */
38228    var method = baseRest(function(path, args) {
38229      return function(object) {
38230        return baseInvoke(object, path, args);
38231      };
38232    });
38233
38234    /**
38235     * The opposite of `_.method`; this method creates a function that invokes
38236     * the method at a given path of `object`. Any additional arguments are
38237     * provided to the invoked method.
38238     *
38239     * @static
38240     * @memberOf _
38241     * @since 3.7.0
38242     * @category Util
38243     * @param {Object} object The object to query.
38244     * @param {...*} [args] The arguments to invoke the method with.
38245     * @returns {Function} Returns the new invoker function.
38246     * @example
38247     *
38248     * var array = _.times(3, _.constant),
38249     *     object = { 'a': array, 'b': array, 'c': array };
38250     *
38251     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
38252     * // => [2, 0]
38253     *
38254     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
38255     * // => [2, 0]
38256     */
38257    var methodOf = baseRest(function(object, args) {
38258      return function(path) {
38259        return baseInvoke(object, path, args);
38260      };
38261    });
38262
38263    /**
vendor: 10,734 bytes, lines 38264-38651
38264     * Adds all own enumerable string keyed function properties of a source
38265     * object to the destination object. If `object` is a function, then methods
38266     * are added to its prototype as well.
38267     *
38268     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
38269     * avoid conflicts caused by modifying the original.
38270     *
38271     * @static
38272     * @since 0.1.0
38273     * @memberOf _
38274     * @category Util
38275     * @param {Function|Object} [object=lodash] The destination object.
38276     * @param {Object} source The object of functions to add.
38277     * @param {Object} [options={}] The options object.
38278     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
38279     * @returns {Function|Object} Returns `object`.
38280     * @example
38281     *
38282     * function vowels(string) {
38283     *   return _.filter(string, function(v) {
38284     *     return /[aeiou]/i.test(v);
38285     *   });
38286     * }
38287     *
38288     * _.mixin({ 'vowels': vowels });
38289     * _.vowels('fred');
38290     * // => ['e']
38291     *
38292     * _('fred').vowels().value();
38293     * // => ['e']
38294     *
38295     * _.mixin({ 'vowels': vowels }, { 'chain': false });
38296     * _('fred').vowels();
38297     * // => ['e']
38298     */
38299    function mixin(object, source, options) {
38300      var props = keys(source),
38301          methodNames = baseFunctions(source, props);
38302
38303      if (options == null &&
38304          !(isObject(source) && (methodNames.length || !props.length))) {
38305        options = source;
38306        source = object;
38307        object = this;
38308        methodNames = baseFunctions(source, keys(source));
38309      }
38310      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
38311          isFunc = isFunction(object);
38312
38313      arrayEach(methodNames, function(methodName) {
38314        var func = source[methodName];
38315        object[methodName] = func;
38316        if (isFunc) {
38317          object.prototype[methodName] = function() {
38318            var chainAll = this.__chain__;
38319            if (chain || chainAll) {
38320              var result = object(this.__wrapped__),
38321                  actions = result.__actions__ = copyArray(this.__actions__);
38322
38323              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
38324              result.__chain__ = chainAll;
38325              return result;
38326            }
38327            return func.apply(object, arrayPush([this.value()], arguments));
38328          };
38329        }
38330      });
38331
38332      return object;
38333    }
38334
38335    /**
38336     * Reverts the `_` variable to its previous value and returns a reference to
38337     * the `lodash` function.
38338     *
38339     * @static
38340     * @since 0.1.0
38341     * @memberOf _
38342     * @category Util
38343     * @returns {Function} Returns the `lodash` function.
38344     * @example
38345     *
38346     * var lodash = _.noConflict();
38347     */
38348    function noConflict() {
38349      if (root._ === this) {
38350        root._ = oldDash;
38351      }
38352      return this;
38353    }
38354
38355    /**
38356     * This method returns `undefined`.
38357     *
38358     * @static
38359     * @memberOf _
38360     * @since 2.3.0
38361     * @category Util
38362     * @example
38363     *
38364     * _.times(2, _.noop);
38365     * // => [undefined, undefined]
38366     */
38367    function noop() {
38368      // No operation performed.
38369    }
38370
38371    /**
38372     * Creates a function that gets the argument at index `n`. If `n` is negative,
38373     * the nth argument from the end is returned.
38374     *
38375     * @static
38376     * @memberOf _
38377     * @since 4.0.0
38378     * @category Util
38379     * @param {number} [n=0] The index of the argument to return.
38380     * @returns {Function} Returns the new pass-thru function.
38381     * @example
38382     *
38383     * var func = _.nthArg(1);
38384     * func('a', 'b', 'c', 'd');
38385     * // => 'b'
38386     *
38387     * var func = _.nthArg(-2);
38388     * func('a', 'b', 'c', 'd');
38389     * // => 'c'
38390     */
38391    function nthArg(n) {
38392      n = toInteger(n);
38393      return baseRest(function(args) {
38394        return baseNth(args, n);
38395      });
38396    }
38397
38398    /**
38399     * Creates a function that invokes `iteratees` with the arguments it receives
38400     * and returns their results.
38401     *
38402     * @static
38403     * @memberOf _
38404     * @since 4.0.0
38405     * @category Util
38406     * @param {...(Function|Function[])} [iteratees=[_.identity]]
38407     *  The iteratees to invoke.
38408     * @returns {Function} Returns the new function.
38409     * @example
38410     *
38411     * var func = _.over([Math.max, Math.min]);
38412     *
38413     * func(1, 2, 3, 4);
38414     * // => [4, 1]
38415     */
38416    var over = createOver(arrayMap);
38417
38418    /**
38419     * Creates a function that checks if **all** of the `predicates` return
38420     * truthy when invoked with the arguments it receives.
38421     *
38422     * Following shorthands are possible for providing predicates.
38423     * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
38424     * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
38425     *
38426     * @static
38427     * @memberOf _
38428     * @since 4.0.0
38429     * @category Util
38430     * @param {...(Function|Function[])} [predicates=[_.identity]]
38431     *  The predicates to check.
38432     * @returns {Function} Returns the new function.
38433     * @example
38434     *
38435     * var func = _.overEvery([Boolean, isFinite]);
38436     *
38437     * func('1');
38438     * // => true
38439     *
38440     * func(null);
38441     * // => false
38442     *
38443     * func(NaN);
38444     * // => false
38445     */
38446    var overEvery = createOver(arrayEvery);
38447
38448    /**
38449     * Creates a function that checks if **any** of the `predicates` return
38450     * truthy when invoked with the arguments it receives.
38451     *
38452     * Following shorthands are possible for providing predicates.
38453     * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate.
38454     * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them.
38455     *
38456     * @static
38457     * @memberOf _
38458     * @since 4.0.0
38459     * @category Util
38460     * @param {...(Function|Function[])} [predicates=[_.identity]]
38461     *  The predicates to check.
38462     * @returns {Function} Returns the new function.
38463     * @example
38464     *
38465     * var func = _.overSome([Boolean, isFinite]);
38466     *
38467     * func('1');
38468     * // => true
38469     *
38470     * func(null);
38471     * // => true
38472     *
38473     * func(NaN);
38474     * // => false
38475     *
38476     * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }])
38477     * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]])
38478     */
38479    var overSome = createOver(arraySome);
38480
38481    /**
38482     * Creates a function that returns the value at `path` of a given object.
38483     *
38484     * @static
38485     * @memberOf _
38486     * @since 2.4.0
38487     * @category Util
38488     * @param {Array|string} path The path of the property to get.
38489     * @returns {Function} Returns the new accessor function.
38490     * @example
38491     *
38492     * var objects = [
38493     *   { 'a': { 'b': 2 } },
38494     *   { 'a': { 'b': 1 } }
38495     * ];
38496     *
38497     * _.map(objects, _.property('a.b'));
38498     * // => [2, 1]
38499     *
38500     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
38501     * // => [1, 2]
38502     */
38503    function property(path) {
38504      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
38505    }
38506
38507    /**
38508     * The opposite of `_.property`; this method creates a function that returns
38509     * the value at a given path of `object`.
38510     *
38511     * @static
38512     * @memberOf _
38513     * @since 3.0.0
38514     * @category Util
38515     * @param {Object} object The object to query.
38516     * @returns {Function} Returns the new accessor function.
38517     * @example
38518     *
38519     * var array = [0, 1, 2],
38520     *     object = { 'a': array, 'b': array, 'c': array };
38521     *
38522     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
38523     * // => [2, 0]
38524     *
38525     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
38526     * // => [2, 0]
38527     */
38528    function propertyOf(object) {
38529      return function(path) {
38530        return object == null ? undefined : baseGet(object, path);
38531      };
38532    }
38533
38534    /**
38535     * Creates an array of numbers (positive and/or negative) progressing from
38536     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
38537     * `start` is specified without an `end` or `step`. If `end` is not specified,
38538     * it's set to `start` with `start` then set to `0`.
38539     *
38540     * **Note:** JavaScript follows the IEEE-754 standard for resolving
38541     * floating-point values which can produce unexpected results.
38542     *
38543     * @static
38544     * @since 0.1.0
38545     * @memberOf _
38546     * @category Util
38547     * @param {number} [start=0] The start of the range.
38548     * @param {number} end The end of the range.
38549     * @param {number} [step=1] The value to increment or decrement by.
38550     * @returns {Array} Returns the range of numbers.
38551     * @see _.inRange, _.rangeRight
38552     * @example
38553     *
38554     * _.range(4);
38555     * // => [0, 1, 2, 3]
38556     *
38557     * _.range(-4);
38558     * // => [0, -1, -2, -3]
38559     *
38560     * _.range(1, 5);
38561     * // => [1, 2, 3, 4]
38562     *
38563     * _.range(0, 20, 5);
38564     * // => [0, 5, 10, 15]
38565     *
38566     * _.range(0, -4, -1);
38567     * // => [0, -1, -2, -3]
38568     *
38569     * _.range(1, 4, 0);
38570     * // => [1, 1, 1]
38571     *
38572     * _.range(0);
38573     * // => []
38574     */
38575    var range = createRange();
38576
38577    /**
38578     * This method is like `_.range` except that it populates values in
38579     * descending order.
38580     *
38581     * @static
38582     * @memberOf _
38583     * @since 4.0.0
38584     * @category Util
38585     * @param {number} [start=0] The start of the range.
38586     * @param {number} end The end of the range.
38587     * @param {number} [step=1] The value to increment or decrement by.
38588     * @returns {Array} Returns the range of numbers.
38589     * @see _.inRange, _.range
38590     * @example
38591     *
38592     * _.rangeRight(4);
38593     * // => [3, 2, 1, 0]
38594     *
38595     * _.rangeRight(-4);
38596     * // => [-3, -2, -1, 0]
38597     *
38598     * _.rangeRight(1, 5);
38599     * // => [4, 3, 2, 1]
38600     *
38601     * _.rangeRight(0, 20, 5);
38602     * // => [15, 10, 5, 0]
38603     *
38604     * _.rangeRight(0, -4, -1);
38605     * // => [-3, -2, -1, 0]
38606     *
38607     * _.rangeRight(1, 4, 0);
38608     * // => [1, 1, 1]
38609     *
38610     * _.rangeRight(0);
38611     * // => []
38612     */
38613    var rangeRight = createRange(true);
38614
38615    /**
38616     * This method returns a new empty array.
38617     *
38618     * @static
38619     * @memberOf _
38620     * @since 4.13.0
38621     * @category Util
38622     * @returns {Array} Returns the new empty array.
38623     * @example
38624     *
38625     * var arrays = _.times(2, _.stubArray);
38626     *
38627     * console.log(arrays);
38628     * // => [[], []]
38629     *
38630     * console.log(arrays[0] === arrays[1]);
38631     * // => false
38632     */
38633    function stubArray() {
38634      return [];
38635    }
38636
38637    /**
38638     * This method returns `false`.
38639     *
38640     * @static
38641     * @memberOf _
38642     * @since 4.13.0
38643     * @category Util
38644     * @returns {boolean} Returns `false`.
38645     * @example
38646     *
38647     * _.times(2, _.stubFalse);
38648     * // => [false, false]
38649     */
38650    function stubFalse() {
38651      return false;
vendor: 1,044 bytes, lines 38652-38705
38652    }
38653
38654    /**
38655     * This method returns a new empty object.
38656     *
38657     * @static
38658     * @memberOf _
38659     * @since 4.13.0
38660     * @category Util
38661     * @returns {Object} Returns the new empty object.
38662     * @example
38663     *
38664     * var objects = _.times(2, _.stubObject);
38665     *
38666     * console.log(objects);
38667     * // => [{}, {}]
38668     *
38669     * console.log(objects[0] === objects[1]);
38670     * // => false
38671     */
38672    function stubObject() {
38673      return {};
38674    }
38675
38676    /**
38677     * This method returns an empty string.
38678     *
38679     * @static
38680     * @memberOf _
38681     * @since 4.13.0
38682     * @category Util
38683     * @returns {string} Returns the empty string.
38684     * @example
38685     *
38686     * _.times(2, _.stubString);
38687     * // => ['', '']
38688     */
38689    function stubString() {
38690      return '';
38691    }
38692
38693    /**
38694     * This method returns `true`.
38695     *
38696     * @static
38697     * @memberOf _
38698     * @since 4.13.0
38699     * @category Util
38700     * @returns {boolean} Returns `true`.
38701     * @example
38702     *
38703     * _.times(2, _.stubTrue);
38704     * // => [true, true]
38705     */
vendor: 9,081 bytes, lines 38706-39049
38706    function stubTrue() {
38707      return true;
38708    }
38709
38710    /**
38711     * Invokes the iteratee `n` times, returning an array of the results of
38712     * each invocation. The iteratee is invoked with one argument; (index).
38713     *
38714     * @static
38715     * @since 0.1.0
38716     * @memberOf _
38717     * @category Util
38718     * @param {number} n The number of times to invoke `iteratee`.
38719     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
38720     * @returns {Array} Returns the array of results.
38721     * @example
38722     *
38723     * _.times(3, String);
38724     * // => ['0', '1', '2']
38725     *
38726     *  _.times(4, _.constant(0));
38727     * // => [0, 0, 0, 0]
38728     */
38729    function times(n, iteratee) {
38730      n = toInteger(n);
38731      if (n < 1 || n > MAX_SAFE_INTEGER) {
38732        return [];
38733      }
38734      var index = MAX_ARRAY_LENGTH,
38735          length = nativeMin(n, MAX_ARRAY_LENGTH);
38736
38737      iteratee = getIteratee(iteratee);
38738      n -= MAX_ARRAY_LENGTH;
38739
38740      var result = baseTimes(length, iteratee);
38741      while (++index < n) {
38742        iteratee(index);
38743      }
38744      return result;
38745    }
38746
38747    /**
38748     * Converts `value` to a property path array.
38749     *
38750     * @static
38751     * @memberOf _
38752     * @since 4.0.0
38753     * @category Util
38754     * @param {*} value The value to convert.
38755     * @returns {Array} Returns the new property path array.
38756     * @example
38757     *
38758     * _.toPath('a.b.c');
38759     * // => ['a', 'b', 'c']
38760     *
38761     * _.toPath('a[0].b.c');
38762     * // => ['a', '0', 'b', 'c']
38763     */
38764    function toPath(value) {
38765      if (isArray(value)) {
38766        return arrayMap(value, toKey);
38767      }
38768      return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
38769    }
38770
38771    /**
38772     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
38773     *
38774     * @static
38775     * @since 0.1.0
38776     * @memberOf _
38777     * @category Util
38778     * @param {string} [prefix=''] The value to prefix the ID with.
38779     * @returns {string} Returns the unique ID.
38780     * @example
38781     *
38782     * _.uniqueId('contact_');
38783     * // => 'contact_104'
38784     *
38785     * _.uniqueId();
38786     * // => '105'
38787     */
38788    function uniqueId(prefix) {
38789      var id = ++idCounter;
38790      return toString(prefix) + id;
38791    }
38792
38793    /*------------------------------------------------------------------------*/
38794
38795    /**
38796     * Adds two numbers.
38797     *
38798     * @static
38799     * @memberOf _
38800     * @since 3.4.0
38801     * @category Math
38802     * @param {number} augend The first number in an addition.
38803     * @param {number} addend The second number in an addition.
38804     * @returns {number} Returns the total.
38805     * @example
38806     *
38807     * _.add(6, 4);
38808     * // => 10
38809     */
38810    var add = createMathOperation(function(augend, addend) {
38811      return augend + addend;
38812    }, 0);
38813
38814    /**
38815     * Computes `number` rounded up to `precision`.
38816     *
38817     * @static
38818     * @memberOf _
38819     * @since 3.10.0
38820     * @category Math
38821     * @param {number} number The number to round up.
38822     * @param {number} [precision=0] The precision to round up to.
38823     * @returns {number} Returns the rounded up number.
38824     * @example
38825     *
38826     * _.ceil(4.006);
38827     * // => 5
38828     *
38829     * _.ceil(6.004, 2);
38830     * // => 6.01
38831     *
38832     * _.ceil(6040, -2);
38833     * // => 6100
38834     */
38835    var ceil = createRound('ceil');
38836
38837    /**
38838     * Divide two numbers.
38839     *
38840     * @static
38841     * @memberOf _
38842     * @since 4.7.0
38843     * @category Math
38844     * @param {number} dividend The first number in a division.
38845     * @param {number} divisor The second number in a division.
38846     * @returns {number} Returns the quotient.
38847     * @example
38848     *
38849     * _.divide(6, 4);
38850     * // => 1.5
38851     */
38852    var divide = createMathOperation(function(dividend, divisor) {
38853      return dividend / divisor;
38854    }, 1);
38855
38856    /**
38857     * Computes `number` rounded down to `precision`.
38858     *
38859     * @static
38860     * @memberOf _
38861     * @since 3.10.0
38862     * @category Math
38863     * @param {number} number The number to round down.
38864     * @param {number} [precision=0] The precision to round down to.
38865     * @returns {number} Returns the rounded down number.
38866     * @example
38867     *
38868     * _.floor(4.006);
38869     * // => 4
38870     *
38871     * _.floor(0.046, 2);
38872     * // => 0.04
38873     *
38874     * _.floor(4060, -2);
38875     * // => 4000
38876     */
38877    var floor = createRound('floor');
38878
38879    /**
38880     * Computes the maximum value of `array`. If `array` is empty or falsey,
38881     * `undefined` is returned.
38882     *
38883     * @static
38884     * @since 0.1.0
38885     * @memberOf _
38886     * @category Math
38887     * @param {Array} array The array to iterate over.
38888     * @returns {*} Returns the maximum value.
38889     * @example
38890     *
38891     * _.max([4, 2, 8, 6]);
38892     * // => 8
38893     *
38894     * _.max([]);
38895     * // => undefined
38896     */
38897    function max(array) {
38898      return (array && array.length)
38899        ? baseExtremum(array, identity, baseGt)
38900        : undefined;
38901    }
38902
38903    /**
38904     * This method is like `_.max` except that it accepts `iteratee` which is
38905     * invoked for each element in `array` to generate the criterion by which
38906     * the value is ranked. The iteratee is invoked with one argument: (value).
38907     *
38908     * @static
38909     * @memberOf _
38910     * @since 4.0.0
38911     * @category Math
38912     * @param {Array} array The array to iterate over.
38913     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
38914     * @returns {*} Returns the maximum value.
38915     * @example
38916     *
38917     * var objects = [{ 'n': 1 }, { 'n': 2 }];
38918     *
38919     * _.maxBy(objects, function(o) { return o.n; });
38920     * // => { 'n': 2 }
38921     *
38922     * // The `_.property` iteratee shorthand.
38923     * _.maxBy(objects, 'n');
38924     * // => { 'n': 2 }
38925     */
38926    function maxBy(array, iteratee) {
38927      return (array && array.length)
38928        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
38929        : undefined;
38930    }
38931
38932    /**
38933     * Computes the mean of the values in `array`.
38934     *
38935     * @static
38936     * @memberOf _
38937     * @since 4.0.0
38938     * @category Math
38939     * @param {Array} array The array to iterate over.
38940     * @returns {number} Returns the mean.
38941     * @example
38942     *
38943     * _.mean([4, 2, 8, 6]);
38944     * // => 5
38945     */
38946    function mean(array) {
38947      return baseMean(array, identity);
38948    }
38949
38950    /**
38951     * This method is like `_.mean` except that it accepts `iteratee` which is
38952     * invoked for each element in `array` to generate the value to be averaged.
38953     * The iteratee is invoked with one argument: (value).
38954     *
38955     * @static
38956     * @memberOf _
38957     * @since 4.7.0
38958     * @category Math
38959     * @param {Array} array The array to iterate over.
38960     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
38961     * @returns {number} Returns the mean.
38962     * @example
38963     *
38964     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
38965     *
38966     * _.meanBy(objects, function(o) { return o.n; });
38967     * // => 5
38968     *
38969     * // The `_.property` iteratee shorthand.
38970     * _.meanBy(objects, 'n');
38971     * // => 5
38972     */
38973    function meanBy(array, iteratee) {
38974      return baseMean(array, getIteratee(iteratee, 2));
38975    }
38976
38977    /**
38978     * Computes the minimum value of `array`. If `array` is empty or falsey,
38979     * `undefined` is returned.
38980     *
38981     * @static
38982     * @since 0.1.0
38983     * @memberOf _
38984     * @category Math
38985     * @param {Array} array The array to iterate over.
38986     * @returns {*} Returns the minimum value.
38987     * @example
38988     *
38989     * _.min([4, 2, 8, 6]);
38990     * // => 2
38991     *
38992     * _.min([]);
38993     * // => undefined
38994     */
38995    function min(array) {
38996      return (array && array.length)
38997        ? baseExtremum(array, identity, baseLt)
38998        : undefined;
38999    }
39000
39001    /**
39002     * This method is like `_.min` except that it accepts `iteratee` which is
39003     * invoked for each element in `array` to generate the criterion by which
39004     * the value is ranked. The iteratee is invoked with one argument: (value).
39005     *
39006     * @static
39007     * @memberOf _
39008     * @since 4.0.0
39009     * @category Math
39010     * @param {Array} array The array to iterate over.
39011     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
39012     * @returns {*} Returns the minimum value.
39013     * @example
39014     *
39015     * var objects = [{ 'n': 1 }, { 'n': 2 }];
39016     *
39017     * _.minBy(objects, function(o) { return o.n; });
39018     * // => { 'n': 1 }
39019     *
39020     * // The `_.property` iteratee shorthand.
39021     * _.minBy(objects, 'n');
39022     * // => { 'n': 1 }
39023     */
39024    function minBy(array, iteratee) {
39025      return (array && array.length)
39026        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
39027        : undefined;
39028    }
39029
39030    /**
39031     * Multiply two numbers.
39032     *
39033     * @static
39034     * @memberOf _
39035     * @since 4.7.0
39036     * @category Math
39037     * @param {number} multiplier The first number in a multiplication.
39038     * @param {number} multiplicand The second number in a multiplication.
39039     * @returns {number} Returns the product.
39040     * @example
39041     *
39042     * _.multiply(6, 4);
39043     * // => 24
39044     */
39045    var multiply = createMathOperation(function(multiplier, multiplicand) {
39046      return multiplier * multiplicand;
39047    }, 1);
39048
39049    /**
vendor: 13,137 bytes, lines 39050-39488
39050     * Computes `number` rounded to `precision`.
39051     *
39052     * @static
39053     * @memberOf _
39054     * @since 3.10.0
39055     * @category Math
39056     * @param {number} number The number to round.
39057     * @param {number} [precision=0] The precision to round to.
39058     * @returns {number} Returns the rounded number.
39059     * @example
39060     *
39061     * _.round(4.006);
39062     * // => 4
39063     *
39064     * _.round(4.006, 2);
39065     * // => 4.01
39066     *
39067     * _.round(4060, -2);
39068     * // => 4100
39069     */
39070    var round = createRound('round');
39071
39072    /**
39073     * Subtract two numbers.
39074     *
39075     * @static
39076     * @memberOf _
39077     * @since 4.0.0
39078     * @category Math
39079     * @param {number} minuend The first number in a subtraction.
39080     * @param {number} subtrahend The second number in a subtraction.
39081     * @returns {number} Returns the difference.
39082     * @example
39083     *
39084     * _.subtract(6, 4);
39085     * // => 2
39086     */
39087    var subtract = createMathOperation(function(minuend, subtrahend) {
39088      return minuend - subtrahend;
39089    }, 0);
39090
39091    /**
39092     * Computes the sum of the values in `array`.
39093     *
39094     * @static
39095     * @memberOf _
39096     * @since 3.4.0
39097     * @category Math
39098     * @param {Array} array The array to iterate over.
39099     * @returns {number} Returns the sum.
39100     * @example
39101     *
39102     * _.sum([4, 2, 8, 6]);
39103     * // => 20
39104     */
39105    function sum(array) {
39106      return (array && array.length)
39107        ? baseSum(array, identity)
39108        : 0;
39109    }
39110
39111    /**
39112     * This method is like `_.sum` except that it accepts `iteratee` which is
39113     * invoked for each element in `array` to generate the value to be summed.
39114     * The iteratee is invoked with one argument: (value).
39115     *
39116     * @static
39117     * @memberOf _
39118     * @since 4.0.0
39119     * @category Math
39120     * @param {Array} array The array to iterate over.
39121     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
39122     * @returns {number} Returns the sum.
39123     * @example
39124     *
39125     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
39126     *
39127     * _.sumBy(objects, function(o) { return o.n; });
39128     * // => 20
39129     *
39130     * // The `_.property` iteratee shorthand.
39131     * _.sumBy(objects, 'n');
39132     * // => 20
39133     */
39134    function sumBy(array, iteratee) {
39135      return (array && array.length)
39136        ? baseSum(array, getIteratee(iteratee, 2))
39137        : 0;
39138    }
39139
39140    /*------------------------------------------------------------------------*/
39141
39142    // Add methods that return wrapped values in chain sequences.
39143    lodash.after = after;
39144    lodash.ary = ary;
39145    lodash.assign = assign;
39146    lodash.assignIn = assignIn;
39147    lodash.assignInWith = assignInWith;
39148    lodash.assignWith = assignWith;
39149    lodash.at = at;
39150    lodash.before = before;
39151    lodash.bind = bind;
39152    lodash.bindAll = bindAll;
39153    lodash.bindKey = bindKey;
39154    lodash.castArray = castArray;
39155    lodash.chain = chain;
39156    lodash.chunk = chunk;
39157    lodash.compact = compact;
39158    lodash.concat = concat;
39159    lodash.cond = cond;
39160    lodash.conforms = conforms;
39161    lodash.constant = constant;
39162    lodash.countBy = countBy;
39163    lodash.create = create;
39164    lodash.curry = curry;
39165    lodash.curryRight = curryRight;
39166    lodash.debounce = debounce;
39167    lodash.defaults = defaults;
39168    lodash.defaultsDeep = defaultsDeep;
39169    lodash.defer = defer;
39170    lodash.delay = delay;
39171    lodash.difference = difference;
39172    lodash.differenceBy = differenceBy;
39173    lodash.differenceWith = differenceWith;
39174    lodash.drop = drop;
39175    lodash.dropRight = dropRight;
39176    lodash.dropRightWhile = dropRightWhile;
39177    lodash.dropWhile = dropWhile;
39178    lodash.fill = fill;
39179    lodash.filter = filter;
39180    lodash.flatMap = flatMap;
39181    lodash.flatMapDeep = flatMapDeep;
39182    lodash.flatMapDepth = flatMapDepth;
39183    lodash.flatten = flatten;
39184    lodash.flattenDeep = flattenDeep;
39185    lodash.flattenDepth = flattenDepth;
39186    lodash.flip = flip;
39187    lodash.flow = flow;
39188    lodash.flowRight = flowRight;
39189    lodash.fromPairs = fromPairs;
39190    lodash.functions = functions;
39191    lodash.functionsIn = functionsIn;
39192    lodash.groupBy = groupBy;
39193    lodash.initial = initial;
39194    lodash.intersection = intersection;
39195    lodash.intersectionBy = intersectionBy;
39196    lodash.intersectionWith = intersectionWith;
39197    lodash.invert = invert;
39198    lodash.invertBy = invertBy;
39199    lodash.invokeMap = invokeMap;
39200    lodash.iteratee = iteratee;
39201    lodash.keyBy = keyBy;
39202    lodash.keys = keys;
39203    lodash.keysIn = keysIn;
39204    lodash.map = map;
39205    lodash.mapKeys = mapKeys;
39206    lodash.mapValues = mapValues;
39207    lodash.matches = matches;
39208    lodash.matchesProperty = matchesProperty;
39209    lodash.memoize = memoize;
39210    lodash.merge = merge;
39211    lodash.mergeWith = mergeWith;
39212    lodash.method = method;
39213    lodash.methodOf = methodOf;
39214    lodash.mixin = mixin;
39215    lodash.negate = negate;
39216    lodash.nthArg = nthArg;
39217    lodash.omit = omit;
39218    lodash.omitBy = omitBy;
39219    lodash.once = once;
39220    lodash.orderBy = orderBy;
39221    lodash.over = over;
39222    lodash.overArgs = overArgs;
39223    lodash.overEvery = overEvery;
39224    lodash.overSome = overSome;
39225    lodash.partial = partial;
39226    lodash.partialRight = partialRight;
39227    lodash.partition = partition;
39228    lodash.pick = pick;
39229    lodash.pickBy = pickBy;
39230    lodash.property = property;
39231    lodash.propertyOf = propertyOf;
39232    lodash.pull = pull;
39233    lodash.pullAll = pullAll;
39234    lodash.pullAllBy = pullAllBy;
39235    lodash.pullAllWith = pullAllWith;
39236    lodash.pullAt = pullAt;
39237    lodash.range = range;
39238    lodash.rangeRight = rangeRight;
39239    lodash.rearg = rearg;
39240    lodash.reject = reject;
39241    lodash.remove = remove;
39242    lodash.rest = rest;
39243    lodash.reverse = reverse;
39244    lodash.sampleSize = sampleSize;
39245    lodash.set = set;
39246    lodash.setWith = setWith;
39247    lodash.shuffle = shuffle;
39248    lodash.slice = slice;
39249    lodash.sortBy = sortBy;
39250    lodash.sortedUniq = sortedUniq;
39251    lodash.sortedUniqBy = sortedUniqBy;
39252    lodash.split = split;
39253    lodash.spread = spread;
39254    lodash.tail = tail;
39255    lodash.take = take;
39256    lodash.takeRight = takeRight;
39257    lodash.takeRightWhile = takeRightWhile;
39258    lodash.takeWhile = takeWhile;
39259    lodash.tap = tap;
39260    lodash.throttle = throttle;
39261    lodash.thru = thru;
39262    lodash.toArray = toArray;
39263    lodash.toPairs = toPairs;
39264    lodash.toPairsIn = toPairsIn;
39265    lodash.toPath = toPath;
39266    lodash.toPlainObject = toPlainObject;
39267    lodash.transform = transform;
39268    lodash.unary = unary;
39269    lodash.union = union;
39270    lodash.unionBy = unionBy;
39271    lodash.unionWith = unionWith;
39272    lodash.uniq = uniq;
39273    lodash.uniqBy = uniqBy;
39274    lodash.uniqWith = uniqWith;
39275    lodash.unset = unset;
39276    lodash.unzip = unzip;
39277    lodash.unzipWith = unzipWith;
39278    lodash.update = update;
39279    lodash.updateWith = updateWith;
39280    lodash.values = values;
39281    lodash.valuesIn = valuesIn;
39282    lodash.without = without;
39283    lodash.words = words;
39284    lodash.wrap = wrap;
39285    lodash.xor = xor;
39286    lodash.xorBy = xorBy;
39287    lodash.xorWith = xorWith;
39288    lodash.zip = zip;
39289    lodash.zipObject = zipObject;
39290    lodash.zipObjectDeep = zipObjectDeep;
39291    lodash.zipWith = zipWith;
39292
39293    // Add aliases.
39294    lodash.entries = toPairs;
39295    lodash.entriesIn = toPairsIn;
39296    lodash.extend = assignIn;
39297    lodash.extendWith = assignInWith;
39298
39299    // Add methods to `lodash.prototype`.
39300    mixin(lodash, lodash);
39301
39302    /*------------------------------------------------------------------------*/
39303
39304    // Add methods that return unwrapped values in chain sequences.
39305    lodash.add = add;
39306    lodash.attempt = attempt;
39307    lodash.camelCase = camelCase;
39308    lodash.capitalize = capitalize;
39309    lodash.ceil = ceil;
39310    lodash.clamp = clamp;
39311    lodash.clone = clone;
39312    lodash.cloneDeep = cloneDeep;
39313    lodash.cloneDeepWith = cloneDeepWith;
39314    lodash.cloneWith = cloneWith;
39315    lodash.conformsTo = conformsTo;
39316    lodash.deburr = deburr;
39317    lodash.defaultTo = defaultTo;
39318    lodash.divide = divide;
39319    lodash.endsWith = endsWith;
39320    lodash.eq = eq;
39321    lodash.escape = escape;
39322    lodash.escapeRegExp = escapeRegExp;
39323    lodash.every = every;
39324    lodash.find = find;
39325    lodash.findIndex = findIndex;
39326    lodash.findKey = findKey;
39327    lodash.findLast = findLast;
39328    lodash.findLastIndex = findLastIndex;
39329    lodash.findLastKey = findLastKey;
39330    lodash.floor = floor;
39331    lodash.forEach = forEach;
39332    lodash.forEachRight = forEachRight;
39333    lodash.forIn = forIn;
39334    lodash.forInRight = forInRight;
39335    lodash.forOwn = forOwn;
39336    lodash.forOwnRight = forOwnRight;
39337    lodash.get = get;
39338    lodash.gt = gt;
39339    lodash.gte = gte;
39340    lodash.has = has;
39341    lodash.hasIn = hasIn;
39342    lodash.head = head;
39343    lodash.identity = identity;
39344    lodash.includes = includes;
39345    lodash.indexOf = indexOf;
39346    lodash.inRange = inRange;
39347    lodash.invoke = invoke;
39348    lodash.isArguments = isArguments;
39349    lodash.isArray = isArray;
39350    lodash.isArrayBuffer = isArrayBuffer;
39351    lodash.isArrayLike = isArrayLike;
39352    lodash.isArrayLikeObject = isArrayLikeObject;
39353    lodash.isBoolean = isBoolean;
39354    lodash.isBuffer = isBuffer;
39355    lodash.isDate = isDate;
39356    lodash.isElement = isElement;
39357    lodash.isEmpty = isEmpty;
39358    lodash.isEqual = isEqual;
39359    lodash.isEqualWith = isEqualWith;
39360    lodash.isError = isError;
39361    lodash.isFinite = isFinite;
39362    lodash.isFunction = isFunction;
39363    lodash.isInteger = isInteger;
39364    lodash.isLength = isLength;
39365    lodash.isMap = isMap;
39366    lodash.isMatch = isMatch;
39367    lodash.isMatchWith = isMatchWith;
39368    lodash.isNaN = isNaN;
39369    lodash.isNative = isNative;
39370    lodash.isNil = isNil;
39371    lodash.isNull = isNull;
39372    lodash.isNumber = isNumber;
39373    lodash.isObject = isObject;
39374    lodash.isObjectLike = isObjectLike;
39375    lodash.isPlainObject = isPlainObject;
39376    lodash.isRegExp = isRegExp;
39377    lodash.isSafeInteger = isSafeInteger;
39378    lodash.isSet = isSet;
39379    lodash.isString = isString;
39380    lodash.isSymbol = isSymbol;
39381    lodash.isTypedArray = isTypedArray;
39382    lodash.isUndefined = isUndefined;
39383    lodash.isWeakMap = isWeakMap;
39384    lodash.isWeakSet = isWeakSet;
39385    lodash.join = join;
39386    lodash.kebabCase = kebabCase;
39387    lodash.last = last;
39388    lodash.lastIndexOf = lastIndexOf;
39389    lodash.lowerCase = lowerCase;
39390    lodash.lowerFirst = lowerFirst;
39391    lodash.lt = lt;
39392    lodash.lte = lte;
39393    lodash.max = max;
39394    lodash.maxBy = maxBy;
39395    lodash.mean = mean;
39396    lodash.meanBy = meanBy;
39397    lodash.min = min;
39398    lodash.minBy = minBy;
39399    lodash.stubArray = stubArray;
39400    lodash.stubFalse = stubFalse;
39401    lodash.stubObject = stubObject;
39402    lodash.stubString = stubString;
39403    lodash.stubTrue = stubTrue;
39404    lodash.multiply = multiply;
39405    lodash.nth = nth;
39406    lodash.noConflict = noConflict;
39407    lodash.noop = noop;
39408    lodash.now = now;
39409    lodash.pad = pad;
39410    lodash.padEnd = padEnd;
39411    lodash.padStart = padStart;
39412    lodash.parseInt = parseInt;
39413    lodash.random = random;
39414    lodash.reduce = reduce;
39415    lodash.reduceRight = reduceRight;
39416    lodash.repeat = repeat;
39417    lodash.replace = replace;
39418    lodash.result = result;
39419    lodash.round = round;
39420    lodash.runInContext = runInContext;
39421    lodash.sample = sample;
39422    lodash.size = size;
39423    lodash.snakeCase = snakeCase;
39424    lodash.some = some;
39425    lodash.sortedIndex = sortedIndex;
39426    lodash.sortedIndexBy = sortedIndexBy;
39427    lodash.sortedIndexOf = sortedIndexOf;
39428    lodash.sortedLastIndex = sortedLastIndex;
39429    lodash.sortedLastIndexBy = sortedLastIndexBy;
39430    lodash.sortedLastIndexOf = sortedLastIndexOf;
39431    lodash.startCase = startCase;
39432    lodash.startsWith = startsWith;
39433    lodash.subtract = subtract;
39434    lodash.sum = sum;
39435    lodash.sumBy = sumBy;
39436    lodash.template = template;
39437    lodash.times = times;
39438    lodash.toFinite = toFinite;
39439    lodash.toInteger = toInteger;
39440    lodash.toLength = toLength;
39441    lodash.toLower = toLower;
39442    lodash.toNumber = toNumber;
39443    lodash.toSafeInteger = toSafeInteger;
39444    lodash.toString = toString;
39445    lodash.toUpper = toUpper;
39446    lodash.trim = trim;
39447    lodash.trimEnd = trimEnd;
39448    lodash.trimStart = trimStart;
39449    lodash.truncate = truncate;
39450    lodash.unescape = unescape;
39451    lodash.uniqueId = uniqueId;
39452    lodash.upperCase = upperCase;
39453    lodash.upperFirst = upperFirst;
39454
39455    // Add aliases.
39456    lodash.each = forEach;
39457    lodash.eachRight = forEachRight;
39458    lodash.first = head;
39459
39460    mixin(lodash, (function() {
39461      var source = {};
39462      baseForOwn(lodash, function(func, methodName) {
39463        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
39464          source[methodName] = func;
39465        }
39466      });
39467      return source;
39468    }()), { 'chain': false });
39469
39470    /*------------------------------------------------------------------------*/
39471
39472    /**
39473     * The semantic version number.
39474     *
39475     * @static
39476     * @memberOf _
39477     * @type {string}
39478     */
39479    lodash.VERSION = VERSION;
39480
39481    // Assign default placeholders.
39482    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
39483      lodash[methodName].placeholder = lodash;
39484    });
39485
39486    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
39487    arrayEach(['drop', 'take'], function(methodName, index) {
39488      LazyWrapper.prototype[methodName] = function(n) {
vendor: 7,434 bytes, lines 39489-39706
39489        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
39490
39491        var result = (this.__filtered__ && !index)
39492          ? new LazyWrapper(this)
39493          : this.clone();
39494
39495        if (result.__filtered__) {
39496          result.__takeCount__ = nativeMin(n, result.__takeCount__);
39497        } else {
39498          result.__views__.push({
39499            'size': nativeMin(n, MAX_ARRAY_LENGTH),
39500            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
39501          });
39502        }
39503        return result;
39504      };
39505
39506      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
39507        return this.reverse()[methodName](n).reverse();
39508      };
39509    });
39510
39511    // Add `LazyWrapper` methods that accept an `iteratee` value.
39512    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
39513      var type = index + 1,
39514          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
39515
39516      LazyWrapper.prototype[methodName] = function(iteratee) {
39517        var result = this.clone();
39518        result.__iteratees__.push({
39519          'iteratee': getIteratee(iteratee, 3),
39520          'type': type
39521        });
39522        result.__filtered__ = result.__filtered__ || isFilter;
39523        return result;
39524      };
39525    });
39526
39527    // Add `LazyWrapper` methods for `_.head` and `_.last`.
39528    arrayEach(['head', 'last'], function(methodName, index) {
39529      var takeName = 'take' + (index ? 'Right' : '');
39530
39531      LazyWrapper.prototype[methodName] = function() {
39532        return this[takeName](1).value()[0];
39533      };
39534    });
39535
39536    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
39537    arrayEach(['initial', 'tail'], function(methodName, index) {
39538      var dropName = 'drop' + (index ? '' : 'Right');
39539
39540      LazyWrapper.prototype[methodName] = function() {
39541        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
39542      };
39543    });
39544
39545    LazyWrapper.prototype.compact = function() {
39546      return this.filter(identity);
39547    };
39548
39549    LazyWrapper.prototype.find = function(predicate) {
39550      return this.filter(predicate).head();
39551    };
39552
39553    LazyWrapper.prototype.findLast = function(predicate) {
39554      return this.reverse().find(predicate);
39555    };
39556
39557    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
39558      if (typeof path == 'function') {
39559        return new LazyWrapper(this);
39560      }
39561      return this.map(function(value) {
39562        return baseInvoke(value, path, args);
39563      });
39564    });
39565
39566    LazyWrapper.prototype.reject = function(predicate) {
39567      return this.filter(negate(getIteratee(predicate)));
39568    };
39569
39570    LazyWrapper.prototype.slice = function(start, end) {
39571      start = toInteger(start);
39572
39573      var result = this;
39574      if (result.__filtered__ && (start > 0 || end < 0)) {
39575        return new LazyWrapper(result);
39576      }
39577      if (start < 0) {
39578        result = result.takeRight(-start);
39579      } else if (start) {
39580        result = result.drop(start);
39581      }
39582      if (end !== undefined) {
39583        end = toInteger(end);
39584        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
39585      }
39586      return result;
39587    };
39588
39589    LazyWrapper.prototype.takeRightWhile = function(predicate) {
39590      return this.reverse().takeWhile(predicate).reverse();
39591    };
39592
39593    LazyWrapper.prototype.toArray = function() {
39594      return this.take(MAX_ARRAY_LENGTH);
39595    };
39596
39597    // Add `LazyWrapper` methods to `lodash.prototype`.
39598    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
39599      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
39600          isTaker = /^(?:head|last)$/.test(methodName),
39601          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
39602          retUnwrapped = isTaker || /^find/.test(methodName);
39603
39604      if (!lodashFunc) {
39605        return;
39606      }
39607      lodash.prototype[methodName] = function() {
39608        var value = this.__wrapped__,
39609            args = isTaker ? [1] : arguments,
39610            isLazy = value instanceof LazyWrapper,
39611            iteratee = args[0],
39612            useLazy = isLazy || isArray(value);
39613
39614        var interceptor = function(value) {
39615          var result = lodashFunc.apply(lodash, arrayPush([value], args));
39616          return (isTaker && chainAll) ? result[0] : result;
39617        };
39618
39619        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
39620          // Avoid lazy use if the iteratee has a "length" value other than `1`.
39621          isLazy = useLazy = false;
39622        }
39623        var chainAll = this.__chain__,
39624            isHybrid = !!this.__actions__.length,
39625            isUnwrapped = retUnwrapped && !chainAll,
39626            onlyLazy = isLazy && !isHybrid;
39627
39628        if (!retUnwrapped && useLazy) {
39629          value = onlyLazy ? value : new LazyWrapper(this);
39630          var result = func.apply(value, args);
39631          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
39632          return new LodashWrapper(result, chainAll);
39633        }
39634        if (isUnwrapped && onlyLazy) {
39635          return func.apply(this, args);
39636        }
39637        result = this.thru(interceptor);
39638        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
39639      };
39640    });
39641
39642    // Add `Array` methods to `lodash.prototype`.
39643    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
39644      var func = arrayProto[methodName],
39645          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
39646          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
39647
39648      lodash.prototype[methodName] = function() {
39649        var args = arguments;
39650        if (retUnwrapped && !this.__chain__) {
39651          var value = this.value();
39652          return func.apply(isArray(value) ? value : [], args);
39653        }
39654        return this[chainName](function(value) {
39655          return func.apply(isArray(value) ? value : [], args);
39656        });
39657      };
39658    });
39659
39660    // Map minified method names to their real names.
39661    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
39662      var lodashFunc = lodash[methodName];
39663      if (lodashFunc) {
39664        var key = lodashFunc.name + '';
39665        if (!hasOwnProperty.call(realNames, key)) {
39666          realNames[key] = [];
39667        }
39668        realNames[key].push({ 'name': methodName, 'func': lodashFunc });
39669      }
39670    });
39671
39672    realNames[createHybrid(undefined, WRAP_BIND_KEY_FLAG).name] = [{
39673      'name': 'wrapper',
39674      'func': undefined
39675    }];
39676
39677    // Add methods to `LazyWrapper`.
39678    LazyWrapper.prototype.clone = lazyClone;
39679    LazyWrapper.prototype.reverse = lazyReverse;
39680    LazyWrapper.prototype.value = lazyValue;
39681
39682    // Add chain sequence methods to the `lodash` wrapper.
39683    lodash.prototype.at = wrapperAt;
39684    lodash.prototype.chain = wrapperChain;
39685    lodash.prototype.commit = wrapperCommit;
39686    lodash.prototype.next = wrapperNext;
39687    lodash.prototype.plant = wrapperPlant;
39688    lodash.prototype.reverse = wrapperReverse;
39689    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
39690
39691    // Add lazy aliases.
39692    lodash.prototype.first = lodash.prototype.head;
39693
39694    if (symIterator) {
39695      lodash.prototype[symIterator] = wrapperToIterator;
39696    }
39697    return lodash;
39698  });
39699
39700  /*--------------------------------------------------------------------------*/
39701
39702  // Export lodash.
39703  var _ = runInContext();
39704
39705  // Some AMD build optimizers, like r.js, check for condition patterns like:
39706  if (t
39706ypeof define == 'function' && typeof define.amd == 'object' && define.amd) {
39707    // Expose Lodash on the global object to prevent errors when Lodash is
39708    // loaded by a script tag in the presence of an AMD loader.
39709    // See http://requirejs.org/docs/errors.html#mismatch for more details.
39710    // Use `_.noConflict` to remove Lodash from the global object.
39711    root._ = _;
39712
39713    // Define as an anonymous module so, through path mapping, it can be
39714    // referenced as the "underscore" module.
39715    define(function() {
39716      return _;
39717    });
39718  }
39719  // Check for `exports` after `define` in case a build optimizer adds it.
39720  else if (freeModule) {
39721    // Export for Node.js.
39722    (freeModule.exports = _)._ = _;
39723    // Export for CommonJS support.
39724    freeExports._ = _;
39725  }
39726  else {
39727    // Export to the global object.
39728    root._ = _;
39729  }
39730}.call(this));
39731
39732}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
39733},{}],112:[function(require,module,exports){
39734'use strict';
39735
39736/** @type {import('./abs')} */
39737module.exports = Math.abs;
39738
39739},{}],113:[function(require,module,exports){
39740'use strict';
39741
39742/** @type {import('./floor')} */
39743module.exports = Math.floor;
39744
39745},{}],114:[function(require,module,exports){
39746'use strict';
39747
39748/** @type {import('./isNaN')} */
39749module.exports = Number.isNaN || function isNaN(a) {
39750	return a !== a;
39751};
39752
39753},{}],115:[function(require,module,exports){
39754'use strict';
39755
39756/** @type {import('./max')} */
39757module.exports = Math.max;
39758
39759},{}],116:[function(require,module,exports){
39760'use strict';
39761
39762/** @type {import('./min')} */
39763module.exports = Math.min;
39764
39765},{}],117:[function(require,module,exports){
39766'use strict';
39767
39768/** @type {import('./pow')} */
39769module.exports = Math.pow;
39770
39771},{}],118:[function(require,module,exports){
39772'use strict';
39773
39774/** @type {import('./round')} */
39775module.exports = Math.round;
39776
39777},{}],119:[function(require,module,exports){
39778'use strict';
39779
39780var $isNaN = require('./isNaN');
39781
39782/** @type {import('./sign')} */
39783module.exports = function sign(number) {
39784	if ($isNaN(number) || number === 0) {
39785		return number;
39786	}
39787	return number < 0 ? -1 : +1;
39788};
39789
39790},{"./isNaN":114}],120:[function(require,module,exports){
39791(function (global
vendor: 6,766 bytes, lines 39791-39964
39791){
39792var hasMap = typeof Map === 'function' && Map.prototype;
39793var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
39794var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
39795var mapForEach = hasMap && Map.prototype.forEach;
39796var hasSet = typeof Set === 'function' && Set.prototype;
39797var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
39798var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
39799var setForEach = hasSet && Set.prototype.forEach;
39800var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
39801var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
39802var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
39803var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
39804var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
39805var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
39806var booleanValueOf = Boolean.prototype.valueOf;
39807var objectToString = Object.prototype.toString;
39808var functionToString = Function.prototype.toString;
39809var $match = String.prototype.match;
39810var $slice = String.prototype.slice;
39811var $replace = String.prototype.replace;
39812var $toUpperCase = String.prototype.toUpperCase;
39813var $toLowerCase = String.prototype.toLowerCase;
39814var $test = RegExp.prototype.test;
39815var $concat = Array.prototype.concat;
39816var $join = Array.prototype.join;
39817var $arrSlice = Array.prototype.slice;
39818var $floor = Math.floor;
39819var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
39820var gOPS = Object.getOwnPropertySymbols;
39821var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
39822var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
39823// ie, `has-tostringtag/shams
39824var toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')
39825    ? Symbol.toStringTag
39826    : null;
39827var isEnumerable = Object.prototype.propertyIsEnumerable;
39828
39829var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
39830    [].__proto__ === Array.prototype // eslint-disable-line no-proto
39831        ? function (O) {
39832            return O.__proto__; // eslint-disable-line no-proto
39833        }
39834        : null
39835);
39836
39837function addNumericSeparator(num, str) {
39838    if (
39839        num === Infinity
39840        || num === -Infinity
39841        || num !== num
39842        || (num && num > -1000 && num < 1000)
39843        || $test.call(/e/, str)
39844    ) {
39845        return str;
39846    }
39847    var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;
39848    if (typeof num === 'number') {
39849        var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)
39850        if (int !== num) {
39851            var intStr = String(int);
39852            var dec = $slice.call(str, intStr.length + 1);
39853            return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');
39854        }
39855    }
39856    return $replace.call(str, sepRegex, '$&_');
39857}
39858
39859var utilInspect = require('./util.inspect');
39860var inspectCustom = utilInspect.custom;
39861var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null;
39862
39863var quotes = {
39864    __proto__: null,
39865    'double': '"',
39866    single: "'"
39867};
39868var quoteREs = {
39869    __proto__: null,
39870    'double': /(["\\])/g,
39871    single: /(['\\])/g
39872};
39873
39874module.exports = function inspect_(obj, options, depth, seen) {
39875    var opts = options || {};
39876
39877    if (has(opts, 'quoteStyle') && !has(quotes, opts.quoteStyle)) {
39878        throw new TypeError('option "quoteStyle" must be "single" or "double"');
39879    }
39880    if (
39881        has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
39882            ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
39883            : opts.maxStringLength !== null
39884        )
39885    ) {
39886        throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
39887    }
39888    var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
39889    if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
39890        throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
39891    }
39892
39893    if (
39894        has(opts, 'indent')
39895        && opts.indent !== null
39896        && opts.indent !== '\t'
39897        && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
39898    ) {
39899        throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');
39900    }
39901    if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {
39902        throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');
39903    }
39904    var numericSeparator = opts.numericSeparator;
39905
39906    if (typeof obj === 'undefined') {
39907        return 'undefined';
39908    }
39909    if (obj === null) {
39910        return 'null';
39911    }
39912    if (typeof obj === 'boolean') {
39913        return obj ? 'true' : 'false';
39914    }
39915
39916    if (typeof obj === 'string') {
39917        return inspectString(obj, opts);
39918    }
39919    if (typeof obj === 'number') {
39920        if (obj === 0) {
39921            return Infinity / obj > 0 ? '0' : '-0';
39922        }
39923        var str = String(obj);
39924        return numericSeparator ? addNumericSeparator(obj, str) : str;
39925    }
39926    if (typeof obj === 'bigint') {
39927        var bigIntStr = String(obj) + 'n';
39928        return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;
39929    }
39930
39931    var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
39932    if (typeof depth === 'undefined') { depth = 0; }
39933    if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
39934        return isArray(obj) ? '[Array]' : '[Object]';
39935    }
39936
39937    var indent = getIndent(opts, depth);
39938
39939    if (typeof seen === 'undefined') {
39940        seen = [];
39941    } else if (indexOf(seen, obj) >= 0) {
39942        return '[Circular]';
39943    }
39944
39945    function inspect(value, from, noIndent) {
39946        if (from) {
39947            seen = $arrSlice.call(seen);
39948            seen.push(from);
39949        }
39950        if (noIndent) {
39951            var newOpts = {
39952                depth: opts.depth
39953            };
39954            if (has(opts, 'quoteStyle')) {
39955                newOpts.quoteStyle = opts.quoteStyle;
39956            }
39957            return inspect_(value, newOpts, depth + 1, seen);
39958        }
39959        return inspect_(value, opts, depth + 1, seen);
39960    }
39961
39962    if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable
39963        var name = nameOf(obj);
39964        var keys = arrObjKeys(obj, inspect);
vendor: 5,552 bytes, lines 39965-40091
39965        return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');
39966    }
39967    if (isSymbol(obj)) {
39968        var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
39969        return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
39970    }
39971    if (isElement(obj)) {
39972        var s = '<' + $toLowerCase.call(String(obj.nodeName));
39973        var attrs = obj.attributes || [];
39974        for (var i = 0; i < attrs.length; i++) {
39975            s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
39976        }
39977        s += '>';
39978        if (obj.childNodes && obj.childNodes.length) { s += '...'; }
39979        s += '</' + $toLowerCase.call(String(obj.nodeName)) + '>';
39980        return s;
39981    }
39982    if (isArray(obj)) {
39983        if (obj.length === 0) { return '[]'; }
39984        var xs = arrObjKeys(obj, inspect);
39985        if (indent && !singleLineValues(xs)) {
39986            return '[' + indentedJoin(xs, indent) + ']';
39987        }
39988        return '[ ' + $join.call(xs, ', ') + ' ]';
39989    }
39990    if (isError(obj)) {
39991        var parts = arrObjKeys(obj, inspect);
39992        if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) {
39993            return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';
39994        }
39995        if (parts.length === 0) { return '[' + String(obj) + ']'; }
39996        return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';
39997    }
39998    if (typeof obj === 'object' && customInspect) {
39999        if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) {
40000            return utilInspect(obj, { depth: maxDepth - depth });
40001        } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
40002            return obj.inspect();
40003        }
40004    }
40005    if (isMap(obj)) {
40006        var mapParts = [];
40007        if (mapForEach) {
40008            mapForEach.call(obj, function (value, key) {
40009                mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
40010            });
40011        }
40012        return collectionOf('Map', mapSize.call(obj), mapParts, indent);
40013    }
40014    if (isSet(obj)) {
40015        var setParts = [];
40016        if (setForEach) {
40017            setForEach.call(obj, function (value) {
40018                setParts.push(inspect(value, obj));
40019            });
40020        }
40021        return collectionOf('Set', setSize.call(obj), setParts, indent);
40022    }
40023    if (isWeakMap(obj)) {
40024        return weakCollectionOf('WeakMap');
40025    }
40026    if (isWeakSet(obj)) {
40027        return weakCollectionOf('WeakSet');
40028    }
40029    if (isWeakRef(obj)) {
40030        return weakCollectionOf('WeakRef');
40031    }
40032    if (isNumber(obj)) {
40033        return markBoxed(inspect(Number(obj)));
40034    }
40035    if (isBigInt(obj)) {
40036        return markBoxed(inspect(bigIntValueOf.call(obj)));
40037    }
40038    if (isBoolean(obj)) {
40039        return markBoxed(booleanValueOf.call(obj));
40040    }
40041    if (isString(obj)) {
40042        return markBoxed(inspect(String(obj)));
40043    }
40044    // note: in IE 8, sometimes `global !== window` but both are the prototypes of each other
40045    /* eslint-env browser */
40046    if (typeof window !== 'undefined' && obj === window) {
40047        return '{ [object Window] }';
40048    }
40049    if (
40050        (typeof globalThis !== 'undefined' && obj === globalThis)
40051        || (typeof global !== 'undefined' && obj === global)
40052    ) {
40053        return '{ [object globalThis] }';
40054    }
40055    if (!isDate(obj) && !isRegExp(obj)) {
40056        var ys = arrObjKeys(obj, inspect);
40057        var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
40058        var protoTag = obj instanceof Object ? '' : 'null prototype';
40059        var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';
40060        var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
40061        var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');
40062        if (ys.length === 0) { return tag + '{}'; }
40063        if (indent) {
40064            return tag + '{' + indentedJoin(ys, indent) + '}';
40065        }
40066        return tag + '{ ' + $join.call(ys, ', ') + ' }';
40067    }
40068    return String(obj);
40069};
40070
40071function wrapQuotes(s, defaultStyle, opts) {
40072    var style = opts.quoteStyle || defaultStyle;
40073    var quoteChar = quotes[style];
40074    return quoteChar + s + quoteChar;
40075}
40076
40077function quote(s) {
40078    return $replace.call(String(s), /"/g, '&quot;');
40079}
40080
40081function canTrustToString(obj) {
40082    return !toStringTag || !(typeof obj === 'object' && (toStringTag in obj || typeof obj[toStringTag] !== 'undefined'));
40083}
40084function isArray(obj) { return toStr(obj) === '[object Array]' && canTrustToString(obj); }
40085function isDate(obj) { return toStr(obj) === '[object Date]' && canTrustToString(obj); }
40086function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && canTrustToString(obj); }
40087function isError(obj) { return toStr(obj) === '[object Error]' && canTrustToString(obj); }
40088function isString(obj) { return toStr(obj) === '[object String]' && canTrustToString(obj); }
40089function isNumber(obj) { return toStr(obj) === '[object Number]' && canTrustToString(obj); }
40090function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && canTrustToString(obj); }
40091
vendor: 6,745 bytes, lines 40092-40336
40092// Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
40093function isSymbol(obj) {
40094    if (hasShammedSymbols) {
40095        return obj && typeof obj === 'object' && obj instanceof Symbol;
40096    }
40097    if (typeof obj === 'symbol') {
40098        return true;
40099    }
40100    if (!obj || typeof obj !== 'object' || !symToString) {
40101        return false;
40102    }
40103    try {
40104        symToString.call(obj);
40105        return true;
40106    } catch (e) {}
40107    return false;
40108}
40109
40110function isBigInt(obj) {
40111    if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
40112        return false;
40113    }
40114    try {
40115        bigIntValueOf.call(obj);
40116        return true;
40117    } catch (e) {}
40118    return false;
40119}
40120
40121var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
40122function has(obj, key) {
40123    return hasOwn.call(obj, key);
40124}
40125
40126function toStr(obj) {
40127    return objectToString.call(obj);
40128}
40129
40130function nameOf(f) {
40131    if (f.name) { return f.name; }
40132    var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/);
40133    if (m) { return m[1]; }
40134    return null;
40135}
40136
40137function indexOf(xs, x) {
40138    if (xs.indexOf) { return xs.indexOf(x); }
40139    for (var i = 0, l = xs.length; i < l; i++) {
40140        if (xs[i] === x) { return i; }
40141    }
40142    return -1;
40143}
40144
40145function isMap(x) {
40146    if (!mapSize || !x || typeof x !== 'object') {
40147        return false;
40148    }
40149    try {
40150        mapSize.call(x);
40151        try {
40152            setSize.call(x);
40153        } catch (s) {
40154            return true;
40155        }
40156        return x instanceof Map; // core-js workaround, pre-v2.5.0
40157    } catch (e) {}
40158    return false;
40159}
40160
40161function isWeakMap(x) {
40162    if (!weakMapHas || !x || typeof x !== 'object') {
40163        return false;
40164    }
40165    try {
40166        weakMapHas.call(x, weakMapHas);
40167        try {
40168            weakSetHas.call(x, weakSetHas);
40169        } catch (s) {
40170            return true;
40171        }
40172        return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
40173    } catch (e) {}
40174    return false;
40175}
40176
40177function isWeakRef(x) {
40178    if (!weakRefDeref || !x || typeof x !== 'object') {
40179        return false;
40180    }
40181    try {
40182        weakRefDeref.call(x);
40183        return true;
40184    } catch (e) {}
40185    return false;
40186}
40187
40188function isSet(x) {
40189    if (!setSize || !x || typeof x !== 'object') {
40190        return false;
40191    }
40192    try {
40193        setSize.call(x);
40194        try {
40195            mapSize.call(x);
40196        } catch (m) {
40197            return true;
40198        }
40199        return x instanceof Set; // core-js workaround, pre-v2.5.0
40200    } catch (e) {}
40201    return false;
40202}
40203
40204function isWeakSet(x) {
40205    if (!weakSetHas || !x || typeof x !== 'object') {
40206        return false;
40207    }
40208    try {
40209        weakSetHas.call(x, weakSetHas);
40210        try {
40211            weakMapHas.call(x, weakMapHas);
40212        } catch (s) {
40213            return true;
40214        }
40215        return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
40216    } catch (e) {}
40217    return false;
40218}
40219
40220function isElement(x) {
40221    if (!x || typeof x !== 'object') { return false; }
40222    if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
40223        return true;
40224    }
40225    return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
40226}
40227
40228function inspectString(str, opts) {
40229    if (str.length > opts.maxStringLength) {
40230        var remaining = str.length - opts.maxStringLength;
40231        var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
40232        return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;
40233    }
40234    var quoteRE = quoteREs[opts.quoteStyle || 'single'];
40235    quoteRE.lastIndex = 0;
40236    // eslint-disable-next-line no-control-regex
40237    var s = $replace.call($replace.call(str, quoteRE, '\\$1'), /[\x00-\x1f]/g, lowbyte);
40238    return wrapQuotes(s, 'single', opts);
40239}
40240
40241function lowbyte(c) {
40242    var n = c.charCodeAt(0);
40243    var x = {
40244        8: 'b',
40245        9: 't',
40246        10: 'n',
40247        12: 'f',
40248        13: 'r'
40249    }[n];
40250    if (x) { return '\\' + x; }
40251    return '\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));
40252}
40253
40254function markBoxed(str) {
40255    return 'Object(' + str + ')';
40256}
40257
40258function weakCollectionOf(type) {
40259    return type + ' { ? }';
40260}
40261
40262function collectionOf(type, size, entries, indent) {
40263    var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');
40264    return type + ' (' + size + ') {' + joinedEntries + '}';
40265}
40266
40267function singleLineValues(xs) {
40268    for (var i = 0; i < xs.length; i++) {
40269        if (indexOf(xs[i], '\n') >= 0) {
40270            return false;
40271        }
40272    }
40273    return true;
40274}
40275
40276function getIndent(opts, depth) {
40277    var baseIndent;
40278    if (opts.indent === '\t') {
40279        baseIndent = '\t';
40280    } else if (typeof opts.indent === 'number' && opts.indent > 0) {
40281        baseIndent = $join.call(Array(opts.indent + 1), ' ');
40282    } else {
40283        return null;
40284    }
40285    return {
40286        base: baseIndent,
40287        prev: $join.call(Array(depth + 1), baseIndent)
40288    };
40289}
40290
40291function indentedJoin(xs, indent) {
40292    if (xs.length === 0) { return ''; }
40293    var lineJoiner = '\n' + indent.prev + indent.base;
40294    return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\n' + indent.prev;
40295}
40296
40297function arrObjKeys(obj, inspect) {
40298    var isArr = isArray(obj);
40299    var xs = [];
40300    if (isArr) {
40301        xs.length = obj.length;
40302        for (var i = 0; i < obj.length; i++) {
40303            xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
40304        }
40305    }
40306    var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
40307    var symMap;
40308    if (hasShammedSymbols) {
40309        symMap = {};
40310        for (var k = 0; k < syms.length; k++) {
40311            symMap['$' + syms[k]] = syms[k];
40312        }
40313    }
40314
40315    for (var key in obj) { // eslint-disable-line no-restricted-syntax
40316        if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
40317        if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
40318        if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
40319            // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
40320            continue; // eslint-disable-line no-restricted-syntax, no-continue
40321        } else if ($test.call(/[^\w$]/, key)) {
40322            xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
40323        } else {
40324            xs.push(key + ': ' + inspect(obj[key], obj));
40325        }
40326    }
40327    if (typeof gOPS === 'function') {
40328        for (var j = 0; j < syms.length; j++) {
40329            if (isEnumerable.call(obj, syms[j])) {
40330                xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
40331            }
40332        }
40333    }
40334    return xs;
40335}
40336
40337}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
40338},{"./util.inspect":138}],121:[function(require,module,exports){
40339'use strict';
40340
40341module.exports = require('./lib')
40342
40343},{"./lib":126}],122:[function(require,module,exports){
40344'use strict';
40345
40346var asap = require('asap/raw');
40347
40348function noop() {}
40349
40350// States:
40351//
40352// 0 - pending
40353// 1 - fulfilled with _value
40354// 2 - rejected with _value
40355// 3 - adopted the state of another promise, _value
40356//
40357// once the state is no longer pending (0) it is immutable
40358
40359// All `_` prefixed properties will be reduced to `_{random number}`
40360// at build time to obfuscate them and discourage their use.
40361// We don't use symbols or Object.defineProperty to fully hide them
40362// because the performance isn't good enough.
40363
40364
40365// to avoid using try/catch inside critical functions, we
40366// extract them to here.
40367var LAST_ERROR = null;
40368var IS_ERROR = {};
40369function getThen(obj) {
40370  try {
40371    return obj.then;
40372  } catch (ex) {
40373    LAST_ERROR = ex;
40374    return IS_ERROR;
40375  }
40376}
40377
40378function tryCallOne(fn, a) {
40379  try {
40380    return fn(a);
40381  } catch (ex) {
40382    LAST_ERROR = ex;
40383    return IS_ERROR;
40384  }
40385}
40386function tryCallTwo(fn, a, b) {
40387  try {
40388    fn(a, b);
40389  } catch (ex) {
40390    LAST_ERROR = ex;
40391    return IS_ERROR;
40392  }
40393}
40394
40395module.exports = Promise;
40396
40397function Promise(fn) {
40398  if (typeof this !== 'object') {
40399    throw new TypeError('Promises must be constructed via new');
40400  }
40401  if (typeof fn !== 'function') {
40402    throw new TypeError('Promise constructor\'s argument is not a function');
40403  }
40404  this._x = 0;
40405  this._y = 0;
40406  this._z = null;
40407  this._A = null;
40408  if (fn === noop) return;
40409  doResolve(fn, this);
40410}
40411Promise._B = null;
40412Promise._C = null;
40413Promise._D = noop;
40414
40415Promise.prototype.then = function(onFulfilled, onRejected) {
40416  if (this.constructor !== Promise) {
40417    return safeThen(this, onFulfilled, onRejected);
40418  }
40419  var res = new Promise(noop);
40420  handle(this, new Handler(onFulfilled, onRejected, res));
40421  return res;
40422};
40423
40424function safeThen(self, onFulfilled, onRejected) {
40425  return new self.constructor(function (resolve, reject) {
40426    var res = new Promise(noop);
40427    res.then(resolve, reject);
40428    handle(self, new Handler(onFulfilled, onRejected, res));
40429  });
40430}
40431function handle(self, deferred) {
40432  while (self._y === 3) {
40433    self = self._z;
40434  }
40435  if (Promise._B) {
40436    Promise._B(self);
40437  }
40438  if (self._y === 0) {
40439    if (self._x === 0) {
40440      self._x = 1;
40441      self._A = deferred;
40442      return;
40443    }
40444    if (self._x === 1) {
40445      self._x = 2;
40446      self._A = [self._A, deferred];
40447      return;
40448    }
40449    self._A.push(deferred);
40450    return;
40451  }
40452  handleResolved(self, deferred);
40453}
40454
40455function handleResolved(self, deferred) {
40456  asap(function() {
40457    var cb = self._y === 1 ? deferred.onFulfilled : deferred.onRejected;
40458    if (cb === null) {
40459      if (self._y === 1) {
40460        resolve(deferred.promise, self._z);
40461      } else {
40462        reject(deferred.promise, self._z);
40463      }
40464      return;
40465    }
40466    var ret = tryCallOne(cb, self._z);
40467    if (ret === IS_ERROR) {
40468      reject(deferred.promise, LAST_ERROR);
40469    } else {
40470      resolve(deferred.promise, ret);
40471    }
40472  });
40473}
40474function resolve(self, newValue) {
40475  // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
40476  if (newValue === self) {
40477    return reject(
40478      self,
40479      new TypeError('A promise cannot be resolved with itself.')
40480    );
40481  }
40482  if (
40483    newValue &&
40484    (typeof newValue === 'object' || typeof newValue === 'function')
40485  ) {
40486    var then = getThen(newValue);
40487    if (then === IS_ERROR) {
40488      return reject(self, LAST_ERROR);
40489    }
40490    if (
40491      then === self.then &&
40492      newValue instanceof Promise
40493    ) {
40494      self._y = 3;
40495      self._z = newValue;
40496      finale(self);
40497      return;
40498    } else if (typeof then === 'function') {
40499      doResolve(then.bind(newValue), self);
40500      return;
40501    }
40502  }
40503  self._y = 1;
40504  self._z = newValue;
40505  finale(self);
40506}
40507
40508function reject(self, newValue) {
40509  self._y = 2;
40510  self._z = newValue;
40511  if (Promise._C) {
40512    Promise._C(self, newValue);
40513  }
40514  finale(self);
40515}
40516function finale(self) {
40517  if (self._x === 1) {
40518    handle(self, self._A);
40519    self._A = null;
40520  }
40521  if (self._x === 2) {
40522    for (var i = 0; i < self._A.length; i++) {
40523      handle(self, self._A[i]);
40524    }
40525    self._A = null;
40526  }
40527}
40528
40529function Handler(onFulfilled, onRejected, promise){
40530  this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
40531  this.onRejected = typeof onRejected === 'function' ? onRejected : null;
40532  this.promise = promise;
40533}
40534
40535/**
40536 * Take a potentially misbehaving resolver function and make sure
40537 * onFulfilled and onRejected are only called once.
40538 *
40539 * Makes no guarantees about asynchrony.
40540 */
40541function doResolve(fn, promise) {
40542  var done = false;
40543  var res = tryCallTwo(fn, function (value) {
40544    if (done) return;
40545    done = true;
40546    resolve(promise, value);
40547  }, function (reason) {
40548    if (done) return;
40549    done = true;
40550    reject(promise, reason);
40551  });
40552  if (!done && res === IS_ERROR) {
40553    done = true;
40554    reject(promise, LAST_ERROR);
40555  }
40556}
40557
40558},{"asap/raw":81}],123:[function(require,module,exports){
40559'use strict';
40560
40561var Promise = require('./core.js');
40562
40563module.exports = Promise;
40564Promise.prototype.done = function (onFulfilled, onRejected) {
40565  var self = arguments.length ? this.then.apply(this, arguments) : this;
40566  self.then(null, function (err) {
40567    setTimeout(function () {
40568      throw err;
40569    }, 0);
40570  });
40571};
40572
40573},{"./core.js":122}],124:[function(require,module,exports){
40574'use strict';
40575
40576//This file contains the ES6 extensions to the core Promises/A+ API
40577
40578var Promise = require('./core.js');
40579
40580module.exports = Promise;
40581
40582/* Static Functions */
40583
40584var TRUE = valuePromise(true);
40585var FALSE = valuePromise(false);
40586var NULL = valuePromise(null);
40587var UNDEFINED = valuePromise(undefined);
40588var ZERO = valuePromise(0);
40589var EMPTYSTRING = valuePromise('');
40590
40591function valuePromise(value) {
40592  var p = new Promise(Promise._D);
40593  p._y = 1;
40594  p._z = value;
40595  return p;
40596}
40597Promise.resolve = function (value) {
40598  if (value instanceof Promise) return value;
40599
40600  if (value === null) return NULL;
40601  if (value === undefined) return UNDEFINED;
40602  if (value === true) return TRUE;
40603  if (value === false) return FALSE;
40604  if (value === 0) return ZERO;
40605  if (value === '') return EMPTYSTRING;
40606
40607  if (typeof value === 'object' || typeof value === 'function') {
40608    try {
40609      var then = value.then;
40610      if (typeof then === 'function') {
40611        return new Promise(then.bind(value));
40612      }
40613    } catch (ex) {
40614      return new Promise(function (resolve, reject) {
40615        reject(ex);
40616      });
40617    }
40618  }
40619  return valuePromise(value);
40620};
40621
40622var iterableToArray = function (iterable) {
40623  if (typeof Array.from === 'function') {
40624    // ES2015+, iterables exist
40625    iterableToArray = Array.from;
40626    return Array.from(iterable);
40627  }
40628
40629  // ES5, only arrays and array-likes exist
40630  iterableToArray = function (x) { return Array.prototype.slice.call(x); };
40631  return Array.prototype.slice.call(iterable);
40632}
40633
40634Promise.all = function (arr) {
40635  var args = iterableToArray(arr);
40636
40637  return new Promise(function (resolve, reject) {
40638    if (args.length === 0) return resolve([]);
40639    var remaining = args.length;
40640    function res(i, val) {
40641      if (val && (typeof val === 'object' || typeof val === 'function')) {
40642        if (val instanceof Promise && val.then === Promise.prototype.then) {
40643          while (val._y === 3) {
40644            val = val._z;
40645          }
40646          if (val._y === 1) return res(i, val._z);
40647          if (val._y === 2) reject(val._z);
40648          val.then(function (val) {
40649            res(i, val);
40650          }, reject);
40651          return;
40652        } else {
40653          var then = val.then;
40654          if (typeof then === 'function') {
40655            var p = new Promise(then.bind(val));
40656            p.then(function (val) {
40657              res(i, val);
40658            }, reject);
40659            return;
40660          }
40661        }
40662      }
40663      args[i] = val;
40664      if (--remaining === 0) {
40665        resolve(args);
40666      }
40667    }
40668    for (var i = 0; i < args.length; i++) {
40669      res(i, args[i]);
40670    }
40671  });
40672};
40673
40674function onSettledFulfill(value) {
40675  return { status: 'fulfilled', value: value };
40676}
40677function onSettledReject(reason) {
40678  return { status: 'rejected', reason: reason };
40679}
40680function mapAllSettled(item) {
40681  if(item && (typeof item === 'object' || typeof item === 'function')){
40682    if(item instanceof Promise && item.then === Promise.prototype.then){
40683      return item.then(onSettledFulfill, onSettledReject);
40684    }
40685    var then = item.then;
40686    if (typeof then === 'function') {
40687      return new Promise(then.bind(item)).then(onSettledFulfill, onSettledReject)
40688    }
40689  }
40690
40691  return onSettledFulfill(item);
40692}
40693Promise.allSettled = function (iterable) {
40694  return Promise.all(iterableToArray(iterable).map(mapAllSettled));
40695};
40696
40697Promise.reject = function (value) {
40698  return new Promise(function (resolve, reject) {
40699    reject(value);
40700  });
40701};
40702
40703Promise.race = function (values) {
40704  return new Promise(function (resolve, reject) {
40705    iterableToArray(values).forEach(function(value){
40706      Promise.resolve(value).then(resolve, reject);
40707    });
40708  });
40709};
40710
40711/* Prototype Methods */
40712
40713Promise.prototype['catch'] = function (onRejected) {
40714  return this.then(null, onRejected);
40715};
40716
40717function getAggregateError(errors){
40718  if(typeof AggregateError === 'function'){
40719    return new AggregateError(errors,'All promises were rejected');
40720  }
40721
40722  var error = new Error('All promises were rejected');
40723
40724  error.name = 'AggregateError';
40725  error.errors = errors;
40726
40727  return error;
40728}
40729
40730Promise.any = function promiseAny(values) {
40731  return new Promise(function(resolve, reject) {
40732    var promises = iterableToArray(values);
40733    var hasResolved = false;
40734    var rejectionReasons = [];
40735
40736    function resolveOnce(value) {
40737      if (!hasResolved) {
40738        hasResolved = true;
40739        resolve(value);
40740      }
40741    }
40742
40743    function rejectionCheck(reason) {
40744      rejectionReasons.push(reason);
40745
40746      if (rejectionReasons.length === promises.length) {
40747        reject(getAggregateError(rejectionReasons));
40748      }
40749    }
40750
40751    if(promises.length === 0){
40752      reject(getAggregateError(rejectionReasons));
40753    } else {
40754      promises.forEach(function(value){
40755        Promise.resolve(value).then(resolveOnce, rejectionCheck);
40756      });
40757    }
40758  });
40759};
40760
40761},{"./core.js":122}],125:[function(require,module,exports){
40762'use strict';
40763
40764var Promise = require('./core.js');
40765
40766module.exports = Promise;
40767Promise.prototype.finally = function (f) {
40768  return this.then(function (value) {
40769    return Promise.resolve(f()).then(function () {
40770      return value;
40771    });
40772  }, function (err) {
40773    return Promise.resolve(f()).then(function () {
40774      throw err;
40775    });
40776  });
40777};
40778
40779},{"./core.js":122}],126:[function(require,module,exports){
40780'use strict';
40781
40782module.exports = require('./core.js');
40783require('./done.js');
40784require('./finally.js');
40785require('./es6-extensions.js');
40786require('./node-extensions.js');
40787require('./synchronous.js');
40788
40789},{"./core.js":122,"./done.js":123,"./es6-extensions.js":124,"./finally.js":125,"./node-extensions.js":127,"./synchronous.js":128}],127:[function(require,module,exports){
40790'use strict';
40791
40792// This file contains then/promise specific extensions that are only useful
40793// for node.js interop
40794
40795var Promise = require('./core.js');
40796var asap = require('asap');
40797
40798module.exports = Promise;
40799
40800/* Static Functions */
40801
40802Promise.denodeify = function (fn, argumentCount) {
40803  if (
40804    typeof argumentCount === 'number' && argumentCount !== Infinity
40805  ) {
40806    return denodeifyWithCount(fn, argumentCount);
40807  } else {
40808    return denodeifyWithoutCount(fn);
40809  }
40810};
40811
40812var callbackFn = (
40813  'function (err, res) {' +
40814  'if (err) { rj(err); } else { rs(res); }' +
40815  '}'
40816);
40817function denodeifyWithCount(fn, argumentCount) {
40818  var args = [];
40819  for (var i = 0; i < argumentCount; i++) {
40820    args.push('a' + i);
40821  }
40822  var body = [
40823    'return function (' + args.join(',') + ') {',
40824    'var self = this;',
40825    'return new Promise(function (rs, rj) {',
40826    'var res = fn.call(',
40827    ['self'].concat(args).concat([callbackFn]).join(','),
40828    ');',
40829    'if (res &&',
40830    '(typeof res === "object" || typeof res === "function") &&',
40831    'typeof res.then === "function"',
40832    ') {rs(res);}',
40833    '});',
40834    '};'
40835  ].join('');
40836  return Function(['Promise', 'fn'], body)(Promise, fn);
40837}
40838function denodeifyWithoutCount(fn) {
40839  var fnLength = Math.max(fn.length - 1, 3);
40840  var args = [];
40841  for (var i = 0; i < fnLength; i++) {
40842    args.push('a' + i);
40843  }
40844  var body = [
40845    'return function (' + args.join(',') + ') {',
40846    'var self = this;',
40847    'var args;',
40848    'var argLength = arguments.length;',
40849    'if (arguments.length > ' + fnLength + ') {',
40850    'args = new Array(arguments.length + 1);',
40851    'for (var i = 0; i < arguments.length; i++) {',
40852    'args[i] = arguments[i];',
40853    '}',
40854    '}',
40855    'return new Promise(function (rs, rj) {',
40856    'var cb = ' + callbackFn + ';',
40857    'var res;',
40858    'switch (argLength) {',
40859    args.concat(['extra']).map(function (_, index) {
40860      return (
40861        'case ' + (index) + ':' +
40862        'res = fn.call(' + ['self'].concat(args.slice(0, index)).concat('cb').join(',') + ');' +
40863        'break;'
40864      );
40865    }).join(''),
40866    'default:',
40867    'args[argLength] = cb;',
40868    'res = fn.apply(self, args);',
40869    '}',
40870    
40871    'if (res &&',
40872    '(typeof res === "object" || typeof res === "function") &&',
40873    'typeof res.then === "function"',
40874    ') {rs(res);}',
40875    '});',
40876    '};'
40877  ].join('');
40878
40879  return Function(
40880    ['Promise', 'fn'],
40881    body
40882  )(Promise, fn);
40883}
40884
40885Promise.nodeify = function (fn) {
40886  return function () {
40887    var args = Array.prototype.slice.call(arguments);
40888    var callback =
40889      typeof args[args.length - 1] === 'function' ? args.pop() : null;
40890    var ctx = this;
40891    try {
40892      return fn.apply(this, arguments).nodeify(callback, ctx);
40893    } catch (ex) {
40894      if (callback === null || typeof callback == 'undefined') {
40895        return new Promise(function (resolve, reject) {
40896          reject(ex);
40897        });
40898      } else {
40899        asap(function () {
40900          callback.call(ctx, ex);
40901        })
40902      }
40903    }
40904  }
40905};
40906
40907Promise.prototype.nodeify = function (callback, ctx) {
40908  if (typeof callback != 'function') return this;
40909
40910  this.then(function (value) {
40911    asap(function () {
40912      callback.call(ctx, null, value);
40913    });
40914  }, function (err) {
40915    asap(function () {
40916      callback.call(ctx, err);
40917    });
40918  });
40919};
40920
40921},{"./core.js":122,"asap":80}],128:[function(require,module,exports){
40922'use strict';
40923
40924var Promise = require('./core.js');
40925
40926module.exports = Promise;
40927Promise.enableSynchronous = function () {
40928  Promise.prototype.isPending = function() {
40929    return this.getState() == 0;
40930  };
40931
40932  Promise.prototype.isFulfilled = function() {
40933    return this.getState() == 1;
40934  };
40935
40936  Promise.prototype.isRejected = function() {
40937    return this.getState() == 2;
40938  };
40939
40940  Promise.prototype.getValue = function () {
40941    if (this._y === 3) {
40942      return this._z.getValue();
40943    }
40944
40945    if (!this.isFulfilled()) {
40946      throw new Error('Cannot get a value of an unfulfilled promise.');
40947    }
40948
40949    return this._z;
40950  };
40951
40952  Promise.prototype.getReason = function () {
40953    if (this._y === 3) {
40954      return this._z.getReason();
40955    }
40956
40957    if (!this.isRejected()) {
40958      throw new Error('Cannot get a rejection reason of a non-rejected promise.');
40959    }
40960
40961    return this._z;
40962  };
40963
40964  Promise.prototype.getState = function () {
40965    if (this._y === 3) {
40966      return this._z.getState();
40967    }
40968    if (this._y === -1 || this._y === -2) {
40969      return 0;
40970    }
40971
40972    return this._y;
40973  };
40974};
40975
40976Promise.disableSynchronous = function() {
40977  Promise.prototype.isPending = undefined;
40978  Promise.prototype.isFulfilled = undefined;
40979  Promise.prototype.isRejected = undefined;
40980  Promise.prototype.getValue = undefined;
40981  Promise.prototype.getReason = undefined;
40982  Promise.prototype.getState = undefined;
40983};
40984
40985},{"./core.js":122}],129:[function(require,module,exports){
40986'use strict';
40987
40988var replace = String.prototype.replace;
40989var percentTwenties = /%20/g;
40990
40991var Format = {
40992    RFC1738: 'RFC1738',
40993    RFC3986: 'RFC3986'
vendor: 6,207 bytes, lines 40994-41182
40994};
40995
40996module.exports = {
40997    'default': Format.RFC3986,
40998    formatters: {
40999        RFC1738: function (value) {
41000            return replace.call(value, percentTwenties, '+');
41001        },
41002        RFC3986: function (value) {
41003            return String(value);
41004        }
41005    },
41006    RFC1738: Format.RFC1738,
41007    RFC3986: Format.RFC3986
41008};
41009
41010},{}],130:[function(require,module,exports){
41011'use strict';
41012
41013var stringify = require('./stringify');
41014var parse = require('./parse');
41015var formats = require('./formats');
41016
41017module.exports = {
41018    formats: formats,
41019    parse: parse,
41020    stringify: stringify
41021};
41022
41023},{"./formats":129,"./parse":131,"./stringify":132}],131:[function(require,module,exports){
41024'use strict';
41025
41026var utils = require('./utils');
41027
41028var has = Object.prototype.hasOwnProperty;
41029var isArray = Array.isArray;
41030
41031var defaults = {
41032    allowDots: false,
41033    allowEmptyArrays: false,
41034    allowPrototypes: false,
41035    allowSparse: false,
41036    arrayLimit: 20,
41037    charset: 'utf-8',
41038    charsetSentinel: false,
41039    comma: false,
41040    decodeDotInKeys: false,
41041    decoder: utils.decode,
41042    delimiter: '&',
41043    depth: 5,
41044    duplicates: 'combine',
41045    ignoreQueryPrefix: false,
41046    interpretNumericEntities: false,
41047    parameterLimit: 1000,
41048    parseArrays: true,
41049    plainObjects: false,
41050    strictDepth: false,
41051    strictMerge: true,
41052    strictNullHandling: false,
41053    throwOnLimitExceeded: false
41054};
41055
41056var interpretNumericEntities = function (str) {
41057    return str.replace(/&#(\d+);/g, function ($0, numberStr) {
41058        return String.fromCharCode(parseInt(numberStr, 10));
41059    });
41060};
41061
41062var parseArrayValue = function (val, options, currentArrayLength) {
41063    if (val && typeof val === 'string' && options.comma && val.indexOf(',') > -1) {
41064        return val.split(',');
41065    }
41066
41067    if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) {
41068        throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
41069    }
41070
41071    return val;
41072};
41073
41074// This is what browsers will submit when the ✓ character occurs in an
41075// application/x-www-form-urlencoded body and the encoding of the page containing
41076// the form is iso-8859-1, or when the submitted form has an accept-charset
41077// attribute of iso-8859-1. Presumably also with other charsets that do not contain
41078// the ✓ character, such as us-ascii.
41079var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('&#10003;')
41080
41081// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
41082var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
41083
41084var parseValues = function parseQueryStringValues(str, options) {
41085    var obj = { __proto__: null };
41086
41087    var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
41088    cleanStr = cleanStr.replace(/%5B/gi, '[').replace(/%5D/gi, ']');
41089
41090    var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit;
41091    var parts = cleanStr.split(
41092        options.delimiter,
41093        options.throwOnLimitExceeded ? limit + 1 : limit
41094    );
41095
41096    if (options.throwOnLimitExceeded && parts.length > limit) {
41097        throw new RangeError('Parameter limit exceeded. Only ' + limit + ' parameter' + (limit === 1 ? '' : 's') + ' allowed.');
41098    }
41099
41100    var skipIndex = -1; // Keep track of where the utf8 sentinel was found
41101    var i;
41102
41103    var charset = options.charset;
41104    if (options.charsetSentinel) {
41105        for (i = 0; i < parts.length; ++i) {
41106            if (parts[i].indexOf('utf8=') === 0) {
41107                if (parts[i] === charsetSentinel) {
41108                    charset = 'utf-8';
41109                } else if (parts[i] === isoSentinel) {
41110                    charset = 'iso-8859-1';
41111                }
41112                skipIndex = i;
41113                i = parts.length; // The eslint settings do not allow break;
41114            }
41115        }
41116    }
41117
41118    for (i = 0; i < parts.length; ++i) {
41119        if (i === skipIndex) {
41120            continue;
41121        }
41122        var part = parts[i];
41123
41124        var bracketEqualsPos = part.indexOf(']=');
41125        var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
41126
41127        var key;
41128        var val;
41129        if (pos === -1) {
41130            key = options.decoder(part, defaults.decoder, charset, 'key');
41131            val = options.strictNullHandling ? null : '';
41132        } else {
41133            key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
41134
41135            if (key !== null) {
41136                val = utils.maybeMap(
41137                    parseArrayValue(
41138                        part.slice(pos + 1),
41139                        options,
41140                        isArray(obj[key]) ? obj[key].length : 0
41141                    ),
41142                    function (encodedVal) {
41143                        return options.decoder(encodedVal, defaults.decoder, charset, 'value');
41144                    }
41145                );
41146            }
41147        }
41148
41149        if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
41150            val = interpretNumericEntities(String(val));
41151        }
41152
41153        if (part.indexOf('[]=') > -1) {
41154            val = isArray(val) ? [val] : val;
41155        }
41156
41157        if (options.comma && isArray(val) && val.length > options.arrayLimit) {
41158            if (options.throwOnLimitExceeded) {
41159                throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
41160            }
41161            val = utils.combine([], val, options.arrayLimit, options.plainObjects);
41162        }
41163
41164        if (key !== null) {
41165            var existing = has.call(obj, key);
41166            if (existing && (options.duplicates === 'combine' || part.indexOf('[]=') > -1)) {
41167                obj[key] = utils.combine(
41168                    obj[key],
41169                    val,
41170                    options.arrayLimit,
41171                    options.plainObjects
41172                );
41173            } else if (!existing || options.duplicates === 'last') {
41174                obj[key] = val;
41175            }
41176        }
41177    }
41178
41179    return obj;
41180};
41181
41182var parseObject = function (chain, val, options, valuesParsed) {
41183    var currentArrayLength = 0;
41184    if (chain.length > 0 && chain[chain.length - 1] === '[]') {
41185        var parentKey = chain.slice(0, -1).join('');
41186        currentArrayLength = Array.isArray(val) && val[parentKey] ? val[parentKey].length : 0;
41187    }
41188
41189    var leaf = valuesParsed ? val : parseArrayValue(val, options, currentArrayLength);
41190
41191    for (var i = chain.length - 1; i >= 0; --i) {
41192        var obj;
41193        var root = chain[i];
41194
41195        if (root === '[]' && options.parseArrays) {
41196            if (utils.isOverflow(leaf)) {
41197                // leaf is already an overflow object, preserve it
41198                obj = leaf;
41199            } else {
41200                obj = options.allowEmptyArrays && (leaf === '' || (options.strictNullHandling && leaf === null))
41201                    ? []
41202                    : utils.combine(
41203                        [],
41204                        leaf,
41205                        options.arrayLimit,
41206                        options.plainObjects
41207                    );
41208            }
41209        } else {
41210            obj = options.plainObjects ? { __proto__: null } : {};
41211            var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
41212            var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, '.') : cleanRoot;
41213            var index = parseInt(decodedRoot, 10);
41214            var isValidArrayIndex = !isNaN(index)
41215                && root !== decodedRoot
41216                && String(index) === decodedRoot
41217                && index >= 0
41218                && options.parseArrays;
41219            if (!options.parseArrays && decodedRoot === '') {
41220                obj = { 0: leaf };
41221            } else if (isValidArrayIndex && index < options.arrayLimit) {
41222                obj = [];
41223                obj[index] = leaf;
41224            } else if (isValidArrayIndex && options.throwOnLimitExceeded) {
41225                throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.');
41226            } else if (isValidArrayIndex) {
41227                obj[index] = leaf;
41228                utils.markOverflow(obj, index);
41229            } else if (decodedRoot !== '__proto__') {
41230                obj[decodedRoot] = leaf;
41231            }
41232        }
41233
41234        leaf = obj;
41235    }
41236
41237    return leaf;
41238};
41239
41240var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) {
41241    var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
41242
41243    if (options.depth <= 0) {
41244        if (!options.plainObjects && has.call(Object.prototype, key)) {
41245            if (!options.allowPrototypes) {
41246                return;
41247            }
41248        }
41249
41250        return [key];
41251    }
41252
41253    var brackets = /(\[[^[\]]*])/;
41254    var child = /(\[[^[\]]*])/g;
41255
41256    var segment = brackets.exec(key);
41257    var parent = segment ? key.slice(0, segment.index) : key;
41258
41259    var keys = [];
41260
41261    if (parent) {
41262        if (!options.plainObjects && has.call(Object.prototype, parent)) {
41263            if (!options.allowPrototypes) {
41264                return;
41265            }
41266        }
41267
41268        keys[keys.length] = parent;
41269    }
41270
41271    var i = 0;
41272    while ((segment = child.exec(key)) !== null && i < options.depth) {
41273        i += 1;
41274
41275        var segmentContent = segment[1].slice(1, -1);
41276        if (!options.plainObjects && has.call(Object.prototype, segmentContent)) {
41277            if (!options.allowPrototypes) {
41278                return;
41279            }
41280        }
41281
41282        keys[keys.length] = segment[1];
41283    }
41284
41285    if (segment) {
41286        if (options.strictDepth === true) {
41287            throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true');
41288        }
41289
41290        keys[keys.length] = '[' + key.slice(segment.index) + ']';
41291    }
41292
41293    return keys;
41294};
41295
41296var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) {
41297    if (!givenKey) {
41298        return;
41299    }
41300
41301    var keys = splitKeyIntoSegments(givenKey, options);
41302
41303    if (!keys) {
41304        return;
41305    }
41306
41307    return parseObject(keys, val, options, valuesParsed);
41308};
41309
41310var normalizeParseOptions = function normalizeParseOptions(opts) {
41311    if (!opts) {
41312        return defaults;
41313    }
41314
41315    if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {
41316        throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided');
41317    }
41318
41319    if (typeof opts.decodeDotInKeys !== 'undefined' && typeof opts.decodeDotInKeys !== 'boolean') {
41320        throw new TypeError('`decodeDotInKeys` option can only be `true` or `false`, when provided');
41321    }
41322
41323    if (opts.decoder !== null && typeof opts.decoder !== 'undefined' && typeof opts.decoder !== 'function') {
41324        throw new TypeError('Decoder has to be a function.');
41325    }
41326
41327    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
41328        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
41329    }
41330
41331    if (typeof opts.throwOnLimitExceeded !== 'undefined' && typeof opts.throwOnLimitExceeded !== 'boolean') {
41332        throw new TypeError('`throwOnLimitExceeded` option must be a boolean');
41333    }
41334
41335    var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
41336
41337    var duplicates = typeof opts.duplicates === 'undefined' ? defaults.duplicates : opts.duplicates;
41338
41339    if (duplicates !== 'combine' && duplicates !== 'first' && duplicates !== 'last') {
41340        throw new TypeError('The duplicates option must be either combine, first, or last');
41341    }
41342
41343    var allowDots = typeof opts.allowDots === 'undefined' ? opts.decodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;
41344
41345    return {
41346        allowDots: allowDots,
vendor: 3,107 bytes, lines 41347-41403
41347        allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
41348        allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
41349        allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse,
41350        arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
41351        charset: charset,
41352        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
41353        comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
41354        decodeDotInKeys: typeof opts.decodeDotInKeys === 'boolean' ? opts.decodeDotInKeys : defaults.decodeDotInKeys,
41355        decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
41356        delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
41357        // eslint-disable-next-line no-implicit-coercion, no-extra-parens
41358        depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
41359        duplicates: duplicates,
41360        ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
41361        interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
41362        parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
41363        parseArrays: opts.parseArrays !== false,
41364        plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
41365        strictDepth: typeof opts.strictDepth === 'boolean' ? !!opts.strictDepth : defaults.strictDepth,
41366        strictMerge: typeof opts.strictMerge === 'boolean' ? !!opts.strictMerge : defaults.strictMerge,
41367        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling,
41368        throwOnLimitExceeded: typeof opts.throwOnLimitExceeded === 'boolean' ? opts.throwOnLimitExceeded : false
41369    };
41370};
41371
41372module.exports = function (str, opts) {
41373    var options = normalizeParseOptions(opts);
41374
41375    if (str === '' || str === null || typeof str === 'undefined') {
41376        return options.plainObjects ? { __proto__: null } : {};
41377    }
41378
41379    var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
41380    var obj = options.plainObjects ? { __proto__: null } : {};
41381
41382    // Iterate over the keys and setup the new object
41383
41384    var keys = Object.keys(tempObj);
41385    for (var i = 0; i < keys.length; ++i) {
41386        var key = keys[i];
41387        var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string');
41388        obj = utils.merge(obj, newObj, options);
41389    }
41390
41391    if (options.allowSparse === true) {
41392        return obj;
41393    }
41394
41395    return utils.compact(obj);
41396};
41397
41398},{"./utils":133}],132:[function(require,module,exports){
41399'use strict';
41400
41401var getSideChannel = require('side-channel');
41402var utils = require('./utils');
41403var formats = require('./formats'
vendor: 11,350 bytes, lines 41403-41755
41403);
41404var has = Object.prototype.hasOwnProperty;
41405
41406var arrayPrefixGenerators = {
41407    brackets: function brackets(prefix) {
41408        return prefix + '[]';
41409    },
41410    comma: 'comma',
41411    indices: function indices(prefix, key) {
41412        return prefix + '[' + key + ']';
41413    },
41414    repeat: function repeat(prefix) {
41415        return prefix;
41416    }
41417};
41418
41419var isArray = Array.isArray;
41420var push = Array.prototype.push;
41421var pushToArray = function (arr, valueOrArray) {
41422    push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
41423};
41424
41425var toISO = Date.prototype.toISOString;
41426
41427var defaultFormat = formats['default'];
41428var defaults = {
41429    addQueryPrefix: false,
41430    allowDots: false,
41431    allowEmptyArrays: false,
41432    arrayFormat: 'indices',
41433    charset: 'utf-8',
41434    charsetSentinel: false,
41435    commaRoundTrip: false,
41436    delimiter: '&',
41437    encode: true,
41438    encodeDotInKeys: false,
41439    encoder: utils.encode,
41440    encodeValuesOnly: false,
41441    filter: void undefined,
41442    format: defaultFormat,
41443    formatter: formats.formatters[defaultFormat],
41444    // deprecated
41445    indices: false,
41446    serializeDate: function serializeDate(date) {
41447        return toISO.call(date);
41448    },
41449    skipNulls: false,
41450    strictNullHandling: false
41451};
41452
41453var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
41454    return typeof v === 'string'
41455        || typeof v === 'number'
41456        || typeof v === 'boolean'
41457        || typeof v === 'symbol'
41458        || typeof v === 'bigint';
41459};
41460
41461var sentinel = {};
41462
41463var stringify = function stringify(
41464    object,
41465    prefix,
41466    generateArrayPrefix,
41467    commaRoundTrip,
41468    allowEmptyArrays,
41469    strictNullHandling,
41470    skipNulls,
41471    encodeDotInKeys,
41472    encoder,
41473    filter,
41474    sort,
41475    allowDots,
41476    serializeDate,
41477    format,
41478    formatter,
41479    encodeValuesOnly,
41480    charset,
41481    sideChannel
41482) {
41483    var obj = object;
41484
41485    var tmpSc = sideChannel;
41486    var step = 0;
41487    var findFlag = false;
41488    while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) {
41489        // Where object last appeared in the ref tree
41490        var pos = tmpSc.get(object);
41491        step += 1;
41492        if (typeof pos !== 'undefined') {
41493            if (pos === step) {
41494                throw new RangeError('Cyclic object value');
41495            } else {
41496                findFlag = true; // Break while
41497            }
41498        }
41499        if (typeof tmpSc.get(sentinel) === 'undefined') {
41500            step = 0;
41501        }
41502    }
41503
41504    if (typeof filter === 'function') {
41505        obj = filter(prefix, obj);
41506    } else if (obj instanceof Date) {
41507        obj = serializeDate(obj);
41508    } else if (generateArrayPrefix === 'comma' && isArray(obj)) {
41509        obj = utils.maybeMap(obj, function (value) {
41510            if (value instanceof Date) {
41511                return serializeDate(value);
41512            }
41513            return value;
41514        });
41515    }
41516
41517    if (obj === null) {
41518        if (strictNullHandling) {
41519            return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix;
41520        }
41521
41522        obj = '';
41523    }
41524
41525    if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
41526        if (encoder) {
41527            var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format);
41528            return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
41529        }
41530        return [formatter(prefix) + '=' + formatter(String(obj))];
41531    }
41532
41533    var values = [];
41534
41535    if (typeof obj === 'undefined') {
41536        return values;
41537    }
41538
41539    var objKeys;
41540    if (generateArrayPrefix === 'comma' && isArray(obj)) {
41541        // we need to join elements in
41542        if (encodeValuesOnly && encoder) {
41543            obj = utils.maybeMap(obj, encoder);
41544        }
41545        objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }];
41546    } else if (isArray(filter)) {
41547        objKeys = filter;
41548    } else {
41549        var keys = Object.keys(obj);
41550        objKeys = sort ? keys.sort(sort) : keys;
41551    }
41552
41553    var encodedPrefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix);
41554
41555    var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + '[]' : encodedPrefix;
41556
41557    if (allowEmptyArrays && isArray(obj) && obj.length === 0) {
41558        return adjustedPrefix + '[]';
41559    }
41560
41561    for (var j = 0; j < objKeys.length; ++j) {
41562        var key = objKeys[j];
41563        var value = typeof key === 'object' && key && typeof key.value !== 'undefined'
41564            ? key.value
41565            : obj[key];
41566
41567        if (skipNulls && value === null) {
41568            continue;
41569        }
41570
41571        var encodedKey = allowDots && encodeDotInKeys ? String(key).replace(/\./g, '%2E') : String(key);
41572        var keyPrefix = isArray(obj)
41573            ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, encodedKey) : adjustedPrefix
41574            : adjustedPrefix + (allowDots ? '.' + encodedKey : '[' + encodedKey + ']');
41575
41576        sideChannel.set(object, step);
41577        var valueSideChannel = getSideChannel();
41578        valueSideChannel.set(sentinel, sideChannel);
41579        pushToArray(values, stringify(
41580            value,
41581            keyPrefix,
41582            generateArrayPrefix,
41583            commaRoundTrip,
41584            allowEmptyArrays,
41585            strictNullHandling,
41586            skipNulls,
41587            encodeDotInKeys,
41588            generateArrayPrefix === 'comma' && encodeValuesOnly && isArray(obj) ? null : encoder,
41589            filter,
41590            sort,
41591            allowDots,
41592            serializeDate,
41593            format,
41594            formatter,
41595            encodeValuesOnly,
41596            charset,
41597            valueSideChannel
41598        ));
41599    }
41600
41601    return values;
41602};
41603
41604var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
41605    if (!opts) {
41606        return defaults;
41607    }
41608
41609    if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') {
41610        throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided');
41611    }
41612
41613    if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') {
41614        throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided');
41615    }
41616
41617    if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') {
41618        throw new TypeError('Encoder has to be a function.');
41619    }
41620
41621    var charset = opts.charset || defaults.charset;
41622    if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
41623        throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
41624    }
41625
41626    var format = formats['default'];
41627    if (typeof opts.format !== 'undefined') {
41628        if (!has.call(formats.formatters, opts.format)) {
41629            throw new TypeError('Unknown format option provided.');
41630        }
41631        format = opts.format;
41632    }
41633    var formatter = formats.formatters[format];
41634
41635    var filter = defaults.filter;
41636    if (typeof opts.filter === 'function' || isArray(opts.filter)) {
41637        filter = opts.filter;
41638    }
41639
41640    var arrayFormat;
41641    if (opts.arrayFormat in arrayPrefixGenerators) {
41642        arrayFormat = opts.arrayFormat;
41643    } else if ('indices' in opts) {
41644        arrayFormat = opts.indices ? 'indices' : 'repeat';
41645    } else {
41646        arrayFormat = defaults.arrayFormat;
41647    }
41648
41649    if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') {
41650        throw new TypeError('`commaRoundTrip` must be a boolean, or absent');
41651    }
41652
41653    var allowDots = typeof opts.allowDots === 'undefined' ? opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots;
41654
41655    return {
41656        addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
41657        allowDots: allowDots,
41658        allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays,
41659        arrayFormat: arrayFormat,
41660        charset: charset,
41661        charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
41662        commaRoundTrip: !!opts.commaRoundTrip,
41663        delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
41664        encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
41665        encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys,
41666        encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
41667        encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
41668        filter: filter,
41669        format: format,
41670        formatter: formatter,
41671        serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
41672        skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
41673        sort: typeof opts.sort === 'function' ? opts.sort : null,
41674        strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
41675    };
41676};
41677
41678module.exports = function (object, opts) {
41679    var obj = object;
41680    var options = normalizeStringifyOptions(opts);
41681
41682    var objKeys;
41683    var filter;
41684
41685    if (typeof options.filter === 'function') {
41686        filter = options.filter;
41687        obj = filter('', obj);
41688    } else if (isArray(options.filter)) {
41689        filter = options.filter;
41690        objKeys = filter;
41691    }
41692
41693    var keys = [];
41694
41695    if (typeof obj !== 'object' || obj === null) {
41696        return '';
41697    }
41698
41699    var generateArrayPrefix = arrayPrefixGenerators[options.arrayFormat];
41700    var commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip;
41701
41702    if (!objKeys) {
41703        objKeys = Object.keys(obj);
41704    }
41705
41706    if (options.sort) {
41707        objKeys.sort(options.sort);
41708    }
41709
41710    var sideChannel = getSideChannel();
41711    for (var i = 0; i < objKeys.length; ++i) {
41712        var key = objKeys[i];
41713        var value = obj[key];
41714
41715        if (options.skipNulls && value === null) {
41716            continue;
41717        }
41718        pushToArray(keys, stringify(
41719            value,
41720            key,
41721            generateArrayPrefix,
41722            commaRoundTrip,
41723            options.allowEmptyArrays,
41724            options.strictNullHandling,
41725            options.skipNulls,
41726            options.encodeDotInKeys,
41727            options.encode ? options.encoder : null,
41728            options.filter,
41729            options.sort,
41730            options.allowDots,
41731            options.serializeDate,
41732            options.format,
41733            options.formatter,
41734            options.encodeValuesOnly,
41735            options.charset,
41736            sideChannel
41737        ));
41738    }
41739
41740    var joined = keys.join(options.delimiter);
41741    var prefix = options.addQueryPrefix === true ? '?' : '';
41742
41743    if (options.charsetSentinel) {
41744        if (options.charset === 'iso-8859-1') {
41745            // encodeURIComponent('&#10003;'), the "numeric entity" representation of a checkmark
41746            prefix += 'utf8=%26%2310003%3B&';
41747        } else {
41748            // encodeURIComponent('✓')
41749            prefix += 'utf8=%E2%9C%93&';
41750        }
41751    }
41752
41753    return joined.length > 0 ? prefix + joined : '';
41754};
41755
41756},{"./formats":129,"./utils":133,"side-channel":137}],133:[function(require,module,exports){
41757'use strict';
41758
41759var formats = require('./formats');
41760var getSideChannel = require('side-channel');
41761
41762var has = Object.prototype.hasOwnProperty;
41763var isArray = Array.isArray;
41764
41765// Track objects created from arrayLimit overflow using side-channel
41766// Stores the current max numeric index for O(1) lookup
41767var overflowChannel = getSideChannel();
41768
41769var markOverflow = function markOverflow(obj, maxIndex) {
41770    overflowChannel.set(obj, maxIndex);
41771    return obj;
41772};
41773
41774var isOverflow = function isOverflow(obj) {
41775    return overflowChannel.has(obj);
41776};
41777
41778var getMaxIndex = function getMaxIndex(obj) {
41779    return overflowChannel.get(obj);
41780};
41781
41782var setMaxIndex = function setMaxIndex(obj, maxIndex) {
41783    overflowChannel.set(obj, maxIndex);
41784};
41785
41786var hexTable = (function () {
41787    var array = [];
41788    for (var i = 0; i < 256; ++i) {
41789        array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
41790    }
41791
41792    return array;
41793}());
41794
vendor: 4,142 bytes, lines 41795-41914
41795var compactQueue = function compactQueue(queue) {
41796    while (queue.length > 1) {
41797        var item = queue.pop();
41798        var obj = item.obj[item.prop];
41799
41800        if (isArray(obj)) {
41801            var compacted = [];
41802
41803            for (var j = 0; j < obj.length; ++j) {
41804                if (typeof obj[j] !== 'undefined') {
41805                    compacted[compacted.length] = obj[j];
41806                }
41807            }
41808
41809            item.obj[item.prop] = compacted;
41810        }
41811    }
41812};
41813
41814var arrayToObject = function arrayToObject(source, options) {
41815    var obj = options && options.plainObjects ? { __proto__: null } : {};
41816    for (var i = 0; i < source.length; ++i) {
41817        if (typeof source[i] !== 'undefined') {
41818            obj[i] = source[i];
41819        }
41820    }
41821
41822    return obj;
41823};
41824
41825var merge = function merge(target, source, options) {
41826    /* eslint no-param-reassign: 0 */
41827    if (!source) {
41828        return target;
41829    }
41830
41831    if (typeof source !== 'object' && typeof source !== 'function') {
41832        if (isArray(target)) {
41833            var nextIndex = target.length;
41834            if (options && typeof options.arrayLimit === 'number' && nextIndex > options.arrayLimit) {
41835                return markOverflow(arrayToObject(target.concat(source), options), nextIndex);
41836            }
41837            target[nextIndex] = source;
41838        } else if (target && typeof target === 'object') {
41839            if (isOverflow(target)) {
41840                // Add at next numeric index for overflow objects
41841                var newIndex = getMaxIndex(target) + 1;
41842                target[newIndex] = source;
41843                setMaxIndex(target, newIndex);
41844            } else if (options && options.strictMerge) {
41845                return [target, source];
41846            } else if (
41847                (options && (options.plainObjects || options.allowPrototypes))
41848                || !has.call(Object.prototype, source)
41849            ) {
41850                target[source] = true;
41851            }
41852        } else {
41853            return [target, source];
41854        }
41855
41856        return target;
41857    }
41858
41859    if (!target || typeof target !== 'object') {
41860        if (isOverflow(source)) {
41861            // Create new object with target at 0, source values shifted by 1
41862            var sourceKeys = Object.keys(source);
41863            var result = options && options.plainObjects
41864                ? { __proto__: null, 0: target }
41865                : { 0: target };
41866            for (var m = 0; m < sourceKeys.length; m++) {
41867                var oldKey = parseInt(sourceKeys[m], 10);
41868                result[oldKey + 1] = source[sourceKeys[m]];
41869            }
41870            return markOverflow(result, getMaxIndex(source) + 1);
41871        }
41872        var combined = [target].concat(source);
41873        if (options && typeof options.arrayLimit === 'number' && combined.length > options.arrayLimit) {
41874            return markOverflow(arrayToObject(combined, options), combined.length - 1);
41875        }
41876        return combined;
41877    }
41878
41879    var mergeTarget = target;
41880    if (isArray(target) && !isArray(source)) {
41881        mergeTarget = arrayToObject(target, options);
41882    }
41883
41884    if (isArray(target) && isArray(source)) {
41885        source.forEach(function (item, i) {
41886            if (has.call(target, i)) {
41887                var targetItem = target[i];
41888                if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
41889                    target[i] = merge(targetItem, item, options);
41890                } else {
41891                    target[target.length] = item;
41892                }
41893            } else {
41894                target[i] = item;
41895            }
41896        });
41897        return target;
41898    }
41899
41900    return Object.keys(source).reduce(function (acc, key) {
41901        var value = source[key];
41902
41903        if (has.call(acc, key)) {
41904            acc[key] = merge(acc[key], value, options);
41905        } else {
41906            acc[key] = value;
41907        }
41908
41909        if (isOverflow(source) && !isOverflow(acc)) {
41910            markOverflow(acc, getMaxIndex(source));
41911        }
41912        if (isOverflow(acc)) {
41913            var keyNum = parseInt(key, 10);
41914            if (String(keyNum) === key && keyNum >= 0 && keyNum > getMaxIndex(acc)) {
vendor: 4,133 bytes, lines 41915-42057
41915                setMaxIndex(acc, keyNum);
41916            }
41917        }
41918
41919        return acc;
41920    }, mergeTarget);
41921};
41922
41923var assign = function assignSingleSource(target, source) {
41924    return Object.keys(source).reduce(function (acc, key) {
41925        acc[key] = source[key];
41926        return acc;
41927    }, target);
41928};
41929
41930var decode = function (str, defaultDecoder, charset) {
41931    var strWithoutPlus = str.replace(/\+/g, ' ');
41932    if (charset === 'iso-8859-1') {
41933        // unescape never throws, no try...catch needed:
41934        return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
41935    }
41936    // utf-8
41937    try {
41938        return decodeURIComponent(strWithoutPlus);
41939    } catch (e) {
41940        return strWithoutPlus;
41941    }
41942};
41943
41944var limit = 1024;
41945
41946/* eslint operator-linebreak: [2, "before"] */
41947
41948var encode = function encode(str, defaultEncoder, charset, kind, format) {
41949    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
41950    // It has been adapted here for stricter adherence to RFC 3986
41951    if (str.length === 0) {
41952        return str;
41953    }
41954
41955    var string = str;
41956    if (typeof str === 'symbol') {
41957        string = Symbol.prototype.toString.call(str);
41958    } else if (typeof str !== 'string') {
41959        string = String(str);
41960    }
41961
41962    if (charset === 'iso-8859-1') {
41963        return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
41964            return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
41965        });
41966    }
41967
41968    var out = '';
41969    for (var j = 0; j < string.length; j += limit) {
41970        var segment = string.length >= limit ? string.slice(j, j + limit) : string;
41971        var arr = [];
41972
41973        for (var i = 0; i < segment.length; ++i) {
41974            var c = segment.charCodeAt(i);
41975            if (
41976                c === 0x2D // -
41977                || c === 0x2E // .
41978                || c === 0x5F // _
41979                || c === 0x7E // ~
41980                || (c >= 0x30 && c <= 0x39) // 0-9
41981                || (c >= 0x41 && c <= 0x5A) // a-z
41982                || (c >= 0x61 && c <= 0x7A) // A-Z
41983                || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( )
41984            ) {
41985                arr[arr.length] = segment.charAt(i);
41986                continue;
41987            }
41988
41989            if (c < 0x80) {
41990                arr[arr.length] = hexTable[c];
41991                continue;
41992            }
41993
41994            if (c < 0x800) {
41995                arr[arr.length] = hexTable[0xC0 | (c >> 6)]
41996                    + hexTable[0x80 | (c & 0x3F)];
41997                continue;
41998            }
41999
42000            if (c < 0xD800 || c >= 0xE000) {
42001                arr[arr.length] = hexTable[0xE0 | (c >> 12)]
42002                    + hexTable[0x80 | ((c >> 6) & 0x3F)]
42003                    + hexTable[0x80 | (c & 0x3F)];
42004                continue;
42005            }
42006
42007            i += 1;
42008            c = 0x10000 + (((c & 0x3FF) << 10) | (segment.charCodeAt(i) & 0x3FF));
42009
42010            arr[arr.length] = hexTable[0xF0 | (c >> 18)]
42011                + hexTable[0x80 | ((c >> 12) & 0x3F)]
42012                + hexTable[0x80 | ((c >> 6) & 0x3F)]
42013                + hexTable[0x80 | (c & 0x3F)];
42014        }
42015
42016        out += arr.join('');
42017    }
42018
42019    return out;
42020};
42021
42022var compact = function compact(value) {
42023    var queue = [{ obj: { o: value }, prop: 'o' }];
42024    var refs = [];
42025
42026    for (var i = 0; i < queue.length; ++i) {
42027        var item = queue[i];
42028        var obj = item.obj[item.prop];
42029
42030        var keys = Object.keys(obj);
42031        for (var j = 0; j < keys.length; ++j) {
42032            var key = keys[j];
42033            var val = obj[key];
42034            if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
42035                queue[queue.length] = { obj: obj, prop: key };
42036                refs[refs.length] = val;
42037            }
42038        }
42039    }
42040
42041    compactQueue(queue);
42042
42043    return value;
42044};
42045
42046var isRegExp = function isRegExp(obj) {
42047    return Object.prototype.toString.call(obj) === '[object RegExp]';
42048};
42049
42050var isBuffer = function isBuffer(obj) {
42051    if (!obj || typeof obj !== 'object') {
42052        return false;
42053    }
42054
42055    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
42056};
42057
42058var combine = function combine(a, b, arrayLimit, plainObjects) {
42059    // If 'a' is already an overflow object, add to it
42060    if (isOverflow(a)) {
42061        var newIndex = getMaxIndex(a) + 1;
42062        a[newIndex] = b;
42063        setMaxIndex(a, newIndex);
42064        return a;
42065    }
42066
42067    var result = [].concat(a, b);
42068    if (result.length > arrayLimit) {
42069        return markOverflow(arrayToObject(result, { plainObjects: plainObjects }), result.length - 1);
42070    }
42071    return result;
42072};
42073
42074var maybeMap = function maybeMap(val, fn) {
42075    if (isArray(val)) {
42076        var mapped = [];
42077        for (var i = 0; i < val.length; i += 1) {
42078            mapped[mapped.length] = fn(val[i]);
42079        }
42080        return mapped;
42081    }
42082    return fn(val);
42083};
42084
42085module.exports = {
42086    arrayToObject: arrayToObject,
42087    assign: assign,
42088    combine: combine,
42089    compact: compact,
42090    decode: decode,
42091    encode: encode,
42092    isBuffer: isBuffer,
42093    isOverflow: isOverflow,
42094    isRegExp: isRegExp,
42095    markOverflow: markOverflow,
42096    maybeMap: maybeMap,
42097    merge: merge
42098};
42099
42100},{"./formats":129,"side-channel":137}],134:[function(require,module,exports){
42101'use strict';
42102
42103var inspect = require('object-inspect');
42104
42105var $TypeError = require('es-errors/type');
42106
42107/*
42108* This function traverses the list returning the node corresponding to the given key.
42109*
42110* That node is also moved to the head of the list, so that if it's accessed again we don't need to traverse the whole list.
42111* By doing so, all the recently used nodes can be accessed relatively quickly.
42112*/
42113/** @type {import('./list.d.ts').listGetNode} */
42114// eslint-disable-next-line consistent-return
42115var listGetNode = function (list, key, isDelete) {
42116	/** @type {typeof list | NonNullable<(typeof list)['next']>} */
42117	var prev = list;
42118	/** @type {(typeof list)['next']} */
42119	var curr;
42120	// eslint-disable-next-line eqeqeq
42121	for (; (curr = prev.next) != null; prev = curr) {
42122		if (curr.key === key) {
42123			prev.next = curr.next;
42124			if (!isDelete) {
42125				// eslint-disable-next-line no-extra-parens
42126				curr.next = /** @type {NonNullable<typeof list.next>} */ (list.next);
42127				list.next = curr; // eslint-disable-line no-param-reassign
42128			}
42129			return curr;
42130		}
42131	}
42132};
42133
42134/** @type {import('./list.d.ts').listGet} */
42135var listGet = function (objects, key) {
42136	if (!objects) {
42137		return void undefined;
42138	}
42139	var node = listGetNode(objects, key);
42140	return node && node.value;
42141};
42142/** @type {import('./list.d.ts').listSet} */
42143var listSet = function (objects, key, value) {
42144	var node = listGetNode(objects, key);
42145	if (node) {
42146		node.value = value;
42147	} else {
42148		// Prepend the new node to the beginning of the list
42149		objects.next = /** @type {import('./list.d.ts').ListNode<typeof value, typeof key>} */ ({ // eslint-disable-line no-param-reassign, no-extra-parens
42150			key: key,
42151			next: objects.next,
42152			value: value
42153		});
42154	}
42155};
42156/** @type {import('./list.d.ts').listHas} */
42157var listHas = function (objects, key) {
42158	if (!objects) {
42159		return false;
42160	}
42161	return !!listGetNode(objects, key);
42162};
42163/** @type {import('./list.d.ts').listDelete} */
42164// eslint-disable-next-line consistent-return
42165var listDelete = function (objects, key) {
42166	if (objects) {
42167		return listGetNode(objects, key, true);
42168	}
42169};
42170
42171/** @type {import('.')} */
42172module.exports = function getSideChannelList() {
42173	/** @typedef {ReturnType<typeof getSideChannelList>} Channel */
42174	/** @typedef {Parameters<Channel['get']>[0]} K */
42175	/** @typedef {Parameters<Channel['set']>[1]} V */
42176
42177	/** @type {import('./list.d.ts').RootNode<V, K> | undefined} */ var $o;
42178
42179	/** @type {Channel} */
42180	var channel = {
42181		assert: function (key) {
42182			if (!channel.has(key)) {
42183				throw new $TypeError('Side channel does not contain ' + inspect(key));
42184			}
42185		},
42186		'delete': function (key) {
42187			var root = $o && $o.next;
42188			var deletedNode = listDelete($o, key);
42189			if (deletedNode && root && root === deletedNode) {
42190				$o = void undefined;
42191			}
42192			return !!deletedNode;
42193		},
42194		get: function (key) {
42195			return listGet($o, key);
42196		},
42197		has: function (key) {
42198			return listHas($o, key);
42199		},
42200		set: function (key, value) {
42201			if (!$o) {
42202				// Initialize the linked list as an empty node, so that we don't have to special-case handling of the first node: we can always refer to it as (previous node).next, instead of something like (list).head
42203				$o = {
42204					next: void undefined
42205				};
42206			}
42207			// eslint-disable-next-line no-extra-parens
42208			listSet(/** @type {NonNullable<typeof $o>} */ ($o), key, value);
42209		}
42210	};
42211	// @ts-expect-error TODO: figure out why this is erroring
42212	return channel;
42213};
42214
42215},{"es-errors/type":95,"object-inspect":120}],135:[function(require,module,exports){
42216'use strict';
42217
42218var GetIntrinsic = require('get-intrinsic');
42219var callBound = require('call-bound');
42220var inspect = require('object-inspect');
42221
42222var $TypeError = require('es-errors/type');
42223var $Map = GetIntrinsic('%Map%', true);
42224
42225/** @type {<K, V>(thisArg: Map<K, V>
vendor: 6,437 bytes, lines 42225-42428
42225, key: K) => V} */
42226var $mapGet = callBound('Map.prototype.get', true);
42227/** @type {<K, V>(thisArg: Map<K, V>, key: K, value: V) => void} */
42228var $mapSet = callBound('Map.prototype.set', true);
42229/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */
42230var $mapHas = callBound('Map.prototype.has', true);
42231/** @type {<K, V>(thisArg: Map<K, V>, key: K) => boolean} */
42232var $mapDelete = callBound('Map.prototype.delete', true);
42233/** @type {<K, V>(thisArg: Map<K, V>) => number} */
42234var $mapSize = callBound('Map.prototype.size', true);
42235
42236/** @type {import('.')} */
42237module.exports = !!$Map && /** @type {Exclude<import('.'), false>} */ function getSideChannelMap() {
42238	/** @typedef {ReturnType<typeof getSideChannelMap>} Channel */
42239	/** @typedef {Parameters<Channel['get']>[0]} K */
42240	/** @typedef {Parameters<Channel['set']>[1]} V */
42241
42242	/** @type {Map<K, V> | undefined} */ var $m;
42243
42244	/** @type {Channel} */
42245	var channel = {
42246		assert: function (key) {
42247			if (!channel.has(key)) {
42248				throw new $TypeError('Side channel does not contain ' + inspect(key));
42249			}
42250		},
42251		'delete': function (key) {
42252			if ($m) {
42253				var result = $mapDelete($m, key);
42254				if ($mapSize($m) === 0) {
42255					$m = void undefined;
42256				}
42257				return result;
42258			}
42259			return false;
42260		},
42261		get: function (key) { // eslint-disable-line consistent-return
42262			if ($m) {
42263				return $mapGet($m, key);
42264			}
42265		},
42266		has: function (key) {
42267			if ($m) {
42268				return $mapHas($m, key);
42269			}
42270			return false;
42271		},
42272		set: function (key, value) {
42273			if (!$m) {
42274				// @ts-expect-error TS can't handle narrowing a variable inside a closure
42275				$m = new $Map();
42276			}
42277			$mapSet($m, key, value);
42278		}
42279	};
42280
42281	// @ts-expect-error TODO: figure out why TS is erroring here
42282	return channel;
42283};
42284
42285},{"call-bound":87,"es-errors/type":95,"get-intrinsic":101,"object-inspect":120}],136:[function(require,module,exports){
42286'use strict';
42287
42288var GetIntrinsic = require('get-intrinsic');
42289var callBound = require('call-bound');
42290var inspect = require('object-inspect');
42291var getSideChannelMap = require('side-channel-map');
42292
42293var $TypeError = require('es-errors/type');
42294var $WeakMap = GetIntrinsic('%WeakMap%', true);
42295
42296/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => V} */
42297var $weakMapGet = callBound('WeakMap.prototype.get', true);
42298/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K, value: V) => void} */
42299var $weakMapSet = callBound('WeakMap.prototype.set', true);
42300/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */
42301var $weakMapHas = callBound('WeakMap.prototype.has', true);
42302/** @type {<K extends object, V>(thisArg: WeakMap<K, V>, key: K) => boolean} */
42303var $weakMapDelete = callBound('WeakMap.prototype.delete', true);
42304
42305/** @type {import('.')} */
42306module.exports = $WeakMap
42307	? /** @type {Exclude<import('.'), false>} */ function getSideChannelWeakMap() {
42308		/** @typedef {ReturnType<typeof getSideChannelWeakMap>} Channel */
42309		/** @typedef {Parameters<Channel['get']>[0]} K */
42310		/** @typedef {Parameters<Channel['set']>[1]} V */
42311
42312		/** @type {WeakMap<K & object, V> | undefined} */ var $wm;
42313		/** @type {Channel | undefined} */ var $m;
42314
42315		/** @type {Channel} */
42316		var channel = {
42317			assert: function (key) {
42318				if (!channel.has(key)) {
42319					throw new $TypeError('Side channel does not contain ' + inspect(key));
42320				}
42321			},
42322			'delete': function (key) {
42323				if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
42324					if ($wm) {
42325						return $weakMapDelete($wm, key);
42326					}
42327				} else if (getSideChannelMap) {
42328					if ($m) {
42329						return $m['delete'](key);
42330					}
42331				}
42332				return false;
42333			},
42334			get: function (key) {
42335				if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
42336					if ($wm) {
42337						return $weakMapGet($wm, key);
42338					}
42339				}
42340				return $m && $m.get(key);
42341			},
42342			has: function (key) {
42343				if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
42344					if ($wm) {
42345						return $weakMapHas($wm, key);
42346					}
42347				}
42348				return !!$m && $m.has(key);
42349			},
42350			set: function (key, value) {
42351				if ($WeakMap && key && (typeof key === 'object' || typeof key === 'function')) {
42352					if (!$wm) {
42353						$wm = new $WeakMap();
42354					}
42355					$weakMapSet($wm, key, value);
42356				} else if (getSideChannelMap) {
42357					if (!$m) {
42358						$m = getSideChannelMap();
42359					}
42360					// eslint-disable-next-line no-extra-parens
42361					/** @type {NonNullable<typeof $m>} */ ($m).set(key, value);
42362				}
42363			}
42364		};
42365
42366		// @ts-expect-error TODO: figure out why this is erroring
42367		return channel;
42368	}
42369	: getSideChannelMap;
42370
42371},{"call-bound":87,"es-errors/type":95,"get-intrinsic":101,"object-inspect":120,"side-channel-map":135}],137:[function(require,module,exports){
42372'use strict';
42373
42374var $TypeError = require('es-errors/type');
42375var inspect = require('object-inspect');
42376var getSideChannelList = require('side-channel-list');
42377var getSideChannelMap = require('side-channel-map');
42378var getSideChannelWeakMap = require('side-channel-weakmap');
42379
42380var makeChannel = getSideChannelWeakMap || getSideChannelMap || getSideChannelList;
42381
42382/** @type {import('.')} */
42383module.exports = function getSideChannel() {
42384	/** @typedef {ReturnType<typeof getSideChannel>} Channel */
42385
42386	/** @type {Channel | undefined} */ var $channelData;
42387
42388	/** @type {Channel} */
42389	var channel = {
42390		assert: function (key) {
42391			if (!channel.has(key)) {
42392				throw new $TypeError('Side channel does not contain ' + inspect(key));
42393			}
42394		},
42395		'delete': function (key) {
42396			return !!$channelData && $channelData['delete'](key);
42397		},
42398		get: function (key) {
42399			return $channelData && $channelData.get(key);
42400		},
42401		has: function (key) {
42402			return !!$channelData && $channelData.has(key);
42403		},
42404		set: function (key, value) {
42405			if (!$channelData) {
42406				$channelData = makeChannel();
42407			}
42408
42409			$channelData.set(key, value);
42410		}
42411	};
42412	// @ts-expect-error TODO: figure out why this is erroring
42413	return channel;
42414};
42415
42416},{"es-errors/type":95,"object-inspect":120,"side-channel-list":134,"side-channel-map":135,"side-channel-weakmap":136}],138:[function(require,module,exports){
42417
42418},{}],139:[function(require,module,exports){
42419(function (global){
42420/*! https://mths.be/punycode v1.3.2 by @mathias */
42421;(function(root) {
42422
42423	/** Detect free variables */
42424	var freeExports = typeof exports == 'object' && exports &&
42425		!exports.nodeType && exports;
42426	var freeModule = typeof module == 'object' && module &&
42427		!module.nodeType && module;
42428	var freeGlobal = typeof global == 'object' && g
vendor: 10,095 bytes, lines 42428-42797
42428lobal;
42429	if (
42430		freeGlobal.global === freeGlobal ||
42431		freeGlobal.window === freeGlobal ||
42432		freeGlobal.self === freeGlobal
42433	) {
42434		root = freeGlobal;
42435	}
42436
42437	/**
42438	 * The `punycode` object.
42439	 * @name punycode
42440	 * @type Object
42441	 */
42442	var punycode,
42443
42444	/** Highest positive signed 32-bit float value */
42445	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
42446
42447	/** Bootstring parameters */
42448	base = 36,
42449	tMin = 1,
42450	tMax = 26,
42451	skew = 38,
42452	damp = 700,
42453	initialBias = 72,
42454	initialN = 128, // 0x80
42455	delimiter = '-', // '\x2D'
42456
42457	/** Regular expressions */
42458	regexPunycode = /^xn--/,
42459	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
42460	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
42461
42462	/** Error messages */
42463	errors = {
42464		'overflow': 'Overflow: input needs wider integers to process',
42465		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
42466		'invalid-input': 'Invalid input'
42467	},
42468
42469	/** Convenience shortcuts */
42470	baseMinusTMin = base - tMin,
42471	floor = Math.floor,
42472	stringFromCharCode = String.fromCharCode,
42473
42474	/** Temporary variable */
42475	key;
42476
42477	/*--------------------------------------------------------------------------*/
42478
42479	/**
42480	 * A generic error utility function.
42481	 * @private
42482	 * @param {String} type The error type.
42483	 * @returns {Error} Throws a `RangeError` with the applicable error message.
42484	 */
42485	function error(type) {
42486		throw RangeError(errors[type]);
42487	}
42488
42489	/**
42490	 * A generic `Array#map` utility function.
42491	 * @private
42492	 * @param {Array} array The array to iterate over.
42493	 * @param {Function} callback The function that gets called for every array
42494	 * item.
42495	 * @returns {Array} A new array of values returned by the callback function.
42496	 */
42497	function map(array, fn) {
42498		var length = array.length;
42499		var result = [];
42500		while (length--) {
42501			result[length] = fn(array[length]);
42502		}
42503		return result;
42504	}
42505
42506	/**
42507	 * A simple `Array#map`-like wrapper to work with domain name strings or email
42508	 * addresses.
42509	 * @private
42510	 * @param {String} domain The domain name or email address.
42511	 * @param {Function} callback The function that gets called for every
42512	 * character.
42513	 * @returns {Array} A new string of characters returned by the callback
42514	 * function.
42515	 */
42516	function mapDomain(string, fn) {
42517		var parts = string.split('@');
42518		var result = '';
42519		if (parts.length > 1) {
42520			// In email addresses, only the domain name should be punycoded. Leave
42521			// the local part (i.e. everything up to `@`) intact.
42522			result = parts[0] + '@';
42523			string = parts[1];
42524		}
42525		// Avoid `split(regex)` for IE8 compatibility. See #17.
42526		string = string.replace(regexSeparators, '\x2E');
42527		var labels = string.split('.');
42528		var encoded = map(labels, fn).join('.');
42529		return result + encoded;
42530	}
42531
42532	/**
42533	 * Creates an array containing the numeric code points of each Unicode
42534	 * character in the string. While JavaScript uses UCS-2 internally,
42535	 * this function will convert a pair of surrogate halves (each of which
42536	 * UCS-2 exposes as separate characters) into a single code point,
42537	 * matching UTF-16.
42538	 * @see `punycode.ucs2.encode`
42539	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
42540	 * @memberOf punycode.ucs2
42541	 * @name decode
42542	 * @param {String} string The Unicode input string (UCS-2).
42543	 * @returns {Array} The new array of code points.
42544	 */
42545	function ucs2decode(string) {
42546		var output = [],
42547		    counter = 0,
42548		    length = string.length,
42549		    value,
42550		    extra;
42551		while (counter < length) {
42552			value = string.charCodeAt(counter++);
42553			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
42554				// high surrogate, and there is a next character
42555				extra = string.charCodeAt(counter++);
42556				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
42557					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
42558				} else {
42559					// unmatched surrogate; only append this code unit, in case the next
42560					// code unit is the high surrogate of a surrogate pair
42561					output.push(value);
42562					counter--;
42563				}
42564			} else {
42565				output.push(value);
42566			}
42567		}
42568		return output;
42569	}
42570
42571	/**
42572	 * Creates a string based on an array of numeric code points.
42573	 * @see `punycode.ucs2.decode`
42574	 * @memberOf punycode.ucs2
42575	 * @name encode
42576	 * @param {Array} codePoints The array of numeric code points.
42577	 * @returns {String} The new Unicode string (UCS-2).
42578	 */
42579	function ucs2encode(array) {
42580		return map(array, function(value) {
42581			var output = '';
42582			if (value > 0xFFFF) {
42583				value -= 0x10000;
42584				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
42585				value = 0xDC00 | value & 0x3FF;
42586			}
42587			output += stringFromCharCode(value);
42588			return output;
42589		}).join('');
42590	}
42591
42592	/**
42593	 * Converts a basic code point into a digit/integer.
42594	 * @see `digitToBasic()`
42595	 * @private
42596	 * @param {Number} codePoint The basic numeric code point value.
42597	 * @returns {Number} The numeric value of a basic code point (for use in
42598	 * representing integers) in the range `0` to `base - 1`, or `base` if
42599	 * the code point does not represent a value.
42600	 */
42601	function basicToDigit(codePoint) {
42602		if (codePoint - 48 < 10) {
42603			return codePoint - 22;
42604		}
42605		if (codePoint - 65 < 26) {
42606			return codePoint - 65;
42607		}
42608		if (codePoint - 97 < 26) {
42609			return codePoint - 97;
42610		}
42611		return base;
42612	}
42613
42614	/**
42615	 * Converts a digit/integer into a basic code point.
42616	 * @see `basicToDigit()`
42617	 * @private
42618	 * @param {Number} digit The numeric value of a basic code point.
42619	 * @returns {Number} The basic code point whose value (when used for
42620	 * representing integers) is `digit`, which needs to be in the range
42621	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
42622	 * used; else, the lowercase form is used. The behavior is undefined
42623	 * if `flag` is non-zero and `digit` has no uppercase form.
42624	 */
42625	function digitToBasic(digit, flag) {
42626		//  0..25 map to ASCII a..z or A..Z
42627		// 26..35 map to ASCII 0..9
42628		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
42629	}
42630
42631	/**
42632	 * Bias adaptation function as per section 3.4 of RFC 3492.
42633	 * http://tools.ietf.org/html/rfc3492#section-3.4
42634	 * @private
42635	 */
42636	function adapt(delta, numPoints, firstTime) {
42637		var k = 0;
42638		delta = firstTime ? floor(delta / damp) : delta >> 1;
42639		delta += floor(delta / numPoints);
42640		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
42641			delta = floor(delta / baseMinusTMin);
42642		}
42643		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
42644	}
42645
42646	/**
42647	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
42648	 * symbols.
42649	 * @memberOf punycode
42650	 * @param {String} input The Punycode string of ASCII-only symbols.
42651	 * @returns {String} The resulting string of Unicode symbols.
42652	 */
42653	function decode(input) {
42654		// Don't use UCS-2
42655		var output = [],
42656		    inputLength = input.length,
42657		    out,
42658		    i = 0,
42659		    n = initialN,
42660		    bias = initialBias,
42661		    basic,
42662		    j,
42663		    index,
42664		    oldi,
42665		    w,
42666		    k,
42667		    digit,
42668		    t,
42669		    /** Cached calculation results */
42670		    baseMinusT;
42671
42672		// Handle the basic code points: let `basic` be the number of input code
42673		// points before the last delimiter, or `0` if there is none, then copy
42674		// the first basic code points to the output.
42675
42676		basic = input.lastIndexOf(delimiter);
42677		if (basic < 0) {
42678			basic = 0;
42679		}
42680
42681		for (j = 0; j < basic; ++j) {
42682			// if it's not a basic code point
42683			if (input.charCodeAt(j) >= 0x80) {
42684				error('not-basic');
42685			}
42686			output.push(input.charCodeAt(j));
42687		}
42688
42689		// Main decoding loop: start just after the last delimiter if any basic code
42690		// points were copied; start at the beginning otherwise.
42691
42692		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
42693
42694			// `index` is the index of the next character to be consumed.
42695			// Decode a generalized variable-length integer into `delta`,
42696			// which gets added to `i`. The overflow checking is easier
42697			// if we increase `i` as we go, then subtract off its starting
42698			// value at the end to obtain `delta`.
42699			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
42700
42701				if (index >= inputLength) {
42702					error('invalid-input');
42703				}
42704
42705				digit = basicToDigit(input.charCodeAt(index++));
42706
42707				if (digit >= base || digit > floor((maxInt - i) / w)) {
42708					error('overflow');
42709				}
42710
42711				i += digit * w;
42712				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
42713
42714				if (digit < t) {
42715					break;
42716				}
42717
42718				baseMinusT = base - t;
42719				if (w > floor(maxInt / baseMinusT)) {
42720					error('overflow');
42721				}
42722
42723				w *= baseMinusT;
42724
42725			}
42726
42727			out = output.length + 1;
42728			bias = adapt(i - oldi, out, oldi == 0);
42729
42730			// `i` was supposed to wrap around from `out` to `0`,
42731			// incrementing `n` each time, so we'll fix that now:
42732			if (floor(i / out) > maxInt - n) {
42733				error('overflow');
42734			}
42735
42736			n += floor(i / out);
42737			i %= out;
42738
42739			// Insert `n` at position `i` of the output
42740			output.splice(i++, 0, n);
42741
42742		}
42743
42744		return ucs2encode(output);
42745	}
42746
42747	/**
42748	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
42749	 * Punycode string of ASCII-only symbols.
42750	 * @memberOf punycode
42751	 * @param {String} input The string of Unicode symbols.
42752	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
42753	 */
42754	function encode(input) {
42755		var n,
42756		    delta,
42757		    handledCPCount,
42758		    basicLength,
42759		    bias,
42760		    j,
42761		    m,
42762		    q,
42763		    k,
42764		    t,
42765		    currentValue,
42766		    output = [],
42767		    /** `inputLength` will hold the number of code points in `input`. */
42768		    inputLength,
42769		    /** Cached calculation results */
42770		    handledCPCountPlusOne,
42771		    baseMinusT,
42772		    qMinusT;
42773
42774		// Convert the input in UCS-2 to Unicode
42775		input = ucs2decode(input);
42776
42777		// Cache the length
42778		inputLength = input.length;
42779
42780		// Initialize the state
42781		n = initialN;
42782		delta = 0;
42783		bias = initialBias;
42784
42785		// Handle the basic code points
42786		for (j = 0; j < inputLength; ++j) {
42787			currentValue = input[j];
42788			if (currentValue < 0x80) {
42789				output.push(stringFromCharCode(currentValue));
42790			}
42791		}
42792
42793		handledCPCount = basicLength = output.length;
42794
42795		// `handledCPCount` is the number of code points that have been handled;
42796		// `basicLength` is the number of basic code points.
42797
vendor: 3,147 bytes, lines 42798-42908
42798		// Finish the basic string - if it is not empty - with a delimiter
42799		if (basicLength) {
42800			output.push(delimiter);
42801		}
42802
42803		// Main encoding loop:
42804		while (handledCPCount < inputLength) {
42805
42806			// All non-basic code points < n have been handled already. Find the next
42807			// larger one:
42808			for (m = maxInt, j = 0; j < inputLength; ++j) {
42809				currentValue = input[j];
42810				if (currentValue >= n && currentValue < m) {
42811					m = currentValue;
42812				}
42813			}
42814
42815			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
42816			// but guard against overflow
42817			handledCPCountPlusOne = handledCPCount + 1;
42818			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
42819				error('overflow');
42820			}
42821
42822			delta += (m - n) * handledCPCountPlusOne;
42823			n = m;
42824
42825			for (j = 0; j < inputLength; ++j) {
42826				currentValue = input[j];
42827
42828				if (currentValue < n && ++delta > maxInt) {
42829					error('overflow');
42830				}
42831
42832				if (currentValue == n) {
42833					// Represent delta as a generalized variable-length integer
42834					for (q = delta, k = base; /* no condition */; k += base) {
42835						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
42836						if (q < t) {
42837							break;
42838						}
42839						qMinusT = q - t;
42840						baseMinusT = base - t;
42841						output.push(
42842							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
42843						);
42844						q = floor(qMinusT / baseMinusT);
42845					}
42846
42847					output.push(stringFromCharCode(digitToBasic(q, 0)));
42848					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
42849					delta = 0;
42850					++handledCPCount;
42851				}
42852			}
42853
42854			++delta;
42855			++n;
42856
42857		}
42858		return output.join('');
42859	}
42860
42861	/**
42862	 * Converts a Punycode string representing a domain name or an email address
42863	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
42864	 * it doesn't matter if you call it on a string that has already been
42865	 * converted to Unicode.
42866	 * @memberOf punycode
42867	 * @param {String} input The Punycoded domain name or email address to
42868	 * convert to Unicode.
42869	 * @returns {String} The Unicode representation of the given Punycode
42870	 * string.
42871	 */
42872	function toUnicode(input) {
42873		return mapDomain(input, function(string) {
42874			return regexPunycode.test(string)
42875				? decode(string.slice(4).toLowerCase())
42876				: string;
42877		});
42878	}
42879
42880	/**
42881	 * Converts a Unicode string representing a domain name or an email address to
42882	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
42883	 * i.e. it doesn't matter if you call it with a domain that's already in
42884	 * ASCII.
42885	 * @memberOf punycode
42886	 * @param {String} input The domain name or email address to convert, as a
42887	 * Unicode string.
42888	 * @returns {String} The Punycode representation of the given domain name or
42889	 * email address.
42890	 */
42891	function toASCII(input) {
42892		return mapDomain(input, function(string) {
42893			return regexNonASCII.test(string)
42894				? 'xn--' + encode(string)
42895				: string;
42896		});
42897	}
42898
42899	/*--------------------------------------------------------------------------*/
42900
42901	/** Define the public API */
42902	punycode = {
42903		/**
42904		 * A string representing the current Punycode.js version number.
42905		 * @memberOf punycode
42906		 * @type String
42907		 */
42908		'version': '1.
429083.2',
42909		/**
42910		 * An object of methods to convert from JavaScript's internal character
42911		 * representation (UCS-2) to Unicode code points, and back.
42912		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
42913		 * @memberOf punycode
42914		 * @type Object
42915		 */
42916		'ucs2': {
42917			'decode': ucs2decode,
42918			'encode': ucs2encode
42919		},
42920		'decode': decode,
42921		'encode': encode,
42922		'toASCII': toASCII,
42923		'toUnicode': toUnicode
42924	};
42925
42926	/** Expose `punycode` */
42927	// Some AMD build optimizers, like r.js, check for specific condition patterns
42928	// like the following:
42929	if (
42930		typeof define == 'function' &&
42931		typeof define.amd == 'object' &&
42932		define.amd
42933	) {
42934		define('punycode', function() {
42935			return punycode;
42936		});
42937	} else if (freeExports && freeModule) {
42938		if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
42939			freeModule.exports = punycode;
42940		} else { // in Narwhal or RingoJS v0.7.0-
42941			for (key in punycode) {
42942				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
42943			}
42944		}
42945	} else { // in Rhino or a web browser
42946		root.punycode = punycode;
42947	}
42948
42949}(this));
42950
42951}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
42952},{}],140:[function(require,module,exports){
42953// Copyright Joyent, Inc. and other Node contributors.
42954//
42955// Permission is hereby granted, free of charge, to any person obtaining a
42956// copy of this software and associated documentation files (the
42957// "Software"), to deal in the Software without restriction, including
42958// without limitation the rights to use, copy, modify, merge, publish,
42959// distribute, sublicense, and/or sell copies of the Software, and to permit
42960// persons to whom the Software is furnished to do so, subject to the
42961// following conditions:
42962//
42963// The above copyright notice and this permission notice shall be included
42964// in all copies or substantial portions of the Software.
42965//
42966// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
42967// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
42968// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
42969// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
42970// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
42971// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
42972// USE OR OTHER DEALINGS IN THE SOFTWARE.
42973
42974'use strict';
42975
42976// If obj.hasOwnProperty has been overridden, then calling
42977// obj.hasOwnProperty(prop) will break.
42978// See: https://github.com/joyent/node/issues/1707
42979function hasOwnProperty(obj, prop) {
42980  return Object.prototype.hasOwnProperty.call(obj, prop);
42981}
42982
42983module.exports = function(qs, sep, eq, options) {
42984  sep = sep || '&';
42985  eq = eq || '=';
42986  var obj = {};
42987
42988  if (typeof qs !== 'string' || qs.length === 0) {
42989    return obj;
42990  }
42991
42992  var regexp = /\+/g;
42993  qs = qs.split(sep);
42994
42995  var maxKeys = 1000;
42996  if (options && typeof options.maxKeys === 'number') {
42997    maxKeys = options.maxKeys;
42998  }
42999
43000  var len = qs.length;
43001  // maxKeys <= 0 means that we should not limit keys count
43002  if (maxKeys > 0 && len > maxKeys) {
43003    len = maxKeys;
43004  }
43005
43006  for (var i = 0; i < len; ++i) {
43007    var x = qs[i].replace(regexp, '%20'),
43008        idx = x.indexOf(eq),
43009        kstr, vstr, k, v;
43010
43011    if (idx >= 0) {
43012      kstr = x.substr(0, idx);
43013      vstr = x.substr(idx + 1);
43014    } else {
43015      kstr = x;
43016      vstr = '';
43017    }
43018
43019    k = decodeURIComponent(kstr);
43020    v = decodeURIComponent(vstr);
43021
43022    if (!hasOwnProperty(obj, k)) {
43023      obj[k] = v;
43024    } else if (isArray(obj[k])) {
43025      obj[k].push(v);
43026    } else {
43027      obj[k] = [obj[k], v];
43028    }
43029  }
43030
43031  return obj;
43032};
43033
43034var isArray = Array.isArray || function (xs) {
43035  return Object.prototype.toString.call(xs) === '[object Array]';
43036};
43037
43038},{}],141:[function(require,module,exports){
43039// Copyright Joyent, Inc. and other Node contributors.
43040//
43041// Permission is hereby granted, free of charge, to any person obtaining a
43042// copy of this software and associated documentation files (the
43043// "Software"), to deal in the Software without restriction, including
43044// without limitation the rights to use, copy, modify, merge, publish,
43045// distribute, sublicense, and/or sell copies of the Software, and to permit
43046// persons to whom the Software is furnished to do so, subject to the
43047// following conditions:
43048//
43049// The above copyright notice and this permission notice shall be included
43050// in all copies or substantial portions of the Software.
43051//
43052// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
43053// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
43054// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
43055// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
43056// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
43057// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
43058// USE OR OTHER DEALINGS IN THE SOFTWARE.
43059
43060'use strict';
43061
43062var stringifyPrimitive = function(v) {
43063  switch (typeof v) {
43064    case 'string':
43065      return v;
43066
43067    case 'boolean':
43068      return v ? 'true' : 'false';
43069
43070    case 'number':
43071      return isFinite(v) ? v : '';
43072
43073    default:
43074      return '';
43075  }
43076};
43077
43078module.exports = function(obj, sep, eq, name) {
43079  sep = sep || '&';
43080  eq = eq || '=';
43081  if (obj === null) {
43082    obj = undefined;
43083  }
43084
43085  if (typeof obj === 'object') {
43086    return map(objectKeys(obj), function(k) {
43087      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
43088      if (isArray(obj[k])) {
43089        return map(obj[k], function(v) {
43090          return ks + encodeURIComponent(stringifyPrimitive(v));
43091        }).join(sep);
43092      } else {
43093        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
43094      }
43095    }).join(sep);
43096
43097  }
43098
43099  if (!name) return '';
43100  return encodeURIComponent(stringifyPrimitive(name)) + eq +
43101         encodeURIComponent(stringifyPrimitive(obj));
43102};
43103
43104var isArray = Array.isArray || function (xs) {
43105  return Object.prototype.toString.call(xs) === '[object Array]';
43106};
43107
43108function map (xs, f) {
43109  if (xs.map) return xs.map(f);
43110  var res = [];
43111  for (var i = 0; i < xs.length; i++) {
43112    res.push(f(xs[i], i));
43113  }
43114  return res;
43115}
43116
43117var objectKeys = Object.keys || function (obj) {
43118  var res = [];
43119  for (var key in obj) {
43120    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
43121  }
43122  return res;
43123};
43124
43125},{}],142:[function(require,module,exports){
43126'use strict';
43127
43128exports.decode = exports.parse = require('./decode');
43129exports.encode = exports.stringify = require('./encode');
43130
43131},{"./decode":140,"./encode":141}],143:[function(require,module,exports){
43132/*!
43133 * URI.js - Mutating URLs
43134 * IPv6 Support
43135 *
43136 * Version: 1.19.2
43137 *
43138 * Author: Rodney Rehm
43139 * Web: http://medialize.github.io/URI.js/
43140 *
43141 * Licensed under
43142 *   MIT License http://www.opensource.org/licenses/mit-license
43143 *
43144 */
43145
43146(function (root, factory) {
43147  'use strict';
43148  // https://github.com/umdjs/umd/blob/master/returnExports.js
43149  if (typeof module === 'object' && module.exports) {
43150    // Node
43151    module.exports = factory();
43152  } else if (typeof define === 'function' && define.amd) {
43153    // AMD. Register as an anonymous module.
43154    define(factory);
43155  } else {
43156    // Browser globals (root is window)
43157    root.IPv6 = factory(root);
43158  }
43159}(this, function (root) {
43160  'use strict';
43161
43162  /*
43163  var _in = "fe80:0000:0000:0000:0204:61ff:fe9d:f156";
43164  var _out = IPv6.best(_in);
43165  var _expected = "fe80::204:61ff:fe9d:f156";
43166
43167  console.log(_in, _out, _expected, _out === _expected);
43168  */
43169
43170  // save current IPv6 variable, if any
43171  var _IPv6 = root && root.IPv6;
43172
43173  function bestPresentation(address) {
43174    // based on:
43175    // Javascript to test an IPv6 address for proper format, and to
43176    // present the "best text representation" according to IETF Draft RFC at
43177    // http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-04
43178    // 8 Feb 2010 Rich Brown, Dartware, LLC
43179    // Please feel free to use this code as long as you provide a link to
43180    // http://www.intermapper.com
43181    // http://intermapper.com/support/tools/IPV6-Validator.aspx
43182    // http://download.dartware.com/thirdparty/ipv6validator.js
43183
43184    var _address = address.toLowerCase();
43185    var segments = _address.split(':');
43186    var length = segments.length;
43187    var total = 8;
43188
43189    // trim colons (:: or ::a:b:c… or …a:b:c::)
43190    if (segments[0] === '' && segments[1] === '' && segments[2] === '') {
43191      // must have been ::
43192      // remove first two items
43193      segments.shift();
43194      segments.shift();
43195    } else if (segments[0] === '' && segments[1] === '') {
43196      // must have been ::xxxx
43197      // remove the first item
43198      segments.shift();
43199    } else if (segments[length - 1] === '' && segments[length - 2] === '') {
43200      // must have been xxxx::
43201      segments.pop();
43202    }
43203
43204    length = segments.length;
43205
43206    // adjust total segments for IPv4 trailer
43207    if (segments[length - 1].indexOf('.') !== -1) {
43208      // found a "." which means IPv4
43209      total = 7;
43210    }
43211
43212    // fill empty segments them with "0000"
43213    var pos;
43214    for (pos = 0; pos < length; pos++) {
43215      if (segments[pos] === '') {
43216        break;
43217      }
43218    }
43219
43220    if (pos < total) {
43221      segments.splice(pos, 1, '0000');
43222      while (segments.length < total) {
43223        segments.splice(pos, 0, '0000');
43224      }
43225    }
43226
43227    // strip leading zeros
43228    var _segments;
43229    for (var i = 0; i < total; i++) {
43230      _segments = segments[i].split('');
43231      for (var j = 0; j < 3 ; j++) {
43232        if (_segments[0] === '0' && _segments.length > 1) {
43233          _segments.splice(0,1);
43234        } else {
43235          break;
43236        }
43237      }
43238
43239      segments[i] = _segments.join('');
43240    }
43241
43242    // find longest sequence of zeroes and coalesce them into one segment
43243    var best = -1;
43244    var _best = 0;
43245    var _current = 0;
43246    var current = -1;
43247    var inzeroes = false;
43248    // i; already declared
43249
43250    for (i = 0; i < total; i++) {
43251      if (inzeroes) {
43252        if (segments[i] === '0') {
43253          _current += 1;
43254        } else {
43255          inzeroes = false;
43256          if (_current > _best) {
43257            best = current;
43258            _best = _current;
43259          }
43260        }
43261      } else {
43262        if (segments[i] === '0') {
43263          inzeroes = true;
43264          current = i;
43265          _current = 1;
43266        }
43267      }
43268    }
43269
43270    if (_current > _best) {
43271      best = current;
43272      _best = _current;
43273    }
43274
43275    if (_best > 1) {
43276      segments.splice(best, _best, '');
43277    }
43278
43279    length = segments.length;
43280
43281    // assemble remaining segments
43282    var result = '';
43283    if (segments[0] === '')  {
43284      result = ':';
43285    }
43286
43287    for (i = 0; i < length; i++) {
43288      result += segments[i];
43289      if (i === length - 1) {
43290        break;
43291      }
43292
43293      result += ':';
43294    }
43295
43296    if (segments[length - 1] === '') {
43297      result += ':';
43298    }
43299
43300    return result;
43301  }
43302
43303  function noConflict() {
43304    /*jshint validthis: true */
43305    if (root.IPv6 === this) {
43306      root.IPv6 = _IPv6;
43307    }
43308
43309    return this;
43310  }
43311
43312  return {
43313    best: bestPresentation,
43314    noConflict: noConflict
43315  };
43316}));
43317
43318},{}],144:[function(require,module,exports){
43319/*!
43320 * URI.js - Mutating URLs
43321 * Second Level Domain (SLD) Support
43322 *
43323 * Version: 1.19.2
43324 *
43325 * Author: Rodney Rehm
43326 * Web: http://medialize.github.io/URI.js/
43327 *
43328 * Licensed under
43329 *   MIT License http://www.opensource.org/licenses/mit-license
43330 *
43331 */
43332
43333(function (root, factory) {
43334  'use strict';
43335  // https://github.com/umdjs/umd/blob/master/returnExports.js
43336  if (typeof module === 'object' && module.exports) {
43337    // Node
43338    module.exports = factory();
43339  } else if (typeof define === 'function' && define.amd) {
43340    // AMD. Register as an anonymous module.
43341    define(factory);
43342  } else {
43343    // Browser globals (root is window)
43344    root.SecondLevelDomains = factory(root);
43345  }
43346}(this, function (root) {
43347  'use strict';
43348
43349  // save current SecondLevelDomains variable, if any
43350  var _SecondLevelDomains = root && root.SecondLevelDomains;
43351
43352  var SLD = {
43353    // list of known Second Level Domains
43354    // converted list of SLDs from https://github.com/gavingmiller/second-level-domains
43355    // ----
43356    // publicsuffix.org is more current and actually used by a couple of browsers internally.
43357    // downside is it also contains domains like "dyndns.org" - which is fine for the security
43358    // issues browser have to deal with (SOP for cookies, etc) - but is way overboard for URI.js
43359    // ----
43360    list: {
43361      'ac':' com gov mil net org ',
43362      'ae':' ac co gov mil name net org pro sch ',
43363      'af':' com edu gov net org ',
43364      'al':' com edu gov mil net org ',
43365      'ao':' co ed gv it og pb ',
43366      'ar':' com edu gob gov int mil net org tur ',
43367      'at':' ac co gv or ',
43368      'au':' asn com csiro edu gov id net org ',
43369      'ba':' co com edu gov mil net org rs unbi unmo unsa untz unze ',
43370      'bb':' biz co com edu gov info net org store tv ',
43371      'bh':' biz cc com edu gov info net org ',
43372      'bn':' com edu gov net org ',
43373      'bo':' com edu gob gov int mil net org tv ',
43374      'br':' adm adv agr am arq art ato b bio blog bmd cim cng cnt com coop ecn edu eng esp etc eti far flog fm fnd fot fst g12 ggf gov imb ind inf jor jus lel mat med mil mus net nom not ntr odo org ppg pro psc psi qsl rec slg srv tmp trd tur tv vet vlog wiki zlg ',
43375      'bs':' com edu gov net org ',
43376      'bz':' du et om ov rg ',
43377      'ca':' ab bc mb nb nf nl ns nt nu on pe qc sk yk ',
43378      'ck':' biz co edu gen gov info net org ',
43379      'cn':' ac ah bj com cq edu fj gd gov gs gx gz ha hb he hi hl hn jl js jx ln mil net nm nx org qh sc sd sh sn sx tj tw xj xz yn zj ',
43380      'co':' com edu gov mil net nom org ',
43381      'cr':' ac c co ed fi go or sa ',
43382      'cy':' ac biz com ekloges gov ltd name net org parliament press pro tm ',
43383      'do':' art com edu gob gov mil net org sld web ',
43384      'dz':' art asso com edu gov net org pol ',
43385      'ec':' com edu fin gov info med mil net org pro ',
43386      'eg':' com edu eun gov mil name net org sci ',
43387      'er':' com edu gov ind mil net org rochest w ',
43388      'es':' com edu gob nom org ',
43389      'et':' biz com edu gov info name net org ',
43390      'fj':' ac biz com info mil name net org pro ',
43391      'fk':' ac co gov net nom org ',
43392      'fr':' asso com f gouv nom prd presse tm ',
43393      'gg':' co net org ',
43394      'gh':' com edu gov mil org ',
43395      'gn':' ac com gov net org ',
43396      'gr':' com edu gov mil net org ',
43397      'gt':' com edu gob ind mil net org ',
43398      'gu':' com edu gov net org ',
43399      'hk':' com edu gov idv net org ',
43400      'hu':' 2000 agrar bolt casino city co erotica erotika film forum games hotel info ingatlan jogasz konyvelo lakas media news org priv reklam sex shop sport suli szex tm tozsde utazas video ',
43401      'id':' ac co go mil net or sch web ',
43402      'il':' ac co gov idf k12 muni net org ',
43403      'in':' ac co edu ernet firm gen gov i ind mil net nic org res ',
43404      'iq':' com edu gov i mil net org ',
43405      'ir':' ac co dnssec gov i id net org sch ',
43406      'it':' edu gov ',
43407      'je':' co net org ',
43408      'jo':' com edu gov mil name net org sch ',
43409      'jp':' ac ad co ed go gr lg ne or ',
43410      'ke':' ac co go info me mobi ne or sc ',
43411      'kh':' com edu gov mil net org per ',
43412      'ki':' biz com de edu gov info mob net org tel ',
43413      'km':' asso com coop edu gouv k medecin mil nom notaires pharmaciens presse tm veterinaire ',
43414      'kn':' edu gov net org ',
43415      'kr':' ac busan chungbuk chungnam co daegu daejeon es gangwon go gwangju gyeongbuk gyeonggi gyeongnam hs incheon jeju jeonbuk jeonnam k kg mil ms ne or pe re sc seoul ulsan ',
43416      'kw':' com edu gov net org ',
43417      'ky':' com edu gov net org ',
43418      'kz':' com edu gov mil net org ',
43419      'lb':' com edu gov net org ',
43420      'lk':' assn com edu gov grp hotel int ltd net ngo org sch soc web ',
43421      'lr':' com edu gov net org ',
43422      'lv':' asn com conf edu gov id mil net org ',
43423      'ly':' com edu gov id med net org plc sch ',
43424      'ma':' ac co gov m net org press ',
43425      'mc':' asso tm ',
43426      'me':' ac co edu gov its net org priv ',
43427      'mg':' com edu gov mil nom org prd tm ',
43428      'mk':' com edu gov inf name net org pro ',
43429      'ml':' com edu gov net org presse ',
43430      'mn':' edu gov org ',
43431      'mo':' com edu gov net org ',
43432      'mt':' com edu gov net org ',
43433      'mv':' aero biz com coop edu gov info int mil museum name net org pro ',
43434      'mw':' ac co com coop edu gov int museum net org ',
43435      'mx':' com edu gob net org ',
43436      'my':' com edu gov mil name net org sch ',
43437      'nf':' arts com firm info net other per rec store web ',
43438      'ng':' biz com edu gov mil mobi name net org sch ',
43439      'ni':' ac co com edu gob mil net nom org ',
43440      'np':' com edu gov mil net org ',
43441      'nr':' biz com edu gov info net org ',
43442      'om':' ac biz co com edu gov med mil museum net org pro sch ',
43443      'pe':' com edu gob mil net nom org sld ',
43444      'ph':' com edu gov i mil net ngo org ',
43445      'pk':' biz com edu fam gob gok gon gop gos gov net org web ',
43446      'pl':' art bialystok biz com edu gda gdansk gorzow gov info katowice krakow lodz lublin mil net ngo olsztyn org poznan pwr radom slupsk szczecin torun warszawa waw wroc wroclaw zgora ',
43447      'pr':' ac biz com edu est gov info isla name net org pro prof ',
43448      'ps':' com edu gov net org plo sec ',
43449      'pw':' belau co ed go ne or ',
43450      'ro':' arts com firm info nom nt org rec store tm www ',
43451      'rs':' ac co edu gov in org ',
43452      'sb':' com edu gov net org ',
43453      'sc':' com edu gov net org ',
43454      'sh':' co com edu gov net nom org ',
43455      'sl':' com edu gov net org ',
43456      'st':' co com consulado edu embaixada gov mil net org principe saotome store ',
43457      'sv':' com edu gob org red ',
43458      'sz':' ac co org ',
43459      'tr':' av bbs bel biz com dr edu gen gov info k12 name net org pol tel tsk tv web ',
43460      'tt':' aero biz cat co com coop edu gov info int jobs mil mobi museum name net org pro tel travel ',
43461      'tw':' club com ebiz edu game gov idv mil net org ',
43462      'mu':' ac co com gov net or org ',
43463      'mz':' ac co edu gov org ',
43464      'na':' co com ',
43465      'nz':' ac co cri geek gen govt health iwi maori mil net org parliament school ',
43466      'pa':' abo ac com edu gob ing med net nom org sld ',
43467      'pt':' com edu gov int net nome org publ ',
43468      'py':' com edu gov mil net org ',
43469      'qa':' com edu gov mil net org ',
43470      're':' asso com nom ',
43471      'ru':' ac adygeya altai amur arkhangelsk astrakhan bashkiria belgorod bir bryansk buryatia cbg chel chelyabinsk chita chukotka chuvashia com dagestan e-burg edu gov grozny int ir
43471kutsk ivanovo izhevsk jar joshkar-ola kalmykia kaluga kamchatka karelia kazan kchr kemerovo khabarovsk khakassia khv kirov koenig komi kostroma kranoyarsk kuban kurgan kursk lipetsk magadan mari mari-el marine mil mordovia mosreg msk murmansk nalchik net nnov nov novosibirsk nsk omsk orenburg org oryol penza perm pp pskov ptz rnd ryazan sakhalin samara saratov simbirsk smolensk spb stavropol stv surgut tambov tatarstan tom tomsk tsaritsyn tsk tula tuva tver tyumen udm udmurtia ulan-ude vladikavkaz vladimir vladivostok volgograd vologda voronezh vrn vyatka yakutia yamal yekaterinburg yuzhno-sakhalinsk ',
43472      'rw':' ac co com edu gouv gov int mil net ',
43473      'sa':' com edu gov med net org pub sch ',
43474      'sd':' com edu gov info med net org tv ',
43475      'se':' a ac b bd c d e f g h i k l m n o org p parti pp press r s t tm u w x y z ',
43476      'sg':' com edu gov idn net org per ',
43477      'sn':' art com edu gouv org perso univ ',
43478      'sy':' com edu gov mil net news org ',
43479      'th':' ac co go in mi net or ',
43480      'tj':' ac biz co com edu go gov info int mil name net nic org test web ',
43481      'tn':' agrinet com defense edunet ens fin gov ind info intl mincom nat net org perso rnrt rns rnu tourism ',
43482      'tz':' ac co go ne or ',
43483      'ua':' biz cherkassy chernigov chernovtsy ck cn co com crimea cv dn dnepropetrovsk donetsk dp edu gov if in ivano-frankivsk kh kharkov kherson khmelnitskiy kiev kirovograd km kr ks kv lg lugansk lutsk lviv me mk net nikolaev od odessa org pl poltava pp rovno rv sebastopol sumy te ternopil uzhgorod vinnica vn zaporizhzhe zhitomir zp zt ',
43484      'ug':' ac co go ne or org sc ',
43485      'uk':' ac bl british-library co cym gov govt icnet jet lea ltd me mil mod national-library-scotland nel net nhs nic nls org orgn parliament plc police sch scot soc ',
43486      'us':' dni fed isa kids nsn ',
43487      'uy':' com edu gub mil net org ',
43488      've':' co com edu gob info mil net org web ',
43489      'vi':' co com k12 net org ',
43490      'vn':' ac biz com edu gov health info int name net org pro ',
43491      'ye':' co com gov ltd me net org plc ',
43492      'yu':' ac co edu gov org ',
43493      'za':' ac agric alt bourse city co cybernet db edu gov grondar iaccess imt inca landesign law mil net ngo nis nom olivetti org pix school tm web ',
43494      'zm':' ac co com edu gov net org sch ',
43495      // https://en.wikipedia.org/wiki/CentralNic#Second-level_domains
43496      'com': 'ar br cn de eu gb gr hu jpn kr no qc ru sa se uk us uy za ',
43497      'net': 'gb jp se uk ',
43498      'org': 'ae',
43499      'de': 'com '
43500    },
43501    // gorhill 2013-10-25: Using indexOf() instead Regexp(). Significant boost
43502    // in both performance and memory footprint. No initialization required.
43503    // http://jsperf.com/uri-js-sld-regex-vs-binary-search/4
43504    // Following methods use lastIndexOf() rather than array.split() in order
43505    // to avoid any memory allocations.
43506    has: function(domain) {
43507      var tldOffset = domain.lastIndexOf('.');
43508      if (tldOffset <= 0 || tldOffset >= (domain.length-1)) {
43509        return false;
43510      }
43511      var sldOffset = domain.lastIndexOf('.', tldOffset-1);
43512      if (sldOffset <= 0 || sldOffset >= (tldOffset-1)) {
43513        return false;
43514      }
43515      var sldList = SLD.list[domain.slice(tldOffset+1)];
43516      if (!sldList) {
43517        return false;
43518      }
43519      return sldList.indexOf(' ' + domain.slice(sldOffset+1, tldOffset) + ' ') >= 0;
43520    },
43521    is: function(domain) {
43522      var tldOffset = domain.lastIndexOf('.');
43523      if (tldOffset <= 0 || tldOffset >= (domain.length-1)) {
43524        return false;
43525      }
43526      var sldOffset = domain.lastIndexOf('.', tldOffset-1);
43527      if (sldOffset >= 0) {
43528        return false;
43529      }
43530      var sldList = SLD.list[domain.slice(tldOffset+1)];
43531      if (!sldList) {
43532        return false;
43533      }
43534      return sldList.indexOf(' ' + domain.slice(0, tldOffset) + ' ') >= 0;
43535    },
43536    get: function(domain) {
43537      var tldOffset = domain.lastIndexOf('.');
43538      if (tldOffset <= 0 || tldOffset >= (domain.length-1)) {
43539        return null;
43540      }
43541      var sldOffset = domain.lastIndexOf('.', tldOffset-1);
43542      if (sldOffset <= 0 || sldOffset >= (tldOffset-1)) {
43543        return null;
43544      }
43545      var sldList = SLD.list[domain.slice(tldOffset+1)];
43546      if (!sldList) {
43547        return null;
43548      }
43549      if (sldList.indexOf(' ' + domain.slice(sldOffset+1, tldOffset) + ' ') < 0) {
43550        return null;
43551      }
43552      return domain.slice(sldOffset+1);
43553    },
43554    noConflict: function(){
43555      if (root.SecondLevelDomains === this) {
43556        root.SecondLevelDomains = _SecondLevelDomains;
43557      }
43558      return this;
43559    }
43560  };
43561
43562  return SLD;
43563}));
43564
43565},{}],145:[function(require,module,exports){
43566/*!
43567 * URI.js - Mutating URLs
43568 *
43569 * Version: 1.19.2
43570 *
43571 * Author: Rodney Rehm
43572 * Web: http://medialize.github.io/URI.js/
43573 *
43574 * Licensed under
43575 *   MIT License http://www.opensource.org/licenses/mit-license
43576 *
43577 */
43578(function (root, factory) {
43579  'use strict';
43580  // https://github.com/umdjs/umd/blob/master/returnExports.js
43581  if (typeof module === 'object' && module.exports) {
43582    // Node
43583    module.exports = factory(require('./punycode'), require('./IPv6'), require('./SecondLevelDomains'));
43584  } else if (typeof define === 'function' && define.amd) {
43585    // AMD. Register as an anonymous module.
43586    define(['./punycode', './IPv6', './SecondLevelDomains'], factory);
43587  } else {
43588    // Browser globals (root is window)
43589    root.URI = factory(root.punycode, root.IPv6, root.SecondLevelDomains, root);
43590  }
43591}(this, function (punycode, IPv6, SLD, root) {
43592  'use strict';
43593  /*global location, escape, unescape */
43594  // FIXME: v2.0.0 renamce non-camelCase properties to uppercase
43595  /*jshint camelcase: false */
43596
43597  // save current URI variable, if any
43598  var _URI = root && root.URI;
43599
43600  function URI(url, base) {
43601    var _urlSupplied = arguments.length >= 1;
43602    var _baseSupplied = arguments.length >= 2;
43603
43604    // Allow instantiation without the 'new' keyword
43605    if (!(this instanceof URI)) {
43606      if (_urlSupplied) {
43607        if (_baseSupplied) {
43608          return new URI(url, base);
43609        }
43610
43611        return new URI(url);
43612      }
43613
43614      return new URI();
43615    }
43616
43617    if (url === undefined) {
43618      if (_urlSupplied) {
43619        throw new TypeError('undefined is not a valid argument for URI');
43620      }
43621
43622      if (typeof location !== 'undefined') {
43623        url = location.href + '';
43624      } else {
43625        url = '';
43626      }
43627    }
43628
43629    if (url === null) {
43630      if (_urlSupplied) {
43631        throw new TypeError('null is not a valid argument for URI');
43632      }
43633    }
43634
43635    this.href(url);
43636
43637    // resolve to base according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor
43638    if (base !== undefined) {
43639      return this.absoluteTo(base);
43640    }
43641
43642    return this;
43643  }
43644
43645  function isInteger(value) {
43646    return /^[0-9]+$/.test(value);
43647  }
43648
43649  URI.version = '1.19.2';
43650
43651  var p = URI.prototype;
43652  var hasOwn = Object.prototype.hasOwnProperty;
43653
43654  function escapeRegEx(string) {
43655    // https://github.com/medialize/URI.js/commit/85ac21783c11f8ccab06106dba9735a31a86924d#commitcomment-821963
43656    return string.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
43657  }
43658
43659  function getType(value) {
43660    // IE8 doesn't return [Object Undefined] but [Object Object] for undefined value
43661    if (value === undefined) {
43662      return 'Undefined';
43663    }
43664
43665    return String(Object.prototype.toString.call(value)).slice(8, -1);
43666  }
43667
43668  function isArray(obj) {
43669    return getType(obj) === 'Array';
43670  }
43671
43672  function filterArrayValues(data, value) {
43673    var lookup = {};
43674    var i, length;
43675
43676    if (getType(value) === 'RegExp') {
43677      lookup = null;
43678    } else if (isArray(value)) {
43679      for (i = 0, length = value.length; i < length; i++) {
43680        lookup[value[i]] = true;
43681      }
43682    } else {
43683      lookup[value] = true;
43684    }
43685
43686    for (i = 0, length = data.length; i < length; i++) {
43687      /*jshint laxbreak: true */
43688      var _match = lookup && lookup[data[i]] !== undefined
43689        || !lookup && value.test(data[i]);
43690      /*jshint laxbreak: false */
43691      if (_match) {
43692        data.splice(i, 1);
43693        length--;
43694        i--;
43695      }
43696    }
43697
43698    return data;
43699  }
43700
43701  function arrayContains(list, value) {
43702    var i, length;
43703
43704    // value may be string, number, array, regexp
43705    if (isArray(value)) {
43706      // Note: this can be optimized to O(n) (instead of current O(m * n))
43707      for (i = 0, length = value.length; i < length; i++) {
43708        if (!arrayContains(list, value[i])) {
43709          return false;
43710        }
43711      }
43712
43713      return true;
43714    }
43715
43716    var _type = getType(value);
43717    for (i = 0, length = list.length; i < length; i++) {
43718      if (_type === 'RegExp') {
43719        if (typeof list[i] === 'string' && list[i].match(value)) {
43720          return true;
43721        }
43722      } else if (list[i] === value) {
43723        return true;
43724      }
43725    }
43726
43727    return false;
43728  }
43729
43730  function arraysEqual(one, two) {
43731    if (!isArray(one) || !isArray(two)) {
43732      return false;
43733    }
43734
43735    // arrays can't be equal if they have different amount of content
43736    if (one.length !== two.length) {
43737      return false;
43738    }
43739
43740    one.sort();
43741    two.sort();
43742
43743    for (var i = 0, l = one.length; i < l; i++) {
43744      if (one[i] !== two[i]) {
43745        return false;
43746      }
43747    }
43748
43749    return true;
43750  }
43751
43752  function trimSlashes(text) {
43753    var trim_expression = /^\/+|\/+$/g;
43754    return text.replace(trim_expression, '');
43755  }
43756
43757  URI._parts = function() {
43758    return {
43759      protocol: null,
43760      username: null,
43761      password: null,
43762      hostname: null,
43763      urn: null,
43764      port: null,
43765      path: null,
43766      query: null,
43767      fragment: null,
43768      // state
43769      preventInvalidHostname: URI.preventInvalidHostname,
43770      duplicateQueryParameters: URI.duplicateQueryParameters,
43771      escapeQuerySpace: URI.escapeQuerySpace
43772    };
43773  };
43774  // state: throw on invalid hostname
43775  // see https://github.com/medialize/URI.js/pull/345
43776  // and https://github.com/medialize/URI.js/issues/354
43777  URI.preventInvalidHostname = false;
43778  // state: allow duplicate query parameters (a=1&a=1)
43779  URI.duplicateQueryParameters = false;
43780  // state: replaces + with %20 (space in query strings)
43781  URI.escapeQuerySpace = true;
43782  // static properties
43783  URI.protocol_expression = /^[a-z][a-z0-9.+-]*$/i;
43784  URI.idn_expression = /[^a-z0-9\._-]/i;
43785  URI.punycode_expression = /(xn--)/i;
43786  // well, 333.444.555.666 matches, but it sure ain't no IPv4 - do we care?
43787  URI.ip4_expression = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
43788  // credits to Rich Brown
43789  // source: http://forums.intermapper.com/viewtopic.php?p=1096#1096
43790  // specification: http://www.ietf.org/rfc/rfc4291.txt
43791  URI.ip6_expression = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/;
43792  // expression used is "gruber revised" (@gruber v2) determined to be the
43793  // best solution in a regex-golf we did a couple of ages ago at
43794  // * http://mathiasbynens.be/demo/url-regex
43795  // * http://rodneyrehm.de/t/url-regex.html
43796  URI.find_uri_expression = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig;
43797  URI.findUri = {
43798    // valid "scheme://" or "www."
43799    start: /\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,
43800    // everything up to the next whitespace
43801    end: /[\s\r\n]|$/,
43802    // trim trailing punctuation captured by end RegExp
43803    trim: /[`!()\[\]{};:'".,<>?«»“”„‘’]+$/,
43804    // balanced parens inclusion (), [], {}, <>
43805    parens: /(\([^\)]*\)|\[[^\]]*\]|\{[^}]*\}|<[^>]*>)/g,
43806  };
43807  // http://www.iana.org/assignments/uri-schemes.html
43808  // http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports
43809  URI.defaultPorts = {
43810    http: '80',
43811    https: '443',
43812    ftp: '21',
43813    gopher: '70',
43814    ws: '80',
43815    wss: '443'
43816  };
43817  // list of protocols which always require a hostname
43818  URI.hostProtocols = [
43819    'http',
43820    'https'
43821  ];
43822
43823  // allowed hostname characters according to RFC 3986
43824  // ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded
43825  // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . - _
43826  URI.invalid_hostname_characters = /[^a-zA-Z0-9\.\-:_]/;
43827  // map DOM Elements to their URI attribute
43828  URI.domAttributes = {
43829    'a': 'href',
43830    'blockquote': 'cite',
43831    'link': 'href',
43832    'base': 'href',
43833    'script': 'src',
43834    'form': 'action',
43835    'img': 'src',
43836    'area': 'href',
43837    'iframe': 'src',
43838    'embed': 'src',
43839    'source': 'src',
43840    'track': 'src',
43841    'input': 'src', // but only if type="image"
43842    'audio': 'src',
43843    'video': 'src'
43844  };
43845  URI.getDomAttribute = function(node) {
43846    if (!node || !node.nodeName) {
43847      return undefined;
43848    }
43849
43850    var nodeName = node.nodeName.toLowerCase();
43851    // <input> should only expose src for type="image"
43852    if (nodeName === 'input' && node.type !== 'image') {
43853      return undefined;
43854    }
43855
43856    return URI.domAttributes[nodeName];
43857  };
43858
43859  function escapeForDumbFirefox36(value) {
43860    // https://github.com/medialize/URI.js/issues/91
43861    return escape(value);
43862  }
43863
43864  // encoding / decoding according to RFC3986
43865  function strictEncodeURIComponent(string) {
43866    // see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent
43867    return encodeURIComponent(string)
43868      .replace(/[!'()*]/g, escapeForDumbFirefox36)
43869      .replace(/\*/g, '%2A');
43870  }
43871  URI.encode = strictEncodeURIComponent;
43872  URI.decode = decodeURIComponent;
43873  URI.iso8859 = function() {
43874    URI.encode = escape;
43875    URI.decode = unescape;
43876  };
43877  URI.unicode = function() {
43878    URI.encode = strictEncodeURIComponent;
43879    URI.decode = decodeURIComponent;
43880  };
43881  URI.characters = {
43882    pathname: {
43883      encode: {
43884        // RFC3986 2.1: For consistency, URI producers and normalizers should
43885        // use uppercase hexadecimal digits for all percent-encodings.
43886        expression: /%(24|26|2B|2C|3B|3D|3A|40)/ig,
43887        map: {
43888          // -._~!'()*
43889          '%24': '$',
43890          '%26': '&',
43891          '%2B': '+',
43892          '%2C': ',',
43893          '%3B': ';',
43894          '%3D': '=',
43895          '%3A': ':',
43896          '%40': '@'
43897        }
43898      },
43899      decode: {
43900        expression: /[\/\?#]/g,
43901        map: {
43902          '/': '%2F',
43903          '?': '%3F',
43904          '#': '%23'
43905        }
43906      }
43907    },
43908    reserved: {
43909      encode: {
43910        // RFC3986 2.1: For consistency, URI producers and normalizers should
43911        // use uppercase hexadecimal digits for all percent-encodings.
43912        expression: /%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig,
43913        map: {
43914          // gen-delims
43915          '%3A': ':',
43916          '%2F': '/',
43917          '%3F': '?',
43918          '%23': '#',
43919          '%5B': '[',
43920          '%5D': ']',
43921          '%40': '@',
43922          // sub-delims
43923          '%21': '!',
43924          '%24': '$',
43925          '%26': '&',
43926          '%27': '\'',
43927          '%28': '(',
43928          '%29': ')',
43929          '%2A': '*',
43930          '%2B': '+',
43931          '%2C': ',',
43932          '%3B': ';',
43933          '%3D': '='
43934        }
43935      }
43936    },
43937    urnpath: {
43938      // The characters under `encode` are the characters called out by RFC 2141 as being acceptable
43939      // for usage in a URN. RFC2141 also calls out "-", ".", and "_" as acceptable characters, but
43940      // these aren't encoded by encodeURIComponent, so we don't have to call them out here. Also
43941      // note that the colon character is not featured in the encoding map; this is because URI.js
43942      // gives the colons in URNs semantic meaning as the delimiters of path segements, and so it
43943      // should not appear unencoded in a segment itself.
43944      // See also the note above about RFC3986 and capitalalized hex digits.
43945      encode: {
43946        expression: /%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/ig,
43947        map: {
43948          '%21': '!',
43949          '%24': '$',
43950          '%27': '\'',
43951          '%28': '(',
43952          '%29': ')',
43953          '%2A': '*',
43954          '%2B': '+',
43955          '%2C': ',',
43956          '%3B': ';',
43957          '%3D': '=',
43958          '%40': '@'
43959        }
43960      },
43961      // These characters are the characters called out by RFC2141 as "reserved" characters that
43962      // should never appear in a URN, plus the colon character (see note above).
43963      decode: {
43964        expression: /[\/\?#:]/g,
43965        map: {
43966          '/': '%2F',
43967          '?': '%3F',
43968          '#': '%23',
43969          ':': '%3A'
43970        }
43971      }
43972    }
43973  };
43974  URI.encodeQuery = function(string, escapeQuerySpace) {
43975    var escaped = URI.encode(string + '');
43976    if (escapeQuerySpace === undefined) {
43977      escapeQuerySpace = URI.escapeQuerySpace;
43978    }
43979
43980    return escapeQuerySpace ? escaped.replace(/%20/g, '+') : escaped;
43981  };
43982  URI.decodeQuery = function(string, escapeQuerySpace) {
43983    string += '';
43984    if (escapeQuerySpace === undefined) {
43985      escapeQuerySpace = URI.escapeQuerySpace;
43986    }
43987
43988    try {
43989      return URI.decode(escapeQuerySpace ? string.replace(/\+/g, '%20') : string);
43990    } catch(e) {
43991      // we're not going to mess with weird encodings,
43992      // give up and return the undecoded original string
43993      // see https://github.com/medialize/URI.js/issues/87
43994      // see https://github.com/medialize/URI.js/issues/92
43995      return string;
43996    }
43997  };
43998  // generate encode/decode path functions
43999  var _parts = {'encode':'encode', 'decode':'decode'};
44000  var _part;
44001  var generateAccessor = function(_group, _part) {
44002    return function(string) {
44003      try {
44004        return URI[_part](string + '').replace(URI.characters[_group][_part].expression, function(c) {
44005          return URI.characters[_group][_part].map[c];
44006        });
44007      } catch (e) {
44008        // we're not going to mess with weird encodings,
44009        // give up and return the undecoded original string
44010        // see https://github.com/medialize/URI.js/issues/87
44011        // see https://github.com/medialize/URI.js/issues/92
44012        return string;
44013      }
44014    };
44015  };
44016
44017  for (_part in _parts) {
44018    URI[_part + 'PathSegment'] = generateAccessor('pathname', _parts[_part]);
44019    URI[_part + 'UrnPathSegment'] = generateAccessor('urnpath', _parts[_part]);
44020  }
44021
44022  var generateSegmentedPathFunction = function(_sep, _codingFuncName, _innerCodingFuncName) {
44023    return function(string) {
44024      // Why pass in names of functions, rather than the function objects themselves? The
44025      // definitions of some functions (but in particular, URI.decode) will occasionally change due
44026      // to URI.js having ISO8859 and Unicode modes. Passing in the name and getting it will ensure
44027      // that the functions we use here are "fresh".
44028      var actualCodingFunc;
44029      if (!_innerCodingFuncName) {
44030        actualCodingFunc = URI[_codingFuncName];
44031      } else {
44032        actualCodingFunc = function(string) {
44033          return URI[_codingFuncName](URI[_innerCodingFuncName](string));
44034        };
44035      }
44036
44037      var segments = (string + '').split(_sep);
44038
44039      for (var i = 0, length = segments.length; i < length; i++) {
44040        segments[i] = actualCodingFunc(segments[i]);
44041      }
44042
44043      return segments.join(_sep);
44044    };
44045  };
44046
44047  // This takes place outside the above loop because we don't want, e.g., encodeUrnPath functions.
44048  URI.decodePath = generateSegmentedPathFunction('/', 'decodePathSegment');
44049  URI.decodeUrnPath = generateSegmentedPathFunction(':', 'decodeUrnPathSegment');
44050  URI.recodePath = generateSegmentedPathFunction('/', 'encodePathSegment', 'decode');
44051  URI.recodeUrnPath = generateSegmentedPathFunction(':', 'encodeUrnPathSegment', 'decode');
44052
44053  URI.encodeReserved = generateAccessor('reserved', 'encode');
44054
44055  URI.parse = function(string, parts) {
44056    var pos;
44057    if (!parts) {
44058      parts = {
44059        preventInvalidHostname: URI.preventInvalidHostname
44060      };
44061    }
44062    // [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment]
44063
44064    // extract fragment
44065    pos = string.indexOf('#');
44066    if (pos > -1) {
44067      // escaping?
44068      parts.fragment = string.substring(pos + 1) || null;
44069      string = string.substring(0, pos);
44070    }
44071
44072    // extract query
44073    pos = string.indexOf('?');
44074    if (pos > -1) {
44075      // escaping?
44076      parts.query = string.substring(pos + 1) || null;
44077      string = string.substring(0, pos);
44078    }
44079
44080    // extract protocol
44081    if (string.substring(0, 2) === '//') {
44082      // relative-scheme
44083      parts.protocol = null;
44084      string = string.substring(2);
44085      // extract "user:pass@host:port"
44086      string = URI.parseAuthority(string, parts);
44087    } else {
44088      pos = string.indexOf(':');
44089      if (pos > -1) {
44090        parts.protocol = string.substring(0, pos) || null;
44091        if (parts.protocol && !parts.protocol.match(URI.protocol_expression)) {
44092          // : may be within the path
44093          parts.protocol = undefined;
44094        } else if (string.substring(pos + 1, pos + 3) === '//') {
44095          string = string.substring(pos + 3);
44096
44097          // extract "user:pass@host:port"
44098          string = URI.parseAuthority(string, parts);
44099        } else {
44100          string = string.substring(pos + 1);
44101          parts.urn = true;
44102        }
44103      }
44104    }
44105
44106    // what's left must be the path
44107    parts.path = string;
44108
44109    // and we're done
44110    return parts;
44111  };
44112  URI.parseHost = function(string, parts) {
44113    if (!string) {
44114      string = '';
44115    }
44116
44117    // Copy chrome, IE, opera backslash-handling behavior.
44118    // Back slashes before the query string get converted to forward slashes
44119    // See: https://github.com/joyent/node/blob/386fd24f49b0e9d1a8a076592a404168faeecc34/lib/url.js#L115-L124
44120    // See: https://code.google.com/p/chromium/issues/detail?id=25916
44121    // https://github.com/medialize/URI.js/pull/233
44122    string = string.replace(/\\/g, '/');
44123
44124    // extract host:port
44125    var pos = string.indexOf('/');
44126    var bracketPos;
44127    var t;
44128
44129    if (pos === -1) {
44130      pos = string.length;
44131    }
44132
44133    if (string.charAt(0) === '[') {
44134      // IPv6 host - http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-04#section-6
44135      // I claim most client software breaks on IPv6 anyways. To simplify things, URI only accepts
44136      // IPv6+port in the format [2001:db8::1]:80 (for the time being)
44137      bracketPos = string.indexOf(']');
44138      parts.hostname = string.substring(1, bracketPos) || null;
44139      parts.port = string.substring(bracketPos + 2, pos) || null;
44140      if (parts.port === '/') {
44141        parts.port = null;
44142      }
44143    } else {
44144      var firstColon = string.indexOf(':');
44145      var firstSlash = string.indexOf('/');
44146      var nextColon = string.indexOf(':', firstColon + 1);
44147      if (nextColon !== -1 && (firstSlash === -1 || nextColon < firstSlash)) {
44148        // IPv6 host contains multiple colons - but no port
44149        // this notation is actually not allowed by RFC 3986, but we're a liberal parser
44150        parts.hostname = string.substring(0, pos) || null;
44151        parts.port = null;
44152      } else {
44153        t = string.substring(0, pos).split(':');
44154        parts.hostname = t[0] || null;
44155        parts.port = t[1] || null;
44156      }
44157    }
44158
44159    if (parts.hostname && string.substring(pos).charAt(0) !== '/') {
44160      pos++;
44161      string = '/' + string;
44162    }
44163
44164    if (parts.preventInvalidHostname) {
44165      URI.ensureValidHostname(parts.hostname, parts.protocol);
44166    }
44167
44168    if (parts.port) {
44169      URI.ensureValidPort(parts.port);
44170    }
44171
44172    return string.substring(pos) || '/';
44173  };
44174  URI.parseAuthority = function(string, parts) {
44175    string = URI.parseUserinfo(string, parts);
44176    return URI.parseHost(string, parts);
44177  };
44178  URI.parseUserinfo = function(string, parts) {
44179    // extract username:password
44180    var firstSlash = string.indexOf('/');
44181    var pos = string.lastIndexOf('@', firstSlash > -1 ? firstSlash : string.length - 1);
44182    var t;
44183
44184    // authority@ must come before /path
44185    if (pos > -1 && (firstSlash === -1 || pos < firstSlash)) {
44186      t = string.substring(0, pos).split(':');
44187      parts.username = t[0] ? URI.decode(t[0]) : null;
44188      t.shift();
44189      parts.password = t[0] ? URI.decode(t.join(':')) : null;
44190      string = string.substring(pos + 1);
44191    } else {
44192      parts.username = null;
44193      parts.password = null;
44194    }
44195
44196    return string;
44197  };
44198  URI.parseQuery = function(string, escapeQuerySpace) {
44199    if (!string) {
44200      return {};
44201    }
44202
44203    // throw out the funky business - "?"[name"="value"&"]+
44204    string = string.replace(/&+/g, '&').replace(/^\?*&*|&+$/g, '');
44205
44206    if (!string) {
44207      return {};
44208    }
44209
44210    var items = {};
44211    var splits = string.split('&');
44212    var length = splits.length;
44213    var v, name, value;
44214
44215    for (var i = 0; i < length; i++) {
44216      v = splits[i].split('=');
44217      name = URI.decodeQuery(v.shift(), escapeQuerySpace);
44218      // no "=" is null according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters
44219      value = v.length ? URI.decodeQuery(v.join('='), escapeQuerySpace) : null;
44220
44221      if (hasOwn.call(items, name)) {
44222        if (typeof items[name] === 'string' || items[name] === null) {
44223          items[name] = [items[name]];
44224        }
44225
44226        items[name].push(value);
44227      } else {
44228        items[name] = value;
44229      }
44230    }
44231
44232    return items;
44233  };
44234
44235  URI.build = function(parts) {
44236    var t = '';
44237    var requireAbsolutePath = false
44238
44239    if (parts.protocol) {
44240      t += parts.protocol + ':';
44241    }
44242
44243    if (!parts.urn && (t || parts.hostname)) {
44244      t += '//';
44245      requireAbsolutePath = true
44246    }
44247
44248    t += (URI.buildAuthority(parts) || '');
44249
44250    if (typeof parts.path === 'string') {
44251      if (parts.path.charAt(0) !== '/' && requireAbsolutePath) {
44252        t += '/';
44253      }
44254
44255      t += parts.path;
44256    }
44257
44258    if (typeof parts.query === 'string' && parts.query) {
44259      t += '?' + parts.query;
44260    }
44261
44262    if (typeof parts.fragment === 'string' && parts.fragment) {
44263      t += '#' + parts.fragment;
44264    }
44265    return t;
44266  };
44267  URI.buildHost = function(parts) {
44268    var t = '';
44269
44270    if (!parts.hostname) {
44271      return '';
44272    } else if (URI.ip6_expression.test(parts.hostname)) {
44273      t += '[' + parts.hostname + ']';
44274    } else {
44275      t += parts.hostname;
44276    }
44277
44278    if (parts.port) {
44279      t += ':' + parts.port;
44280    }
44281
44282    return t;
44283  };
44284  URI.buildAuthority = function(parts) {
44285    return URI.buildUserinfo(parts) + URI.buildHost(parts);
44286  };
44287  URI.buildUserinfo = function(parts) {
44288    var t = '';
44289
44290    if (parts.username) {
44291      t += URI.encode(parts.username);
44292    }
44293
44294    if (parts.password) {
44295      t += ':' + URI.encode(parts.password);
44296    }
44297
44298    if (t) {
44299      t += '@';
44300    }
44301
44302    return t;
44303  };
44304  URI.buildQuery = function(data, duplicateQueryParameters, escapeQuerySpace) {
44305    // according to http://tools.ietf.org/html/rfc3986 or http://labs.apache.org/webarch/uri/rfc/rfc3986.html
44306    // being »-._~!$&'()*+,;=:@/?« %HEX and alnum are allowed
44307    // the RFC explicitly states ?/foo being a valid use case, no mention of parameter syntax!
44308    // URI.js treats the query string as being application/x-www-form-urlencoded
44309    // see http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type
44310
44311    var t = '';
44312    var unique, key, i, length;
44313    for (key in data) {
44314      if (hasOwn.call(data, key)) {
44315        if (isArray(data[key])) {
44316          unique = {};
44317          for (i = 0, length = data[key].length; i < length; i++) {
44318            if (data[key][i] !== undefined && unique[data[key][i] + ''] === undefined) {
44319              t += '&' + URI.buildQueryParameter(key, data[key][i], escapeQuerySpace);
44320              if (duplicateQueryParameters !== true) {
44321                unique[data[key][i] + ''] = true;
44322              }
44323            }
44324          }
44325        } else if (data[key] !== undefined) {
44326          t += '&' + URI.buildQueryParameter(key, data[key], escapeQuerySpace);
44327        }
44328      }
44329    }
44330
44331    return t.substring(1);
44332  };
44333  URI.buildQueryParameter = function(name, value, escapeQuerySpace) {
44334    // http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type -- application/x-www-form-urlencoded
44335    // don't append "=" for null values, according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#url-parameter-serialization
44336    return URI.encodeQuery(name, escapeQuerySpace) + (value !== null ? '=' + URI.encodeQuery(value, escapeQuerySpace) : '');
44337  };
44338
44339  URI.addQuery = function(data, name, value) {
44340    if (typeof name === 'object') {
44341      for (var key in name) {
44342        if (hasOwn.call(name, key)) {
44343          URI.addQuery(data, key, name[key]);
44344        }
44345      }
44346    } else if (typeof name === 'string') {
44347      if (data[name] === undefined) {
44348        data[name] = value;
44349        return;
44350      } else if (typeof data[name] === 'string') {
44351        data[name] = [data[name]];
44352      }
44353
44354      if (!isArray(value)) {
44355        value = [value];
44356      }
44357
44358      data[name] = (data[name] || []).concat(value);
44359    } else {
44360      throw new TypeError('URI.addQuery() accepts an object, string as the name parameter');
44361    }
44362  };
44363
44364  URI.setQuery = function(data, name, value) {
44365    if (typeof name === 'object') {
44366      for (var key in name) {
44367        if (hasOwn.call(name, key)) {
44368          URI.setQuery(data, key, name[key]);
44369        }
44370      }
44371    } else if (typeof name === 'string') {
44372      data[name] = value === undefined ? null : value;
44373    } else {
44374      throw new TypeError('URI.setQuery() accepts an object, string as the name parameter');
44375    }
44376  };
44377
44378  URI.removeQuery = function(data, name, value) {
44379    var i, length, key;
44380
44381    if (isArray(name)) {
44382      for (i = 0, length = name.length; i < length; i++) {
44383        data[name[i]] = undefined;
44384      }
44385    } else if (getType(name) === 'RegExp') {
44386      for (key in data) {
44387        if (name.test(key)) {
44388          data[key] = undefined;
44389        }
44390      }
44391    } else if (typeof name === 'object') {
44392      for (key in name) {
44393        if (hasOwn.call(name, key)) {
44394          URI.removeQuery(data, key, name[key]);
44395        }
44396      }
44397    } else if (typeof name === 'string') {
44398      if (value !== undefined) {
44399        if (getType(value) === 'RegExp') {
44400          if (!isArray(data[name]) && value.test(data[name])) {
44401            data[name] = undefined;
44402          } else {
44403            data[name] = filterArrayValues(data[name], value);
44404          }
44405        } else if (data[name] === String(value) && (!isArray(value) || value.length === 1)) {
44406          data[name] = undefined;
44407        } else if (isArray(data[name])) {
44408          data[name] = filterArrayValues(data[name], value);
44409        }
44410      } else {
44411        data[name] = undefined;
44412      }
44413    } else {
44414      throw new TypeError('URI.removeQuery() accepts an object, string, RegExp as the first parameter');
44415    }
44416  };
44417  URI.hasQuery = function(data, name, value, withinArray) {
44418    switch (getType(name)) {
44419      case 'String':
44420        // Nothing to do here
44421        break;
44422
44423      case 'RegExp':
44424        for (var key in data) {
44425          if (hasOwn.call(data, key)) {
44426            if (name.test(key) && (value === undefined || URI.hasQuery(data, key, value))) {
44427              return true;
44428            }
44429          }
44430        }
44431
44432        return false;
44433
44434      case 'Object':
44435        for (var _key in name) {
44436          if (hasOwn.call(name, _key)) {
44437            if (!URI.hasQuery(data, _key, name[_key])) {
44438              return false;
44439            }
44440          }
44441        }
44442
44443        return true;
44444
44445      default:
44446        throw new TypeError('URI.hasQuery() accepts a string, regular expression or object as the name parameter');
44447    }
44448
44449    switch (getType(value)) {
44450      case 'Undefined':
44451        // true if exists (but may be empty)
44452        return name in data; // data[name] !== undefined;
44453
44454      case 'Boolean':
44455        // true if exists and non-empty
44456        var _booly = Boolean(isArray(data[name]) ? data[name].length : data[name]);
44457        return value === _booly;
44458
44459      case 'Function':
44460        // allow complex comparison
44461        return !!value(data[name], name, data);
44462
44463      case 'Array':
44464        if (!isArray(data[name])) {
44465          return false;
44466        }
44467
44468        var op = withinArray ? arrayContains : arraysEqual;
44469        return op(data[name], value);
44470
44471      case 'RegExp':
44472        if (!isArray(data[name])) {
44473          return Boolean(data[name] && data[name].match(value));
44474        }
44475
44476        if (!withinArray) {
44477          return false;
44478        }
44479
44480        return arrayContains(data[name], value);
44481
44482      case 'Number':
44483        value = String(value);
44484        /* falls through */
44485      case 'String':
44486        if (!isArray(data[name])) {
44487          return data[name] === value;
44488        }
44489
44490        if (!withinArray) {
44491          return false;
44492        }
44493
44494        return arrayContains(data[name], value);
44495
44496      default:
44497        throw new TypeError('URI.hasQuery() accepts undefined, boolean, string, number, RegExp, Function as the value parameter');
44498    }
44499  };
44500
44501
44502  URI.joinPaths = function() {
44503    var input = [];
44504    var segments = [];
44505    var nonEmptySegments = 0;
44506
44507    for (var i = 0; i < arguments.length; i++) {
44508      var url = new URI(arguments[i]);
44509      input.push(url);
44510      var _segments = url.segment();
44511      for (var s = 0; s < _segments.length; s++) {
44512        if (typeof _segments[s] === 'string') {
44513          segments.push(_segments[s]);
44514        }
44515
44516        if (_segments[s]) {
44517          nonEmptySegments++;
44518        }
44519      }
44520    }
44521
44522    if (!segments.length || !nonEmptySegments) {
44523      return new URI('');
44524    }
44525
44526    var uri = new URI('').segment(segments);
44527
44528    if (input[0].path() === '' || input[0].path().slice(0, 1) === '/') {
44529      uri.path('/' + uri.path());
44530    }
44531
44532    return uri.normalize();
44533  };
44534
44535  URI.commonPath = function(one, two) {
44536    var length = Math.min(one.length, two.length);
44537    var pos;
44538
44539    // find first non-matching character
44540    for (pos = 0; pos < length; pos++) {
44541      if (one.charAt(pos) !== two.charAt(pos)) {
44542        pos--;
44543        break;
44544      }
44545    }
44546
44547    if (pos < 1) {
44548      return one.charAt(0) === two.charAt(0) && one.charAt(0) === '/' ? '/' : '';
44549    }
44550
44551    // revert to last /
44552    if (one.charAt(pos) !== '/' || two.charAt(pos) !== '/') {
44553      pos = one.substring(0, pos).lastIndexOf('/');
44554    }
44555
44556    return one.substring(0, pos + 1);
44557  };
44558
44559  URI.withinString = function(string, callback, options) {
44560    options || (options = {});
44561    var _start = options.start || URI.findUri.start;
44562    var _end = options.end || URI.findUri.end;
44563    var _trim = options.trim || URI.findUri.trim;
44564    var _parens = options.parens || URI.findUri.parens;
44565    var _attributeOpen = /[a-z0-9-]=["']?$/i;
44566
44567    _start.lastIndex = 0;
44568    while (true) {
44569      var match = _start.exec(string);
44570      if (!match) {
44571        break;
44572      }
44573
44574      var start = match.index;
44575      if (options.ignoreHtml) {
44576        // attribut(e=["']?$)
44577        var attributeOpen = string.slice(Math.max(start - 3, 0), start);
44578        if (attributeOpen && _attributeOpen.test(attributeOpen)) {
44579          continue;
44580        }
44581      }
44582
44583      var end = start + string.slice(start).search(_end);
44584      var slice = string.slice(start, end);
44585      // make sure we include well balanced parens
44586      var parensEnd = -1;
44587      while (true) {
44588        var parensMatch = _parens.exec(slice);
44589        if (!parensMatch) {
44590          break;
44591        }
44592
44593        var parensMatchEnd = parensMatch.index + parensMatch[0].length;
44594        parensEnd = Math.max(parensEnd, parensMatchEnd);
44595      }
44596
44597      if (parensEnd > -1) {
44598        slice = slice.slice(0, parensEnd) + slice.slice(parensEnd).replace(_trim, '');
44599      } else {
44600        slice = slice.replace(_trim, '');
44601      }
44602
44603      if (slice.length <= match[0].length) {
44604        // the extract only contains the starting marker of a URI,
44605        // e.g. "www" or "http://"
44606        continue;
44607      }
44608
44609      if (options.ignore && options.ignore.test(slice)) {
44610        continue;
44611      }
44612
44613      end = start + slice.length;
44614      var result = callback(slice, start, end, string);
44615      if (result === undefined) {
44616        _start.lastIndex = end;
44617        continue;
44618      }
44619
44620      result = String(result);
44621      string = string.slice(0, start) + result + string.slice(end);
44622      _start.lastIndex = start + result.length;
44623    }
44624
44625    _start.lastIndex = 0;
44626    return string;
44627  };
44628
44629  URI.ensureValidHostname = function(v, protocol) {
44630    // Theoretically URIs allow percent-encoding in Hostnames (according to RFC 3986)
44631    // they are not part of DNS and therefore ignored by URI.js
44632
44633    var hasHostname = !!v; // not null and not an empty string
44634    var hasProtocol = !!protocol;
44635    var rejectEmptyHostname = false;
44636
44637    if (hasProtocol) {
44638      rejectEmptyHostname = arrayContains(URI.hostProtocols, protocol);
44639    }
44640
44641    if (rejectEmptyHostname && !hasHostname) {
44642      throw new TypeError('Hostname cannot be empty, if protocol is ' + protocol);
44643    } else if (v && v.match(URI.invalid_hostname_characters)) {
44644      // test punycode
44645      if (!punycode) {
44646        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_] and Punycode.js is not available');
44647      }
44648      if (punycode.toASCII(v).match(URI.invalid_hostname_characters)) {
44649        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-:_]');
44650      }
44651    }
44652  };
44653
44654  URI.ensureValidPort = function (v) {
44655    if (!v) {
44656      return;
44657    }
44658
44659    var port = Number(v);
44660    if (isInteger(port) && (port > 0) && (port < 65536)) {
44661      return;
44662    }
44663
44664    throw new TypeError('Port "' + v + '" is not a valid port');
44665  };
44666
44667  // noConflict
44668  URI.noConflict = function(removeAll) {
44669    if (removeAll) {
44670      var unconflicted = {
44671        URI: this.noConflict()
44672      };
44673
44674      if (root.URITemplate && typeof root.URITemplate.noConflict === 'function') {
44675        unconflicted.URITemplate = root.URITemplate.noConflict();
44676      }
44677
44678      if (root.IPv6 && typeof root.IPv6.noConflict === 'function') {
44679        unconflicted.IPv6 = root.IPv6.noConflict();
44680      }
44681
44682      if (root.SecondLevelDomains && typeof root.SecondLevelDomains.noConflict === 'function') {
44683        unconflicted.SecondLevelDomains = root.SecondLevelDomains.noConflict();
44684      }
44685
44686      return unconflicted;
44687    } else if (root.URI === this) {
44688      root.URI = _URI;
44689    }
44690
44691    return this;
44692  };
44693
44694  p.build = function(deferBuild) {
44695    if (deferBuild === true) {
44696      this._deferred_build = true;
44697    } else if (deferBuild === undefined || this._deferred_build) {
44698      this._string = URI.build(this._parts);
44699      this._deferred_build = false;
44700    }
44701
44702    return this;
44703  };
44704
44705  p.clone = function() {
44706    return new URI(this);
44707  };
44708
44709  p.valueOf = p.toString = function() {
44710    return this.build(false)._string;
44711  };
44712
44713
44714  function generateSimpleAccessor(_part){
44715    return function(v, build) {
44716      if (v === undefined) {
44717        return this._parts[_part] || '';
44718      } else {
44719        this._parts[_part] = v || null;
44720        this.build(!build);
44721        return this;
44722      }
44723    };
44724  }
44725
44726  function generatePrefixAccessor(_part, _key){
44727    return function(v, build) {
44728      if (v === undefined) {
44729        return this._parts[_part] || '';
44730      } else {
44731        if (v !== null) {
44732          v = v + '';
44733          if (v.charAt(0) === _key) {
44734            v = v.substring(1);
44735          }
44736        }
44737
44738        this._parts[_part] = v;
44739        this.build(!build);
44740        return this;
44741      }
44742    };
44743  }
44744
44745  p.protocol = generateSimpleAccessor('protocol');
44746  p.username = generateSimpleAccessor('username');
44747  p.password = generateSimpleAccessor('password');
44748  p.hostname = generateSimpleAccessor('hostname');
44749  p.port = generateSimpleAccessor('port');
44750  p.query = generatePrefixAccessor('query', '?');
44751  p.fragment = generatePrefixAccessor('fragment', '#');
44752
44753  p.search = function(v, build) {
44754    var t = this.query(v, build);
44755    return typeof t === 'string' && t.length ? ('?' + t) : t;
44756  };
44757  p.hash = function(v, build) {
44758    var t = this.fragment(v, build);
44759    return typeof t === 'string' && t.length ? ('#' + t) : t;
44760  };
44761
44762  p.pathname = function(v, build) {
44763    if (v === undefined || v === true) {
44764      var res = this._parts.path || (this._parts.hostname ? '/' : '');
44765      return v ? (this._parts.urn ? URI.decodeUrnPath : URI.decodePath)(res) : res;
44766    } else {
44767      if (this._parts.urn) {
44768        this._parts.path = v ? URI.recodeUrnPath(v) : '';
44769      } else {
44770        this._parts.path = v ? URI.recodePath(v) : '/';
44771      }
44772      this.build(!build);
44773      return this;
44774    }
44775  };
44776  p.path = p.pathname;
44777  p.href = function(href, build) {
44778    var key;
44779
44780    if (href === undefined) {
44781      return this.toString();
44782    }
44783
44784    this._string = '';
44785    this._parts = URI._parts();
44786
44787    var _URI = href instanceof URI;
44788    var _object = typeof href === 'object' && (href.hostname || href.path || href.pathname);
44789    if (href.nodeName) {
44790      var attribute = URI.getDomAttribute(href);
44791      href = href[attribute] || '';
44792      _object = false;
44793    }
44794
44795    // window.location is reported to be an object, but it's not the sort
44796    // of object we're looking for:
44797    // * location.protocol ends with a colon
44798    // * location.query != object.search
44799    // * location.hash != object.fragment
44800    // simply serializing the unknown object should do the trick
44801    // (for location, not for everything...)
44802    if (!_URI && _object && href.pathname !== undefined) {
44803      href = href.toString();
44804    }
44805
44806    if (typeof href === 'string' || href instanceof String) {
44807      this._parts = URI.parse(String(href), this._parts);
44808    } else if (_URI || _object) {
44809      var src = _URI ? href._parts : href;
44810      for (key in src) {
44811        if (key === 'query') { continue; }
44812        if (hasOwn.call(this._parts, key)) {
44813          this._parts[key] = src[key];
44814        }
44815      }
44816      if (src.query) {
44817        this.query(src.query, false);
44818      }
44819    } else {
44820      throw new TypeError('invalid input');
44821    }
44822
44823    this.build(!build);
44824    return this;
44825  };
44826
44827  // identification accessors
44828  p.is = function(what) {
44829    var ip = false;
44830    var ip4 = false;
44831    var ip6 = false;
44832    var name = false;
44833    var sld = false;
44834    var idn = false;
44835    var punycode = false;
44836    var relative = !this._parts.urn;
44837
44838    if (this._parts.hostname) {
44839      relative = false;
44840      ip4 = URI.ip4_expression.test(this._parts.hostname);
44841      ip6 = URI.ip6_expression.test(this._parts.hostname);
44842      ip = ip4 || ip6;
44843      name = !ip;
44844      sld = name && SLD && SLD.has(this._parts.hostname);
44845      idn = name && URI.idn_expression.test(this._parts.hostname);
44846      punycode = name && URI.punycode_expression.test(this._parts.hostname);
44847    }
44848
44849    switch (what.toLowerCase()) {
44850      case 'relative':
44851        return relative;
44852
44853      case 'absolute':
44854        return !relative;
44855
44856      // hostname identification
44857      case 'domain':
44858      case 'name':
44859        return name;
44860
44861      case 'sld':
44862        return sld;
44863
44864      case 'ip':
44865        return ip;
44866
44867      case 'ip4':
44868      case 'ipv4':
44869      case 'inet4':
44870        return ip4;
44871
44872      case 'ip6':
44873      case 'ipv6':
44874      case 'inet6':
44875        return ip6;
44876
44877      case 'idn':
44878        return idn;
44879
44880      case 'url':
44881        return !this._parts.urn;
44882
44883      case 'urn':
44884        return !!this._parts.urn;
44885
44886      case 'punycode':
44887        return punycode;
44888    }
44889
44890    return null;
44891  };
44892
44893  // component specific input validation
44894  var _protocol = p.protocol;
44895  var _port = p.port;
44896  var _hostname = p.hostname;
44897
44898  p.protocol = function(v, build) {
44899    if (v) {
44900      // accept trailing ://
44901      v = v.replace(/:(\/\/)?$/, '');
44902
44903      if (!v.match(URI.protocol_expression)) {
44904        throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
44905      }
44906    }
44907
44908    return _protocol.call(this, v, build);
44909  };
44910  p.scheme = p.protocol;
44911  p.port = function(v, build) {
44912    if (this._parts.urn) {
44913      return v === undefined ? '' : this;
44914    }
44915
44916    if (v !== undefined) {
44917      if (v === 0) {
44918        v = null;
44919      }
44920
44921      if (v) {
44922        v += '';
44923        if (v.charAt(0) === ':') {
44924          v = v.substring(1);
44925        }
44926
44927        URI.ensureValidPort(v);
44928      }
44929    }
44930    return _port.call(this, v, build);
44931  };
44932  p.hostname = function(v, build) {
44933    if (this._parts.urn) {
44934      return v === undefined ? '' : this;
44935    }
44936
44937    if (v !== undefined) {
44938      var x = { preventInvalidHostname: this._parts.preventInvalidHostname };
44939      var res = URI.parseHost(v, x);
44940      if (res !== '/') {
44941        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
44942      }
44943
44944      v = x.hostname;
44945      if (this._parts.preventInvalidHostname) {
44946        URI.ensureValidHostname(v, this._parts.protocol);
44947      }
44948    }
44949
44950    return _hostname.call(this, v, build);
44951  };
44952
44953  // compound accessors
44954  p.origin = function(v, build) {
44955    if (this._parts.urn) {
44956      return v === undefined ? '' : this;
44957    }
44958
44959    if (v === undefined) {
44960      var protocol = this.protocol();
44961      var authority = this.authority();
44962      if (!authority) {
44963        return '';
44964      }
44965
44966      return (protocol ? protocol + '://' : '') + this.authority();
44967    } else {
44968      var origin = URI(v);
44969      this
44970        .protocol(origin.protocol())
44971        .authority(origin.authority())
44972        .build(!build);
44973      return this;
44974    }
44975  };
44976  p.host = function(v, build) {
44977    if (this._parts.urn) {
44978      return v === undefined ? '' : this;
44979    }
44980
44981    if (v === undefined) {
44982      return this._parts.hostname ? URI.buildHost(this._parts) : '';
44983    } else {
44984      var res = URI.parseHost(v, this._parts);
44985      if (res !== '/') {
44986        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
44987      }
44988
44989      this.build(!build);
44990      return this;
44991    }
44992  };
44993  p.authority = function(v, build) {
44994    if (this._parts.urn) {
44995      return v === undefined ? '' : this;
44996    }
44997
44998    if (v === undefined) {
44999      return this._parts.hostname ? URI.buildAuthority(this._parts) : '';
45000    } else {
45001      var res = URI.parseAuthority(v, this._parts);
45002      if (res !== '/') {
45003        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
45004      }
45005
45006      this.build(!build);
45007      return this;
45008    }
45009  };
45010  p.userinfo = function(v, build) {
45011    if (this._parts.urn) {
45012      return v === undefined ? '' : this;
45013    }
45014
45015    if (v === undefined) {
45016      var t = URI.buildUserinfo(this._parts);
45017      return t ? t.substring(0, t.length -1) : t;
45018    } else {
45019      if (v[v.length-1] !== '@') {
45020        v += '@';
45021      }
45022
45023      URI.parseUserinfo(v, this._parts);
45024      this.build(!build);
45025      return this;
45026    }
45027  };
45028  p.resource = function(v, build) {
45029    var parts;
45030
45031    if (v === undefined) {
45032      return this.path() + this.search() + this.hash();
45033    }
45034
45035    parts = URI.parse(v);
45036    this._parts.path = parts.path;
45037    this._parts.query = parts.query;
45038    this._parts.fragment = parts.fragment;
45039    this.build(!build);
45040    return this;
45041  };
45042
45043  // fraction accessors
45044  p.subdomain = function(v, build) {
45045    if (this._parts.urn) {
45046      return v === undefined ? '' : this;
45047    }
45048
45049    // convenience, return "www" from "www.example.org"
45050    if (v === undefined) {
45051      if (!this._parts.hostname || this.is('IP')) {
45052        return '';
45053      }
45054
45055      // grab domain and add another segment
45056      var end = this._parts.hostname.length - this.domain().length - 1;
45057      return this._parts.hostname.substring(0, end) || '';
45058    } else {
45059      var e = this._parts.hostname.length - this.domain().length;
45060      var sub = this._parts.hostname.substring(0, e);
45061      var replace = new RegExp('^' + escapeRegEx(sub));
45062
45063      if (v && v.charAt(v.length - 1) !== '.') {
45064        v += '.';
45065      }
45066
45067      if (v.indexOf(':') !== -1) {
45068        throw new TypeError('Domains cannot contain colons');
45069      }
45070
45071      if (v) {
45072        URI.ensureValidHostname(v, this._parts.protocol);
45073      }
45074
45075      this._parts.hostname = this._parts.hostname.replace(replace, v);
45076      this.build(!build);
45077      return this;
45078    }
45079  };
45080  p.domain = function(v, build) {
45081    if (this._parts.urn) {
45082      return v === undefined ? '' : this;
45083    }
45084
45085    if (typeof v === 'boolean') {
45086      build = v;
45087      v = undefined;
45088    }
45089
45090    // convenience, return "example.org" from "www.example.org"
45091    if (v === undefined) {
45092      if (!this._parts.hostname || this.is('IP')) {
45093        return '';
45094      }
45095
45096      // if hostname consists of 1 or 2 segments, it must be the domain
45097      var t = this._parts.hostname.match(/\./g);
45098      if (t && t.length < 2) {
45099        return this._parts.hostname;
45100      }
45101
45102      // grab tld and add another segment
45103      var end = this._parts.hostname.length - this.tld(build).length - 1;
45104      end = this._parts.hostname.lastIndexOf('.', end -1) + 1;
45105      return this._parts.hostname.substring(end) || '';
45106    } else {
45107      if (!v) {
45108        throw new TypeError('cannot set domain empty');
45109      }
45110
45111      if (v.indexOf(':') !== -1) {
45112        throw new TypeError('Domains cannot contain colons');
45113      }
45114
45115      URI.ensureValidHostname(v, this._parts.protocol);
45116
45117      if (!this._parts.hostname || this.is('IP')) {
45118        this._parts.hostname = v;
45119      } else {
45120        var replace = new RegExp(escapeRegEx(this.domain()) + '$');
45121        this._parts.hostname = this._parts.hostname.replace(replace, v);
45122      }
45123
45124      this.build(!build);
45125      return this;
45126    }
45127  };
45128  p.tld = function(v, build) {
45129    if (this._parts.urn) {
45130      return v === undefined ? '' : this;
45131    }
45132
45133    if (typeof v === 'boolean') {
45134      build = v;
45135      v = undefined;
45136    }
45137
45138    // return "org" from "www.example.org"
45139    if (v === undefined) {
45140      if (!this._parts.hostname || this.is('IP')) {
45141        return '';
45142      }
45143
45144      var pos = this._parts.hostname.lastIndexOf('.');
45145      var tld = this._parts.hostname.substring(pos + 1);
45146
45147      if (build !== true && SLD && SLD.list[tld.toLowerCase()]) {
45148        return SLD.get(this._parts.hostname) || tld;
45149      }
45150
45151      return tld;
45152    } else {
45153      var replace;
45154
45155      if (!v) {
45156        throw new TypeError('cannot set TLD empty');
45157      } else if (v.match(/[^a-zA-Z0-9-]/)) {
45158        if (SLD && SLD.is(v)) {
45159          replace = new RegExp(escapeRegEx(this.tld()) + '$');
45160          this._parts.hostname = this._parts.hostname.replace(replace, v);
45161        } else {
45162          throw new TypeError('TLD "' + v + '" contains characters other than [A-Z0-9]');
45163        }
45164      } else if (!this._parts.hostname || this.is('IP')) {
45165        throw new ReferenceError('cannot set TLD on non-domain host');
45166      } else {
45167        replace = new RegExp(escapeRegEx(this.tld()) + '$');
45168        this._parts.hostname = this._parts.hostname.replace(replace, v);
45169      }
45170
45171      this.build(!build);
45172      return this;
45173    }
45174  };
45175  p.directory = function(v, build) {
45176    if (this._parts.urn) {
45177      return v === undefined ? '' : this;
45178    }
45179
45180    if (v === undefined || v === true) {
45181      if (!this._parts.path && !this._parts.hostname) {
45182        return '';
45183      }
45184
45185      if (this._parts.path === '/') {
45186        return '/';
45187      }
45188
45189      var end = this._parts.path.length - this.filename().length - 1;
45190      var res = this._parts.path.substring(0, end) || (this._parts.hostname ? '/' : '');
45191
45192      return v ? URI.decodePath(res) : res;
45193
45194    } else {
45195      var e = this._parts.path.length - this.filename().length;
45196      var directory = this._parts.path.substring(0, e);
45197      var replace = new RegExp('^' + escapeRegEx(directory));
45198
45199      // fully qualifier directories begin with a slash
45200      if (!this.is('relative')) {
45201        if (!v) {
45202          v = '/';
45203        }
45204
45205        if (v.charAt(0) !== '/') {
45206          v = '/' + v;
45207        }
45208      }
45209
45210      // directories always end with a slash
45211      if (v && v.charAt(v.length - 1) !== '/') {
45212        v += '/';
45213      }
45214
45215      v = URI.recodePath(v);
45216      this._parts.path = this._parts.path.replace(replace, v);
45217      this.build(!build);
45218      return this;
45219    }
45220  };
45221  p.filename = function(v, build) {
45222    if (this._parts.urn) {
45223      return v === undefined ? '' : this;
45224    }
45225
45226    if (typeof v !== 'string') {
45227      if (!this._parts.path || this._parts.path === '/') {
45228        return '';
45229      }
45230
45231      var pos = this._parts.path.lastIndexOf('/');
45232      var res = this._parts.path.substring(pos+1);
45233
45234      return v ? URI.decodePathSegment(res) : res;
45235    } else {
45236      var mutatedDirectory = false;
45237
45238      if (v.charAt(0) === '/') {
45239        v = v.substring(1);
45240      }
45241
45242      if (v.match(/\.?\//)) {
45243        mutatedDirectory = true;
45244      }
45245
45246      var replace = new RegExp(escapeRegEx(this.filename()) + '$');
45247      v = URI.recodePath(v);
45248      this._parts.path = this._parts.path.replace(replace, v);
45249
45250      if (mutatedDirectory) {
45251        this.normalizePath(build);
45252      } else {
45253        this.build(!build);
45254      }
45255
45256      return this;
45257    }
45258  };
45259  p.suffix = function(v, build) {
45260    if (this._parts.urn) {
45261      return v === undefined ? '' : this;
45262    }
45263
45264    if (v === undefined || v === true) {
45265      if (!this._parts.path || this._parts.path === '/') {
45266        return '';
45267      }
45268
45269      var filename = this.filename();
45270      var pos = filename.lastIndexOf('.');
45271      var s, res;
45272
45273      if (pos === -1) {
45274        return '';
45275      }
45276
45277      // suffix may only contain alnum characters (yup, I made this up.)
45278      s = filename.substring(pos+1);
45279      res = (/^[a-z0-9%]+$/i).test(s) ? s : '';
45280      return v ? URI.decodePathSegment(res) : res;
45281    } else {
45282      if (v.charAt(0) === '.') {
45283        v = v.substring(1);
45284      }
45285
45286      var suffix = this.suffix();
45287      var replace;
45288
45289      if (!suffix) {
45290        if (!v) {
45291          return this;
45292        }
45293
45294        this._parts.path += '.' + URI.recodePath(v);
45295      } else if (!v) {
45296        replace = new RegExp(escapeRegEx('.' + suffix) + '$');
45297      } else {
45298        replace = new RegExp(escapeRegEx(suffix) + '$');
45299      }
45300
45301      if (replace) {
45302        v = URI.recodePath(v);
45303        this._parts.path = this._parts.path.replace(replace, v);
45304      }
45305
45306      this.build(!build);
45307      return this;
45308    }
45309  };
45310  p.segment = function(segment, v, build) {
45311    var separator = this._parts.urn ? ':' : '/';
45312    var path = this.path();
45313    var absolute = path.substring(0, 1) === '/';
45314    var segments = path.split(separator);
45315
45316    if (segment !== undefined && typeof segment !== 'number') {
45317      build = v;
45318      v = segment;
45319      segment = undefined;
45320    }
45321
45322    if (segment !== undefined && typeof segment !== 'number') {
45323      throw new Error('Bad segment "' + segment + '", must be 0-based integer');
45324    }
45325
45326    if (absolute) {
45327      segments.shift();
45328    }
45329
45330    if (segment < 0) {
45331      // allow negative indexes to address from the end
45332      segment = Math.max(segments.length + segment, 0);
45333    }
45334
45335    if (v === undefined) {
45336      /*jshint laxbreak: true */
45337      return segment === undefined
45338        ? segments
45339        : segments[segment];
45340      /*jshint laxbreak: false */
45341    } else if (segment === null || segments[segment] === undefined) {
45342      if (isArray(v)) {
45343        segments = [];
45344        // collapse empty elements within array
45345        for (var i=0, l=v.length; i < l; i++) {
45346          if (!v[i].length && (!segments.length || !segments[segments.length -1].length)) {
45347            continue;
45348          }
45349
45350          if (segments.length && !segments[segments.length -1].length) {
45351            segments.pop();
45352          }
45353
45354          segments.push(trimSlashes(v[i]));
45355        }
45356      } else if (v || typeof v === 'string') {
45357        v = trimSlashes(v);
45358        if (segments[segments.length -1] === '') {
45359          // empty trailing elements have to be overwritten
45360          // to prevent results such as /foo//bar
45361          segments[segments.length -1] = v;
45362        } else {
45363          segments.push(v);
45364        }
45365      }
45366    } else {
45367      if (v) {
45368        segments[segment] = trimSlashes(v);
45369      } else {
45370        segments.splice(segment, 1);
45371      }
45372    }
45373
45374    if (absolute) {
45375      segments.unshift('');
45376    }
45377
45378    return this.path(segments.join(separator), build);
45379  };
45380  p.segmentCoded = function(segment, v, build) {
45381    var segments, i, l;
45382
45383    if (typeof segment !== 'number') {
45384      build = v;
45385      v = segment;
45386      segment = undefined;
45387    }
45388
45389    if (v === undefined) {
45390      segments = this.segment(segment, v, build);
45391      if (!isArray(segments)) {
45392        segments = segments !== undefined ? URI.decode(segments) : undefined;
45393      } else {
45394        for (i = 0, l = segments.length; i < l; i++) {
45395          segments[i] = URI.decode(segments[i]);
45396        }
45397      }
45398
45399      return segments;
45400    }
45401
45402    if (!isArray(v)) {
45403      v = (typeof v === 'string' || v instanceof String) ? URI.encode(v) : v;
45404    } else {
45405      for (i = 0, l = v.length; i < l; i++) {
45406        v[i] = URI.encode(v[i]);
45407      }
45408    }
45409
45410    return this.segment(segment, v, build);
45411  };
45412
45413  // mutating query string
45414  var q = p.query;
45415  p.query = function(v, build) {
45416    if (v === true) {
45417      return URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
45418    } else if (typeof v === 'function') {
45419      var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
45420      var result = v.call(this, data);
45421      this._parts.query = URI.buildQuery(result || data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
45422      this.build(!build);
45423      return this;
45424    } else if (v !== undefined && typeof v !== 'string') {
45425      this._parts.query = URI.buildQuery(v, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
45426      this.build(!build);
45427      return this;
45428    } else {
45429      return q.call(this, v, build);
45430    }
45431  };
45432  p.setQuery = function(name, value, build) {
45433    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
45434
45435    if (typeof name === 'string' || name instanceof String) {
45436      data[name] = value !== undefined ? value : null;
45437    } else if (typeof name === 'object') {
45438      for (var key in name) {
45439        if (hasOwn.call(name, key)) {
45440          data[key] = name[key];
45441        }
45442      }
45443    } else {
45444      throw new TypeError('URI.addQuery() accepts an object, string as the name parameter');
45445    }
45446
45447    this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
45448    if (typeof name !== 'string') {
45449      build = value;
45450    }
45451
45452    this.build(!build);
45453    return this;
45454  };
45455  p.addQuery = function(name, value, build) {
45456    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
45457    URI.addQuery(data, name, value === undefined ? null : value);
45458    this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
45459    if (typeof name !== 'string') {
45460      build = value;
45461    }
45462
45463    this.build(!build);
45464    return this;
45465  };
45466  p.removeQuery = function(name, value, build) {
45467    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
45468    URI.removeQuery(data, name, value);
45469    this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
45470    if (typeof name !== 'string') {
45471      build = value;
45472    }
45473
45474    this.build(!build);
45475    return this;
45476  };
45477  p.hasQuery = function(name, value, withinArray) {
45478    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
45479    return URI.hasQuery(data, name, value, withinArray);
45480  };
45481  p.setSearch = p.setQuery;
45482  p.addSearch = p.addQuery;
45483  p.removeSearch = p.removeQuery;
45484  p.hasSearch = p.hasQuery;
45485
45486  // sanitizing URLs
45487  p.normalize = function() {
45488    if (this._parts.urn) {
45489      return this
45490        .normalizeProtocol(false)
45491        .normalizePath(false)
45492        .normalizeQuery(false)
45493        .normalizeFragment(false)
45494        .build();
45495    }
45496
45497    return this
45498      .normalizeProtocol(false)
45499      .normalizeHostname(false)
45500      .normalizePort(false)
45501      .normalizePath(false)
45502      .normalizeQuery(false)
45503      .normalizeFragment(false)
45504      .build();
45505  };
45506  p.normalizeProtocol = function(build) {
45507    if (typeof this._parts.protocol === 'string') {
45508      this._parts.protocol = this._parts.protocol.toLowerCase();
45509      this.build(!build);
45510    }
45511
45512    return this;
45513  };
45514  p.normalizeHostname = function(build) {
45515    if (this._parts.hostname) {
45516      if (this.is('IDN') && punycode) {
45517        this._parts.hostname = punycode.toASCII(this._parts.hostname);
45518      } else if (this.is('IPv6') && IPv6) {
45519        this._parts.hostname = IPv6.best(this._parts.hostname);
45520      }
45521
45522      this._parts.hostname = this._parts.hostname.toLowerCase();
45523      this.build(!build);
45524    }
45525
45526    return this;
45527  };
45528  p.normalizePort = function(build) {
45529    // remove port of it's the protocol's default
45530    if (typeof this._parts.protocol === 'string' && this._parts.port === URI.defaultPorts[this._parts.protocol]) {
45531      this._parts.port = null;
45532      this.build(!build);
45533    }
45534
45535    return this;
45536  };
45537  p.normalizePath = function(build) {
45538    var _path = this._parts.path;
45539    if (!_path) {
45540      return this;
45541    }
45542
45543    if (this._parts.urn) {
45544      this._parts.path = URI.recodeUrnPath(this._parts.path);
45545      this.build(!build);
45546      return this;
45547    }
45548
45549    if (this._parts.path === '/') {
45550      return this;
45551    }
45552
45553    _path = URI.recodePath(_path);
45554
45555    var _was_relative;
45556    var _leadingParents = '';
45557    var _parent, _pos;
45558
45559    // handle relative paths
45560    if (_path.charAt(0) !== '/') {
45561      _was_relative = true;
45562      _path = '/' + _path;
45563    }
45564
45565    // handle relative files (as opposed to directories)
45566    if (_path.slice(-3) === '/..' || _path.slice(-2) === '/.') {
45567      _path += '/';
45568    }
45569
45570    // resolve simples
45571    _path = _path
45572      .replace(/(\/(\.\/)+)|(\/\.$)/g, '/')
45573      .replace(/\/{2,}/g, '/');
45574
45575    // remember leading parents
45576    if (_was_relative) {
45577      _leadingParents = _path.substring(1).match(/^(\.\.\/)+/) || '';
45578      if (_leadingParents) {
45579        _leadingParents = _leadingParents[0];
45580      }
45581    }
45582
45583    // resolve parents
45584    while (true) {
45585      _parent = _path.search(/\/\.\.(\/|$)/);
45586      if (_parent === -1) {
45587        // no more ../ to resolve
45588        break;
45589      } else if (_parent === 0) {
45590        // top level cannot be relative, skip it
45591        _path = _path.substring(3);
45592        continue;
45593      }
45594
45595      _pos = _path.substring(0, _parent).lastIndexOf('/');
45596      if (_pos === -1) {
45597        _pos = _parent;
45598      }
45599      _path = _path.substring(0, _pos) + _path.substring(_parent + 3);
45600    }
45601
45602    // revert to relative
45603    if (_was_relative && this.is('relative')) {
45604      _path = _leadingParents + _path.substring(1);
45605    }
45606
45607    this._parts.path = _path;
45608    this.build(!build);
45609    return this;
45610  };
45611  p.normalizePathname = p.normalizePath;
45612  p.normalizeQuery = function(build) {
45613    if (typeof this._parts.query === 'string') {
45614      if (!this._parts.query.length) {
45615        this._parts.query = null;
45616      } else {
45617        this.query(URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace));
45618      }
45619
45620      this.build(!build);
45621    }
45622
45623    return this;
45624  };
45625  p.normalizeFragment = function(build) {
45626    if (!this._parts.fragment) {
45627      this._parts.fragment = null;
45628      this.build(!build);
45629    }
45630
45631    return this;
45632  };
45633  p.normalizeSearch = p.normalizeQuery;
45634  p.normalizeHash = p.normalizeFragment;
45635
45636  p.iso8859 = function() {
45637    // expect unicode input, iso8859 output
45638    var e = URI.encode;
45639    var d = URI.decode;
45640
45641    URI.encode = escape;
45642    URI.decode = decodeURIComponent;
45643    try {
45644      this.normalize();
45645    } finally {
45646      URI.encode = e;
45647      URI.decode = d;
45648    }
45649    return this;
45650  };
45651
45652  p.unicode = function() {
45653    // expect iso8859 input, unicode output
45654    var e = URI.encode;
45655    var d = URI.decode;
45656
45657    URI.encode = strictEncodeURIComponent;
45658    URI.decode = unescape;
45659    try {
45660      this.normalize();
45661    } finally {
45662      URI.encode = e;
45663      URI.decode = d;
45664    }
45665    return this;
45666  };
45667
45668  p.readable = function() {
45669    var uri = this.clone();
45670    // removing username, password, because they shouldn't be displayed according to RFC 3986
45671    uri.username('').password('').normalize();
45672    var t = '';
45673    if (uri._parts.protocol) {
45674      t += uri._parts.protocol + '://';
45675    }
45676
45677    if (uri._parts.hostname) {
45678      if (uri.is('punycode') && punycode) {
45679        t += punycode.toUnicode(uri._parts.hostname);
45680        if (uri._parts.port) {
45681          t += ':' + uri._parts.port;
45682        }
45683      } else {
45684        t += uri.host();
45685      }
45686    }
45687
45688    if (uri._parts.hostname && uri._parts.path && uri._parts.path.charAt(0) !== '/') {
45689      t += '/';
45690    }
45691
45692    t += uri.path(true);
45693    if (uri._parts.query) {
45694      var q = '';
45695      for (var i = 0, qp = uri._parts.query.split('&'), l = qp.length; i < l; i++) {
45696        var kv = (qp[i] || '').split('=');
45697        q += '&' + URI.decodeQuery(kv[0], this._parts.escapeQuerySpace)
45698          .replace(/&/g, '%26');
45699
45700        if (kv[1] !== undefined) {
45701          q += '=' + URI.decodeQuery(kv[1], this._parts.escapeQuerySpace)
45702            .replace(/&/g, '%26');
45703        }
45704      }
45705      t += '?' + q.substring(1);
45706    }
45707
45708    t += URI.decodeQuery(uri.hash(), true);
45709    return t;
45710  };
45711
45712  // resolving relative and absolute URLs
45713  p.absoluteTo = function(base) {
45714    var resolved = this.clone();
45715    var properties = ['protocol', 'username', 'password', 'hostname', 'port'];
45716    var basedir, i, p;
45717
45718    if (this._parts.urn) {
45719      throw new Error('URNs do not have any generally defined hierarchical components');
45720    }
45721
45722    if (!(base instanceof URI)) {
45723      base = new URI(base);
45724    }
45725
45726    if (resolved._parts.protocol) {
45727      // Directly returns even if this._parts.hostname is empty.
45728      return resolved;
45729    } else {
45730      resolved._parts.protocol = base._parts.protocol;
45731    }
45732
45733    if (this._parts.hostname) {
45734      return resolved;
45735    }
45736
45737    for (i = 0; (p = properties[i]); i++) {
45738      resolved._parts[p] = base._parts[p];
45739    }
45740
45741    if (!resolved._parts.path) {
45742      resolved._parts.path = base._parts.path;
45743      if (!resolved._parts.query) {
45744        resolved._parts.query = base._parts.query;
45745      }
45746    } else {
45747      if (resolved._parts.path.substring(-2) === '..') {
45748        resolved._parts.path += '/';
45749      }
45750
45751      if (resolved.path().charAt(0) !== '/') {
45752        basedir = base.directory();
45753        basedir = basedir ? basedir : base.path().indexOf('/') === 0 ? '/' : '';
45754        resolved._parts.path = (basedir ? (basedir + '/') : '') + resolved._parts.path;
45755        resolved.normalizePath();
45756      }
45757    }
45758
45759    resolved.build();
45760    return resolved;
45761  };
45762  p.relativeTo = function(base) {
45763    var relative = this.clone().normalize();
45764    var relativeParts, baseParts, common, relativePath, basePath;
45765
45766    if (relative._parts.urn) {
45767      throw new Error('URNs do not have any generally defined hierarchical components');
45768    }
45769
45770    base = new URI(base).normalize();
45771    relativeParts = relative._parts;
45772    baseParts = base._parts;
45773    relativePath = relative.path();
45774    basePath = base.path();
45775
45776    if (relativePath.charAt(0) !== '/') {
45777      throw new Error('URI is already relative');
45778    }
45779
45780    if (basePath.charAt(0) !== '/') {
45781      throw new Error('Cannot calculate a URI relative to another relative URI');
45782    }
45783
45784    if (relativeParts.protocol === baseParts.protocol) {
45785      relativeParts.protocol = null;
45786    }
45787
45788    if (relativeParts.username !== baseParts.username || relativeParts.password !== baseParts.password) {
45789      return relative.build();
45790    }
45791
45792    if (relativeParts.protocol !== null || relativeParts.username !== null || relativeParts.password !== null) {
45793      return relative.build();
45794    }
45795
45796    if (relativeParts.hostname === baseParts.hostname && relativeParts.port === baseParts.port) {
45797      relativeParts.hostname = null;
45798      relativeParts.port = null;
45799    } else {
45800      return relative.build();
45801    }
45802
45803    if (relativePath === basePath) {
45804      relativeParts.path = '';
45805      return relative.build();
45806    }
45807
45808    // determine common sub path
45809    common = URI.commonPath(relativePath, basePath);
45810
45811    // If the paths have nothing in common, return a relative URL with the absolute path.
45812    if (!common) {
45813      return relative.build();
45814    }
45815
45816    var parents = baseParts.path
45817      .substring(common.length)
45818      .replace(/[^\/]*$/, '')
45819      .replace(/.*?\//g, '../');
45820
45821    relativeParts.path = (parents + relativeParts.path.substring(common.length)) || './';
45822
45823    return relative.build();
45824  };
45825
45826  // comparing URIs
45827  p.equals = function(uri) {
45828    var one = this.clone();
45829    var two = new URI(uri);
45830    var one_map = {};
45831    var two_map = {};
45832    var checked = {};
45833    var one_query, two_query, key;
45834
45835    one.normalize();
45836    two.normalize();
45837
45838    // exact match
45839    if (one.toString() === two.toString()) {
45840      return true;
45841    }
45842
45843    // extract query string
45844    one_query = one.query();
45845    two_query = two.query();
45846    one.query('');
45847    two.query('');
45848
45849    // definitely not equal if not even non-query parts match
45850    if (one.toString() !== two.toString()) {
45851      return false;
45852    }
45853
45854    // query parameters have the same length, even if they're permuted
45855    if (one_query.length !== two_query.length) {
45856      return false;
45857    }
45858
45859    one_map = URI.parseQuery(one_query, this._parts.escapeQuerySpace);
45860    two_map = URI.parseQuery(two_query, this._parts.escapeQuerySpace);
45861
45862    for (key in one_map) {
45863      if (hasOwn.call(one_map, key)) {
45864        if (!isArray(one_map[key])) {
45865          if (one_map[key] !== two_map[key]) {
45866            return false;
45867          }
45868        } else if (!arraysEqual(one_map[key], two_map[key])) {
45869          return false;
45870        }
45871
45872        checked[key] = true;
45873      }
45874    }
45875
45876    for (key in two_map) {
45877      if (hasOwn.call(two_map, key)) {
45878        if (!checked[key]) {
45879          // two contains a parameter not present in one
45880          return false;
45881        }
45882      }
45883    }
45884
45885    return true;
45886  };
45887
45888  // state
45889  p.preventInvalidHostname = function(v) {
45890    this._parts.preventInvalidHostname = !!v;
45891    return this;
45892  };
45893
45894  p.duplicateQueryParameters = function(v) {
45895    this._parts.duplicateQueryParameters = !!v;
45896    return this;
45897  };
45898
45899  p.escapeQuerySpace = function(v) {
45900    this._parts.escapeQuerySpace = !!v;
45901    return this;
45902  };
45903
45904  return URI;
45905}));
45906
45907},{"./IPv6":143,"./SecondLevelDomains":144,"./punycode":146}],146:[function(require,module,exports){
45908(function (global){
45909/*! https://mths.be/punycode v1.4.0
vendor: 13,540 bytes, lines 45909-46397
45909 by @mathias */
45910;(function(root) {
45911
45912	/** Detect free variables */
45913	var freeExports = typeof exports == 'object' && exports &&
45914		!exports.nodeType && exports;
45915	var freeModule = typeof module == 'object' && module &&
45916		!module.nodeType && module;
45917	var freeGlobal = typeof global == 'object' && global;
45918	if (
45919		freeGlobal.global === freeGlobal ||
45920		freeGlobal.window === freeGlobal ||
45921		freeGlobal.self === freeGlobal
45922	) {
45923		root = freeGlobal;
45924	}
45925
45926	/**
45927	 * The `punycode` object.
45928	 * @name punycode
45929	 * @type Object
45930	 */
45931	var punycode,
45932
45933	/** Highest positive signed 32-bit float value */
45934	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
45935
45936	/** Bootstring parameters */
45937	base = 36,
45938	tMin = 1,
45939	tMax = 26,
45940	skew = 38,
45941	damp = 700,
45942	initialBias = 72,
45943	initialN = 128, // 0x80
45944	delimiter = '-', // '\x2D'
45945
45946	/** Regular expressions */
45947	regexPunycode = /^xn--/,
45948	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
45949	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
45950
45951	/** Error messages */
45952	errors = {
45953		'overflow': 'Overflow: input needs wider integers to process',
45954		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
45955		'invalid-input': 'Invalid input'
45956	},
45957
45958	/** Convenience shortcuts */
45959	baseMinusTMin = base - tMin,
45960	floor = Math.floor,
45961	stringFromCharCode = String.fromCharCode,
45962
45963	/** Temporary variable */
45964	key;
45965
45966	/*--------------------------------------------------------------------------*/
45967
45968	/**
45969	 * A generic error utility function.
45970	 * @private
45971	 * @param {String} type The error type.
45972	 * @returns {Error} Throws a `RangeError` with the applicable error message.
45973	 */
45974	function error(type) {
45975		throw new RangeError(errors[type]);
45976	}
45977
45978	/**
45979	 * A generic `Array#map` utility function.
45980	 * @private
45981	 * @param {Array} array The array to iterate over.
45982	 * @param {Function} callback The function that gets called for every array
45983	 * item.
45984	 * @returns {Array} A new array of values returned by the callback function.
45985	 */
45986	function map(array, fn) {
45987		var length = array.length;
45988		var result = [];
45989		while (length--) {
45990			result[length] = fn(array[length]);
45991		}
45992		return result;
45993	}
45994
45995	/**
45996	 * A simple `Array#map`-like wrapper to work with domain name strings or email
45997	 * addresses.
45998	 * @private
45999	 * @param {String} domain The domain name or email address.
46000	 * @param {Function} callback The function that gets called for every
46001	 * character.
46002	 * @returns {Array} A new string of characters returned by the callback
46003	 * function.
46004	 */
46005	function mapDomain(string, fn) {
46006		var parts = string.split('@');
46007		var result = '';
46008		if (parts.length > 1) {
46009			// In email addresses, only the domain name should be punycoded. Leave
46010			// the local part (i.e. everything up to `@`) intact.
46011			result = parts[0] + '@';
46012			string = parts[1];
46013		}
46014		// Avoid `split(regex)` for IE8 compatibility. See #17.
46015		string = string.replace(regexSeparators, '\x2E');
46016		var labels = string.split('.');
46017		var encoded = map(labels, fn).join('.');
46018		return result + encoded;
46019	}
46020
46021	/**
46022	 * Creates an array containing the numeric code points of each Unicode
46023	 * character in the string. While JavaScript uses UCS-2 internally,
46024	 * this function will convert a pair of surrogate halves (each of which
46025	 * UCS-2 exposes as separate characters) into a single code point,
46026	 * matching UTF-16.
46027	 * @see `punycode.ucs2.encode`
46028	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
46029	 * @memberOf punycode.ucs2
46030	 * @name decode
46031	 * @param {String} string The Unicode input string (UCS-2).
46032	 * @returns {Array} The new array of code points.
46033	 */
46034	function ucs2decode(string) {
46035		var output = [],
46036		    counter = 0,
46037		    length = string.length,
46038		    value,
46039		    extra;
46040		while (counter < length) {
46041			value = string.charCodeAt(counter++);
46042			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
46043				// high surrogate, and there is a next character
46044				extra = string.charCodeAt(counter++);
46045				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
46046					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
46047				} else {
46048					// unmatched surrogate; only append this code unit, in case the next
46049					// code unit is the high surrogate of a surrogate pair
46050					output.push(value);
46051					counter--;
46052				}
46053			} else {
46054				output.push(value);
46055			}
46056		}
46057		return output;
46058	}
46059
46060	/**
46061	 * Creates a string based on an array of numeric code points.
46062	 * @see `punycode.ucs2.decode`
46063	 * @memberOf punycode.ucs2
46064	 * @name encode
46065	 * @param {Array} codePoints The array of numeric code points.
46066	 * @returns {String} The new Unicode string (UCS-2).
46067	 */
46068	function ucs2encode(array) {
46069		return map(array, function(value) {
46070			var output = '';
46071			if (value > 0xFFFF) {
46072				value -= 0x10000;
46073				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
46074				value = 0xDC00 | value & 0x3FF;
46075			}
46076			output += stringFromCharCode(value);
46077			return output;
46078		}).join('');
46079	}
46080
46081	/**
46082	 * Converts a basic code point into a digit/integer.
46083	 * @see `digitToBasic()`
46084	 * @private
46085	 * @param {Number} codePoint The basic numeric code point value.
46086	 * @returns {Number} The numeric value of a basic code point (for use in
46087	 * representing integers) in the range `0` to `base - 1`, or `base` if
46088	 * the code point does not represent a value.
46089	 */
46090	function basicToDigit(codePoint) {
46091		if (codePoint - 48 < 10) {
46092			return codePoint - 22;
46093		}
46094		if (codePoint - 65 < 26) {
46095			return codePoint - 65;
46096		}
46097		if (codePoint - 97 < 26) {
46098			return codePoint - 97;
46099		}
46100		return base;
46101	}
46102
46103	/**
46104	 * Converts a digit/integer into a basic code point.
46105	 * @see `basicToDigit()`
46106	 * @private
46107	 * @param {Number} digit The numeric value of a basic code point.
46108	 * @returns {Number} The basic code point whose value (when used for
46109	 * representing integers) is `digit`, which needs to be in the range
46110	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
46111	 * used; else, the lowercase form is used. The behavior is undefined
46112	 * if `flag` is non-zero and `digit` has no uppercase form.
46113	 */
46114	function digitToBasic(digit, flag) {
46115		//  0..25 map to ASCII a..z or A..Z
46116		// 26..35 map to ASCII 0..9
46117		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
46118	}
46119
46120	/**
46121	 * Bias adaptation function as per section 3.4 of RFC 3492.
46122	 * https://tools.ietf.org/html/rfc3492#section-3.4
46123	 * @private
46124	 */
46125	function adapt(delta, numPoints, firstTime) {
46126		var k = 0;
46127		delta = firstTime ? floor(delta / damp) : delta >> 1;
46128		delta += floor(delta / numPoints);
46129		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
46130			delta = floor(delta / baseMinusTMin);
46131		}
46132		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
46133	}
46134
46135	/**
46136	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
46137	 * symbols.
46138	 * @memberOf punycode
46139	 * @param {String} input The Punycode string of ASCII-only symbols.
46140	 * @returns {String} The resulting string of Unicode symbols.
46141	 */
46142	function decode(input) {
46143		// Don't use UCS-2
46144		var output = [],
46145		    inputLength = input.length,
46146		    out,
46147		    i = 0,
46148		    n = initialN,
46149		    bias = initialBias,
46150		    basic,
46151		    j,
46152		    index,
46153		    oldi,
46154		    w,
46155		    k,
46156		    digit,
46157		    t,
46158		    /** Cached calculation results */
46159		    baseMinusT;
46160
46161		// Handle the basic code points: let `basic` be the number of input code
46162		// points before the last delimiter, or `0` if there is none, then copy
46163		// the first basic code points to the output.
46164
46165		basic = input.lastIndexOf(delimiter);
46166		if (basic < 0) {
46167			basic = 0;
46168		}
46169
46170		for (j = 0; j < basic; ++j) {
46171			// if it's not a basic code point
46172			if (input.charCodeAt(j) >= 0x80) {
46173				error('not-basic');
46174			}
46175			output.push(input.charCodeAt(j));
46176		}
46177
46178		// Main decoding loop: start just after the last delimiter if any basic code
46179		// points were copied; start at the beginning otherwise.
46180
46181		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
46182
46183			// `index` is the index of the next character to be consumed.
46184			// Decode a generalized variable-length integer into `delta`,
46185			// which gets added to `i`. The overflow checking is easier
46186			// if we increase `i` as we go, then subtract off its starting
46187			// value at the end to obtain `delta`.
46188			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
46189
46190				if (index >= inputLength) {
46191					error('invalid-input');
46192				}
46193
46194				digit = basicToDigit(input.charCodeAt(index++));
46195
46196				if (digit >= base || digit > floor((maxInt - i) / w)) {
46197					error('overflow');
46198				}
46199
46200				i += digit * w;
46201				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
46202
46203				if (digit < t) {
46204					break;
46205				}
46206
46207				baseMinusT = base - t;
46208				if (w > floor(maxInt / baseMinusT)) {
46209					error('overflow');
46210				}
46211
46212				w *= baseMinusT;
46213
46214			}
46215
46216			out = output.length + 1;
46217			bias = adapt(i - oldi, out, oldi == 0);
46218
46219			// `i` was supposed to wrap around from `out` to `0`,
46220			// incrementing `n` each time, so we'll fix that now:
46221			if (floor(i / out) > maxInt - n) {
46222				error('overflow');
46223			}
46224
46225			n += floor(i / out);
46226			i %= out;
46227
46228			// Insert `n` at position `i` of the output
46229			output.splice(i++, 0, n);
46230
46231		}
46232
46233		return ucs2encode(output);
46234	}
46235
46236	/**
46237	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
46238	 * Punycode string of ASCII-only symbols.
46239	 * @memberOf punycode
46240	 * @param {String} input The string of Unicode symbols.
46241	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
46242	 */
46243	function encode(input) {
46244		var n,
46245		    delta,
46246		    handledCPCount,
46247		    basicLength,
46248		    bias,
46249		    j,
46250		    m,
46251		    q,
46252		    k,
46253		    t,
46254		    currentValue,
46255		    output = [],
46256		    /** `inputLength` will hold the number of code points in `input`. */
46257		    inputLength,
46258		    /** Cached calculation results */
46259		    handledCPCountPlusOne,
46260		    baseMinusT,
46261		    qMinusT;
46262
46263		// Convert the input in UCS-2 to Unicode
46264		input = ucs2decode(input);
46265
46266		// Cache the length
46267		inputLength = input.length;
46268
46269		// Initialize the state
46270		n = initialN;
46271		delta = 0;
46272		bias = initialBias;
46273
46274		// Handle the basic code points
46275		for (j = 0; j < inputLength; ++j) {
46276			currentValue = input[j];
46277			if (currentValue < 0x80) {
46278				output.push(stringFromCharCode(currentValue));
46279			}
46280		}
46281
46282		handledCPCount = basicLength = output.length;
46283
46284		// `handledCPCount` is the number of code points that have been handled;
46285		// `basicLength` is the number of basic code points.
46286
46287		// Finish the basic string - if it is not empty - with a delimiter
46288		if (basicLength) {
46289			output.push(delimiter);
46290		}
46291
46292		// Main encoding loop:
46293		while (handledCPCount < inputLength) {
46294
46295			// All non-basic code points < n have been handled already. Find the next
46296			// larger one:
46297			for (m = maxInt, j = 0; j < inputLength; ++j) {
46298				currentValue = input[j];
46299				if (currentValue >= n && currentValue < m) {
46300					m = currentValue;
46301				}
46302			}
46303
46304			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
46305			// but guard against overflow
46306			handledCPCountPlusOne = handledCPCount + 1;
46307			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
46308				error('overflow');
46309			}
46310
46311			delta += (m - n) * handledCPCountPlusOne;
46312			n = m;
46313
46314			for (j = 0; j < inputLength; ++j) {
46315				currentValue = input[j];
46316
46317				if (currentValue < n && ++delta > maxInt) {
46318					error('overflow');
46319				}
46320
46321				if (currentValue == n) {
46322					// Represent delta as a generalized variable-length integer
46323					for (q = delta, k = base; /* no condition */; k += base) {
46324						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
46325						if (q < t) {
46326							break;
46327						}
46328						qMinusT = q - t;
46329						baseMinusT = base - t;
46330						output.push(
46331							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
46332						);
46333						q = floor(qMinusT / baseMinusT);
46334					}
46335
46336					output.push(stringFromCharCode(digitToBasic(q, 0)));
46337					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
46338					delta = 0;
46339					++handledCPCount;
46340				}
46341			}
46342
46343			++delta;
46344			++n;
46345
46346		}
46347		return output.join('');
46348	}
46349
46350	/**
46351	 * Converts a Punycode string representing a domain name or an email address
46352	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
46353	 * it doesn't matter if you call it on a string that has already been
46354	 * converted to Unicode.
46355	 * @memberOf punycode
46356	 * @param {String} input The Punycoded domain name or email address to
46357	 * convert to Unicode.
46358	 * @returns {String} The Unicode representation of the given Punycode
46359	 * string.
46360	 */
46361	function toUnicode(input) {
46362		return mapDomain(input, function(string) {
46363			return regexPunycode.test(string)
46364				? decode(string.slice(4).toLowerCase())
46365				: string;
46366		});
46367	}
46368
46369	/**
46370	 * Converts a Unicode string representing a domain name or an email address to
46371	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
46372	 * i.e. it doesn't matter if you call it with a domain that's already in
46373	 * ASCII.
46374	 * @memberOf punycode
46375	 * @param {String} input The domain name or email address to convert, as a
46376	 * Unicode string.
46377	 * @returns {String} The Punycode representation of the given domain name or
46378	 * email address.
46379	 */
46380	function toASCII(input) {
46381		return mapDomain(input, function(string) {
46382			return regexNonASCII.test(string)
46383				? 'xn--' + encode(string)
46384				: string;
46385		});
46386	}
46387
46388	/*--------------------------------------------------------------------------*/
46389
46390	/** Define the public API */
46391	punycode = {
46392		/**
46393		 * A string representing the current Punycode.js version number.
46394		 * @memberOf punycode
46395		 * @type String
46396		 */
46397		'version': '1.
vendor: 1,241 bytes, lines 46397-46444
463973.2',
46398		/**
46399		 * An object of methods to convert from JavaScript's internal character
46400		 * representation (UCS-2) to Unicode code points, and back.
46401		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
46402		 * @memberOf punycode
46403		 * @type Object
46404		 */
46405		'ucs2': {
46406			'decode': ucs2decode,
46407			'encode': ucs2encode
46408		},
46409		'decode': decode,
46410		'encode': encode,
46411		'toASCII': toASCII,
46412		'toUnicode': toUnicode
46413	};
46414
46415	/** Expose `punycode` */
46416	// Some AMD build optimizers, like r.js, check for specific condition patterns
46417	// like the following:
46418	if (
46419		typeof define == 'function' &&
46420		typeof define.amd == 'object' &&
46421		define.amd
46422	) {
46423		define('punycode', function() {
46424			return punycode;
46425		});
46426	} else if (freeExports && freeModule) {
46427		if (module.exports == freeExports) {
46428			// in Node.js, io.js, or RingoJS v0.8.0+
46429			freeModule.exports = punycode;
46430		} else {
46431			// in Narwhal or RingoJS v0.7.0-
46432			for (key in punycode) {
46433				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
46434			}
46435		}
46436	} else {
46437		// in Rhino or a web browser
46438		root.punycode = punycode;
46439	}
46440
46441}(this));
46442
46443}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
46444},{}],147
vendor: 23,366 bytes, lines 46444-47178
46444:[function(require,module,exports){
46445// Copyright Joyent, Inc. and other Node contributors.
46446//
46447// Permission is hereby granted, free of charge, to any person obtaining a
46448// copy of this software and associated documentation files (the
46449// "Software"), to deal in the Software without restriction, including
46450// without limitation the rights to use, copy, modify, merge, publish,
46451// distribute, sublicense, and/or sell copies of the Software, and to permit
46452// persons to whom the Software is furnished to do so, subject to the
46453// following conditions:
46454//
46455// The above copyright notice and this permission notice shall be included
46456// in all copies or substantial portions of the Software.
46457//
46458// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
46459// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46460// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
46461// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
46462// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
46463// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
46464// USE OR OTHER DEALINGS IN THE SOFTWARE.
46465
46466'use strict';
46467
46468var punycode = require('punycode');
46469var util = require('./util');
46470
46471exports.parse = urlParse;
46472exports.resolve = urlResolve;
46473exports.resolveObject = urlResolveObject;
46474exports.format = urlFormat;
46475
46476exports.Url = Url;
46477
46478function Url() {
46479  this.protocol = null;
46480  this.slashes = null;
46481  this.auth = null;
46482  this.host = null;
46483  this.port = null;
46484  this.hostname = null;
46485  this.hash = null;
46486  this.search = null;
46487  this.query = null;
46488  this.pathname = null;
46489  this.path = null;
46490  this.href = null;
46491}
46492
46493// Reference: RFC 3986, RFC 1808, RFC 2396
46494
46495// define these here so at least they only have to be
46496// compiled once on the first module load.
46497var protocolPattern = /^([a-z0-9.+-]+:)/i,
46498    portPattern = /:[0-9]*$/,
46499
46500    // Special case for a simple path URL
46501    simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
46502
46503    // RFC 2396: characters reserved for delimiting URLs.
46504    // We actually just auto-escape these.
46505    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
46506
46507    // RFC 2396: characters not allowed for various reasons.
46508    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
46509
46510    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
46511    autoEscape = ['\''].concat(unwise),
46512    // Characters that are never ever allowed in a hostname.
46513    // Note that any invalid chars are also handled, but these
46514    // are the ones that are *expected* to be seen, so we fast-path
46515    // them.
46516    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
46517    hostEndingChars = ['/', '?', '#'],
46518    hostnameMaxLen = 255,
46519    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
46520    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
46521    // protocols that can allow "unsafe" and "unwise" chars.
46522    unsafeProtocol = {
46523      'javascript': true,
46524      'javascript:': true
46525    },
46526    // protocols that never have a hostname.
46527    hostlessProtocol = {
46528      'javascript': true,
46529      'javascript:': true
46530    },
46531    // protocols that always contain a // bit.
46532    slashedProtocol = {
46533      'http': true,
46534      'https': true,
46535      'ftp': true,
46536      'gopher': true,
46537      'file': true,
46538      'http:': true,
46539      'https:': true,
46540      'ftp:': true,
46541      'gopher:': true,
46542      'file:': true
46543    },
46544    querystring = require('querystring');
46545
46546function urlParse(url, parseQueryString, slashesDenoteHost) {
46547  if (url && util.isObject(url) && url instanceof Url) return url;
46548
46549  var u = new Url;
46550  u.parse(url, parseQueryString, slashesDenoteHost);
46551  return u;
46552}
46553
46554Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
46555  if (!util.isString(url)) {
46556    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
46557  }
46558
46559  // Copy chrome, IE, opera backslash-handling behavior.
46560  // Back slashes before the query string get converted to forward slashes
46561  // See: https://code.google.com/p/chromium/issues/detail?id=25916
46562  var queryIndex = url.indexOf('?'),
46563      splitter =
46564          (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
46565      uSplit = url.split(splitter),
46566      slashRegex = /\\/g;
46567  uSplit[0] = uSplit[0].replace(slashRegex, '/');
46568  url = uSplit.join(splitter);
46569
46570  var rest = url;
46571
46572  // trim before proceeding.
46573  // This is to support parse stuff like "  http://foo.com  \n"
46574  rest = rest.trim();
46575
46576  if (!slashesDenoteHost && url.split('#').length === 1) {
46577    // Try fast path regexp
46578    var simplePath = simplePathPattern.exec(rest);
46579    if (simplePath) {
46580      this.path = rest;
46581      this.href = rest;
46582      this.pathname = simplePath[1];
46583      if (simplePath[2]) {
46584        this.search = simplePath[2];
46585        if (parseQueryString) {
46586          this.query = querystring.parse(this.search.substr(1));
46587        } else {
46588          this.query = this.search.substr(1);
46589        }
46590      } else if (parseQueryString) {
46591        this.search = '';
46592        this.query = {};
46593      }
46594      return this;
46595    }
46596  }
46597
46598  var proto = protocolPattern.exec(rest);
46599  if (proto) {
46600    proto = proto[0];
46601    var lowerProto = proto.toLowerCase();
46602    this.protocol = lowerProto;
46603    rest = rest.substr(proto.length);
46604  }
46605
46606  // figure out if it's got a host
46607  // user@server is *always* interpreted as a hostname, and url
46608  // resolution will treat //foo/bar as host=foo,path=bar because that's
46609  // how the browser resolves relative URLs.
46610  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
46611    var slashes = rest.substr(0, 2) === '//';
46612    if (slashes && !(proto && hostlessProtocol[proto])) {
46613      rest = rest.substr(2);
46614      this.slashes = true;
46615    }
46616  }
46617
46618  if (!hostlessProtocol[proto] &&
46619      (slashes || (proto && !slashedProtocol[proto]))) {
46620
46621    // there's a hostname.
46622    // the first instance of /, ?, ;, or # ends the host.
46623    //
46624    // If there is an @ in the hostname, then non-host chars *are* allowed
46625    // to the left of the last @ sign, unless some host-ending character
46626    // comes *before* the @-sign.
46627    // URLs are obnoxious.
46628    //
46629    // ex:
46630    // http://a@b@c/ => user:a@b host:c
46631    // http://a@b?@c => user:a host:c path:/?@c
46632
46633    // v0.12 TODO(isaacs): This is not quite how Chrome does things.
46634    // Review our test case against browsers more comprehensively.
46635
46636    // find the first instance of any hostEndingChars
46637    var hostEnd = -1;
46638    for (var i = 0; i < hostEndingChars.length; i++) {
46639      var hec = rest.indexOf(hostEndingChars[i]);
46640      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
46641        hostEnd = hec;
46642    }
46643
46644    // at this point, either we have an explicit point where the
46645    // auth portion cannot go past, or the last @ char is the decider.
46646    var auth, atSign;
46647    if (hostEnd === -1) {
46648      // atSign can be anywhere.
46649      atSign = rest.lastIndexOf('@');
46650    } else {
46651      // atSign must be in auth portion.
46652      // http://a@b/c@d => host:b auth:a path:/c@d
46653      atSign = rest.lastIndexOf('@', hostEnd);
46654    }
46655
46656    // Now we have a portion which is definitely the auth.
46657    // Pull that off.
46658    if (atSign !== -1) {
46659      auth = rest.slice(0, atSign);
46660      rest = rest.slice(atSign + 1);
46661      this.auth = decodeURIComponent(auth);
46662    }
46663
46664    // the host is the remaining to the left of the first non-host char
46665    hostEnd = -1;
46666    for (var i = 0; i < nonHostChars.length; i++) {
46667      var hec = rest.indexOf(nonHostChars[i]);
46668      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
46669        hostEnd = hec;
46670    }
46671    // if we still have not hit it, then the entire thing is a host.
46672    if (hostEnd === -1)
46673      hostEnd = rest.length;
46674
46675    this.host = rest.slice(0, hostEnd);
46676    rest = rest.slice(hostEnd);
46677
46678    // pull out port.
46679    this.parseHost();
46680
46681    // we've indicated that there is a hostname,
46682    // so even if it's empty, it has to be present.
46683    this.hostname = this.hostname || '';
46684
46685    // if hostname begins with [ and ends with ]
46686    // assume that it's an IPv6 address.
46687    var ipv6Hostname = this.hostname[0] === '[' &&
46688        this.hostname[this.hostname.length - 1] === ']';
46689
46690    // validate a little.
46691    if (!ipv6Hostname) {
46692      var hostparts = this.hostname.split(/\./);
46693      for (var i = 0, l = hostparts.length; i < l; i++) {
46694        var part = hostparts[i];
46695        if (!part) continue;
46696        if (!part.match(hostnamePartPattern)) {
46697          var newpart = '';
46698          for (var j = 0, k = part.length; j < k; j++) {
46699            if (part.charCodeAt(j) > 127) {
46700              // we replace non-ASCII char with a temporary placeholder
46701              // we need this to make sure size of hostname is not
46702              // broken by replacing non-ASCII by nothing
46703              newpart += 'x';
46704            } else {
46705              newpart += part[j];
46706            }
46707          }
46708          // we test again with ASCII char only
46709          if (!newpart.match(hostnamePartPattern)) {
46710            var validParts = hostparts.slice(0, i);
46711            var notHost = hostparts.slice(i + 1);
46712            var bit = part.match(hostnamePartStart);
46713            if (bit) {
46714              validParts.push(bit[1]);
46715              notHost.unshift(bit[2]);
46716            }
46717            if (notHost.length) {
46718              rest = '/' + notHost.join('.') + rest;
46719            }
46720            this.hostname = validParts.join('.');
46721            break;
46722          }
46723        }
46724      }
46725    }
46726
46727    if (this.hostname.length > hostnameMaxLen) {
46728      this.hostname = '';
46729    } else {
46730      // hostnames are always lower case.
46731      this.hostname = this.hostname.toLowerCase();
46732    }
46733
46734    if (!ipv6Hostname) {
46735      // IDNA Support: Returns a punycoded representation of "domain".
46736      // It only converts parts of the domain name that
46737      // have non-ASCII characters, i.e. it doesn't matter if
46738      // you call it with a domain that already is ASCII-only.
46739      this.hostname = punycode.toASCII(this.hostname);
46740    }
46741
46742    var p = this.port ? ':' + this.port : '';
46743    var h = this.hostname || '';
46744    this.host = h + p;
46745    this.href += this.host;
46746
46747    // strip [ and ] from the hostname
46748    // the host field still retains them, though
46749    if (ipv6Hostname) {
46750      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
46751      if (rest[0] !== '/') {
46752        rest = '/' + rest;
46753      }
46754    }
46755  }
46756
46757  // now rest is set to the post-host stuff.
46758  // chop off any delim chars.
46759  if (!unsafeProtocol[lowerProto]) {
46760
46761    // First, make 100% sure that any "autoEscape" chars get
46762    // escaped, even if encodeURIComponent doesn't think they
46763    // need to be.
46764    for (var i = 0, l = autoEscape.length; i < l; i++) {
46765      var ae = autoEscape[i];
46766      if (rest.indexOf(ae) === -1)
46767        continue;
46768      var esc = encodeURIComponent(ae);
46769      if (esc === ae) {
46770        esc = escape(ae);
46771      }
46772      rest = rest.split(ae).join(esc);
46773    }
46774  }
46775
46776
46777  // chop off from the tail first.
46778  var hash = rest.indexOf('#');
46779  if (hash !== -1) {
46780    // got a fragment string.
46781    this.hash = rest.substr(hash);
46782    rest = rest.slice(0, hash);
46783  }
46784  var qm = rest.indexOf('?');
46785  if (qm !== -1) {
46786    this.search = rest.substr(qm);
46787    this.query = rest.substr(qm + 1);
46788    if (parseQueryString) {
46789      this.query = querystring.parse(this.query);
46790    }
46791    rest = rest.slice(0, qm);
46792  } else if (parseQueryString) {
46793    // no query string, but parseQueryString still requested
46794    this.search = '';
46795    this.query = {};
46796  }
46797  if (rest) this.pathname = rest;
46798  if (slashedProtocol[lowerProto] &&
46799      this.hostname && !this.pathname) {
46800    this.pathname = '/';
46801  }
46802
46803  //to support http.request
46804  if (this.pathname || this.search) {
46805    var p = this.pathname || '';
46806    var s = this.search || '';
46807    this.path = p + s;
46808  }
46809
46810  // finally, reconstruct the href based on what has been validated.
46811  this.href = this.format();
46812  return this;
46813};
46814
46815// format a parsed object into a url string
46816function urlFormat(obj) {
46817  // ensure it's an object, and not a string url.
46818  // If it's an obj, this is a no-op.
46819  // this way, you can call url_format() on strings
46820  // to clean up potentially wonky urls.
46821  if (util.isString(obj)) obj = urlParse(obj);
46822  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
46823  return obj.format();
46824}
46825
46826Url.prototype.format = function() {
46827  var auth = this.auth || '';
46828  if (auth) {
46829    auth = encodeURIComponent(auth);
46830    auth = auth.replace(/%3A/i, ':');
46831    auth += '@';
46832  }
46833
46834  var protocol = this.protocol || '',
46835      pathname = this.pathname || '',
46836      hash = this.hash || '',
46837      host = false,
46838      query = '';
46839
46840  if (this.host) {
46841    host = auth + this.host;
46842  } else if (this.hostname) {
46843    host = auth + (this.hostname.indexOf(':') === -1 ?
46844        this.hostname :
46845        '[' + this.hostname + ']');
46846    if (this.port) {
46847      host += ':' + this.port;
46848    }
46849  }
46850
46851  if (this.query &&
46852      util.isObject(this.query) &&
46853      Object.keys(this.query).length) {
46854    query = querystring.stringify(this.query);
46855  }
46856
46857  var search = this.search || (query && ('?' + query)) || '';
46858
46859  if (protocol && protocol.substr(-1) !== ':') protocol += ':';
46860
46861  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
46862  // unless they had them to begin with.
46863  if (this.slashes ||
46864      (!protocol || slashedProtocol[protocol]) && host !== false) {
46865    host = '//' + (host || '');
46866    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
46867  } else if (!host) {
46868    host = '';
46869  }
46870
46871  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
46872  if (search && search.charAt(0) !== '?') search = '?' + search;
46873
46874  pathname = pathname.replace(/[?#]/g, function(match) {
46875    return encodeURIComponent(match);
46876  });
46877  search = search.replace('#', '%23');
46878
46879  return protocol + host + pathname + search + hash;
46880};
46881
46882function urlResolve(source, relative) {
46883  return urlParse(source, false, true).resolve(relative);
46884}
46885
46886Url.prototype.resolve = function(relative) {
46887  return this.resolveObject(urlParse(relative, false, true)).format();
46888};
46889
46890function urlResolveObject(source, relative) {
46891  if (!source) return relative;
46892  return urlParse(source, false, true).resolveObject(relative);
46893}
46894
46895Url.prototype.resolveObject = function(relative) {
46896  if (util.isString(relative)) {
46897    var rel = new Url();
46898    rel.parse(relative, false, true);
46899    relative = rel;
46900  }
46901
46902  var result = new Url();
46903  var tkeys = Object.keys(this);
46904  for (var tk = 0; tk < tkeys.length; tk++) {
46905    var tkey = tkeys[tk];
46906    result[tkey] = this[tkey];
46907  }
46908
46909  // hash is always overridden, no matter what.
46910  // even href="" will remove it.
46911  result.hash = relative.hash;
46912
46913  // if the relative url is empty, then there's nothing left to do here.
46914  if (relative.href === '') {
46915    result.href = result.format();
46916    return result;
46917  }
46918
46919  // hrefs like //foo/bar always cut to the protocol.
46920  if (relative.slashes && !relative.protocol) {
46921    // take everything except the protocol from relative
46922    var rkeys = Object.keys(relative);
46923    for (var rk = 0; rk < rkeys.length; rk++) {
46924      var rkey = rkeys[rk];
46925      if (rkey !== 'protocol')
46926        result[rkey] = relative[rkey];
46927    }
46928
46929    //urlParse appends trailing / to urls like http://www.example.com
46930    if (slashedProtocol[result.protocol] &&
46931        result.hostname && !result.pathname) {
46932      result.path = result.pathname = '/';
46933    }
46934
46935    result.href = result.format();
46936    return result;
46937  }
46938
46939  if (relative.protocol && relative.protocol !== result.protocol) {
46940    // if it's a known url protocol, then changing
46941    // the protocol does weird things
46942    // first, if it's not file:, then we MUST have a host,
46943    // and if there was a path
46944    // to begin with, then we MUST have a path.
46945    // if it is file:, then the host is dropped,
46946    // because that's known to be hostless.
46947    // anything else is assumed to be absolute.
46948    if (!slashedProtocol[relative.protocol]) {
46949      var keys = Object.keys(relative);
46950      for (var v = 0; v < keys.length; v++) {
46951        var k = keys[v];
46952        result[k] = relative[k];
46953      }
46954      result.href = result.format();
46955      return result;
46956    }
46957
46958    result.protocol = relative.protocol;
46959    if (!relative.host && !hostlessProtocol[relative.protocol]) {
46960      var relPath = (relative.pathname || '').split('/');
46961      while (relPath.length && !(relative.host = relPath.shift()));
46962      if (!relative.host) relative.host = '';
46963      if (!relative.hostname) relative.hostname = '';
46964      if (relPath[0] !== '') relPath.unshift('');
46965      if (relPath.length < 2) relPath.unshift('');
46966      result.pathname = relPath.join('/');
46967    } else {
46968      result.pathname = relative.pathname;
46969    }
46970    result.search = relative.search;
46971    result.query = relative.query;
46972    result.host = relative.host || '';
46973    result.auth = relative.auth;
46974    result.hostname = relative.hostname || relative.host;
46975    result.port = relative.port;
46976    // to support http.request
46977    if (result.pathname || result.search) {
46978      var p = result.pathname || '';
46979      var s = result.search || '';
46980      result.path = p + s;
46981    }
46982    result.slashes = result.slashes || relative.slashes;
46983    result.href = result.format();
46984    return result;
46985  }
46986
46987  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
46988      isRelAbs = (
46989          relative.host ||
46990          relative.pathname && relative.pathname.charAt(0) === '/'
46991      ),
46992      mustEndAbs = (isRelAbs || isSourceAbs ||
46993                    (result.host && relative.pathname)),
46994      removeAllDots = mustEndAbs,
46995      srcPath = result.pathname && result.pathname.split('/') || [],
46996      relPath = relative.pathname && relative.pathname.split('/') || [],
46997      psychotic = result.protocol && !slashedProtocol[result.protocol];
46998
46999  // if the url is a non-slashed url, then relative
47000  // links like ../.. should be able
47001  // to crawl up to the hostname, as well.  This is strange.
47002  // result.protocol has already been set by now.
47003  // Later on, put the first path part into the host field.
47004  if (psychotic) {
47005    result.hostname = '';
47006    result.port = null;
47007    if (result.host) {
47008      if (srcPath[0] === '') srcPath[0] = result.host;
47009      else srcPath.unshift(result.host);
47010    }
47011    result.host = '';
47012    if (relative.protocol) {
47013      relative.hostname = null;
47014      relative.port = null;
47015      if (relative.host) {
47016        if (relPath[0] === '') relPath[0] = relative.host;
47017        else relPath.unshift(relative.host);
47018      }
47019      relative.host = null;
47020    }
47021    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
47022  }
47023
47024  if (isRelAbs) {
47025    // it's absolute.
47026    result.host = (relative.host || relative.host === '') ?
47027                  relative.host : result.host;
47028    result.hostname = (relative.hostname || relative.hostname === '') ?
47029                      relative.hostname : result.hostname;
47030    result.search = relative.search;
47031    result.query = relative.query;
47032    srcPath = relPath;
47033    // fall through to the dot-handling below.
47034  } else if (relPath.length) {
47035    // it's relative
47036    // throw away the existing file, and take the new path instead.
47037    if (!srcPath) srcPath = [];
47038    srcPath.pop();
47039    srcPath = srcPath.concat(relPath);
47040    result.search = relative.search;
47041    result.query = relative.query;
47042  } else if (!util.isNullOrUndefined(relative.search)) {
47043    // just pull out the search.
47044    // like href='?foo'.
47045    // Put this after the other two cases because it simplifies the booleans
47046    if (psychotic) {
47047      result.hostname = result.host = srcPath.shift();
47048      //occationaly the auth can get stuck only in host
47049      //this especially happens in cases like
47050      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
47051      var authInHost = result.host && result.host.indexOf('@') > 0 ?
47052                       result.host.split('@') : false;
47053      if (authInHost) {
47054        result.auth = authInHost.shift();
47055        result.host = result.hostname = authInHost.shift();
47056      }
47057    }
47058    result.search = relative.search;
47059    result.query = relative.query;
47060    //to support http.request
47061    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
47062      result.path = (result.pathname ? result.pathname : '') +
47063                    (result.search ? result.search : '');
47064    }
47065    result.href = result.format();
47066    return result;
47067  }
47068
47069  if (!srcPath.length) {
47070    // no path at all.  easy.
47071    // we've already handled the other stuff above.
47072    result.pathname = null;
47073    //to support http.request
47074    if (result.search) {
47075      result.path = '/' + result.search;
47076    } else {
47077      result.path = null;
47078    }
47079    result.href = result.format();
47080    return result;
47081  }
47082
47083  // if a url ENDs in . or .., then it must get a trailing slash.
47084  // however, if it ends in anything else non-slashy,
47085  // then it must NOT get a trailing slash.
47086  var last = srcPath.slice(-1)[0];
47087  var hasTrailingSlash = (
47088      (result.host || relative.host || srcPath.length > 1) &&
47089      (last === '.' || last === '..') || last === '');
47090
47091  // strip single dots, resolve double dots to parent dir
47092  // if the path tries to go above the root, `up` ends up > 0
47093  var up = 0;
47094  for (var i = srcPath.length; i >= 0; i--) {
47095    last = srcPath[i];
47096    if (last === '.') {
47097      srcPath.splice(i, 1);
47098    } else if (last === '..') {
47099      srcPath.splice(i, 1);
47100      up++;
47101    } else if (up) {
47102      srcPath.splice(i, 1);
47103      up--;
47104    }
47105  }
47106
47107  // if the path is allowed to go above the root, restore leading ..s
47108  if (!mustEndAbs && !removeAllDots) {
47109    for (; up--; up) {
47110      srcPath.unshift('..');
47111    }
47112  }
47113
47114  if (mustEndAbs && srcPath[0] !== '' &&
47115      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
47116    srcPath.unshift('');
47117  }
47118
47119  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
47120    srcPath.push('');
47121  }
47122
47123  var isAbsolute = srcPath[0] === '' ||
47124      (srcPath[0] && srcPath[0].charAt(0) === '/');
47125
47126  // put the host back
47127  if (psychotic) {
47128    result.hostname = result.host = isAbsolute ? '' :
47129                                    srcPath.length ? srcPath.shift() : '';
47130    //occationaly the auth can get stuck only in host
47131    //this especially happens in cases like
47132    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
47133    var authInHost = result.host && result.host.indexOf('@') > 0 ?
47134                     result.host.split('@') : false;
47135    if (authInHost) {
47136      result.auth = authInHost.shift();
47137      result.host = result.hostname = authInHost.shift();
47138    }
47139  }
47140
47141  mustEndAbs = mustEndAbs || (result.host && srcPath.length);
47142
47143  if (mustEndAbs && !isAbsolute) {
47144    srcPath.unshift('');
47145  }
47146
47147  if (!srcPath.length) {
47148    result.pathname = null;
47149    result.path = null;
47150  } else {
47151    result.pathname = srcPath.join('/');
47152  }
47153
47154  //to support request.http
47155  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
47156    result.path = (result.pathname ? result.pathname : '') +
47157                  (result.search ? result.search : '');
47158  }
47159  result.auth = relative.auth || result.auth;
47160  result.slashes = result.slashes || relative.slashes;
47161  result.href = result.format();
47162  return result;
47163};
47164
47165Url.prototype.parseHost = function() {
47166  var host = this.host;
47167  var port = portPattern.exec(host);
47168  if (port) {
47169    port = port[0];
47170    if (port !== ':') {
47171      this.port = port.substr(1);
47172    }
47173    host = host.substr(0, host.length - port.length);
47174  }
47175  if (host) this.hostname = host;
47176};
47177
47178},{"./util":
47178148,"punycode":139,"querystring":142}],148:[function(require,module,exports){
47179'use strict';
47180
47181module.exports = {
47182  isString: function(arg) {
47183    return typeof(arg) === 'string';
47184  },
47185  isObject: function(arg) {
47186    return typeof(arg) === 'object' && arg !== null;
47187  },
47188  isNull: function(arg) {
47189    return arg === null;
47190  },
47191  isNullOrUndefined: function(arg) {
47192    return arg == null;
47193  }
47194};
47195
47196},{}]},{},[3]);
47197
47198//# sourceMappingURL=app.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.