PageSourceSearch

https://damier.info/templates/Skyline_v2/resources/js/browserify.build.js

js damier.info collected 2026-09-24 10:10:52 UTC 339,020 bytes, 10,727 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":57}],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":57,"lodash.bind":59,"lodash.foreach":60,"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":57,"lodash.bind":59}],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":57,"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.0.4 (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 */
4594var keys = require('lodash.keys');
4595
4596/**
4597 * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
4598 * of an array-like value.
4599 */
4600var MAX_SAFE_INTEGER = 9007199254740991;
4601
4602/**
4603 * The base implementation of `_.forEach` without support for callback
4604 * shorthands and `this` binding.
4605 *
4606 * @private
4607 * @param {Array|Object|string} collection The collection to iterate over.
4608 * @param {Function} iteratee The function invoked per iteration.
4609 * @returns {Array|Object|string} Returns `collection`.
4610 */
4611var baseEach = createBaseEach(baseForOwn);
4612
4613/**
4614 * The base implementation of `baseForIn` and `baseForOwn` which iterates
4615 * over `object` properties returned by `keysFunc` invoking `iteratee` for
4616 * each property. Iteratee functions may exit iteration early by explicitly
4617 * returning `false`.
4618 *
4619 * @private
4620 * @param {Object} object The object to iterate over.
4621 * @param {Function} iteratee The function invoked per iteration.
4622 * @param {Function} keysFunc The function to get the keys of `object`.
4623 * @returns {Object} Returns `object`.
4624 */
4625var baseFor = createBaseFor();
4626
4627/**
4628 * The base implementation of `_.forOwn` without support for callback
4629 * shorthands and `this` binding.
4630 *
4631 * @private
4632 * @param {Object} object The object to iterate over.
4633 * @param {Function} iteratee The function invoked per iteration.
4634 * @returns {Object} Returns `object`.
4635 */
4636function baseForOwn(object, iteratee) {
4637  return baseFor(object, iteratee, keys);
4638}
4639
4640/**
4641 * The base implementation of `_.property` without support for deep paths.
4642 *
4643 * @private
4644 * @param {string} key The key of the property to get.
4645 * @returns {Function} Returns the new function.
4646 */
4647function baseProperty(key) {
4648  return function(object) {
4649    return object == null ? undefined : object[key];
4650  };
4651}
4652
4653/**
4654 * Creates a `baseEach` or `baseEachRight` function.
4655 *
4656 * @private
4657 * @param {Function} eachFunc The function to iterate over a collection.
4658 * @param {boolean} [fromRight] Specify iterating from right to left.
4659 * @returns {Function} Returns the new base function.
4660 */
4661function createBaseEach(eachFunc, fromRight) {
4662  return function(collection, iteratee) {
4663    var length = collection ? getLength(collection) : 0;
4664    if (!isLength(length)) {
4665      return eachFunc(collection, iteratee);
4666    }
4667    var index = fromRight ? length : -1,
4668        iterable = toObject(collection);
4669
4670    while ((fromRight ? index-- : ++index < length)) {
4671      if (iteratee(iterable[index], index, iterable) === false) {
4672        break;
4673      }
4674    }
4675    return collection;
4676  };
4677}
4678
4679/**
4680 * Creates a base function for `_.forIn` or `_.forInRight`.
4681 *
4682 * @private
4683 * @param {boolean} [fromRight] Specify iterating from right to left.
4684 * @returns {Function} Returns the new base function.
4685 */
4686function createBaseFor(fromRight) {
4687  return function(object, iteratee, keysFunc) {
4688    var iterable = toObject(object),
4689        props = keysFunc(object),
4690        length = props.length,
4691        index = fromRight ? length : -1;
4692
4693    while ((fromRight ? index-- : ++index < length)) {
4694      var key = props[index];
4695      if (iteratee(iterable[key], key, iterable) === false) {
4696        break;
4697      }
4698    }
4699    return object;
4700  };
4701}
4702
4703/**
4704 * Gets the "length" property value of `object`.
4705 *
4706 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
4707 * that affects Safari on at least iOS 8.1-8.3 ARM64.
4708 *
4709 * @private
4710 * @param {Object} object The object to query.
4711 * @returns {*} Returns the "length" value.
4712 */
4713var getLength = baseProperty('length');
4714
4715/**
4716 * Checks if `value` is a valid array-like length.
4717 *
4718 * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
4719 *
4720 * @private
4721 * @param {*} value The value to check.
4722 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
4723 */
4724function isLength(value) {
4725  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
4726}
4727
4728/**
4729 * Converts `value` to an object if it's not one.
4730 *
4731 * @private
4732 * @param {*} value The value to process.
4733 * @returns {Object} Returns the object.
4734 */
4735function toObject(value) {
4736  return isObject(value) ? value : Object(value);
4737}
4738
4739/**
4740 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
4741 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
4742 *
4743 * @static
4744 * @memberOf _
4745 * @category Lang
4746 * @param {*} value The value to check.
4747 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
4748 * @example
4749 *
4750 * _.isObject({});
4751 * // => true
4752 *
4753 * _.isObject([1, 2, 3]);
4754 * // => true
4755 *
4756 * _.isObject(1);
4757 * // => false
4758 */
4759function isObject(value) {
4760  // Avoid a V8 JIT bug in Chrome 19-20.
4761  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
4762  var type = typeof value;
4763  return !!value && (type == 'object' || type == 'function');
4764}
4765
4766module.exports = baseEach;
4767
4768},{"lodash.keys":67}],47:[function(require,module,exports){
4769/**
4770 * lodash 3.7.2 (Custom Build) <https://lodash.com/>
4771 * Build: `lodash modern modularize exports="npm" -o ./`
4772 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4773 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4774 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4775 * Available under MIT license <https://lodash.com/license>
4776 */
4777
4778/**
4779 * The base implementation of `get` without support for string paths
4780 * and default values.
4781 *
4782 * @private
4783 * @param {Object} object The object to query.
4784 * @param {Array} path The path of the property to get.
4785 * @param {string} [pathKey] The key representation of path.
4786 * @returns {*} Returns the resolved value.
4787 */
4788function baseGet(object, path, pathKey) {
4789  if (object == null) {
4790    return;
4791  }
4792  if (pathKey !== undefined && pathKey in toObject(object)) {
4793    path = [pathKey];
4794  }
4795  var index = 0,
4796      length = path.length;
4797
4798  while (object != null && index < length) {
4799    object = object[path[index++]];
4800  }
4801  return (index && index == length) ? object : undefined;
4802}
4803
4804/**
4805 * Converts `value` to an object if it's not one.
4806 *
4807 * @private
4808 * @param {*} value The value to process.
4809 * @returns {Object} Returns the object.
4810 */
4811function toObject(value) {
4812  return isObject(value) ? value : Object(value);
4813}
4814
4815/**
4816 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
4817 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
4818 *
4819 * @static
4820 * @memberOf _
4821 * @category Lang
4822 * @param {*} value The value to check.
4823 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
4824 * @example
4825 *
4826 * _.isObject({});
4827 * // => true
4828 *
4829 * _.isObject([1, 2, 3]);
4830 * // => true
4831 *
4832 * _.isObject(1);
4833 * // => false
4834 */
4835function isObject(value) {
4836  // Avoid a V8 JIT bug in Chrome 19-20.
4837  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
4838  var type = typeof value;
4839  return !!value && (type == 'object' || type == 'function');
4840}
4841
4842module.exports = baseGet;
4843
4844},{}],48:[function(require,module,exports){
4845/**
4846 * lodash 3.0.3 (Custom Build) <https://lodash.com/>
4847 * Build: `lodash modern modularize exports="npm" -o ./`
4848 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4849 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4850 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4851 * Available under MIT license <https://lodash.com/license>
4852 */
4853
4854/**
4855 * The base implementation of `_.slice` without an iteratee call guard.
4856 *
4857 * @private
4858 * @param {Array} array The array to slice.
4859 * @param {number} [start=0] The start position.
4860 * @param {number} [end=array.length] The end position.
4861 * @returns {Array} Returns the slice of `array`.
4862 */
4863function baseSlice(array, start, end) {
4864  var index = -1,
4865      length = array.length;
4866
4867  start = start == null ? 0 : (+start || 0);
4868  if (start < 0) {
4869    start = -start > length ? 0 : (length + start);
4870  }
4871  end = (end === undefined || end > length) ? length : (+end || 0);
4872  if (end < 0) {
4873    end += length;
4874  }
4875  length = start > end ? 0 : ((end - start) >>> 0);
4876  start >>>= 0;
4877
4878  var result = Array(length);
4879  while (++index < length) {
4880    result[index] = array[index + start];
4881  }
4882  return result;
4883}
4884
4885module.exports = baseSlice;
4886
4887},{}],49:[function(require,module,exports){
4888/**
4889 * lodash 3.0.1 (Custom Build) <https://lodash.com/>
4890 * Build: `lodash modern modularize exports="npm" -o ./`
4891 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4892 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4893 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4894 * Available under MIT license <https://lodash.com/license>
4895 */
4896
4897/**
4898 * A specialized version of `baseCallback` which only supports `this` binding
4899 * and specifying the number of arguments to provide to `func`.
4900 *
4901 * @private
4902 * @param {Function} func The function to bind.
4903 * @param {*} thisArg The `this` binding of `func`.
4904 * @param {number} [argCount] The number of arguments to provide to `func`.
4905 * @returns {Function} Returns the callback.
4906 */
4907function bindCallback(func, thisArg, argCount) {
4908  if (typeof func != 'function') {
4909    return identity;
4910  }
4911  if (thisArg === undefined) {
4912    return func;
4913  }
4914  switch (argCount) {
4915    case 1: return function(value) {
4916      return func.call(thisArg, value);
4917    };
4918    case 3: return function(value, index, collection) {
4919      return func.call(thisArg, value, index, collection);
4920    };
4921    case 4: return function(accumulator, value, index, collection) {
4922      return func.call(thisArg, accumulator, value, index, collection);
4923    };
4924    case 5: return function(value, other, key, object, source) {
4925      return func.call(thisArg, value, other, key, object, source);
4926    };
4927  }
4928  return function() {
4929    return func.apply(thisArg, arguments);
4930  };
4931}
4932
4933/**
4934 * This method returns the first argument provided to it.
4935 *
4936 * @static
4937 * @memberOf _
4938 * @category Utility
4939 * @param {*} value Any value.
4940 * @returns {*} Returns `value`.
4941 * @example
4942 *
4943 * var object = { 'user': 'fred' };
4944 *
4945 * _.identity(object) === object;
4946 * // => true
4947 */
4948function identity(value) {
4949  return value;
4950}
4951
4952module.exports = bindCallback;
4953
4954},{}],50:[function(require,module,exports){
4955/**
4956 * lodash 3.1.1 (Custom Build) <https://lodash.com/>
4957 * Build: `lodash modern modularize exports="npm" -o ./`
4958 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
4959 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
4960 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
4961 * Available under MIT license <https://lodash.com/license>
4962 */
4963var bindCallback = require('lodash._bindcallback'),
4964    isIterateeCall = require('lodash._isiterateecall'),
4965    restParam = require('lodash.restparam');
4966
4967/**
4968 * Creates a function that assigns properties of source object(s) to a given
4969 * destination object.
4970 *
4971 * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`.
4972 *
4973 * @private
4974 * @param {Function} assigner The function to assign values.
4975 * @returns {Function} Returns the new assigner function.
4976 */
4977function createAssigner(assigner) {
4978  return restParam(function(object, sources) {
4979    var index = -1,
4980        length = object == null ? 0 : sources.length,
4981        customizer = length > 2 ? sources[length - 2] : undefined,
4982        guard = length > 2 ? sources[2] : undefined,
4983        thisArg = length > 1 ? sources[length - 1] : undefined;
4984
4985    if (typeof customizer == 'function') {
4986      customizer = bindCallback(customizer, thisArg, 5);
4987      length -= 2;
4988    } else {
4989      customizer = typeof thisArg == 'function' ? thisArg : undefined;
4990      length -= (customizer ? 1 : 0);
4991    }
4992    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
4993      customizer = length < 3 ? undefined : customizer;
4994      length = 1;
4995    }
4996    while (++index < length) {
4997      var source = sources[index];
4998      if (source) {
4999        assigner(object, source, customizer);
5000      }
5001    }
5002    return object;
5003  });
5004}
5005
5006module.exports = createAssigner;
5007
5008},{"lodash._bindcallback":49,"lodash._isiterateecall":53,"lodash.restparam":69}],51:[function(require,module,exports){
5009/**
5010 * lodash 3.2.0 (Custom Build) <https://lodash.com/>
5011 * Build: `lodash modularize exports="npm" -o ./`
5012 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
5013 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5014 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5015 * Available under MIT license <https://lodash.com/license>
5016 */
5017var root = require('lodash._root');
5018
5019/** Used to compose bitmasks for wrapper metadata. */
5020var BIND_FLAG = 1,
5021    BIND_KEY_FLAG = 2,
5022    CURRY_BOUND_FLAG = 4,
5023    CURRY_FLAG = 8,
5024    CURRY_RIGHT_FLAG = 16,
5025    PARTIAL_FLAG = 32,
5026    PARTIAL_RIGHT_FLAG = 64,
5027    ARY_FLAG = 128,
5028    FLIP_FLAG = 512;
5029
5030/** Used as the `TypeError` message for "Functions" methods. */
5031var FUNC_ERROR_TEXT = 'Expected a function';
5032
5033/** Used as references for various `Number` constants. */
5034var INFINITY = 1 / 0,
5035    MAX_SAFE_INTEGER = 9007199254740991,
5036    MAX_INTEGER = 1.7976931348623157e+308,
5037    NAN = 0 / 0;
5038
5039/** Used as the internal argument placeholder. */
5040var PLACEHOLDER = '__lodash_placeholder__';
5041
5042/** `Object#toString` result references. */
5043var funcTag = '[object Function]',
5044    genTag = '[object GeneratorFunction]';
5045
5046/** Used to match leading and trailing whitespace. */
5047var reTrim = /^\s+|\s+$/g;
5048
5049/** Used to detect bad signed hexadecimal string values. */
5050var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
5051
5052/** Used to detect binary string values. */
5053var reIsBinary = /^0b[01]+$/i;
5054
5055/** Used to detect octal string values. */
5056var reIsOctal = /^0o[0-7]+$/i;
5057
5058/** Used to detect unsigned integer values. */
5059var reIsUint = /^(?:0|[1-9]\d*)$/;
5060
5061/** Built-in method references without a dependency on `root`. */
5062var freeParseInt = parseInt;
5063
5064/**
5065 * A faster alternative to `Function#apply`, this function invokes `func`
5066 * with the `this` binding of `thisArg` and the arguments of `args`.
5067 *
5068 * @private
5069 * @param {Function} func The function to invoke.
5070 * @param {*} thisArg The `this` binding of `func`.
5071 * @param {...*} args The arguments to invoke `func` with.
5072 * @returns {*} Returns the result of `func`.
5073 */
5074function apply(func, thisArg, args) {
5075  var length = args.length;
5076  switch (length) {
5077    case 0: return func.call(thisArg);
5078    case 1: return func.call(thisArg, args[0]);
5079    case 2: return func.call(thisArg, args[0], args[1]);
5080    case 3: return func.call(thisArg, args[0], args[1], args[2]);
5081  }
5082  return func.apply(thisArg, args);
5083}
5084
5085/**
5086 * Checks if `value` is a valid array-like index.
5087 *
5088 * @private
5089 * @param {*} value The value to check.
5090 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
5091 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
5092 */
5093function isIndex(value, length) {
5094  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
5095  length = length == null ? MAX_SAFE_INTEGER : length;
5096  return value > -1 && value % 1 == 0 && value < length;
5097}
5098
5099/**
5100 * Replaces all `placeholder` elements in `array` with an internal placeholder
5101 * and returns an array of their indexes.
5102 *
5103 * @private
5104 * @param {Array} array The array to modify.
5105 * @param {*} placeholder The placeholder to replace.
5106 * @returns {Array} Returns the new array of placeholder indexes.
5107 */
5108function replaceHolders(array, placeholder) {
5109  var index = -1,
5110      length = array.length,
5111      resIndex = -1,
5112      result = [];
5113
5114  while (++index < length) {
5115    if (array[index] === placeholder) {
5116      array[index] = PLACEHOLDER;
5117      result[++resIndex] = index;
5118    }
5119  }
5120  return result;
5121}
5122
5123/** Used for built-in method references. */
5124var objectProto = Object.prototype;
5125
5126/**
5127 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
5128 * of values.
5129 */
5130var objectToString = objectProto.toString;
5131
5132/* Built-in method references for those with the same name as other `lodash` methods. */
5133var nativeMax = Math.max,
5134    nativeMin = Math.min;
5135
5136/**
5137 * The base implementation of `_.create` without support for assigning
5138 * properties to the created object.
5139 *
5140 * @private
5141 * @param {Object} prototype The object to inherit from.
5142 * @returns {Object} Returns the new object.
5143 */
5144var baseCreate = (function() {
5145  function object() {}
5146  return function(prototype) {
5147    if (isObject(prototype)) {
5148      object.prototype = prototype;
5149      var result = new object;
5150      object.prototype = undefined;
5151    }
5152    return result || {};
5153  };
5154}());
5155
5156/**
5157 * Creates an array that is the composition of partially applied arguments,
5158 * placeholders, and provided arguments into a single array of arguments.
5159 *
5160 * @private
5161 * @param {Array|Object} args The provided arguments.
5162 * @param {Array}
5162 partials The arguments to prepend to those provided.
5163 * @param {Array} holders The `partials` placeholder indexes.
5164 * @returns {Array} Returns the new array of composed arguments.
5165 */
5166function composeArgs(args, partials, holders) {
5167  var holdersLength = holders.length,
5168      argsIndex = -1,
5169      argsLength = nativeMax(args.length - holdersLength, 0),
5170      leftIndex = -1,
5171      leftLength = partials.length,
5172      result = Array(leftLength + argsLength);
5173
5174  while (++leftIndex < leftLength) {
5175    result[leftIndex] = partials[leftIndex];
5176  }
5177  while (++argsIndex < holdersLength) {
5178    result[holders[argsIndex]] = args[argsIndex];
5179  }
5180  while (argsLength--) {
5181    result[leftIndex++] = args[argsIndex++];
5182  }
5183  return result;
5184}
5185
5186/**
5187 * This function is like `composeArgs` except that the arguments composition
5188 * is tailored for `_.partialRight`.
5189 *
5190 * @private
5191 * @param {Array|Object} args The provided arguments.
5192 * @param {Array} partials The arguments to append to those provided.
5193 * @param {Array} holders The `partials` placeholder indexes.
5194 * @returns {Array} Returns the new array of composed arguments.
5195 */
5196function composeArgsRight(args, partials, holders) {
5197  var holdersIndex = -1,
5198      holdersLength = holders.length,
5199      argsIndex = -1,
5200      argsLength = nativeMax(args.length - holdersLength, 0),
5201      rightIndex = -1,
5202      rightLength = partials.length,
5203      result = Array(argsLength + rightLength);
5204
5205  while (++argsIndex < argsLength) {
5206    result[argsIndex] = args[argsIndex];
5207  }
5208  var offset = argsIndex;
5209  while (++rightIndex < rightLength) {
5210    result[offset + rightIndex] = partials[rightIndex];
5211  }
5212  while (++holdersIndex < holdersLength) {
5213    result[offset + holders[holdersIndex]] = args[argsIndex++];
5214  }
5215  return result;
5216}
5217
5218/**
5219 * Copies the values of `source` to `array`.
5220 *
5221 * @private
5222 * @param {Array} source The array to copy values from.
5223 * @param {Array} [array=[]] The array to copy values to.
5224 * @returns {Array} Returns `array`.
5225 */
5226function copyArray(source, array) {
5227  var index = -1,
5228      length = source.length;
5229
5230  array || (array = Array(length));
5231  while (++index < length) {
5232    array[index] = source[index];
5233  }
5234  return array;
5235}
5236
5237/**
5238 * Creates a function that wraps `func` to invoke it with the optional `this`
5239 * binding of `thisArg`.
5240 *
5241 * @private
5242 * @param {Function} func The function to wrap.
5243 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5244 * @param {*} [thisArg] The `this` binding of `func`.
5245 * @returns {Function} Returns the new wrapped function.
5246 */
5247function createBaseWrapper(func, bitmask, thisArg) {
5248  var isBind = bitmask & BIND_FLAG,
5249      Ctor = createCtorWrapper(func);
5250
5251  function wrapper() {
5252    var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5253    return fn.apply(isBind ? thisArg : this, arguments);
5254  }
5255  return wrapper;
5256}
5257
5258/**
5259 * Creates a function that produces an instance of `Ctor` regardless of
5260 * whether it was invoked as part of a `new` expression or by `call` or `apply`.
5261 *
5262 * @private
5263 * @param {Function} Ctor The constructor to wrap.
5264 * @returns {Function} Returns the new wrapped function.
5265 */
5266function createCtorWrapper(Ctor) {
5267  return function() {
5268    // Use a `switch` statement to work with class constructors.
5269    // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
5270    // for more details.
5271    var args = arguments;
5272    switch (args.length) {
5273      case 0: return new Ctor;
5274      case 1: return new Ctor(args[0]);
5275      case 2: return new Ctor(args[0], args[1]);
5276      case 3: return new Ctor(args[0], args[1], args[2]);
5277      case 4: return new Ctor(args[0], args[1], args[2], args[3]);
5278      case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
5279      case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
5280      case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
5281    }
5282    var thisBinding = baseCreate(Ctor.prototype),
5283        result = Ctor.apply(thisBinding, args);
5284
5285    // Mimic the constructor's `return` behavior.
5286    // See https://es5.github.io/#x13.2.2 for more details.
5287    return isObject(result) ? result : thisBinding;
5288  };
5289}
5290
5291/**
5292 * Creates a function that wraps `func` to enable currying.
5293 *
5294 * @private
5295 * @param {Function} func The function to wrap.
5296 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5297 * @param {number} arity The arity of `func`.
5298 * @returns {Function} Returns the new wrapped function.
5299 */
5300function createCurryWrapper(func, bitmask, arity) {
5301  var Ctor = createCtorWrapper(func);
5302
5303  function wrapper() {
5304    var length = arguments.length,
5305        index = length,
5306        args = Array(length),
5307        fn = (this && this !== root && this instanceof wrapper) ? Ctor : func,
5308        placeholder = wrapper.placeholder;
5309
5310    while (index--) {
5311      args[index] = arguments[index];
5312    }
5313    var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
5314      ? []
5315      : replaceHolders(args, placeholder);
5316
5317    length -= holders.length;
5318    return length < arity
5319      ? createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, undefined, args, holders, undefined, undefined, arity - length)
5320      : apply(fn, this, args);
5321  }
5322  return wrapper;
5323}
5324
5325/**
5326 * Creates a function that wraps `func` to invoke it with optional `this`
5327 * binding of `thisArg`, partial application, and currying.
5328 *
5329 * @private
5330 * @param {Function|string} func The function or method name to wrap.
5331 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5332 * @param {*} [thisArg] The `this` binding of `func`.
5333 * @param {Array} [partials] The arguments to prepend to those provided to the new function.
5334 * @param {Array} [holders] The `partials` placeholder indexes.
5335 * @param {Array} [partialsRight] The arguments to append to those provided to the new function.
5336 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
5337 * @param {Array} [argPos] The argument positions of the new function.
5338 * @param {number} [ary] The arity cap of `func`.
5339 * @param {number} [arity] The arity of `func`.
5340 * @returns {Function} Returns the new wrapped function.
5341 */
5342function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
5343  var isAry = bitmask & ARY_FLAG,
5344      isBind = bitmask & BIND_FLAG,
5345      isBindKey = bitmask & BIND_KEY_FLAG,
5346      isCurry = bitmask & CURRY_FLAG,
5347      isCurryRight = bitmask & CURRY_RIGHT_FLAG,
5348      isFlip = bitmask & FLIP_FLAG,
5349      Ctor = isBindKey ? undefined : createCtorWrapper(func);
5350
5351  function wrapper() {
5352    var length = arguments.length,
5353        index = length,
5354        args = Array(length);
5355
5356    while (index--) {
5357      args[index] = arguments[index];
5358    }
5359    if (partials) {
5360      args = composeArgs(args, partials, holders);
5361    }
5362    if (partialsRight) {
5363      args = composeArgsRight(args, partialsRight, holdersRight);
5364    }
5365    if (isCurry || isCurryRight) {
5366      var placeholder = wrapper.placeholder,
5367          argsHolders = replaceHolders(args, placeholder);
5368
5369      length -= argsHolders.length;
5370      if (length < arity) {
5371        return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length);
5372      }
5373    }
5374    var thisBinding = isBind ? thisArg : this,
5375        fn = isBindKey ? thisBinding[func] : func;
5376
5377    if (argPos) {
5378      args = reorder(args, argPos);
5379    } else if (isFlip && args.length > 1) {
5380      args.reverse();
5381    }
5382    if (isAry && ary < args.length) {
5383      args.length = ary;
5384    }
5385    if (this && this !== root && this instanceof wrapper) {
5386      fn = Ctor || createCtorWrapper(fn);
5387    }
5388    return fn.apply(thisBinding, args);
5389  }
5390  return wrapper;
5391}
5392
5393/**
5394 * Creates a function that wraps `func` to invoke it with the optional `this`
5395 * binding of `thisArg` and the `partials` prepended to those provided to
5396 * the wrapper.
5397 *
5398 * @private
5399 * @param {Function} func The function to wrap.
5400 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5401 * @param {*} thisArg The `this` binding of `func`.
5402 * @param {Array}
5402 partials The arguments to prepend to those provided to the new function.
5403 * @returns {Function} Returns the new wrapped function.
5404 */
5405function createPartialWrapper(func, bitmask, thisArg, partials) {
5406  var isBind = bitmask & BIND_FLAG,
5407      Ctor = createCtorWrapper(func);
5408
5409  function wrapper() {
5410    var argsIndex = -1,
5411        argsLength = arguments.length,
5412        leftIndex = -1,
5413        leftLength = partials.length,
5414        args = Array(leftLength + argsLength),
5415        fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
5416
5417    while (++leftIndex < leftLength) {
5418      args[leftIndex] = partials[leftIndex];
5419    }
5420    while (argsLength--) {
5421      args[leftIndex++] = arguments[++argsIndex];
5422    }
5423    return apply(fn, isBind ? thisArg : this, args);
5424  }
5425  return wrapper;
5426}
5427
5428/**
5429 * Creates a function that wraps `func` to continue currying.
5430 *
5431 * @private
5432 * @param {Function} func The function to wrap.
5433 * @param {number} bitmask The bitmask of wrapper flags. See `createWrapper` for more details.
5434 * @param {Function} wrapFunc The function to create the `func` wrapper.
5435 * @param {*} placeholder The placeholder to replace.
5436 * @param {*} [thisArg] The `this` binding of `func`.
5437 * @param {Array} [partials] The arguments to prepend to those provided to the new function.
5438 * @param {Array} [holders] The `partials` placeholder indexes.
5439 * @param {Array} [argPos] The argument positions of the new function.
5440 * @param {number} [ary] The arity cap of `func`.
5441 * @param {number} [arity] The arity of `func`.
5442 * @returns {Function} Returns the new wrapped function.
5443 */
5444function createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
5445  var isCurry = bitmask & CURRY_FLAG,
5446      newArgPos = argPos ? copyArray(argPos) : undefined,
5447      newsHolders = isCurry ? holders : undefined,
5448      newHoldersRight = isCurry ? undefined : holders,
5449      newPartials = isCurry ? partials : undefined,
5450      newPartialsRight = isCurry ? undefined : partials;
5451
5452  bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
5453  bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
5454
5455  if (!(bitmask & CURRY_BOUND_FLAG)) {
5456    bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
5457  }
5458  var result = wrapFunc(func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity);
5459
5460  result.placeholder = placeholder;
5461  return result;
5462}
5463
5464/**
5465 * Creates a function that either curries or invokes `func` with optional
5466 * `this` binding and partially applied arguments.
5467 *
5468 * @private
5469 * @param {Function|string} func The function or method name to wrap.
5470 * @param {number} bitmask The bitmask of wrapper flags.
5471 *  The bitmask may be composed of the following flags:
5472 *     1 - `_.bind`
5473 *     2 - `_.bindKey`
5474 *     4 - `_.curry` or `_.curryRight` of a bound function
5475 *     8 - `_.curry`
5476 *    16 - `_.curryRight`
5477 *    32 - `_.partial`
5478 *    64 - `_.partialRight`
5479 *   128 - `_.rearg`
5480 *   256 - `_.ary`
5481 * @param {*} [thisArg] The `this` binding of `func`.
5482 * @param {Array} [partials] The arguments to be partially applied.
5483 * @param {Array} [holders] The `partials` placeholder indexes.
5484 * @param {Array} [argPos] The argument positions of the new function.
5485 * @param {number} [ary] The arity cap of `func`.
5486 * @param {number} [arity] The arity of `func`.
5487 * @returns {Function} Returns the new wrapped function.
5488 */
5489function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
5490  var isBindKey = bitmask & BIND_KEY_FLAG;
5491  if (!isBindKey && typeof func != 'function') {
5492    throw new TypeError(FUNC_ERROR_TEXT);
5493  }
5494  var length = partials ? partials.length : 0;
5495  if (!length) {
5496    bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
5497    partials = holders = undefined;
5498  }
5499  ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
5500  arity = arity === undefined ? arity : toInteger(arity);
5501  length -= holders ? holders.length : 0;
5502
5503  if (bitmask & PARTIAL_RIGHT_FLAG) {
5504    var partialsRight = partials,
5505        holdersRight = holders;
5506
5507    partials = holders = undefined;
5508  }
5509  var newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
5510
5511  func = newData[0];
5512  bitmask = newData[1];
5513  thisArg = newData[2];
5514  partials = newData[3];
5515  holders = newData[4];
5516  arity = newData[9] = newData[9] == null
5517    ? (isBindKey ? 0 : func.length)
5518    : nativeMax(newData[9] - length, 0);
5519
5520  if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
5521    bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
5522  }
5523  if (!bitmask || bitmask == BIND_FLAG) {
5524    var result = createBaseWrapper(func, bitmask, thisArg);
5525  } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
5526    result = createCurryWrapper(func, bitmask, arity);
5527  } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
5528    result = createPartialWrapper(func, bitmask, thisArg, partials);
5529  } else {
5530    result = createHybridWrapper.apply(undefined, newData);
5531  }
5532  return result;
5533}
5534
5535/**
5536 * Reorder `array` according to the specified indexes where the element at
5537 * the first index is assigned as the first element, the element at
5538 * the second index is assigned as the second element, and so on.
5539 *
5540 * @private
5541 * @param {Array} array The array to reorder.
5542 * @param {Array} indexes The arranged array indexes.
5543 * @returns {Array} Returns `array`.
5544 */
5545function reorder(array, indexes) {
5546  var arrLength = array.length,
5547      length = nativeMin(indexes.length, arrLength),
5548      oldArray = copyArray(array);
5549
5550  while (length--) {
5551    var index = indexes[length];
5552    array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
5553  }
5554  return array;
5555}
5556
5557/**
5558 * Checks if `value` is classified as a `Function` object.
5559 *
5560 * @static
5561 * @memberOf _
5562 * @category Lang
5563 * @param {*} value The value to check.
5564 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
5565 * @example
5566 *
5567 * _.isFunction(_);
5568 * // => true
5569 *
5570 * _.isFunction(/abc/);
5571 * // => false
5572 */
5573function isFunction(value) {
5574  // The use of `Object#toString` avoids issues with the `typeof` operator
5575  // in Safari 8 which returns 'object' for typed array constructors, and
5576  // PhantomJS 1.9 which returns 'function' for `NodeList` instances.
5577  var tag = isObject(value) ? objectToString.call(value) : '';
5578  return tag == funcTag || tag == genTag;
5579}
5580
5581/**
5582 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
5583 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
5584 *
5585 * @static
5586 * @memberOf _
5587 * @category Lang
5588 * @param {*} value The value to check.
5589 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
5590 * @example
5591 *
5592 * _.isObject({});
5593 * // => true
5594 *
5595 * _.isObject([1, 2, 3]);
5596 * // => true
5597 *
5598 * _.isObject(_.noop);
5599 * // => true
5600 *
5601 * _.isObject(null);
5602 * // => false
5603 */
5604function isObject(value) {
5605  var type = typeof value;
5606  return !!value && (type == 'object' || type == 'function');
5607}
5608
5609/**
5610 * Converts `value` to an integer.
5611 *
5612 * **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
5613 *
5614 * @static
5615 * @memberOf _
5616 * @category Lang
5617 * @param {*} value The value to convert.
5618 * @returns {number} Returns the converted integer.
5619 * @example
5620 *
5621 * _.toInteger(3);
5622 * // => 3
5623 *
5624 * _.toInteger(Number.MIN_VALUE);
5625 * // => 0
5626 *
5627 * _.toInteger(Infinity);
5628 * // => 1.7976931348623157e+308
5629 *
5630 * _.toInteger('3');
5631 * // => 3
5632 */
5633function toInteger(value) {
5634  if (!value) {
5635    return value === 0 ? value : 0;
5636  }
5637  value = toNumber(value);
5638  if (value === INFINITY || value === -INFINITY) {
5639    var sign = (value < 0 ? -1 : 1);
5640    return sign * MAX_INTEGER;
5641  }
5642  var remainder = value % 1;
5643  return value === value ? (remainder ? value - remainder : value) : 0;
5644}
5645
5646/**
5647 * Converts `value` to a number.
5648 *
5649 * @static
5650 * @memberOf _
5651 * @category Lang
5652 * @param {*} value The value to process.
5653 * @returns {number} Returns the number.
5654 * @example
5655 *
5656 * _.toNumber(3);
5657 * // => 3
5658 *
5659 * _.toNumber(Number.MIN_VALUE);
5660 * // => 5e-324
5661 *
5662 * _.toNumber(Infinity);
5663 * // => Infinity
5664 *
5665 * _.toNumber('3');
5666 * // => 3
5667 */
5668function toNumber(value) {
5669  if (isObject(value)) {
5670    var other = isFunction(value.valueOf) ? value.valueOf() : value;
5671    value = isObject(other) ? (other + '') : other;
5672  }
5673  if (typeof value != 'string') {
5674    return value === 0 ? value : +value;
5675  }
5676  value = value.replace(reTrim, '');
5677  var isBinary = reIsBinary.test(value);
5678  return (isBinary || reIsOctal.test(value))
5679    ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
5680    : (reIsBadHex.test(value) ? NAN : +value);
5681}
5682
5683module.exports = createWrapper;
5684
5685},{"lodash._root":55}],52:[function(require,module,exports){
5686/**
5687 * lodash 3.9.1 (Custom Build) <https://lodash.com/>
5688 * Build: `lodash modern modularize exports="npm" -o ./`
5689 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5690 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5691 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5692 * Available under MIT license <https://lodash.com/license>
5693 */
5694
5695/** `Object#toString` result references. */
5696var funcTag = '[object Function]';
5697
5698/** Used to detect host constructors (Safari > 5). */
5699var reIsHostCtor = /^\[object .+?Constructor\]$/;
5700
5701/**
5702 * Checks if `value` is object-like.
5703 *
5704 * @private
5705 * @param {*} value The value to check.
5706 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
5707 */
5708function isObjectLike(value) {
5709  return !!value && typeof value == 'object';
5710}
5711
5712/** Used for native method references. */
5713var objectProto = Object.prototype;
5714
5715/** Used to resolve the decompiled source of functions. */
5716var fnToString = Function.prototype.toString;
5717
5718/** Used to check objects for own properties. */
5719var hasOwnProperty = objectProto.hasOwnProperty;
5720
5721/**
5722 * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
5723 * of values.
5724 */
5725var objToString = objectProto.toString;
5726
5727/** Used to detect if a method is native. */
5728var reIsNative = RegExp('^' +
5729  fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
5730  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
5731);
5732
5733/**
5734 * Gets the native function at `key` of `object`.
5735 *
5736 * @private
5737 * @param {Object} object The object to query.
5738 * @param {string} key The key of the method to get.
5739 * @returns {*} Returns the function if it's native, else `undefined`.
5740 */
5741function getNative(object, key) {
5742  var value = object == null ? undefined : object[key];
5743  return isNative(value) ? value : undefined;
5744}
5745
5746/**
5747 * Checks if `value` is classified as a `Function` object.
5748 *
5749 * @static
5750 * @memberOf _
5751 * @category Lang
5752 * @param {*} value The value to check.
5753 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
5754 * @example
5755 *
5756 * _.isFunction(_);
5757 * // => true
5758 *
5759 * _.isFunction(/abc/);
5760 * // => false
5761 */
5762function isFunction(value) {
vendor: 9,109 bytes, lines 5763-6062
5763  // The use of `Object#toString` avoids issues with the `typeof` operator
5764  // in older versions of Chrome and Safari which return 'function' for regexes
5765  // and Safari 8 equivalents which return 'object' for typed array constructors.
5766  return isObject(value) && objToString.call(value) == funcTag;
5767}
5768
5769/**
5770 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
5771 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
5772 *
5773 * @static
5774 * @memberOf _
5775 * @category Lang
5776 * @param {*} value The value to check.
5777 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
5778 * @example
5779 *
5780 * _.isObject({});
5781 * // => true
5782 *
5783 * _.isObject([1, 2, 3]);
5784 * // => true
5785 *
5786 * _.isObject(1);
5787 * // => false
5788 */
5789function isObject(value) {
5790  // Avoid a V8 JIT bug in Chrome 19-20.
5791  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
5792  var type = typeof value;
5793  return !!value && (type == 'object' || type == 'function');
5794}
5795
5796/**
5797 * Checks if `value` is a native function.
5798 *
5799 * @static
5800 * @memberOf _
5801 * @category Lang
5802 * @param {*} value The value to check.
5803 * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
5804 * @example
5805 *
5806 * _.isNative(Array.prototype.push);
5807 * // => true
5808 *
5809 * _.isNative(_);
5810 * // => false
5811 */
5812function isNative(value) {
5813  if (value == null) {
5814    return false;
5815  }
5816  if (isFunction(value)) {
5817    return reIsNative.test(fnToString.call(value));
5818  }
5819  return isObjectLike(value) && reIsHostCtor.test(value);
5820}
5821
5822module.exports = getNative;
5823
5824},{}],53:[function(require,module,exports){
5825/**
5826 * lodash 3.0.9 (Custom Build) <https://lodash.com/>
5827 * Build: `lodash modern modularize exports="npm" -o ./`
5828 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5829 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
5830 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5831 * Available under MIT license <https://lodash.com/license>
5832 */
5833
5834/** Used to detect unsigned integer values. */
5835var reIsUint = /^\d+$/;
5836
5837/**
5838 * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
5839 * of an array-like value.
5840 */
5841var MAX_SAFE_INTEGER = 9007199254740991;
5842
5843/**
5844 * The base implementation of `_.property` without support for deep paths.
5845 *
5846 * @private
5847 * @param {string} key The key of the property to get.
5848 * @returns {Function} Returns the new function.
5849 */
5850function baseProperty(key) {
5851  return function(object) {
5852    return object == null ? undefined : object[key];
5853  };
5854}
5855
5856/**
5857 * Gets the "length" property value of `object`.
5858 *
5859 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
5860 * that affects Safari on at least iOS 8.1-8.3 ARM64.
5861 *
5862 * @private
5863 * @param {Object} object The object to query.
5864 * @returns {*} Returns the "length" value.
5865 */
5866var getLength = baseProperty('length');
5867
5868/**
5869 * Checks if `value` is array-like.
5870 *
5871 * @private
5872 * @param {*} value The value to check.
5873 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
5874 */
5875function isArrayLike(value) {
5876  return value != null && isLength(getLength(value));
5877}
5878
5879/**
5880 * Checks if `value` is a valid array-like index.
5881 *
5882 * @private
5883 * @param {*} value The value to check.
5884 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
5885 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
5886 */
5887function isIndex(value, length) {
5888  value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
5889  length = length == null ? MAX_SAFE_INTEGER : length;
5890  return value > -1 && value % 1 == 0 && value < length;
5891}
5892
5893/**
5894 * Checks if the provided arguments are from an iteratee call.
5895 *
5896 * @private
5897 * @param {*} value The potential iteratee value argument.
5898 * @param {*} index The potential iteratee index or key argument.
5899 * @param {*} object The potential iteratee object argument.
5900 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
5901 */
5902function isIterateeCall(value, index, object) {
5903  if (!isObject(object)) {
5904    return false;
5905  }
5906  var type = typeof index;
5907  if (type == 'number'
5908      ? (isArrayLike(object) && isIndex(index, object.length))
5909      : (type == 'string' && index in object)) {
5910    var other = object[index];
5911    return value === value ? (value === other) : (other !== other);
5912  }
5913  return false;
5914}
5915
5916/**
5917 * Checks if `value` is a valid array-like length.
5918 *
5919 * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength).
5920 *
5921 * @private
5922 * @param {*} value The value to check.
5923 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
5924 */
5925function isLength(value) {
5926  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
5927}
5928
5929/**
5930 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
5931 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
5932 *
5933 * @static
5934 * @memberOf _
5935 * @category Lang
5936 * @param {*} value The value to check.
5937 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
5938 * @example
5939 *
5940 * _.isObject({});
5941 * // => true
5942 *
5943 * _.isObject([1, 2, 3]);
5944 * // => true
5945 *
5946 * _.isObject(1);
5947 * // => false
5948 */
5949function isObject(value) {
5950  // Avoid a V8 JIT bug in Chrome 19-20.
5951  // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
5952  var type = typeof value;
5953  return !!value && (type == 'object' || type == 'function');
5954}
5955
5956module.exports = isIterateeCall;
5957
5958},{}],54:[function(require,module,exports){
5959/**
5960 * lodash 3.0.0 (Custom Build) <https://lodash.com/>
5961 * Build: `lodash modern modularize exports="npm" -o ./`
5962 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
5963 * Based on Underscore.js 1.7.0 <http://underscorejs.org/LICENSE>
5964 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
5965 * Available under MIT license <https://lodash.com/license>
5966 */
5967
5968/** Used as the internal argument placeholder. */
5969var PLACEHOLDER = '__lodash_placeholder__';
5970
5971/**
5972 * Replaces all `placeholder` elements in `array` with an internal placeholder
5973 * and returns an array of their indexes.
5974 *
5975 * @private
5976 * @param {Array} array The array to modify.
5977 * @param {*} placeholder The placeholder to replace.
5978 * @returns {Array} Returns the new array of placeholder indexes.
5979 */
5980function replaceHolders(array, placeholder) {
5981  var index = -1,
5982      length = array.length,
5983      resIndex = -1,
5984      result = [];
5985
5986  while (++index < length) {
5987    if (array[index] === placeholder) {
5988      array[index] = PLACEHOLDER;
5989      result[++resIndex] = index;
5990    }
5991  }
5992  return result;
5993}
5994
5995module.exports = replaceHolders;
5996
5997},{}],55:[function(require,module,exports){
5998(function (global){
5999/**
6000 * lodash 3.0.1 (Custom Build) <https://lodash.com/>
6001 * Build: `lodash modularize exports="npm" -o ./`
6002 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
6003 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6004 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6005 * Available under MIT license <https://lodash.com/license>
6006 */
6007
6008/** Used to determine if values are of the language type `Object`. */
6009var objectTypes = {
6010  'function': true,
6011  'object': true
6012};
6013
6014/** Detect free variable `exports`. */
6015var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
6016  ? exports
6017  : undefined;
6018
6019/** Detect free variable `module`. */
6020var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
6021  ? module
6022  : undefined;
6023
6024/** Detect free variable `global` from Node.js. */
6025var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
6026
6027/** Detect free variable `self`. */
6028var freeSelf = checkGlobal(objectTypes[typeof self] && self);
6029
6030/** Detect free variable `window`. */
6031var freeWindow = checkGlobal(objectTypes[typeof window] && window);
6032
6033/** Detect `this` as the global object. */
6034var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
6035
6036/**
6037 * Used as a reference to the global object.
6038 *
6039 * The `this` value is used if it's the global object to avoid Greasemonkey's
6040 * restricted `window` object, otherwise the `window` object is used.
6041 */
6042var root = freeGlobal ||
6043  ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
6044    freeSelf || thisGlobal || Function('return this')();
6045
6046/**
6047 * Checks if `value` is a global object.
6048 *
6049 * @private
6050 * @param {*} value The value to check.
6051 * @returns {null|Object} Returns `value` if it's a global object, else `null`.
6052 */
6053function checkGlobal(value) {
6054  return (value && value.Object === Object) ? value : null;
6055}
6056
6057module.exports = root;
6058
6059}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
6060},{}],56:[function(require,module,exports){
6061/**
6062 * lodash 3.8.1 (Custom Build) <https://lodash.com/>
6063 * Build: `lodash modern modularize exports="npm" -o ./`
6064 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6065 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6066 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6067 * Available under MIT license <https://lodash.com/license>
6068 */
6069var isArray = require('lodash.isarray');
6070
6071/** Used to match property names within property paths. */
6072var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
6073
6074/** Used to match backslashes in property paths. */
6075var reEscapeChar = /\\(\\)?/g;
6076
6077/**
6078 * Converts `value` to a string if it's not one. An empty string is returned
6079 * for `null` or `undefined` values.
6080 *
6081 * @private
6082 * @param {*} value The value to process.
6083 * @returns {string} Returns the string.
6084 */
6085function baseToString(value) {
6086  return value == null ? '' : (value + '');
6087}
6088
6089/**
6090 * Converts `value` to property path array if it's not one.
6091 *
6092 * @private
6093 * @param {*} value The value to process.
6094 * @returns {Array} Returns the property path array.
6095 */
6096function toPath(value) {
6097  if (isArray(value)) {
6098    return value;
6099  }
6100  var result = [];
6101  baseToString(value).replace(rePropName, function(match, number, quote, string) {
6102    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
6103  });
6104  return result;
6105}
6106
6107module.exports = toPath;
6108
6109},{"lodash.isarray":62}],57:[function(require,module,exports){
6110/**
6111 * lodash 3.2.0 (Custom Build) <https://lodash.com/>
6112 * Build: `lodash modern modularize exports="npm" -o ./`
6113 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6114 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6115 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6116 * Available under MIT license <https://lodash.com/license>
6117 */
6118var baseAssign = require('lodash._baseassign'),
6119    createAssigner = require('lodash._createassigner'),
6120    keys = require('lodash.keys');
6121
6122/**
6123 * A specialized version of `_.assign` for customizing assigned values without
6124 * support for argument juggling, multiple sources, and `this` binding `customizer`
6125 * functions.
6126 *
6127 * @private
6128 * @param {Object} object The destination object.
6129 * @param {Object} source The source object.
6130 * @param {Function} customizer The function to customize assigned values.
6131 * @returns {Object} Returns `object`.
6132 */
6133function assignWith(object, source, customizer) {
6134  var index = -1,
6135      props = keys(source),
6136      length = props.length;
6137
6138  while (++index < length) {
6139    var key = props[index],
6140        value = object[key],
6141        result = customizer(value, source[key], key, object, source);
6142
6143    if ((result === result ? (result !== value) : (value === value)) ||
6144        (value === undefined && !(key in object))) {
6145      object[key] = result;
6146    }
6147  }
6148  return object;
6149}
6150
6151/**
6152 * Assigns own enumerable properties of source object(s) to the destination
6153 * object. Subsequent sources overwrite property assignments of previous sources.
6154 * If `customizer` is provided it is invoked to produce the assigned values.
6155 * The `customizer` is bound to `thisArg` and invoked with five arguments:
6156 * (objectValue, sourceValue, key, object, source).
6157 *
6158 * **Note:** This method mutates `object` and is based on
6159 * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign).
6160 *
6161 * @static
6162 * @memberOf _
6163 * @alias extend
6164 * @category Object
6165 * @param {Object} object The destination object.
6166 * @param {...Object} [sources] The source objects.
6167 * @param {Function} [customizer] The function to customize assigned values.
6168 * @param {*} [thisArg] The `this` binding of `customizer`.
6169 * @returns {Object} Returns `object`.
6170 * @example
6171 *
6172 * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
6173 * // => { 'user': 'fred', 'age': 40 }
6174 *
6175 * // using a customizer callback
6176 * var defaults = _.partialRight(_.assign, function(value, other) {
6177 *   return _.isUndefined(value) ? other : value;
6178 * });
6179 *
6180 * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
6181 * // => { 'user': 'barney', 'age': 36 }
6182 */
6183var assign = createAssigner(function(object, source, customizer) {
6184  return customizer
6185    ? assignWith(object, source, customizer)
6186    : baseAssign(object, source);
6187});
6188
6189module.exports = assign;
6190
6191},{"lodash._baseassign":44,"lodash._createassigner":50,"lodash.keys":67}],58:[function(require,module,exports){
6192/**
6193 * lodash 3.0.3 (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 */
6200
6201/** Used as the `TypeError` message for "Functions" methods. */
6202var FUNC_ERROR_TEXT = 'Expected a function';
6203
6204/**
6205 * Creates a function that invokes `func`, with the `this` binding and arguments
6206 * of the created function, while it is called less than `n` times. Subsequent
6207 * calls to the created function return the result of the last `func` invocation.
6208 *
6209 * @static
6210 * @memberOf _
6211 * @category Function
6212 * @param {number} n The number of calls at which `func` is no longer invoked.
6213 * @param {Function} func The function to restrict.
6214 * @returns {Function} Returns the new restricted function.
6215 * @example
6216 *
6217 * jQuery('#add').on('click', _.before(5, addContactToList));
6218 * // => allows adding up to 4 contacts to the list
6219 */
6220function before(n, func) {
6221  var result;
6222  if (typeof func != 'function') {
6223    if (typeof n == 'function') {
6224      var temp = n;
6225      n = func;
6226      func = temp;
6227    } else {
6228      throw new TypeError(FUNC_ERROR_TEXT);
6229    }
6230  }
6231  return function() {
6232    if (--n > 0) {
6233      result = func.apply(this, arguments);
6234    }
6235    if (n <= 1) {
6236      func = undefined;
6237    }
6238    return result;
6239  };
6240}
6241
6242module.exports = before;
6243
6244},{}],59:[function(require,module,exports){
6245/**
6246 * lodash 3.1.0 (Custom Build) <https://lodash.com/>
6247 * Build: `lodash modern modularize exports="npm" -o ./`
6248 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6249 * Based on Underscore.js 1.8.2 <http://underscorejs.org/LICENSE>
6250 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6251 * Available under MIT license <https://lodash.com/license>
6252 */
6253var createWrapper = require('lodash._createwrapper'),
6254    replaceHolders = require('lodash._replaceholders'),
6255    restParam = require('lodash.restparam');
6256
6257/** Used to compose bitmasks for wrapper metadata. */
6258var BIND_FLAG = 1,
6259    PARTIAL_FLAG = 32;
6260
6261/**
6262 * Creates a function that invokes `func` with the `this` binding of `thisArg`
6263 * and prepends any additional `_.bind` arguments to those provided to the
6264 * bound function.
6265 *
6266 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
6267 * may be used as a placeholder for partially applied arguments.
6268 *
6269 * **Note:** Unlike native `Function#bind` this method does not set the `length`
6270 * property of bound functions.
6271 *
6272 * @static
6273 * @memberOf _
6274 * @category Function
6275 * @param {Function} func The function to bind.
6276 * @param {*} thisArg The `this` binding of `func`.
6277 * @param {...*} [partials] The arguments to be partially applied.
6278 * @returns {Function} Returns the new bound function.
6279 * @example
6280 *
6281 * var greet = function(greeting, punctuation) {
6282 *   return greeting + ' ' + this.user + punctuation;
6283 * };
6284 *
6285 * var object = { 'user': 'fred' };
6286 *
6287 * var bound = _.bind(greet, object, 'hi');
6288 * bound('!');
6289 * // => 'hi fred!'
6290 *
6291 * // using placeholders
6292 * var bound = _.bind(greet, object, _, '!');
6293 * bound('hi');
6294 * // => 'hi fred!'
6295 */
6296var bind = restParam(function(func, thisArg, partials) {
6297  var bitmask = BIND_FLAG;
6298  if (partials.length) {
6299    var holders = replaceHolders(partials, bind.placeholder);
6300    bitmask |= PARTIAL_FLAG;
6301  }
6302  return createWrapper(func, bitmask, thisArg, partials, holders);
6303});
6304
6305// Assign default placeholders.
6306bind.placeholder = {};
6307
6308module.exports = bind;
6309
6310},{"lodash._createwrapper":51,"lodash._replaceholders":54,"lodash.restparam":69}],60:[function(require,module,exports){
6311/**
6312 * lodash 3.0.3 (Custom Build) <https://lodash.com/>
6313 * Build: `lodash modern modularize exports="npm" -o ./`
6314 * Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
6315 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6316 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
6317 * Available under MIT license <https://lodash.com/license>
6318 */
6319var arrayEach = require('lodash._arrayeach'),
6320    baseEach = require('lodash._baseeach'),
6321    bindCallback = require('lodash._bindcallback'),
6322    isArray = require('lodash.isarray');
6323
6324/**
6325 * Creates a function for `_.forEach` or `_.forEachRight`.
6326 *
6327 * @private
6328 * @param {Function} arrayFunc The function to iterate over an array.
6329 * @param {Function} eachFunc The function to iterate over a collection.
6330 * @returns {Function} Returns the new each function.
6331 */
6332function createForEach(arrayFunc, eachFunc) {
6333  return function(collection, iteratee, thisArg) {
6334    return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
6335      ? arrayFunc(collection, iteratee)
6336      : eachFunc(collection, bindCallback(iteratee, thisArg, 3));
6337  };
6338}
6339
6340/**
6341 * Iterates over elements of `collection` invoking `iteratee` for each element.
6342 * The `iteratee` is bound to `thisArg` and invoked with three arguments:
6343 * (value, index|key, collection). Iteratee functions may exit iteration early
6344 * by explicitly returning `false`.
6345 *
6346 * **Note:** As with other "Collections" methods, objects with a "length" property
6347 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
6348 * may be used for object iteration.
6349 *
6350 * @static
6351 * @memberOf _
6352 * @alias each
6353 * @category Collection
6354 * @param {Array|Object|string} collection The collection to iterate over.
6355 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
6356 * @param {*} [thisArg] The `this` binding of `iteratee`.
6357 * @returns {Array|Object|string} Returns `collection`.
6358 * @example
6359 *
6360 * _([1, 2]).forEach(function(n) {
6361 *   console.log(n);
6362 * }).value();
6363 * // => logs each value from left to right and returns the array
6364 *
6365 * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
6366 *   console.log(n, key);
6367 * });
6368 * // => logs each value-key pair and returns the object (iteration order is not guaranteed)
6369 */
6370var forEach = createForEach(arrayEach, baseEach);
6371
6372module.exports = forEach;
6373
6374},{"lodash._arrayeach":43,"lodash._baseeach":46,"lodash._bindcallback":49,"lodash.isarray":62}],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) {
vendor: 11,060 bytes, lines 6508-6910
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){
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,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":52,"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":58}],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":47,"lodash._baseslice":48,"lodash._topath":56,"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":55}],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.12';
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: '>
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
8418-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    return obj && obj[field];
8688  });
8689};
8690
8691module.exports = exports['default'];
8692
8693
8694},{}],87:[function(require,module,exports){
8695'use strict';
8696
8697exports.__esModule = true;
8698
8699var _utils = require('../utils');
8700
8701exports['default'] = function (instance) {
8702  instance.registerHelper('with', function (context, options) {
8703    if (_utils.isFunction(context)) {
8704      context = context.call(this);
8705    }
8706
8707    var fn = options.fn;
8708
8709    if (!_utils.isEmpty(context)) {
8710      var data = options.data;
8711      if (options.data && options.ids) {
8712        data = _utils.createFrame(options.data);
8713        data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);
8714      }
8715
8716      return fn(context, {
8717        data: data,
8718        blockParams: _utils.blockParams([context], [data && data.contextPath])
8719      });
8720    } else {
8721      return options.inverse(this);
8722    }
8723  });
8724};
8725
8726module.exports = exports['default'];
8727
8728
8729},{"../utils":92}],88:[function(require,module,exports){
8730'use strict';
8731
8732exports.__esModule = true;
8733
8734var _utils = require('./utils');
8735
8736var logger = {
8737  methodMap: ['debug', 'info', 'warn', 'error'],
8738  level: 'info',
8739
8740  // Maps a given level value to the `methodMap` indexes above.
8741  lookupLevel: function lookupLevel(level) {
8742    if (typeof level === 'string') {
8743      var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());
8744      if (levelMap >= 0) {
8745        level = levelMap;
8746      } else {
8747        level = parseInt(level, 10);
8748      }
8749    }
8750
8751    return level;
8752  },
8753
8754  // Can be overridden in the host environment
8755  log: function log(level) {
8756    level = logger.lookupLevel(level);
8757
8758    if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
8759      var method = logger.methodMap[level];
8760      if (!console[method]) {
8761        // eslint-disable-line no-console
8762        method = 'log';
8763      }
8764
8765      for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
8766        message[_key - 1] = arguments[_key];
8767      }
8768
8769      console[method].apply(console, message); // eslint-disable-line no-console
8770    }
8771  }
8772};
8773
8774exports['default'] = logger;
8775module.exports = exports['default'];
8776
8777
8778},{"./utils":92}],89:[function(require,module,exports){
8779(function (global){
8780/* global window */
8781'use strict';
8782
8783exports.__esModule = true;
8784
8785exports['default'] = function (Handlebars) {
8786  /* istanbul ignore next */
8787  var root = typeof global !== 'undefined' ? global : window,
8788      $Handlebars = root.Handlebars;
8789  /* istanbul ignore next */
8790  Handlebars.noConflict = function () {
8791    if (root.Handlebars === Handlebars) {
8792      root.Handlebars = $Handlebars;
8793    }
8794    return Handlebars;
8795  };
8796};
8797
8798module.exports = exports['default'];
8799
8800
8801}
8801).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
8802},{}],90:[function(require,module,exports){
8803'use strict';
8804
8805exports.__esModule = true;
8806exports.checkRevision = checkRevision;
8807exports.template = template;
8808exports.wrapProgram = wrapProgram;
8809exports.resolvePartial = resolvePartial;
8810exports.invokePartial = invokePartial;
8811exports.noop = noop;
8812// istanbul ignore next
8813
8814function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
8815
8816// istanbul ignore next
8817
8818function _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; } }
8819
8820var _utils = require('./utils');
8821
8822var Utils = _interopRequireWildcard(_utils);
8823
8824var _exception = require('./exception');
8825
8826var _exception2 = _interopRequireDefault(_exception);
8827
8828var _base = require('./base');
8829
8830function checkRevision(compilerInfo) {
8831  var compilerRevision = compilerInfo && compilerInfo[0] || 1,
8832      currentRevision = _base.COMPILER_REVISION;
8833
8834  if (compilerRevision !== currentRevision) {
8835    if (compilerRevision < currentRevision) {
8836      var runtimeVersions = _base.REVISION_CHANGES[currentRevision],
8837          compilerVersions = _base.REVISION_CHANGES[compilerRevision];
8838      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 + ').');
8839    } else {
8840      // Use the embedded version info since the runtime doesn't know about this revision yet
8841      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] + ').');
8842    }
8843  }
8844}
8845
8846function template(templateSpec, env) {
8847  /* istanbul ignore next */
8848  if (!env) {
8849    throw new _exception2['default']('No environment passed to template');
8850  }
8851  if (!templateSpec || !templateSpec.main) {
8852    throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
8853  }
8854
8855  templateSpec.main.decorator = templateSpec.main_d;
8856
8857  // Note: Using env.VM references rather than local var references throughout this section to allow
8858  // for external users to override these as psuedo-supported APIs.
8859  env.VM.checkRevision(templateSpec.compiler);
8860
8861  function invokePartialWrapper(partial, context, options) {
8862    if (options.hash) {
8863      context = Utils.extend({}, context, options.hash);
8864      if (options.ids) {
8865        options.ids[0] = true;
8866      }
8867    }
8868
8869    partial = env.VM.resolvePartial.call(this, partial, context, options);
8870    var result = env.VM.invokePartial.call(this, partial, context, options);
8871
8872    if (result == null && env.compile) {
8873      options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
8874      result = options.partials[options.name](context, options);
8875    }
8876    if (result != null) {
8877      if (options.indent) {
8878        var lines = result.split('\n');
8879        for (var i = 0, l = lines.length; i < l; i++) {
8880          if (!lines[i] && i + 1 === l) {
8881            break;
8882          }
8883
8884          lines[i] = options.indent + lines[i];
8885        }
8886        result = lines.join('\n');
8887      }
8888      return result;
8889    } else {
8890      throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
8891    }
8892  }
8893
8894  // Just add water
8895  var container = {
8896    strict: function strict(obj, name) {
8897      if (!(name in obj)) {
8898        throw new _exception2['default']('"' + name + '" not defined in ' + obj);
8899      }
8900      return obj[name];
8901    },
8902    lookup: function lookup(depths, name) {
8903      var len = depths.length;
8904      for (var i = 0; i < len; i++) {
8905        if (depths[i] && depths[i][name] != null) {
8906          return depths[i][name];
8907        }
8908      }
8909    },
8910    lambda: function lambda(current, context) {
8911      return typeof current === 'function' ? current.call(context) : current;
8912    },
8913
8914    escapeExpression: Utils.escapeExpression,
8915    invokePartial: invokePartialWrapper,
8916
8917    fn: function fn(i) {
8918      var ret = templateSpec[i];
8919      ret.decorator = templateSpec[i + '_d'];
8920      return ret;
8921    },
8922
8923    programs: [],
8924    program: function program(i, data, declaredBlockParams, blockParams, depths) {
8925      var programWrapper = this.programs[i],
8926          fn = this.fn(i);
8927      if (data || depths || blockParams || declaredBlockParams) {
8928        programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
8929      } else if (!programWrapper) {
8930        programWrapper = this.programs[i] = wrapProgram(this, i, fn);
8931      }
8932      return programWrapper;
8933    },
8934
8935    data: function data(value, depth) {
8936      while (value && depth--) {
8937        value = value._parent;
8938      }
8939      return value;
8940    },
8941    merge: function merge(param, common) {
8942      var obj = param || common;
8943
8944      if (param && common && param !== common) {
8945        obj = Utils.extend({}, common, param);
8946      }
8947
8948      return obj;
8949    },
8950    // An empty object to use as replacement for null-contexts
8951    nullContext: Object.seal({}),
8952
8953    noop: env.VM.noop,
8954    compilerInfo: templateSpec.compiler
8955  };
8956
8957  function ret(context) {
8958    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
8959
8960    var data = options.data;
8961
8962    ret._setup(options);
8963    if (!options.partial && templateSpec.useData) {
8964      data = initData(context, data);
8965    }
8966    var depths = undefined,
8967        blockParams = templateSpec.useBlockParams ? [] : undefined;
8968    if (templateSpec.useDepths) {
8969      if (options.depths) {
8970        depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;
8971      } else {
8972        depths = [context];
8973      }
8974    }
8975
8976    function main(context /*, options*/) {
8977      return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
8978    }
8979    main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
8980    return main(context, options);
8981  }
8982  ret.isTop = true;
8983
8984  ret._setup = function (options) {
8985    if (!options.partial) {
8986      container.helpers = container.merge(options.helpers, env.helpers);
8987
8988      if (templateSpec.usePartial) {
8989        container.partials = container.merge(options.partials, env.partials);
8990      }
8991      if (templateSpec.usePartial || templateSpec.useDecorators) {
8992        container.decorators = container.merge(options.decorators, env.decorators);
8993      }
8994    } else {
8995      container.helpers = options.helpers;
8996      container.partials = options.partials;
8997      container.decorators = options.decorators;
8998    }
8999  };
9000
9001  ret._child = function (i, data, blockParams, depths) {
9002    if (templateSpec.useBlockParams && !blockParams) {
9003      throw new _exception2['default']('must pass block params');
9004    }
9005    if (templateSpec.useDepths && !depths) {
9006      throw new _exception2['default']('must pass parent depths');
9007    }
9008
9009    return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
9010  };
9011  return ret;
9012}
9013
9014function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
9015  function prog(context) {
9016    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
9017
9018    var currentDepths = depths;
9019    if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {
9020      currentDepths = [context].concat(depths);
9021    }
9022
9023    return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
9024  }
9025
9026  prog = executeDecorators(fn, prog, container, depths, data, blockParams);
9027
9028  prog.program = i;
9029  prog.depth = depths ? depths.length : 0;
9030  prog.blockParams = declaredBlockParams || 0;
9031  return prog;
9032}
9033
9034function resolvePartial(partial, context, options) {
9035  if (!partial) {
9036    if (options.name === '@partial-block') {
9037      partial = options.data['partial-block'];
9038    } else {
9039      partial = options.partials[options.name];
9040    }
9041  } else if (!partial.call && !options.name) {
9042    // This is a dynamic partial that returned a string
9043    options.name = partial;
9044    partial = options.partials[partial];
9045  }
9046  return partial;
9047}
9048
9049function invokePartial(partial, context, options) {
9050  // Use the current closure context to save the partial-block if this partial
9051  var currentPartialBlock = options.data && options.data['partial-block'];
9052  options.partial = true;
9053  if (options.ids) {
9054    options.data.contextPath = options.ids[0] || options.data.contextPath;
9055  }
9056
9057  var partialBlock = undefined;
9058  if (options.fn && options.fn !== noop) {
9059    (function () {
9060      options.data = _base.createFrame(options.data);
9061      // Wrapper function to get access to currentPartialBlock from the closure
9062      var fn = options.fn;
9063      partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) {
9064        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
9065
9066        // Restore the partial-block from the closure for the execution of the block
9067        // i.e. the part inside the block of the partial call.
9068        options.data = _base.createFrame(options.data);
9069        options.data['partial-block'] = currentPartialBlock;
9070        return fn(context, options);
9071      };
9072      if (fn.partials) {
9073        options.partials = Utils.extend({}, options.partials, fn.partials);
9074      }
9075    })();
9076  }
9077
9078  if (partial === undefined && partialBlock) {
9079    partial = partialBlock;
9080  }
9081
9082  if (partial === undefined) {
9083    throw new _exception2['default']('The partial ' + options.name + ' could not be found');
9084  } else if (partial instanceof Function) {
9085    return partial(context, options);
9086  }
9087}
9088
9089function noop() {
9090  return '';
9091}
9092
9093function initData(context, data) {
9094  if (!data || !('root' in data)) {
9095    data = data ? _base.createFrame(data) : {};
9096    data.root = context;
9097  }
9098  return data;
9099}
9100
9101function executeDecorators(fn, prog, container, depths, data, blockParams) {
9102  if (fn.decorator) {
9103    var props = {};
9104    prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
9105    Utils.extend(prog, props);
9106  }
9107  return prog;
9108}
9109
9110
9111}
9111,{"./base":76,"./exception":79,"./utils":92}],91:[function(require,module,exports){
9112// Build out our basic SafeString type
9113'use strict';
9114
9115exports.__esModule = true;
9116function SafeString(string) {
9117  this.string = string;
9118}
9119
9120SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
9121  return '' + this.string;
9122};
9123
9124exports['default'] = SafeString;
9125module.exports = exports['default'];
9126
9127
9128},{}],92:[function(require,module,exports){
9129'use strict';
9130
9131exports.__esModule = true;
9132exports.extend = extend;
9133exports.indexOf = indexOf;
9134exports.escapeExpression = escapeExpression;
9135exports.isEmpty = isEmpty;
9136exports.createFrame = createFrame;
9137exports.blockParams = blockParams;
9138exports.appendContextPath = appendContextPath;
9139var escape = {
9140  '&': '&amp;',
9141  '<': '&lt;',
9142  '>': '&gt;',
9143  '"': '&quot;',
9144  "'": '&#x27;',
9145  '`': '&#x60;',
9146  '=': '&#x3D;'
9147};
9148
9149var badChars = /[&<>"'`=]/g,
9150    possible = /[&<>"'`=]/;
9151
9152function escapeChar(chr) {
9153  return escape[chr];
9154}
9155
9156function extend(obj /* , ...source */) {
9157  for (var i = 1; i < arguments.length; i++) {
9158    for (var key in arguments[i]) {
9159      if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
9160        obj[key] = arguments[i][key];
9161      }
9162    }
9163  }
9164
9165  return obj;
9166}
9167
9168var toString = Object.prototype.toString;
9169
9170exports.toString = toString;
9171// Sourced from lodash
9172// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
9173/* eslint-disable func-style */
9174var isFunction = function isFunction(value) {
9175  return typeof value === 'function';
9176};
9177// fallback for older versions of Chrome and Safari
9178/* istanbul ignore next */
9179if (isFunction(/x/)) {
9180  exports.isFunction = isFunction = function (value) {
9181    return typeof value === 'function' && toString.call(value) === '[object Function]';
9182  };
9183}
9184exports.isFunction = isFunction;
9185
9186/* eslint-enable func-style */
9187
9188/* istanbul ignore next */
9189var isArray = Array.isArray || function (value) {
9190  return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
9191};
9192
9193exports.isArray = isArray;
9194// Older IE versions do not directly support indexOf so we must implement our own, sadly.
9195
9196function indexOf(array, value) {
9197  for (var i = 0, len = array.length; i < len; i++) {
9198    if (array[i] === value) {
9199      return i;
9200    }
9201  }
9202  return -1;
9203}
9204
9205function escapeExpression(string) {
9206  if (typeof string !== 'string') {
9207    // don't escape SafeStrings, since they're already safe
9208    if (string && string.toHTML) {
9209      return string.toHTML();
9210    } else if (string == null) {
9211      return '';
9212    } else if (!string) {
9213      return string + '';
9214    }
9215
9216    // Force a string conversion as this will be done by the append regardless and
9217    // the regex test will do this transparently behind the scenes, causing issues if
9218    // an object's to string has escaped characters in it.
9219    string = '' + string;
9220  }
9221
9222  if (!possible.test(string)) {
9223    return string;
9224  }
9225  return string.replace(badChars, escapeChar);
9226}
9227
9228function isEmpty(value) {
9229  if (!value && value !== 0) {
9230    return true;
9231  } else if (isArray(value) && value.length === 0) {
9232    return true;
9233  } else {
9234    return false;
9235  }
9236}
9237
9238function createFrame(object) {
9239  var frame = extend({}, object);
9240  frame._parent = object;
9241  return frame;
9242}
9243
9244function blockParams(params, ids) {
9245  params.path = ids;
9246  return params;
9247}
9248
9249function appendContextPath(contextPath, id) {
9250  return (contextPath ? contextPath + '.' : '') + id;
9251}
9252
9253
9254},{}],93:[function(require,module,exports){
9255// Create a simple path alias to allow browserify to resolve
9256// the runtime on a supported path.
9257module.exports = require('./dist/cjs/handlebars.runtime')['default'];
9258
9259},{"./dist/cjs/handlebars.runtime":75}],94:[function(require,module,exports){
9260(function (global){
9261/*! https://mths.be/punycode v1.4.1 by @mathias */
9262;(function(root) {
9263
9264	/** Detect free variables */
9265	var freeExports = typeof exports == 'object' && exports &&
9266		!exports.nodeType && exports;
9267	var freeModule = typeof module == 'object' && module &&
9268		!module.nodeType && module;
9269	var freeGlobal = typeof global == 'object' && global;
9270	if (
9271		freeGlobal.global === freeGlobal ||
9272		freeGlobal.window === freeGlobal ||
9273		freeGlobal.self === freeGlobal
9274	) {
9275		root = freeGlobal;
9276	}
9277
9278	/**
9279	 * The `punycode` object.
9280	 * @name punycode
9281	 * @type Object
9282	 */
9283	var punycode,
9284
9285	/** Highest positive signed 32-bit float value */
9286	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
9287
9288	/** Bootstring parameters */
9289	base = 36,
9290	tMin = 1,
9291	tMax = 26,
9292	skew = 38,
9293	damp = 700,
9294	initialBias = 72,
9295	initialN = 128, // 0x80
9296	delimiter = '-', // '\x2D'
9297
9298	/** Regular expressions */
9299	regexPunycode = /^xn--/,
9300	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
9301	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
9302
9303	/** Error messages */
9304	errors = {
9305		'overflow': 'Overflow: input needs wider integers to process',
9306		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
9307		'invalid-input': 'Invalid input'
9308	},
9309
9310	/** Convenience shortcuts */
9311	baseMinusTMin = base - tMin,
9312	floor = Math.floor,
9313	stringFromCharCode = String.fromCharCode,
9314
9315	/** Temporary variable */
9316	key;
9317
9318	/*--------------------------------------------------------------------------*/
9319
9320	/**
9321	 * A generic error utility function.
9322	 * @private
9323	 * @param {String} type The error type.
9324	 * @returns {Error} Throws a `RangeError` with the applicable error message.
9325	 */
9326	function error(type) {
9327		throw new RangeError(errors[type]);
9328	}
9329
9330	/**
9331	 * A generic `Array#map` utility function.
9332	 * @private
9333	 * @param {Array} array The array to iterate over.
9334	 * @param {Function} callback The function that gets called for every array
9335	 * item.
9336	 * @returns {Array} A new array of values returned by the callback function.
9337	 */
9338	function map(array, fn) {
9339		var length = array.length;
9340		var result = [];
9341		while (length--) {
9342			result[length] = fn(array[length]);
9343		}
9344		return result;
9345	}
9346
9347	/**
9348	 * A simple `Array#map`-like wrapper to work with domain name strings or email
9349	 * addresses.
9350	 * @private
9351	 * @param {String} domain The domain name or email address.
9352	 * @param {Function} callback The function that gets called for every
9353	 * character.
9354	 * @returns {Array} A new string of characters returned by the callback
9355	 * function.
9356	 */
9357	function mapDomain(string, fn) {
9358		var parts = string.split('@');
9359		var result = '';
9360		if (parts.length > 1) {
9361			// In email addresses, only the domain name should be punycoded. Leave
9362			// the local part (i.e. everything up to `@`) intact.
9363			result = parts[0] + '@';
9364			string = parts[1];
9365		}
9366		// Avoid `split(regex)` for IE8 compatibility. See #17.
9367		string = string.replace(regexSeparators, '\x2E');
9368		var labels = string.split('.');
9369		var encoded = map(labels, fn).join('.');
9370		return result + encoded;
9371	}
9372
9373	/**
9374	 * Creates an array containing the numeric code points of each Unicode
9375	 * character in the string. While JavaScript uses UCS-2 internally,
9376	 * this function will convert a pair of surrogate halves (each of which
9377	 * UCS-2 exposes as separate characters) into a single code point,
9378	 * matching UTF-16.
9379	 * @see `punycode.ucs2.encode`
9380	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
9381	 * @memberOf punycode.ucs2
9382	 * @name decode
9383	 * @param {String} string The Unicode input string (UCS-2).
9384	 * @returns {Array} The new array of code points.
9385	 */
9386	function ucs2decode(string) {
9387		var output = [],
9388		    counter = 0,
9389		    length = string.length,
9390		    value,
9391		    extra;
9392		while (counter < length) {
9393			value = string.charCodeAt(counter++);
9394			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
9395				// high surrogate, and there is a next character
9396				extra = string.charCodeAt(counter++);
9397				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
vendor: 2,267 bytes, lines 9398-9474
9398					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
9399				} else {
9400					// unmatched surrogate; only append this code unit, in case the next
9401					// code unit is the high surrogate of a surrogate pair
9402					output.push(value);
9403					counter--;
9404				}
9405			} else {
9406				output.push(value);
9407			}
9408		}
9409		return output;
9410	}
9411
9412	/**
9413	 * Creates a string based on an array of numeric code points.
9414	 * @see `punycode.ucs2.decode`
9415	 * @memberOf punycode.ucs2
9416	 * @name encode
9417	 * @param {Array} codePoints The array of numeric code points.
9418	 * @returns {String} The new Unicode string (UCS-2).
9419	 */
9420	function ucs2encode(array) {
9421		return map(array, function(value) {
9422			var output = '';
9423			if (value > 0xFFFF) {
9424				value -= 0x10000;
9425				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
9426				value = 0xDC00 | value & 0x3FF;
9427			}
9428			output += stringFromCharCode(value);
9429			return output;
9430		}).join('');
9431	}
9432
9433	/**
9434	 * Converts a basic code point into a digit/integer.
9435	 * @see `digitToBasic()`
9436	 * @private
9437	 * @param {Number} codePoint The basic numeric code point value.
9438	 * @returns {Number} The numeric value of a basic code point (for use in
9439	 * representing integers) in the range `0` to `base - 1`, or `base` if
9440	 * the code point does not represent a value.
9441	 */
9442	function basicToDigit(codePoint) {
9443		if (codePoint - 48 < 10) {
9444			return codePoint - 22;
9445		}
9446		if (codePoint - 65 < 26) {
9447			return codePoint - 65;
9448		}
9449		if (codePoint - 97 < 26) {
9450			return codePoint - 97;
9451		}
9452		return base;
9453	}
9454
9455	/**
9456	 * Converts a digit/integer into a basic code point.
9457	 * @see `basicToDigit()`
9458	 * @private
9459	 * @param {Number} digit The numeric value of a basic code point.
9460	 * @returns {Number} The basic code point whose value (when used for
9461	 * representing integers) is `digit`, which needs to be in the range
9462	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
9463	 * used; else, the lowercase form is used. The behavior is undefined
9464	 * if `flag` is non-zero and `digit` has no uppercase form.
9465	 */
9466	function digitToBasic(digit, flag) {
9467		//  0..25 map to ASCII a..z or A..Z
9468		// 26..35 map to ASCII 0..9
9469		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
9470	}
9471
9472	/**
9473	 * Bias adaptation function as per section 3.4 of RFC 3492.
9474	 * https
vendor: 7,293 bytes, lines 9474-9749
9474://tools.ietf.org/html/rfc3492#section-3.4
9475	 * @private
9476	 */
9477	function adapt(delta, numPoints, firstTime) {
9478		var k = 0;
9479		delta = firstTime ? floor(delta / damp) : delta >> 1;
9480		delta += floor(delta / numPoints);
9481		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
9482			delta = floor(delta / baseMinusTMin);
9483		}
9484		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
9485	}
9486
9487	/**
9488	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
9489	 * symbols.
9490	 * @memberOf punycode
9491	 * @param {String} input The Punycode string of ASCII-only symbols.
9492	 * @returns {String} The resulting string of Unicode symbols.
9493	 */
9494	function decode(input) {
9495		// Don't use UCS-2
9496		var output = [],
9497		    inputLength = input.length,
9498		    out,
9499		    i = 0,
9500		    n = initialN,
9501		    bias = initialBias,
9502		    basic,
9503		    j,
9504		    index,
9505		    oldi,
9506		    w,
9507		    k,
9508		    digit,
9509		    t,
9510		    /** Cached calculation results */
9511		    baseMinusT;
9512
9513		// Handle the basic code points: let `basic` be the number of input code
9514		// points before the last delimiter, or `0` if there is none, then copy
9515		// the first basic code points to the output.
9516
9517		basic = input.lastIndexOf(delimiter);
9518		if (basic < 0) {
9519			basic = 0;
9520		}
9521
9522		for (j = 0; j < basic; ++j) {
9523			// if it's not a basic code point
9524			if (input.charCodeAt(j) >= 0x80) {
9525				error('not-basic');
9526			}
9527			output.push(input.charCodeAt(j));
9528		}
9529
9530		// Main decoding loop: start just after the last delimiter if any basic code
9531		// points were copied; start at the beginning otherwise.
9532
9533		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
9534
9535			// `index` is the index of the next character to be consumed.
9536			// Decode a generalized variable-length integer into `delta`,
9537			// which gets added to `i`. The overflow checking is easier
9538			// if we increase `i` as we go, then subtract off its starting
9539			// value at the end to obtain `delta`.
9540			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
9541
9542				if (index >= inputLength) {
9543					error('invalid-input');
9544				}
9545
9546				digit = basicToDigit(input.charCodeAt(index++));
9547
9548				if (digit >= base || digit > floor((maxInt - i) / w)) {
9549					error('overflow');
9550				}
9551
9552				i += digit * w;
9553				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
9554
9555				if (digit < t) {
9556					break;
9557				}
9558
9559				baseMinusT = base - t;
9560				if (w > floor(maxInt / baseMinusT)) {
9561					error('overflow');
9562				}
9563
9564				w *= baseMinusT;
9565
9566			}
9567
9568			out = output.length + 1;
9569			bias = adapt(i - oldi, out, oldi == 0);
9570
9571			// `i` was supposed to wrap around from `out` to `0`,
9572			// incrementing `n` each time, so we'll fix that now:
9573			if (floor(i / out) > maxInt - n) {
9574				error('overflow');
9575			}
9576
9577			n += floor(i / out);
9578			i %= out;
9579
9580			// Insert `n` at position `i` of the output
9581			output.splice(i++, 0, n);
9582
9583		}
9584
9585		return ucs2encode(output);
9586	}
9587
9588	/**
9589	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
9590	 * Punycode string of ASCII-only symbols.
9591	 * @memberOf punycode
9592	 * @param {String} input The string of Unicode symbols.
9593	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
9594	 */
9595	function encode(input) {
9596		var n,
9597		    delta,
9598		    handledCPCount,
9599		    basicLength,
9600		    bias,
9601		    j,
9602		    m,
9603		    q,
9604		    k,
9605		    t,
9606		    currentValue,
9607		    output = [],
9608		    /** `inputLength` will hold the number of code points in `input`. */
9609		    inputLength,
9610		    /** Cached calculation results */
9611		    handledCPCountPlusOne,
9612		    baseMinusT,
9613		    qMinusT;
9614
9615		// Convert the input in UCS-2 to Unicode
9616		input = ucs2decode(input);
9617
9618		// Cache the length
9619		inputLength = input.length;
9620
9621		// Initialize the state
9622		n = initialN;
9623		delta = 0;
9624		bias = initialBias;
9625
9626		// Handle the basic code points
9627		for (j = 0; j < inputLength; ++j) {
9628			currentValue = input[j];
9629			if (currentValue < 0x80) {
9630				output.push(stringFromCharCode(currentValue));
9631			}
9632		}
9633
9634		handledCPCount = basicLength = output.length;
9635
9636		// `handledCPCount` is the number of code points that have been handled;
9637		// `basicLength` is the number of basic code points.
9638
9639		// Finish the basic string - if it is not empty - with a delimiter
9640		if (basicLength) {
9641			output.push(delimiter);
9642		}
9643
9644		// Main encoding loop:
9645		while (handledCPCount < inputLength) {
9646
9647			// All non-basic code points < n have been handled already. Find the next
9648			// larger one:
9649			for (m = maxInt, j = 0; j < inputLength; ++j) {
9650				currentValue = input[j];
9651				if (currentValue >= n && currentValue < m) {
9652					m = currentValue;
9653				}
9654			}
9655
9656			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
9657			// but guard against overflow
9658			handledCPCountPlusOne = handledCPCount + 1;
9659			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
9660				error('overflow');
9661			}
9662
9663			delta += (m - n) * handledCPCountPlusOne;
9664			n = m;
9665
9666			for (j = 0; j < inputLength; ++j) {
9667				currentValue = input[j];
9668
9669				if (currentValue < n && ++delta > maxInt) {
9670					error('overflow');
9671				}
9672
9673				if (currentValue == n) {
9674					// Represent delta as a generalized variable-length integer
9675					for (q = delta, k = base; /* no condition */; k += base) {
9676						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
9677						if (q < t) {
9678							break;
9679						}
9680						qMinusT = q - t;
9681						baseMinusT = base - t;
9682						output.push(
9683							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
9684						);
9685						q = floor(qMinusT / baseMinusT);
9686					}
9687
9688					output.push(stringFromCharCode(digitToBasic(q, 0)));
9689					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
9690					delta = 0;
9691					++handledCPCount;
9692				}
9693			}
9694
9695			++delta;
9696			++n;
9697
9698		}
9699		return output.join('');
9700	}
9701
9702	/**
9703	 * Converts a Punycode string representing a domain name or an email address
9704	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
9705	 * it doesn't matter if you call it on a string that has already been
9706	 * converted to Unicode.
9707	 * @memberOf punycode
9708	 * @param {String} input The Punycoded domain name or email address to
9709	 * convert to Unicode.
9710	 * @returns {String} The Unicode representation of the given Punycode
9711	 * string.
9712	 */
9713	function toUnicode(input) {
9714		return mapDomain(input, function(string) {
9715			return regexPunycode.test(string)
9716				? decode(string.slice(4).toLowerCase())
9717				: string;
9718		});
9719	}
9720
9721	/**
9722	 * Converts a Unicode string representing a domain name or an email address to
9723	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
9724	 * i.e. it doesn't matter if you call it with a domain that's already in
9725	 * ASCII.
9726	 * @memberOf punycode
9727	 * @param {String} input The domain name or email address to convert, as a
9728	 * Unicode string.
9729	 * @returns {String} The Punycode representation of the given domain name or
9730	 * email address.
9731	 */
9732	function toASCII(input) {
9733		return mapDomain(input, function(string) {
9734			return regexNonASCII.test(string)
9735				? 'xn--' + encode(string)
9736				: string;
9737		});
9738	}
9739
9740	/*--------------------------------------------------------------------------*/
9741
9742	/** Define the public API */
9743	punycode = {
9744		/**
9745		 * A string representing the current Punycode.js version number.
9746		 * @memberOf punycode
9747		 * @type String
9748		 */
9749		'version': '1.
97494.1',
9750		/**
9751		 * An object of methods to convert from JavaScript's internal character
9752		 * representation (UCS-2) to Unicode code points, and back.
9753		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
9754		 * @memberOf punycode
9755		 * @type Object
9756		 */
9757		'ucs2': {
9758			'decode': ucs2decode,
9759			'encode': ucs2encode
9760		},
9761		'decode': decode,
9762		'encode': encode,
9763		'toASCII': toASCII,
9764		'toUnicode': toUnicode
9765	};
9766
9767	/** Expose `punycode` */
9768	// Some AMD build optimizers, like r.js, check for specific condition patterns
9769	// like the following:
9770	if (
9771		typeof define == 'function' &&
9772		typeof define.amd == 'object' &&
9773		define.amd
9774	) {
9775		define('punycode', function() {
9776			return punycode;
9777		});
9778	} else if (freeExports && freeModule) {
9779		if (module.exports == freeExports) {
9780			// in Node.js, io.js, or RingoJS v0.8.0+
9781			freeModule.exports = punycode;
9782		} else {
9783			// in Narwhal or RingoJS v0.7.0-
9784			for (key in punycode) {
9785				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
9786			}
9787		}
9788	} else {
9789		// in Rhino or a web browser
9790		root.punycode = punycode;
9791	}
9792
9793}(this));
9794
9795}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
9796},{}],95:[function(require,module,exports){
9797// Copyright Joyent, Inc. and other Node contributors.
9798//
9799// Permission is hereby granted, free of charge, to any person obtaining a
9800// copy of this software and associated documentation files (the
9801// "Software"), to deal in the Software without restriction, including
9802// without limitation the rights to use, copy, modify, merge, publish,
9803// distribute, sublicense, and/or sell copies of the Software, and to permit
9804// persons to whom the Software is furnished to do so, subject to the
9805// following conditions:
9806//
9807// The above copyright notice and this permission notice shall be included
9808// in all copies or substantial portions of the Software.
9809//
9810// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9811// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9812// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
9813// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
9814// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
9815// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
9816// USE OR OTHER DEALINGS IN THE SOFTWARE.
9817
9818'use strict';
9819
9820// If obj.hasOwnProperty has been overridden, then calling
9821// obj.hasOwnProperty(prop) will break.
9822// See: https://github.com/joyent/node/issues/1707
9823function hasOwnProperty(obj, prop) {
9824  return Object.prototype.hasOwnProperty.call(obj, prop);
9825}
9826
9827module.exports = function(qs, sep, eq, options) {
9828  sep = sep || '&';
9829  eq = eq || '=';
9830  var obj = {};
9831
9832  if (typeof qs !== 'string' || qs.length === 0) {
9833    return obj;
9834  }
9835
9836  var regexp = /\+/g;
9837  qs = qs.split(sep);
9838
9839  var maxKeys = 1000;
9840  if (options && typeof options.maxKeys === 'number') {
9841    maxKeys = options.maxKeys;
9842  }
9843
9844  var len = qs.length;
9845  // maxKeys <= 0 means that we should not limit keys count
9846  if (maxKeys > 0 && len > maxKeys) {
9847    len = maxKeys;
9848  }
9849
9850  for (var i = 0; i < len; ++i) {
9851    var x = qs[i].replace(regexp, '%20'),
9852        idx = x.indexOf(eq),
9853        kstr, vstr, k, v;
9854
9855    if (idx >= 0) {
9856      kstr = x.substr(0, idx);
9857      vstr = x.substr(idx + 1);
9858    } else {
9859      kstr = x;
9860      vstr = '';
9861    }
9862
9863    k = decodeURIComponent(kstr);
9864    v = decodeURIComponent(vstr);
9865
9866    if (!hasOwnProperty(obj, k)) {
9867      obj[k] = v;
9868    } else if (isArray(obj[k])) {
9869      obj[k].push(v);
9870    } else {
9871      obj[k] = [obj[k], v];
9872    }
9873  }
9874
9875  return obj;
9876};
9877
9878var isArray = Array.isArray || function (xs) {
9879  return Object.prototype.toString.call(xs) === '[object Array]';
9880};
9881
9882},{}],96:[function(require,module,exports){
9883// Copyright Joyent, Inc. and other Node contributors.
9884//
9885// Permission is hereby granted, free of charge, to any person obtaining a
9886// copy of this software and associated documentation files (the
9887// "Software"), to deal in the Software without restriction, including
9888// without limitation the rights to use, copy, modify, merge, publish,
9889// distribute, sublicense, and/or sell copies of the Software, and to permit
9890// persons to whom the Software is furnished to do so, subject to the
9891// following conditions:
9892//
9893// The above copyright notice and this permission notice shall be included
9894// in all copies or substantial portions of the Software.
9895//
9896// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9897// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9898// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
9899// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
9900// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
9901// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
9902// USE OR OTHER DEALINGS IN THE SOFTWARE.
9903
9904'use strict';
9905
9906var stringifyPrimitive = function(v) {
9907  switch (typeof v) {
9908    case 'string':
9909      return v;
9910
9911    case 'boolean':
9912      return v ? 'true' : 'false';
9913
9914    case 'number':
9915      return isFinite(v) ? v : '';
9916
9917    default:
9918      return '';
9919  }
9920};
9921
9922module.exports = function(obj, sep, eq, name) {
9923  sep = sep || '&';
9924  eq = eq || '=';
9925  if (obj === null) {
9926    obj = undefined;
9927  }
9928
9929  if (typeof obj === 'object') {
9930    return map(objectKeys(obj), function(k) {
9931      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
9932      if (isArray(obj[k])) {
9933        return map(obj[k], function(v) {
9934          return ks + encodeURIComponent(stringifyPrimitive(v));
9935        }).join(sep);
9936      } else {
9937        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
9938      }
9939    }).join(sep);
9940
9941  }
9942
9943  if (!name) return '';
9944  return encodeURIComponent(stringifyPrimitive(name)) + eq +
9945         encodeURIComponent(stringifyPrimitive(obj));
9946};
9947
9948var isArray = Array.isArray || function (xs) {
9949  return Object.prototype.toString.call(xs) === '[object Array]';
9950};
9951
9952function map (xs, f) {
9953  if (xs.map) return xs.map(f);
9954  var res = [];
9955  for (var i = 0; i < xs.length; i++) {
9956    res.push(f(xs[i], i));
9957  }
9958  return res;
9959}
9960
9961var objectKeys = Object.keys || function (obj) {
9962  var res = [];
9963  for (var key in obj) {
9964    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
9965  }
9966  return res;
9967};
9968
9969},{}],97:[function(require,module,exports){
9970'use strict';
9971
9972exports.decode = exports.parse = require('./decode');
9973exports.encode = exports.stringify = require('./encode');
9974
9975},{"./decode":95,"./encode":96}],98:[function(require,module,exports){
9976// Copyright Joyent, Inc. and other Node contributors.
9977//
9978// Permission is hereby granted, free of charge, to any person obtaining a
9979// copy of this software and associated documentation files (the
9980// "Software"), to deal in the Software without restriction, including
9981// without limitation the rights to use, copy, modify, merge, publish,
9982// distribute, sublicense, and/or sell copies of the Software, and to permit
9983// persons to whom the Software is furnished to do so, subject to the
9984// following conditions:
9985//
9986// The above copyright notice and this permission notice shall be included
9987// in all copies or substantial portions of the Software.
9988//
9989// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
9990// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
9991// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
9992// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
9993// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
9994// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
9995// USE OR OTHER DEALINGS IN THE SOFTWARE.
9996
9997'use strict';
9998
9999var punycode = require('punycode');
10000var util = require('./util');
10001
10002exports.parse = urlParse;
10003exports.resolve = urlResolve;
10004exports.resolveObject = urlResolveObject;
10005exports.format = urlFormat;
10006
10007exports.Url = Url;
10008
10009function Url() {
10010  this.protocol = null;
10011  this.slashes = null;
10012  this.auth = null;
10013  this.host = null;
10014  this.port = null;
10015  this.hostname = null;
10016  this.hash = null;
10017  this.search = null;
10018  this.query = null;
10019  this.pathname = null;
10020  this.path = null;
10021  this.href = null;
10022}
10023
10024// Reference: RFC 3986, RFC 1808, RFC 2396
10025
10026// define these here so at least they only have to be
10027// compiled once on the first module load.
10028var protocolPattern = /^([a-z0-9.+-]+:)/i,
10029    portPattern = /:[0-9]*$/,
10030
10031    // Special case for a simple path URL
vendor: 11,778 bytes, lines 10032-10409
10032    simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
10033
10034    // RFC 2396: characters reserved for delimiting URLs.
10035    // We actually just auto-escape these.
10036    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
10037
10038    // RFC 2396: characters not allowed for various reasons.
10039    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
10040
10041    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
10042    autoEscape = ['\''].concat(unwise),
10043    // Characters that are never ever allowed in a hostname.
10044    // Note that any invalid chars are also handled, but these
10045    // are the ones that are *expected* to be seen, so we fast-path
10046    // them.
10047    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
10048    hostEndingChars = ['/', '?', '#'],
10049    hostnameMaxLen = 255,
10050    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
10051    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
10052    // protocols that can allow "unsafe" and "unwise" chars.
10053    unsafeProtocol = {
10054      'javascript': true,
10055      'javascript:': true
10056    },
10057    // protocols that never have a hostname.
10058    hostlessProtocol = {
10059      'javascript': true,
10060      'javascript:': true
10061    },
10062    // protocols that always contain a // bit.
10063    slashedProtocol = {
10064      'http': true,
10065      'https': true,
10066      'ftp': true,
10067      'gopher': true,
10068      'file': true,
10069      'http:': true,
10070      'https:': true,
10071      'ftp:': true,
10072      'gopher:': true,
10073      'file:': true
10074    },
10075    querystring = require('querystring');
10076
10077function urlParse(url, parseQueryString, slashesDenoteHost) {
10078  if (url && util.isObject(url) && url instanceof Url) return url;
10079
10080  var u = new Url;
10081  u.parse(url, parseQueryString, slashesDenoteHost);
10082  return u;
10083}
10084
10085Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
10086  if (!util.isString(url)) {
10087    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
10088  }
10089
10090  // Copy chrome, IE, opera backslash-handling behavior.
10091  // Back slashes before the query string get converted to forward slashes
10092  // See: https://code.google.com/p/chromium/issues/detail?id=25916
10093  var queryIndex = url.indexOf('?'),
10094      splitter =
10095          (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
10096      uSplit = url.split(splitter),
10097      slashRegex = /\\/g;
10098  uSplit[0] = uSplit[0].replace(slashRegex, '/');
10099  url = uSplit.join(splitter);
10100
10101  var rest = url;
10102
10103  // trim before proceeding.
10104  // This is to support parse stuff like "  http://foo.com  \n"
10105  rest = rest.trim();
10106
10107  if (!slashesDenoteHost && url.split('#').length === 1) {
10108    // Try fast path regexp
10109    var simplePath = simplePathPattern.exec(rest);
10110    if (simplePath) {
10111      this.path = rest;
10112      this.href = rest;
10113      this.pathname = simplePath[1];
10114      if (simplePath[2]) {
10115        this.search = simplePath[2];
10116        if (parseQueryString) {
10117          this.query = querystring.parse(this.search.substr(1));
10118        } else {
10119          this.query = this.search.substr(1);
10120        }
10121      } else if (parseQueryString) {
10122        this.search = '';
10123        this.query = {};
10124      }
10125      return this;
10126    }
10127  }
10128
10129  var proto = protocolPattern.exec(rest);
10130  if (proto) {
10131    proto = proto[0];
10132    var lowerProto = proto.toLowerCase();
10133    this.protocol = lowerProto;
10134    rest = rest.substr(proto.length);
10135  }
10136
10137  // figure out if it's got a host
10138  // user@server is *always* interpreted as a hostname, and url
10139  // resolution will treat //foo/bar as host=foo,path=bar because that's
10140  // how the browser resolves relative URLs.
10141  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
10142    var slashes = rest.substr(0, 2) === '//';
10143    if (slashes && !(proto && hostlessProtocol[proto])) {
10144      rest = rest.substr(2);
10145      this.slashes = true;
10146    }
10147  }
10148
10149  if (!hostlessProtocol[proto] &&
10150      (slashes || (proto && !slashedProtocol[proto]))) {
10151
10152    // there's a hostname.
10153    // the first instance of /, ?, ;, or # ends the host.
10154    //
10155    // If there is an @ in the hostname, then non-host chars *are* allowed
10156    // to the left of the last @ sign, unless some host-ending character
10157    // comes *before* the @-sign.
10158    // URLs are obnoxious.
10159    //
10160    // ex:
10161    // http://a@b@c/ => user:a@b host:c
10162    // http://a@b?@c => user:a host:c path:/?@c
10163
10164    // v0.12 TODO(isaacs): This is not quite how Chrome does things.
10165    // Review our test case against browsers more comprehensively.
10166
10167    // find the first instance of any hostEndingChars
10168    var hostEnd = -1;
10169    for (var i = 0; i < hostEndingChars.length; i++) {
10170      var hec = rest.indexOf(hostEndingChars[i]);
10171      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
10172        hostEnd = hec;
10173    }
10174
10175    // at this point, either we have an explicit point where the
10176    // auth portion cannot go past, or the last @ char is the decider.
10177    var auth, atSign;
10178    if (hostEnd === -1) {
10179      // atSign can be anywhere.
10180      atSign = rest.lastIndexOf('@');
10181    } else {
10182      // atSign must be in auth portion.
10183      // http://a@b/c@d => host:b auth:a path:/c@d
10184      atSign = rest.lastIndexOf('@', hostEnd);
10185    }
10186
10187    // Now we have a portion which is definitely the auth.
10188    // Pull that off.
10189    if (atSign !== -1) {
10190      auth = rest.slice(0, atSign);
10191      rest = rest.slice(atSign + 1);
10192      this.auth = decodeURIComponent(auth);
10193    }
10194
10195    // the host is the remaining to the left of the first non-host char
10196    hostEnd = -1;
10197    for (var i = 0; i < nonHostChars.length; i++) {
10198      var hec = rest.indexOf(nonHostChars[i]);
10199      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
10200        hostEnd = hec;
10201    }
10202    // if we still have not hit it, then the entire thing is a host.
10203    if (hostEnd === -1)
10204      hostEnd = rest.length;
10205
10206    this.host = rest.slice(0, hostEnd);
10207    rest = rest.slice(hostEnd);
10208
10209    // pull out port.
10210    this.parseHost();
10211
10212    // we've indicated that there is a hostname,
10213    // so even if it's empty, it has to be present.
10214    this.hostname = this.hostname || '';
10215
10216    // if hostname begins with [ and ends with ]
10217    // assume that it's an IPv6 address.
10218    var ipv6Hostname = this.hostname[0] === '[' &&
10219        this.hostname[this.hostname.length - 1] === ']';
10220
10221    // validate a little.
10222    if (!ipv6Hostname) {
10223      var hostparts = this.hostname.split(/\./);
10224      for (var i = 0, l = hostparts.length; i < l; i++) {
10225        var part = hostparts[i];
10226        if (!part) continue;
10227        if (!part.match(hostnamePartPattern)) {
10228          var newpart = '';
10229          for (var j = 0, k = part.length; j < k; j++) {
10230            if (part.charCodeAt(j) > 127) {
10231              // we replace non-ASCII char with a temporary placeholder
10232              // we need this to make sure size of hostname is not
10233              // broken by replacing non-ASCII by nothing
10234              newpart += 'x';
10235            } else {
10236              newpart += part[j];
10237            }
10238          }
10239          // we test again with ASCII char only
10240          if (!newpart.match(hostnamePartPattern)) {
10241            var validParts = hostparts.slice(0, i);
10242            var notHost = hostparts.slice(i + 1);
10243            var bit = part.match(hostnamePartStart);
10244            if (bit) {
10245              validParts.push(bit[1]);
10246              notHost.unshift(bit[2]);
10247            }
10248            if (notHost.length) {
10249              rest = '/' + notHost.join('.') + rest;
10250            }
10251            this.hostname = validParts.join('.');
10252            break;
10253          }
10254        }
10255      }
10256    }
10257
10258    if (this.hostname.length > hostnameMaxLen) {
10259      this.hostname = '';
10260    } else {
10261      // hostnames are always lower case.
10262      this.hostname = this.hostname.toLowerCase();
10263    }
10264
10265    if (!ipv6Hostname) {
10266      // IDNA Support: Returns a punycoded representation of "domain".
10267      // It only converts parts of the domain name that
10268      // have non-ASCII characters, i.e. it doesn't matter if
10269      // you call it with a domain that already is ASCII-only.
10270      this.hostname = punycode.toASCII(this.hostname);
10271    }
10272
10273    var p = this.port ? ':' + this.port : '';
10274    var h = this.hostname || '';
10275    this.host = h + p;
10276    this.href += this.host;
10277
10278    // strip [ and ] from the hostname
10279    // the host field still retains them, though
10280    if (ipv6Hostname) {
10281      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
10282      if (rest[0] !== '/') {
10283        rest = '/' + rest;
10284      }
10285    }
10286  }
10287
10288  // now rest is set to the post-host stuff.
10289  // chop off any delim chars.
10290  if (!unsafeProtocol[lowerProto]) {
10291
10292    // First, make 100% sure that any "autoEscape" chars get
10293    // escaped, even if encodeURIComponent doesn't think they
10294    // need to be.
10295    for (var i = 0, l = autoEscape.length; i < l; i++) {
10296      var ae = autoEscape[i];
10297      if (rest.indexOf(ae) === -1)
10298        continue;
10299      var esc = encodeURIComponent(ae);
10300      if (esc === ae) {
10301        esc = escape(ae);
10302      }
10303      rest = rest.split(ae).join(esc);
10304    }
10305  }
10306
10307
10308  // chop off from the tail first.
10309  var hash = rest.indexOf('#');
10310  if (hash !== -1) {
10311    // got a fragment string.
10312    this.hash = rest.substr(hash);
10313    rest = rest.slice(0, hash);
10314  }
10315  var qm = rest.indexOf('?');
10316  if (qm !== -1) {
10317    this.search = rest.substr(qm);
10318    this.query = rest.substr(qm + 1);
10319    if (parseQueryString) {
10320      this.query = querystring.parse(this.query);
10321    }
10322    rest = rest.slice(0, qm);
10323  } else if (parseQueryString) {
10324    // no query string, but parseQueryString still requested
10325    this.search = '';
10326    this.query = {};
10327  }
10328  if (rest) this.pathname = rest;
10329  if (slashedProtocol[lowerProto] &&
10330      this.hostname && !this.pathname) {
10331    this.pathname = '/';
10332  }
10333
10334  //to support http.request
10335  if (this.pathname || this.search) {
10336    var p = this.pathname || '';
10337    var s = this.search || '';
10338    this.path = p + s;
10339  }
10340
10341  // finally, reconstruct the href based on what has been validated.
10342  this.href = this.format();
10343  return this;
10344};
10345
10346// format a parsed object into a url string
10347function urlFormat(obj) {
10348  // ensure it's an object, and not a string url.
10349  // If it's an obj, this is a no-op.
10350  // this way, you can call url_format() on strings
10351  // to clean up potentially wonky urls.
10352  if (util.isString(obj)) obj = urlParse(obj);
10353  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
10354  return obj.format();
10355}
10356
10357Url.prototype.format = function() {
10358  var auth = this.auth || '';
10359  if (auth) {
10360    auth = encodeURIComponent(auth);
10361    auth = auth.replace(/%3A/i, ':');
10362    auth += '@';
10363  }
10364
10365  var protocol = this.protocol || '',
10366      pathname = this.pathname || '',
10367      hash = this.hash || '',
10368      host = false,
10369      query = '';
10370
10371  if (this.host) {
10372    host = auth + this.host;
10373  } else if (this.hostname) {
10374    host = auth + (this.hostname.indexOf(':') === -1 ?
10375        this.hostname :
10376        '[' + this.hostname + ']');
10377    if (this.port) {
10378      host += ':' + this.port;
10379    }
10380  }
10381
10382  if (this.query &&
10383      util.isObject(this.query) &&
10384      Object.keys(this.query).length) {
10385    query = querystring.stringify(this.query);
10386  }
10387
10388  var search = this.search || (query && ('?' + query)) || '';
10389
10390  if (protocol && protocol.substr(-1) !== ':') protocol += ':';
10391
10392  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
10393  // unless they had them to begin with.
10394  if (this.slashes ||
10395      (!protocol || slashedProtocol[protocol]) && host !== false) {
10396    host = '//' + (host || '');
10397    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
10398  } else if (!host) {
10399    host = '';
10400  }
10401
10402  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
10403  if (search && search.charAt(0) !== '?') search = '?' + search;
10404
10405  pathname = pathname.replace(/[?#]/g, function(match) {
10406    return encodeURIComponent(match);
10407  });
10408  search = search.replace('#', '%23');
10409
10410  return protocol + host + pathname + search + hash;
10411};
10412
10413function urlResolve(source, relative) {
10414  return urlParse(source, false, true).resolve(relative);
10415}
10416
10417Url.prototype.resolve = function(relative) {
10418  return this.resolveObject(urlParse(relative, false, true)).format();
10419};
10420
10421function urlResolveObject(source, relative) {
10422  if (!source) return relative;
10423  return urlParse(source, false, true).resolveObject(relative);
10424}
10425
10426Url.prototype.resolveObject = function(relative) {
10427  if (util.isString(relative)) {
10428    var rel = new Url();
10429    rel.parse(relative, false, true);
10430    relative = rel;
10431  }
10432
10433  var result = new Url();
10434  var tkeys = Object.keys(this);
10435  for (var tk = 0; tk < tkeys.length; tk++) {
10436    var tkey = tkeys[tk];
10437    result[tkey] = this[tkey];
10438  }
10439
10440  // hash is always overridden, no matter what.
10441  // even href="" will remove it.
10442  result.hash = relative.hash;
10443
10444  // if the relative url is empty, then there's nothing left to do here.
10445  if (relative.href === '') {
10446    result.href = result.format();
10447    return result;
10448  }
10449
10450  // hrefs like //foo/bar always cut to the protocol.
10451  if (relative.slashes && !relative.protocol) {
10452    // take everything except the protocol from relative
10453    var rkeys = Object.keys(relative);
10454    for (var rk = 0; rk < rkeys.length; rk++) {
10455      var rkey = rkeys[rk];
10456      if (rkey !== 'protocol')
10457        result[rkey] = relative[rkey];
10458    }
10459
10460    //urlParse appends trailing / to urls like http://www.example.com
10461    if (slashedProtocol[result.protocol] &&
10462        result.hostname && !result.pathname) {
10463      result.path = result.pathname = '/';
10464    }
10465
10466    result.href = result.format();
10467    return result;
10468  }
10469
10470  if (relative.protocol && relative.protocol !== result.protocol) {
10471    // if it's a known url protocol, then changing
10472    // the protocol does weird things
10473    // first, if it's not file:, then we MUST have a host,
10474    // and if there was a path
10475    // to begin with, then we MUST have a path.
10476    // if it is file:, then the host is dropped,
10477    // because that's known to be hostless.
10478    // anything else is assumed to be absolute.
10479    if (!slashedProtocol[relative.protocol]) {
10480      var keys = Object.keys(relative);
10481      for (var v = 0; v < keys.length; v++) {
10482        var k = keys[v];
10483        result[k] = relative[k];
10484      }
10485      result.href = result.format();
10486      return result;
10487    }
10488
10489    result.protocol = relative.protocol;
10490    if (!relative.host && !hostlessProtocol[relative.protocol]) {
10491      var relPath = (relative.pathname || '').split('/');
10492      while (relPath.length && !(relative.host = relPath.shift()));
10493      if (!relative.host) relative.host = '';
10494      if (!relative.hostname) relative.hostname = '';
10495      if (relPath[0] !== '') relPath.unshift('');
10496      if (relPath.length < 2) relPath.unshift('');
10497      result.pathname = relPath.join('/');
10498    } else {
10499      result.pathname = relative.pathname;
10500    }
10501    result.search = relative.search;
10502    result.query = relative.query;
10503    result.host = relative.host || '';
10504    result.auth = relative.auth;
10505    result.hostname = relative.hostname || relative.host;
10506    result.port = relative.port;
10507    // to support http.request
10508    if (result.pathname || result.search) {
10509      var p = result.pathname || '';
10510      var s = result.search || '';
10511      result.path = p + s;
10512    }
10513    result.slashes = result.slashes || relative.slashes;
10514    result.href = result.format();
10515    return result;
10516  }
10517
10518  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
10519      isRelAbs = (
10520          relative.host ||
10521          relative.pathname && relative.pathname.charAt(0) === '/'
10522      ),
10523      mustEndAbs = (isRelAbs || isSourceAbs ||
10524                    (result.host && relative.pathname)),
10525      removeAllDots = mustEndAbs,
10526      srcPath = result.pathname && result.pathname.split('/') || [],
10527      relPath = relative.pathname && relative.pathname.split('/') || [],
10528      psychotic = result.protocol && !slashedProtocol[result.protocol];
10529
10530  // if the url is a non-slashed url, then relative
10531  // links like ../.. should be able
10532  // to crawl up to the hostname, as well.  This is strange.
10533  // result.protocol has already been set by now.
10534  // Later on, put the first path part into the host field.
10535  if (psychotic) {
10536    result.hostname = '';
10537    result.port = null;
10538    if (result.host) {
10539      if (srcPath[0] === '') srcPath[0] = result.host;
10540      else srcPath.unshift(result.host);
10541    }
10542    result.host = '';
10543    if (relative.protocol) {
10544      relative.hostname = null;
10545      relative.port = null;
10546      if (relative.host) {
10547        if (relPath[0] === '') relPath[0] = relative.host;
10548        else relPath.unshift(relative.host);
10549      }
10550      relative.host = null;
10551    }
10552    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
10553  }
10554
10555  if (isRelAbs) {
10556    // it's absolute.
10557    result.host = (relative.host || relative.host === '') ?
10558                  relative.host : result.host;
10559    result.hostname = (relative.hostname || relative.hostname === '') ?
10560                      relative.hostname : result.hostname;
10561    result.search = relative.search;
10562    result.query = relative.query;
10563    srcPath = relPath;
10564    // fall through to the dot-handling below.
vendor: 4,843 bytes, lines 10565-10727
10565  } else if (relPath.length) {
10566    // it's relative
10567    // throw away the existing file, and take the new path instead.
10568    if (!srcPath) srcPath = [];
10569    srcPath.pop();
10570    srcPath = srcPath.concat(relPath);
10571    result.search = relative.search;
10572    result.query = relative.query;
10573  } else if (!util.isNullOrUndefined(relative.search)) {
10574    // just pull out the search.
10575    // like href='?foo'.
10576    // Put this after the other two cases because it simplifies the booleans
10577    if (psychotic) {
10578      result.hostname = result.host = srcPath.shift();
10579      //occationaly the auth can get stuck only in host
10580      //this especially happens in cases like
10581      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
10582      var authInHost = result.host && result.host.indexOf('@') > 0 ?
10583                       result.host.split('@') : false;
10584      if (authInHost) {
10585        result.auth = authInHost.shift();
10586        result.host = result.hostname = authInHost.shift();
10587      }
10588    }
10589    result.search = relative.search;
10590    result.query = relative.query;
10591    //to support http.request
10592    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
10593      result.path = (result.pathname ? result.pathname : '') +
10594                    (result.search ? result.search : '');
10595    }
10596    result.href = result.format();
10597    return result;
10598  }
10599
10600  if (!srcPath.length) {
10601    // no path at all.  easy.
10602    // we've already handled the other stuff above.
10603    result.pathname = null;
10604    //to support http.request
10605    if (result.search) {
10606      result.path = '/' + result.search;
10607    } else {
10608      result.path = null;
10609    }
10610    result.href = result.format();
10611    return result;
10612  }
10613
10614  // if a url ENDs in . or .., then it must get a trailing slash.
10615  // however, if it ends in anything else non-slashy,
10616  // then it must NOT get a trailing slash.
10617  var last = srcPath.slice(-1)[0];
10618  var hasTrailingSlash = (
10619      (result.host || relative.host || srcPath.length > 1) &&
10620      (last === '.' || last === '..') || last === '');
10621
10622  // strip single dots, resolve double dots to parent dir
10623  // if the path tries to go above the root, `up` ends up > 0
10624  var up = 0;
10625  for (var i = srcPath.length; i >= 0; i--) {
10626    last = srcPath[i];
10627    if (last === '.') {
10628      srcPath.splice(i, 1);
10629    } else if (last === '..') {
10630      srcPath.splice(i, 1);
10631      up++;
10632    } else if (up) {
10633      srcPath.splice(i, 1);
10634      up--;
10635    }
10636  }
10637
10638  // if the path is allowed to go above the root, restore leading ..s
10639  if (!mustEndAbs && !removeAllDots) {
10640    for (; up--; up) {
10641      srcPath.unshift('..');
10642    }
10643  }
10644
10645  if (mustEndAbs && srcPath[0] !== '' &&
10646      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
10647    srcPath.unshift('');
10648  }
10649
10650  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
10651    srcPath.push('');
10652  }
10653
10654  var isAbsolute = srcPath[0] === '' ||
10655      (srcPath[0] && srcPath[0].charAt(0) === '/');
10656
10657  // put the host back
10658  if (psychotic) {
10659    result.hostname = result.host = isAbsolute ? '' :
10660                                    srcPath.length ? srcPath.shift() : '';
10661    //occationaly the auth can get stuck only in host
10662    //this especially happens in cases like
10663    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
10664    var authInHost = result.host && result.host.indexOf('@') > 0 ?
10665                     result.host.split('@') : false;
10666    if (authInHost) {
10667      result.auth = authInHost.shift();
10668      result.host = result.hostname = authInHost.shift();
10669    }
10670  }
10671
10672  mustEndAbs = mustEndAbs || (result.host && srcPath.length);
10673
10674  if (mustEndAbs && !isAbsolute) {
10675    srcPath.unshift('');
10676  }
10677
10678  if (!srcPath.length) {
10679    result.pathname = null;
10680    result.path = null;
10681  } else {
10682    result.pathname = srcPath.join('/');
10683  }
10684
10685  //to support request.http
10686  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
10687    result.path = (result.pathname ? result.pathname : '') +
10688                  (result.search ? result.search : '');
10689  }
10690  result.auth = relative.auth || result.auth;
10691  result.slashes = result.slashes || relative.slashes;
10692  result.href = result.format();
10693  return result;
10694};
10695
10696Url.prototype.parseHost = function() {
10697  var host = this.host;
10698  var port = portPattern.exec(host);
10699  if (port) {
10700    port = port[0];
10701    if (port !== ':') {
10702      this.port = port.substr(1);
10703    }
10704    host = host.substr(0, host.length - port.length);
10705  }
10706  if (host) this.hostname = host;
10707};
10708
10709},{"./util":99,"punycode":94,"querystring":97}],99:[function(require,module,exports){
10710'use strict';
10711
10712module.exports = {
10713  isString: function(arg) {
10714    return typeof(arg) === 'string';
10715  },
10716  isObject: function(arg) {
10717    return typeof(arg) === 'object' && arg !== null;
10718  },
10719  isNull: function(arg) {
10720    return arg === null;
10721  },
10722  isNullOrUndefined: function(arg) {
10723    return arg == null;
10724  }
10725};
10726
10727},{}]},{},[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.