PageSourceSearch

https://ikapture.com.au/templates/Skyline_v2/resources/js/browserify.build.js

js ikapture.com.au collected 2026-09-30 16:09:32 UTC 339,258 bytes, 10,733 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){
2var initSitelocation = require('../../common_javascript/initialize-sitelocation');
3var siteLocation = require('@yola/sitelocation');
4var callAsync = require('../../common_javascript/call-async');
5
6require('@yola/mobilemenu');
7
8var initMenu = function() {
9  var els = [
10    document.querySelector('.yola_content_wrap'),
11    document.querySelector('.yola_footer_wrap'),
12    document.querySelector('.yola_banner_wrap'),
13    document.getElementById('sys_yolacredit_wrap'),
14    document.getElementById('yola_heading_block')
15  ];
16
17  var mobileMenuOpen = function(event) {
18    els.forEach(function(el) {
19      if (!el) { return; }
20      el.classList.add('small_device_hide');
21    });
22  };
23
24  var mobileMenuClose = function(event) {
25    els.forEach(function(el) {
26      if (!el) { return; }
27      el.classList.remove('small_device_hide');
28    });
29  };
30
31  $('.mob_menu').mobileMenu({
32    onOpen: mobileMenuOpen,
33    onClose: mobileMenuClose
34  });
35};
36
37/* With all Javascript bundled into one file, javascript is significantly
38 * more brittle, especially given that users have the power to overwrite
39 * globals that could interfere with bundled code. Initializing each component
40 * on its own turn of the event loop should minimize failures to individual
41 * Javascript components, instead of the whole site.
42 */
43callAsync(initMenu);
44callAsync(initSitelocation(siteLocation, 'locationData'));
45
46},{"../../common_javascript/call-async":73,"../../common_javascript/initialize-sitelocation":74,"@yola/mobilemenu":2,"@yola/sitelocation":8}],2:[function(require,module,exports){
47'use strict';
48
49/*
50 * jQuery mobilemenu plugin
51 */
52
53(function ($, window, document, undefined) {
54
55  var pluginName = 'mobileMenu';
56  var subName = 'subMenu';
57  var defaults = {};
58
59  //The plugin constructor
60  function MobileMenu(element, options) {
61    this.$element = $(element);
62    this.options = $.extend({}, defaults, options);
63    this._defaults = defaults;
64    this._name = pluginName;
65    this._onOpen = options.onOpen || $.noop;
66    this._onClose = options.onClose || $.noop;
67    this.init();
68  }
69
70  MobileMenu.prototype.init = function() {
71    var menuToggle = this.menuToggle.bind(this);
72    var subToggle = this.subToggle.bind(this);
73
74    this.$menuToggleBtn = this.$element.find('.mob_menu_toggle');
75    this.$menuToggleBtn.on('click', menuToggle);
76
77    this.$subMenuToggleBtns = this.$element.find('.mob_more_toggle');
78    this.$subMenuToggleBtns.on('click', subToggle);
79
80    this.$subMenuWrappers = this.$element.find('li');
81  };
82
83  MobileMenu.prototype.menuToggle = function(event) {
84    this.$element.toggleClass('menu_open');
85
86    if(! this.$element.hasClass('menu_open')) {
87      this.closeSubMenus();
88      this._onClose(event);
89    } else {
90      this._onOpen(event);
91    }
92  };
93
94  MobileMenu.prototype.subToggle = function(event) {
95    var $buttonClicked = $(event.target);
96    var $subMenu = $buttonClicked.closest('li');
97
98    $subMenu.toggleClass('sub_menu_open');
99    this.closeSubMenus($subMenu);
100  };
101
102  MobileMenu.prototype.closeSubMenus = function(exclude) {
103    if(! exclude) {
104      return this.$subMenuWrappers.removeClass('sub_menu_open');
105    }
106
107    this.$subMenuWrappers.each(function(index) {
108      if(this !== exclude.get(0)) {
109        $(this).removeClass('sub_menu_open');
110      }
111    });
112  };
113
114  $.fn[pluginName] = function(options) {
115    return this.each(function() {
116      if (!$.data(this, 'plugin_' + pluginName)) {
117
118        var pluginInstance = new MobileMenu(this, options);
119        $.data(this, 'plugin_' + pluginName, pluginInstance);
120
121      }
122    });
123  };
124
125})(jQuery, window, document);
126
127},{}],3:[function(require,module,exports){
128module.exports={"cs":{"Address":"Adresa","Call":"Zavolat","Closed":"Zavřeno","Closed all day":"Zavřeno celý den","Closes":"Zavírá","Current Location":"Aktuální pozice","Currently closed":"Momentálně zavřeno","Day":"Den","Friday":"Pátek","Hours":"Hodiny","Map":"Mapa","Monday":"Pondělí","Open now":"Otevřít nyní","Open today from %s to %s":"Dnes otevřeno od %s do %s","Opens":"Otevírá","Phone":"Telefon","Saturday":"Sobota","Sunday":"Neděle","This Week":"Tento týden","Thursday":"Čtvrtek","Today":"Dnes","Today's Hours":"Dnešní otevírací doba","Tuesday":"Úterý","Wednesday":"Středa"},"da":{"Address":"Adresse","Call":"Ring","Closed":"Lukket","Closed all day":"Lukket hele dagen","Closes":"Lukker","Current Location":"Nuværende placering","Currently closed":"Lukket lige nu","Day":"Dag","Friday":"Fredag","Hours":"Åbningstider","Map":"Kort","Monday":"Mandag","Open now":"Åben nu","Open today from %s to %s":"Åben i dag fra %s til %s","Opens":"Åbner","Phone":"Telefon","Saturday":"Lørdag","Sunday":"Søndag","This Week":"Denne uge","Thursday":"Torsdag","Today":"I dag","Today's Hours":"Dagens åbningstider","Tuesday":"Tirsdag","Wednesday":"Onsdag"},"de":{"Address":"Adresse","Call":"Telefon","Closed":"Geschlossen","Closed all day":"Ganztägig geschlossen","Closes":"schließt","Current Location":"aktueller Standort","Currently closed":"derzeit geschlossen","Day":"Wochentag","Friday":"Freitag","Hours":"Öffnungszeiten","Map":"Karte","Monday":"Montag","Open now":"Jetzt geöffnet","Open today from %s to %s":"Heute geöffnet von %s bis %s","Opens":"öffnet","Phone":"Telefon","Saturday":"Samstag","Sunday":"Sonntag","This Week":"diese Woche","Thursday":"Donnerstag","Today":"heute","Today's Hours":"Öffnungszeiten heute","Tuesday":"Dienstag","Wednesday":"Mittwoch"},"es":{"Address":"Dirección","Call":"Llamar","Closed":"Cerrada","Closed all day":"Cerrado todo el día","Closes":"Cierra","Current Location":"Ubicación actual","Currently closed":"Cerrado de momento","Day":"Día","Frid
128ay":"Viernes","Hours":"Horas","Map":"Mapa","Monday":"Lunes","Open now":"Abrir ahora","Open today from %s to %s":"Abrir hoy de %s a %s","Opens":"Abre","Phone":"Teléfono","Saturday":"Sábado","Sunday":"Domingo","This Week":"Esta semana","Thursday":"Jueves","Today":"Hoy","Today's Hours":"Horas para el día de hoy","Tuesday":"Martes","Wednesday":"Miércoles"},"fr":{"Address":"Adresse","Call":"Appel","Closed":"Fermé","Closed all day":"Fermé toute la journée","Closes":"Ferme","Current Location":"Emplacement actuel","Currently closed":"Actuellement fermé","Day":"Jour","Friday":"Vendredi","Hours":"Heures","Map":"Carte","Monday":"Lundi","Open now":"Ouvert maintenant","Open today from %s to %s":"Ouvert aujourd'hui de %s à %s","Opens":"Ouvre","Phone":"Téléphone","Saturday":"Samedi","Sunday":"Dimanche","This Week":"Cette semaine","Thursday":"Jeudi","Today":"Aujourd'hui","Today's Hours":"Heures du Jour","Tuesday":"Mardi","Wednesday":"Mercredi"},"hu":{"Address":"Cím","Call":"Hívás","Closed":"Zárva","Closed all day":"Egész nap zárva","Closes":"Bezár","Current Location":"Jelenlegi hely","Currently closed":"Jelenleg zárva","Day":"Nap","Friday":"Péntek","Hours":"Órák","Map":"Térkép","Monday":"Hétfő","Open now":"Most nyitva","Open today from %s to %s":"Mai napon nyitva %s-tól %s-ig","Opens":"Nyit","Phone":"Telefon","Saturday":"Szombat","Sunday":"Vasárnap","This Week":"Ezen a héten","Thursday":"Csütörtök","Today":"Ma","Today's Hours":"Mai órák","Tuesday":"Kedd","Wednesday":"Szerda"},"id":{"Address":"Alamat","Call":"Telepon","Closed":"Tutup","Closed all day":"Tutup sepanjang hari","Closes":"Menutup","Current Location":"Lokasi saat ini","Currently closed":"Saat ini tutup","Day":"Hari","Friday":"Jumat","Hours":"Jam","Map":"Peta","Monday":"Senin","Open now":"Buka sekarang","Open today from %s to %s":"Hari ini buka dari %s sampai %s","Opens":"Buka","Phone":"Telepon","Saturday":"Sabtu","Sunday":"Hari Minggu","This Week":"Minggu ini","Thursday":"Kamis","Today":"Hari ini","Today's Hours":"Jam hari ini","Tuesday":"Selasa","Wednesday":"Hari Rabu"},"it":{"Address":"indirizzo","Call":"Chiamata","Closed":"Chiuso","Closed all day":"Chiuso tutto il giorno","Closes":"Chiude","Current Location":"Indirizzo attuale","Currently closed":"Attualmente chiuso","Day":"Giorno","Friday":"Venerdi'","Hours":"Ore","Map":"Mappa","Monday":"Lunedi'","Open now":"Aperto adesso","Open today from %s to %s":"aperto oggi dalle %s alle %s","Opens":"Apre","Phone":"Telefono","Saturday":"Sabato","Sunday":"Domenica","This Week":"Questa settimana","Thursday":"Giovedi'","Today":"Oggi","Today's Hours":"Ore di oggi","Tuesday":"Martedi'","Wednesday":"Mercoledi'"},"ja":{"Address":"アドレス","Call":"電話","Closed":"閉鎖","Closed all day":"閉店日","Closes":"閉店","Current Location":"現在地","Currently closed":"現在、閉じています","Day":"曜日","Friday":"金曜日","Hours":"時","Map":"地図","Monday":"月曜日","Open now":"現在、開いています","Open today from %s to %s":"本日、%s時から%s時までオープン","Opens":"開店","Phone":"電話","Saturday":"土曜日","Sunday":"日曜日","This Week":"今週","Thursday":"木曜日","Today":"今日","Today's Hours":"今日の就業時間","Tuesday":"火曜日","Wednesday":"水曜日"},"nb":{"Address":"Adresse","Call":"Ring","Closed":"Stengt","Closed all day":"Stengt hele dagen","Closes":"Stenger","Current Location":"Nåværende posisjon","Currently closed":"For øyeblikket lukket","Day":"Dag","Friday":"Fredag","Hours":"Timer","Map":"Kart","Monday":"Mandag","Open now":"Åpen nå","Open today from %s to %s":"Åpen i dag fra %s til %s","Opens":"Åpner","Phone":"Telefon","Saturday":"Lørdag","Sunday":"Søndag","This Week":"Denne uken","Thursday":"Torsdag","Today":"I dag","Today's Hours":"Dagens åpningstider","Tuesday":"Tirsdag","Wednesday":"Onsdag"},"nl":{"Address":"Adres","Call":"Bel","Closed":"Gesloten","Closed all day":"De hele dag gesloten","Closes":"Sluit","Current Location":"Huidige locatie","Currently closed":"Momenteel gesloten","Day":"Dag","Friday":"Vrijdag","Hours":"Uren","Map":"Kaart","Monday":"Maandag","Open now":"Nu open","Open today from %s to %s":"Vandaag open van %s tot %s","Opens":"Opent","Phone":"Telefoon","Saturday":"Zaterdag","Sunday":"Zondag","This Week":"Deze Week","Thursday":"Donderdag","Today":"Vandaag","Today's Hours":"Uren van vandaag","Tuesday":"Dinsdag","Wednesday":"Woensdag"},"pl":{"Address":"Adres","Call":"Połączenie","Closed":"Zamknięty","Closed all day":"Zamknięte przez cały dzień","Closes":"Zamyka","Current Location":"Aktualna lokalizacja","Currently closed":"Aktualnie zamknięte","Day":"Dzień","Friday":"Piątek","Hours":"Godziny","Map":"Mapa","Monday":"Poniedziałek","Open now":"Otwarte teraz","Open today from %s to %s":"Otwarte dzisiaj od %s do %s","Opens":"Otwiera","Phone":"Nr telefonu","Saturday":"Sobota","Sunday":"Niedziela","This Week":"W tym tygodniu","Thursday":"Czwartek","Today":"Dzisiaj","Today's Hours":"Dzisiejsze godziny","Tuesday":"Wtorek","Wednesday":"Środa"},"pt_BR":{"Address":"Endereço","Call":"Ligar","Closed":"Fechado","Closed all day":"Fechado durante todo o dia","Closes":"Fecha","Current Location":"Localização Atual","Currently closed":"Atualmente fechado","Day":"Dia","Friday":"Sexta-feira","Hours":"Horas","Map":"Mapa","Monday":"Segunda-feira","Open now":"Aberto agora","Open today from %s to %s":"Aberto hoje das %s as %s","Opens":"Abre","Phone":"Telefone","Saturday":"Sábado","Sunday":"Domingo","This Week":"Esta Semana","Thursday":"Quinta-feira","Today":"Hoje","Today's Hours":"Horário de Hoje","Tuesday":"Terça-feira","Wednesday":"Quarta-feira"},"ru":{"Address":"Адрес","Call":"Звонок","Closed":"Закрыто","Closed all day":"Закрыто весь день","Closes":"Закрывается","Current Location":"Нынешнее Местонахождение","Currently closed":"В данный момент закрыт","Day":"День","Frid
128ay":"Пятница","Hours":"Часы","Map":"Карта","Monday":"Понедельник","Open now":"Открыть сейчас","Open today from %s to %s":"Открыто сегодня с %s до %s","Opens":"Открывается","Phone":"Телефон","Saturday":"Суббота","Sunday":"Воскресенье","This Week":"На этой неделе","Thursday":"Четверг","Today":"Сегодня","Today's Hours":"Рабочие часы сегодня","Tuesday":"Вторник","Wednesday":"Среда"},"sk":{"Address":"Adresa","Call":"Zavolať","Closed":"Zavreté","Closed all day":"Zavreté celý deň","Closes":"Zaviera sa","Current Location":"Aktuálna poloha","Currently closed":"Momentálne uzavreté","Day":"Deň","Friday":"Piatok","Hours":"Hodín","Map":"Mapa","Monday":"Pondelok","Open now":"Teraz otvorené","Open today from %s to %s":"Dnes otvorené od %s do %s","Opens":"Otvára sa","Phone":"Telefón","Saturday":"Sobota","Sunday":"Nedeľa","This Week":"Tento týždeň","Thursday":"Štvrtok","Today":"Dnes","Today's Hours":"Dnešný hodiny","Tuesday":"Utorok","Wednesday":"Streda"},"sv":{"Address":"Adress","Call":"Ring","Closed":"Stängd","Closed all day":"Stängt hela dagen","Closes":"Stänger","Current Location":"Nuvarande plats","Currently closed":"Stängt för närvarande","Day":"Dag","Friday":"Fredag","Hours":"Timmar","Map":"Karta","Monday":"Måndag","Open now":"Öppna nu","Open today from %s to %s":"Öppet idag från %s till %s","Opens":"Öppnar","Phone":"Telefon","Saturday":"Lördag","Sunday":"Söndag","This Week":"Den här veckan","Thursday":"Torsdag","Today":"Idag","Today's Hours":"Dagens timmar","Tuesday":"Tisdag","Wednesday":"Onsdag"},"zh_CN":{"Address":"地址","Call":"拨打","Closed":"已关闭","Closed all day":"全天关闭","Closes":"关闭","Current Location":"当前位置","Currently closed":"当前已关闭","Day":"天","Friday":"星期五","Hours":"营业时间","Map":"地图","Monday":"星期一","Open now":"现在打开","Open today from %s to %s":"今天从 %s 到 %s打开","Opens":"打开","Phone":"电话","Saturday":"星期六","Sunday":"星期日","This Week":"本周","Thursday":"星期四","Today":"今天","Today's Hours":"今天的小时数","Tuesday":"星期二","Wednesday":"星期三"}}
129},{}],4:[function(require,module,exports){
130'use strict';
131
132
133var canonicalize = function(phoneNumber) {
134  if(! phoneNumber) {
135    return null;
136  }
137
138  var canonicalPhone;
139  var phoneString = '' + phoneNumber;
140  var match = /^\+?[0-9()\-\s.]+$/.exec(phoneString);
141
142  if(match === null) {
143    console.error('Found invalid characters in phone number: ' + phoneString);
144
145    return null;
146  }
147
148  canonicalPhone = phoneString.replace(/[()\-\s.]+/g, '');
149
150  if(canonicalPhone[0] === '+') {
151    return canonicalPhone;
152  }
153
154  if(canonicalPhone.length === 10) {
155    return '+1' + canonicalPhone;
156  }
157
158  if(canonicalPhone.length === 11 && canonicalPhone[0] === '1') {
159    return '+' + canonicalPhone;
160  }
161
162  return canonicalPhone;
163};
164
165module.exports = canonicalize;
166
167},{}],5:[function(require,module,exports){
168'use strict';
169
170var cards = [];
171
172var counter = {
173  getCards: function() {
174    return cards;
175  },
176
177  register: function(card) {
178    cards.push(card);
179    this.positionCards();
180  },
181
182  unregister: function(card) {
183    var cardIndex = cards.indexOf(card);
184    cards.splice(cardIndex, 1);
185    this.positionCards();
186  },
187
188  /* This function is responsible for vertically positioning
189   * stacked cards. The first card in the cards array will
190   * be positioned at the top, and the second below it and
191   * so on.
192   */
193  positionCards: function() {
194    var cardEl;
195    var cardHeight;
196    var spacing = 15;
197    var verticalSpacing = 0;
198
199    for(var i = 0; i < cards.length; i++) {
200      cardEl = cards[i].getCardEl();
201      cardHeight = cards[i].getCardHeight();
202      cardHeight += spacing;
203
204      cardEl.style.top = (verticalSpacing + spacing) + 'px';
205      verticalSpacing += cardHeight;
206    }
207  }
208};
209
210module.exports = counter;
211
212},{}],6:[function(require,module,exports){
213'use strict';
214
215var siteData = require('./site-data');
216var transCatalog = require('../i18n-catalog.json');
217var Handlebars = require('hbsfy/runtime');
218
219
220var trans = function(text) {
221  var locale = siteData.getLocale() || '';
222
223  if (! locale) {
224    return text;
225  }
226
227  if (! transCatalog[locale]) {
228    setTimeout(function() {
229      throw new Error('Locale does not exist: ' + locale);
230    });
231
232    return text;
233  }
234
235  if(! transCatalog[locale][text]) {
236    return text;
237  }
238
239  return transCatalog[locale][text];
240};
241
242Handlebars.registerHelper('trans', trans);
243
244module.exports = trans;
245
246},{"../i18n-catalog.json":3,"./site-data":13,"hbsfy/runtime":42}],7:[function(require,module,exports){
247'use strict';
248
249var gettext = require('./gettext');
250var sprintf = require('sprintf-js').sprintf;
251var todaysHoursHTML = require('./templates/today-hours.hbs');
252var weekHTML = require('./templates/hours-table.hbs');
253require('date-utils');
254
255var hoursRenderer = {
256  days: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
257  formatTime: function(time) {
258    var formattedTime = '';
259    var timeSplat = time.split(':');
260    var hourDigit = Number(timeSplat[0]);
261    var isPm = hourDigit >= 12;
262
263    if(hourDigit > 12) {
264      hourDigit -= 12;
265    } else if (hourDigit === 0) {
266      hourDigit = 12;
267    }
268
269    formattedTime = hourDigit + ':' + timeSplat[1];
270
271    formattedTime += isPm ? ' pm' : ' am';
272
273    return formattedTime;
274  },
275
276  today: function(hours) {
277    var date = new Date();
278    var day = date.toFormat('DDD').substring(0,2);
279    var todaysHours = hours[day];
280
281    if(! todaysHours) {
282      return;
283    }
284
285    var openTime = this.formatTime(todaysHours.open);
286    var closeTime = this.formatTime(todaysHours.close);
287
288    return {
289      open: openTime,
290      close: closeTime
291    };
292  },
293
294  openToday: function(hours) {
295    var openStatus;
296    var todaysHours = this.today(hours);
297
298    if(! todaysHours) {
299      return sprintf(gettext('Closed all day'));
300    }
301
302    openStatus = gettext('Open today from %s to %s');
303    return sprintf(openStatus, todaysHours.open, todaysHours.close);
304  },
305
306  isOpenNow: function(now, hours) {
307    var today = this.days[now.getDay()];
308    var todaysHours = hours[today];
309
310    if (! todaysHours) {
311      return false;
312    }
313
314    var openSplat = todaysHours.open.split(':');
315    var closeSplat = todaysHours.close.split(':');
316
317    var openDate = new Date(
318      now.getFullYear(),
319      now.getMonth(),
320      now.getDate(),
321      Number(openSplat[0]),
322      Number(openSplat[1])
323    );
324
325    var closeDate = new Date(
326      now.getFullYear(),
327      now.getMonth(),
328      now.getDate(),
329      Number(closeSplat[0]),
330      Number(closeSplat[1])
331    );
332
333    return now > openDate && now < closeDate;
334  },
335
336  week: function(hours) {
337    var now = new Date();
338    var wrapper = document.createElement('div');
339    var todaysHours = this.today(hours);
340    var isOpenNow = this.isOpenNow(now, hours);
341    var dayRow, openEl, closeEl, openNowEl, openNowMsg, openCloseClass, todayEl;
342    var todayElContext;
343    var injectDay = function(day) {
344      dayRow = wrapper.querySelector('.' + day);
345      openEl = dayRow.querySelector('td:nth-child(2)');
346      closeEl = dayRow.querySelector('td:nth-child(3)');
347
348      if(! hours[day]) {
349        openEl.innerHTML = gettext('Closed');
350        return;
351      }
352
353      openEl.innerHTML = this.formatTime(hours[day].open);
354      closeEl.innerHTML = this.formatTime(hours[day].close);
355    };
356
357    wrapper.innerHTML = weekHTML();
358
359    this.days.forEach(injectDay.bind(this));
360
361    todayEl = wrapper.querySelector('.today');
362
363    todayElContext = {
364      hasHours: todaysHours,
365      opens: todaysHours && todaysHours.open,
366      closes: todaysHours && todaysHours.close
367    };
368
369    todayEl.innerHTML = todaysHoursHTML(todayElContext);
370    openNowEl = wrapper.querySelector('.now');
371
372    openCloseClass = isOpenNow ? 'open' : 'closed';
373    openNowMsg = isOpenNow ? gettext('Open now') : gettext('Currently closed');
374
375    openNowEl.innerHTML = openNowMsg;
376    openNowEl.classList.add(openCloseClass);
377    return wrapper;
378  }
379};
380
381module.exports = hoursRenderer;
382
383},{"./gettext":6,"./templates/hours-table.hbs":16,"./templates/today-hours.hbs":22,"date-utils":39,"sprintf-js":72}],8:[function(require,module,exports){
384'use strict';
385
386require('./gettext');
387
388var Router = require('./router');
389var setupMessaging = require('./messaging');
390
391
392require('date-utils');
393require('classlist-polyfill');
394
395setupMessaging(Router);
396
397module.exports = {
398  initialize: Router.initInstance
399};
400
401},{"./gettext":6,"./messaging":9,"./router":12,"classlist-polyfill":38,"date-utils":39}],9:[function(require,module,exports){
402'use strict';
403
404var windowManager = require('./window-manager');
405
406
407var initializeMessageListening = function(router) {
408  var topWindow = windowManager.get('top');
409
410  var receiveMessage = function(event) {
411    var parentOrigin = topWindow.location.origin;
412
413    if (event.origin !== parentOrigin) {
414      console.log('Message from an unknown source: ', event.origin);
415      return;
416    }
417
418    if (typeof event.data !== 'object') {
419      console.log('Message has no event.data property');
420      return;
421    }
422
423    router.forceInit(event.data);
424  };
425
426  windowManager.get().addEventListener('message', receiveMessage);
427};
428
429module.exports = initializeMessageListening;
430
431}
431,{"./window-manager":32}],10:[function(require,module,exports){
432'use strict';
433
434/* Hideable is a mixin for objects that can be shown  and hidden
435 * from view.
436 */
437
438var hideable = {
439  hide: function(cb, timeout) {
440    var displayNone = function() {
441      this[this.contentName].classList.add('hide');
442      this[this.contentName].classList.remove('open');
443      if(typeof cb === 'function') {
444        cb();
445      }
446    };
447
448    if(timeout === undefined) {
449      timeout = 400;
450    }
451
452    if(this.noscroll) {
453      this.removeNoScroll();
454    }
455
456    this[this.contentName].classList.remove(this.transIn || '');
457    this[this.contentName].classList.add(this.transOut || '');
458    setTimeout(displayNone.bind(this), timeout);
459  },
460
461  show: function() {
462    if(this.noscroll) {
463      this.addNoScroll();
464    }
465
466    this[this.contentName].classList.add('open');
467    this[this.contentName].classList.remove('hide');
468    this[this.contentName].classList.add(this.transIn || '');
469    this[this.contentName].classList.remove(this.transOut || '');
470  },
471
472  addNoScroll: function() {
473    document.body.classList.add('noscroll');
474  },
475
476  removeNoScroll: function() {
477    document.body.classList.remove('noscroll');
478  }
479};
480
481module.exports = hideable;
482
483},{}],11:[function(require,module,exports){
484'use strict';
485
486
487var renderable = {
488  render: function(cb) {
489    if(! this.isRendered) {
490      this[this.wrapperName].appendChild(this[this.contentName]);
491    }
492
493    if(typeof this.onRender === 'function') {
494      this.onRender(cb);
495    }
496
497    this.isRendered = true;
498  },
499
500  remove: function() {
501    if(this.isRendered) {
502      this[this.wrapperName].removeChild(this[this.contentName]);
503    }
504
505    if(typeof this.onRemove === 'function') {
506      this.onRemove();
507    }
508
509    this.isRendered = false;
510  }
511};
512
513module.exports = renderable;
514
515},{}],12:[function(require,module,exports){
516'use strict';
517
518var AmpersandRouter = require('ampersand-router');
519var PageView = require('./views/page');
520var siteData = require('./site-data');
521
522
523var SiteLocationRouter = AmpersandRouter.extend({
524  routes: {
525    'toolbar': 'toolbar',
526    'exit': 'exit',
527    'toolbar/map': 'map',
528    'toolbar/hours': 'hours'
529  },
530
531  initialize: function() {
532    this.pageView = new PageView();
533  },
534
535  toolbar: function() {
536    this.pageView.renderToolbar();
537  },
538
539  exit: function() {
540    this.pageView.removeAll();
541
542    this.navigate('', {replace: true});
543  },
544
545  map: function() {
546    this.pageView.renderMap();
547  },
548
549  hours: function() {
550    this.pageView.renderHours();
551  },
552
553  tearDown: function() {
554    var navOpts = {
555      trigger: true,
556      replace: true
557    };
558
559    this.navigate('exit', navOpts);
560
561    this.pageView.removeAll();
562    this.pageView.removeActionButton();
563  }
564});
565
566SiteLocationRouter.initInstance = function(data) {
567  if(SiteLocationRouter.instance) {
568    console.info('Sitelocation already instantiated.');
569    return;
570  }
571
572  siteData.set(data);
573
574  if(! PageView.shouldRender()) {
575    console.info('No data for sitelocation to render.');
576    return;
577  }
578
579  var router = new SiteLocationRouter();
580
581  if(! router.history.started()) {
582    router.history.start({ pushState: false });
583  }
584
585  SiteLocationRouter.instance = router;
586
587  return router;
588};
589
590SiteLocationRouter.forceInit = function(data) {
591  var route = data.route || 'exit';
592  var navOpts = {
593    trigger: true,
594    replace: true
595  };
596
597  delete data.route;
598
599  if(this.instance) {
600    this.instance.tearDown();
601    delete this.instance;
602  }
603
604  this.initInstance(data);
605
606  if(this.instance) {
607    this.instance.navigate(route, navOpts);
608  }
609};
610
611module.exports = SiteLocationRouter;
612
613},{"./site-data":13,"./views/page":30,"ampersand-router":36}],13:[function(require,module,exports){
614'use strict';
615
616
617var siteData = {
618  data: {},
619
620  set: function(key, value) {
621    if(typeof key === 'object') {
622      this.data = key;
623    }
624
625    this.data[key] = value;
626  },
627
628  get: function(key) {
629    if (key === 'locale') {
630      return this.getLocale();
631    }
632
633    return this.data[key];
634  },
635
636  getLocale: function() {
637    var langSplat;
638    var lang = this.get('lang') || '';
639
640    if(lang === 'en') {
641      return '';
642    }
643
644    if (lang.length !== 5) {
645      return lang;
646    }
647
648    langSplat = lang.split('-');
649
650    return langSplat[0].toLowerCase() + '_' + langSplat[1].toUpperCase();
651  }
652};
653
654module.exports = siteData;
655
656},{}],14:[function(require,module,exports){
657// hbsfy compiled Handlebars template
658var HandlebarsCompiler = require('hbsfy/runtime');
659module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
660    return "<div class=\"title\">"
661    + container.escapeExpression((helpers.trans || (depth0 && depth0.trans) || helpers.helperMissing).call(
661depth0 != null ? depth0 : (container.nullContext || {}),"Address",{"name":"trans","hash":{},"data":data}))
662    + ":</div>\n<address>\n  <div class=\"line-one\"></div>\n  <div class=\"line-two\"></div>\n</address>\n";
663},"useData":true});
664
665},{"hbsfy/runtime":42}],15:[function(require,module,exports){
666// hbsfy compiled Handlebars template
667var HandlebarsCompiler = require('hbsfy/runtime');
668module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
669    return "<div class=\"title\">"
670    + container.escapeExpression((helpers.trans || (depth0 && depth0.trans) || helpers.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"Today's Hours",{"name":"trans","hash":{},"data":data}))
671    + ":</div>\n<div class=\"hours\"></div>\n";
672},"useData":true});
673
674},{"hbsfy/runtime":42}],16:[function(require,module,exports){
675// hbsfy compiled Handlebars template
676var HandlebarsCompiler = require('hbsfy/runtime');
677module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
678    var alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3=container.escapeExpression;
679
680  return "<h2>"
681    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Hours",{"name":"trans","hash":{},"data":data}))
682    + "</h2>\n\n<h3>"
683    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Today",{"name":"trans","hash":{},"data":data}))
684    + "</h3>\n\n<div class=\"today\"></div>\n\n<h3>"
685    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"This Week",{"name":"trans","hash":{},"data":data}))
686    + "</h3>\n\n<table>\n  <thead>\n    <tr>\n      <th>"
687    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Day",{"name":"trans","hash":{},"data":data}))
688    + "</th>\n      <th>"
689    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Opens",{"name":"trans","hash":{},"data":data}))
690    + "</th>\n      <th>"
691    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Closes",{"name":"trans","hash":{},"data":data}))
692    + "</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr class=\"Su\">\n      <td>"
693    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Sunday",{"name":"trans","hash":{},"data":data}))
694    + "</td>\n      <td></td>\n      <td></td>\n    </tr>\n    <tr class=\"Mo\">\n      <td>"
695    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Monday",{"name":"trans","hash":{},"data":data}))
696    + "</td>\n      <td></td>\n      <td></td>\n    </tr>\n    <tr class=\"Tu\">\n      <td>"
697    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Tuesday",{"name":"trans","hash":{},"data":data}))
698    + "</td>\n      <td></td>\n      <td></td>\n    </tr>\n    <tr class=\"We\">\n      <td>"
699    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Wednesday",{"name":"trans","hash":{},"data":data}))
700    + "</td>\n      <td></td>\n      <td></td>\n    </tr>\n    <tr class=\"Th\">\n      <td>"
701    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Thursday",{"name":"trans","hash":{},"data":data}))
702    + "</td>\n      <td></td>\n      <td></td>\n    </tr>\n    <tr class=\"Fr\">\n      <td>"
703    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Friday",{"name":"trans","hash":{},"data":data}))
704    + "</td>\n      <td></td>\n      <td></td>\n    </tr>\n    <tr class=\"Sa\">\n      <td>"
705    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Saturday",{"name":"trans","hash":{},"data":data}))
706    + "</td>\n      <td></td>\n      <td></td>\n    </tr>\n  </tbody>\n</table>\n";
707},"useData":true});
708
709},{"hbsfy/runtime":42}],17:[function(require,module,exports){
710// hbsfy compiled Handlebars template
711var HandlebarsCompiler = require('hbsfy/runtime');
712module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
713    return "<input class=\"animated\" placeholder=\""
714    + container.escapeExpression((helpers.trans || (depth0 && depth0.trans) || helpers.helperMissing).call(
714depth0 != null ? depth0 : (container.nullContext || {}),"Current Location",{"name":"trans","hash":{},"data":data}))
715    + "\">\n<div class=\"transport-toggle\">\n  <button class=\"walk-icon\" data-mode=\"walking\">\n    <svg id=\"walk-icon\" x=\"0px\" y=\"0px\" width=\"25px\" height=\"25px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\">\n      <path d=\"M48.947,11.08c0-3.972-3.111-7.08-7.081-7.08c-3.974,0-7.082,3.108-7.082,7.08  c0,3.971,3.108,7.082,7.082,7.082C45.835,18.162,48.947,15.051,48.947,11.08z\"/>\n      <path d=\"M71.465,30.522c0,0-8.447-4.743-12.188-6.708c-3.744-1.97-11.175-7.06-17.801-1.17  C38.467,25.319,35,39,35,39l-14,8.634l2.299,3.204l15.251-5.544l4.262-5.516l4.513,9.945l-9.109,15.962l-7.188,26.828l7.438,2.508  l8.357-25.072l6.185-6.102l13.539,32.01l6.52-3.01L62.119,53.902c0,0,1.365-2.799,1.365-7.254c0-5.11-4.039-13.473-4.039-13.473  l6.611,1.518l1.48,16.639l4.162,0.391L71.465,30.522z\"/>\n    </svg>\n  </button>\n  <button class=\"drive-icon selected\" data-mode=\"driving\">\n    <svg id=\"drive-icon\" x=\"0px\" y=\"0px\" width=\"25px\" height=\"20px\" viewBox=\"0 0 100 83.648\" enable-background=\"new 0 0 100 83.648\" xml:space=\"preserve\">\n      <path d=\"M15.727,43.753\"/>\n      <path d=\"M90.925,28.696L82.728,7.529C81.195,3.477,77.845,0.029,71.505,0h-11.56H40.188H28.427\n        c-6.311,0.029-9.661,3.477-11.222,7.529L9.006,28.696C5.751,29.116-0.01,32.941,0,40.187v26.951h7.999v8.603\n        c-0.02,10.606,14.989,10.48,14.985,0v-8.603H50h26.948v8.603c0.033,10.48,15.042,10.606,15.052,0v-8.603h8V40.187\n        C99.975,32.941,94.21,29.116,90.925,28.696z M15.727,50.874c-3.834,0.011-6.938-3.187-6.922-7.12\n        c-0.016-3.96,3.088-7.161,6.922-7.128c3.822-0.033,6.926,3.168,6.921,7.128C22.653,47.687,19.548,50.884,15.727,50.874z M50,28.497\n        h-0.067H17.541l6.182-16.668c0.746-2.366,1.904-4.059,4.639-4.1h21.571H50H71.64c2.693,0.041,3.854,1.733,4.636,4.1l6.183,16.668H50\n        z M84.274,50.874c-3.861,0.011-6.967-3.187-6.988-7.12c0.021-3.96,3.127-7.161,6.988-7.128c3.795-0.033,6.898,3.168,6.922,7.128\n        C91.172,47.687,88.069,50.884,84.274,50.874z\"/>\n      <path d=\"M84.274,43.753\"/>\n    </svg>\n  </button>\n</div>\n";
716},"useData":true});
717
718},{"hbsfy/runtime":42}],18:[function(require,module,exports){
719// hbsfy compiled Handlebars template
720var HandlebarsCompiler = require('hbsfy/runtime');
721module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
722    var helper;
723
724  return "<iframe\n  frameborder=\"0\"\n  style=\"border:0;width:100%;height:100%;\"\n  src=\""
725    + container.escapeExpression(((helper = (helper = helpers.mapSource || (depth0 != null ? depth0.mapSource : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"mapSource","hash":{},"data":data}) : helper)))
726    + "\"\n  allowfullscreen>\n</iframe>\n";
727},"useData":true});
728
729},{"hbsfy/runtime":42}],19:[function(require,module,exports){
730// hbsfy compiled Handlebars template
731var HandlebarsCompiler = require('hbsfy/runtime');
732module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
733    var alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3=container.escapeExpression;
734
735  return "<div>\n  <a id=\"location-tools-phone\" class=\"phone hide\" href=\"\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" id=\"Capa_1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 578.106 578.106\" style=\"enable-background:new 0 0 578.106 578.106;\" xml:space=\"preserve\">\n      <g>\n        <path d=\"M577.83,456.128c1.225,9.385-1.635,17.545-8.568,24.48l-81.396,80.781    c-3.672,4.08-8.465,7.551-14.381,10.404c-5.916,2.857-11.729,4.693-17.439,5.508c-0.408,0-1.635,0.105-3.676,0.309    c-2.037,0.203-4.689,0.307-7.953,0.307c-7.754,0-20.301-1.326-37.641-3.979s-38.555-9.182-63.645-19.584    c-25.096-10.404-53.553-26.012-85.376-46.818c-31.823-20.805-65.688-49.367-101.592-85.68    c-28.56-28.152-52.224-55.08-70.992-80.783c-18.768-25.705-33.864-49.471-45.288-71.299    c-11.425-21.828-19.993-41.616-25.705-59.364S4.59,177.362,2.55,164.51s-2.856-22.95-2.448-30.294    c0.408-7.344,0.612-11.424,0.612-12.24c0.816-5.712,2.652-11.526,5.508-17.442s6.324-10.71,10.404-14.382L98.022,8.756    c5.712-5.712,12.24-8.568,19.584-8.568c5.304,0,9.996,1.53,14.076,4.59s7.548,6.834,10.404,11.322l65.484,124.236    c3.672,6.528,4.692,13.668,3.06,21.42c-1.632,7.752-5.1,14.28-10.404,19.584l-29.988,29.988c-0.816,0.816-1.53,2.142-2.142,3.978    s-0.918,3.366-0.918,4.59c1.632,8.568,5.304,18.36,11.
735016,29.376c4.896,9.792,12.444,21.726,22.644,35.802    s24.684,30.293,43.452,48.653c18.36,18.77,34.68,33.354,48.96,43.76c14.277,10.4,26.215,18.053,35.803,22.949    c9.588,4.896,16.932,7.854,22.031,8.871l7.648,1.531c0.816,0,2.145-0.307,3.979-0.918c1.836-0.613,3.162-1.326,3.979-2.143    l34.883-35.496c7.348-6.527,15.912-9.791,25.705-9.791c6.938,0,12.443,1.223,16.523,3.672h0.611l118.115,69.768    C571.098,441.238,576.197,447.968,577.83,456.128z\"/>\n      </g>\n    </svg>\n\n    "
736    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Call",{"name":"trans","hash":{},"data":data}))
737    + "\n  </a>\n  <a id=\"location-tools-location\" class=\"map hide\" href=\"#toolbar/map\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" id=\"Capa_1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 51.114 51.114\" style=\"enable-background:new 0 0 51.114 51.114;\" xml:space=\"preserve\">\n      <g>\n        <path d=\"M41.945,16.388C41.943,7.337,34.609,0,25.56,0C16.507,0,9.169,7.337,9.169,16.388    c0,7.812,12.208,28.683,15.553,34.251c0.176,0.295,0.494,0.475,0.837,0.475c0.343,0,0.662-0.18,0.836-0.474    C29.738,45.072,41.945,24.2,41.945,16.388z M25.559,29.068c-6.991,0-12.683-5.688-12.683-12.681    c0-6.992,5.69-12.681,12.683-12.681s12.679,5.689,12.679,12.681C38.238,23.379,32.551,29.068,25.559,29.068z\"/>\n      </g>\n    </svg>\n\n    "
738    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Map",{"name":"trans","hash":{},"data":data}))
739    + "\n  </a>\n  <a id=\"location-tools-hours\" class=\"hours hide\" href=\"#toolbar/hours\">\n    <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" id=\"Capa_1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 612 612\" style=\"enable-background:new 0 0 612 612;\" xml:space=\"preserve\">\n      <g id=\"clock\">\n        <path d=\"M306,0C136.992,0,0,136.992,0,306s136.992,306,306,306s306-137.012,306-306S475.008,0,306,0z M306,573.157     C158.451,573.157,38.843,453.55,38.843,306C38.843,158.451,158.451,38.843,306,38.843c147.55,0,267.157,119.608,267.157,267.157     C573.157,453.55,453.55,573.157,306,573.157z M325.125,115.955h-37.657l0.593,209.782l132.077,112.952l23.313-32.876     l-118.326-99.221V115.955z\"/>\n      </g>\n    </svg>\n\n    "
740    + alias3((helpers.trans || (depth0 && depth0.trans) || alias2).call(alias1,"Hours",{"name":"trans","hash":{},"data":data}))
741    + "\n  </a>\n</div>\n";
742},"useData":true});
743
744},{"hbsfy/runtime":42}],20:[function(require,module,exports){
745// hbsfy compiled Handlebars template
746var HandlebarsCompiler = require('hbsfy/runtime');
747module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
748    return "<div class=\"title\">"
749    + container.escapeExpression((helpers.trans || (depth0 && depth0.trans) || helpers.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"Phone",{"name":"trans","hash":{},"data":data}))
750    + ":</div>\n<div class=\"phone\"></div>\n";
751},"useData":true});
752
753},{"hbsfy/runtime":42}],21:[function(require,module,exports){
754// hbsfy compiled Handlebars template
755var HandlebarsCompiler = require('hbsfy/runtime');
756module.exports = HandlebarsCompiler.template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
757    return "<svg width=\"20\" height=\"20\">\n    <line x1=\"10\" y1=\"0\" x2=\"10\" y2=\"20\" stroke-width=\"2\"></line>\n    <line x1=\"0\" y1=\"10\" x2=\"20\" y2=\"10\" stroke-width=\"2\"></line>\n</svg>\n";
758},"useData":true});
759
760},{"hbsfy/runtime":42}],22:[function(require,module,exports){
761// hbsfy compiled Handlebars template
762var HandlebarsCompiler = require('hbsfy/runtime');
763module.exports = HandlebarsCompiler.template({"1":function(container,depth0,helpers,partials,data) {
764    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
765
766  return "  <time class=\"open\">"
767    + alias4(((helper = (helper = helpers.opens || (depth0 != null ? depth0.opens : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"opens","hash":{},"data":data}) : helper)))
768    + "</time> - <time class=\"close\">"
769    + alias4(((helper = (helper = helpers.closes || (depth0 != null ? depth0.closes : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"closes","hash":{},"data":data}) : helper)))
770    + "</time>\n";
771},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
772    var stack1;
773
774  return "<span class=\"now\"></span>\n"
775    + ((stack1 = helpers["if"].call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.hasHours : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
776},"useData":true});
777
778},{"hbsfy/runtime":42}],23:[function(require,module,exports){
779'use strict';
780
781var renderable = require('../mixins/renderable');
782var windowManager = require('../window-manager');
783var actionButtonHTML = require('../templates/plus.hbs');
784
785
786function ActionButton(options) {
787  this.options = options || {};
788  this.actionButton = document.createElement('button');
789  this.actionButton.setAttribute('class', 'action-button');
790  this.actionButton.innerHTML = actionButtonHTML();
791  this.wrapperEl = this.options.wrapperEl || document.body;
792  this.wrapperName = 'wrapperEl';
793  this.contentName = 'actionButton';
794
795  this.actionButton.addEventListener('click', this.toggle.bind(this));
796}
797
798ActionButton.prototype = Object.create(renderable);
799
800ActionButton.prototype.toggle = function(event) {
801  var window = windowManager.get();
802
803  if(this.actionButton.classList.contains('open')) {
804    window.location.hash = 'exit';
805    this.close();
806  } else {
807    window.location.hash = 'toolbar';
808    this.open();
809  }
810};
811
812ActionButton.prototype.open = function(event) {
813  this.actionButton.classList.add('open');
814
815  if(typeof this.openCallback === 'function') {
816    this.openCallback(event);
817  }
818};
819
820ActionButton.prototype.close = function(event) {
821  this.actionButton.classList.remove('open');
822
823  if(typeof this.closeCallback === 'function') {
824    this.closeCallback(event);
825  }
826};
827
828ActionButton.prototype.onOpen = function(func) {
829  this.openCallback = func;
830};
831
832ActionButton.prototype.onClose = function(func) {
833  this.closeCallback = func;
834};
835
836module.exports = ActionButton;
837
838},{"../mixins/renderable":11,"../templates/plus.hbs":21,"../window-manager":32}],24:[function(require,module,exports){
839'use strict';
840
841var hideable = require('../mixins/hideable');
842var renderable = require('../mixins/renderable');
843var extend = require('extend');
844
845function Backdrop(options) {
846  this.options = options || {};
847  this.backdropEl = document.createElement('div');
848  this.backdropEl.setAttribute('class', 'backdrop animated hide');
849  this.transIn = 'fadein';
850  this.transOut = 'fadeout';
851  this.contentName = 'backdropEl';
852  this.wrapperName = 'wrapper';
853  this.wrapper = this.options.wrapperEl || document.body;
854}
855
856extend(Backdrop.prototype, hideable, renderable);
857
858Backdrop.prototype.onClick = function(route) {
859  return this.backdropEl.addEventListener('click', function() {
860    window.location.hash = route;
861  });
862};
863
864module.exports = Backdrop;
865
866},{"../mixins/hideable":10,"../mixins/renderable":11,"extend":41}],25:[function(require,module,exports){
867'use strict';
868
869
870var siteData = require('../site-data');
871var canonicalizePhone = require('../canonicalize-phone');
872var Card = require('./card');
873var hoursRenderer = require('../hours-renderer');
874var addressHTML = require('../templates/address.hbs');
875var hoursHTML = require('../templates/hours-card.hbs');
876var phoneHTML = require('../templates/phone-card.hbs');
877
878
879function CardListing(options) {
880  var location = siteData.get('location');
881  var hoursData = siteData.get('hours');
882  var addrSecondLine;
883  var phoneNumber = siteData.get('phone');
884
885  this.cards = [];
886  this.options = options || {};
887
888  if(location) {
889    addrSecondLine = location.city + ' ' + location.state + ', ';
890    addrSecondLine += location.zipcode;
891
892    this.addressCard = new Card({
893      html: addressHTML(),
894      zLayer: 120
895    });
896
897    this.addressCard.inject('.line-one', location.address);
898    this.addressCard.inject('.line-two', addrSecondLine);
899    this.cards.push(this.addressCard);
900  }
901
902  if(hoursData) {
903    this.hoursCard = new Card({
904      html: hoursHTML(),
905      zLayer: 120
906    });
907
908    this.hoursCard.inject('.hours', hoursRenderer.openToday(hoursData));
909    this.cards.push(this.hoursCard);
910  }
911
912  if(canonicalizePhone(phoneNumber) !== null) {
913    this.phoneCard = new Card({
914      html: phoneHTML(),
915      zLayer: 120
916    });
917
918    this.phoneCard.inject('.phone', phoneNumber);
919    this.cards.push(this.phoneCard);
920  }
921}
922
923CardListing.prototype.renderCards = function() {
924  for(var i = 0; i < this.cards.length; i++) {
925    this.cards[i].render();
926    this.cards[i].show();
927  }
928};
929
930CardListing.prototype.removeCards = function() {
931  for(var i = 0; i < this.cards.length; i++) {
932    this.cards[i].hideAndRemove();
933  }
934};
935
936module.exports = CardListing;
937
938},{"../canonicalize-phone":4,"../hours-renderer":7,"../site-data":13,"../templates/address.hbs":14,"../templates/hours-card.hbs":15,"../templates/phone-card.hbs":20,"./card":26}],26:[function(require,module,exports){
939'use strict';
940
941var cardCounter = require('../card-counter');
942var renderable = require('../mixins/renderable');
943var hideable = require('../mixins/hideable');
944var extend = require('extend');
945
946function Card(options) {
947  this.options = options || {};
948  this.html = options.html;
949
950  this.contentName = 'cardEl';
951  this.cardEl = document.createElement('div');
952  this.cardEl.classList.add('info-card');
953  this.cardEl.classList.add('animated');
954  this.cardEl.classList.add('zoomIn');
955  this.cardEl.innerHTML = options.html;
956  this.cardEl.style['z-index'] = options.zLayer || 0;
957
958  this.closeEl = document.createElement('button');
959  this.closeEl.classList.add('close');
960  this.closeEl.classList.add('fa');
961  this.closeEl.classList.add('fa-times');
962
963  this.closeEl.addEventListener('click', this.hideAndRemove.bind(this));
964  this.cardEl.appendChild(this.closeEl);
965
966  this.wrapperName = 'wrapper';
967  this.wrapper = this.options.wrapperEl || document.body;
968
969  this.transIn = 'zoomIn';
970  this.transOut = 'zoomOut';
971}
972
973extend(Card.prototype, hideable, renderable);
974
975Card.prototype.hideAndRemove = function() {
976  this.hide(this.remove.bind(this));
977};
978
979Card.prototype.inject = function(selector, content) {
980  this.cardEl.querySelector(selector).innerHTML = content;
981};
982
983Card.prototype.getCardEl = function() {
984  return this.cardEl;
985};
986
987Card.prototype.getCardHeight = function() {
988  var cardHeight = this.cardEl.offsetHeight;
989  cardHeight += parseInt(this.cardEl.style['margin-top']) || 0;
990  cardHeight += parseInt(this.cardEl.style['margin-bottom']) || 0;
991
992  return cardHeight;
993};
994
995Card.prototype.onRender = function() {
996  cardCounter.register(this);
997};
998
999Card.prototype.onRemove = function() {
1000  cardCounter.unregister(this);
1001};
1002
1003module.exports = Card;
1004
1005}
1005,{"../card-counter":5,"../mixins/hideable":10,"../mixins/renderable":11,"extend":41}],27:[function(require,module,exports){
1006'use strict';
1007
1008var hoursRenderer = require('../hours-renderer');
1009var hideable = require('../mixins/hideable');
1010var renderable = require('../mixins/renderable');
1011var extend = require('extend');
1012
1013
1014function HoursView(options) {
1015  this.options = options || {};
1016  this.hours = options.hours;
1017  this.hoursEl = hoursRenderer.week(this.hours);
1018  this.contentEl = document.createElement('div');
1019  this.contentEl.classList.add('hours-view');
1020  this.contentEl.classList.add('animated');
1021  this.contentEl.classList.add('hide');
1022  this.contentEl.appendChild(this.hoursEl);
1023  this.contentName = 'contentEl';
1024  this.wrapper = this.options.wrapperEl || document.body;
1025
1026  /* Properties to be consumed by hideable mixin */
1027  this.transIn = 'fadein';
1028  this.transOut = 'fadeout';
1029  this.contentName = 'contentEl';
1030  this.wrapperName = 'wrapper';
1031
1032  this.setHeight(options.height || 500);
1033}
1034
1035extend(HoursView.prototype, hideable, renderable);
1036
1037HoursView.prototype.setHeight = function(newHeight) {
1038  this.contentEl.style.height = newHeight + 'px';
1039};
1040
1041module.exports = HoursView;
1042
1043},{"../hours-renderer":7,"../mixins/hideable":10,"../mixins/renderable":11,"extend":41}],28:[function(require,module,exports){
1044'use strict';
1045
1046var toolbarTemplate = require('../templates/map-toolbar.hbs');
1047var renderable = require('../mixins/renderable');
1048var hideable = require('../mixins/hideable');
1049var extend = require('extend');
1050
1051function MapToolbarView(options) {
1052  options = options || {};
1053  this.options = options;
1054  this.wrapperName = options.wrapperName;
1055  this.wrapper = options.wrapper;
1056  this.contentName = 'contentEl';
1057  this.contentEl = document.createElement('section');
1058  this.contentEl.innerHTML = toolbarTemplate();
1059  this.contentEl.classList.add('animated');
1060  this.contentEl.classList.add('map-toolbar');
1061  this.searchInput = this.contentEl.querySelector('input');
1062  this.toggleDrive = this.contentEl.querySelector('.drive-icon');
1063  this.toggleWalk = this.contentEl.querySelector('.walk-icon');
1064  this.transIn = 'fadein';
1065  this.transOut = 'fadeout';
1066  this.selectedMode = 'driving';
1067}
1068
1069extend(MapToolbarView.prototype, renderable, hideable);
1070
1071
1072/* This function handles the UI of the walk/drive selection.
1073 * It removes the style from the currently selected button and
1074 * adds it to the button passed in from the event handler.
1075 */
1076MapToolbarView.prototype.select = function(button) {
1077  var selectedEl = this.contentEl.querySelector('.selected');
1078  selectedEl.classList.remove('selected');
1079  button.classList.add('selected');
1080  this.selectedMode = button.getAttribute('data-mode');
1081};
1082
1083module.exports = MapToolbarView;
1084
1085},{"../mixins/hideable":10,"../mixins/renderable":11,"../templates/map-toolbar.hbs":17,"extend":41}],29:[function(require,module,exports){
1086/* global google, navigator */
1087
1088'use strict';
1089
1090var debounce = require('debounce');
1091var extend = require('extend');
1092var url = require('url');
1093
1094var googleMapsTemplate = require('../templates/map.hbs');
1095var MapToolbarView = require('./map-toolbar');
1096var renderable = require('../mixins/renderable');
1097
1098var BASEURL = 'https://www.google.com/maps/embed/v1/';
1099
1100/* This function is the Map constructor.
1101 * Options include:
1102 *
1103 * - height: the height of the map view
1104 * - google embed API key
1105 * - address, city, state, zipcode
1106 */
1107function MapView(options) {
1108  options = options || {};
1109  this.options = options;
1110  this.height = options.height || '100%';
1111  this.address = options.address + ' ' + options.city + ', ' + options.state;
1112  this.address += ' ' + options.zipcode;
1113  this.mapOptions = {
1114    embedAPIKey: options.embedAPIKey,
1115    businessLocation: this.address
1116  };
1117  this.mapContext = {};
1118
1119  this.setupMarkup();
1120  this.getOriginLocation();
1121  this.attachListeners();
1122}
1123
1124extend(MapView.prototype, renderable);
1125
1126MapView.prototype.setupMarkup = function() {
1127  var searchHeightOffset;
1128
1129  this.contentName = 'contentEl';
1130  this.contentEl = document.createElement('div');
1131
1132  this.wrapperName = 'wrapper';
1133  this.wrapper = this.options.wrapperEl || document.body;
1134
1135  this.mapToolbar = new MapToolbarView({
1136    wrapper: this.contentEl,
1137    wrapperName: this.wrapperName
1138  });
1139  this.mapToolbar.render();
1140  searchHeightOffset = this.mapToolbar.offsetHeight || 50;
1141
1142  this.mapWrapper = document.createElement('div');
1143  this.mapWrapper.classList.add('google-map');
1144  this.mapWrapper.classList.add('animated');
1145  this.mapWrapper.style.height = this.height - searchHeightOffset + 'px';
1146
1147  this.contentEl.appendChild(this.mapWrapper);
1148};
1149
1150MapView.prototype.attachListeners = function() {
1151  var debounceCurrentLocation = debounce(
1152    this.getOriginLocation.bind(this), 1000);
1153
1154  this.mapToolbar.searchInput.addEventListener(
1155    'input', debounceCurrentLocation);
1156
1157  this.mapToolbar.toggleDrive.addEventListener(
1158    'click', this.setTransportMode.bind(this), false);
1159
1160  this.mapToolbar.toggleWalk.addEventListener(
1161    'click', this.setTransportMode.bind(this), false);
1162};
1163
1164MapView.prototype.setTransportMode = function(event) {
1165  var button = event.currentTarget;
1166
1167  if (!button.classList.contains('selected')) {
1168    var mode = button.getAttribute('data-mode');
1169
1170    this.mapToolbar.select(button);
1171    this.mapOptions.directionsMode = mode;
1172    this.renderDirectionsMode();
1173  }
1174};
1175
1176/* This function sets the origin location using
1177 * one of two methods:
1178 *
1179 * 1. It will use user provided address if the user
1180 *    has entered a value via the seach box at the
1181 *    top of the view.
1182 *
1183 * 2. If the user has not entered a value in the
1184 *    search box and the user has a geolocation
1185 *    enabled device and the site has SSL enabled,
1186 *    then the function will use navigator to get
1187 *    the current location.
1188 *
1189 * If 1 and 2 are not available, the map will
1190 * simply display a marker where the given business
1191 * address is located.
1192 */
1193MapView.prototype.getOriginLocation = function() {
1194  var setCurrentLocation = function(position) {
1195    var latStr = String(position.coords.latitude);
1196    var lngStr = String(position.coords.longitude);
1197    this.mapOptions.originLocation = latStr + ',' + lngStr;
1198    this.render();
1199  }.bind(this);
1200
1201
1202  if(this.mapToolbar.searchInput.value) {
1203    this.mapOptions.originLocation = this.mapToolbar.searchInput.value;
1204    this.renderDirectionsMode();
1205    return;
1206  }
1207
1208  if(navigator.geolocation) {
1209    // HTML5 Geolocation API
1210    // renders business location if current position cannot be retrieved
1211    navigator.geolocation.getCurrentPosition(
1212      setCurrentLocation,
1213      this.renderPlaceMode.bind(this),
1214      {timeout: 3500}
1215    );
1216    return;
1217  }
1218
1219  this.renderPlaceMode();
1220};
1221
1222MapView.prototype.renderPlaceMode = function() {
1223  var placeModeUrl = BASEURL + 'place';
1224  var urlObj = url.parse(placeModeUrl);
1225
1226  urlObj.query ={
1227    key: this.mapOptions.embedAPIKey,
1228    q: this.mapOptions.businessLocation
1229  };
1230
1231  this.mapContext.mapSource = urlObj.format();
1232  this.render();
1233};
1234
1235MapView.prototype.renderDirectionsMode = function() {
1236  var directionsModeUrl = BASEURL + 'directions';
1237  var urlObj = url.parse(directionsModeUrl);
1238
1239  urlObj.query = {
1240    key: this.mapOptions.embedAPIKey,
1241    origin: this.mapOptions.originLocation,
1242    destination: this.mapOptions.businessLocation
1243  }
1244
1245  if(this.mapOptions.directionsMode) {
1246    urlObj.query.mode = this.mapOptions.directionsMode;
1247  }
1248
1249  this.mapContext.mapSource = urlObj.format();
1250  this.render();
1251};
1252
1253MapView.prototype.getWrapper = function() {
1254  return this.mapWrapper;
1255};
1256
1257/* Show the Map */
1258MapView.prototype.show = function() {
1259  this.mapWrapper.classList.add('open');
1260  this.mapWrapper.classList.add('fadein');
1261  this.mapWrapper.classList.remove('fadeout');
1262  this.mapToolbar.show();
1263};
1264
1265/* Hide the Map */
1266MapView.prototype.hide = function(cb, timeout) {
1267  if(timeout === undefined) {
1268    timeout = 400;
1269  }
1270
1271  this.mapWrapper.classList.add('fadeout');
1272  this.mapWrapper.classList.remove('fadein');
1273  this.mapToolbar.hide();
1274
1275  var removeOpenClass = function() {
1276    this.mapWrapper.classList.remove('open');
1277    this.mapToolbar.contentEl.classList.remove('open');
1278    if(typeof cb === 'function') {
1279      cb();
1280    }
1281  };
1282
1283  setTimeout(removeOpenClass.bind(this), timeout);
1284};
1285
1286MapView.prototype.onRender = function() {
1287  this.mapWrapper.innerHTML = googleMapsTemplate(this.mapContext);
1288};
1289
1290module.exports = MapView;
1291
1292},{"../mixins/renderable":11,"../templates/map.hbs":18,"./map-toolbar":28,"debounce":40,"extend":41,"url":98}],30:[function(require,module,exports){
1293'use strict';
1294
1295var MapView = require('./map');
1296var Backdrop = require('./backdrop');
1297var Toolbar = require('./toolbar');
1298var ActionButton = require('./action-button');
1299var HoursView = require('./hours');
1300var animatedScrollTo = require('animated-scrollto');
1301var siteData = require('../site-data');
1302var CardListing = require('./card-listing');
1303var canonicalizePhone = require('../canonicalize-phone');
1304
1305
1306var getViewportHeight = function() {
1307  return Math.max(
1308    document.documentElement.clientHeight, window.innerHeight || 0);
1309};
1310
1311function PageView(options) {
1312  this.options = options || {};
1313  this.actionButton = new ActionButton();
1314  this.toolbar = new Toolbar();
1315  this.backdrop = new Backdrop();
1316  this.mapHoursHeight = getViewportHeight() - this.toolbar.getHeight();
1317
1318  this.cardListing = new CardListing();
1319
1320  this.initializePhone();
1321
1322  var hasLoc = siteData.get('location');
1323  var hasPhone = siteData.get('phone');
1324  var hasHours = siteData.get('hours');
1325
1326  if(hasHours) {
1327    this.initializeHours();
1328  }
1329
1330  if(hasLoc) {
1331    this.initializeMap();
1332  }
1333
1334  if(hasLoc || hasHours || hasPhone) {
1335    this.actionButton.render();
1336  }
1337
1338  this.backdrop.onClick('exit');
1339
1340  var resize = function(event) {
1341    var mapHoursHeight = getViewportHeight() - this.toolbar.getHeight();
1342    if(this.mapView && this.mapView.google) {
1343      this.mapView.setHeight(mapHoursHeight);
1344    }
1345
1346    if(this.hoursView) {
1347      this.hoursView.setHeight(mapHoursHeight);
1348    }
1349  };
1350
1351  window.addEventListener('resize', resize.bind(this));
1352}
1353
1354PageView.prototype.initializeMap = function() {
1355  var location = siteData.get('location');
1356  var embedAPIKey = siteData.get('embedAPIKey');
1357
1358  this.mapView = new MapView({
1359    address: location.address,
1360    city: location.city,
1361    state: location.state,
1362    zipcode: location.zipcode,
1363    height: this.mapHoursHeight,
1364    embedAPIKey: embedAPIKey
1365  });
1366
1367  this.toolbar.showButton('map');
1368};
1369
1370PageView.prototype.initializeHours = function() {
1371  this.hoursView = new HoursView({
1372    hours: siteData.get('hours'),
1373    height: this.mapHoursHeight
1374  });
1375
1376  this.toolbar.showButton('hours');
1377};
1378
1379PageView.prototype.initializePhone = function() {
1380  var phoneNumber = siteData.get('phone');
1381  var canonicalPhone = canonicalizePhone(phoneNumber);
1382
1383  if(canonicalPhone !== null) {
1384    this.toolbar.phoneNumber(canonicalPhone);
1385    this.toolbar.showButton('phone');
1386  }
1387};
1388
1389PageView.prototype.open = function() {
1390  animatedScrollTo(document.body, 0, 400);
1391  this.backdrop.render();
1392  this.backdrop.show();
1393  this.actionButton.open();
1394  this.toolbar.render();
1395  this.toolbar.show();
1396  this.actionButton.open();
1397};
1398
1399PageView.prototype.renderToolbar = function() {
1400  this.open();
1401  this.cardListing.renderCards();
1402};
1403
1404PageView.prototype.renderHours = function() {
1405  if(this.hoursView) {
1406    this.hoursView.render();
1407    this.hoursView.show();
1408  }
1409
1410  this.removeMap();
1411  this.open();
1412  this.cardListing.removeCards();
1413};
1414
1415PageView.prototype.renderMap = function() {
1416  if(this.mapView) {
1417    this.mapView.render();
1418    this.mapView.show();
1419  }
1420
1421  this.removeHours();
1422  this.open();
1423  this.cardListing.removeCards();
1424};
1425
1426PageView.prototype.removeActionButton = function() {
1427  if(this.actionButton.isRendered) {
1428    this.actionButton.remove();
1429  }
1430};
1431
1432PageView.prototype.removeMap = function() {
1433  if(this.mapView) {
1434    this.mapView.hide(this.mapView.remove.bind(this.mapView));
1435  }
1436};
1437
1438PageView.prototype.removeHours = function() {
1439  if(this.hoursView) {
1440    this.hoursView.hide(this.hoursView.remove.bind(this.hoursView));
1441  }
1442};
1443
1444PageView.prototype.removeToolbar = function() {
1445  this.toolbar.hide(this.toolbar.remove.bind(this.toolbar));
1446};
1447
1448PageView.prototype.removeBackdrop = function() {
1449  this.backdrop.hide(this.backdrop.remove.bind(this.backdrop));
1450};
1451
1452PageView.prototype.removeAll = function() {
1453  this.removeHours();
1454  this.removeMap();
1455  this.removeBackdrop();
1456  this.removeToolbar();
1457  this.actionButton.close();
1458
1459  this.cardListing.removeCards();
1460};
1461
1462PageView.shouldRender = function() {
1463  var phone = siteData.get('phone');
1464  var hours = siteData.get('hours');
1465  var location = siteData.get('location');
1466
1467  return phone || hours || location;
1468};
1469
1470module.exports = PageView;
1471
1472},{"../canonicalize-phone":4,"../site-data":13,"./action-button":23,"./backdrop":24,"./card-listing":25,"./hours":27,"./map":29,"./toolbar":31,"animated-scrollto":37}],31:[function(require,module,exports){
1473'use strict';
1474
1475var hideable = require('../mixins/hideable');
1476var renderable = require('../mixins/renderable');
1477var extend = require('extend');
1478var toolbarHTML = require('../templates/mobile-features.hbs');
1479
1480function Toolbar(options) {
1481  this.options = options || {};
1482  this.contentEl = document.createElement('section');
1483  this.contentName = 'contentEl';
1484
1485  this.wrapperEl = this.options.wrapperEl || document.body;
1486  this.wrapperName = 'wrapperEl';
1487
1488  this.transIn = 'fadeinup';
1489  this.transOut = 'fadeoutdown';
1490
1491  this.contentEl.innerHTML = toolbarHTML();
1492
1493  this.contentEl.classList.add('mobile-features');
1494  this.contentEl.classList.add('animated');
1495  this.contentEl.classList.add('hide');
1496
1497  this.noscroll = true;
1498}
1499
1500extend(Toolbar.prototype, hideable, renderable);
1501
1502Toolbar.prototype.getWrapperEl = function() {
1503  return this.contentEl;
1504};
1505
1506Toolbar.prototype.showButton = function(buttonName) {
1507  var buttonEl = this.contentEl.querySelector('.' + buttonName);
1508
1509  buttonEl.classList.remove('hide');
1510};
1511
1512Toolbar.prototype.phoneNumber = function(phoneNumber) {
1513  var callEl = this.contentEl.querySelector('#location-tools-phone');
1514
1515  callEl.href = 'tel:' + phoneNumber;
1516};
1517
1518Toolbar.prototype.getHeight = function() {
1519  return this.contentEl.offsetHeight || 70;
1520};
1521
1522Toolbar.prototype.onDirectionsClick = function(func) {
1523  this.contentEl.querySelector('#location-tools-map')
1524    .addEventListener('click', func);
1525};
1526
1527Toolbar.prototype.onPhoneClick = function(func) {
1528  this.contentEl.querySelector('#location-tools-phone')
1529    .addEventListener('click', func);
1530};
1531
1532Toolbar.prototype.onHoursClick = function(func) {
1533  this.contentEl.querySelector('#location-tools-hours')
1534    .addEventListener('click', func);
1535};
1536
1537module.exports = Toolbar;
1538
1539},{"../mixins/hideable":10,"../mixins/renderable":11,"../templates/mobile-features.hbs":19,"extend":41}],32:[function(require,module,exports){
1540'use strict';
1541
1542
1543var windowManager = {
1544  set: function(_window) {
1545    this.window = _window;
1546  },
1547
1548  get: function() {
1549    return this.window;
1550  },
1551
1552  reset: function() {
1553    this.window = this.originalWindow;
1554  },
1555
1556  init: function(_window) {
1557    this.window = _window;
1558    this.originalWindow = _window;
1559  }
1560};
1561
1562windowManager.init(window);
1563
1564module.exports = windowManager;
1565
1566},{}],33:[function(require,module,exports){
1567var assign = require('lodash.assign');
1568
1569/// Following code is largely pasted from Backbone.js
1570
1571// Helper function to correctly set up the prototype chain, for subclasses.
1572// Similar to `goog.inherits`, but uses a hash of prototype properties and
1573// class properties to be extended.
1574var extend = function(protoProps) {
1575    var parent = this;
1576    var child;
1577    var args = [].slice.call(arguments);
1578
1579    // The constructor function for the new subclass is either defined by you
1580    // (the "constructor" property in your `extend` definition), or defaulted
1581    // by us to simply call the parent's constructor.
1582    if (protoProps && protoProps.hasOwnProperty('constructor')) {
1583        child = protoProps.constructor;
1584    } else {
1585        child = function () {
1586            return parent.apply(this, arguments);
1587        };
1588    }
1589
1590    // Add static properties to the constructor function from parent
1591    assign(child, parent);
1592
1593    // Set the prototype chain to inherit from `parent`, without calling
1594    // `parent`'s constructor function.
1595    var Surrogate = function(){ this.constructor = child; };
1596    Surrogate.prototype = parent.prototype;
1597    child.prototype = new Surrogate();
1598
1599    // Mix in all prototype properties to the subclass if supplied.
1600    if (protoProps) {
1601        args.unshift(child.prototype);
1602        assign.apply(null, args);
1603    }
1604
1605    // Set a convenience property in case the parent's prototype is needed
1606    // later.
1607    child.__super__ = parent.prototype;
1608
1609    return child;
1610};
1611
1612// Expose the extend function
1613module.exports = extend;
1614
1615},{"lodash.assign":56}],34:[function(require,module,exports){
1616;if (typeof window !== "undefined") {  window.ampersand = window.ampersand || {};  window.ampersand["ampersand-events"] = window.ampersand["ampersand-events"] || [];  window.ampersand["ampersand-events"].push("1.1.1");}
1617var runOnce = require('lodash.once');
1618var uniqueId = require('lodash.uniqueid');
1619var keys = require('lodash.keys');
1620var isEmpty = require('lodash.isempty');
1621var each = require('lodash.foreach');
1622var bind = require('lodash.bind');
1623var assign = require('lodash.assign');
1624var slice = Array.prototype.slice;
1625var eventSplitter = /\s+/;
1626
1627
1628var Events = {
1629    // Bind an event to a `callback` function. Passing `"all"` will bind
1630    // the callback to all events fired.
1631    on: function(name, callback, context) {
1632        if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
1633        this._events || (this._events = {});
1634        var events = this._events[name] || (this._events[name] = []);
1635        events.push({callback: callback, context: context, ctx: context || this});
1636        return this;
1637    },
1638
1639    // Bind an event to only be triggered a single time. After the first time
1640    // the callback is invoked, it will be removed.
1641    once: function(name, callback, context) {
1642        if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
1643        var self = this;
1644        var once = runOnce(function() {
1645            self.off(name, once);
1646            callback.apply(this, arguments);
1647        });
1648        once._callback = callback;
1649        return this.on(name, once, context);
1650    },
1651
1652    // Remove one or many callbacks. If `context` is null, removes all
1653    // callbacks with that function. If `callback` is null, removes all
1654    // callbacks for the event. If `name` is null, removes all bound
1655    // callbacks for all events.
1656    off: function(name, callback, context) {
1657        var retain, ev, events, names, i, l, j, k;
1658        if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
1659        if (!name && !callback && !context) {
1660            this._events = void 0;
1661            return this;
1662        }
1663        names = name ? [name] : keys(this._events);
1664        for (i = 0, l = names.length; i < l; i++) {
1665            name = names[i];
1666            if (events = this._events[name]) {
1667                this._events[name] = retain = [];
1668                if (callback || context) {
1669                    for (j = 0, k = events.length; j < k; j++) {
1670                        ev = events[j];
1671                        if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
1672                                (context && context !== ev.context)) {
1673                            retain.push(ev);
1674                        }
1675                    }
1676                }
1677                if (!retain.length) delete this._events[name];
1678            }
1679        }
1680
1681        return this;
1682    },
1683
1684    // Trigger one or many events, firing all bound callbacks. Callbacks are
1685    // passed the same arguments as `trigger` is, apart from the event name
1686    // (unless you're listening on `"all"`, which will cause your callback to
1687    // receive the true name of the event as the first argument).
1688    trigger: function(name) {
1689        if (!this._events) return this;
1690        var args = slice.call(arguments, 1);
1691        if (!eventsApi(this, 'trigger', name, args)) return this;
1692        var events = this._events[name];
1693        var allEvents = this._events.all;
1694        if (events) triggerEvents(events, args);
1695        if (allEvents) triggerEvents(allEvents, arguments);
1696        return this;
1697    },
1698
1699    // Tell this object to stop listening to either specific events ... or
1700    // to every object it's currently listening to.
1701    stopListening: function(obj, name, callback) {
1702        var listeningTo = this._listeningTo;
1703        if (!listeningTo) return this;
1704        var remove = !name && !callback;
1705        if (!callback && typeof name === 'object') callback = this;
1706        if (obj) (listeningTo = {})[obj._listenId] = obj;
1707        for (var id in listeningTo) {
1708            obj = listeningTo[id];
1709            obj.off(name, callback, this);
1710            if (remove || isEmpty(obj._events)) delete this._listeningTo[id];
1711        }
1712        return this;
1713    },
1714
1715    // extend an object with event capabilities if passed
1716    // or just return a new one.
1717    createEmitter: function (obj) {
1718        return assign(obj || {}, Events);
1719    }
1720};
1721
1722Events.bind = Events.on;
1723Events.unbind = Events.off;
1724
1725
1726// Implement fancy features of the Events API such as multiple event
1727// names `"change blur"` and jQuery-style event maps `{change: action}`
1728// in terms of the existing API.
1729var eventsApi = function(obj, action, name, rest) {
1730    if (!name) return true;
1731
1732    // Handle event maps.
1733    if (typeof name === 'object') {
1734        for (var key in name) {
1735            obj[action].apply(obj, [key, name[key]].concat(rest));
1736        }
1737        return false;
1738    }
1739
1740    // Handle space separated event names.
1741    if (eventSplitter.test(name)) {
1742        var names = name.split(eventSplitter);
1743        for (var i = 0, l = names.length; i < l; i++) {
1744            obj[action].apply(obj, [names[i]].concat(rest));
1745        }
1746        return false;
1747    }
1748
1749    return true;
1750};
1751
1752// A difficult-to-believe, but optimized internal dispatch function for
1753// triggering events. Tries to keep the usual cases speedy.
1754var triggerEvents = function(events, args) {
1755    var ev;
1756    var i = -1;
1757    var l = events.length;
1758    var a1 = args[0];
1759    var a2 = args[1];
1760    var a3 = args[2];
1761    switch (args.length) {
1762        case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
1763        case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
1764        case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
1765        case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
1766        default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
1767    }
1768};
1769
1770var listenMethods = {
1771    listenTo: 'on',
1772    listenToOnce: 'once'
1773};
1774
1775// Inversion-of-control versions of `on` and `once`. Tell *this* object to
1776// listen to an event in another object ... keeping track of what it's
1777// listening to.
1778each(listenMethods, function(implementation, method) {
1779    Events[method] = function(obj, name, callback, run) {
1780        var listeningTo = this._listeningTo || (this._listeningTo = {});
1781        var id = obj._listenId || (obj._listenId = uniqueId('l'));
1782        listeningTo[id] = obj;
1783        if (!callback && typeof name === 'object') callback = this;
1784        obj[implementation](name, callback, this);
1785        return this;
1786    };
1787});
1788
1789Events.listenToAndRun = function (obj, name, callback) {
1790    Events.listenTo.apply(this, arguments);
1791    if (!callback && typeof name === 'object') callback = this;
1792    callback.apply(this);
1793    return this;
1794};
1795
1796module.exports = Events;
1797
1798},{"lodash.assign":56,"lodash.bind":58,"lodash.foreach":59,"lodash.isempty":63,"lodash.keys":67,"lodash.once":68,"lodash.uniqueid":71}],35:[function(require,module,exports){
1799var Events = require('ampersand-events');
1800var extend = require('lodash.assign');
1801var bind = require('lodash.bind');
1802
1803
1804// Handles cross-browser history management, based on either
1805// [pushState](http://diveintohtml5.info/history.html) and real URLs, or
1806// [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
1807// and URL fragments. If the browser supports neither.
1808var History = function () {
1809    this.handlers = [];
1810    this.checkUrl = bind(this.checkUrl, this);
1811
1812    // Ensure that `History` can be used outside of the browser.
1813    if (typeof window !== 'undefined') {
1814        this.location = window.location;
1815        this.history = window.history;
1816    }
1817};
1818
1819// Cached regex for stripping a leading hash/slash and trailing space.
1820var routeStripper = /^[#\/]|\s+$/g;
1821
1822// Cached regex for stripping leading and trailing slashes.
1823var rootStripper = /^\/+|\/+$/g;
1824
1825// Cached regex for stripping urls of hash.
1826var pathStripper = /#.*$/;
1827
1828// Has the history handling already been started?
1829History.started = false;
1830
1831// Set up all inheritable **Backbone.History** properties and methods.
1832extend(History.prototype, Events, {
1833
1834    // The default interval to poll for hash changes, if necessary, is
1835    // twenty times a second.
1836    interval: 50,
1837
1838    // Are we at the app root?
1839    atRoot: function () {
1840        var path = this.location.pathname.replace(/[^\/]$/, '$&/');
1841        return path === this.root && !this.location.search;
1842    },
1843
1844    // Gets the true hash value. Cannot use location.hash directly due to bug
1845    // in Firefox where location.hash will always be decoded.
1846    getHash: function (window) {
1847        var match = (window || this).location.href.match(/#(.*)$/);
1848        return match ? match[1] : '';
1849    },
1850
1851    // Get the pathname and search params, without the root.
1852    getPath: function () {
1853        var path = decodeURI(this.location.pathname + this.location.search);
1854        var root = this.root.slice(0, -1);
1855        if (!path.indexOf(root)) path = path.slice(root.length);
1856        return path.slice(1);
1857    },
1858
1859    // Get the cross-browser normalized URL fragment from the path or hash.
1860    getFragment: function (fragment) {
1861        if (fragment == null) {
1862            if (this._hasPushState || !this._wantsHashChange) {
1863                fragment = this.getPath();
1864            } else {
1865                fragment = this.getHash();
1866            }
1867        }
1868        return fragment.replace(routeStripper, '');
1869    },
1870
1871    // Start the hash change handling, returning `true` if the current URL matches
1872    // an existing route, and `false` otherwise.
1873    start: function (options) {
1874        if (History.started) throw new Error("Backbone.history has already been started");
1875        History.started = true;
1876
1877        // Figure out the initial configuration.
1878        // Is pushState desired ... is it available?
1879        this.options          = extend({root: '/', pushState: true}, this.options, options);
1880        this.root             = this.options.root;
1881        this._wantsHashChange = this.options.hashChange !== false;
1882        this._hasHashChange   = 'onhashchange' in window;
1883        this._wantsPushState  = !!this.options.pushState;
1884        this._hasPushState    = !!(this.options.pushState && this.history && this.history.pushState);
1885        this.fragment         = this.getFragment();
1886
1887        // Add a cross-platform `addEventListener` shim for older browsers.
1888        var addEventListener = window.addEventListener;
1889
1890        // Normalize root to always include a leading and trailing slash.
1891        this.root = ('/' + this.root + '/').replace(rootStripper, '/');
1892
1893        // Depending on whether we're using pushState or hashes, and whether
1894        // 'onhashchange' is supported, determine how we check the URL state.
1895        if (this._hasPushState) {
1896            addEventListener('popstate', this.checkUrl, false);
1897        } else if (this._wantsHashChange && this._hasHashChange) {
1898            addEventListener('hashchange', this.checkUrl, false);
1899        } else if (this._wantsHashChange) {
1900            this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
1901        }
1902
1903        // Transition from hashChange to pushState or vice versa if both are
1904        // requested.
1905        if (this._wantsHashChange && this._wantsPushState) {
1906
1907            // If we've started off with a route from a `pushState`-enabled
1908            // browser, but we're currently in a browser that doesn't support it...
1909            if (!this._hasPushState && !this.atRoot()) {
1910                this.location.replace(this.root + '#' + this.getPath());
1911                // Return immediately as browser will do redirect to new url
1912                return true;
1913
1914            // Or if we've started out with a hash-based route, but we're currently
1915            // in a browser where it could be `pushState`-based instead...
1916            } else if (this._hasPushState && this.atRoot()) {
1917                this.navigate(this.getHash(), {replace: true});
1918            }
1919        }
1920
1921        if (!this.options.silent) return this.loadUrl();
1922    },
1923
1924    // Returns the value of History.started. Allows an app or units tests to
1925    // check whether or not the router has been started with
1926    // router.history.started(); otherwise the started flag is inaccessible
1927    started: function () {
1928      return History.started;
1929    },
1930
1931    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
1932    // but possibly useful for unit testing Routers.
1933    stop: function () {
1934        // Add a cross-platform `removeEventListener` shim for older browsers.
1935        var removeEventListener = window.removeEventListener;
1936
1937        // Remove window listeners.
1938        if (this._hasPushState) {
1939            removeEventListener('popstate', this.checkUrl, false);
1940        } else if (this._wantsHashChange && this._hasHashChange) {
1941            removeEventListener('hashchange', this.checkUrl, false);
1942        }
1943
1944        // Some environments will throw when clearing an undefined interval.
1945        if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
1946        History.started = false;
1947    },
1948
1949    // Add a route to be tested when the fragment changes. Routes added later
1950    // may override previous routes.
1951    route: function (route, callback) {
1952        this.handlers.unshift({route: route, callback: callback});
1953    },
1954
1955    urlChanged: function () {
1956        var current = this.getFragment();
1957        if (current === this.fragment) return false;
1958        return true;
1959    },
1960
1961    // Checks the current URL to see if it has changed, and if it has,
1962    // calls `loadUrl`.
1963    checkUrl: function (e) {
1964        this.urlChanged() && this.loadUrl();
1965    },
1966
1967    // Attempt to load the current URL fragment. If a route succeeds with a
1968    // match, returns `true`. If no defined routes matches the fragment,
1969    // returns `false`.
1970    loadUrl: function (fragment) {
1971        fragment = this.fragment = this.getFragment(fragment);
1972        return this.handlers.some(function (handler) {
1973            if (handler.route.test(fragment)) {
1974                handler.callback(fragment);
1975                return true;
1976            }
1977        });
1978    },
1979
1980    // Save a fragment into the hash history, or replace the URL state if the
1981    // 'replace' option is passed. You are responsible for properly URL-encoding
1982    // the fragment in advance.
1983    //
1984    // The options object can contain `trigger: false` if you wish to have the
1985    // route callback not be fired (sometimes desirable), or `replace: true`, if
1986    // you wish to modify the current URL without adding an entry to the history.
1987    navigate: function (fragment, options) {
1988        if (!History.started) return false;
1989        options = extend({trigger: true}, options);
1990
1991        var url = this.root + (fragment = this.getFragment(fragment || ''));
1992
1993        // Strip the hash and decode for matching.
1994        fragment = decodeURI(fragment.replace(pathStripper, ''));
1995
1996        if (this.fragment === fragment) return;
1997        this.fragment = fragment;
1998
1999        // Don't include a trailing slash on the root.
2000        if (fragment === '' && url !== '/') url = url.slice(0, -1);
2001
2002        // If pushState is available, we use it to set the fragment as a real URL.
2003        if (this._hasPushState) {
2004            this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
2005
2006            // If hash changes haven't been explicitly disabled, update the hash
2007            // fragment to store history.
2008        } else if (this._wantsHashChange) {
2009            this._updateHash(this.location, fragment, options.replace);
2010            // If you've told us that you explicitly don't want fallback hashchange-
2011            // based history, then `navigate` becomes a page refresh.
2012        } else {
2013            return this.location.assign(url);
2014        }
2015
2016        if (options.trigger) return this.loadUrl(fragment);
2017    },
2018
2019    // Update the hash location, either replacing the current entry, or adding
2020    // a new one to the browser history.
2021    _updateHash: function (location, fragment, replace) {
2022        if (replace) {
2023            var href = location.href.replace(/(javascript:|#).*$/, '');
2024            location.replace(href + '#' + fragment);
2025        } else {
2026            // Some browsers require that `hash` contains a leading #.
2027            location.hash = '#' + fragment;
2028        }
2029    }
2030
2031});
2032
2033module.exports = new History();
2034
2035},{"ampersand-events":34,"lodash.assign":56,"lodash.bind":58}],36:[function(require,module,exports){
2036;if (typeof window !== "undefined") {  window.ampersand = window.ampersand || {};  window.ampersand["ampersand-router"] = window.ampersand["ampersand-router"] || [];  window.ampersand["ampersand-router"].push("3.0.2");}
2037var classExtend = require('ampersand-class-extend');
2038var Events = require('ampersand-events');
2039var extend = require('lodash.assign');
2040var isRegexp = require('lodash.isregexp');
2041var isFunction = require('lodash.isfunction');
2042var result = require('lodash.result');
2043
2044var ampHistory = require('./ampersand-history');
2045
2046// Routers map faux-URLs to actions, and fire events when routes are
2047// matched. Creating a new one sets its `routes` hash, if not set statically.
2048var Router = module.exports = function (options) {
2049    options || (options = {});
2050    this.history = options.history || ampHistory;
2051    if (options.routes) this.routes = options.routes;
2052    this._bindRoutes();
2053    this.initialize.apply(this, arguments);
2054};
2055
2056// Cached regular expressions for matching named param parts and splatted
2057// parts of route strings.
2058var optionalParam = /\((.*?)\)/g;
2059var namedParam    = /(\(\?)?:\w+/g;
2060var splatParam    = /\*\w+/g;
2061var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
2062
2063// Set up all inheritable **Backbone.Router** properties and methods.
2064extend(Router.prototype, Events, {
2065
2066    // Initialize is an empty function by default. Override it with your own
2067    // initialization logic.
2068    initialize: function () {},
2069
2070    // Manually bind a single named route to a callback. For example:
2071    //
2072    //     this.route('search/:query/p:num', 'search', function (query, num) {
2073    //       ...
2074    //     });
2075    //
2076    route: function (route, name, callback) {
2077        if (!isRegexp(route)) route = this._routeToRegExp(route);
2078        if (isFunction(name)) {
2079            callback = name;
2080            name = '';
2081        }
2082        if (!callback) callback = this[name];
2083        var router = this;
2084        this.history.route(route, function (fragment) {
2085            var args = router._extractParameters(route, fragment);
2086            if (router.execute(callback, args, name) !== false) {
2087                router.trigger.apply(router, ['route:' + name].concat(args));
2088                router.trigger('route', name, args);
2089                router.history.trigger('route', router, name, args);
2090            }
2091        });
2092        return this;
2093    },
2094
2095    // Execute a route handler with the provided parameters.  This is an
2096    // excellent place to do pre-route setup or post-route cleanup.
2097    execute: function (callback, args, name) {
2098        if (callback) callback.apply(this, args);
2099    },
2100
2101    // Simple proxy to `ampHistory` to save a fragment into the history.
2102    navigate: function (fragment, options) {
2103        this.history.navigate(fragment, options);
2104        return this;
2105    },
2106
2107    // Reload the current route as if it was navigated to from somewhere
2108    // else
2109    reload: function () {
2110        this.history.loadUrl(this.history.fragment);
2111        return this;
2112    },
2113
2114    // Helper for doing `internal` redirects without adding to history
2115    // and thereby breaking backbutton functionality.
2116    redirectTo: function (newUrl) {
2117        this.navigate(newUrl, {replace: true});
2118    },
2119
2120    // Bind all defined routes to `history`. We have to reverse the
2121    // order of the routes here to support behavior where the most general
2122    // routes can be defined at the bottom of the route map.
2123    _bindRoutes: function () {
2124        if (!this.routes) return;
2125        this.routes = result(this, 'routes');
2126        var route, routes = Object.keys(this.routes);
2127        while ((route = routes.pop()) != null) {
2128            this.route(route, this.routes[route]);
2129        }
2130    },
2131
2132    // Convert a route string into a regular expression, suitable for matching
2133    // against the current location hash.
2134    _routeToRegExp: function (route) {
2135        route = route
2136            .replace(escapeRegExp, '\\$&')
2137            .replace(optionalParam, '(?:$1)?')
2138            .replace(namedParam, function (match, optional) {
2139                return optional ? match : '([^/?]+)';
2140            })
2141            .replace(splatParam, '([^?]*?)');
2142        return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
2143    },
2144
2145    // Given a route, and a URL fragment that it matches, return the array of
2146    // extracted decoded parameters. Empty or unmatched parameters will be
2147    // treated as `null` to normalize cross-browser behavior.
2148    _extractParameters: function (route, fragment) {
2149        var params = route.exec(fragment).slice(1);
2150        return params.map(function (param, i) {
2151            // Don't decode the search params.
2152            if (i === params.length - 1) return param || null;
2153            return param ? decodeURIComponent(param) : null;
2154        });
2155    }
2156
2157});
2158
2159Router.extend = classExtend;
2160
2161},{"./ampersand-history":35,"ampersand-class-extend":33,"ampersand-events":34,"lodash.assign":56,"lodash.isfunction":64,"lodash.isregexp":65,"lodash.result":70}],37:[function(require,module,exports){
2162(function (window) {
2163    var requestAnimFrame = (function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(callback){window.setTimeout(callback,1000/60);};})();
2164
2165    var easeInOutQuad = function (t, b, c, d) {
2166        t /= d/2;
2167        if (t < 1) return c/2*t*t + b;
2168        t--;
2169        return -c/2 * (t*(t-2) - 1) + b;
2170    };
2171
2172    var animatedScrollTo = function (element, to, duration, callback) {
2173        var start = element.scrollTop,
2174        change = to - start,
2175        animationStart = +new Date();
2176        var animating = true;
2177        var lastpos = null;
2178
2179        var animateScroll = function() {
2180            if (!animating) {
2181                return;
2182            }
2183            requestAnimFrame(animateScroll);
2184            var now = +new Date();
2185            var val = Math.floor(easeInOutQuad(now - animationStart, start, change, duration));
2186            if (lastpos) {
2187                if (lastpos === element.scrollTop) {
2188                    lastpos = val;
2189                    element.scrollTop = val;
2190                } else {
2191                    animating = false;
2192                }
2193            } else {
2194                lastpos = val;
2195                element.scrollTop = val;
2196            }
2197            if (now > animationStart + duration) {
2198                element.scrollTop = to;
2199                animating = false;
2200                if (callback) { callback(); }
2201            }
2202        };
2203        requestAnimFrame(animateScroll);
2204    };
2205
2206    if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
2207        module.exports = animatedScrollTo;
2208    } else {
2209        window.animatedScrollTo = animatedScrollTo;
2210    }
2211})(window);
2212
2213},{}],38:[function(require,module,exports){
2214/*
2215 * classList.js: Cross-browser full element.classList implementation.
2216 * 2014-07-23
2217 *
2218 * By Eli Grey, http://eligrey.com
2219 * Public Domain.
2220 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
2221 */
2222
2223/*global self, document, DOMException */
2224
2225/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
2226
2227/* Copied from MDN:
2228 * https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
2229 */
2230
2231if ("document" in window.self) {
2232
2233  // Full polyfill for browsers with no classList support
2234  // Including IE < Edge missing SVGElement.classList
2235  if (!("classList" in document.createElement("_"))
2236    || document.createElementNS && !("classList" in document.createElementNS("http://www.w3.org/2000/svg","g"))) {
2237
2238  (function (view) {
2239
2240    "use strict";
2241
2242    if (!('Element' in view)) return;
2243
2244    var
2245        classListProp = "classList"
2246      , protoProp = "prototype"
2247      , elemCtrProto = view.Element[protoProp]
2248      , objCtr = Object
2249      , strTrim = String[protoProp].trim || function () {
2250        return this.replace(/^\s+|\s+$/g, "");
2251      }
2252      , arrIndexOf = Array[protoProp].indexOf || function (item) {
2253        var
2254            i = 0
2255          , len = this.length
2256        ;
2257        for (; i < len; i++) {
2258          if (i in this && this[i] === item) {
2259            return i;
2260          }
2261        }
2262        return -1;
2263      }
2264      // Vendors: please allow content code to instantiate DOMExceptions
2265      , DOMEx = function (type, message) {
2266        this.name = type;
2267        this.code = DOMException[type];
2268        this.message = message;
2269      }
2270      , checkTokenAndGetIndex = function (classList, token) {
2271        if (token === "") {
2272          throw new DOMEx(
2273              "SYNTAX_ERR"
2274            , "An invalid or illegal string was specified"
2275          );
2276        }
2277        if (/\s/.test(token)) {
2278          throw new DOMEx(
2279              "INVALID_CHARACTER_ERR"
2280            , "String contains an invalid character"
2281          );
2282        }
2283        return arrIndexOf.call(classList, token);
2284      }
2285      , ClassList = function (elem) {
2286        var
2287            trimmedClasses = strTrim.call(elem.getAttribute("class") || "")
2288          , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
2289          , i = 0
2290          , len = classes.length
2291        ;
2292        for (; i < len; i++) {
2293          this.push(classes[i]);
2294        }
2295        this._updateClassName = function () {
2296          elem.setAttribute("class", this.toString());
2297        };
2298      }
2299      , classListProto = ClassList[protoProp] = []
2300      , classListGetter = function () {
2301        return new ClassList(this);
2302      }
2303    ;
2304    // Most DOMException implementations don't allow calling DOMException's toString()
2305    // on non-DOMExceptions. Error's toString() is sufficient here.
2306    DOMEx[protoProp] = Error[protoProp];
2307    classListProto.item = function (i) {
2308      return this[i] || null;
2309    };
2310    classListProto.contains = function (token) {
2311      token += "";
2312      return checkTokenAndGetIndex(this, token) !== -1;
2313    };
2314    classListProto.add = function () {
2315      var
2316          tokens = arguments
2317        , i = 0
2318        , l = tokens.length
2319        , token
2320        , updated = false
2321      ;
2322      do {
2323        token = tokens[i] + "";
2324        if (checkTokenAndGetIndex(this, token) === -1) {
2325          this.push(token);
2326          updated = true;
2327        }
2328      }
2329      while (++i < l);
2330
2331      if (updated) {
2332        this._updateClassName();
2333      }
2334    };
2335    classListProto.remove = function () {
2336      var
2337          tokens = arguments
2338        , i = 0
2339        , l = tokens.length
2340        , token
2341        , updated = false
2342        , index
2343      ;
2344      do {
2345        token = tokens[i] + "";
2346        index = checkTokenAndGetIndex(this, token);
2347        while (index !== -1) {
2348          this.splice(index, 1);
2349          updated = true;
2350          index = checkTokenAndGetIndex(this, token);
2351        }
2352      }
2353      while (++i < l);
2354
2355      if (updated) {
2356        this._updateClassName();
2357      }
2358    };
2359    classListProto.toggle = function (token, force) {
2360      token += "";
2361
2362      var
2363          result = this.contains(token)
2364        , method = result ?
2365          force !== true && "remove"
2366        :
2367          force !== false && "add"
2368      ;
2369
2370      if (method) {
2371        this[method](token);
2372      }
2373
2374      if (force === true || force === false) {
2375        return force;
2376      } else {
2377        return !result;
2378      }
2379    };
2380    classListProto.toString = function () {
2381      return this.join(" ");
2382    };
2383
2384    if (objCtr.defineProperty) {
2385      var classListPropDesc = {
2386          get: classListGetter
2387        , enumerable: true
2388        , configurable: true
2389      };
2390      try {
2391        objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
2392      } catch (ex) { // IE 8 doesn't support enumerable:true
2393        if (ex.number === -0x7FF5EC54) {
2394          classListPropDesc.enumerable = false;
2395          objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
2396        }
2397      }
2398    } else if (objCtr[protoProp].__defineGetter__) {
2399      elemCtrProto.__defineGetter__(classListProp, classListGetter);
2400    }
2401
2402    }(window.self));
2403
2404    } else {
2405    // There is full or partial native classList support, so just check if we need
2406    // to normalize the add/remove and toggle APIs.
2407
2408    (function () {
2409      "use strict";
2410
2411      var testElement = document.createElement("_");
2412
2413      testElement.classList.add("c1", "c2");
2414
2415      // Polyfill for IE 10/11 and Firefox <26, where classList.add and
2416      // classList.remove exist but support only one argument at a time.
2417      if (!testElement.classList.contains("c2")) {
2418        var createMethod = function(method) {
2419          var original = DOMTokenList.prototype[method];
2420
2421          DOMTokenList.prototype[method] = function(token) {
2422            var i, len = arguments.length;
2423
2424            for (i = 0; i < len; i++) {
2425              token = arguments[i];
2426              original.call(this, token);
2427            }
2428          };
2429        };
2430        createMethod('add');
2431        createMethod('remove');
2432      }
2433
2434      testElement.classList.toggle("c3", false);
2435
2436      // Polyfill for IE 10 and Firefox <24, where classList.toggle does not
2437      // support the second argument.
2438      if (testElement.classList.contains("c3")) {
2439        var _toggle = DOMTokenList.prototype.toggle;
2440
2441        DOMTokenList.prototype.toggle = function(token, force) {
2442          if (1 in arguments && !this.contains(token) === !force) {
2443            return force;
2444          } else {
2445            return _toggle.call(this, token);
2446          }
2447        };
2448
2449      }
2450
2451      testElement = null;
2452    }());
2453  }
2454}
2455
2456},{}],39:[function(require,module,exports){
2457/*
2458
2459© 2011 by Jerry Sievert
2460
2461Permission is hereby granted, free of charge, to any person obtaining a copy
2462of this software and associated documentation files (the "Software"), to deal
2463in the Software without restriction, including without limitation the rights
2464to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2465copies of the Software, and to permit persons to whom the Software is
2466furnished to do so, subject to the following conditions:
2467
2468The above copyright notice and this permission notice shall be included in
2469all copies or substantial portions of the Software.
2470
2471THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2472IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2473FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2474AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2475LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2476OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2477THE SOFTWARE.
2478
2479*/
2480
2481
2482(function () {
2483    /** @class Date */
2484    // constants
2485    var monthsAbbr = [], monthsFull = [], daysAbbr = [], daysFull = [], dayNames = {}, monthsAll, daysAll = [], monthNames = [];
2486    monthsAbbr = [
2487        'Jan',
2488        'Feb',
2489        'Mar',
2490        'Apr',
2491        'May',
2492        'Jun',
2493        'Jul',
2494        'Aug',
2495        'Sep',
2496        'Oct',
2497        'Nov',
2498        'Dec'
2499    ];
2500
2501    monthsFull = [
2502        'January',
2503        'February',
2504        'March',
2505        'April',
2506        'May',
2507        'June',
2508        'July',
2509        'August',
2510        'September',
2511        'October',
2512        'November',
2513        'December'
2514    ];
2515
2516    daysAbbr = [
2517        'Sun',
2518        'Mon',
2519        'Tue',
2520        'Wed',
2521        'Thu',
2522        'Fri',
2523        'Sat'
2524    ];
2525
2526    daysFull = [
2527        'Sunday',
2528        'Monday',
2529        'Tuesday',
2530        'Wednesday',
2531        'Thursday',
2532        'Friday',
2533        'Saturday'
2534    ];
2535
2536    dayNames = {
2537        'su':         0,
2538        'sun':        0,
2539        'sunday':     0,
2540        'mo':         1,
2541        'mon':        1,
2542        'monday':     1,
2543        'tu':         2,
2544        'tue':        2,
2545        'tuesday':    2,
2546        'we':         3,
2547        'wed':        3,
2548        'wednesday':  3,
2549        'th':         4,
2550        'thu':        4,
2551        'thursday':   4,
2552        'fr':         5,
2553        'fri':        5,
2554        'friday':     5,
2555        'sa':         6,
2556        'sat':        6,
2557        'saturday':   6
2558    };
2559    monthsAll = monthsFull.concat(monthsAbbr);
2560    daysAll = [
2561        'su',
2562        'sun',
2563        'sunday',
2564        'mo',
2565        'mon',
2566        'monday',
2567        'tu',
2568        'tue',
2569        'tuesday',
2570        'we',
2571        'wed',
2572        'wednesday',
2573        'th',
2574        'thu',
2575        'thursday',
2576        'fr',
2577        'fri',
2578        'friday',
2579        'sa',
2580        'sat',
2581        'saturday'
2582    ];
2583
2584    monthNames = {
2585        'jan':        0,
2586        'january':    0,
2587        'feb':        1,
2588        'february':   1,
2589        'mar':        2,
2590        'march':      2,
2591        'apr':        3,
2592        'april':      3,
2593        'may':        4,
2594        'jun':        5,
2595        'june':       5,
2596        'jul':        6,
2597        'july':       6,
2598        'aug':        7,
2599        'august':     7,
2600        'sep':        8,
2601        'september':  8,
2602        'oct':        9,
2603        'october':    9,
2604        'nov':        10,
2605        'november':   10,
2606        'dec':        11,
2607        'december':   11
2608    };
2609
2610    var daysInMonth = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];
2611
2612
2613    // private helper functions
2614    /** @ignore */
2615    function pad(str, length) {
2616        str = String(str);
2617        while (str.length < length) {
2618            str = '0' + str;
2619        }
2620        return str;
2621    }
2622
2623    var isInteger = function (str) {
2624        if (str.match(/^(\d+)$/)) {
2625            return true;
2626        }
2627        return false;
2628    };
2629    var getInt = function (str, i, minlength, maxlength) {
2630        for (var x = maxlength; x >= minlength; x--) {
2631            var token = str.substring(i, i + x);
2632            if (token.length < minlength) {
2633                return null;
2634            }
2635            if (isInteger(token)) {
2636                return token;
2637            }
2638        }
2639        return null;
2640    };
2641
2642    // static class methods
2643    var origParse = Date.parse;
2644    // ------------------------------------------------------------------
2645    // getDateFromFormat( date_string , format_string )
2646    //
2647    // This function takes a date string and a format string. It matches
2648    // If the date string matches the format string, it returns the
2649    // getTime() of the date. If it does not match, it returns NaN.
2650    // Original Author: Matt Kruse <[email protected]>
2651    // WWW: http://www.mattkruse.com/
2652    // Adapted from: http://www.mattkruse.com/javascript/date/source.html
2653    // ------------------------------------------------------------------
2654
2655
2656    var getDateFromFormat = function (val, format) {
2657        val = val + "";
2658        format = format + "";
2659        var iVal = 0;
2660        var iFormat = 0;
2661        var c = "";
2662        var token = "";
2663        var token2 = "";
2664        var x, y;
2665        var now = new Date();
2666        var year = now.getYear();
2667        var month = now.getMonth() + 1;
2668        var date = 1;
2669        var hh = 0;
2670        var mm = 0;
2671        var ss = 0;
2672        var ampm = "";
2673
2674
2675
2676        while (iFormat < format.length) {
2677            // Get next token from format string
2678            c = format.charAt(iFormat);
2679            token = "";
2680            while ((format.charAt(iFormat) === c) && (iFormat < format.length)) {
2681                token += format.charAt(iFormat++);
2682            }
2683            // Extract contents of value based on format token
2684            if (token === "yyyy" || token === "yy" || token === "y") {
2685                if (token === "yyyy") {
2686                    x = 4;
2687                    y = 4;
2688                }
2689                if (token === "yy") {
2690                    x = 2;
2691                    y = 2;
2692                }
2693                if (token === "y") {
2694                    x = 2;
2695                    y = 4;
2696                }
2697                year = getInt(val, iVal, x, y);
2698                if (year === null) {
2699                    return NaN;
2700                }
2701                iVal += year.length;
2702                if (year.length === 2) {
2703                    if (year > 70) {
2704                        year = 1900 + (year - 0);
2705                    } else {
2706                        year = 2000 + (year - 0);
2707                    }
2708                }
2709            } else if (token === "MMM" || token === "NNN") {
2710                month = 0;
2711                for (var i = 0; i < monthsAll.length; i++) {
2712                    var monthName = monthsAll[i];
2713                    if (val.substring(iVal, iVal + monthName.length).toLowerCase() === monthName.toLowerCase()) {
2714                        if (token === "MMM" || (token === "NNN" && i > 11)) {
2715                            month = i + 1;
2716                            if (month > 12) {
2717                                month -= 12;
2718                            }
2719                            iVal += monthName.length;
2720                            break;
2721                        }
2722                    }
2723                }
2724                if ((month < 1) || (month > 12)) {
2725                    return NaN;
2726                }
2727            } else if (token === "EE" || token === "E") {
2728                for (var n = 0; n < daysAll.length; n++) {
2729                    var dayName = daysAll[n];
2730                    if (val.substring(iVal, iVal + dayName.length).toLowerCase() === dayName.toLowerCase()) {
2731                        iVal += dayName.length;
2732                        break;
2733                    }
2734                }
2735            } else if (token === "MM" || token === "M") {
2736                month = getInt(val, iVal, token.length, 2);
2737                if (month === null || (month < 1) || (month > 12)) {
2738                    return NaN;
2739                }
2740                iVal += month.length;
2741            } else if (token === "dd" || token === "d") {
2742                date = getInt(val, iVal, token.length, 2);
2743                if (date === null || (date < 1) || (date > 31)) {
2744                    return NaN;
2745                }
2746                iVal += date.length;
2747            } else if (token === "hh" || token === "h") {
2748                hh = getInt(val, iVal, token.length, 2);
2749                if (hh === null || (hh < 1) || (hh > 12)) {
2750                    return NaN;
2751                }
2752                iVal += hh.length;
2753            } else if (token === "HH" || token === "H") {
2754                hh = getInt(val, iVal, token.length, 2);
2755                if (hh === null || (hh < 0) || (hh > 23)) {
2756                    return NaN;
2757                }
2758                iVal += hh.length;
2759            } else if (token === "KK" || token === "K") {
2760                hh = getInt(val, iVal, token.length, 2);
2761                if (hh === null || (hh < 0) || (hh > 11)) {
2762                    return NaN;
2763                }
2764                iVal += hh.length;
2765            } else if (token === "kk" || token === "k") {
2766                hh = getInt(val, iVal, token.length, 2);
2767                if (hh === null || (hh < 1) || (hh > 24)) {
2768                    return NaN;
2769                }
2770                iVal += hh.length;
2771                hh--;
2772            } else if (token === "mm" || token === "m") {
2773                mm = getInt(val, iVal, token.length, 2);
2774                if (mm === null || (mm < 0) || (mm > 59)) {
2775                    return NaN;
2776                }
2777                iVal += mm.length;
2778            } else if (token === "ss" || token === "s") {
2779                ss = getInt(val, iVal, token.length, 2);
2780                if (ss === null || (ss < 0) || (ss > 59)) {
2781                    return NaN;
2782                }
2783                iVal += ss.length;
2784            } else if (token === "a") {
2785                if (val.substring(iVal, iVal + 2).toLowerCase() === "am") {
2786                    ampm = "AM";
2787                } else if (val.substring(iVal, iVal + 2).toLowerCase() === "pm") {
2788                    ampm = "PM";
2789                } else {
2790                    return NaN;
2791                }
2792                iVal += 2;
2793            } else {
2794                if (val.substring(iVal, iVal + token.length) !== token) {
2795                    return NaN;
2796                } else {
2797                    iVal += token.length;
2798                }
2799            }
2800        }
2801        // If there are any trailing characters left in the value, it doesn't match
2802        if (iVal !== val.length) {
2803            return NaN;
2804        }
2805        // Is date valid for month?
2806        if (month === 2) {
2807            // Check for leap year
2808            if (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)) { // leap year
2809                if (date > 29) {
2810                    return NaN;
2811                }
2812            } else {
2813                if (date > 28) {
2814                    return NaN;
2815                }
2816            }
2817        }
2818        if ((month === 4) || (month === 6) || (month === 9) || (month === 11)) {
2819            if (date > 30) {
2820                return NaN;
2821            }
2822        }
2823        // Correct hours value
2824        if (hh < 12 && ampm === "PM") {
2825            hh = hh - 0 + 12;
2826        } else if (hh > 11 && ampm === "AM") {
2827            hh -= 12;
2828        }
2829        var newdate = new Date(year, month - 1, date, hh, mm, ss);
2830        return newdate.getTime();
2831    };
2832
2833
2834    /** @ignore */
2835    Date.parse = function (date, format) {
2836        if (format) {
2837            return getDateFromFormat(date, format);
2838        }
2839        var timestamp = origParse(date), minutesOffset = 0, match;
2840        if (isNaN(timestamp) && (match = /^(\d{4}|[+\-]\d{6})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3,}))?)?(?:(Z)|([+\-])(\d{2})(?::?(\d{2}))?))?/.exec(date))) {
2841            if (match[8] !== 'Z') {
2842                minutesOffset = +match[10] * 60 + (+match[11]);
2843
2844                if (match[9] === '+') {
2845                    minutesOffset = 0 - minutesOffset;
2846                }
2847            }
2848
2849            match[7] = match[7] || '000';
2850
2851            timestamp = Date.UTC(+match[1], +match[2] - 1, +match[3], +match[4], +match[5] + minutesOffset, +match[6], +match[7].substr(0, 3));
2852        }
2853
2854        return timestamp;
2855    };
2856
2857    function polyfill(name, func) {
2858        if (Date.prototype[name] === undefined) {
2859            Date.prototype[name] = func;
2860        }
2861    }
2862
2863    /**
2864        Returns new instance of Date object with the date set to today and
2865        the time set to midnight
2866        @static
2867        @returns {Date} Today's Date
2868        @function today
2869        @memberof Date
2870     */
2871    Date.today = function () {
2872        return new Date().clearTime();
2873    };
2874
2875    /**
2876        Returns new instance of Date object with the date set to today and
2877        the time set to midnight in UTC
2878        @static
2879        @returns {Date} Today's Date in UTC
2880        @function UTCtoday
2881        @memberof Date
2882     */
2883    Date.UTCtoday = function () {
2884        return new Date().clearUTCTime();
2885    };
2886
2887    /**
2888        Returns new instance of Date object with the date set to tomorrow and
2889        the time set to midnight
2890        @static
2891        @returns {Date} Tomorrow's Date
2892        @function tomorrow
2893        @memberof Date
2894     */
2895    Date.tomorrow = function () {
2896        return Date.today().add({days: 1});
2897    };
2898
2899    /**
2900        Returns new instance of Date object with the date set to tomorrow and
2901        the time set to midnight in UTC
2902        @static
2903        @returns {Date} Tomorrow's Date in UTC
2904        @function UTCtomorrow
2905        @memberof Date
2906     */
2907    Date.UTCtomorrow = function () {
2908        return Date.UTCtoday().add({days: 1});
2909    };
2910
2911    /**
2912        Returns new instance of Date object with the date set to yesterday and
2913        the time set to midnight
2914        @static
2915        @returns {Date} Yesterday's Date
2916        @function yesterday
2917        @memberof Date
2918     */
2919    Date.yesterday = function () {
2920        return Date.today().add({days: -1});
2921    };
2922
2923    /**
2924        Returns new instance of Date object with the date set to yesterday and
2925        the time set to midnight in UTC
2926        @static
2927        @returns {Date} Yesterday's Date in UTC
2928        @function UTCyesterday
2929        @memberof Date
2930     */
2931    Date.UTCyesterday = function () {
2932        return Date.UTCtoday().add({days: -1});
2933    };
2934
2935   /**
2936       Returns whether the day is valid
2937       @static
2938       @param day {Number} day of the month
2939       @param year {Number} year
2940       @param month {Number} month of the year [0-11]
2941       @returns {Boolean}
2942       @function validateDay
2943       @memberof Date
2944    */
2945    Date.validateDay = function (day, year, month) {
2946        var date = new Date(year, month, day);
2947        return (date.getFullYear() === year &&
2948            date.getMonth() === month &&
2949            date.getDate() === day);
2950    };
2951
2952    /**
2953       Returns whether the year is valid
2954       @static
2955       @param year {Number} year
2956       @returns {Boolean}
2957       @function validateYear
2958       @memberof Date
2959    */
2960    Date.validateYear = function (year) {
2961        return (year >= 0 && year <= 9999);
2962    };
2963
2964    /**
2965       Returns whether the second is valid
2966       @static
2967       @param second {Number} second
2968       @returns {Boolean}
2969       @function validateSecond
2970       @memberof Date
2971    */
2972    Date.validateSecond = function (second) {
2973        return (second >= 0 && second < 60);
2974    };
2975
2976    /**
2977       Returns whether the month is valid [0-11]
2978       @static
2979       @param month {Number} month
2980       @returns {Boolean}
2981       @function validateMonth
2982       @memberof Date
2983    */
2984    Date.validateMonth = function (month) {
2985        return (month >= 0 && month < 12);
2986    };
2987
2988    /**
2989       Returns whether the minute is valid
2990       @static
2991       @param minute {Number} minute
2992       @returns {Boolean}
2993       @function validateMinute
2994       @memberof Date
2995    */
2996    Date.validateMinute = function (minute) {
2997        return (minute >= 0 && minute < 60);
2998    };
2999
3000  /**
3001     Returns whether the millisecond is valid
3002     @static
3003     @param millisecond {Number} millisecond
3004     @returns {Boolean}
3005     @function validateMillisecond
3006     @memberof Date
3007  */
3008    Date.validateMillisecond = function (milli) {
3009        return (milli >= 0 && milli < 1000);
3010    };
3011
3012    /**
3013       Returns whether the hour is valid [0-23]
3014       @static
3015       @param hour {Number} hour
3016       @returns {Boolean}
3017       @function validateHour
3018       @memberof Date
3019    */
3020    Date.validateHour = function (hour) {
3021        return (hour >= 0 && hour < 24);
3022    };
3023
3024    /**
3025       Compares two dates
3026       @static
3027       @param date1 {Date} first date
3028       @param date2 {Date} second date
3029       @returns {Number} -1 if date1 is less than date2, 0 if they are equal, 1 if date1 is more than date2
3030       @function compare
3031       @memberof Date
3032    */
3033    Date.compare = function (date1, date2) {
3034        if (date1.valueOf() < date2.valueOf()) {
3035            return -1;
3036        } else if (date1.valueOf() > date2.valueOf()) {
3037            return 1;
3038        }
3039        return 0;
3040    };
3041
3042    /**
3043       Compares two dates to the millisecond
3044       @static
3045       @param date1 {Date} first date
3046       @param date2 {Date} second date
3047       @returns {Boolean}
3048       @function equals
3049       @memberof Date
3050    */
3051    Date.equals = function (date1, date2) {
3052        return date1.valueOf() === date2.valueOf();
3053    };
3054
3055    /**
3056       Compares two dates by day
3057       @static
3058       @param date1 {Date} first date
3059       @param date2 {Date} second date
3060       @returns {Boolean}
3061       @function equalsDay
3062       @memberof Date
3063    */
3064    Date.equalsDay = function (date1, date2) {
3065        return date1.toYMD() === date2.toYMD();
3066    };
3067
3068    /**
3069       Returns the day number for a day [0-6]
3070       @static
3071       @param day {String} day name
3072       @returns {Number}
3073       @function getDayNumberFromName
3074       @memberof Date
3075    */
3076    Date.getDayNumberFromName = function (name) {
3077        return dayNames[name.toLowerCase()];
3078    };
3079
3080    /**
3081       Returns the day number for a month [0-11]
3082       @static
3083       @param month {String} month name
3084       @returns {Number}
3085       @function getMonthNumberFromName
3086       @memberof Date
3087    */
3088    Date.getMonthNumberFromName = function (name) {
3089        return monthNames[name.toLowerCase()];
3090    };
3091
3092    /**
3093       Returns the month name for a month [0-11]
3094       @static
3095       @param month {Number} month
3096       @returns {String}
3097       @function getMonthNameFromNumber
3098       @memberof Date
3099    */
3100    Date.getMonthNameFromNumber = function (number) {
3101        return monthsFull[number];
3102    };
3103
3104    /**
3105       Returns the month name abbreviated for a month [0-11]
3106       @static
3107       @param month {Number} month
3108       @returns {String}
3109       @function getMonthAbbrFromNumber
3110       @memberof Date
3111    */
3112    Date.getMonthAbbrFromNumber = function (number) {
3113        return monthsAbbr[number];
3114    };
3115
3116    /**
3117       Returns whether or not the year is a leap year
3118       @static
3119       @param year {Number} year
3120       @returns {Boolean}
3121       @function isLeapYear
3122       @memberof Date
3123    */
3124    Date.isLeapYear = function (year) {
3125        return (new Date(year, 1, 29).getDate() === 29);
3126    };
3127
3128    /**
3129       Returns the number of days in a month
3130       @static
3131       @param year {Number} year
3132       @param month {Number} month
3133       @returns {Number}
3134       @function getDaysInMonth
3135       @memberof Date
3136    */
3137    Date.getDaysInMonth = function (year, month) {
3138        if (month === 1) {
3139            return Date.isLeapYear(year) ? 29 : 28;
3140        }
3141        return daysInMonth[month];
3142    };
3143
3144    /**
3145       Returns the abbreviated month name
3146       @returns {String}
3147       @function getMonthAbbr
3148       @instance
3149       @memberof Date
3150    */
3151    polyfill('getMonthAbbr', function () {
3152        return monthsAbbr[this.getMonth()];
3153    });
3154
3155    /**
3156       Returns the month name
3157       @returns {String}
3158       @function getMonthName
3159       @instance
3160       @memberof Date
3161    */
3162    polyfill('getMonthName', function () {
3163        return monthsFull[this.getMonth()];
3164    });
3165
3166    /**
3167       Returns the name of last month
3168       @returns {String}
3169       @function getLastMonthName
3170       @instance
3171       @memberof Date
3172    */
3173    polyfill('getLastMonthName', function () {
3174        var i = this.getMonth();
3175        i = (i === 0 ? 11 : i - 1);
3176        return monthsFull[i];
3177    });
3178
3179    /**
3180       Returns the current UTC office
3181       @returns {String}
3182       @function getUTCOffset
3183       @instance
3184       @memberof Date
3185    */
3186    polyfill('getUTCOffset', function () {
3187        var tz = pad(Math.abs(this.getTimezoneOffset() / 0.6), 4);
3188        if (this.getTimezoneOffset() > 0) {
3189            tz = '-' + tz;
3190        }
3191        return tz;
3192    });
3193
3194    /**
3195       Returns a padded Common Log Format
3196       @returns {String}
3197       @function toCLFString
3198       @deprecated Will be deprecated in version 2.0 in favor of toFormat
3199       @instance
3200       @memberof Date
3201    */
3202    polyfill('toCLFString',  function () {
3203        return pad(this.getDate(), 2) + '/' + this.getMonthAbbr() + '/' +
3204               this.getFullYear() + ':' + pad(this.getHours(), 2) + ':' +
3205               pad(this.getMinutes(), 2) + ':' + pad(this.getSeconds(), 2) +
3206               ' ' + this.getUTCOffset();
3207    });
3208
3209    /**
3210       Returns a padded Year/Month/Day
3211       @returns {String}
3212       @param separator {String} optional, defaults to "-"
3213       @function toYMD
3214       @deprecated Will be deprecated in version 2.0 in favor of toFormat
3215       @instance
3216       @memberof Date
3217    */
3218    polyfill('toYMD', function (separator) {
3219        separator = typeof separator === 'undefined' ? '-' : separator;
3220        return this.getFullYear() + separator + pad(this.getMonth() + 1, 2) +
3221            separator + pad(this.getDate(), 2);
3222    });
3223
3224    /**
3225       Returns a formatted String for database insertion
3226       @returns {String}
3227       @function toDBString
3228       @deprecated Will be deprecated in version 2.0 in favor of toFormat
3229       @instance
3230       @memberof Date
3231    */
3232    polyfill('toDBString', function () {
3233        return this.getUTCFullYear() + '-' +  pad(this.getUTCMonth() + 1, 2) +
3234               '-' + pad(this.getUTCDate(), 2) + ' ' + pad(this.getUTCHours(), 2) +
3235               ':' + pad(this.getUTCMinutes(), 2) + ':' + pad(this.getUTCSeconds(), 2);
3236    });
3237
3238    /**
3239       Sets the time to 00:00:00.0000 and returns a new Date object
3240       @returns {Date}
3241       @function clearTime
3242       @instance
3243       @memberof Date
3244    */
3245    polyfill('clearTime', function () {
3246        this.setHours(0);
3247        this.setMinutes(0);
3248        this.setSeconds(0);
3249        this.setMilliseconds(0);
3250
3251        return this;
3252    });
3253
3254    /**
3255       Sets the time to 00:00:00.0000 and returns a new Date object with set to UTC
3256       @returns {Date}
3257       @function clearUTCTime
3258       @instance
3259       @memberof Date
3260    */
3261    polyfill('clearUTCTime', function () {
3262        this.setUTCHours(0);
3263        this.setUTCMinutes(0);
3264        this.setUTCSeconds(0);
3265        this.setUTCMilliseconds(0);
3266
3267        return this;
3268    });
3269
3270    /**
3271       Adds `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years` and returns a new Date.
3272       Usage: `data.add({ "seconds": 10, "days": 1 })`
3273       @param additions {Object}
3274       @returns {Date}
3275       @function add
3276       @instance
3277       @memberof Date
3278    */
3279    polyfill('add', function (obj) {
3280        if (obj.milliseconds !== undefined) {
3281            this.setMilliseconds(this.getMilliseconds() + obj.milliseconds);
3282        }
3283        if (obj.seconds !== undefined) {
3284            this.setSeconds(this.getSeconds() + obj.seconds);
3285        }
3286        if (obj.minutes !== undefined) {
3287            this.setMinutes(this.getMinutes() + obj.minutes);
3288        }
3289        if (obj.hours !== undefined) {
3290            this.setHours(this.getHours() + obj.hours);
3291        }
3292        if (obj.days !== undefined) {
3293            this.setDate(this.getDate() + obj.days);
3294        }
3295        if (obj.weeks !== undefined) {
3296            this.setDate(this.getDate() + (obj.weeks * 7));
3297        }
3298        if (obj.months !== undefined) {
3299            this.setMonth(this.getMonth() + obj.months);
3300        }
3301        if (obj.years !== undefined) {
3302            this.setFullYear(this.getFullYear() + obj.years);
3303        }
3304        return this;
3305    });
3306
3307    /**
3308       Adds milliseconds to the Date and returns it
3309       @returns {Date}
3310       @param milliseconds {Number} Number of milliseconds to add
3311       @function addMilliseconds
3312       @deprecated Will be deprecated in version 2.0 in favor of add
3313       @instance
3314       @memberof Date
3315    */
3316    polyfill('addMilliseconds', function (milliseconds) {
3317        return this.add({ milliseconds: milliseconds });
3318    });
3319
3320    /**
3321       Adds seconds to the Date and returns it
3322       @returns {Date}
3323       @param seconds {Number} Number of seconds to add
3324       @function addSeconds
3325       @deprecated Will be deprecated in version 2.0 in favor of add
3326       @instance
3327       @memberof Date
3328    */
3329    polyfill('addSeconds', function (seconds) {
3330        return this.add({ seconds: seconds });
3331    });
3332
3333    /**
3334       Adds minutes to the Date and returns it
3335       @returns {Date}
3336       @param minutes {Number} Number of minutes to add
3337       @function addMinutes
3338       @deprecated Will be deprecated in version 2.0 in favor of add
3339       @instance
3340       @memberof Date
3341    */
3342    polyfill('addMinutes', function (minutes) {
3343        return this.add({ minutes: minutes });
3344    });
3345
3346    /**
3347       Adds hours to the Date and returns it
3348       @returns {Date}
3349       @param hours {Number} Number of hours to add
3350       @function addHours
3351       @deprecated Will be deprecated in version 2.0 in favor of add
3352       @instance
3353       @memberof Date
3354    */
3355    polyfill('addHours', function (hours) {
3356        return this.add({ hours: hours });
3357    });
3358
3359    /**
3360       Adds days to the Date and returns it
3361       @returns {Date}
3362       @param days {Number} Number of days to add
3363       @function addSeconds
3364       @deprecated Will be deprecated in version 2.0 in favor of add
3365       @instance
3366       @memberof Date
3367    */
3368    polyfill('addDays', function (days) {
3369        return this.add({ days: days });
3370    });
3371
3372    /**
3373       Adds weeks to the Date and returns it
3374       @returns {Date}
3375       @param weeks {Number} Number of weeks to add
3376       @function addWeeks
3377       @deprecated Will be deprecated in version 2.0 in favor of add
3378       @instance
3379       @memberof Date
3380    */
3381    polyfill('addWeeks', function (weeks) {
3382        return this.add({ days: (weeks * 7) });
3383    });
3384
3385    /**
3386       Adds months to the Date and returns it
3387       @returns {Date}
3388       @param months {Number} Number of months to add
3389       @function addMonths
3390       @deprecated Will be deprecated in version 2.0 in favor of add
3391       @instance
3392       @memberof Date
3393    */
3394    polyfill('addMonths', function (months) {
3395        return this.add({ months: months });
3396    });
3397
3398    /**
3399       Adds years to the Date and returns it
3400       @returns {Date}
3401       @param years {Number} Number of years to add
3402       @function addYears
3403       @deprecated Will be deprecated in version 2.0 in favor of add
3404       @instance
3405       @memberof Date
3406    */
3407    polyfill('addYears', function (years) {
3408        return this.add({ years: years });
3409    });
3410
3411    /**
3412       Removes `milliseconds`, `seconds`, `minutes`, `hours`, `days`, `weeks`, `months`, and `years` and returns a new Date.
3413       Usage: `data.remove({ "seconds": 10, "days": 1 })`
3414       @param removals {Object}
3415       @returns {Date}
3416       @function remove
3417       @instance
3418       @memberof Date
3419    */
3420    polyfill('remove', function (obj) {
3421        if (obj.seconds !== undefined) {
3422            this.setSeconds(this.getSeconds() - obj.seconds);
3423        }
3424        if (obj.minutes !== undefined) {
3425            this.setMinutes(this.getMinutes() - obj.minutes);
3426        }
3427        if (obj.hours !== undefined) {
3428            this.setHours(this.getHours() - obj.hours);
3429        }
3430        if (obj.days !== undefined) {
3431            this.setDate(this.getDate() - obj.days);
3432        }
3433        if (obj.weeks !== undefined) {
3434            this.setDate(this.getDate() - (obj.weeks * 7));
3435        }
3436        if (obj.months !== undefined) {
3437            this.setMonth(this.getMonth() - obj.months);
3438        }
3439        if (obj.years !== undefined) {
3440            this.setFullYear(this.getFullYear() - obj.years);
3441        }
3442        return this;
3443    });
3444
3445    /**
3446       Removes milliseconds from the Date and returns it
3447       @returns {Date}
3448       @param milliseconds {Number} Number of millseconds to remove
3449       @function removeMilliseconds
3450       @deprecated Will be deprecated in version 2.0 in favor of remove
3451       @instance
3452       @memberof Date
3453    */
3454    polyfill('removeMilliseconds', function (milliseconds) {
3455        throw new Error('Not implemented');
3456    });
3457
3458    /**
3459       Removes seconds from the Date and returns it
3460       @returns {Date}
3461       @param seconds {Number} Number of seconds to remove
3462       @function removeSeconds
3463       @deprecated Will be deprecated in version 2.0 in favor of remove
3464       @instance
3465       @memberof Date
3466    */
3467    polyfill('removeSeconds', function (seconds) {
3468        return this.remove({ seconds: seconds });
3469    });
3470
3471    /**
3472       Removes minutes from the Date and returns it
3473       @returns {Date}
3474       @param seconds {Number} Number of minutes to remove
3475       @function removeMinutes
3476       @deprecated Will be deprecated in version 2.0 in favor of remove
3477       @instance
3478       @memberof Date
3479    */
3480    polyfill('removeMinutes', function (minutes) {
3481        return this.remove({ minutes: minutes });
3482    });
3483
3484    /**
3485       Removes hours from the Date and returns it
3486       @returns {Date}
3487       @param hours {Number} Number of hours to remove
3488       @function removeHours
3489       @deprecated Will be deprecated in version 2.0 in favor of remove
3490       @instance
3491       @memberof Date
3492    */
3493    polyfill('removeHours', function (hours) {
3494        return this.remove({ hours: hours });
3495    });
3496
3497    /**
3498       Removes days from the Date and returns it
3499       @returns {Date}
3500       @param days {Number} Number of days to remove
3501       @function removeDays
3502       @deprecated Will be deprecated in version 2.0 in favor of remove
3503       @instance
3504       @memberof Date
3505    */
3506    polyfill('removeDays', function (days) {
3507        return this.remove({ days: days });
3508    });
3509
3510    /**
3511       Removes weeks from the Date and returns it
3512       @returns {Date}
3513       @param weeks {Number} Number of weeks to remove
3514       @function removeWeeks
3515       @deprecated Will be deprecated in version 2.0 in favor of remove
3516       @instance
3517       @memberof Date
3518    */
3519    polyfill('removeWeeks', function (weeks) {
3520        return this.remove({ days: (weeks * 7) });
3521    });
3522
3523    /**
3524       Removes months from the Date and returns it
3525       @returns {Date}
3526       @param months {Number} Number of months to remove
3527       @function removeMonths
3528       @deprecated Will be deprecated in version 2.0 in favor of remove
3529       @instance
3530       @memberof Date
3531    */
3532    polyfill('removeMonths', function (months) {
3533        return this.remove({ months: months });
3534    });
3535
3536    /**
3537       Removes years from the Date and returns it
3538       @returns {Date}
3539       @param years {Number} Number of years to remove
3540       @function removeYears
3541       @deprecated Will be deprecated in version 2.0 in favor of remove
3542       @instance
3543       @memberof Date
3544    */
3545    polyfill('removeYears', function (years) {
3546        return this.remove({ years: years });
3547    });
3548
3549    /**
3550       Adds weekdays based on a Mon-Fri work schedule and returns it
3551       @returns {Date}
3552       @param weekdays {Number} Number of weekdays to add
3553       @function addWeekdays
3554       @instance
3555       @memberof Date
3556    */
3557    polyfill('addWeekdays', function (weekdays) {
3558        var day = this.getDay();
3559        if (day === 0) { day = 7; }
3560        var daysOffset = weekdays;
3561        var weekspan = Math.floor(( weekdays + day - 1 ) / 5.0);
3562        if (weekdays > 0){
3563            daysOffset += weekspan * 2;
3564            if ( day > 5 ) { daysOffset -= day - 5; }
3565        } else {
3566            daysOffset += Math.min( weekspan * 2, 0);
3567            if ( day > 6 ) { daysOffset -= 1; }
3568        }
3569        return this.addDays( daysOffset );
3570    });
3571
3572    /**
3573       Sets the time and date to now
3574       @function setTimeToNow
3575       @instance
3576       @memberof Date
3577    */
3578    polyfill('setTimeToNow', function () {
3579        var n = new Date();
3580        this.setMilliseconds(n.getMilliseconds());
3581        this.setSeconds(n.getSeconds());
3582        this.setMinutes(n.getMinutes());
3583        this.setHours(n.getHours());
3584    });
3585
3586    /**
3587       Returns a cloned copy of the current Date
3588       @function clone
3589       @instance
3590       @memberof Date
3591    */
3592    polyfill('clone', function () {
3593        return new Date(this.valueOf());
3594    });
3595
3596    /**
3597       Returns whether this Date is between a start and end date
3598       @function between
3599       @returns {Boolean}
3600       @instance
3601       @memberof Date
3602    */
3603    polyfill('between', function (start, end) {
3604        return (this.valueOf() >= start.valueOf() &&
3605                this.valueOf() <= end.valueOf());
3606    });
3607    /**
3608       Compares a Date to this Date
3609       @param {Date} Date to compare to
3610       @function compareTo
3611       @returns {Number} -1 if less than date, 0 if they are equal, 1 if more than date
3612       @instance
3613       @memberof Date
3614    */
3615    polyfill('compareTo', function (date) {
3616        return Date.compare(this, date);
3617    });
3618
3619    /**
3620       Compares a Date and time to this Date and time for equality
3621       @param {Date} Date to compare to
3622       @function equals
3623       @returns {Boolean}
3624       @instance
3625       @memberof Date
3626    */
3627    polyfill('equals', function (date) {
3628        return Date.equals(this, date);
3629    });
3630
3631    /**
3632       Compares a Date to this Date for equality
3633       @param {Date} Date to compare to
3634       @function equalsDay
3635       @returns {Boolean}
3636       @instance
3637       @memberof Date
3638    */
3639    polyfill('equalsDay', function (date) {
3640        return Date.equalsDay(this, date);
3641    });
3642
3643    /**
3644       Checks to see if the Date is today
3645       @function isToday
3646       @returns {Boolean}
3647       @instance
3648       @memberof Date
3649    */
3650    polyfill('isToday', function () {
3651        return Date.equalsDay(this, Date.today());
3652    });
3653
3654    /**
3655       Compares a Date to this Date for to see if it is after the Date passed
3656       @param {Date} Date to compare to
3657       @function isAfter
3658       @returns {Boolean}
3659       @instance
3660       @memberof Date
3661    */
3662    polyfill('isAfter', function (date) {
3663        date = date ? date : new Date();
3664        return (this.compareTo(date) > 0);
3665    });
3666
3667    /**
3668       Compares a Date to this Date for to see if it is before the Date passed
3669       @param {Date} Date to compare to
3670       @function isBefore
3671       @returns {Boolean}
3672       @instance
3673       @memberof Date
3674    */
3675    polyfill('isBefore', function (date) {
3676        date = date ? date : new Date();
3677        return (this.compareTo(date) < 0);
3678    });
3679
3680    /**
3681       Returns `true` if the Date is a weekend using standard Saturday/Sunday definition of a weekend
3682       @function isWeekend
3683       @returns {Boolean}
3684       @instance
3685       @memberof Date
3686    */
3687    polyfill('isWeekend', function (date) {
3688        return (this.getDay() % 6 === 0);
3689    });
3690
3691    /**
3692       Returns the number of days between this Date and the Date passed in
3693       @function getDaysBetween
3694       @param {Date} Date to compare to
3695       @returns {Number}
3696       @instance
3697       @memberof Date
3698    */
3699    polyfill('getDaysBetween', function (date) {
3700        return ((date.clone().valueOf() - this.valueOf()) / 86400000) | 0;
3701    });
3702
3703    /**
3704       Returns the number of hours between this Date and the Date passed in
3705       @function getHoursBetween
3706       @param {Date} Date to compare to
3707       @returns {Number}
3708       @instance
3709       @memberof Date
3710    */
3711    polyfill('getHoursBetween', function (date) {
3712        return ((date.clone().valueOf() - this.valueOf()) / 3600000) | 0;
3713    });
3714
3715    /**
3716       Returns the number of minutes between this Date and the Date passed in
3717       @function getMinutesBetween
3718       @param {Date} Date to compare to
3719       @returns {Number}
3720       @instance
3721       @memberof Date
3722    */
3723    polyfill('getMinutesBetween', function (date) {
3724        return ((date.clone().valueOf() - this.valueOf()) / 60000) | 0;
3725    });
3726
3727    /**
3728       Returns the number of seconds between this Date and the Date passed in
3729       @function getSecondsBetween
3730       @param {Date} Date to compare to
3731       @returns {Number}
3732       @instance
3733       @memberof Date
3734    */
3735    polyfill('getSecondsBetween', function (date) {
3736        return ((date.clone().valueOf() - this.valueOf()) / 1000) | 0;
3737    });
3738
3739    /**
3740       Returns the number of milliseconds between this Date and the Date passed in
3741       @function getMillisecondsBetween
3742       @param {Date} Date to compare to
3743       @returns {Number}
3744       @instance
3745       @memberof Date
3746    */
3747    polyfill('getMillisecondsBetween', function (date) {
3748        return ((date.clone().valueOf() - this.valueOf())) | 0;
3749    });
3750
3751    /**
3752       Returns the number of months between this Date and the Date passed in
3753       @function getMonthsBetween
3754       @param {Date} Date to compare to
3755       @returns {Number}
3756       @instance
3757       @memberof Date
3758    */
3759    polyfill('getMonthsBetween', function (date) {
3760      var daysDiff = Math.abs(((+this) / (86400 * 1000)) - ((+date) / (86400 * 1000)));
3761      var start = new Date((+date) < (+this) ? (+date) : (+this));
3762      var end = new Date((date) > (+this) ? (+date) : (+this));
3763
3764      var months = 0;
3765      while (+start < +end) {
3766        months++;
3767        start = start.addMonths(1);
3768      }
3769
3770      var days = Math.abs(((+start) / (86400 * 1000)) - ((+end) / (86400 * 1000)));
3771
3772      return months - (days / 31);
3773    });
3774
3775    /**
3776       Returns the ordinal number of this Date
3777       @function getOrdinalNumber
3778       @returns {Number}
3779       @instance
3780       @memberof Date
3781    */
3782    polyfill('getOrdinalNumber', function () {
3783        return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 86400000) + 1;
3784    });
3785
3786    /**
3787       Returns the a formatted version of this Date
3788       @function toFormat
3789       @param format {String} Format of the Date, using `YYYY`, `YY`, `MM`, `DD`, `HH`, `HH24`, `MI`, `SS`, etc
3790       @returns {String}
3791       @instance
3792       @memberof Date
3793    */
3794    polyfill('toFormat', function (format) {
3795        return toFormat(format, getReplaceMap(this));
3796    });
3797
3798    /**
3799       Returns the a formatted version of the UTC version of this Date
3800       @function toUTCFormat
3801       @param format {String} Format of the Date, using `YYYY`, `YY`, `MM`, `DD`, `HH`, `HH24`, `MI`, `SS`, etc
3802       @returns {String}
3803       @instance
3804       @memberof Date
3805    */
3806    polyfill('toUTCFormat', function (format) {
3807        return toFormat(format, getUTCReplaceMap(this));
3808    });
3809
3810    /**
3811       Returns the week number of this Date
3812       @function getWeekNumber
3813       @returns {Number}
3814       @instance
3815       @memberof Date
3816    */
3817    polyfill('getWeekNumber', function() {
3818        var onejan = new Date(this.getFullYear(),0,1);
3819        return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
3820    });
3821
3822    /**
3823       Returns the week number of this Date, zero padded
3824       @function getFullWeekNumber
3825       @returns {Number}
3826       @instance
3827       @memberof Date
3828    */
3829    polyfill('getFullWeekNumber', function() {
3830        var weekNumber = '' + this.getWeekNumber();
3831        if (weekNumber.length === 1) {
3832            weekNumber = "0" + weekNumber;
3833        }
3834
3835        return weekNumber;
3836    });
3837
3838    var toFormat = function(format, replaceMap) {
3839        var f = [ format ], i, l, s;
3840        var replace = function (str, rep) {
3841            var i = 0, l = f.length, j, ll, t, n = [];
3842            for (; i < l; i++) {
3843                if (typeof f[i] == 'string') {
3844                    t = f[i].split(str);
3845                    for (j = 0, ll = t.length - 1; j < ll; j++) {
3846                        n.push(t[j]);
3847                        n.push([rep]); // replacement pushed as non-string
3848                    }
3849                    n.push(t[ll]);
3850                } else {
3851                    // must be a replacement, don't process, just push
3852                    n.push(f[i]);
3853                }
3854            }
3855            f = n;
3856        };
3857
3858        for (i in replaceMap) {
3859            replace(i, replaceMap[i]);
3860        }
3861
3862        s = '';
3863        for (i = 0, l = f.length; i < l; i++)
3864          s += typeof f[i] == 'string' ? f[i] : f[i][0];
3865        return f.join('');
3866    };
3867
3868    var getReplaceMap = function(date) {
3869        var hours = (date.getHours() % 12) ? date.getHours() % 12 : 12;
3870        return {
3871            'YYYY': date.getFullYear(),
3872            'YY': String(date.getFullYear()).slice(-2),
3873            'MMMM': monthsFull[date.getMonth()],
3874            'MMM': monthsAbbr[date.getMonth()],
3875            'MM': pad(date.getMonth() + 1, 2),
3876            'MI': pad(date.getMinutes(), 2),
3877            'M': date.getMonth() + 1,
3878            'DDDD': daysFull[date.getDay()],
3879            'DDD': daysAbbr[date.getDay()],
3880            'DD': pad(date.getDate(), 2),
3881            'D': date.getDate(),
3882            'HH24': pad(date.getHours(), 2),
3883            'HH': pad(hours, 2),
3884            'H': hours,
3885            'SS': pad(date.getSeconds(), 2),
3886            'PP': (date.getHours() >= 12) ? 'PM' : 'AM',
3887            'P': (date.getHours() >= 12) ? 'pm' : 'am',
3888            'LL': pad(date.getMilliseconds(), 3)
3889        };
3890    };
3891
3892    var getUTCReplaceMap = function(date) {
3893        var hours = (date.getUTCHours() % 12) ? date.getUTCHours() % 12 : 12;
3894        return {
3895            'YYYY': date.getUTCFullYear(),
3896            'YY': String(date.getUTCFullYear()).slice(-2),
3897            'MMMM': monthsFull[date.getUTCMonth()],
3898            'MMM': monthsAbbr[date.getUTCMonth()],
3899            'MM': pad(date.getUTCMonth() + 1, 2),
3900            'MI': pad(date.getUTCMinutes(), 2),
3901            'M': date.getUTCMonth() + 1,
3902            'DDDD': daysFull[date.getUTCDay()],
3903            'DDD': daysAbbr[date.getUTCDay()],
3904            'DD': pad(date.getUTCDate(), 2),
3905            'D': date.getUTCDate(),
3906            'HH24': pad(date.getUTCHours(), 2),
3907            'HH': pad(hours, 2),
3908            'H': hours,
3909            'SS': pad(date.getUTCSeconds(), 2),
3910            'PP': (date.getUTCHours() >= 12) ? 'PM' : 'AM',
3911            'P': (date.getUTCHours() >= 12) ? 'pm' : 'am',
3912            'LL': pad(date.getUTCMilliseconds(), 3)
3913        };
3914    };
3915
3916    /*
3917     * change the language
3918     * @param lang => support "es" Spanish, "fr" french, "pt-BR" Portuguese Brazil
3919     * translate => diego
3920     */
3921    var language = function (lang) {
3922        if (lang == "es") {
3923            monthsAbbr = [
3924                'Ene',
3925                'Feb',
3926                'Mar',
3927                'Abr',
3928                'May',
3929                'Jun',
3930                'Jul',
3931                'Ago',
3932                'Sep',
3933                'Oct',
3934                'Nov',
3935                'Dic'
3936            ];
3937
3938            monthsFull = [
3939                'Enero',
3940                'Febrero',
3941                'Marzo',
3942                'Abril',
3943                'Mayo',
3944                'Junio',
3945                'Julio',
3946                'Agosto',
3947                'Septiembre',
3948                'Octubre',
3949                'Noviembre',
3950                'Diciembre'
3951            ];
3952
3953            daysAbbr = [
3954                'Dom',
3955                'Lun',
3956                'Mar',
3957                'Mie',
3958                'Jue',
3959                'Vie',
3960                'Sab'
3961            ];
3962
3963            daysFull = [
3964                'Domingo',
3965                'Lunes',
3966                'Martes',
3967                'Miércoles',
3968                'Jueves',
3969                'Viernes',
3970                'Sábado'
3971            ];
3972
3973            dayNames = {
3974                'do': 0,
3975                'dom': 0,
3976                'domingo': 0,
3977                'lu': 1,
3978                'lun': 1,
3979                'lunes': 1,
3980                'ma': 2,
3981                'mar': 2,
3982                'martes': 2,
3983                'mi': 3,
3984                'mie': 3,
3985                'miercoles': 3,
3986                'ju': 4,
3987                'jue': 4,
3988                'jueves': 4,
3989                'vi': 5,
3990                'vie': 5,
3991                'viernes': 5,
3992                'sa': 6,
3993                'sab': 6,
3994                'sabado': 6
3995            };
3996            monthsAll = monthsFull.concat(monthsAbbr);
3997            daysAll = [
3998                'do',
3999                'dom',
4000                'domingo',
4001                'lu',
4002                'lun',
4003                'lunes',
4004                'ma',
4005                'mar',
4006                'martes',
4007                'mi',
4008                'mie',
4009                'miércoles',
4010                'ju',
4011                'jue',
4012                'jueves',
4013                'vi',
4014                'vie',
4015                'viernes',
4016                'sa',
4017                'sab',
4018                'sábado'
4019            ];
4020
4021            monthNames = {
4022                'ene': 0,
4023                'enero': 0,
4024                'feb': 1,
4025                'febrero': 1,
4026                'mar': 2,
4027                'marzo': 2,
4028                'abr': 3,
4029                'abril': 3,
4030                'may': 4,
4031                'mayo':4,
4032                'jun': 5,
4033                'junio': 5,
4034                'jul': 6,
4035                'julio': 6,
4036                'ago': 7,
4037                'agosto': 7,
4038                'sep': 8,
4039                'septiembre': 8,
4040                'oct': 9,
4041                'octubre': 9,
4042                'nov': 10,
4043                'noviembre': 10,
4044                'dic': 11,
4045                'diciembre': 11
4046            };
4047        } else if (lang == "fr") {
4048            monthsAbbr = [
4049                'Jan',
4050                'Fév',
4051                'Mar',
4052                'Avr',
4053                'Mai',
4054                'Jui',
4055                'Jul',
4056                'Aoû',
4057                'Sep',
4058                'Oct',
4059                'Nov',
4060                'Déc'
4061            ];
4062
4063            monthsFull = [
4064                'Janvier',
4065                'Février',
4066                'Mars',
4067                'Avril',
4068                'Mai',
4069                'Juin',
4070                'Juillet',
4071                'Août',
4072                'Septembre',
4073                'Octobre',
4074                'Novembre',
4075                'Décembre'
4076            ];
4077
4078            daysAbbr = [
4079                'Dim',
4080                'Lun',
4081                'Mar',
4082                'Mer',
4083                'Jeu',
4084                'Ven',
4085                'Sam'
4086            ];
4087
4088            daysFull = [
4089                'Dimanchi',
4090                'Lundi',
4091                'Mardi',
4092                'Mercredi',
4093                'Jeudi',
4094                'Vendredi',
4095                'Samedi'
4096            ];
4097
4098            dayNames = {
4099                'di': 0,
4100                'dim': 0,
4101                'dimanchi': 0,
4102                'lu': 1,
4103                'lun': 1,
4104                'lundi': 1,
4105                'ma': 2,
4106                'mar': 2,
4107                'mardi': 2,
4108                'me': 3,
4109                'mer': 3,
4110                'mercredi': 3,
4111                'je': 4,
4112                'jeu': 4,
4113                'jeudi': 4,
4114                've': 5,
4115                'ven': 5,
4116                'vendredi': 5,
4117                'sa': 6,
4118                'sam': 6,
4119                'samedi': 6
4120            };
4121            monthsAll = monthsFull.concat(monthsAbbr);
4122            daysAll = [
4123                'di',
4124                'dim',
4125                'dimanchi',
4126                'lu',
4127                'lun',
4128                'lundi',
4129                'ma',
4130                'mar',
4131                'mardi',
4132                'me',
4133                'mer',
4134                'mercredi',
4135                'je',
4136                'jeu',
4137                'jeudi',
4138                've',
4139                'ven',
4140                'vendredi',
4141                'sa',
4142                'sam',
4143                'samedi'
4144            ];
4145
4146            monthNames = {
4147                'jan': 0,
4148                'janvier': 0,
4149                'fév': 1,
4150                'février': 1,
4151                'mar': 2,
4152                'mars': 2,
4153                'avr': 3,
4154                'avril': 3,
4155                'mai': 4,
4156                'jui': 5,
4157                'juin': 5,
4158                'jul': 6,
4159                'juillet': 6,
4160                'aoû': 7,
4161                'août': 7,
4162                'sep': 8,
4163                'septembre': 8,
4164                'oct': 9,
4165                'octobre': 9,
4166                'nov': 10,
4167                'novembre': 10,
4168                'déc': 11,
4169                'décembre': 11
4170            };
4171        } else if (lang == "pt-BR") {
4172            monthsAbbr = [
4173                'Jan',
4174                'Fev',
4175                'Mar',
4176                'Abr',
4177                'Mai',
4178                'Jun',
4179                'Jul',
4180                'Ago',
4181                'Set',
4182                'Out',
4183                'Nov',
4184                'Dez'
4185            ];
4186
4187            monthsFull = [
4188                'Janeiro',
4189                'Fevereiro',
4190                'Março',
4191                'Abril',
4192                'Maio',
4193                'Junho',
4194                'Julho',
4195                'Agosto',
4196                'Setembro',
4197                'Outubro',
4198                'Novembro',
4199                'Dezembro'
4200            ];
4201
4202            daysAbbr = [
4203                'Dom',
4204                'Seg',
4205                'Ter',
4206                'Qua',
4207                'Qui',
4208                'Sex',
4209                'Sab'
4210            ];
4211
4212            daysFull = [
4213                'Domingo',
4214                'Segunda',
4215                'Terça',
4216                'Quarta',
4217                'Quinta',
4218                'Sexta',
4219                'Sábado'
4220            ];
4221
4222            dayNames = {
4223                'do': 0,
4224                'dom': 0,
4225                'domingo': 0,
4226                'se': 1,
4227                'seg': 1,
4228                'segunda': 1,
4229                'te': 2,
4230                'ter': 2,
4231                'terca': 2,
4232                'qa': 3,
4233                'qua': 3,
4234                'quarta': 3,
4235                'qi': 4,
4236                'qui': 4,
4237                'quinta': 4,
4238                'se': 5,
4239                'sex': 5,
4240                'sexta': 5,
4241                'sa': 6,
4242                'sab': 6,
4243                'sabado': 6
4244            };
4245            monthsAll = monthsFull.concat(monthsAbbr);
4246            daysAll = [
4247                'do',
4248                'dom',
4249                'domingo',
4250                'se',
4251                'seg',
4252                'segunda',
4253                'te',
4254                'ter',
4255                'terça',
4256                'qa',
4257                'qua',
4258                'quarta',
4259                'qi',
4260                'qui',
4261                'quinta',
4262                'se',
4263                'sex',
4264                'sexta',
4265                'sa',
4266                'sab',
4267                'sábado'
4268            ];
4269
4270            monthNames = {
4271                'jan': 0,
4272                'janeiro': 0,
4273                'fev': 1,
4274                'fevereiro': 1,
4275                'mar': 2,
4276                'março': 2,
4277                'abr': 3,
4278                'abril': 3,
4279                'mai': 4,
4280                'jun': 5,
4281                'junho': 5,
4282                'jul': 6,
4283                'julho': 6,
4284                'ago': 7,
4285                'agosto': 7,
4286                'set': 8,
4287                'setembro': 8,
4288                'out': 9,
4289                'outubro': 9,
4290                'nov': 10,
4291                'novembro': 10,
4292                'dez': 11,
4293                'dezembro': 11
4294            };
4295        }
4296    };
4297
4298    // Are we being imported?..
4299    if (typeof module !== "undefined" && typeof module.exports === "object") {
4300        module.exports.language = language;
4301    } else if (typeof exports === "object") {
4302        exports.language = language;
4303    } else if (typeof Date.language === "undefined"){
4304        // ...if not and if no language, then add statically to Date (for browsers.)
4305        Date.language = language;
4306    }
4307}());
4308
4309},{}],40:[function(require,module,exports){
4310/**
4311 * Returns a function, that, as long as it continues to be invoked, will not
4312 * be triggered. The function will be called after it stops being called for
4313 * N milliseconds. If `immediate` is passed, trigger the function on the
4314 * leading edge, instead of the trailing. The function also has a property 'clear' 
4315 * that is a function which will clear the timer to prevent previously scheduled executions. 
4316 *
4317 * @source underscore.js
4318 * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/
4319 * @param {Function} function to wrap
4320 * @param {Number} timeout in ms (`100`)
4321 * @param {Boolean} whether to execute at the beginning (`false`)
4322 * @api public
4323 */
4324
4325module.exports = function debounce(func, wait, immediate){
4326  var timeout, args, context, timestamp, result;
4327  if (null == wait) wait = 100;
4328
4329  function later() {
4330    var last = Date.now() - timestamp;
4331
4332    if (last < wait && last >= 0) {
4333      timeout = setTimeout(later, wait - last);
4334    } else {
4335      timeout = null;
4336      if (!immediate) {
4337        result = func.apply(context, args);
4338        context = args = null;
4339      }
4340    }
4341  };
4342
4343  var debounced = function(){
4344    context = this;
4345    args = arguments;
4346    timestamp = Date.now();
4347    var callNow = immediate && !timeout;
4348    if (!timeout) timeout = setTimeout(later, wait);
4349    if (callNow) {
4350      result = func.apply(context, args);
4351      context = args = null;
4352    }
4353
4354    return result;
4355  };
4356
4357  debounced.clear = function() {
4358    if (timeout) {
4359      clearTimeout(timeout);
4360      timeout = null;
4361    }
4362  };
4363
4364  return debounced;
4365};
4366
4367},{}],41:[function(require,module,exports){
4368'use strict';
4369
4370var hasOwn = Object.prototype.hasOwnProperty;
4371var toStr = Object.prototype.toString;
4372var defineProperty = Object.defineProperty;
4373var gOPD = Object.getOwnPropertyDescriptor;
4374
4375var isArray = function isArray(arr) {
4376	if (typeof Array.isArray === 'function') {
4377		return Array.isArray(arr);
4378	}
4379
4380	return toStr.call(arr) === '[object Array]';
4381};
4382
4383var isPlainObject = function isPlainObject(obj) {
4384	if (!obj || toStr.call(obj) !== '[object Object]') {
4385		return false;
4386	}
4387
4388	var hasOwnConstructor = hasOwn.call(obj, 'constructor');
4389	var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
4390	// Not own constructor property must be Object
4391	if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
4392		return false;
4393	}
4394
4395	// Own properties are enumerated firstly, so to speed up,
4396	// if last one is own, then all properties are own.
4397	var key;
4398	for (key in obj) { /**/ }
4399
4400	return typeof key === 'undefined' || hasOwn.call(obj, key);
4401};
4402
4403// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
4404var setProperty = function setProperty(target, options) {
4405	if (defineProperty && options.name === '__proto__') {
4406		defineProperty(target, options.name, {
4407			enumerable: true,
4408			configurable: true,
4409			value: options.newValue,
4410			writable: true
4411		});
4412	} else {
4413		target[options.name] = options.newValue;
4414	}
4415};
4416
4417// Return undefined instead of __proto__ if '__proto__' is not an own property
4418var getProperty = function getProperty(obj, name) {
4419	if (name === '__proto__') {
4420		if (!hasOwn.call(obj, name)) {
4421			return void 0;
4422		} else if (gOPD) {
4423			// In early versions of node, obj['__proto__'] is buggy when obj has
4424			// __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
4425			return gOPD(obj, name).value;
4426		}
4427	}
4428
4429	return obj[name];
4430};
4431
4432module.exports = function extend() {
4433	var options, name, src, copy, copyIsArray, clone;
4434	var target = arguments[0];
4435	var i = 1;
4436	var length = arguments.length;
4437	var deep = false;
4438
4439	// Handle a deep copy situation
4440	if (typeof target === 'boolean') {
4441		deep = target;
4442		target = arguments[1] || {};
4443		// skip the boolean and the target
4444		i = 2;
4445	}
4446	if (target == null || (typeof target !== 'object' && typeof target !== 'function')) {
4447		target = {};
4448	}
4449
4450	for (; i < length; ++i) {
4451		options = arguments[i];
4452		// Only deal with non-null/undefined values
4453		if (options != null) {
4454			// Extend the base object
4455			for (name in options) {
4456				src = getProperty(target, name);
4457				copy = getProperty(options, name);
4458
4459				// Prevent never-ending loop
4460				if (target !== copy) {
4461					// Recurse if we're merging plain objects or arrays
4462					if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
4463						if (copyIsArray) {
4464							copyIsArray = false;
4465							clone = src && isArray(src) ? src : [];
4466						} else {
4467							clone = src && isPlainObject(src) ? src : {};
4468						}
4469
4470						// Never move original objects, clone them
4471						setProperty(target, { name: name, newValue: extend(deep, clone, copy) });
4472
4473					// Don't bring in undefined values
4474					} else if (typeof copy !== 'undefined') {
4475						setProperty(target, { name: name, newValue: copy });
4476					}
4477				}
4478			}
4479		}
4480	}
4481
4482	// Return the modified object
4483	return target;
4484};
4485
4486},{}],42:[function(require,module,exports){
4487module.exports = require("handlebars/runtime")["default"];
4488
4489},{"handlebars/runtime":93}],43:[function(require,module,exports){
4490/**
4491 * lodash 3.0.0 (Custom Build) <https://lodash.com/>
4492 * Build: `lodash modern modularize exports="npm" -o ./`
4493 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4494 * Based on Underscore.js 1.7.0 <http://underscorejs.org/LICENSE>
4495 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4496 * Available under MIT license <https://lodash.com/license>
4497 */
4498
4499/**
4500 * A specialized version of `_.forEach` for arrays without support for callback
4501 * shorthands or `this` binding.
4502 *
4503 * @private
4504 * @param {Array} array The array to iterate over.
4505 * @param {Function} iteratee The function invoked per iteration.
4506 * @returns {Array} Returns `array`.
4507 */
4508function arrayEach(array, iteratee) {
4509  var index = -1,
4510      length = array.length;
4511
4512  while (++index < length) {
4513    if (iteratee(array[index], index, array) === false) {
4514      break;
4515    }
4516  }
4517  return array;
4518}
4519
4520module.exports = arrayEach;
4521
4522},{}],44:[function(require,module,exports){
4523/**
4524 * lodash 3.2.0 (Custom Build) <https://lodash.com/>
4525 * Build: `lodash modern modularize exports="npm" -o ./`
4526 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4527 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4528 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4529 * Available under MIT license <https://lodash.com/license>
4530 */
4531var baseCopy = require('lodash._basecopy'),
4532    keys = require('lodash.keys');
4533
4534/**
4535 * The base implementation of `_.assign` without support for argument juggling,
4536 * multiple sources, and `customizer` functions.
4537 *
4538 * @private
4539 * @param {Object} object The destination object.
4540 * @param {Object} source The source object.
4541 * @returns {Object} Returns `object`.
4542 */
4543function baseAssign(object, source) {
4544  return source == null
4545    ? object
4546    : baseCopy(source, keys(source), object);
4547}
4548
4549module.exports = baseAssign;
4550
4551},{"lodash._basecopy":45,"lodash.keys":67}],45:[function(require,module,exports){
4552/**
4553 * lodash 3.0.1 (Custom Build) <https://lodash.com/>
4554 * Build: `lodash modern modularize exports="npm" -o ./`
4555 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4556 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4557 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4558 * Available under MIT license <https://lodash.com/license>
4559 */
4560
4561/**
4562 * Copies properties of `source` to `object`.
4563 *
4564 * @private
4565 * @param {Object} source The object to copy properties from.
4566 * @param {Array} props The property names to copy.
4567 * @param {Object} [object={}] The object to copy properties to.
4568 * @returns {Object} Returns `object`.
4569 */
4570function baseCopy(source, props, object) {
4571  object || (object = {});
4572
4573  var index = -1,
4574      length = props.length;
4575
4576  while (++index < length) {
4577    var key = props[index];
4578    object[key] = source[key];
4579  }
4580  return object;
4581}
4582
4583module.exports = baseCopy;
4584
4585},{}],46:[function(require,module,exports){
4586/**
4587 * lodash 3.7.2 (Custom Build) <https://lodash.com/>
4588 * Build: `lodash modern modularize exports="npm" -o ./`
4589 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4590 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4591 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4592 * Available under MIT license <https://lodash.com/license>
4593 */
4594
4595/**
4596 * The base implementation of `get` without support for string paths
4597 * and default values.
4598 *
4599 * @private
4600 * @param {Object} object The object to query.
4601 * @param {Array} path The path of the property to get.
4602 * @param {string} [pathKey] The key representation of path.
4603 * @returns {*} Returns the resolved value.
4604 */
4605function baseGet(object, path, pathKey) {
4606  if (object == null) {
4607    return;
4608  }
4609  if (pathKey !== undefined && pathKey in toObject(object)) {
4610    path = [pathKey];
4611  }
4612  var index = 0,
4613      length = path.length;
4614
4615  while (object != null && index < length) {
4616    object = object[path[index++]];
4617  }
4618  return (index && index == length) ? object : undefined;
4619}
4620
4621/**
4622 * Converts `value` to an object if it's not one.
4623 *
4624 * @private
4625 * @param {*} value The value to process.
4626 * @returns {Object} Returns the object.
4627 */
4628function toObject(value) {
4629  return isObject(value) ? value : Object(value);
4630}
4631
4632/**
4633 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
4634 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
4635 *
4636 * @static
4637 * @memberOf _
4638 * @category Lang
4639 * @param {*} value The value to check.
4640 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
4641 * @example
4642 *
4643 * _.isObject({});
4644 * // => true
4645 *
4646 * _.isObject([1, 2, 3]);
4647 * // => true
4648 *
4649 * _.isObject(1);
4650 * // => false
4651 */
4652function isObject(value) {
4653  // Avoid a V8 JIT bug in Chrome 19-20.
4654  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
4655  var type = typeof value;
4656  return !!value && (type == 'object' || type == 'function');
4657}
4658
4659module.exports = baseGet;
4660
4661},{}],47:[function(require,module,exports){
4662/**
4663 * lodash 3.0.3 (Custom Build) <https://lodash.com/>
vendor: 5,194 bytes, lines 4664-4827
4664 * Build: `lodash modern modularize exports="npm" -o ./`
4665 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4666 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4667 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4668 * Available under MIT license <https://lodash.com/license>
4669 */
4670
4671/**
4672 * The base implementation of `_.slice` without an iteratee call guard.
4673 *
4674 * @private
4675 * @param {Array} array The array to slice.
4676 * @param {number} [start=0] The start position.
4677 * @param {number} [end=array.length] The end position.
4678 * @returns {Array} Returns the slice of `array`.
4679 */
4680function baseSlice(array, start, end) {
4681  var index = -1,
4682      length = array.length;
4683
4684  start = start == null ? 0 : (+start || 0);
4685  if (start < 0) {
4686    start = -start > length ? 0 : (length + start);
4687  }
4688  end = (end === undefined || end > length) ? length : (+end || 0);
4689  if (end < 0) {
4690    end += length;
4691  }
4692  length = start > end ? 0 : ((end - start) >>> 0);
4693  start >>>= 0;
4694
4695  var result = Array(length);
4696  while (++index < length) {
4697    result[index] = array[index + start];
4698  }
4699  return result;
4700}
4701
4702module.exports = baseSlice;
4703
4704},{}],48:[function(require,module,exports){
4705/**
4706 * lodash 3.0.1 (Custom Build) <https://lodash.com/>
4707 * Build: `lodash modern modularize exports="npm" -o ./`
4708 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4709 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4710 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4711 * Available under MIT license <https://lodash.com/license>
4712 */
4713
4714/**
4715 * A specialized version of `baseCallback` which only supports `this` binding
4716 * and specifying the number of arguments to provide to `func`.
4717 *
4718 * @private
4719 * @param {Function} func The function to bind.
4720 * @param {*} thisArg The `this` binding of `func`.
4721 * @param {number} [argCount] The number of arguments to provide to `func`.
4722 * @returns {Function} Returns the callback.
4723 */
4724function bindCallback(func, thisArg, argCount) {
4725  if (typeof func != 'function') {
4726    return identity;
4727  }
4728  if (thisArg === undefined) {
4729    return func;
4730  }
4731  switch (argCount) {
4732    case 1: return function(value) {
4733      return func.call(thisArg, value);
4734    };
4735    case 3: return function(value, index, collection) {
4736      return func.call(thisArg, value, index, collection);
4737    };
4738    case 4: return function(accumulator, value, index, collection) {
4739      return func.call(thisArg, accumulator, value, index, collection);
4740    };
4741    case 5: return function(value, other, key, object, source) {
4742      return func.call(thisArg, value, other, key, object, source);
4743    };
4744  }
4745  return function() {
4746    return func.apply(thisArg, arguments);
4747  };
4748}
4749
4750/**
4751 * This method returns the first argument provided to it.
4752 *
4753 * @static
4754 * @memberOf _
4755 * @category Utility
4756 * @param {*} value Any value.
4757 * @returns {*} Returns `value`.
4758 * @example
4759 *
4760 * var object = { 'user': 'fred' };
4761 *
4762 * _.identity(object) === object;
4763 * // => true
4764 */
4765function identity(value) {
4766  return value;
4767}
4768
4769module.exports = bindCallback;
4770
4771},{}],49:[function(require,module,exports){
4772/**
4773 * lodash 3.1.1 (Custom Build) <https://lodash.com/>
4774 * Build: `lodash modern modularize exports="npm" -o ./`
4775 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4776 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4777 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4778 * Available under MIT license <https://lodash.com/license>
4779 */
4780var bindCallback = require('lodash._bindcallback'),
4781    isIterateeCall = require('lodash._isiterateecall'),
4782    restParam = require('lodash.restparam');
4783
4784/**
4785 * Creates a function that assigns properties of source object(s) to a given
4786 * destination object.
4787 *
4788 * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`.
4789 *
4790 * @private
4791 * @param {Function} assigner The function to assign values.
4792 * @returns {Function} Returns the new assigner function.
4793 */
4794function createAssigner(assigner) {
4795  return restParam(function(object, sources) {
4796    var index = -1,
4797        length = object == null ? 0 : sources.length,
4798        customizer = length > 2 ? sources[length - 2] : undefined,
4799        guard = length > 2 ? sources[2] : undefined,
4800        thisArg = length > 1 ? sources[length - 1] : undefined;
4801
4802    if (typeof customizer == 'function') {
4803      customizer = bindCallback(customizer, thisArg, 5);
4804      length -= 2;
4805    } else {
4806      customizer = typeof thisArg == 'function' ? thisArg : undefined;
4807      length -= (customizer ? 1 : 0);
4808    }
4809    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4810      customizer = length < 3 ? undefined : customizer;
4811      length = 1;
4812    }
4813    while (++index < length) {
4814      var source = sources[index];
4815      if (source) {
4816        assigner(object, source, customizer);
4817      }
4818    }
4819    return object;
4820  });
4821}
4822
4823module.exports = createAssigner;
4824
4825},{"lodash._bindcallback":48,"lodash._isiterateecall":52,"lodash.restparam":69}],50:[function(require,module,exports){
4826/**
4827 * lodash 3.2.0 (Custom Build) <https://lodash.com/>
4828 * Build: `lodash modularize exports="npm" -o ./`
4829 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
4830 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4831 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4832 * Available under MIT license <https://lodash.com/license>
4833 */
4834var root = require('lodash._root');
4835
4836/** Used to compose bitmasks for wrapper metadata. */
4837var BIND_FLAG = 1,
4838    BIND_KEY_FLAG = 2,
4839    CURRY_BOUND_FLAG = 4,
4840    CURRY_FLAG = 8,
4841    CURRY_RIGHT_FLAG = 16,
4842    PARTIAL_FLAG = 32,
4843    PARTIAL_RIGHT_FLAG = 64,
4844    ARY_FLAG = 128,
4845    FLIP_FLAG = 512;
4846
4847/** Used as the `TypeError` message for "Functions" methods. */
4848var FUNC_ERROR_TEXT = 'Expected a function';
4849
4850/** Used as references for various `Number` constants. */
4851var INFINITY = 1 / 0,
4852    MAX_SAFE_INTEGER = 9007199254740991,
4853    MAX_INTEGER = 1.7976931348623157e+308,
4854    NAN = 0 / 0;
4855
4856/** Used as the internal argument placeholder. */
4857var PLACEHOLDER = '__lodash_placeholder__';
4858
4859/** `Object#toString` result references. */
4860var funcTag = '[object Function]',
4861    genTag = '[object GeneratorFunction]';
4862
4863/** Used to match leading and trailing whitespace. */
4864var reTrim = /^\s+|\s+$/g;
4865
4866/** Used to detect bad signed hexadecimal string values. */
4867var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
4868
4869/** Used to detect binary string values. */
4870var reIsBinary = /^0b[01]+$/i;
4871
4872/** Used to detect octal string values. */
4873var reIsOctal = /^0o[0-7]+$/i;
4874
4875/** Used to detect unsigned integer values. */
4876var reIsUint = /^(?:0|[1-9]\d*)$/;
4877
4878/** Built-in method references without a dependency on `root`. */
4879var freeParseInt = parseInt;
4880
4881/**
4882 * A faster alternative to `Function#apply`, this function invokes `func`
4883 * with the `this` binding of `thisArg` and the arguments of `args`.
4884 *
4885 * @private
4886 * @param {Function} func The function to invoke.
4887 * @param {*} thisArg The `this` binding of `func`.
4888 * @param {...*} args The arguments to invoke `func` with.
4889 * @returns {*} Returns the result of `func`.
4890 */
4891function apply(func, thisArg, args) {
4892  var length = args.length;
4893  switch (length) {
4894    case 0: return func.call(thisArg);
4895    case 1: return func.call(thisArg, args[0]);
4896    case 2: return func.call(thisArg, args[0], args[1]);
4897    case 3: return func.call(thisArg, args[0], args[1], args[2]);
4898  }
4899  return func.apply(thisArg, args);
4900}
4901
4902/**
4903 * Checks if `value` is a valid array-like index.
4904 *
4905 * @private
4906 * @param {*} value The value to check.
4907 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
4908 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
4909 */
4910function isIndex(value, length) {
4911  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
4912  length = length == null ? MAX_SAFE_INTEGER : length;
4913  return value > -1 && value % 1 == 0 && value < length;
4914}
4915
4916/**
4917 * Replaces all `placeholder` elements in `array` with an internal placeholder
4918 * and returns an array of their indexes.
4919 *
4920 * @private
4921 * @param {Array} array The array to modify.
4922 * @param {*} placeholder The placeholder to replace.
4923 * @returns {Array} Returns the new array of placeholder indexes.
4924 */
4925function replaceHolders(array, placeholder) {
4926  var index = -1,
4927      length = array.length,
4928      resIndex = -1,
4929      result = [];
4930
4931  while (++index < length) {
4932    if (array[index] === placeholder) {
4933      array[index] = PLACEHOLDER;
4934      result[++resIndex] = index;
4935    }
4936  }
4937  return result;
4938}
4939
4940/** Used for built-in method references. */
4941var objectProto = Object.prototype;
4942
4943/**
4944 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
4945 * of values.
4946 */
4947var objectToString = objectProto.toString;
4948
4949/* Built-in method references for those with the same name as other `lodash` methods. */
4950var nativeMax = Math.max,
4951    nativeMin = Math.min;
4952
4953/**
4954 * The base implementation of `_.create` without support for assigning
4955 * properties to the created object.
4956 *
4957 * @private
4958 * @param {Object} prototype The object to inherit from.
4959 * @returns {Object} Returns the new object.
4960 */
4961var baseCreate = (function() {
4962  function object() {}
4963  return function(prototype) {
4964    if (isObject(prototype)) {
4965      object.prototype = prototype;
4966      var result = new object;
4967      object.prototype = undefined;
4968    }
4969    return result || {};
4970  };
4971}());
4972
4973/**
4974 * Creates an array that is the composition of partially applied arguments,
4975 * placeholders, and provided arguments into a single array of arguments.
4976 *
4977 * @private
4978 * @param {Array|Object} args The provided arguments.
4979 * @param {Array}
4979 partials The arguments to prepend to those provided.
4980 * @param {Array} holders The `partials` placeholder indexes.
4981 * @returns {Array} Returns the new array of composed arguments.
4982 */
4983function composeArgs(args, partials, holders) {
4984  var holdersLength = holders.length,
4985      argsIndex = -1,
4986      argsLength = nativeMax(args.length - holdersLength, 0),
4987      leftIndex = -1,
4988      leftLength = partials.length,
4989      result = Array(leftLength + argsLength);
4990
4991  while (++leftIndex < leftLength) {
4992    result[leftIndex] = partials[leftIndex];
4993  }
4994  while (++argsIndex < holdersLength) {
4995    result[holders[argsIndex]] = args[argsIndex];
4996  }
4997  while (argsLength--) {
4998    result[leftIndex++] = args[argsIndex++];
4999  }
5000  return result;
5001}
5002
5003/**
5004 * This function is like `composeArgs` except that the arguments composition
5005 * is tailored for `_.partialRight`.
5006 *
5007 * @private
5008 * @param {Array|Object} args The provided arguments.
5009 * @param {Array} partials The arguments to append to those provided.
5010 * @param {Array} holders The `partials` placeholder indexes.
5011 * @returns {Array} Returns the new array of composed arguments.
5012 */
5013function composeArgsRight(args, partials, holders) {
5014  var holdersIndex = -1,
5015      holdersLength = holders.length,
5016      argsIndex = -1,
5017      argsLength = nativeMax(args.length - holdersLength, 0),
5018      rightIndex = -1,
5019      rightLength = partials.length,
5020      result = Array(argsLength + rightLength);
5021
5022  while (++argsIndex < argsLength) {
5023    result[argsIndex] = args[argsIndex];
5024  }
5025  var offset = argsIndex;
5026  while (++rightIndex < rightLength) {
5027    result[offset + rightIndex] = partials[rightIndex];
5028  }
5029  while (++holdersIndex < holdersLength) {
5030    result[offset + holders[holdersIndex]] = args[argsIndex++];
5031  }
5032  return result;
5033}
5034
5035/**
5036 * Copies the values of `source` to `array`.
5037 *
5038 * @private
5039 * @param {Array} source The array to copy values from.
5040 * @param {Array} [array=[]] The array to copy values to.
5041 * @returns {Array} Returns `array`.
5042 */
5043function copyArray(source, array) {
5044  var index = -1,
5045      length = source.length;
5046
5047  array || (array = Array(length));
5048  while (++index < length) {
5049    array[index] = source[index];
5050  }
5051  return array;
5052}
5053
5054/**
5055 * Creates a function that wraps `func` to invoke it with the optional `this`
5056 * binding of `thisArg`.
5057 *
5058 * @private
5059 * @param {Function} func The function to wrap.
5060 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5061 * @param {*} [thisArg] The `this` binding of `func`.
5062 * @returns {Function} Returns the new wrapped function.
5063 */
5064function createBaseWrapper(func, bitmask, thisArg) {
5065  var isBind = bitmask & BIND_FLAG,
5066      Ctor = createCtorWrapper(func);
5067
5068  function wrapper() {
5069    var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5070    return fn.apply(isBind ? thisArg : this, arguments);
5071  }
5072  return wrapper;
5073}
5074
5075/**
5076 * Creates a function that produces an instance of `Ctor` regardless of
5077 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5078 *
5079 * @private
5080 * @param {Function} Ctor The constructor to wrap.
5081 * @returns {Function} Returns the new wrapped function.
5082 */
5083function createCtorWrapper(Ctor) {
5084  return function() {
5085    // Use a `switch` statement to work with class constructors.
5086    // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5087    // for more details.
5088    var args = arguments;
5089    switch (args.length) {
5090      case 0: return new Ctor;
5091      case 1: return new Ctor(args[0]);
5092      case 2: return new Ctor(args[0], args[1]);
5093      case 3: return new Ctor(args[0], args[1], args[2]);
5094      case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5095      case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5096      case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5097      case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5098    }
5099    var thisBinding = baseCreate(Ctor.prototype),
5100        result = Ctor.apply(thisBinding, args);
5101
5102    // Mimic the constructor's `return` behavior.
5103    // See https://es5.github.io/#x13.2.2 for more details.
5104    return isObject(result) ? result : thisBinding;
5105  };
5106}
5107
5108/**
5109 * Creates a function that wraps `func` to enable currying.
5110 *
5111 * @private
5112 * @param {Function} func The function to wrap.
5113 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5114 * @param {number} arity The arity of `func`.
5115 * @returns {Function} Returns the new wrapped function.
5116 */
5117function createCurryWrapper(func, bitmask, arity) {
5118  var Ctor = createCtorWrapper(func);
5119
5120  function wrapper() {
5121    var length = arguments.length,
5122        index = length,
5123        args = Array(length),
5124        fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
5125        placeholder = wrapper.placeholder;
5126
5127    while (index--) {
5128      args[index] = arguments[index];
5129    }
5130    var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5131      ? []
5132      : replaceHolders(args, placeholder);
5133
5134    length -= holders.length;
5135    return length < arity
5136      ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
5137      : apply(fn, this, args);
5138  }
5139  return wrapper;
5140}
5141
5142/**
5143 * Creates a function that wraps `func` to invoke it with optional `this`
5144 * binding of `thisArg`, partial application, and currying.
5145 *
5146 * @private
5147 * @param {Function|string} func The function or method name to wrap.
5148 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5149 * @param {*} [thisArg] The `this` binding of `func`.
5150 * @param {Array} [partials] The arguments to prepend to those provided to the new function.
5151 * @param {Array} [holders] The `partials` placeholder indexes.
5152 * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
5153 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5154 * @param {Array} [argPos] The argument positions of the new function.
5155 * @param {number} [ary] The arity cap of `func`.
5156 * @param {number} [arity] The arity of `func`.
5157 * @returns {Function} Returns the new wrapped function.
5158 */
5159function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5160  var isAry = bitmask & ARY_FLAG,
5161      isBind = bitmask & BIND_FLAG,
5162      isBindKey = bitmask & BIND_KEY_FLAG,
5163      isCurry = bitmask & CURRY_FLAG,
5164      isCurryRight = bitmask & CURRY_RIGHT_FLAG,
5165      isFlip = bitmask & FLIP_FLAG,
5166      Ctor = isBindKey ? undefined : createCtorWrapper(func);
5167
5168  function wrapper() {
5169    var length = arguments.length,
5170        index = length,
5171        args = Array(length);
5172
5173    while (index--) {
5174      args[index] = arguments[index];
5175    }
5176    if (partials) {
5177      args = composeArgs(args, partials, holders);
5178    }
5179    if (partialsRight) {
5180      args = composeArgsRight(args, partialsRight, holdersRight);
5181    }
5182    if (isCurry || isCurryRight) {
5183      var placeholder = wrapper.placeholder,
5184          argsHolders = replaceHolders(args, placeholder);
5185
5186      length -= argsHolders.length;
5187      if (length < arity) {
5188        return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
5189      }
5190    }
5191    var thisBinding = isBind ? thisArg : this,
5192        fn = isBindKey ? thisBinding[func] : func;
5193
5194    if (argPos) {
5195      args = reorder(args, argPos);
5196    } else if (isFlip && args.length > 1) {
5197      args.reverse();
5198    }
5199    if (isAry && ary < args.length) {
5200      args.length = ary;
5201    }
5202    if (this && this !== root && this instanceof wrapper) {
5203      fn = Ctor || createCtorWrapper(fn);
5204    }
5205    return fn.apply(thisBinding, args);
5206  }
5207  return wrapper;
5208}
5209
5210/**
5211 * Creates a function that wraps `func` to invoke it with the optional `this`
5212 * binding of `thisArg` and the `partials` prepended to those provided to
5213 * the wrapper.
5214 *
5215 * @private
5216 * @param {Function} func The function to wrap.
5217 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5218 * @param {*} thisArg The `this` binding of `func`.
5219 * @param {Array}
5219 partials The arguments to prepend to those provided to the new function.
5220 * @returns {Function} Returns the new wrapped function.
5221 */
5222function createPartialWrapper(func, bitmask, thisArg, partials) {
5223  var isBind = bitmask & BIND_FLAG,
5224      Ctor = createCtorWrapper(func);
5225
5226  function wrapper() {
5227    var argsIndex = -1,
5228        argsLength = arguments.length,
5229        leftIndex = -1,
5230        leftLength = partials.length,
5231        args = Array(leftLength + argsLength),
5232        fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5233
5234    while (++leftIndex < leftLength) {
5235      args[leftIndex] = partials[leftIndex];
5236    }
5237    while (argsLength--) {
5238      args[leftIndex++] = arguments[++argsIndex];
5239    }
5240    return apply(fn, isBind ? thisArg : this, args);
5241  }
5242  return wrapper;
5243}
5244
5245/**
5246 * Creates a function that wraps `func` to continue currying.
5247 *
5248 * @private
5249 * @param {Function} func The function to wrap.
5250 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5251 * @param {Function} wrapFunc The function to create the `func` wrapper.
5252 * @param {*} placeholder The placeholder to replace.
5253 * @param {*} [thisArg] The `this` binding of `func`.
5254 * @param {Array} [partials] The arguments to prepend to those provided to the new function.
5255 * @param {Array} [holders] The `partials` placeholder indexes.
5256 * @param {Array} [argPos] The argument positions of the new function.
5257 * @param {number} [ary] The arity cap of `func`.
5258 * @param {number} [arity] The arity of `func`.
5259 * @returns {Function} Returns the new wrapped function.
5260 */
5261function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5262  var isCurry = bitmask & CURRY_FLAG,
5263      newArgPos = argPos ? copyArray(argPos) : undefined,
5264      newsHolders = isCurry ? holders : undefined,
5265      newHoldersRight = isCurry ? undefined : holders,
5266      newPartials = isCurry ? partials : undefined,
5267      newPartialsRight = isCurry ? undefined : partials;
5268
5269  bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
5270  bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
5271
5272  if (!(bitmask & CURRY_BOUND_FLAG)) {
5273    bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
5274  }
5275  var result = wrapFunc(func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity);
5276
5277  result.placeholder = placeholder;
5278  return result;
5279}
5280
5281/**
5282 * Creates a function that either curries or invokes `func` with optional
5283 * `this` binding and partially applied arguments.
5284 *
5285 * @private
5286 * @param {Function|string} func The function or method name to wrap.
5287 * @param {number} bitmask The bitmask of wrapper flags.
5288 *  The bitmask may be composed of the following flags:
5289 *     1 - `_.bind`
5290 *     2 - `_.bindKey`
5291 *     4 - `_.curry` or `_.curryRight` of a bound function
5292 *     8 - `_.curry`
5293 *    16 - `_.curryRight`
5294 *    32 - `_.partial`
5295 *    64 - `_.partialRight`
5296 *   128 - `_.rearg`
5297 *   256 - `_.ary`
5298 * @param {*} [thisArg] The `this` binding of `func`.
5299 * @param {Array} [partials] The arguments to be partially applied.
5300 * @param {Array} [holders] The `partials` placeholder indexes.
5301 * @param {Array} [argPos] The argument positions of the new function.
5302 * @param {number} [ary] The arity cap of `func`.
5303 * @param {number} [arity] The arity of `func`.
5304 * @returns {Function} Returns the new wrapped function.
5305 */
5306function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5307  var isBindKey = bitmask & BIND_KEY_FLAG;
5308  if (!isBindKey && typeof func != 'function') {
5309    throw new TypeError(FUNC_ERROR_TEXT);
5310  }
5311  var length = partials ? partials.length : 0;
5312  if (!length) {
5313    bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
5314    partials = holders = undefined;
5315  }
5316  ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5317  arity = arity === undefined ? arity : toInteger(arity);
5318  length -= holders ? holders.length : 0;
5319
5320  if (bitmask & PARTIAL_RIGHT_FLAG) {
5321    var partialsRight = partials,
5322        holdersRight = holders;
5323
5324    partials = holders = undefined;
5325  }
5326  var newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
5327
5328  func = newData[0];
5329  bitmask = newData[1];
5330  thisArg = newData[2];
5331  partials = newData[3];
5332  holders = newData[4];
5333  arity = newData[9] = newData[9] == null
5334    ? (isBindKey ? 0 : func.length)
5335    : nativeMax(newData[9] - length, 0);
5336
5337  if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
5338    bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
5339  }
5340  if (!bitmask || bitmask == BIND_FLAG) {
5341    var result = createBaseWrapper(func, bitmask, thisArg);
5342  } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
5343    result = createCurryWrapper(func, bitmask, arity);
5344  } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
5345    result = createPartialWrapper(func, bitmask, thisArg, partials);
5346  } else {
5347    result = createHybridWrapper.apply(undefined, newData);
5348  }
5349  return result;
5350}
5351
5352/**
5353 * Reorder `array` according to the specified indexes where the element at
5354 * the first index is assigned as the first element, the element at
5355 * the second index is assigned as the second element, and so on.
5356 *
5357 * @private
5358 * @param {Array} array The array to reorder.
5359 * @param {Array} indexes The arranged array indexes.
5360 * @returns {Array} Returns `array`.
5361 */
5362function reorder(array, indexes) {
5363  var arrLength = array.length,
5364      length = nativeMin(indexes.length, arrLength),
5365      oldArray = copyArray(array);
5366
5367  while (length--) {
5368    var index = indexes[length];
5369    array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5370  }
5371  return array;
5372}
5373
5374/**
5375 * Checks if `value` is classified as a `Function` object.
5376 *
5377 * @static
5378 * @memberOf _
5379 * @category Lang
5380 * @param {*} value The value to check.
5381 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
5382 * @example
5383 *
5384 * _.isFunction(_);
5385 * // => true
5386 *
5387 * _.isFunction(/abc/);
5388 * // => false
5389 */
5390function isFunction(value) {
5391  // The use of `Object#toString` avoids issues with the `typeof` operator
5392  // in Safari 8 which returns 'object' for typed array constructors, and
5393  // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
5394  var tag = isObject(value) ? objectToString.call(value) : '';
5395  return tag == funcTag || tag == genTag;
5396}
5397
5398/**
5399 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
5400 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
5401 *
5402 * @static
5403 * @memberOf _
5404 * @category Lang
5405 * @param {*} value The value to check.
5406 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
5407 * @example
5408 *
5409 * _.isObject({});
5410 * // => true
5411 *
5412 * _.isObject([1, 2, 3]);
5413 * // => true
5414 *
5415 * _.isObject(_.noop);
5416 * // => true
5417 *
5418 * _.isObject(null);
5419 * // => false
5420 */
5421function isObject(value) {
5422  var type = typeof value;
5423  return !!value && (type == 'object' || type == 'function');
5424}
5425
5426/**
5427 * Converts `value` to an integer.
5428 *
5429 * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
5430 *
5431 * @static
5432 * @memberOf _
5433 * @category Lang
5434 * @param {*} value The value to convert.
5435 * @returns {number} Returns the converted integer.
5436 * @example
5437 *
5438 * _.toInteger(3);
5439 * // => 3
5440 *
5441 * _.toInteger(Number.MIN_VALUE);
5442 * // => 0
5443 *
5444 * _.toInteger(Infinity);
5445 * // => 1.7976931348623157e+308
5446 *
5447 * _.toInteger('3');
5448 * // => 3
5449 */
5450function toInteger(value) {
5451  if (!value) {
5452    return value === 0 ? value : 0;
5453  }
5454  value = toNumber(value);
5455  if (value === INFINITY || value === -INFINITY) {
5456    var sign = (value < 0 ? -1 : 1);
5457    return sign * MAX_INTEGER;
5458  }
5459  var remainder = value % 1;
5460  return value === value ? (remainder ? value - remainder : value) : 0;
5461}
5462
5463/**
5464 * Converts `value` to a number.
5465 *
5466 * @static
5467 * @memberOf _
5468 * @category Lang
5469 * @param {*} value The value to process.
5470 * @returns {number} Returns the number.
5471 * @example
5472 *
5473 * _.toNumber(3);
5474 * // => 3
5475 *
5476 * _.toNumber(Number.MIN_VALUE);
5477 * // => 5e-324
5478 *
5479 * _.toNumber(Infinity);
5480 * // => Infinity
5481 *
5482 * _.toNumber('3');
5483 * // => 3
5484 */
5485function toNumber(value) {
5486  if (isObject(value)) {
5487    var other = isFunction(value.valueOf) ? value.valueOf() : value;
5488    value = isObject(other) ? (other + '') : other;
5489  }
5490  if (typeof value != 'string') {
5491    return value === 0 ? value : +value;
5492  }
5493  value = value.replace(reTrim, '');
5494  var isBinary = reIsBinary.test(value);
5495  return (isBinary || reIsOctal.test(value))
5496    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
5497    : (reIsBadHex.test(value) ? NAN : +value);
5498}
5499
5500module.exports = createWrapper;
5501
5502},{"lodash._root":54}],51:[function(require,module,exports){
5503/**
5504 * lodash 3.9.1 (Custom Build) <https://lodash.com/>
5505 * Build: `lodash modern modularize exports="npm" -o ./`
5506 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5507 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5508 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5509 * Available under MIT license <https://lodash.com/license>
5510 */
5511
5512/** `Object#toString` result references. */
5513var funcTag = '[object Function]';
5514
5515/** Used to detect host constructors (Safari > 5). */
5516var reIsHostCtor = /^\[object .+?Constructor\]$/;
5517
5518/**
5519 * Checks if `value` is object-like.
5520 *
5521 * @private
5522 * @param {*} value The value to check.
5523 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
5524 */
5525function isObjectLike(value) {
5526  return !!value && typeof value == 'object';
5527}
5528
5529/** Used for native method references. */
5530var objectProto = Object.prototype;
5531
5532/** Used to resolve the decompiled source of functions. */
5533var fnToString = Function.prototype.toString;
5534
5535/** Used to check objects for own properties. */
5536var hasOwnProperty = objectProto.hasOwnProperty;
5537
5538/**
5539 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
5540 * of values.
5541 */
5542var objToString = objectProto.toString;
5543
5544/** Used to detect if a method is native. */
5545var reIsNative = RegExp('^' +
5546  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
5547  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
5548);
5549
5550/**
5551 * Gets the native function at `key` of `object`.
5552 *
5553 * @private
5554 * @param {Object} object The object to query.
5555 * @param {string} key The key of the method to get.
5556 * @returns {*} Returns the function if it's native, else `undefined`.
5557 */
5558function getNative(object, key) {
5559  var value = object == null ? undefined : object[key];
5560  return isNative(value) ? value : undefined;
5561}
5562
5563/**
5564 * Checks if `value` is classified as a `Function` object.
5565 *
5566 * @static
5567 * @memberOf _
5568 * @category Lang
5569 * @param {*} value The value to check.
5570 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
5571 * @example
5572 *
5573 * _.isFunction(_);
5574 * // => true
5575 *
5576 * _.isFunction(/abc/);
5577 * // => false
5578 */
5579function isFunction(value) {
vendor: 9,135 bytes, lines 5580-5879
5580  // The use of `Object#toString` avoids issues with the `typeof` operator
5581  // in older versions of Chrome and Safari which return 'function' for regexes
5582  // and Safari 8 equivalents which return 'object' for typed array constructors.
5583  return isObject(value) && objToString.call(value) == funcTag;
5584}
5585
5586/**
5587 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
5588 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
5589 *
5590 * @static
5591 * @memberOf _
5592 * @category Lang
5593 * @param {*} value The value to check.
5594 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
5595 * @example
5596 *
5597 * _.isObject({});
5598 * // => true
5599 *
5600 * _.isObject([1, 2, 3]);
5601 * // => true
5602 *
5603 * _.isObject(1);
5604 * // => false
5605 */
5606function isObject(value) {
5607  // Avoid a V8 JIT bug in Chrome 19-20.
5608  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
5609  var type = typeof value;
5610  return !!value && (type == 'object' || type == 'function');
5611}
5612
5613/**
5614 * Checks if `value` is a native function.
5615 *
5616 * @static
5617 * @memberOf _
5618 * @category Lang
5619 * @param {*} value The value to check.
5620 * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
5621 * @example
5622 *
5623 * _.isNative(Array.prototype.push);
5624 * // => true
5625 *
5626 * _.isNative(_);
5627 * // => false
5628 */
5629function isNative(value) {
5630  if (value == null) {
5631    return false;
5632  }
5633  if (isFunction(value)) {
5634    return reIsNative.test(fnToString.call(value));
5635  }
5636  return isObjectLike(value) && reIsHostCtor.test(value);
5637}
5638
5639module.exports = getNative;
5640
5641},{}],52:[function(require,module,exports){
5642/**
5643 * lodash 3.0.9 (Custom Build) <https://lodash.com/>
5644 * Build: `lodash modern modularize exports="npm" -o ./`
5645 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5646 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5647 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5648 * Available under MIT license <https://lodash.com/license>
5649 */
5650
5651/** Used to detect unsigned integer values. */
5652var reIsUint = /^\d+$/;
5653
5654/**
5655 * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
5656 * of an array-like value.
5657 */
5658var MAX_SAFE_INTEGER = 9007199254740991;
5659
5660/**
5661 * The base implementation of `_.property` without support for deep paths.
5662 *
5663 * @private
5664 * @param {string} key The key of the property to get.
5665 * @returns {Function} Returns the new function.
5666 */
5667function baseProperty(key) {
5668  return function(object) {
5669    return object == null ? undefined : object[key];
5670  };
5671}
5672
5673/**
5674 * Gets the "length" property value of `object`.
5675 *
5676 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
5677 * that affects Safari on at least iOS 8.1-8.3 ARM64.
5678 *
5679 * @private
5680 * @param {Object} object The object to query.
5681 * @returns {*} Returns the "length" value.
5682 */
5683var getLength = baseProperty('length');
5684
5685/**
5686 * Checks if `value` is array-like.
5687 *
5688 * @private
5689 * @param {*} value The value to check.
5690 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
5691 */
5692function isArrayLike(value) {
5693  return value != null && isLength(getLength(value));
5694}
5695
5696/**
5697 * Checks if `value` is a valid array-like index.
5698 *
5699 * @private
5700 * @param {*} value The value to check.
5701 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
5702 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
5703 */
5704function isIndex(value, length) {
5705  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
5706  length = length == null ? MAX_SAFE_INTEGER : length;
5707  return value > -1 && value % 1 == 0 && value < length;
5708}
5709
5710/**
5711 * Checks if the provided arguments are from an iteratee call.
5712 *
5713 * @private
5714 * @param {*} value The potential iteratee value argument.
5715 * @param {*} index The potential iteratee index or key argument.
5716 * @param {*} object The potential iteratee object argument.
5717 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
5718 */
5719function isIterateeCall(value, index, object) {
5720  if (!isObject(object)) {
5721    return false;
5722  }
5723  var type = typeof index;
5724  if (type == 'number'
5725      ? (isArrayLike(object) && isIndex(index, object.length))
5726      : (type == 'string' && index in object)) {
5727    var other = object[index];
5728    return value === value ? (value === other) : (other !== other);
5729  }
5730  return false;
5731}
5732
5733/**
5734 * Checks if `value` is a valid array-like length.
5735 *
5736 * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
5737 *
5738 * @private
5739 * @param {*} value The value to check.
5740 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
5741 */
5742function isLength(value) {
5743  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
5744}
5745
5746/**
5747 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
5748 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
5749 *
5750 * @static
5751 * @memberOf _
5752 * @category Lang
5753 * @param {*} value The value to check.
5754 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
5755 * @example
5756 *
5757 * _.isObject({});
5758 * // => true
5759 *
5760 * _.isObject([1, 2, 3]);
5761 * // => true
5762 *
5763 * _.isObject(1);
5764 * // => false
5765 */
5766function isObject(value) {
5767  // Avoid a V8 JIT bug in Chrome 19-20.
5768  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
5769  var type = typeof value;
5770  return !!value && (type == 'object' || type == 'function');
5771}
5772
5773module.exports = isIterateeCall;
5774
5775},{}],53:[function(require,module,exports){
5776/**
5777 * lodash 3.0.0 (Custom Build) <https://lodash.com/>
5778 * Build: `lodash modern modularize exports="npm" -o ./`
5779 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5780 * Based on Underscore.js 1.7.0 <http://underscorejs.org/LICENSE>
5781 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5782 * Available under MIT license <https://lodash.com/license>
5783 */
5784
5785/** Used as the internal argument placeholder. */
5786var PLACEHOLDER = '__lodash_placeholder__';
5787
5788/**
5789 * Replaces all `placeholder` elements in `array` with an internal placeholder
5790 * and returns an array of their indexes.
5791 *
5792 * @private
5793 * @param {Array} array The array to modify.
5794 * @param {*} placeholder The placeholder to replace.
5795 * @returns {Array} Returns the new array of placeholder indexes.
5796 */
5797function replaceHolders(array, placeholder) {
5798  var index = -1,
5799      length = array.length,
5800      resIndex = -1,
5801      result = [];
5802
5803  while (++index < length) {
5804    if (array[index] === placeholder) {
5805      array[index] = PLACEHOLDER;
5806      result[++resIndex] = index;
5807    }
5808  }
5809  return result;
5810}
5811
5812module.exports = replaceHolders;
5813
5814},{}],54:[function(require,module,exports){
5815(function (global){(function (){
5816/**
5817 * lodash 3.0.1 (Custom Build) <https://lodash.com/>
5818 * Build: `lodash modularize exports="npm" -o ./`
5819 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
5820 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5821 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5822 * Available under MIT license <https://lodash.com/license>
5823 */
5824
5825/** Used to determine if values are of the language type `Object`. */
5826var objectTypes = {
5827  'function': true,
5828  'object': true
5829};
5830
5831/** Detect free variable `exports`. */
5832var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
5833  ? exports
5834  : undefined;
5835
5836/** Detect free variable `module`. */
5837var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
5838  ? module
5839  : undefined;
5840
5841/** Detect free variable `global` from Node.js. */
5842var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
5843
5844/** Detect free variable `self`. */
5845var freeSelf = checkGlobal(objectTypes[typeof self] && self);
5846
5847/** Detect free variable `window`. */
5848var freeWindow = checkGlobal(objectTypes[typeof window] && window);
5849
5850/** Detect `this` as the global object. */
5851var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
5852
5853/**
5854 * Used as a reference to the global object.
5855 *
5856 * The `this` value is used if it's the global object to avoid Greasemonkey's
5857 * restricted `window` object, otherwise the `window` object is used.
5858 */
5859var root = freeGlobal ||
5860  ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
5861    freeSelf || thisGlobal || Function('return this')();
5862
5863/**
5864 * Checks if `value` is a global object.
5865 *
5866 * @private
5867 * @param {*} value The value to check.
5868 * @returns {null|Object} Returns `value` if it's a global object, else `null`.
5869 */
5870function checkGlobal(value) {
5871  return (value && value.Object === Object) ? value : null;
5872}
5873
5874module.exports = root;
5875
5876}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
5877},{}],55:[function(require,module,exports){
5878/**
5879 * lodash 3.8.1 (Custom Build) <https://lodash.com/>
5880 * Build: `lodash modern modularize exports="npm" -o ./`
5881 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5882 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5883 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5884 * Available under MIT license <https://lodash.com/license>
5885 */
5886var isArray = require('lodash.isarray');
5887
5888/** Used to match property names within property paths. */
5889var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
5890
5891/** Used to match backslashes in property paths. */
5892var reEscapeChar = /\\(\\)?/g;
5893
5894/**
5895 * Converts `value` to a string if it's not one. An empty string is returned
5896 * for `null` or `undefined` values.
5897 *
5898 * @private
5899 * @param {*} value The value to process.
5900 * @returns {string} Returns the string.
5901 */
5902function baseToString(value) {
5903  return value == null ? '' : (value + '');
5904}
5905
5906/**
5907 * Converts `value` to property path array if it's not one.
5908 *
5909 * @private
5910 * @param {*} value The value to process.
5911 * @returns {Array} Returns the property path array.
5912 */
5913function toPath(value) {
5914  if (isArray(value)) {
5915    return value;
5916  }
5917  var result = [];
5918  baseToString(value).replace(rePropName, function(match, number, quote, string) {
5919    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
5920  });
5921  return result;
5922}
5923
5924module.exports = toPath;
5925
5926},{"lodash.isarray":62}],56:[function(require,module,exports){
5927/**
5928 * lodash 3.2.0 (Custom Build) <https://lodash.com/>
5929 * Build: `lodash modern modularize exports="npm" -o ./`
5930 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5931 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5932 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5933 * Available under MIT license <https://lodash.com/license>
5934 */
5935var baseAssign = require('lodash._baseassign'),
5936    createAssigner = require('lodash._createassigner'),
5937    keys = require('lodash.keys');
5938
5939/**
5940 * A specialized version of `_.assign` for customizing assigned values without
5941 * support for argument juggling, multiple sources, and `this` binding `customizer`
5942 * functions.
5943 *
5944 * @private
5945 * @param {Object} object The destination object.
5946 * @param {Object} source The source object.
5947 * @param {Function} customizer The function to customize assigned values.
5948 * @returns {Object} Returns `object`.
5949 */
5950function assignWith(object, source, customizer) {
5951  var index = -1,
5952      props = keys(source),
5953      length = props.length;
5954
5955  while (++index < length) {
5956    var key = props[index],
5957        value = object[key],
5958        result = customizer(value, source[key], key, object, source);
5959
5960    if ((result === result ? (result !== value) : (value === value)) ||
5961        (value === undefined && !(key in object))) {
5962      object[key] = result;
5963    }
5964  }
5965  return object;
5966}
5967
5968/**
5969 * Assigns own enumerable properties of source object(s) to the destination
5970 * object. Subsequent sources overwrite property assignments of previous sources.
5971 * If `customizer` is provided it is invoked to produce the assigned values.
5972 * The `customizer` is bound to `thisArg` and invoked with five arguments:
5973 * (objectValue, sourceValue, key, object, source).
5974 *
5975 * **Note:** This method mutates `object` and is based on
5976 * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign).
5977 *
5978 * @static
5979 * @memberOf _
5980 * @alias extend
5981 * @category Object
5982 * @param {Object} object The destination object.
5983 * @param {...Object} [sources] The source objects.
5984 * @param {Function} [customizer] The function to customize assigned values.
5985 * @param {*} [thisArg] The `this` binding of `customizer`.
5986 * @returns {Object} Returns `object`.
5987 * @example
5988 *
5989 * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
5990 * // => { 'user': 'fred', 'age': 40 }
5991 *
5992 * // using a customizer callback
5993 * var defaults = _.partialRight(_.assign, function(value, other) {
5994 *   return _.isUndefined(value) ? other : value;
5995 * });
5996 *
5997 * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
5998 * // => { 'user': 'barney', 'age': 36 }
5999 */
6000var assign = createAssigner(function(object, source, customizer) {
6001  return customizer
6002    ? assignWith(object, source, customizer)
6003    : baseAssign(object, source);
6004});
6005
6006module.exports = assign;
6007
6008},{"lodash._baseassign":44,"lodash._createassigner":49,"lodash.keys":67}],57:[function(require,module,exports){
6009/**
6010 * lodash 3.0.3 (Custom Build) <https://lodash.com/>
6011 * Build: `lodash modern modularize exports="npm" -o ./`
6012 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6013 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6014 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6015 * Available under MIT license <https://lodash.com/license>
6016 */
6017
6018/** Used as the `TypeError` message for "Functions" methods. */
6019var FUNC_ERROR_TEXT = 'Expected a function';
6020
6021/**
6022 * Creates a function that invokes `func`, with the `this` binding and arguments
6023 * of the created function, while it is called less than `n` times. Subsequent
6024 * calls to the created function return the result of the last `func` invocation.
6025 *
6026 * @static
6027 * @memberOf _
6028 * @category Function
6029 * @param {number} n The number of calls at which `func` is no longer invoked.
6030 * @param {Function} func The function to restrict.
6031 * @returns {Function} Returns the new restricted function.
6032 * @example
6033 *
6034 * jQuery('#add').on('click', _.before(5, addContactToList));
6035 * // => allows adding up to 4 contacts to the list
6036 */
6037function before(n, func) {
6038  var result;
6039  if (typeof func != 'function') {
6040    if (typeof n == 'function') {
6041      var temp = n;
6042      n = func;
6043      func = temp;
6044    } else {
6045      throw new TypeError(FUNC_ERROR_TEXT);
6046    }
6047  }
6048  return function() {
6049    if (--n > 0) {
6050      result = func.apply(this, arguments);
6051    }
6052    if (n <= 1) {
6053      func = undefined;
6054    }
6055    return result;
6056  };
6057}
6058
6059module.exports = before;
6060
6061},{}],58:[function(require,module,exports){
6062/**
6063 * lodash 3.1.0 (Custom Build) <https://lodash.com/>
6064 * Build: `lodash modern modularize exports="npm" -o ./`
6065 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6066 * Based on Underscore.js 1.8.2 <http://underscorejs.org/LICENSE>
6067 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6068 * Available under MIT license <https://lodash.com/license>
6069 */
6070var createWrapper = require('lodash._createwrapper'),
6071    replaceHolders = require('lodash._replaceholders'),
6072    restParam = require('lodash.restparam');
6073
6074/** Used to compose bitmasks for wrapper metadata. */
6075var BIND_FLAG = 1,
6076    PARTIAL_FLAG = 32;
6077
6078/**
6079 * Creates a function that invokes `func` with the `this` binding of `thisArg`
6080 * and prepends any additional `_.bind` arguments to those provided to the
6081 * bound function.
6082 *
6083 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
6084 * may be used as a placeholder for partially applied arguments.
6085 *
6086 * **Note:** Unlike native `Function#bind` this method does not set the `length`
6087 * property of bound functions.
6088 *
6089 * @static
6090 * @memberOf _
6091 * @category Function
6092 * @param {Function} func The function to bind.
6093 * @param {*} thisArg The `this` binding of `func`.
6094 * @param {...*} [partials] The arguments to be partially applied.
6095 * @returns {Function} Returns the new bound function.
6096 * @example
6097 *
6098 * var greet = function(greeting, punctuation) {
6099 *   return greeting + ' ' + this.user + punctuation;
6100 * };
6101 *
6102 * var object = { 'user': 'fred' };
6103 *
6104 * var bound = _.bind(greet, object, 'hi');
6105 * bound('!');
6106 * // => 'hi fred!'
6107 *
6108 * // using placeholders
6109 * var bound = _.bind(greet, object, _, '!');
6110 * bound('hi');
6111 * // => 'hi fred!'
6112 */
6113var bind = restParam(function(func, thisArg, partials) {
6114  var bitmask = BIND_FLAG;
6115  if (partials.length) {
6116    var holders = replaceHolders(partials, bind.placeholder);
6117    bitmask |= PARTIAL_FLAG;
6118  }
6119  return createWrapper(func, bitmask, thisArg, partials, holders);
6120});
6121
6122// Assign default placeholders.
6123bind.placeholder = {};
6124
6125module.exports = bind;
6126
6127},{"lodash._createwrapper":50,"lodash._replaceholders":53,"lodash.restparam":69}],59:[function(require,module,exports){
6128/**
6129 * lodash 3.0.3 (Custom Build) <https://lodash.com/>
6130 * Build: `lodash modern modularize exports="npm" -o ./`
6131 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6132 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6133 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6134 * Available under MIT license <https://lodash.com/license>
6135 */
6136var arrayEach = require('lodash._arrayeach'),
6137    baseEach = require('lodash._baseeach'),
6138    bindCallback = require('lodash._bindcallback'),
6139    isArray = require('lodash.isarray');
6140
6141/**
6142 * Creates a function for `_.forEach` or `_.forEachRight`.
6143 *
6144 * @private
6145 * @param {Function} arrayFunc The function to iterate over an array.
6146 * @param {Function} eachFunc The function to iterate over a collection.
6147 * @returns {Function} Returns the new each function.
6148 */
6149function createForEach(arrayFunc, eachFunc) {
6150  return function(collection, iteratee, thisArg) {
6151    return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
6152      ? arrayFunc(collection, iteratee)
6153      : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
6154  };
6155}
6156
6157/**
6158 * Iterates over elements of `collection` invoking `iteratee` for each element.
6159 * The `iteratee` is bound to `thisArg` and invoked with three arguments:
6160 * (value, index|key, collection). Iteratee functions may exit iteration early
6161 * by explicitly returning `false`.
6162 *
6163 * **Note:** As with other "Collections" methods, objects with a "length" property
6164 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
6165 * may be used for object iteration.
6166 *
6167 * @static
6168 * @memberOf _
6169 * @alias each
6170 * @category Collection
6171 * @param {Array|Object|string} collection The collection to iterate over.
6172 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
6173 * @param {*} [thisArg] The `this` binding of `iteratee`.
6174 * @returns {Array|Object|string} Returns `collection`.
6175 * @example
6176 *
6177 * _([1, 2]).forEach(function(n) {
6178 *   console.log(n);
6179 * }).value();
6180 * // => logs each value from left to right and returns the array
6181 *
6182 * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
6183 *   console.log(n, key);
6184 * });
6185 * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
6186 */
6187var forEach = createForEach(arrayEach, baseEach);
6188
6189module.exports = forEach;
6190
6191},{"lodash._arrayeach":43,"lodash._baseeach":60,"lodash._bindcallback":48,"lodash.isarray":62}],60:[function(require,module,exports){
6192/**
6193 * lodash 3.0.4 (Custom Build) <https://lodash.com/>
6194 * Build: `lodash modern modularize exports="npm" -o ./`
6195 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6196 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6197 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6198 * Available under MIT license <https://lodash.com/license>
6199 */
6200var keys = require('lodash.keys');
6201
6202/**
6203 * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
6204 * of an array-like value.
6205 */
6206var MAX_SAFE_INTEGER = 9007199254740991;
6207
6208/**
6209 * The base implementation of `_.forEach` without support for callback
6210 * shorthands and `this` binding.
6211 *
6212 * @private
6213 * @param {Array|Object|string} collection The collection to iterate over.
6214 * @param {Function} iteratee The function invoked per iteration.
6215 * @returns {Array|Object|string} Returns `collection`.
6216 */
6217var baseEach = createBaseEach(baseForOwn);
6218
6219/**
6220 * The base implementation of `baseForIn` and `baseForOwn` which iterates
6221 * over `object` properties returned by `keysFunc` invoking `iteratee` for
6222 * each property. Iteratee functions may exit iteration early by explicitly
6223 * returning `false`.
6224 *
6225 * @private
6226 * @param {Object} object The object to iterate over.
6227 * @param {Function} iteratee The function invoked per iteration.
6228 * @param {Function} keysFunc The function to get the keys of `object`.
6229 * @returns {Object} Returns `object`.
6230 */
6231var baseFor = createBaseFor();
6232
6233/**
6234 * The base implementation of `_.forOwn` without support for callback
6235 * shorthands and `this` binding.
6236 *
6237 * @private
6238 * @param {Object} object The object to iterate over.
6239 * @param {Function} iteratee The function invoked per iteration.
6240 * @returns {Object} Returns `object`.
6241 */
6242function baseForOwn(object, iteratee) {
6243  return baseFor(object, iteratee, keys);
6244}
6245
6246/**
6247 * The base implementation of `_.property` without support for deep paths.
6248 *
6249 * @private
6250 * @param {string} key The key of the property to get.
6251 * @returns {Function} Returns the new function.
6252 */
6253function baseProperty(key) {
6254  return function(object) {
6255    return object == null ? undefined : object[key];
6256  };
6257}
6258
6259/**
6260 * Creates a `baseEach` or `baseEachRight` function.
6261 *
6262 * @private
6263 * @param {Function} eachFunc The function to iterate over a collection.
6264 * @param {boolean} [fromRight] Specify iterating from right to left.
6265 * @returns {Function} Returns the new base function.
6266 */
6267function createBaseEach(eachFunc, fromRight) {
6268  return function(collection, iteratee) {
6269    var length = collection ? getLength(collection) : 0;
6270    if (!isLength(length)) {
6271      return eachFunc(collection, iteratee);
6272    }
6273    var index = fromRight ? length : -1,
6274        iterable = toObject(collection);
6275
6276    while ((fromRight ? index-- : ++index < length)) {
6277      if (iteratee(iterable[index], index, iterable) === false) {
6278        break;
6279      }
6280    }
6281    return collection;
6282  };
6283}
6284
6285/**
6286 * Creates a base function for `_.forIn` or `_.forInRight`.
6287 *
6288 * @private
6289 * @param {boolean} [fromRight] Specify iterating from right to left.
6290 * @returns {Function} Returns the new base function.
6291 */
6292function createBaseFor(fromRight) {
6293  return function(object, iteratee, keysFunc) {
6294    var iterable = toObject(object),
6295        props = keysFunc(object),
6296        length = props.length,
6297        index = fromRight ? length : -1;
6298
6299    while ((fromRight ? index-- : ++index < length)) {
6300      var key = props[index];
6301      if (iteratee(iterable[key], key, iterable) === false) {
6302        break;
6303      }
6304    }
6305    return object;
6306  };
6307}
6308
6309/**
6310 * Gets the "length" property value of `object`.
6311 *
6312 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
6313 * that affects Safari on at least iOS 8.1-8.3 ARM64.
6314 *
6315 * @private
6316 * @param {Object} object The object to query.
6317 * @returns {*} Returns the "length" value.
6318 */
6319var getLength = baseProperty('length');
6320
6321/**
6322 * Checks if `value` is a valid array-like length.
6323 *
6324 * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
6325 *
6326 * @private
6327 * @param {*} value The value to check.
6328 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
6329 */
6330function isLength(value) {
6331  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
6332}
6333
6334/**
6335 * Converts `value` to an object if it's not one.
6336 *
6337 * @private
6338 * @param {*} value The value to process.
6339 * @returns {Object} Returns the object.
6340 */
6341function toObject(value) {
6342  return isObject(value) ? value : Object(value);
6343}
6344
6345/**
6346 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
6347 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
6348 *
6349 * @static
6350 * @memberOf _
6351 * @category Lang
6352 * @param {*} value The value to check.
6353 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
6354 * @example
6355 *
6356 * _.isObject({});
6357 * // => true
6358 *
6359 * _.isObject([1, 2, 3]);
6360 * // => true
6361 *
6362 * _.isObject(1);
6363 * // => false
6364 */
6365function isObject(value) {
6366  // Avoid a V8 JIT bug in Chrome 19-20.
6367  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
6368  var type = typeof value;
6369  return !!value && (type == 'object' || type == 'function');
6370}
6371
6372module.exports = baseEach;
6373
6374},{"lodash.keys":67}],61:[function(require,module,exports){
6375/**
6376 * lodash (Custom Build) <https://lodash.com/>
6377 * Build: `lodash modularize exports="npm" -o ./`
6378 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
6379 * Released under MIT license <https://lodash.com/license>
6380 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6381 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6382 */
6383
6384/** Used as references for various `Number` constants. */
6385var MAX_SAFE_INTEGER = 9007199254740991;
6386
6387/** `Object#toString` result references. */
6388var argsTag = '[object Arguments]',
6389    funcTag = '[object Function]',
6390    genTag = '[object GeneratorFunction]';
6391
6392/** Used for built-in method references. */
6393var objectProto = Object.prototype;
6394
6395/** Used to check objects for own properties. */
6396var hasOwnProperty = objectProto.hasOwnProperty;
6397
6398/**
6399 * Used to resolve the
6400 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
6401 * of values.
6402 */
6403var objectToString = objectProto.toString;
6404
6405/** Built-in value references. */
6406var propertyIsEnumerable = objectProto.propertyIsEnumerable;
6407
6408/**
6409 * Checks if `value` is likely an `arguments` object.
6410 *
6411 * @static
6412 * @memberOf _
6413 * @since 0.1.0
6414 * @category Lang
6415 * @param {*} value The value to check.
6416 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
6417 *  else `false`.
6418 * @example
6419 *
6420 * _.isArguments(function() { return arguments; }());
6421 * // => true
6422 *
6423 * _.isArguments([1, 2, 3]);
6424 * // => false
6425 */
6426function isArguments(value) {
6427  // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
6428  return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
6429    (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
6430}
6431
6432/**
6433 * Checks if `value` is array-like. A value is considered array-like if it's
6434 * not a function and has a `value.length` that's an integer greater than or
6435 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
6436 *
6437 * @static
6438 * @memberOf _
6439 * @since 4.0.0
6440 * @category Lang
6441 * @param {*} value The value to check.
6442 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
6443 * @example
6444 *
6445 * _.isArrayLike([1, 2, 3]);
6446 * // => true
6447 *
6448 * _.isArrayLike(document.body.children);
6449 * // => true
6450 *
6451 * _.isArrayLike('abc');
6452 * // => true
6453 *
6454 * _.isArrayLike(_.noop);
6455 * // => false
6456 */
6457function isArrayLike(value) {
6458  return value != null && isLength(value.length) && !isFunction(value);
6459}
6460
6461/**
6462 * This method is like `_.isArrayLike` except that it also checks if `value`
6463 * is an object.
6464 *
6465 * @static
6466 * @memberOf _
6467 * @since 4.0.0
6468 * @category Lang
6469 * @param {*} value The value to check.
6470 * @returns {boolean} Returns `true` if `value` is an array-like object,
6471 *  else `false`.
6472 * @example
6473 *
6474 * _.isArrayLikeObject([1, 2, 3]);
6475 * // => true
6476 *
6477 * _.isArrayLikeObject(document.body.children);
6478 * // => true
6479 *
6480 * _.isArrayLikeObject('abc');
6481 * // => false
6482 *
6483 * _.isArrayLikeObject(_.noop);
6484 * // => false
6485 */
6486function isArrayLikeObject(value) {
6487  return isObjectLike(value) && isArrayLike(value);
6488}
6489
6490/**
6491 * Checks if `value` is classified as a `Function` object.
6492 *
6493 * @static
6494 * @memberOf _
6495 * @since 0.1.0
6496 * @category Lang
6497 * @param {*} value The value to check.
6498 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
6499 * @example
6500 *
6501 * _.isFunction(_);
6502 * // => true
6503 *
6504 * _.isFunction(/abc/);
6505 * // => false
6506 */
6507function isFunction(value) {
6508  // The use of `Object#toString` avoids issues with the `typeof` operator
6509  // in Safari 8-9 which returns 'object' for typed array and other constructors.
6510  var tag = isObject(value) ? objectToString.call(value) : '';
6511  return tag == funcTag || tag == genTag;
6512}
6513
6514/**
6515 * Checks if `value` is a valid array-like length.
6516 *
6517 * **Note:** This method is loosely based on
6518 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
6519 *
6520 * @static
6521 * @memberOf _
6522 * @since 4.0.0
6523 * @category Lang
6524 * @param {*} value The value to check.
6525 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
6526 * @example
6527 *
6528 * _.isLength(3);
6529 * // => true
6530 *
6531 * _.isLength(Number.MIN_VALUE);
6532 * // => false
6533 *
6534 * _.isLength(Infinity);
6535 * // => false
6536 *
6537 * _.isLength('3');
6538 * // => false
6539 */
6540function isLength(value) {
6541  return typeof value == 'number' &&
6542    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
6543}
6544
6545/**
6546 * Checks if `value` is the
6547 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
6548 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
6549 *
6550 * @static
6551 * @memberOf _
6552 * @since 0.1.0
6553 * @category Lang
6554 * @param {*} value The value to check.
6555 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
6556 * @example
6557 *
6558 * _.isObject({});
6559 * // => true
6560 *
6561 * _.isObject([1, 2, 3]);
6562 * // => true
6563 *
6564 * _.isObject(_.noop);
6565 * // => true
6566 *
6567 * _.isObject(null);
6568 * // => false
6569 */
6570function isObject(value) {
6571  var type = typeof value;
6572  return !!value && (type == 'object' || type == 'function');
6573}
6574
6575/**
6576 * Checks if `value` is object-like. A value is object-like if it's not `null`
6577 * and has a `typeof` result of "object".
6578 *
6579 * @static
6580 * @memberOf _
6581 * @since 4.0.0
6582 * @category Lang
6583 * @param {*} value The value to check.
6584 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
6585 * @example
6586 *
6587 * _.isObjectLike({});
6588 * // => true
6589 *
6590 * _.isObjectLike([1, 2, 3]);
6591 * // => true
6592 *
6593 * _.isObjectLike(_.noop);
6594 * // => false
6595 *
6596 * _.isObjectLike(null);
6597 * // => false
6598 */
6599function isObjectLike(value) {
6600  return !!value && typeof value == 'object';
6601}
6602
6603module.exports = isArguments;
6604
6605},{}],62:[function(require,module,exports){
6606/**
6607 * lodash 3.0.4 (Custom Build) <https://lodash.com/>
6608 * Build: `lodash modern modularize exports="npm" -o ./`
6609 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6610 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6611 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6612 * Available under MIT license <https://lodash.com/license>
6613 */
6614
6615/** `Object#toString` result references. */
6616var arrayTag = '[object Array]',
6617    funcTag = '[object Function]';
6618
6619/** Used to detect host constructors (Safari > 5). */
6620var reIsHostCtor = /^\[object .+?Constructor\]$/;
6621
6622/**
6623 * Checks if `value` is object-like.
6624 *
6625 * @private
6626 * @param {*} value The value to check.
6627 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
6628 */
6629function isObjectLike(value) {
6630  return !!value && typeof value == 'object';
6631}
6632
6633/** Used for native method references. */
6634var objectProto = Object.prototype;
6635
6636/** Used to resolve the decompiled source of functions. */
6637var fnToString = Function.prototype.toString;
6638
6639/** Used to check objects for own properties. */
6640var hasOwnProperty = objectProto.hasOwnProperty;
6641
6642/**
6643 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
6644 * of values.
6645 */
6646var objToString = objectProto.toString;
6647
6648/** Used to detect if a method is native. */
6649var reIsNative = RegExp('^' +
6650  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
6651  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
6652);
6653
6654/* Native method references for those with the same name as other `lodash` methods. */
6655var nativeIsArray = getNative(Array, 'isArray');
6656
6657/**
6658 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
6659 * of an array-like value.
6660 */
6661var MAX_SAFE_INTEGER = 9007199254740991;
6662
6663/**
6664 * Gets the native function at `key` of `object`.
6665 *
6666 * @private
6667 * @param {Object} object The object to query.
6668 * @param {string} key The key of the method to get.
6669 * @returns {*} Returns the function if it's native, else `undefined`.
6670 */
6671function getNative(object, key) {
6672  var value = object == null ? undefined : object[key];
6673  return isNative(value) ? value : undefined;
6674}
6675
6676/**
6677 * Checks if `value` is a valid array-like length.
6678 *
6679 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
6680 *
6681 * @private
6682 * @param {*} value The value to check.
6683 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
6684 */
6685function isLength(value) {
6686  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
6687}
6688
6689/**
6690 * Checks if `value` is classified as an `Array` object.
6691 *
6692 * @static
6693 * @memberOf _
6694 * @category Lang
6695 * @param {*} value The value to check.
6696 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
6697 * @example
6698 *
6699 * _.isArray([1, 2, 3]);
6700 * // => true
6701 *
6702 * _.isArray(function() { return arguments; }());
6703 * // => false
6704 */
6705var isArray = nativeIsArray || function(value) {
6706  return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
6707};
6708
6709/**
6710 * Checks if `value` is classified as a `Function` object.
6711 *
6712 * @static
6713 * @memberOf _
6714 * @category Lang
6715 * @param {*} value The value to check.
6716 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
6717 * @example
6718 *
6719 * _.isFunction(_);
6720 * // => true
6721 *
6722 * _.isFunction(/abc/);
6723 * // => false
6724 */
6725function isFunction(value) {
6726  // The use of `Object#toString` avoids issues with the `typeof` operator
6727  // in older versions of Chrome and Safari which return 'function' for regexes
6728  // and Safari 8 equivalents which return 'object' for typed array constructors.
6729  return isObject(value) && objToString.call(value) == funcTag;
6730}
6731
6732/**
6733 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
6734 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
6735 *
6736 * @static
6737 * @memberOf _
6738 * @category Lang
6739 * @param {*} value The value to check.
6740 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
6741 * @example
6742 *
6743 * _.isObject({});
6744 * // => true
6745 *
6746 * _.isObject([1, 2, 3]);
6747 * // => true
6748 *
6749 * _.isObject(1);
6750 * // => false
6751 */
6752function isObject(value) {
6753  // Avoid a V8 JIT bug in Chrome 19-20.
6754  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
6755  var type = typeof value;
6756  return !!value && (type == 'object' || type == 'function');
6757}
6758
6759/**
6760 * Checks if `value` is a native function.
6761 *
6762 * @static
6763 * @memberOf _
6764 * @category Lang
6765 * @param {*} value The value to check.
6766 * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
6767 * @example
6768 *
6769 * _.isNative(Array.prototype.push);
6770 * // => true
6771 *
6772 * _.isNative(_);
6773 * // => false
6774 */
6775function isNative(value) {
6776  if (value == null) {
6777    return false;
6778  }
6779  if (isFunction(value)) {
6780    return reIsNative.test(fnToString.call(value));
6781  }
6782  return isObjectLike(value) && reIsHostCtor.test(value);
6783}
6784
6785module.exports = isArray;
6786
6787},{}],63:[function(require,module,exports){
6788/**
6789 * lodash 3.0.4 (Custom Build) <https://lodash.com/>
6790 * Build: `lodash modern modularize exports="npm" -o ./`
6791 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6792 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6793 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6794 * Available under MIT license <https://lodash.com/license>
6795 */
6796var isArguments = require('lodash.isarguments'),
6797    isArray = require('lodash.isarray'),
6798    isFunction = require('lodash.isfunction'),
6799    isString = require('lodash.isstring'),
6800    keys = require('lodash.keys');
6801
6802/**
6803 * Checks if `value` is object-like.
6804 *
6805 * @private
6806 * @param {*} value The value to check.
6807 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
6808 */
6809function isObjectLike(value) {
6810  return !!value && typeof value == 'object';
6811}
6812
6813/**
6814 * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
6815 * of an array-like value.
6816 */
6817var MAX_SAFE_INTEGER = 9007199254740991;
6818
6819/**
6820 * The base implementation of `_.property` without support for deep paths.
6821 *
6822 * @private
6823 * @param {string} key The key of the property to get.
6824 * @returns {Function} Returns the new function.
6825 */
6826function baseProperty(key) {
6827  return function(object) {
6828    return object == null ? undefined : object[key];
6829  };
6830}
6831
6832/**
6833 * Gets the "length" property value of `object`.
6834 *
6835 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
6836 * that affects Safari on at least iOS 8.1-8.3 ARM64.
6837 *
6838 * @private
6839 * @param {Object} object The object to query.
6840 * @returns {*} Returns the "length" value.
6841 */
6842var getLength = baseProperty('length');
6843
6844/**
6845 * Checks if `value` is array-like.
6846 *
6847 * @private
6848 * @param {*} value The value to check.
6849 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
6850 */
6851function isArrayLike(value) {
6852  return value != null && isLength(getLength(value));
6853}
6854
6855/**
6856 * Checks if `value` is a valid array-like length.
6857 *
6858 * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
6859 *
6860 * @private
6861 * @param {*} value The value to check.
6862 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
6863 */
6864function isLength(value) {
6865  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
6866}
6867
6868/**
6869 * Checks if `value` is empty. A value is considered empty unless it is an
6870 * `arguments` object, array, string, or jQuery-like collection with a length
6871 * greater than `0` or an object with own enumerable properties.
6872 *
6873 * @static
6874 * @memberOf _
6875 * @category Lang
6876 * @param {Array|Object|string} value The value to inspect.
6877 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
6878 * @example
6879 *
6880 * _.isEmpty(null);
6881 * // => true
6882 *
6883 * _.isEmpty(true);
6884 * // => true
6885 *
6886 * _.isEmpty(1);
6887 * // => true
6888 *
6889 * _.isEmpty([1, 2, 3]);
6890 * // => false
6891 *
6892 * _.isEmpty({ 'a': 1 });
6893 * // => false
6894 */
6895function isEmpty(value) {
6896  if (value == null) {
6897    return true;
6898  }
6899  if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) ||
6900      (isObjectLike(value) && isFunction(value.splice)))) {
6901    return !value.length;
6902  }
6903  return !keys(value).length;
6904}
6905
6906module.exports = isEmpty;
6907
6908},{"lodash.isarguments":61,"lodash.isarray":62,"lodash.isfunction":64,"lodash.isstring":66,"lodash.keys":67}],64:[function(require,module,exports){
6909(function (global){(function (){
6910/**
6911 * Lodash (Custom Build) <https://lodash.com/>
6912 * Build: `lodash modularize exports="npm" -o ./`
6913 * Copyright JS Foundation and other contributors <https://js.foundation/>
6914 * Released under MIT license <https://lodash.com/license>
6915 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6916 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6917 */
6918
6919/** `Object#toString` result references. */
6920var asyncTag = '[object AsyncFunction]',
6921    funcTag = '[object Function]',
6922    genTag = '[object GeneratorFunction]',
6923    nullTag = '[object Null]',
6924    proxyTag = '[object Proxy]',
6925    undefinedTag = '[object Undefined]';
6926
6927/** Detect free variable `global` from Node.js. */
6928var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
6929
6930/** Detect free variable `self`. */
6931var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
6932
6933/** Used as a reference to the global object. */
6934var root = freeGlobal || freeSelf || Function('return this')();
6935
6936/** Used for built-in method references. */
6937var objectProto = Object.prototype;
6938
6939/** Used to check objects for own properties. */
6940var hasOwnProperty = objectProto.hasOwnProperty;
6941
6942/**
6943 * Used to resolve the
6944 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
6945 * of values.
6946 */
6947var nativeObjectToString = objectProto.toString;
6948
6949/** Built-in value references. */
6950var Symbol = root.Symbol,
6951    symToStringTag = Symbol ? Symbol.toStringTag : undefined;
6952
6953/**
6954 * The base implementation of `getTag` without fallbacks for buggy environments.
6955 *
6956 * @private
6957 * @param {*} value The value to query.
6958 * @returns {string} Returns the `toStringTag`.
6959 */
6960function baseGetTag(value) {
6961  if (value == null) {
6962    return value === undefined ? undefinedTag : nullTag;
6963  }
6964  return (symToStringTag && symToStringTag in Object(value))
6965    ? getRawTag(value)
6966    : objectToString(value);
6967}
6968
6969/**
6970 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
6971 *
6972 * @private
6973 * @param {*} value The value to query.
6974 * @returns {string} Returns the raw `toStringTag`.
6975 */
6976function getRawTag(value) {
6977  var isOwn = hasOwnProperty.call(value, symToStringTag),
6978      tag = value[symToStringTag];
6979
6980  try {
6981    value[symToStringTag] = undefined;
6982    var unmasked = true;
6983  } catch (e) {}
6984
6985  var result = nativeObjectToString.call(value);
6986  if (unmasked) {
6987    if (isOwn) {
6988      value[symToStringTag] = tag;
6989    } else {
6990      delete value[symToStringTag];
6991    }
6992  }
6993  return result;
6994}
6995
6996/**
6997 * Converts `value` to a string using `Object.prototype.toString`.
6998 *
6999 * @private
7000 * @param {*} value The value to convert.
7001 * @returns {string} Returns the converted string.
7002 */
7003function objectToString(value) {
7004  return nativeObjectToString.call(value);
7005}
7006
7007/**
7008 * Checks if `value` is classified as a `Function` object.
7009 *
7010 * @static
7011 * @memberOf _
7012 * @since 0.1.0
7013 * @category Lang
7014 * @param {*} value The value to check.
7015 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
7016 * @example
7017 *
7018 * _.isFunction(_);
7019 * // => true
7020 *
7021 * _.isFunction(/abc/);
7022 * // => false
7023 */
7024function isFunction(value) {
7025  if (!isObject(value)) {
7026    return false;
7027  }
7028  // The use of `Object#toString` avoids issues with the `typeof` operator
7029  // in Safari 9 which returns 'object' for typed arrays and other constructors.
7030  var tag = baseGetTag(value);
7031  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
7032}
7033
7034/**
7035 * Checks if `value` is the
7036 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
7037 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
7038 *
7039 * @static
7040 * @memberOf _
7041 * @since 0.1.0
7042 * @category Lang
7043 * @param {*} value The value to check.
7044 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
7045 * @example
7046 *
7047 * _.isObject({});
7048 * // => true
7049 *
7050 * _.isObject([1, 2, 3]);
7051 * // => true
7052 *
7053 * _.isObject(_.noop);
7054 * // => true
7055 *
7056 * _.isObject(null);
7057 * // => false
7058 */
7059function isObject(value) {
7060  var type = typeof value;
7061  return value != null && (type == 'object' || type == 'function');
7062}
7063
7064module.exports = isFunction;
7065
7066}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
7067},{}],65:[function(require,module,exports){
7068/**
7069 * lodash 3.0.5 (Custom Build) <https://lodash.com/>
vendor: 10,156 bytes, lines 7070-7434
7070 * Build: `lodash modularize exports="npm" -o ./`
7071 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
7072 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7073 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7074 * Available under MIT license <https://lodash.com/license>
7075 */
7076
7077/** `Object#toString` result references. */
7078var regexpTag = '[object RegExp]';
7079
7080/** Used for built-in method references. */
7081var objectProto = Object.prototype;
7082
7083/**
7084 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
7085 * of values.
7086 */
7087var objectToString = objectProto.toString;
7088
7089/**
7090 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
7091 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
7092 *
7093 * @static
7094 * @memberOf _
7095 * @category Lang
7096 * @param {*} value The value to check.
7097 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
7098 * @example
7099 *
7100 * _.isObject({});
7101 * // => true
7102 *
7103 * _.isObject([1, 2, 3]);
7104 * // => true
7105 *
7106 * _.isObject(_.noop);
7107 * // => true
7108 *
7109 * _.isObject(null);
7110 * // => false
7111 */
7112function isObject(value) {
7113  var type = typeof value;
7114  return !!value && (type == 'object' || type == 'function');
7115}
7116
7117/**
7118 * Checks if `value` is classified as a `RegExp` object.
7119 *
7120 * @static
7121 * @memberOf _
7122 * @category Lang
7123 * @param {*} value The value to check.
7124 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
7125 * @example
7126 *
7127 * _.isRegExp(/abc/);
7128 * // => true
7129 *
7130 * _.isRegExp('/abc/');
7131 * // => false
7132 */
7133function isRegExp(value) {
7134  return isObject(value) && objectToString.call(value) == regexpTag;
7135}
7136
7137module.exports = isRegExp;
7138
7139},{}],66:[function(require,module,exports){
7140/**
7141 * lodash 3.0.1 (Custom Build) <https://lodash.com/>
7142 * Build: `lodash modern modularize exports="npm" -o ./`
7143 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
7144 * Based on Underscore.js 1.8.2 <http://underscorejs.org/LICENSE>
7145 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7146 * Available under MIT license <https://lodash.com/license>
7147 */
7148
7149/** `Object#toString` result references. */
7150var stringTag = '[object String]';
7151
7152/**
7153 * Checks if `value` is object-like.
7154 *
7155 * @private
7156 * @param {*} value The value to check.
7157 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
7158 */
7159function isObjectLike(value) {
7160  return !!value && typeof value == 'object';
7161}
7162
7163/** Used for native method references. */
7164var objectProto = Object.prototype;
7165
7166/**
7167 * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
7168 * of values.
7169 */
7170var objToString = objectProto.toString;
7171
7172/**
7173 * Checks if `value` is classified as a `String` primitive or object.
7174 *
7175 * @static
7176 * @memberOf _
7177 * @category Lang
7178 * @param {*} value The value to check.
7179 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
7180 * @example
7181 *
7182 * _.isString('abc');
7183 * // => true
7184 *
7185 * _.isString(1);
7186 * // => false
7187 */
7188function isString(value) {
7189  return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag);
7190}
7191
7192module.exports = isString;
7193
7194},{}],67:[function(require,module,exports){
7195/**
7196 * lodash 3.1.2 (Custom Build) <https://lodash.com/>
7197 * Build: `lodash modern modularize exports="npm" -o ./`
7198 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
7199 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7200 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7201 * Available under MIT license <https://lodash.com/license>
7202 */
7203var getNative = require('lodash._getnative'),
7204    isArguments = require('lodash.isarguments'),
7205    isArray = require('lodash.isarray');
7206
7207/** Used to detect unsigned integer values. */
7208var reIsUint = /^\d+$/;
7209
7210/** Used for native method references. */
7211var objectProto = Object.prototype;
7212
7213/** Used to check objects for own properties. */
7214var hasOwnProperty = objectProto.hasOwnProperty;
7215
7216/* Native method references for those with the same name as other `lodash` methods. */
7217var nativeKeys = getNative(Object, 'keys');
7218
7219/**
7220 * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
7221 * of an array-like value.
7222 */
7223var MAX_SAFE_INTEGER = 9007199254740991;
7224
7225/**
7226 * The base implementation of `_.property` without support for deep paths.
7227 *
7228 * @private
7229 * @param {string} key The key of the property to get.
7230 * @returns {Function} Returns the new function.
7231 */
7232function baseProperty(key) {
7233  return function(object) {
7234    return object == null ? undefined : object[key];
7235  };
7236}
7237
7238/**
7239 * Gets the "length" property value of `object`.
7240 *
7241 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
7242 * that affects Safari on at least iOS 8.1-8.3 ARM64.
7243 *
7244 * @private
7245 * @param {Object} object The object to query.
7246 * @returns {*} Returns the "length" value.
7247 */
7248var getLength = baseProperty('length');
7249
7250/**
7251 * Checks if `value` is array-like.
7252 *
7253 * @private
7254 * @param {*} value The value to check.
7255 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
7256 */
7257function isArrayLike(value) {
7258  return value != null && isLength(getLength(value));
7259}
7260
7261/**
7262 * Checks if `value` is a valid array-like index.
7263 *
7264 * @private
7265 * @param {*} value The value to check.
7266 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
7267 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
7268 */
7269function isIndex(value, length) {
7270  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
7271  length = length == null ? MAX_SAFE_INTEGER : length;
7272  return value > -1 && value % 1 == 0 && value < length;
7273}
7274
7275/**
7276 * Checks if `value` is a valid array-like length.
7277 *
7278 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
7279 *
7280 * @private
7281 * @param {*} value The value to check.
7282 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
7283 */
7284function isLength(value) {
7285  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
7286}
7287
7288/**
7289 * A fallback implementation of `Object.keys` which creates an array of the
7290 * own enumerable property names of `object`.
7291 *
7292 * @private
7293 * @param {Object} object The object to query.
7294 * @returns {Array} Returns the array of property names.
7295 */
7296function shimKeys(object) {
7297  var props = keysIn(object),
7298      propsLength = props.length,
7299      length = propsLength && object.length;
7300
7301  var allowIndexes = !!length && isLength(length) &&
7302    (isArray(object) || isArguments(object));
7303
7304  var index = -1,
7305      result = [];
7306
7307  while (++index < propsLength) {
7308    var key = props[index];
7309    if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
7310      result.push(key);
7311    }
7312  }
7313  return result;
7314}
7315
7316/**
7317 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
7318 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
7319 *
7320 * @static
7321 * @memberOf _
7322 * @category Lang
7323 * @param {*} value The value to check.
7324 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
7325 * @example
7326 *
7327 * _.isObject({});
7328 * // => true
7329 *
7330 * _.isObject([1, 2, 3]);
7331 * // => true
7332 *
7333 * _.isObject(1);
7334 * // => false
7335 */
7336function isObject(value) {
7337  // Avoid a V8 JIT bug in Chrome 19-20.
7338  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
7339  var type = typeof value;
7340  return !!value && (type == 'object' || type == 'function');
7341}
7342
7343/**
7344 * Creates an array of the own enumerable property names of `object`.
7345 *
7346 * **Note:** Non-object values are coerced to objects. See the
7347 * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
7348 * for more details.
7349 *
7350 * @static
7351 * @memberOf _
7352 * @category Object
7353 * @param {Object} object The object to query.
7354 * @returns {Array} Returns the array of property names.
7355 * @example
7356 *
7357 * function Foo() {
7358 *   this.a = 1;
7359 *   this.b = 2;
7360 * }
7361 *
7362 * Foo.prototype.c = 3;
7363 *
7364 * _.keys(new Foo);
7365 * // => ['a', 'b'] (iteration order is not guaranteed)
7366 *
7367 * _.keys('hi');
7368 * // => ['0', '1']
7369 */
7370var keys = !nativeKeys ? shimKeys : function(object) {
7371  var Ctor = object == null ? undefined : object.constructor;
7372  if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
7373      (typeof object != 'function' && isArrayLike(object))) {
7374    return shimKeys(object);
7375  }
7376  return isObject(object) ? nativeKeys(object) : [];
7377};
7378
7379/**
7380 * Creates an array of the own and inherited enumerable property names of `object`.
7381 *
7382 * **Note:** Non-object values are coerced to objects.
7383 *
7384 * @static
7385 * @memberOf _
7386 * @category Object
7387 * @param {Object} object The object to query.
7388 * @returns {Array} Returns the array of property names.
7389 * @example
7390 *
7391 * function Foo() {
7392 *   this.a = 1;
7393 *   this.b = 2;
7394 * }
7395 *
7396 * Foo.prototype.c = 3;
7397 *
7398 * _.keysIn(new Foo);
7399 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
7400 */
7401function keysIn(object) {
7402  if (object == null) {
7403    return [];
7404  }
7405  if (!isObject(object)) {
7406    object = Object(object);
7407  }
7408  var length = object.length;
7409  length = (length && isLength(length) &&
7410    (isArray(object) || isArguments(object)) && length) || 0;
7411
7412  var Ctor = object.constructor,
7413      index = -1,
7414      isProto = typeof Ctor == 'function' && Ctor.prototype === object,
7415      result = Array(length),
7416      skipIndexes = length > 0;
7417
7418  while (++index < length) {
7419    result[index] = (index + '');
7420  }
7421  for (var key in object) {
7422    if (!(skipIndexes && isIndex(key, length)) &&
7423        !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
7424      result.push(key);
7425    }
7426  }
7427  return result;
7428}
7429
7430module.exports = keys;
7431
7432},{"lodash._getnative":51,"lodash.isarguments":61,"lodash.isarray":62}],68:[function(require,module,exports){
7433/**
7434 * lodash 3.0.1 (Custom Build) <https://lodash.com/>
7435 * Build: `lodash modern modularize exports="npm" -o ./`
7436 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
7437 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7438 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7439 * Available under MIT license <https://lodash.com/license>
7440 */
7441var before = require('lodash.before');
7442
7443/**
7444 * Creates a function that is restricted to invoking `func` once. Repeat calls
7445 * to the function return the value of the first call. The `func` is invoked
7446 * with the `this` binding and arguments of the created function.
7447 *
7448 * @static
7449 * @memberOf _
7450 * @category Function
7451 * @param {Function} func The function to restrict.
7452 * @returns {Function} Returns the new restricted function.
7453 * @example
7454 *
7455 * var initialize = _.once(createApplication);
7456 * initialize();
7457 * initialize();
7458 * // `initialize` invokes `createApplication` once
7459 */
7460function once(func) {
7461  return before(2, func);
7462}
7463
7464module.exports = once;
7465
7466},{"lodash.before":57}],69:[function(require,module,exports){
7467/**
7468 * lodash 3.6.1 (Custom Build) <https://lodash.com/>
7469 * Build: `lodash modern modularize exports="npm" -o ./`
7470 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
7471 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7472 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7473 * Available under MIT license <https://lodash.com/license>
7474 */
7475
7476/** Used as the `TypeError` message for "Functions" methods. */
7477var FUNC_ERROR_TEXT = 'Expected a function';
7478
7479/* Native method references for those with the same name as other `lodash` methods. */
7480var nativeMax = Math.max;
7481
7482/**
7483 * Creates a function that invokes `func` with the `this` binding of the
7484 * created function and arguments from `start` and beyond provided as an array.
7485 *
7486 * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
7487 *
7488 * @static
7489 * @memberOf _
7490 * @category Function
7491 * @param {Function} func The function to apply a rest parameter to.
7492 * @param {number} [start=func.length-1] The start position of the rest parameter.
7493 * @returns {Function} Returns the new function.
7494 * @example
7495 *
7496 * var say = _.restParam(function(what, names) {
7497 *   return what + ' ' + _.initial(names).join(', ') +
7498 *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
7499 * });
7500 *
7501 * say('hello', 'fred', 'barney', 'pebbles');
7502 * // => 'hello fred, barney, & pebbles'
7503 */
7504function restParam(func, start) {
7505  if (typeof func != 'function') {
7506    throw new TypeError(FUNC_ERROR_TEXT);
7507  }
7508  start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
7509  return function() {
7510    var args = arguments,
7511        index = -1,
7512        length = nativeMax(args.length - start, 0),
7513        rest = Array(length);
7514
7515    while (++index < length) {
7516      rest[index] = args[start + index];
7517    }
7518    switch (start) {
7519      case 0: return func.call(this, rest);
7520      case 1: return func.call(this, args[0], rest);
7521      case 2: return func.call(this, args[0], args[1], rest);
7522    }
7523    var otherArgs = Array(start + 1);
7524    index = -1;
7525    while (++index < start) {
7526      otherArgs[index] = args[index];
7527    }
7528    otherArgs[start] = rest;
7529    return func.apply(this, otherArgs);
7530  };
7531}
7532
7533module.exports = restParam;
7534
7535},{}],70:[function(require,module,exports){
7536/**
7537 * lodash 3.1.2 (Custom Build) <https://lodash.com/>
7538 * Build: `lodash modern modularize exports="npm" -o ./`
7539 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
7540 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7541 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7542 * Available under MIT license <https://lodash.com/license>
7543 */
7544var baseGet = require('lodash._baseget'),
7545    baseSlice = require('lodash._baseslice'),
7546    toPath = require('lodash._topath'),
7547    isArray = require('lodash.isarray'),
7548    isFunction = require('lodash.isfunction');
7549
7550/** Used to match property names within property paths. */
7551var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
7552    reIsPlainProp = /^\w*$/;
7553
7554/**
7555 * Checks if `value` is a property name and not a property path.
7556 *
7557 * @private
7558 * @param {*} value The value to check.
7559 * @param {Object} [object] The object to query keys on.
7560 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
7561 */
7562function isKey(value, object) {
7563  var type = typeof value;
7564  if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
7565    return true;
7566  }
7567  if (isArray(value)) {
7568    return false;
7569  }
7570  var result = !reIsDeepProp.test(value);
7571  return result || (object != null && value in toObject(object));
7572}
7573
7574/**
7575 * Converts `value` to an object if it's not one.
7576 *
7577 * @private
7578 * @param {*} value The value to process.
7579 * @returns {Object} Returns the object.
7580 */
7581function toObject(value) {
7582  return isObject(value) ? value : Object(value);
7583}
7584
7585/**
7586 * Gets the last element of `array`.
7587 *
7588 * @static
7589 * @memberOf _
7590 * @category Array
7591 * @param {Array} array The array to query.
7592 * @returns {*} Returns the last element of `array`.
7593 * @example
7594 *
7595 * _.last([1, 2, 3]);
7596 * // => 3
7597 */
7598function last(array) {
7599  var length = array ? array.length : 0;
7600  return length ? array[length - 1] : undefined;
7601}
7602
7603/**
7604 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
7605 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
7606 *
7607 * @static
7608 * @memberOf _
7609 * @category Lang
7610 * @param {*} value The value to check.
7611 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
7612 * @example
7613 *
7614 * _.isObject({});
7615 * // => true
7616 *
7617 * _.isObject([1, 2, 3]);
7618 * // => true
7619 *
7620 * _.isObject(1);
7621 * // => false
7622 */
7623function isObject(value) {
7624  // Avoid a V8 JIT bug in Chrome 19-20.
7625  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
7626  var type = typeof value;
7627  return !!value && (type == 'object' || type == 'function');
7628}
7629
7630/**
7631 * This method is like `_.get` except that if the resolved value is a function
7632 * it is invoked with the `this` binding of its parent object and its result
7633 * is returned.
7634 *
7635 * @static
7636 * @memberOf _
7637 * @category Object
7638 * @param {Object} object The object to query.
7639 * @param {Array|string} path The path of the property to resolve.
7640 * @param {*} [defaultValue] The value returned if the resolved value is `undefined`.
7641 * @returns {*} Returns the resolved value.
7642 * @example
7643 *
7644 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
7645 *
7646 * _.result(object, 'a[0].b.c1');
7647 * // => 3
7648 *
7649 * _.result(object, 'a[0].b.c2');
7650 * // => 4
7651 *
7652 * _.result(object, 'a.b.c', 'default');
7653 * // => 'default'
7654 *
7655 * _.result(object, 'a.b.c', _.constant('default'));
7656 * // => 'default'
7657 */
7658function result(object, path, defaultValue) {
7659  var result = object == null ? undefined : object[path];
7660  if (result === undefined) {
7661    if (object != null && !isKey(path, object)) {
7662      path = toPath(path);
7663      object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
7664      result = object == null ? undefined : object[last(path)];
7665    }
7666    result = result === undefined ? defaultValue : result;
7667  }
7668  return isFunction(result) ? result.call(object) : result;
7669}
7670
7671module.exports = result;
7672
7673},{"lodash._baseget":46,"lodash._baseslice":47,"lodash._topath":55,"lodash.isarray":62,"lodash.isfunction":64}],71:[function(require,module,exports){
7674/**
7675 * lodash 3.2.0 (Custom Build) <https://lodash.com/>
7676 * Build: `lodash modularize exports="npm" -o ./`
7677 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
7678 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7679 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7680 * Available under MIT license <https://lodash.com/license>
7681 */
7682var root = require('lodash._root');
7683
7684/** Used as references for various `Number` constants. */
7685var INFINITY = 1 / 0;
7686
7687/** `Object#toString` result references. */
7688var symbolTag = '[object Symbol]';
7689
7690/** Used for built-in method references. */
7691var objectProto = Object.prototype;
7692
7693/** Used to generate unique IDs. */
7694var idCounter = 0;
7695
7696/**
7697 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
7698 * of values.
7699 */
7700var objectToString = objectProto.toString;
7701
7702/** Built-in value references. */
7703var Symbol = root.Symbol;
7704
7705/** Used to convert symbols to primitives and strings. */
7706var symbolProto = Symbol ? Symbol.prototype : undefined,
7707    symbolToString = Symbol ? symbolProto.toString : undefined;
7708
7709/**
7710 * Checks if `value` is object-like. A value is object-like if it's not `null`
7711 * and has a `typeof` result of "object".
7712 *
7713 * @static
7714 * @memberOf _
7715 * @category Lang
7716 * @param {*} value The value to check.
7717 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
7718 * @example
7719 *
7720 * _.isObjectLike({});
7721 * // => true
7722 *
7723 * _.isObjectLike([1, 2, 3]);
7724 * // => true
7725 *
7726 * _.isObjectLike(_.noop);
7727 * // => false
7728 *
7729 * _.isObjectLike(null);
7730 * // => false
7731 */
7732function isObjectLike(value) {
7733  return !!value && typeof value == 'object';
7734}
7735
7736/**
7737 * Checks if `value` is classified as a `Symbol` primitive or object.
7738 *
7739 * @static
7740 * @memberOf _
7741 * @category Lang
7742 * @param {*} value The value to check.
7743 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
7744 * @example
7745 *
7746 * _.isSymbol(Symbol.iterator);
7747 * // => true
7748 *
7749 * _.isSymbol('abc');
7750 * // => false
7751 */
7752function isSymbol(value) {
7753  return typeof value == 'symbol' ||
7754    (isObjectLike(value) && objectToString.call(value) == symbolTag);
7755}
7756
7757/**
7758 * Converts `value` to a string if it's not one. An empty string is returned
7759 * for `null` and `undefined` values. The sign of `-0` is preserved.
7760 *
7761 * @static
7762 * @memberOf _
7763 * @category Lang
7764 * @param {*} value The value to process.
7765 * @returns {string} Returns the string.
7766 * @example
7767 *
7768 * _.toString(null);
7769 * // => ''
7770 *
7771 * _.toString(-0);
7772 * // => '-0'
7773 *
7774 * _.toString([1, 2, 3]);
7775 * // => '1,2,3'
7776 */
7777function toString(value) {
7778  // Exit early for strings to avoid a performance hit in some environments.
7779  if (typeof value == 'string') {
7780    return value;
7781  }
7782  if (value == null) {
7783    return '';
7784  }
7785  if (isSymbol(value)) {
7786    return Symbol ? symbolToString.call(value) : '';
7787  }
7788  var result = (value + '');
7789  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
7790}
7791
7792/**
7793 * Generates a unique ID. If `prefix` is provided the ID is appended to it.
7794 *
7795 * @static
7796 * @memberOf _
7797 * @category Util
7798 * @param {string} [prefix] The value to prefix the ID with.
7799 * @returns {string} Returns the unique ID.
7800 * @example
7801 *
7802 * _.uniqueId('contact_');
7803 * // => 'contact_104'
7804 *
7805 * _.uniqueId();
7806 * // => '105'
7807 */
7808function uniqueId(prefix) {
7809  var id = ++idCounter;
7810  return toString(prefix) + id;
7811}
7812
7813module.exports = uniqueId;
7814
7815},{"lodash._root":54}],72:[function(require,module,exports){
7816(function(window) {
7817    var re = {
7818        not_string: /[^s]/,
7819        number: /[diefg]/,
7820        json: /[j]/,
7821        not_json: /[^j]/,
7822        text: /^[^\x25]+/,
7823        modulo: /^\x25{2}/,
7824        placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosuxX])
7824/,
7825        key: /^([a-z_][a-z_\d]*)/i,
7826        key_access: /^\.([a-z_][a-z_\d]*)/i,
7827        index_access: /^\[(\d+)\]/,
7828        sign: /^[\+\-]/
7829    }
7830
7831    function sprintf() {
7832        var key = arguments[0], cache = sprintf.cache
7833        if (!(cache[key] && cache.hasOwnProperty(key))) {
7834            cache[key] = sprintf.parse(key)
7835        }
7836        return sprintf.format.call(null, cache[key], arguments)
7837    }
7838
7839    sprintf.format = function(parse_tree, argv) {
7840        var cursor = 1, tree_length = parse_tree.length, node_type = "", arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = ""
7841        for (i = 0; i < tree_length; i++) {
7842            node_type = get_type(parse_tree[i])
7843            if (node_type === "string") {
7844                output[output.length] = parse_tree[i]
7845            }
7846            else if (node_type === "array") {
7847                match = parse_tree[i] // convenience purposes only
7848                if (match[2]) { // keyword argument
7849                    arg = argv[cursor]
7850                    for (k = 0; k < match[2].length; k++) {
7851                        if (!arg.hasOwnProperty(match[2][k])) {
7852                            throw new Error(sprintf("[sprintf] property '%s' does not exist", match[2][k]))
7853                        }
7854                        arg = arg[match[2][k]]
7855                    }
7856                }
7857                else if (match[1]) { // positional argument (explicit)
7858                    arg = argv[match[1]]
7859                }
7860                else { // positional argument (implicit)
7861                    arg = argv[cursor++]
7862                }
7863
7864                if (get_type(arg) == "function") {
7865                    arg = arg()
7866                }
7867
7868                if (re.not_string.test(match[8]) && re.not_json.test(match[8]) && (get_type(arg) != "number" && isNaN(arg))) {
7869                    throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg)))
7870                }
7871
7872                if (re.number.test(match[8])) {
7873                    is_positive = arg >= 0
7874                }
7875
7876                switch (match[8]) {
7877                    case "b":
7878                        arg = arg.toString(2)
7879                    break
7880                    case "c":
7881                        arg = String.fromCharCode(arg)
7882                    break
7883                    case "d":
7884                    case "i":
7885                        arg = parseInt(arg, 10)
7886                    break
7887                    case "j":
7888                        arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0)
7889                    break
7890                    case "e":
7891                        arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential()
7892                    break
7893                    case "f":
7894                        arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg)
7895                    break
7896                    case "g":
7897                        arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg)
7898                    break
7899                    case "o":
7900                        arg = arg.toString(8)
7901                    break
7902                    case "s":
7903                        arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg)
7904                    break
7905                    case "u":
7906                        arg = arg >>> 0
7907                    break
7908                    case "x":
7909                        arg = arg.toString(16)
7910                    break
7911                    case "X":
7912                        arg = arg.toString(16).toUpperCase()
7913                    break
7914                }
7915                if (re.json.test(match[8])) {
7916                    output[output.length] = arg
7917                }
7918                else {
7919                    if (re.number.test(match[8]) && (!is_positive || match[3])) {
7920                        sign = is_positive ? "+" : "-"
7921                        arg = arg.toString().replace(re.sign, "")
7922                    }
7923                    else {
7924                        sign = ""
7925                    }
7926                    pad_character = match[4] ? match[4] === "0" ? "0" : match[4].charAt(1) : " "
7927                    pad_length = match[6] - (sign + arg).length
7928                    pad = match[6] ? (pad_length >
7928 0 ? str_repeat(pad_character, pad_length) : "") : ""
7929                    output[output.length] = match[5] ? sign + arg + pad : (pad_character === "0" ? sign + pad + arg : pad + sign + arg)
7930                }
7931            }
7932        }
7933        return output.join("")
7934    }
7935
7936    sprintf.cache = {}
7937
7938    sprintf.parse = function(fmt) {
7939        var _fmt = fmt, match = [], parse_tree = [], arg_names = 0
7940        while (_fmt) {
7941            if ((match = re.text.exec(_fmt)) !== null) {
7942                parse_tree[parse_tree.length] = match[0]
7943            }
7944            else if ((match = re.modulo.exec(_fmt)) !== null) {
7945                parse_tree[parse_tree.length] = "%"
7946            }
7947            else if ((match = re.placeholder.exec(_fmt)) !== null) {
7948                if (match[2]) {
7949                    arg_names |= 1
7950                    var field_list = [], replacement_field = match[2], field_match = []
7951                    if ((field_match = re.key.exec(replacement_field)) !== null) {
7952                        field_list[field_list.length] = field_match[1]
7953                        while ((replacement_field = replacement_field.substring(field_match[0].length)) !== "") {
7954                            if ((field_match = re.key_access.exec(replacement_field)) !== null) {
7955                                field_list[field_list.length] = field_match[1]
7956                            }
7957                            else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
7958                                field_list[field_list.length] = field_match[1]
7959                            }
7960                            else {
7961                                throw new SyntaxError("[sprintf] failed to parse named argument key")
7962                            }
7963                        }
7964                    }
7965                    else {
7966                        throw new SyntaxError("[sprintf] failed to parse named argument key")
7967                    }
7968                    match[2] = field_list
7969                }
7970                else {
7971                    arg_names |= 2
7972                }
7973                if (arg_names === 3) {
7974                    throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported")
7975                }
7976                parse_tree[parse_tree.length] = match
7977            }
7978            else {
7979                throw new SyntaxError("[sprintf] unexpected placeholder")
7980            }
7981            _fmt = _fmt.substring(match[0].length)
7982        }
7983        return parse_tree
7984    }
7985
7986    var vsprintf = function(fmt, argv, _argv) {
7987        _argv = (argv || []).slice(0)
7988        _argv.splice(0, 0, fmt)
7989        return sprintf.apply(null, _argv)
7990    }
7991
7992    /**
7993     * helpers
7994     */
7995    function get_type(variable) {
7996        return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase()
7997    }
7998
7999    function str_repeat(input, multiplier) {
8000        return Array(multiplier + 1).join(input)
8001    }
8002
8003    /**
8004     * export to either browser or node.js
8005     */
8006    if (typeof exports !== "undefined") {
8007        exports.sprintf = sprintf
8008        exports.vsprintf = vsprintf
8009    }
8010    else {
8011        window.sprintf = sprintf
8012        window.vsprintf = vsprintf
8013
8014        if (typeof define === "function" && define.amd) {
8015            define(function() {
8016                return {
8017                    sprintf: sprintf,
8018                    vsprintf: vsprintf
8019                }
8020            })
8021        }
8022    }
8023})(typeof window === "undefined" ? this : window);
8024
8025},{}],73:[function(require,module,exports){
8026module.exports = function(func) {
8027  setTimeout(func, 0);
8028};
8029
8030},{}],74:[function(require,module,exports){
8031var checkEmpty = function(locationData) {
8032  if(! locationData || locationData.trim().length === 0 ) {
8033    return null;
8034  }
8035  return locationData;
8036};
8037
8038var parseJsonLocationData = function(jsonLocationDataEl) {
8039  if(!jsonLocationDataEl) {
8040    return {address: {}};
8041  }
8042
8043  return JSON.parse(jsonLocationDataEl.textContent);
8044};
8045
8046var getEmbedKey = function(locationDataEl) {
8047  if(!locationDataEl) {
8048    return '';
8049  }
8050
8051  return locationDataEl.getAttribute('data-embed-key');
8052};
8053
8054var formatHours = function(hoursData) {
8055
8056  if (! hoursData || hoursData.length === 0) {
8057    return null;
8058  }
8059
8060  var hoursArray = hoursData.map(function(day) {
8061    var daySplat = day.split(' ');
8062    var dayAbbrev = daySplat[0];
8063    var openCloseSplat = daySplat[1].split('-');
8064
8065    return {
8066      day: dayAbbrev,
8067      open: openCloseSplat[0],
8068      close: openCloseSplat[1]
8069    };
8070  });
8071
8072  return hoursArray.reduce(function(accumulatedDayObject, dayObject) {
8073    accumulatedDayObject[dayObject.day] = {
8074      open: dayObject.open,
8075      close: dayObject.close
8076    };
8077
8078    return accumulatedDayObject;
8079  }, {});
8080};
8081
8082var initializeSiteLocation = function(siteLocation, locationDataID) {
8083  var initializeHelper = function() {
8084    var locationDataEl = document.getElementById(locationDataID);
8085    var embedAPIKey = getEmbedKey(locationDataEl);
8086    var jsonld = parseJsonLocationData(locationDataEl);
8087    var hoursObject, locationData, address, city, state, zipcode, country;
8088    address = checkEmpty(jsonld.address.streetAddress);
8089    city = checkEmpty(jsonld.address.addressLocality);
8090    state = checkEmpty(jsonld.address.addressRegion);
8091    zipcode = checkEmpty(jsonld.address.postalCode);
8092    country = checkEmpty(jsonld.address.addressCountry);
8093    hoursObject = formatHours(jsonld.openingHours);
8094
8095
8096    if(address || city || state || zipcode || country) {
8097      locationData = {
8098        address: address,
8099        city: city,
8100        state: state,
8101        zipcode: zipcode,
8102        country: country
8103      };
8104    }
8105
8106    var cleintWidth = document.documentElement.clientWidth;
8107    var innerWidth = window.innerWidth || 0;
8108    var viewportWidth = Math.max(cleintWidth, innerWidth);
8109    var lang = document.body.lang || 'en';
8110
8111    /* Only initialize the sitelocation view if the viewport is smaller than
8112     * 736 pixels.
8113     */
8114    if(viewportWidth <= 736) {
8115      siteLocation.initialize({
8116        lang: lang,
8117        hours: hoursObject,
8118        phone: checkEmpty(jsonld.telephone),
8119        location: locationData,
8120        embedAPIKey: embedAPIKey
8121      });
8122    }
8123  };
8124
8125  return initializeHelper;
8126};
8127
8128module.exports = initializeSiteLocation;
8129
8130},{}],75:[function(require,module,exports){
8131'use strict';
8132
8133exports.__esModule = true;
8134// istanbul ignore next
8135
8136function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8137
8138// istanbul ignore next
8139
8140function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8141
8142var _handlebarsBase = require('./handlebars/base');
8143
8144var base = _interopRequireWildcard(_handlebarsBase);
8145
8146// Each of these augment the Handlebars object. No need to setup here.
8147// (This is done to easily share code between commonjs and browse envs)
8148
8149var _handlebarsSafeString = require('./handlebars/safe-string');
8150
8151var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString);
8152
8153var _handlebarsException = require('./handlebars/exception');
8154
8155var _handlebarsException2 = _interopRequireDefault(_handlebarsException);
8156
8157var _handlebarsUtils = require('./handlebars/utils');
8158
8159var Utils = _interopRequireWildcard(_handlebarsUtils);
8160
8161var _handlebarsRuntime = require('./handlebars/runtime');
8162
8163var runtime = _interopRequireWildcard(_handlebarsRuntime);
8164
8165var _handlebarsNoConflict = require('./handlebars/no-conflict');
8166
8167var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
8168
8169// For compatibility and usage outside of module systems, make the Handlebars object a namespace
8170function create() {
8171  var hb = new base.HandlebarsEnvironment();
8172
8173  Utils.extend(hb, base);
8174  hb.SafeString = _handlebarsSafeString2['default'];
8175  hb.Exception = _handlebarsException2['default'];
8176  hb.Utils = Utils;
8177  hb.escapeExpression = Utils.escapeExpression;
8178
8179  hb.VM = runtime;
8180  hb.template = function (spec) {
8181    return runtime.template(spec, hb);
8182  };
8183
8184  return hb;
8185}
8186
8187var inst = create();
8188inst.create = create;
8189
8190_handlebarsNoConflict2['default'](inst);
8191
8192inst['default'] = inst;
8193
8194exports['default'] = inst;
8195module.exports = exports['default'];
8196
8197
8198},{"./handlebars/base":76,"./handlebars/exception":79,"./handlebars/no-conflict":89,"./handlebars/runtime":90,"./handlebars/safe-string":91,"./handlebars/utils":92}],76:[function(require,module,exports){
8199'use strict';
8200
8201exports.__esModule = true;
8202exports.HandlebarsEnvironment = HandlebarsEnvironment;
8203// istanbul ignore next
8204
8205function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8206
8207var _utils = require('./utils');
8208
8209var _exception = require('./exception');
8210
8211var _exception2 = _interopRequireDefault(_exception);
8212
8213var _helpers = require('./helpers');
8214
8215var _decorators = require('./decorators');
8216
8217var _logger = require('./logger');
8218
8219var _logger2 = _interopRequireDefault(_logger);
8220
8221var VERSION = '4.0.14';
8222exports.VERSION = VERSION;
8223var COMPILER_REVISION = 7;
8224
8225exports.COMPILER_REVISION = COMPILER_REVISION;
8226var REVISION_CHANGES = {
8227  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
8228  2: '== 1.0.0-rc.3',
8229  3: '== 1.0.0-rc.4',
8230  4: '== 1.x.x',
8231  5: '== 2.0.0-alpha.x',
8232  6: '>
vendor: 29,761 bytes, lines 8232-9266
8232= 2.0.0-beta.1',
8233  7: '>= 4.0.0'
8234};
8235
8236exports.REVISION_CHANGES = REVISION_CHANGES;
8237var objectType = '[object Object]';
8238
8239function HandlebarsEnvironment(helpers, partials, decorators) {
8240  this.helpers = helpers || {};
8241  this.partials = partials || {};
8242  this.decorators = decorators || {};
8243
8244  _helpers.registerDefaultHelpers(this);
8245  _decorators.registerDefaultDecorators(this);
8246}
8247
8248HandlebarsEnvironment.prototype = {
8249  constructor: HandlebarsEnvironment,
8250
8251  logger: _logger2['default'],
8252  log: _logger2['default'].log,
8253
8254  registerHelper: function registerHelper(name, fn) {
8255    if (_utils.toString.call(name) === objectType) {
8256      if (fn) {
8257        throw new _exception2['default']('Arg not supported with multiple helpers');
8258      }
8259      _utils.extend(this.helpers, name);
8260    } else {
8261      this.helpers[name] = fn;
8262    }
8263  },
8264  unregisterHelper: function unregisterHelper(name) {
8265    delete this.helpers[name];
8266  },
8267
8268  registerPartial: function registerPartial(name, partial) {
8269    if (_utils.toString.call(name) === objectType) {
8270      _utils.extend(this.partials, name);
8271    } else {
8272      if (typeof partial === 'undefined') {
8273        throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined');
8274      }
8275      this.partials[name] = partial;
8276    }
8277  },
8278  unregisterPartial: function unregisterPartial(name) {
8279    delete this.partials[name];
8280  },
8281
8282  registerDecorator: function registerDecorator(name, fn) {
8283    if (_utils.toString.call(name) === objectType) {
8284      if (fn) {
8285        throw new _exception2['default']('Arg not supported with multiple decorators');
8286      }
8287      _utils.extend(this.decorators, name);
8288    } else {
8289      this.decorators[name] = fn;
8290    }
8291  },
8292  unregisterDecorator: function unregisterDecorator(name) {
8293    delete this.decorators[name];
8294  }
8295};
8296
8297var log = _logger2['default'].log;
8298
8299exports.log = log;
8300exports.createFrame = _utils.createFrame;
8301exports.logger = _logger2['default'];
8302
8303
8304},{"./decorators":77,"./exception":79,"./helpers":80,"./logger":88,"./utils":92}],77:[function(require,module,exports){
8305'use strict';
8306
8307exports.__esModule = true;
8308exports.registerDefaultDecorators = registerDefaultDecorators;
8309// istanbul ignore next
8310
8311function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8312
8313var _decoratorsInline = require('./decorators/inline');
8314
8315var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline);
8316
8317function registerDefaultDecorators(instance) {
8318  _decoratorsInline2['default'](instance);
8319}
8320
8321
8322},{"./decorators/inline":78}],78:[function(require,module,exports){
8323'use strict';
8324
8325exports.__esModule = true;
8326
8327var _utils = require('../utils');
8328
8329exports['default'] = function (instance) {
8330  instance.registerDecorator('inline', function (fn, props, container, options) {
8331    var ret = fn;
8332    if (!props.partials) {
8333      props.partials = {};
8334      ret = function (context, options) {
8335        // Create a new partials stack frame prior to exec.
8336        var original = container.partials;
8337        container.partials = _utils.extend({}, original, props.partials);
8338        var ret = fn(context, options);
8339        container.partials = original;
8340        return ret;
8341      };
8342    }
8343
8344    props.partials[options.args[0]] = options.fn;
8345
8346    return ret;
8347  });
8348};
8349
8350module.exports = exports['default'];
8351
8352
8353},{"../utils":92}],79:[function(require,module,exports){
8354'use strict';
8355
8356exports.__esModule = true;
8357
8358var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
8359
8360function Exception(message, node) {
8361  var loc = node && node.loc,
8362      line = undefined,
8363      column = undefined;
8364  if (loc) {
8365    line = loc.start.line;
8366    column = loc.start.column;
8367
8368    message += ' - ' + line + ':' + column;
8369  }
8370
8371  var tmp = Error.prototype.constructor.call(this, message);
8372
8373  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
8374  for (var idx = 0; idx < errorProps.length; idx++) {
8375    this[errorProps[idx]] = tmp[errorProps[idx]];
8376  }
8377
8378  /* istanbul ignore else */
8379  if (Error.captureStackTrace) {
8380    Error.captureStackTrace(this, Exception);
8381  }
8382
8383  try {
8384    if (loc) {
8385      this.lineNumber = line;
8386
8387      // Work around issue under safari where we can't directly set the column value
8388      /* istanbul ignore next */
8389      if (Object.defineProperty) {
8390        Object.defineProperty(this, 'column', {
8391          value: column,
8392          enumerable: true
8393        });
8394      } else {
8395        this.column = column;
8396      }
8397    }
8398  } catch (nop) {
8399    /* Ignore if the browser is very particular */
8400  }
8401}
8402
8403Exception.prototype = new Error();
8404
8405exports['default'] = Exception;
8406module.exports = exports['default'];
8407
8408
8409},{}],80:[function(require,module,exports){
8410'use strict';
8411
8412exports.__esModule = true;
8413exports.registerDefaultHelpers = registerDefaultHelpers;
8414// istanbul ignore next
8415
8416function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8417
8418var _helpersBlockHelperMissing = require('./helpers/block-helper-missing');
8419
8420var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing);
8421
8422var _helpersEach = require('./helpers/each');
8423
8424var _helpersEach2 = _interopRequireDefault(_helpersEach);
8425
8426var _helpersHelperMissing = require('./helpers/helper-missing');
8427
8428var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing);
8429
8430var _helpersIf = require('./helpers/if');
8431
8432var _helpersIf2 = _interopRequireDefault(_helpersIf);
8433
8434var _helpersLog = require('./helpers/log');
8435
8436var _helpersLog2 = _interopRequireDefault(_helpersLog);
8437
8438var _helpersLookup = require('./helpers/lookup');
8439
8440var _helpersLookup2 = _interopRequireDefault(_helpersLookup);
8441
8442var _helpersWith = require('./helpers/with');
8443
8444var _helpersWith2 = _interopRequireDefault(_helpersWith);
8445
8446function registerDefaultHelpers(instance) {
8447  _helpersBlockHelperMissing2['default'](instance);
8448  _helpersEach2['default'](instance);
8449  _helpersHelperMissing2['default'](instance);
8450  _helpersIf2['default'](instance);
8451  _helpersLog2['default'](instance);
8452  _helpersLookup2['default'](instance);
8453  _helpersWith2['default'](instance);
8454}
8455
8456
8457},{"./helpers/block-helper-missing":81,"./helpers/each":82,"./helpers/helper-missing":83,"./helpers/if":84,"./helpers/log":85,"./helpers/lookup":86,"./helpers/with":87}],81:[function(require,module,exports){
8458'use strict';
8459
8460exports.__esModule = true;
8461
8462var _utils = require('../utils');
8463
8464exports['default'] = function (instance) {
8465  instance.registerHelper('blockHelperMissing', function (context, options) {
8466    var inverse = options.inverse,
8467        fn = options.fn;
8468
8469    if (context === true) {
8470      return fn(this);
8471    } else if (context === false || context == null) {
8472      return inverse(this);
8473    } else if (_utils.isArray(context)) {
8474      if (context.length > 0) {
8475        if (options.ids) {
8476          options.ids = [options.name];
8477        }
8478
8479        return instance.helpers.each(context, options);
8480      } else {
8481        return inverse(this);
8482      }
8483    } else {
8484      if (options.data && options.ids) {
8485        var data = _utils.createFrame(options.data);
8486        data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name);
8487        options = { data: data };
8488      }
8489
8490      return fn(context, options);
8491    }
8492  });
8493};
8494
8495module.exports = exports['default'];
8496
8497
8498},{"../utils":92}],82:[function(require,module,exports){
8499'use strict';
8500
8501exports.__esModule = true;
8502// istanbul ignore next
8503
8504function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8505
8506var _utils = require('../utils');
8507
8508var _exception = require('../exception');
8509
8510var _exception2 = _interopRequireDefault(_exception);
8511
8512exports['default'] = function (instance) {
8513  instance.registerHelper('each', function (context, options) {
8514    if (!options) {
8515      throw new _exception2['default']('Must pass iterator to #each');
8516    }
8517
8518    var fn = options.fn,
8519        inverse = options.inverse,
8520        i = 0,
8521        ret = '',
8522        data = undefined,
8523        contextPath = undefined;
8524
8525    if (options.data && options.ids) {
8526      contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
8527    }
8528
8529    if (_utils.isFunction(context)) {
8530      context = context.call(this);
8531    }
8532
8533    if (options.data) {
8534      data = _utils.createFrame(options.data);
8535    }
8536
8537    function execIteration(field, index, last) {
8538      if (data) {
8539        data.key = field;
8540        data.index = index;
8541        data.first = index === 0;
8542        data.last = !!last;
8543
8544        if (contextPath) {
8545          data.contextPath = contextPath + field;
8546        }
8547      }
8548
8549      ret = ret + fn(context[field], {
8550        data: data,
8551        blockParams: _utils.blockParams([context[field], field], [contextPath + field, null])
8552      });
8553    }
8554
8555    if (context && typeof context === 'object') {
8556      if (_utils.isArray(context)) {
8557        for (var j = context.length; i < j; i++) {
8558          if (i in context) {
8559            execIteration(i, i, i === context.length - 1);
8560          }
8561        }
8562      } else {
8563        var priorKey = undefined;
8564
8565        for (var key in context) {
8566          if (context.hasOwnProperty(key)) {
8567            // We're running the iterations one step out of sync so we can detect
8568            // the last iteration without have to scan the object twice and create
8569            // an itermediate keys array.
8570            if (priorKey !== undefined) {
8571              execIteration(priorKey, i - 1);
8572            }
8573            priorKey = key;
8574            i++;
8575          }
8576        }
8577        if (priorKey !== undefined) {
8578          execIteration(priorKey, i - 1, true);
8579        }
8580      }
8581    }
8582
8583    if (i === 0) {
8584      ret = inverse(this);
8585    }
8586
8587    return ret;
8588  });
8589};
8590
8591module.exports = exports['default'];
8592
8593
8594},{"../exception":79,"../utils":92}],83:[function(require,module,exports){
8595'use strict';
8596
8597exports.__esModule = true;
8598// istanbul ignore next
8599
8600function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8601
8602var _exception = require('../exception');
8603
8604var _exception2 = _interopRequireDefault(_exception);
8605
8606exports['default'] = function (instance) {
8607  instance.registerHelper('helperMissing', function () /* [args, ]options */{
8608    if (arguments.length === 1) {
8609      // A missing field in a {{foo}} construct.
8610      return undefined;
8611    } else {
8612      // Someone is actually trying to call something, blow up.
8613      throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
8614    }
8615  });
8616};
8617
8618module.exports = exports['default'];
8619
8620
8621},{"../exception":79}],84:[function(require,module,exports){
8622'use strict';
8623
8624exports.__esModule = true;
8625
8626var _utils = require('../utils');
8627
8628exports['default'] = function (instance) {
8629  instance.registerHelper('if', function (conditional, options) {
8630    if (_utils.isFunction(conditional)) {
8631      conditional = conditional.call(this);
8632    }
8633
8634    // Default behavior is to render the positive path if the value is truthy and not empty.
8635    // The `includeZero` option may be set to treat the condtional as purely not empty based on the
8636    // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
8637    if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) {
8638      return options.inverse(this);
8639    } else {
8640      return options.fn(this);
8641    }
8642  });
8643
8644  instance.registerHelper('unless', function (conditional, options) {
8645    return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash });
8646  });
8647};
8648
8649module.exports = exports['default'];
8650
8651
8652},{"../utils":92}],85:[function(require,module,exports){
8653'use strict';
8654
8655exports.__esModule = true;
8656
8657exports['default'] = function (instance) {
8658  instance.registerHelper('log', function () /* message, options */{
8659    var args = [undefined],
8660        options = arguments[arguments.length - 1];
8661    for (var i = 0; i < arguments.length - 1; i++) {
8662      args.push(arguments[i]);
8663    }
8664
8665    var level = 1;
8666    if (options.hash.level != null) {
8667      level = options.hash.level;
8668    } else if (options.data && options.data.level != null) {
8669      level = options.data.level;
8670    }
8671    args[0] = level;
8672
8673    instance.log.apply(instance, args);
8674  });
8675};
8676
8677module.exports = exports['default'];
8678
8679
8680},{}],86:[function(require,module,exports){
8681'use strict';
8682
8683exports.__esModule = true;
8684
8685exports['default'] = function (instance) {
8686  instance.registerHelper('lookup', function (obj, field) {
8687    if (!obj) {
8688      return obj;
8689    }
8690    if (field === 'constructor' && !obj.propertyIsEnumerable(field)) {
8691      return undefined;
8692    }
8693    return obj[field];
8694  });
8695};
8696
8697module.exports = exports['default'];
8698
8699
8700},{}],87:[function(require,module,exports){
8701'use strict';
8702
8703exports.__esModule = true;
8704
8705var _utils = require('../utils');
8706
8707exports['default'] = function (instance) {
8708  instance.registerHelper('with', function (context, options) {
8709    if (_utils.isFunction(context)) {
8710      context = context.call(this);
8711    }
8712
8713    var fn = options.fn;
8714
8715    if (!_utils.isEmpty(context)) {
8716      var data = options.data;
8717      if (options.data && options.ids) {
8718        data = _utils.createFrame(options.data);
8719        data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);
8720      }
8721
8722      return fn(context, {
8723        data: data,
8724        blockParams: _utils.blockParams([context], [data && data.contextPath])
8725      });
8726    } else {
8727      return options.inverse(this);
8728    }
8729  });
8730};
8731
8732module.exports = exports['default'];
8733
8734
8735},{"../utils":92}],88:[function(require,module,exports){
8736'use strict';
8737
8738exports.__esModule = true;
8739
8740var _utils = require('./utils');
8741
8742var logger = {
8743  methodMap: ['debug', 'info', 'warn', 'error'],
8744  level: 'info',
8745
8746  // Maps a given level value to the `methodMap` indexes above.
8747  lookupLevel: function lookupLevel(level) {
8748    if (typeof level === 'string') {
8749      var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());
8750      if (levelMap >= 0) {
8751        level = levelMap;
8752      } else {
8753        level = parseInt(level, 10);
8754      }
8755    }
8756
8757    return level;
8758  },
8759
8760  // Can be overridden in the host environment
8761  log: function log(level) {
8762    level = logger.lookupLevel(level);
8763
8764    if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
8765      var method = logger.methodMap[level];
8766      if (!console[method]) {
8767        // eslint-disable-line no-console
8768        method = 'log';
8769      }
8770
8771      for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
8772        message[_key - 1] = arguments[_key];
8773      }
8774
8775      console[method].apply(console, message); // eslint-disable-line no-console
8776    }
8777  }
8778};
8779
8780exports['default'] = logger;
8781module.exports = exports['default'];
8782
8783
8784},{"./utils":92}],89:[function(require,module,exports){
8785(function (global){(function (){
8786/* global window */
8787'use strict';
8788
8789exports.__esModule = true;
8790
8791exports['default'] = function (Handlebars) {
8792  /* istanbul ignore next */
8793  var root = typeof global !== 'undefined' ? global : window,
8794      $Handlebars = root.Handlebars;
8795  /* istanbul ignore next */
8796  Handlebars.noConflict = function () {
8797    if (root.Handlebars === Handlebars) {
8798      root.Handlebars = $Handlebars;
8799    }
8800    return Handlebars;
8801  };
8802};
8803
8804module.exports = exports['default'];
8805
8806
8807}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
8808},{}],90:[function(require,module,exports){
8809'use strict';
8810
8811exports.__esModule = true;
8812exports.checkRevision = checkRevision;
8813exports.template = template;
8814exports.wrapProgram = wrapProgram;
8815exports.resolvePartial = resolvePartial;
8816exports.invokePartial = invokePartial;
8817exports.noop = noop;
8818// istanbul ignore next
8819
8820function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8821
8822// istanbul ignore next
8823
8824function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
8825
8826var _utils = require('./utils');
8827
8828var Utils = _interopRequireWildcard(_utils);
8829
8830var _exception = require('./exception');
8831
8832var _exception2 = _interopRequireDefault(_exception);
8833
8834var _base = require('./base');
8835
8836function checkRevision(compilerInfo) {
8837  var compilerRevision = compilerInfo && compilerInfo[0] || 1,
8838      currentRevision = _base.COMPILER_REVISION;
8839
8840  if (compilerRevision !== currentRevision) {
8841    if (compilerRevision < currentRevision) {
8842      var runtimeVersions = _base.REVISION_CHANGES[currentRevision],
8843          compilerVersions = _base.REVISION_CHANGES[compilerRevision];
8844      throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
8845    } else {
8846      // Use the embedded version info since the runtime doesn't know about this revision yet
8847      throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
8848    }
8849  }
8850}
8851
8852function template(templateSpec, env) {
8853  /* istanbul ignore next */
8854  if (!env) {
8855    throw new _exception2['default']('No environment passed to template');
8856  }
8857  if (!templateSpec || !templateSpec.main) {
8858    throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
8859  }
8860
8861  templateSpec.main.decorator = templateSpec.main_d;
8862
8863  // Note: Using env.VM references rather than local var references throughout this section to allow
8864  // for external users to override these as psuedo-supported APIs.
8865  env.VM.checkRevision(templateSpec.compiler);
8866
8867  function invokePartialWrapper(partial, context, options) {
8868    if (options.hash) {
8869      context = Utils.extend({}, context, options.hash);
8870      if (options.ids) {
8871        options.ids[0] = true;
8872      }
8873    }
8874
8875    partial = env.VM.resolvePartial.call(this, partial, context, options);
8876    var result = env.VM.invokePartial.call(this, partial, context, options);
8877
8878    if (result == null && env.compile) {
8879      options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
8880      result = options.partials[options.name](context, options);
8881    }
8882    if (result != null) {
8883      if (options.indent) {
8884        var lines = result.split('\n');
8885        for (var i = 0, l = lines.length; i < l; i++) {
8886          if (!lines[i] && i + 1 === l) {
8887            break;
8888          }
8889
8890          lines[i] = options.indent + lines[i];
8891        }
8892        result = lines.join('\n');
8893      }
8894      return result;
8895    } else {
8896      throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
8897    }
8898  }
8899
8900  // Just add water
8901  var container = {
8902    strict: function strict(obj, name) {
8903      if (!(name in obj)) {
8904        throw new _exception2['default']('"' + name + '" not defined in ' + obj);
8905      }
8906      return obj[name];
8907    },
8908    lookup: function lookup(depths, name) {
8909      var len = depths.length;
8910      for (var i = 0; i < len; i++) {
8911        if (depths[i] && depths[i][name] != null) {
8912          return depths[i][name];
8913        }
8914      }
8915    },
8916    lambda: function lambda(current, context) {
8917      return typeof current === 'function' ? current.call(context) : current;
8918    },
8919
8920    escapeExpression: Utils.escapeExpression,
8921    invokePartial: invokePartialWrapper,
8922
8923    fn: function fn(i) {
8924      var ret = templateSpec[i];
8925      ret.decorator = templateSpec[i + '_d'];
8926      return ret;
8927    },
8928
8929    programs: [],
8930    program: function program(i, data, declaredBlockParams, blockParams, depths) {
8931      var programWrapper = this.programs[i],
8932          fn = this.fn(i);
8933      if (data || depths || blockParams || declaredBlockParams) {
8934        programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
8935      } else if (!programWrapper) {
8936        programWrapper = this.programs[i] = wrapProgram(this, i, fn);
8937      }
8938      return programWrapper;
8939    },
8940
8941    data: function data(value, depth) {
8942      while (value && depth--) {
8943        value = value._parent;
8944      }
8945      return value;
8946    },
8947    merge: function merge(param, common) {
8948      var obj = param || common;
8949
8950      if (param && common && param !== common) {
8951        obj = Utils.extend({}, common, param);
8952      }
8953
8954      return obj;
8955    },
8956    // An empty object to use as replacement for null-contexts
8957    nullContext: Object.seal({}),
8958
8959    noop: env.VM.noop,
8960    compilerInfo: templateSpec.compiler
8961  };
8962
8963  function ret(context) {
8964    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
8965
8966    var data = options.data;
8967
8968    ret._setup(options);
8969    if (!options.partial && templateSpec.useData) {
8970      data = initData(context, data);
8971    }
8972    var depths = undefined,
8973        blockParams = templateSpec.useBlockParams ? [] : undefined;
8974    if (templateSpec.useDepths) {
8975      if (options.depths) {
8976        depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;
8977      } else {
8978        depths = [context];
8979      }
8980    }
8981
8982    function main(context /*, options*/) {
8983      return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
8984    }
8985    main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
8986    return main(context, options);
8987  }
8988  ret.isTop = true;
8989
8990  ret._setup = function (options) {
8991    if (!options.partial) {
8992      container.helpers = container.merge(options.helpers, env.helpers);
8993
8994      if (templateSpec.usePartial) {
8995        container.partials = container.merge(options.partials, env.partials);
8996      }
8997      if (templateSpec.usePartial || templateSpec.useDecorators) {
8998        container.decorators = container.merge(options.decorators, env.decorators);
8999      }
9000    } else {
9001      container.helpers = options.helpers;
9002      container.partials = options.partials;
9003      container.decorators = options.decorators;
9004    }
9005  };
9006
9007  ret._child = function (i, data, blockParams, depths) {
9008    if (templateSpec.useBlockParams && !blockParams) {
9009      throw new _exception2['default']('must pass block params');
9010    }
9011    if (templateSpec.useDepths && !depths) {
9012      throw new _exception2['default']('must pass parent depths');
9013    }
9014
9015    return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
9016  };
9017  return ret;
9018}
9019
9020function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
9021  function prog(context) {
9022    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
9023
9024    var currentDepths = depths;
9025    if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {
9026      currentDepths = [context].concat(depths);
9027    }
9028
9029    return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
9030  }
9031
9032  prog = executeDecorators(fn, prog, container, depths, data, blockParams);
9033
9034  prog.program = i;
9035  prog.depth = depths ? depths.length : 0;
9036  prog.blockParams = declaredBlockParams || 0;
9037  return prog;
9038}
9039
9040function resolvePartial(partial, context, options) {
9041  if (!partial) {
9042    if (options.name === '@partial-block') {
9043      partial = options.data['partial-block'];
9044    } else {
9045      partial = options.partials[options.name];
9046    }
9047  } else if (!partial.call && !options.name) {
9048    // This is a dynamic partial that returned a string
9049    options.name = partial;
9050    partial = options.partials[partial];
9051  }
9052  return partial;
9053}
9054
9055function invokePartial(partial, context, options) {
9056  // Use the current closure context to save the partial-block if this partial
9057  var currentPartialBlock = options.data && options.data['partial-block'];
9058  options.partial = true;
9059  if (options.ids) {
9060    options.data.contextPath = options.ids[0] || options.data.contextPath;
9061  }
9062
9063  var partialBlock = undefined;
9064  if (options.fn && options.fn !== noop) {
9065    (function () {
9066      options.data = _base.createFrame(options.data);
9067      // Wrapper function to get access to currentPartialBlock from the closure
9068      var fn = options.fn;
9069      partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) {
9070        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
9071
9072        // Restore the partial-block from the closure for the execution of the block
9073        // i.e. the part inside the block of the partial call.
9074        options.data = _base.createFrame(options.data);
9075        options.data['partial-block'] = currentPartialBlock;
9076        return fn(context, options);
9077      };
9078      if (fn.partials) {
9079        options.partials = Utils.extend({}, options.partials, fn.partials);
9080      }
9081    })();
9082  }
9083
9084  if (partial === undefined && partialBlock) {
9085    partial = partialBlock;
9086  }
9087
9088  if (partial === undefined) {
9089    throw new _exception2['default']('The partial ' + options.name + ' could not be found');
9090  } else if (partial instanceof Function) {
9091    return partial(context, options);
9092  }
9093}
9094
9095function noop() {
9096  return '';
9097}
9098
9099function initData(context, data) {
9100  if (!data || !('root' in data)) {
9101    data = data ? _base.createFrame(data) : {};
9102    data.root = context;
9103  }
9104  return data;
9105}
9106
9107function executeDecorators(fn, prog, container, depths, data, blockParams) {
9108  if (fn.decorator) {
9109    var props = {};
9110    prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
9111    Utils.extend(prog, props);
9112  }
9113  return prog;
9114}
9115
9116
9117},{"./base":76,"./exception":79,"./utils":92}],91:[function(require,module,exports){
9118// Build out our basic SafeString type
9119'use strict';
9120
9121exports.__esModule = true;
9122function SafeString(string) {
9123  this.string = string;
9124}
9125
9126SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
9127  return '' + this.string;
9128};
9129
9130exports['default'] = SafeString;
9131module.exports = exports['default'];
9132
9133
9134},{}],92:[function(require,module,exports){
9135'use strict';
9136
9137exports.__esModule = true;
9138exports.extend = extend;
9139exports.indexOf = indexOf;
9140exports.escapeExpression = escapeExpression;
9141exports.isEmpty = isEmpty;
9142exports.createFrame = createFrame;
9143exports.blockParams = blockParams;
9144exports.appendContextPath = appendContextPath;
9145var escape = {
9146  '&': '&amp;',
9147  '<': '&lt;',
9148  '>': '&gt;',
9149  '"': '&quot;',
9150  "'": '&#x27;',
9151  '`': '&#x60;',
9152  '=': '&#x3D;'
9153};
9154
9155var badChars = /[&<>"'`=]/g,
9156    possible = /[&<>"'`=]/;
9157
9158function escapeChar(chr) {
9159  return escape[chr];
9160}
9161
9162function extend(obj /* , ...source */) {
9163  for (var i = 1; i < arguments.length; i++) {
9164    for (var key in arguments[i]) {
9165      if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
9166        obj[key] = arguments[i][key];
9167      }
9168    }
9169  }
9170
9171  return obj;
9172}
9173
9174var toString = Object.prototype.toString;
9175
9176exports.toString = toString;
9177// Sourced from lodash
9178// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
9179/* eslint-disable func-style */
9180var isFunction = function isFunction(value) {
9181  return typeof value === 'function';
9182};
9183// fallback for older versions of Chrome and Safari
9184/* istanbul ignore next */
9185if (isFunction(/x/)) {
9186  exports.isFunction = isFunction = function (value) {
9187    return typeof value === 'function' && toString.call(value) === '[object Function]';
9188  };
9189}
9190exports.isFunction = isFunction;
9191
9192/* eslint-enable func-style */
9193
9194/* istanbul ignore next */
9195var isArray = Array.isArray || function (value) {
9196  return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
9197};
9198
9199exports.isArray = isArray;
9200// Older IE versions do not directly support indexOf so we must implement our own, sadly.
9201
9202function indexOf(array, value) {
9203  for (var i = 0, len = array.length; i < len; i++) {
9204    if (array[i] === value) {
9205      return i;
9206    }
9207  }
9208  return -1;
9209}
9210
9211function escapeExpression(string) {
9212  if (typeof string !== 'string') {
9213    // don't escape SafeStrings, since they're already safe
9214    if (string && string.toHTML) {
9215      return string.toHTML();
9216    } else if (string == null) {
9217      return '';
9218    } else if (!string) {
9219      return string + '';
9220    }
9221
9222    // Force a string conversion as this will be done by the append regardless and
9223    // the regex test will do this transparently behind the scenes, causing issues if
9224    // an object's to string has escaped characters in it.
9225    string = '' + string;
9226  }
9227
9228  if (!possible.test(string)) {
9229    return string;
9230  }
9231  return string.replace(badChars, escapeChar);
9232}
9233
9234function isEmpty(value) {
9235  if (!value && value !== 0) {
9236    return true;
9237  } else if (isArray(value) && value.length === 0) {
9238    return true;
9239  } else {
9240    return false;
9241  }
9242}
9243
9244function createFrame(object) {
9245  var frame = extend({}, object);
9246  frame._parent = object;
9247  return frame;
9248}
9249
9250function blockParams(params, ids) {
9251  params.path = ids;
9252  return params;
9253}
9254
9255function appendContextPath(contextPath, id) {
9256  return (contextPath ? contextPath + '.' : '') + id;
9257}
9258
9259
9260},{}],93:[function(require,module,exports){
9261// Create a simple path alias to allow browserify to resolve
9262// the runtime on a supported path.
9263module.exports = require('./dist/cjs/handlebars.runtime')['default'];
9264
9265},{"./dist/cjs/handlebars.runtime":75}],94:[function(require,module,exports){
9266(function (global){(function (){
vendor: 14,672 bytes, lines 9266-9800
9266
9267/*! https://mths.be/punycode v1.4.1 by @mathias */
9268;(function(root) {
9269
9270	/** Detect free variables */
9271	var freeExports = typeof exports == 'object' && exports &&
9272		!exports.nodeType && exports;
9273	var freeModule = typeof module == 'object' && module &&
9274		!module.nodeType && module;
9275	var freeGlobal = typeof global == 'object' && global;
9276	if (
9277		freeGlobal.global === freeGlobal ||
9278		freeGlobal.window === freeGlobal ||
9279		freeGlobal.self === freeGlobal
9280	) {
9281		root = freeGlobal;
9282	}
9283
9284	/**
9285	 * The `punycode` object.
9286	 * @name punycode
9287	 * @type Object
9288	 */
9289	var punycode,
9290
9291	/** Highest positive signed 32-bit float value */
9292	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
9293
9294	/** Bootstring parameters */
9295	base = 36,
9296	tMin = 1,
9297	tMax = 26,
9298	skew = 38,
9299	damp = 700,
9300	initialBias = 72,
9301	initialN = 128, // 0x80
9302	delimiter = '-', // '\x2D'
9303
9304	/** Regular expressions */
9305	regexPunycode = /^xn--/,
9306	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
9307	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
9308
9309	/** Error messages */
9310	errors = {
9311		'overflow': 'Overflow: input needs wider integers to process',
9312		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
9313		'invalid-input': 'Invalid input'
9314	},
9315
9316	/** Convenience shortcuts */
9317	baseMinusTMin = base - tMin,
9318	floor = Math.floor,
9319	stringFromCharCode = String.fromCharCode,
9320
9321	/** Temporary variable */
9322	key;
9323
9324	/*--------------------------------------------------------------------------*/
9325
9326	/**
9327	 * A generic error utility function.
9328	 * @private
9329	 * @param {String} type The error type.
9330	 * @returns {Error} Throws a `RangeError` with the applicable error message.
9331	 */
9332	function error(type) {
9333		throw new RangeError(errors[type]);
9334	}
9335
9336	/**
9337	 * A generic `Array#map` utility function.
9338	 * @private
9339	 * @param {Array} array The array to iterate over.
9340	 * @param {Function} callback The function that gets called for every array
9341	 * item.
9342	 * @returns {Array} A new array of values returned by the callback function.
9343	 */
9344	function map(array, fn) {
9345		var length = array.length;
9346		var result = [];
9347		while (length--) {
9348			result[length] = fn(array[length]);
9349		}
9350		return result;
9351	}
9352
9353	/**
9354	 * A simple `Array#map`-like wrapper to work with domain name strings or email
9355	 * addresses.
9356	 * @private
9357	 * @param {String} domain The domain name or email address.
9358	 * @param {Function} callback The function that gets called for every
9359	 * character.
9360	 * @returns {Array} A new string of characters returned by the callback
9361	 * function.
9362	 */
9363	function mapDomain(string, fn) {
9364		var parts = string.split('@');
9365		var result = '';
9366		if (parts.length > 1) {
9367			// In email addresses, only the domain name should be punycoded. Leave
9368			// the local part (i.e. everything up to `@`) intact.
9369			result = parts[0] + '@';
9370			string = parts[1];
9371		}
9372		// Avoid `split(regex)` for IE8 compatibility. See #17.
9373		string = string.replace(regexSeparators, '\x2E');
9374		var labels = string.split('.');
9375		var encoded = map(labels, fn).join('.');
9376		return result + encoded;
9377	}
9378
9379	/**
9380	 * Creates an array containing the numeric code points of each Unicode
9381	 * character in the string. While JavaScript uses UCS-2 internally,
9382	 * this function will convert a pair of surrogate halves (each of which
9383	 * UCS-2 exposes as separate characters) into a single code point,
9384	 * matching UTF-16.
9385	 * @see `punycode.ucs2.encode`
9386	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
9387	 * @memberOf punycode.ucs2
9388	 * @name decode
9389	 * @param {String} string The Unicode input string (UCS-2).
9390	 * @returns {Array} The new array of code points.
9391	 */
9392	function ucs2decode(string) {
9393		var output = [],
9394		    counter = 0,
9395		    length = string.length,
9396		    value,
9397		    extra;
9398		while (counter < length) {
9399			value = string.charCodeAt(counter++);
9400			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
9401				// high surrogate, and there is a next character
9402				extra = string.charCodeAt(counter++);
9403				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
9404					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
9405				} else {
9406					// unmatched surrogate; only append this code unit, in case the next
9407					// code unit is the high surrogate of a surrogate pair
9408					output.push(value);
9409					counter--;
9410				}
9411			} else {
9412				output.push(value);
9413			}
9414		}
9415		return output;
9416	}
9417
9418	/**
9419	 * Creates a string based on an array of numeric code points.
9420	 * @see `punycode.ucs2.decode`
9421	 * @memberOf punycode.ucs2
9422	 * @name encode
9423	 * @param {Array} codePoints The array of numeric code points.
9424	 * @returns {String} The new Unicode string (UCS-2).
9425	 */
9426	function ucs2encode(array) {
9427		return map(array, function(value) {
9428			var output = '';
9429			if (value > 0xFFFF) {
9430				value -= 0x10000;
9431				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
9432				value = 0xDC00 | value & 0x3FF;
9433			}
9434			output += stringFromCharCode(value);
9435			return output;
9436		}).join('');
9437	}
9438
9439	/**
9440	 * Converts a basic code point into a digit/integer.
9441	 * @see `digitToBasic()`
9442	 * @private
9443	 * @param {Number} codePoint The basic numeric code point value.
9444	 * @returns {Number} The numeric value of a basic code point (for use in
9445	 * representing integers) in the range `0` to `base - 1`, or `base` if
9446	 * the code point does not represent a value.
9447	 */
9448	function basicToDigit(codePoint) {
9449		if (codePoint - 48 < 10) {
9450			return codePoint - 22;
9451		}
9452		if (codePoint - 65 < 26) {
9453			return codePoint - 65;
9454		}
9455		if (codePoint - 97 < 26) {
9456			return codePoint - 97;
9457		}
9458		return base;
9459	}
9460
9461	/**
9462	 * Converts a digit/integer into a basic code point.
9463	 * @see `basicToDigit()`
9464	 * @private
9465	 * @param {Number} digit The numeric value of a basic code point.
9466	 * @returns {Number} The basic code point whose value (when used for
9467	 * representing integers) is `digit`, which needs to be in the range
9468	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
9469	 * used; else, the lowercase form is used. The behavior is undefined
9470	 * if `flag` is non-zero and `digit` has no uppercase form.
9471	 */
9472	function digitToBasic(digit, flag) {
9473		//  0..25 map to ASCII a..z or A..Z
9474		// 26..35 map to ASCII 0..9
9475		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
9476	}
9477
9478	/**
9479	 * Bias adaptation function as per section 3.4 of RFC 3492.
9480	 * https://tools.ietf.org/html/rfc3492#section-3.4
9481	 * @private
9482	 */
9483	function adapt(delta, numPoints, firstTime) {
9484		var k = 0;
9485		delta = firstTime ? floor(delta / damp) : delta >> 1;
9486		delta += floor(delta / numPoints);
9487		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
9488			delta = floor(delta / baseMinusTMin);
9489		}
9490		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
9491	}
9492
9493	/**
9494	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
9495	 * symbols.
9496	 * @memberOf punycode
9497	 * @param {String} input The Punycode string of ASCII-only symbols.
9498	 * @returns {String} The resulting string of Unicode symbols.
9499	 */
9500	function decode(input) {
9501		// Don't use UCS-2
9502		var output = [],
9503		    inputLength = input.length,
9504		    out,
9505		    i = 0,
9506		    n = initialN,
9507		    bias = initialBias,
9508		    basic,
9509		    j,
9510		    index,
9511		    oldi,
9512		    w,
9513		    k,
9514		    digit,
9515		    t,
9516		    /** Cached calculation results */
9517		    baseMinusT;
9518
9519		// Handle the basic code points: let `basic` be the number of input code
9520		// points before the last delimiter, or `0` if there is none, then copy
9521		// the first basic code points to the output.
9522
9523		basic = input.lastIndexOf(delimiter);
9524		if (basic < 0) {
9525			basic = 0;
9526		}
9527
9528		for (j = 0; j < basic; ++j) {
9529			// if it's not a basic code point
9530			if (input.charCodeAt(j) >= 0x80) {
9531				error('not-basic');
9532			}
9533			output.push(input.charCodeAt(j));
9534		}
9535
9536		// Main decoding loop: start just after the last delimiter if any basic code
9537		// points were copied; start at the beginning otherwise.
9538
9539		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
9540
9541			// `index` is the index of the next character to be consumed.
9542			// Decode a generalized variable-length integer into `delta`,
9543			// which gets added to `i`. The overflow checking is easier
9544			// if we increase `i` as we go, then subtract off its starting
9545			// value at the end to obtain `delta`.
9546			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
9547
9548				if (index >= inputLength) {
9549					error('invalid-input');
9550				}
9551
9552				digit = basicToDigit(input.charCodeAt(index++));
9553
9554				if (digit >= base || digit > floor((maxInt - i) / w)) {
9555					error('overflow');
9556				}
9557
9558				i += digit * w;
9559				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
9560
9561				if (digit < t) {
9562					break;
9563				}
9564
9565				baseMinusT = base - t;
9566				if (w > floor(maxInt / baseMinusT)) {
9567					error('overflow');
9568				}
9569
9570				w *= baseMinusT;
9571
9572			}
9573
9574			out = output.length + 1;
9575			bias = adapt(i - oldi, out, oldi == 0);
9576
9577			// `i` was supposed to wrap around from `out` to `0`,
9578			// incrementing `n` each time, so we'll fix that now:
9579			if (floor(i / out) > maxInt - n) {
9580				error('overflow');
9581			}
9582
9583			n += floor(i / out);
9584			i %= out;
9585
9586			// Insert `n` at position `i` of the output
9587			output.splice(i++, 0, n);
9588
9589		}
9590
9591		return ucs2encode(output);
9592	}
9593
9594	/**
9595	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
9596	 * Punycode string of ASCII-only symbols.
9597	 * @memberOf punycode
9598	 * @param {String} input The string of Unicode symbols.
9599	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
9600	 */
9601	function encode(input) {
9602		var n,
9603		    delta,
9604		    handledCPCount,
9605		    basicLength,
9606		    bias,
9607		    j,
9608		    m,
9609		    q,
9610		    k,
9611		    t,
9612		    currentValue,
9613		    output = [],
9614		    /** `inputLength` will hold the number of code points in `input`. */
9615		    inputLength,
9616		    /** Cached calculation results */
9617		    handledCPCountPlusOne,
9618		    baseMinusT,
9619		    qMinusT;
9620
9621		// Convert the input in UCS-2 to Unicode
9622		input = ucs2decode(input);
9623
9624		// Cache the length
9625		inputLength = input.length;
9626
9627		// Initialize the state
9628		n = initialN;
9629		delta = 0;
9630		bias = initialBias;
9631
9632		// Handle the basic code points
9633		for (j = 0; j < inputLength; ++j) {
9634			currentValue = input[j];
9635			if (currentValue < 0x80) {
9636				output.push(stringFromCharCode(currentValue));
9637			}
9638		}
9639
9640		handledCPCount = basicLength = output.length;
9641
9642		// `handledCPCount` is the number of code points that have been handled;
9643		// `basicLength` is the number of basic code points.
9644
9645		// Finish the basic string - if it is not empty - with a delimiter
9646		if (basicLength) {
9647			output.push(delimiter);
9648		}
9649
9650		// Main encoding loop:
9651		while (handledCPCount < inputLength) {
9652
9653			// All non-basic code points < n have been handled already. Find the next
9654			// larger one:
9655			for (m = maxInt, j = 0; j < inputLength; ++j) {
9656				currentValue = input[j];
9657				if (currentValue >= n && currentValue < m) {
9658					m = currentValue;
9659				}
9660			}
9661
9662			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
9663			// but guard against overflow
9664			handledCPCountPlusOne = handledCPCount + 1;
9665			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
9666				error('overflow');
9667			}
9668
9669			delta += (m - n) * handledCPCountPlusOne;
9670			n = m;
9671
9672			for (j = 0; j < inputLength; ++j) {
9673				currentValue = input[j];
9674
9675				if (currentValue < n && ++delta > maxInt) {
9676					error('overflow');
9677				}
9678
9679				if (currentValue == n) {
9680					// Represent delta as a generalized variable-length integer
9681					for (q = delta, k = base; /* no condition */; k += base) {
9682						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
9683						if (q < t) {
9684							break;
9685						}
9686						qMinusT = q - t;
9687						baseMinusT = base - t;
9688						output.push(
9689							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
9690						);
9691						q = floor(qMinusT / baseMinusT);
9692					}
9693
9694					output.push(stringFromCharCode(digitToBasic(q, 0)));
9695					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
9696					delta = 0;
9697					++handledCPCount;
9698				}
9699			}
9700
9701			++delta;
9702			++n;
9703
9704		}
9705		return output.join('');
9706	}
9707
9708	/**
9709	 * Converts a Punycode string representing a domain name or an email address
9710	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
9711	 * it doesn't matter if you call it on a string that has already been
9712	 * converted to Unicode.
9713	 * @memberOf punycode
9714	 * @param {String} input The Punycoded domain name or email address to
9715	 * convert to Unicode.
9716	 * @returns {String} The Unicode representation of the given Punycode
9717	 * string.
9718	 */
9719	function toUnicode(input) {
9720		return mapDomain(input, function(string) {
9721			return regexPunycode.test(string)
9722				? decode(string.slice(4).toLowerCase())
9723				: string;
9724		});
9725	}
9726
9727	/**
9728	 * Converts a Unicode string representing a domain name or an email address to
9729	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
9730	 * i.e. it doesn't matter if you call it with a domain that's already in
9731	 * ASCII.
9732	 * @memberOf punycode
9733	 * @param {String} input The domain name or email address to convert, as a
9734	 * Unicode string.
9735	 * @returns {String} The Punycode representation of the given domain name or
9736	 * email address.
9737	 */
9738	function toASCII(input) {
9739		return mapDomain(input, function(string) {
9740			return regexNonASCII.test(string)
9741				? 'xn--' + encode(string)
9742				: string;
9743		});
9744	}
9745
9746	/*--------------------------------------------------------------------------*/
9747
9748	/** Define the public API */
9749	punycode = {
9750		/**
9751		 * A string representing the current Punycode.js version number.
9752		 * @memberOf punycode
9753		 * @type String
9754		 */
9755		'version': '1.4.1',
9756		/**
9757		 * An object of methods to convert from JavaScript's internal character
9758		 * representation (UCS-2) to Unicode code points, and back.
9759		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
9760		 * @memberOf punycode
9761		 * @type Object
9762		 */
9763		'ucs2': {
9764			'decode': ucs2decode,
9765			'encode': ucs2encode
9766		},
9767		'decode': decode,
9768		'encode': encode,
9769		'toASCII': toASCII,
9770		'toUnicode': toUnicode
9771	};
9772
9773	/** Expose `punycode` */
9774	// Some AMD build optimizers, like r.js, check for specific condition patterns
9775	// like the following:
9776	if (
9777		typeof define == 'function' &&
9778		typeof define.amd == 'object' &&
9779		define.amd
9780	) {
9781		define('punycode', function() {
9782			return punycode;
9783		});
9784	} else if (freeExports && freeModule) {
9785		if (module.exports == freeExports) {
9786			// in Node.js, io.js, or RingoJS v0.8.0+
9787			freeModule.exports = punycode;
9788		} else {
9789			// in Narwhal or RingoJS v0.7.0-
9790			for (key in punycode) {
9791				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
9792			}
9793		}
9794	} else {
9795		// in Rhino or a web browser
9796		root.punycode = punycode;
9797	}
9798
9799}(this));
9800
vendor: 29,271 bytes, lines 9801-10733
9801}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
9802},{}],95:[function(require,module,exports){
9803// Copyright Joyent, Inc. and other Node contributors.
9804//
9805// Permission is hereby granted, free of charge, to any person obtaining a
9806// copy of this software and associated documentation files (the
9807// "Software"), to deal in the Software without restriction, including
9808// without limitation the rights to use, copy, modify, merge, publish,
9809// distribute, sublicense, and/or sell copies of the Software, and to permit
9810// persons to whom the Software is furnished to do so, subject to the
9811// following conditions:
9812//
9813// The above copyright notice and this permission notice shall be included
9814// in all copies or substantial portions of the Software.
9815//
9816// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9817// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9818// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
9819// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
9820// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
9821// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
9822// USE OR OTHER DEALINGS IN THE SOFTWARE.
9823
9824'use strict';
9825
9826// If obj.hasOwnProperty has been overridden, then calling
9827// obj.hasOwnProperty(prop) will break.
9828// See: https://github.com/joyent/node/issues/1707
9829function hasOwnProperty(obj, prop) {
9830  return Object.prototype.hasOwnProperty.call(obj, prop);
9831}
9832
9833module.exports = function(qs, sep, eq, options) {
9834  sep = sep || '&';
9835  eq = eq || '=';
9836  var obj = {};
9837
9838  if (typeof qs !== 'string' || qs.length === 0) {
9839    return obj;
9840  }
9841
9842  var regexp = /\+/g;
9843  qs = qs.split(sep);
9844
9845  var maxKeys = 1000;
9846  if (options && typeof options.maxKeys === 'number') {
9847    maxKeys = options.maxKeys;
9848  }
9849
9850  var len = qs.length;
9851  // maxKeys <= 0 means that we should not limit keys count
9852  if (maxKeys > 0 && len > maxKeys) {
9853    len = maxKeys;
9854  }
9855
9856  for (var i = 0; i < len; ++i) {
9857    var x = qs[i].replace(regexp, '%20'),
9858        idx = x.indexOf(eq),
9859        kstr, vstr, k, v;
9860
9861    if (idx >= 0) {
9862      kstr = x.substr(0, idx);
9863      vstr = x.substr(idx + 1);
9864    } else {
9865      kstr = x;
9866      vstr = '';
9867    }
9868
9869    k = decodeURIComponent(kstr);
9870    v = decodeURIComponent(vstr);
9871
9872    if (!hasOwnProperty(obj, k)) {
9873      obj[k] = v;
9874    } else if (isArray(obj[k])) {
9875      obj[k].push(v);
9876    } else {
9877      obj[k] = [obj[k], v];
9878    }
9879  }
9880
9881  return obj;
9882};
9883
9884var isArray = Array.isArray || function (xs) {
9885  return Object.prototype.toString.call(xs) === '[object Array]';
9886};
9887
9888},{}],96:[function(require,module,exports){
9889// Copyright Joyent, Inc. and other Node contributors.
9890//
9891// Permission is hereby granted, free of charge, to any person obtaining a
9892// copy of this software and associated documentation files (the
9893// "Software"), to deal in the Software without restriction, including
9894// without limitation the rights to use, copy, modify, merge, publish,
9895// distribute, sublicense, and/or sell copies of the Software, and to permit
9896// persons to whom the Software is furnished to do so, subject to the
9897// following conditions:
9898//
9899// The above copyright notice and this permission notice shall be included
9900// in all copies or substantial portions of the Software.
9901//
9902// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9903// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9904// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
9905// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
9906// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
9907// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
9908// USE OR OTHER DEALINGS IN THE SOFTWARE.
9909
9910'use strict';
9911
9912var stringifyPrimitive = function(v) {
9913  switch (typeof v) {
9914    case 'string':
9915      return v;
9916
9917    case 'boolean':
9918      return v ? 'true' : 'false';
9919
9920    case 'number':
9921      return isFinite(v) ? v : '';
9922
9923    default:
9924      return '';
9925  }
9926};
9927
9928module.exports = function(obj, sep, eq, name) {
9929  sep = sep || '&';
9930  eq = eq || '=';
9931  if (obj === null) {
9932    obj = undefined;
9933  }
9934
9935  if (typeof obj === 'object') {
9936    return map(objectKeys(obj), function(k) {
9937      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
9938      if (isArray(obj[k])) {
9939        return map(obj[k], function(v) {
9940          return ks + encodeURIComponent(stringifyPrimitive(v));
9941        }).join(sep);
9942      } else {
9943        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
9944      }
9945    }).join(sep);
9946
9947  }
9948
9949  if (!name) return '';
9950  return encodeURIComponent(stringifyPrimitive(name)) + eq +
9951         encodeURIComponent(stringifyPrimitive(obj));
9952};
9953
9954var isArray = Array.isArray || function (xs) {
9955  return Object.prototype.toString.call(xs) === '[object Array]';
9956};
9957
9958function map (xs, f) {
9959  if (xs.map) return xs.map(f);
9960  var res = [];
9961  for (var i = 0; i < xs.length; i++) {
9962    res.push(f(xs[i], i));
9963  }
9964  return res;
9965}
9966
9967var objectKeys = Object.keys || function (obj) {
9968  var res = [];
9969  for (var key in obj) {
9970    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
9971  }
9972  return res;
9973};
9974
9975},{}],97:[function(require,module,exports){
9976'use strict';
9977
9978exports.decode = exports.parse = require('./decode');
9979exports.encode = exports.stringify = require('./encode');
9980
9981},{"./decode":95,"./encode":96}],98:[function(require,module,exports){
9982// Copyright Joyent, Inc. and other Node contributors.
9983//
9984// Permission is hereby granted, free of charge, to any person obtaining a
9985// copy of this software and associated documentation files (the
9986// "Software"), to deal in the Software without restriction, including
9987// without limitation the rights to use, copy, modify, merge, publish,
9988// distribute, sublicense, and/or sell copies of the Software, and to permit
9989// persons to whom the Software is furnished to do so, subject to the
9990// following conditions:
9991//
9992// The above copyright notice and this permission notice shall be included
9993// in all copies or substantial portions of the Software.
9994//
9995// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9996// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9997// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
9998// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
9999// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
10000// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
10001// USE OR OTHER DEALINGS IN THE SOFTWARE.
10002
10003'use strict';
10004
10005var punycode = require('punycode');
10006var util = require('./util');
10007
10008exports.parse = urlParse;
10009exports.resolve = urlResolve;
10010exports.resolveObject = urlResolveObject;
10011exports.format = urlFormat;
10012
10013exports.Url = Url;
10014
10015function Url() {
10016  this.protocol = null;
10017  this.slashes = null;
10018  this.auth = null;
10019  this.host = null;
10020  this.port = null;
10021  this.hostname = null;
10022  this.hash = null;
10023  this.search = null;
10024  this.query = null;
10025  this.pathname = null;
10026  this.path = null;
10027  this.href = null;
10028}
10029
10030// Reference: RFC 3986, RFC 1808, RFC 2396
10031
10032// define these here so at least they only have to be
10033// compiled once on the first module load.
10034var protocolPattern = /^([a-z0-9.+-]+:)/i,
10035    portPattern = /:[0-9]*$/,
10036
10037    // Special case for a simple path URL
10038    simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
10039
10040    // RFC 2396: characters reserved for delimiting URLs.
10041    // We actually just auto-escape these.
10042    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
10043
10044    // RFC 2396: characters not allowed for various reasons.
10045    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
10046
10047    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
10048    autoEscape = ['\''].concat(unwise),
10049    // Characters that are never ever allowed in a hostname.
10050    // Note that any invalid chars are also handled, but these
10051    // are the ones that are *expected* to be seen, so we fast-path
10052    // them.
10053    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
10054    hostEndingChars = ['/', '?', '#'],
10055    hostnameMaxLen = 255,
10056    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
10057    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
10058    // protocols that can allow "unsafe" and "unwise" chars.
10059    unsafeProtocol = {
10060      'javascript': true,
10061      'javascript:': true
10062    },
10063    // protocols that never have a hostname.
10064    hostlessProtocol = {
10065      'javascript': true,
10066      'javascript:': true
10067    },
10068    // protocols that always contain a // bit.
10069    slashedProtocol = {
10070      'http': true,
10071      'https': true,
10072      'ftp': true,
10073      'gopher': true,
10074      'file': true,
10075      'http:': true,
10076      'https:': true,
10077      'ftp:': true,
10078      'gopher:': true,
10079      'file:': true
10080    },
10081    querystring = require('querystring');
10082
10083function urlParse(url, parseQueryString, slashesDenoteHost) {
10084  if (url && util.isObject(url) && url instanceof Url) return url;
10085
10086  var u = new Url;
10087  u.parse(url, parseQueryString, slashesDenoteHost);
10088  return u;
10089}
10090
10091Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
10092  if (!util.isString(url)) {
10093    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
10094  }
10095
10096  // Copy chrome, IE, opera backslash-handling behavior.
10097  // Back slashes before the query string get converted to forward slashes
10098  // See: https://code.google.com/p/chromium/issues/detail?id=25916
10099  var queryIndex = url.indexOf('?'),
10100      splitter =
10101          (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
10102      uSplit = url.split(splitter),
10103      slashRegex = /\\/g;
10104  uSplit[0] = uSplit[0].replace(slashRegex, '/');
10105  url = uSplit.join(splitter);
10106
10107  var rest = url;
10108
10109  // trim before proceeding.
10110  // This is to support parse stuff like "  http://foo.com  \n"
10111  rest = rest.trim();
10112
10113  if (!slashesDenoteHost && url.split('#').length === 1) {
10114    // Try fast path regexp
10115    var simplePath = simplePathPattern.exec(rest);
10116    if (simplePath) {
10117      this.path = rest;
10118      this.href = rest;
10119      this.pathname = simplePath[1];
10120      if (simplePath[2]) {
10121        this.search = simplePath[2];
10122        if (parseQueryString) {
10123          this.query = querystring.parse(this.search.substr(1));
10124        } else {
10125          this.query = this.search.substr(1);
10126        }
10127      } else if (parseQueryString) {
10128        this.search = '';
10129        this.query = {};
10130      }
10131      return this;
10132    }
10133  }
10134
10135  var proto = protocolPattern.exec(rest);
10136  if (proto) {
10137    proto = proto[0];
10138    var lowerProto = proto.toLowerCase();
10139    this.protocol = lowerProto;
10140    rest = rest.substr(proto.length);
10141  }
10142
10143  // figure out if it's got a host
10144  // user@server is *always* interpreted as a hostname, and url
10145  // resolution will treat //foo/bar as host=foo,path=bar because that's
10146  // how the browser resolves relative URLs.
10147  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
10148    var slashes = rest.substr(0, 2) === '//';
10149    if (slashes && !(proto && hostlessProtocol[proto])) {
10150      rest = rest.substr(2);
10151      this.slashes = true;
10152    }
10153  }
10154
10155  if (!hostlessProtocol[proto] &&
10156      (slashes || (proto && !slashedProtocol[proto]))) {
10157
10158    // there's a hostname.
10159    // the first instance of /, ?, ;, or # ends the host.
10160    //
10161    // If there is an @ in the hostname, then non-host chars *are* allowed
10162    // to the left of the last @ sign, unless some host-ending character
10163    // comes *before* the @-sign.
10164    // URLs are obnoxious.
10165    //
10166    // ex:
10167    // http://a@b@c/ => user:a@b host:c
10168    // http://a@b?@c => user:a host:c path:/?@c
10169
10170    // v0.12 TODO(isaacs): This is not quite how Chrome does things.
10171    // Review our test case against browsers more comprehensively.
10172
10173    // find the first instance of any hostEndingChars
10174    var hostEnd = -1;
10175    for (var i = 0; i < hostEndingChars.length; i++) {
10176      var hec = rest.indexOf(hostEndingChars[i]);
10177      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
10178        hostEnd = hec;
10179    }
10180
10181    // at this point, either we have an explicit point where the
10182    // auth portion cannot go past, or the last @ char is the decider.
10183    var auth, atSign;
10184    if (hostEnd === -1) {
10185      // atSign can be anywhere.
10186      atSign = rest.lastIndexOf('@');
10187    } else {
10188      // atSign must be in auth portion.
10189      // http://a@b/c@d => host:b auth:a path:/c@d
10190      atSign = rest.lastIndexOf('@', hostEnd);
10191    }
10192
10193    // Now we have a portion which is definitely the auth.
10194    // Pull that off.
10195    if (atSign !== -1) {
10196      auth = rest.slice(0, atSign);
10197      rest = rest.slice(atSign + 1);
10198      this.auth = decodeURIComponent(auth);
10199    }
10200
10201    // the host is the remaining to the left of the first non-host char
10202    hostEnd = -1;
10203    for (var i = 0; i < nonHostChars.length; i++) {
10204      var hec = rest.indexOf(nonHostChars[i]);
10205      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
10206        hostEnd = hec;
10207    }
10208    // if we still have not hit it, then the entire thing is a host.
10209    if (hostEnd === -1)
10210      hostEnd = rest.length;
10211
10212    this.host = rest.slice(0, hostEnd);
10213    rest = rest.slice(hostEnd);
10214
10215    // pull out port.
10216    this.parseHost();
10217
10218    // we've indicated that there is a hostname,
10219    // so even if it's empty, it has to be present.
10220    this.hostname = this.hostname || '';
10221
10222    // if hostname begins with [ and ends with ]
10223    // assume that it's an IPv6 address.
10224    var ipv6Hostname = this.hostname[0] === '[' &&
10225        this.hostname[this.hostname.length - 1] === ']';
10226
10227    // validate a little.
10228    if (!ipv6Hostname) {
10229      var hostparts = this.hostname.split(/\./);
10230      for (var i = 0, l = hostparts.length; i < l; i++) {
10231        var part = hostparts[i];
10232        if (!part) continue;
10233        if (!part.match(hostnamePartPattern)) {
10234          var newpart = '';
10235          for (var j = 0, k = part.length; j < k; j++) {
10236            if (part.charCodeAt(j) > 127) {
10237              // we replace non-ASCII char with a temporary placeholder
10238              // we need this to make sure size of hostname is not
10239              // broken by replacing non-ASCII by nothing
10240              newpart += 'x';
10241            } else {
10242              newpart += part[j];
10243            }
10244          }
10245          // we test again with ASCII char only
10246          if (!newpart.match(hostnamePartPattern)) {
10247            var validParts = hostparts.slice(0, i);
10248            var notHost = hostparts.slice(i + 1);
10249            var bit = part.match(hostnamePartStart);
10250            if (bit) {
10251              validParts.push(bit[1]);
10252              notHost.unshift(bit[2]);
10253            }
10254            if (notHost.length) {
10255              rest = '/' + notHost.join('.') + rest;
10256            }
10257            this.hostname = validParts.join('.');
10258            break;
10259          }
10260        }
10261      }
10262    }
10263
10264    if (this.hostname.length > hostnameMaxLen) {
10265      this.hostname = '';
10266    } else {
10267      // hostnames are always lower case.
10268      this.hostname = this.hostname.toLowerCase();
10269    }
10270
10271    if (!ipv6Hostname) {
10272      // IDNA Support: Returns a punycoded representation of "domain".
10273      // It only converts parts of the domain name that
10274      // have non-ASCII characters, i.e. it doesn't matter if
10275      // you call it with a domain that already is ASCII-only.
10276      this.hostname = punycode.toASCII(this.hostname);
10277    }
10278
10279    var p = this.port ? ':' + this.port : '';
10280    var h = this.hostname || '';
10281    this.host = h + p;
10282    this.href += this.host;
10283
10284    // strip [ and ] from the hostname
10285    // the host field still retains them, though
10286    if (ipv6Hostname) {
10287      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
10288      if (rest[0] !== '/') {
10289        rest = '/' + rest;
10290      }
10291    }
10292  }
10293
10294  // now rest is set to the post-host stuff.
10295  // chop off any delim chars.
10296  if (!unsafeProtocol[lowerProto]) {
10297
10298    // First, make 100% sure that any "autoEscape" chars get
10299    // escaped, even if encodeURIComponent doesn't think they
10300    // need to be.
10301    for (var i = 0, l = autoEscape.length; i < l; i++) {
10302      var ae = autoEscape[i];
10303      if (rest.indexOf(ae) === -1)
10304        continue;
10305      var esc = encodeURIComponent(ae);
10306      if (esc === ae) {
10307        esc = escape(ae);
10308      }
10309      rest = rest.split(ae).join(esc);
10310    }
10311  }
10312
10313
10314  // chop off from the tail first.
10315  var hash = rest.indexOf('#');
10316  if (hash !== -1) {
10317    // got a fragment string.
10318    this.hash = rest.substr(hash);
10319    rest = rest.slice(0, hash);
10320  }
10321  var qm = rest.indexOf('?');
10322  if (qm !== -1) {
10323    this.search = rest.substr(qm);
10324    this.query = rest.substr(qm + 1);
10325    if (parseQueryString) {
10326      this.query = querystring.parse(this.query);
10327    }
10328    rest = rest.slice(0, qm);
10329  } else if (parseQueryString) {
10330    // no query string, but parseQueryString still requested
10331    this.search = '';
10332    this.query = {};
10333  }
10334  if (rest) this.pathname = rest;
10335  if (slashedProtocol[lowerProto] &&
10336      this.hostname && !this.pathname) {
10337    this.pathname = '/';
10338  }
10339
10340  //to support http.request
10341  if (this.pathname || this.search) {
10342    var p = this.pathname || '';
10343    var s = this.search || '';
10344    this.path = p + s;
10345  }
10346
10347  // finally, reconstruct the href based on what has been validated.
10348  this.href = this.format();
10349  return this;
10350};
10351
10352// format a parsed object into a url string
10353function urlFormat(obj) {
10354  // ensure it's an object, and not a string url.
10355  // If it's an obj, this is a no-op.
10356  // this way, you can call url_format() on strings
10357  // to clean up potentially wonky urls.
10358  if (util.isString(obj)) obj = urlParse(obj);
10359  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
10360  return obj.format();
10361}
10362
10363Url.prototype.format = function() {
10364  var auth = this.auth || '';
10365  if (auth) {
10366    auth = encodeURIComponent(auth);
10367    auth = auth.replace(/%3A/i, ':');
10368    auth += '@';
10369  }
10370
10371  var protocol = this.protocol || '',
10372      pathname = this.pathname || '',
10373      hash = this.hash || '',
10374      host = false,
10375      query = '';
10376
10377  if (this.host) {
10378    host = auth + this.host;
10379  } else if (this.hostname) {
10380    host = auth + (this.hostname.indexOf(':') === -1 ?
10381        this.hostname :
10382        '[' + this.hostname + ']');
10383    if (this.port) {
10384      host += ':' + this.port;
10385    }
10386  }
10387
10388  if (this.query &&
10389      util.isObject(this.query) &&
10390      Object.keys(this.query).length) {
10391    query = querystring.stringify(this.query);
10392  }
10393
10394  var search = this.search || (query && ('?' + query)) || '';
10395
10396  if (protocol && protocol.substr(-1) !== ':') protocol += ':';
10397
10398  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
10399  // unless they had them to begin with.
10400  if (this.slashes ||
10401      (!protocol || slashedProtocol[protocol]) && host !== false) {
10402    host = '//' + (host || '');
10403    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
10404  } else if (!host) {
10405    host = '';
10406  }
10407
10408  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
10409  if (search && search.charAt(0) !== '?') search = '?' + search;
10410
10411  pathname = pathname.replace(/[?#]/g, function(match) {
10412    return encodeURIComponent(match);
10413  });
10414  search = search.replace('#', '%23');
10415
10416  return protocol + host + pathname + search + hash;
10417};
10418
10419function urlResolve(source, relative) {
10420  return urlParse(source, false, true).resolve(relative);
10421}
10422
10423Url.prototype.resolve = function(relative) {
10424  return this.resolveObject(urlParse(relative, false, true)).format();
10425};
10426
10427function urlResolveObject(source, relative) {
10428  if (!source) return relative;
10429  return urlParse(source, false, true).resolveObject(relative);
10430}
10431
10432Url.prototype.resolveObject = function(relative) {
10433  if (util.isString(relative)) {
10434    var rel = new Url();
10435    rel.parse(relative, false, true);
10436    relative = rel;
10437  }
10438
10439  var result = new Url();
10440  var tkeys = Object.keys(this);
10441  for (var tk = 0; tk < tkeys.length; tk++) {
10442    var tkey = tkeys[tk];
10443    result[tkey] = this[tkey];
10444  }
10445
10446  // hash is always overridden, no matter what.
10447  // even href="" will remove it.
10448  result.hash = relative.hash;
10449
10450  // if the relative url is empty, then there's nothing left to do here.
10451  if (relative.href === '') {
10452    result.href = result.format();
10453    return result;
10454  }
10455
10456  // hrefs like //foo/bar always cut to the protocol.
10457  if (relative.slashes && !relative.protocol) {
10458    // take everything except the protocol from relative
10459    var rkeys = Object.keys(relative);
10460    for (var rk = 0; rk < rkeys.length; rk++) {
10461      var rkey = rkeys[rk];
10462      if (rkey !== 'protocol')
10463        result[rkey] = relative[rkey];
10464    }
10465
10466    //urlParse appends trailing / to urls like http://www.example.com
10467    if (slashedProtocol[result.protocol] &&
10468        result.hostname && !result.pathname) {
10469      result.path = result.pathname = '/';
10470    }
10471
10472    result.href = result.format();
10473    return result;
10474  }
10475
10476  if (relative.protocol && relative.protocol !== result.protocol) {
10477    // if it's a known url protocol, then changing
10478    // the protocol does weird things
10479    // first, if it's not file:, then we MUST have a host,
10480    // and if there was a path
10481    // to begin with, then we MUST have a path.
10482    // if it is file:, then the host is dropped,
10483    // because that's known to be hostless.
10484    // anything else is assumed to be absolute.
10485    if (!slashedProtocol[relative.protocol]) {
10486      var keys = Object.keys(relative);
10487      for (var v = 0; v < keys.length; v++) {
10488        var k = keys[v];
10489        result[k] = relative[k];
10490      }
10491      result.href = result.format();
10492      return result;
10493    }
10494
10495    result.protocol = relative.protocol;
10496    if (!relative.host && !hostlessProtocol[relative.protocol]) {
10497      var relPath = (relative.pathname || '').split('/');
10498      while (relPath.length && !(relative.host = relPath.shift()));
10499      if (!relative.host) relative.host = '';
10500      if (!relative.hostname) relative.hostname = '';
10501      if (relPath[0] !== '') relPath.unshift('');
10502      if (relPath.length < 2) relPath.unshift('');
10503      result.pathname = relPath.join('/');
10504    } else {
10505      result.pathname = relative.pathname;
10506    }
10507    result.search = relative.search;
10508    result.query = relative.query;
10509    result.host = relative.host || '';
10510    result.auth = relative.auth;
10511    result.hostname = relative.hostname || relative.host;
10512    result.port = relative.port;
10513    // to support http.request
10514    if (result.pathname || result.search) {
10515      var p = result.pathname || '';
10516      var s = result.search || '';
10517      result.path = p + s;
10518    }
10519    result.slashes = result.slashes || relative.slashes;
10520    result.href = result.format();
10521    return result;
10522  }
10523
10524  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
10525      isRelAbs = (
10526          relative.host ||
10527          relative.pathname && relative.pathname.charAt(0) === '/'
10528      ),
10529      mustEndAbs = (isRelAbs || isSourceAbs ||
10530                    (result.host && relative.pathname)),
10531      removeAllDots = mustEndAbs,
10532      srcPath = result.pathname && result.pathname.split('/') || [],
10533      relPath = relative.pathname && relative.pathname.split('/') || [],
10534      psychotic = result.protocol && !slashedProtocol[result.protocol];
10535
10536  // if the url is a non-slashed url, then relative
10537  // links like ../.. should be able
10538  // to crawl up to the hostname, as well.  This is strange.
10539  // result.protocol has already been set by now.
10540  // Later on, put the first path part into the host field.
10541  if (psychotic) {
10542    result.hostname = '';
10543    result.port = null;
10544    if (result.host) {
10545      if (srcPath[0] === '') srcPath[0] = result.host;
10546      else srcPath.unshift(result.host);
10547    }
10548    result.host = '';
10549    if (relative.protocol) {
10550      relative.hostname = null;
10551      relative.port = null;
10552      if (relative.host) {
10553        if (relPath[0] === '') relPath[0] = relative.host;
10554        else relPath.unshift(relative.host);
10555      }
10556      relative.host = null;
10557    }
10558    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
10559  }
10560
10561  if (isRelAbs) {
10562    // it's absolute.
10563    result.host = (relative.host || relative.host === '') ?
10564                  relative.host : result.host;
10565    result.hostname = (relative.hostname || relative.hostname === '') ?
10566                      relative.hostname : result.hostname;
10567    result.search = relative.search;
10568    result.query = relative.query;
10569    srcPath = relPath;
10570    // fall through to the dot-handling below.
10571  } else if (relPath.length) {
10572    // it's relative
10573    // throw away the existing file, and take the new path instead.
10574    if (!srcPath) srcPath = [];
10575    srcPath.pop();
10576    srcPath = srcPath.concat(relPath);
10577    result.search = relative.search;
10578    result.query = relative.query;
10579  } else if (!util.isNullOrUndefined(relative.search)) {
10580    // just pull out the search.
10581    // like href='?foo'.
10582    // Put this after the other two cases because it simplifies the booleans
10583    if (psychotic) {
10584      result.hostname = result.host = srcPath.shift();
10585      //occationaly the auth can get stuck only in host
10586      //this especially happens in cases like
10587      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
10588      var authInHost = result.host && result.host.indexOf('@') > 0 ?
10589                       result.host.split('@') : false;
10590      if (authInHost) {
10591        result.auth = authInHost.shift();
10592        result.host = result.hostname = authInHost.shift();
10593      }
10594    }
10595    result.search = relative.search;
10596    result.query = relative.query;
10597    //to support http.request
10598    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
10599      result.path = (result.pathname ? result.pathname : '') +
10600                    (result.search ? result.search : '');
10601    }
10602    result.href = result.format();
10603    return result;
10604  }
10605
10606  if (!srcPath.length) {
10607    // no path at all.  easy.
10608    // we've already handled the other stuff above.
10609    result.pathname = null;
10610    //to support http.request
10611    if (result.search) {
10612      result.path = '/' + result.search;
10613    } else {
10614      result.path = null;
10615    }
10616    result.href = result.format();
10617    return result;
10618  }
10619
10620  // if a url ENDs in . or .., then it must get a trailing slash.
10621  // however, if it ends in anything else non-slashy,
10622  // then it must NOT get a trailing slash.
10623  var last = srcPath.slice(-1)[0];
10624  var hasTrailingSlash = (
10625      (result.host || relative.host || srcPath.length > 1) &&
10626      (last === '.' || last === '..') || last === '');
10627
10628  // strip single dots, resolve double dots to parent dir
10629  // if the path tries to go above the root, `up` ends up > 0
10630  var up = 0;
10631  for (var i = srcPath.length; i >= 0; i--) {
10632    last = srcPath[i];
10633    if (last === '.') {
10634      srcPath.splice(i, 1);
10635    } else if (last === '..') {
10636      srcPath.splice(i, 1);
10637      up++;
10638    } else if (up) {
10639      srcPath.splice(i, 1);
10640      up--;
10641    }
10642  }
10643
10644  // if the path is allowed to go above the root, restore leading ..s
10645  if (!mustEndAbs && !removeAllDots) {
10646    for (; up--; up) {
10647      srcPath.unshift('..');
10648    }
10649  }
10650
10651  if (mustEndAbs && srcPath[0] !== '' &&
10652      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
10653    srcPath.unshift('');
10654  }
10655
10656  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
10657    srcPath.push('');
10658  }
10659
10660  var isAbsolute = srcPath[0] === '' ||
10661      (srcPath[0] && srcPath[0].charAt(0) === '/');
10662
10663  // put the host back
10664  if (psychotic) {
10665    result.hostname = result.host = isAbsolute ? '' :
10666                                    srcPath.length ? srcPath.shift() : '';
10667    //occationaly the auth can get stuck only in host
10668    //this especially happens in cases like
10669    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
10670    var authInHost = result.host && result.host.indexOf('@') > 0 ?
10671                     result.host.split('@') : false;
10672    if (authInHost) {
10673      result.auth = authInHost.shift();
10674      result.host = result.hostname = authInHost.shift();
10675    }
10676  }
10677
10678  mustEndAbs = mustEndAbs || (result.host && srcPath.length);
10679
10680  if (mustEndAbs && !isAbsolute) {
10681    srcPath.unshift('');
10682  }
10683
10684  if (!srcPath.length) {
10685    result.pathname = null;
10686    result.path = null;
10687  } else {
10688    result.pathname = srcPath.join('/');
10689  }
10690
10691  //to support request.http
10692  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
10693    result.path = (result.pathname ? result.pathname : '') +
10694                  (result.search ? result.search : '');
10695  }
10696  result.auth = relative.auth || result.auth;
10697  result.slashes = result.slashes || relative.slashes;
10698  result.href = result.format();
10699  return result;
10700};
10701
10702Url.prototype.parseHost = function() {
10703  var host = this.host;
10704  var port = portPattern.exec(host);
10705  if (port) {
10706    port = port[0];
10707    if (port !== ':') {
10708      this.port = port.substr(1);
10709    }
10710    host = host.substr(0, host.length - port.length);
10711  }
10712  if (host) this.hostname = host;
10713};
10714
10715},{"./util":99,"punycode":94,"querystring":97}],99:[function(require,module,exports){
10716'use strict';
10717
10718module.exports = {
10719  isString: function(arg) {
10720    return typeof(arg) === 'string';
10721  },
10722  isObject: function(arg) {
10723    return typeof(arg) === 'object' && arg !== null;
10724  },
10725  isNull: function(arg) {
10726    return arg === null;
10727  },
10728  isNullOrUndefined: function(arg) {
10729    return arg == null;
10730  }
10731};
10732
10733},{}]},{},[1]);

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.