/*!
 * Bootstrap v3.3.5 (http://getbootstrap.com)
 * Copyright 2011-2015 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

/*!
 * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=edd6285e54d5a7153208)
 * Config saved to config.json and https://gist.github.com/edd6285e54d5a7153208
 */
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(t){"use strict";var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),n=i.data("bs.tooltip"),s="object"==typeof e&&e;(n||!/destroy|hide/.test(e))&&(n||i.data("bs.tooltip",n=new o(this,s)),"string"==typeof e&&n[e]())})}var o=function(t,e){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",t,e)};o.VERSION="3.3.5",o.TRANSITION_DURATION=150,o.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},o.prototype.init=function(e,o,i){if(this.enabled=!0,this.type=e,this.$element=t(o),this.options=this.getOptions(i),this.$viewport=this.options.viewport&&t(t.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var n=this.options.trigger.split(" "),s=n.length;s--;){var r=n[s];if("click"==r)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=r){var a="hover"==r?"mouseenter":"focusin",p="hover"==r?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(p+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},o.prototype.getDefaults=function(){return o.DEFAULTS},o.prototype.getOptions=function(e){return e=t.extend({},this.getDefaults(),this.$element.data(),e),e.delay&&"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),e},o.prototype.getDelegateOptions=function(){var e={},o=this.getDefaults();return this._options&&t.each(this._options,function(t,i){o[t]!=i&&(e[t]=i)}),e},o.prototype.enter=function(e){var o=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return o||(o=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,o)),e instanceof t.Event&&(o.inState["focusin"==e.type?"focus":"hover"]=!0),o.tip().hasClass("in")||"in"==o.hoverState?void(o.hoverState="in"):(clearTimeout(o.timeout),o.hoverState="in",o.options.delay&&o.options.delay.show?void(o.timeout=setTimeout(function(){"in"==o.hoverState&&o.show()},o.options.delay.show)):o.show())},o.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},o.prototype.leave=function(e){var o=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return o||(o=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,o)),e instanceof t.Event&&(o.inState["focusout"==e.type?"focus":"hover"]=!1),o.isInStateTrue()?void 0:(clearTimeout(o.timeout),o.hoverState="out",o.options.delay&&o.options.delay.hide?void(o.timeout=setTimeout(function(){"out"==o.hoverState&&o.hide()},o.options.delay.hide)):o.hide())},o.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var i=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!i)return;var n=this,s=this.tip(),r=this.getUID(this.type);this.setContent(),s.attr("id",r),this.$element.attr("aria-describedby",r),this.options.animation&&s.addClass("fade");var a="function"==typeof this.options.placement?this.options.placement.call(this,s[0],this.$element[0]):this.options.placement,p=/\s?auto?\s?/i,l=p.test(a);l&&(a=a.replace(p,"")||"top"),s.detach().css({top:0,left:0,display:"block"}).addClass(a).data("bs."+this.type,this),this.options.container?s.appendTo(this.options.container):s.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var h=this.getPosition(),f=s[0].offsetWidth,c=s[0].offsetHeight;if(l){var d=a,u=this.getPosition(this.$viewport);a="bottom"==a&&h.bottom+c>u.bottom?"top":"top"==a&&h.top-c<u.top?"bottom":"right"==a&&h.right+f>u.width?"left":"left"==a&&h.left-f<u.left?"right":a,s.removeClass(d).addClass(a)}var v=this.getCalculatedOffset(a,h,f,c);this.applyPlacement(v,a);var g=function(){var t=n.hoverState;n.$element.trigger("shown.bs."+n.type),n.hoverState=null,"out"==t&&n.leave(n)};t.support.transition&&this.$tip.hasClass("fade")?s.one("bsTransitionEnd",g).emulateTransitionEnd(o.TRANSITION_DURATION):g()}},o.prototype.applyPlacement=function(e,o){var i=this.tip(),n=i[0].offsetWidth,s=i[0].offsetHeight,r=parseInt(i.css("margin-top"),10),a=parseInt(i.css("margin-left"),10);isNaN(r)&&(r=0),isNaN(a)&&(a=0),e.top+=r,e.left+=a,t.offset.setOffset(i[0],t.extend({using:function(t){i.css({top:Math.round(t.top),left:Math.round(t.left)})}},e),0),i.addClass("in");var p=i[0].offsetWidth,l=i[0].offsetHeight;"top"==o&&l!=s&&(e.top=e.top+s-l);var h=this.getViewportAdjustedDelta(o,e,p,l);h.left?e.left+=h.left:e.top+=h.top;var f=/top|bottom/.test(o),c=f?2*h.left-n+p:2*h.top-s+l,d=f?"offsetWidth":"offsetHeight";i.offset(e),this.replaceArrow(c,i[0][d],f)},o.prototype.replaceArrow=function(t,e,o){this.arrow().css(o?"left":"top",50*(1-t/e)+"%").css(o?"top":"left","")},o.prototype.setContent=function(){var t=this.tip(),e=this.getTitle();t.find(".tooltip-inner")[this.options.html?"html":"text"](e),t.removeClass("fade in top bottom left right")},o.prototype.hide=function(e){function i(){"in"!=n.hoverState&&s.detach(),n.$element.removeAttr("aria-describedby").trigger("hidden.bs."+n.type),e&&e()}var n=this,s=t(this.$tip),r=t.Event("hide.bs."+this.type);return this.$element.trigger(r),r.isDefaultPrevented()?void 0:(s.removeClass("in"),t.support.transition&&s.hasClass("fade")?s.one("bsTransitionEnd",i).emulateTransitionEnd(o.TRANSITION_DURATION):i(),this.hoverState=null,this)},o.prototype.fixTitle=function(){var t=this.$element;(t.attr("title")||"string"!=typeof t.attr("data-original-title"))&&t.attr("data-original-title",t.attr("title")||"").attr("title","")},o.prototype.hasContent=function(){return this.getTitle()},o.prototype.getPosition=function(e){e=e||this.$element;var o=e[0],i="BODY"==o.tagName,n=o.getBoundingClientRect();null==n.width&&(n=t.extend({},n,{width:n.right-n.left,height:n.bottom-n.top}));var s=i?{top:0,left:0}:e.offset(),r={scroll:i?document.documentElement.scrollTop||document.body.scrollTop:e.scrollTop()},a=i?{width:t(window).width(),height:t(window).height()}:null;return t.extend({},n,r,a,s)},o.prototype.getCalculatedOffset=function(t,e,o,i){return"bottom"==t?{top:e.top+e.height,left:e.left+e.width/2-o/2}:"top"==t?{top:e.top-i,left:e.left+e.width/2-o/2}:"left"==t?{top:e.top+e.height/2-i/2,left:e.left-o}:{top:e.top+e.height/2-i/2,left:e.left+e.width}},o.prototype.getViewportAdjustedDelta=function(t,e,o,i){var n={top:0,left:0};if(!this.$viewport)return n;var s=this.options.viewport&&this.options.viewport.padding||0,r=this.getPosition(this.$viewport);if(/right|left/.test(t)){var a=e.top-s-r.scroll,p=e.top+s-r.scroll+i;a<r.top?n.top=r.top-a:p>r.top+r.height&&(n.top=r.top+r.height-p)}else{var l=e.left-s,h=e.left+s+o;l<r.left?n.left=r.left-l:h>r.right&&(n.left=r.left+r.width-h)}return n},o.prototype.getTitle=function(){var t,e=this.$element,o=this.options;return t=e.attr("data-original-title")||("function"==typeof o.title?o.title.call(e[0]):o.title)},o.prototype.getUID=function(t){do t+=~~(1e6*Math.random());while(document.getElementById(t));return t},o.prototype.tip=function(){if(!this.$tip&&(this.$tip=t(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},o.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},o.prototype.enable=function(){this.enabled=!0},o.prototype.disable=function(){this.enabled=!1},o.prototype.toggleEnabled=function(){this.enabled=!this.enabled},o.prototype.toggle=function(e){var o=this;e&&(o=t(e.currentTarget).data("bs."+this.type),o||(o=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,o))),e?(o.inState.click=!o.inState.click,o.isInStateTrue()?o.enter(o):o.leave(o)):o.tip().hasClass("in")?o.leave(o):o.enter(o)},o.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null})};var i=t.fn.tooltip;t.fn.tooltip=e,t.fn.tooltip.Constructor=o,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=i,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),n=i.data("bs.popover"),s="object"==typeof e&&e;(n||!/destroy|hide/.test(e))&&(n||i.data("bs.popover",n=new o(this,s)),"string"==typeof e&&n[e]())})}var o=function(t,e){this.init("popover",t,e)};if(!t.fn.tooltip)throw new Error("Popover requires tooltip.js");o.VERSION="3.3.5",o.DEFAULTS=t.extend({},t.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),o.prototype=t.extend({},t.fn.tooltip.Constructor.prototype),o.prototype.constructor=o,o.prototype.getDefaults=function(){return o.DEFAULTS},o.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),o=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof o?"html":"append":"text"](o),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},o.prototype.hasContent=function(){return this.getTitle()||this.getContent()},o.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},o.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var i=t.fn.popover;t.fn.popover=e,t.fn.popover.Constructor=o,t.fn.popover.noConflict=function(){return t.fn.popover=i,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),n=i.data("bs.tab");n||i.data("bs.tab",n=new o(this)),"string"==typeof e&&n[e]()})}var o=function(e){this.element=t(e)};o.VERSION="3.3.5",o.TRANSITION_DURATION=150,o.prototype.show=function(){var e=this.element,o=e.closest("ul:not(.dropdown-menu)"),i=e.data("target");if(i||(i=e.attr("href"),i=i&&i.replace(/.*(?=#[^\s]*$)/,"")),!e.parent("li").hasClass("active")){var n=o.find(".active:last a"),s=t.Event("hide.bs.tab",{relatedTarget:e[0]}),r=t.Event("show.bs.tab",{relatedTarget:n[0]});if(n.trigger(s),e.trigger(r),!r.isDefaultPrevented()&&!s.isDefaultPrevented()){var a=t(i);this.activate(e.closest("li"),o),this.activate(a,a.parent(),function(){n.trigger({type:"hidden.bs.tab",relatedTarget:e[0]}),e.trigger({type:"shown.bs.tab",relatedTarget:n[0]})})}}},o.prototype.activate=function(e,i,n){function s(){r.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),e.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),a?(e[0].offsetWidth,e.addClass("in")):e.removeClass("fade"),e.parent(".dropdown-menu").length&&e.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),n&&n()}var r=i.find("> .active"),a=n&&t.support.transition&&(r.length&&r.hasClass("fade")||!!i.find("> .fade").length);r.length&&a?r.one("bsTransitionEnd",s).emulateTransitionEnd(o.TRANSITION_DURATION):s(),r.removeClass("in")};var i=t.fn.tab;t.fn.tab=e,t.fn.tab.Constructor=o,t.fn.tab.noConflict=function(){return t.fn.tab=i,this};var n=function(o){o.preventDefault(),e.call(t(this),"show")};t(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',n).on("click.bs.tab.data-api",'[data-toggle="pill"]',n)}(jQuery);
/* ========================================================================
 * Bootstrap: transition.js v3.3.7
 * http://getbootstrap.com/javascript/#transitions
 * ========================================================================
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================

  function transitionEnd() {
    var el = document.createElement('bootstrap')

    var transEndEventNames = {
      WebkitTransition : 'webkitTransitionEnd',
      MozTransition    : 'transitionend',
      OTransition      : 'oTransitionEnd otransitionend',
      transition       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return { end: transEndEventNames[name] }
      }
    }

    return false // explicit for ie8 (  ._.)
  }

  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) {
    var called = false
    var $el = this
    $(this).one('bsTransitionEnd', function () { called = true })
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
    setTimeout(callback, duration)
    return this
  }

  $(function () {
    $.support.transition = transitionEnd()

    if (!$.support.transition) return

    $.event.special.bsTransitionEnd = {
      bindType: $.support.transition.end,
      delegateType: $.support.transition.end,
      handle: function (e) {
        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
      }
    }
  })

}(jQuery);

/*! Select2 4.0.0 | https://github.com/select2/select2/blob/master/LICENSE.md */!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){var b=function(){if(a&&a.fn&&a.fn.select2&&a.fn.select2.amd)var b=a.fn.select2.amd;var b;return function(){if(!b||!b.requirejs){b?c=b:b={};var a,c,d;!function(b){function e(a,b){return u.call(a,b)}function f(a,b){var c,d,e,f,g,h,i,j,k,l,m,n=b&&b.split("/"),o=s.map,p=o&&o["*"]||{};if(a&&"."===a.charAt(0))if(b){for(n=n.slice(0,n.length-1),a=a.split("/"),g=a.length-1,s.nodeIdCompat&&w.test(a[g])&&(a[g]=a[g].replace(w,"")),a=n.concat(a),k=0;k<a.length;k+=1)if(m=a[k],"."===m)a.splice(k,1),k-=1;else if(".."===m){if(1===k&&(".."===a[2]||".."===a[0]))break;k>0&&(a.splice(k-1,2),k-=2)}a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if((n||p)&&o){for(c=a.split("/"),k=c.length;k>0;k-=1){if(d=c.slice(0,k).join("/"),n)for(l=n.length;l>0;l-=1)if(e=o[n.slice(0,l).join("/")],e&&(e=e[d])){f=e,h=k;break}if(f)break;!i&&p&&p[d]&&(i=p[d],j=k)}!f&&i&&(f=i,h=j),f&&(c.splice(0,h,f),a=c.join("/"))}return a}function g(a,c){return function(){return n.apply(b,v.call(arguments,0).concat([a,c]))}}function h(a){return function(b){return f(b,a)}}function i(a){return function(b){q[a]=b}}function j(a){if(e(r,a)){var c=r[a];delete r[a],t[a]=!0,m.apply(b,c)}if(!e(q,a)&&!e(t,a))throw new Error("No "+a);return q[a]}function k(a){var b,c=a?a.indexOf("!"):-1;return c>-1&&(b=a.substring(0,c),a=a.substring(c+1,a.length)),[b,a]}function l(a){return function(){return s&&s.config&&s.config[a]||{}}}var m,n,o,p,q={},r={},s={},t={},u=Object.prototype.hasOwnProperty,v=[].slice,w=/\.js$/;o=function(a,b){var c,d=k(a),e=d[0];return a=d[1],e&&(e=f(e,b),c=j(e)),e?a=c&&c.normalize?c.normalize(a,h(b)):f(a,b):(a=f(a,b),d=k(a),e=d[0],a=d[1],e&&(c=j(e))),{f:e?e+"!"+a:a,n:a,pr:e,p:c}},p={require:function(a){return g(a)},exports:function(a){var b=q[a];return"undefined"!=typeof b?b:q[a]={}},module:function(a){return{id:a,uri:"",exports:q[a],config:l(a)}}},m=function(a,c,d,f){var h,k,l,m,n,s,u=[],v=typeof d;if(f=f||a,"undefined"===v||"function"===v){for(c=!c.length&&d.length?["require","exports","module"]:c,n=0;n<c.length;n+=1)if(m=o(c[n],f),k=m.f,"require"===k)u[n]=p.require(a);else if("exports"===k)u[n]=p.exports(a),s=!0;else if("module"===k)h=u[n]=p.module(a);else if(e(q,k)||e(r,k)||e(t,k))u[n]=j(k);else{if(!m.p)throw new Error(a+" missing "+k);m.p.load(m.n,g(f,!0),i(k),{}),u[n]=q[k]}l=d?d.apply(q[a],u):void 0,a&&(h&&h.exports!==b&&h.exports!==q[a]?q[a]=h.exports:l===b&&s||(q[a]=l))}else a&&(q[a]=d)},a=c=n=function(a,c,d,e,f){if("string"==typeof a)return p[a]?p[a](c):j(o(a,c).f);if(!a.splice){if(s=a,s.deps&&n(s.deps,s.callback),!c)return;c.splice?(a=c,c=d,d=null):a=b}return c=c||function(){},"function"==typeof d&&(d=e,e=f),e?m(b,a,c,d):setTimeout(function(){m(b,a,c,d)},4),n},n.config=function(a){return n(a)},a._defined=q,d=function(a,b,c){b.splice||(c=b,b=[]),e(q,a)||e(r,a)||(r[a]=[a,b,c])},d.amd={jQuery:!0}}(),b.requirejs=a,b.require=c,b.define=d}}(),b.define("almond",function(){}),b.define("jquery",[],function(){var b=a||$;return null==b&&console&&console.error&&console.error("Select2: An instance of jQuery or a jQuery-compatible library was not found. Make sure that you are including jQuery before Select2 on your web page."),b}),b.define("select2/utils",["jquery"],function(a){function b(a){var b=a.prototype,c=[];for(var d in b){var e=b[d];"function"==typeof e&&"constructor"!==d&&c.push(d)}return c}var c={};c.Extend=function(a,b){function c(){this.constructor=a}var d={}.hasOwnProperty;for(var e in b)d.call(b,e)&&(a[e]=b[e]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a},c.Decorate=function(a,c){function d(){var b=Array.prototype.unshift,d=c.prototype.constructor.length,e=a.prototype.constructor;d>0&&(b.call(arguments,a.prototype.constructor),e=c.prototype.constructor),e.apply(this,arguments)}function e(){this.constructor=d}var f=b(c),g=b(a);c.displayName=a.displayName,d.prototype=new e;for(var h=0;h<g.length;h++){var i=g[h];d.prototype[i]=a.prototype[i]}for(var j=(function(a){var b=function(){};a in d.prototype&&(b=d.prototype[a]);var e=c.prototype[a];return function(){var a=Array.prototype.unshift;return a.call(arguments,b),e.apply(this,arguments)}}),k=0;k<f.length;k++){var l=f[k];d.prototype[l]=j(l)}return d};var d=function(){this.listeners={}};return d.prototype.on=function(a,b){this.listeners=this.listeners||{},a in this.listeners?this.listeners[a].push(b):this.listeners[a]=[b]},d.prototype.trigger=function(a){var b=Array.prototype.slice;this.listeners=this.listeners||{},a in this.listeners&&this.invoke(this.listeners[a],b.call(arguments,1)),"*"in this.listeners&&this.invoke(this.listeners["*"],arguments)},d.prototype.invoke=function(a,b){for(var c=0,d=a.length;d>c;c++)a[c].apply(this,b)},c.Observable=d,c.generateChars=function(a){for(var b="",c=0;a>c;c++){var d=Math.floor(36*Math.random());b+=d.toString(36)}return b},c.bind=function(a,b){return function(){a.apply(b,arguments)}},c._convertData=function(a){for(var b in a){var c=b.split("-"),d=a;if(1!==c.length){for(var e=0;e<c.length;e++){var f=c[e];f=f.substring(0,1).toLowerCase()+f.substring(1),f in d||(d[f]={}),e==c.length-1&&(d[f]=a[b]),d=d[f]}delete a[b]}}return a},c.hasScroll=function(b,c){var d=a(c),e=c.style.overflowX,f=c.style.overflowY;return e!==f||"hidden"!==f&&"visible"!==f?"scroll"===e||"scroll"===f?!0:d.innerHeight()<c.scrollHeight||d.innerWidth()<c.scrollWidth:!1},c.escapeMarkup=function(a){var b={"\\":"&#92;","&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#47;"};return"string"!=typeof a?a:String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})},c.appendMany=function(b,c){if("1.7"===a.fn.jquery.substr(0,3)){var d=a();a.map(c,function(a){d=d.add(a)}),c=d}b.append(c)},c}),b.define("select2/results",["jquery","./utils"],function(a,b){function c(a,b,d){this.$element=a,this.data=d,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<ul class="select2-results__options" role="tree"></ul>');return this.options.get("multiple")&&b.attr("aria-multiselectable","true"),this.$results=b,b},c.prototype.clear=function(){this.$results.empty()},c.prototype.displayMessage=function(b){var c=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var d=a('<li role="treeitem" class="select2-results__option"></li>'),e=this.options.get("translations").get(b.message);d.append(c(e(b.args))),this.$results.append(d)},c.prototype.append=function(a){this.hideLoading();var b=[];if(null==a.results||0===a.results.length)return void(0===this.$results.children().length&&this.trigger("results:message",{message:"noResults"}));a.results=this.sort(a.results);for(var c=0;c<a.results.length;c++){var d=a.results[c],e=this.option(d);b.push(e)}this.$results.append(b)},c.prototype.position=function(a,b){var c=b.find(".select2-results");c.append(a)},c.prototype.sort=function(a){var b=this.options.get("sorter");return b(a)},c.prototype.setClasses=function(){var b=this;this.data.current(function(c){var d=a.map(c,function(a){return a.id.toString()}),e=b.$results.find(".select2-results__option[aria-selected]");e.each(function(){var b=a(this),c=a.data(this,"data"),e=""+c.id;null!=c.element&&c.element.selected||null==c.element&&a.inArray(e,d)>-1?b.attr("aria-selected","true"):b.attr("aria-selected","false")});var f=e.filter("[aria-selected=true]");f.length>0?f.first().trigger("mouseenter"):e.first().trigger("mouseenter")})},c.prototype.showLoading=function(a){this.hideLoading();var b=this.options.get("translations").get("searching"),c={disabled:!0,loading:!0,text:b(a)},d=this.option(c);d.className+=" loading-results",this.$results.prepend(d)},c.prototype.hideLoading=function(){this.$results.find(".loading-results").remove()},c.prototype.option=function(b){var c=document.createElement("li");c.className="select2-results__option";var d={role:"treeitem","aria-selected":"false"};b.disabled&&(delete d["aria-selected"],d["aria-disabled"]="true"),null==b.id&&delete d["aria-selected"],null!=b._resultId&&(c.id=b._resultId),b.title&&(c.title=b.title),b.children&&(d.role="group",d["aria-label"]=b.text,delete d["aria-selected"]);for(var e in d){var f=d[e];c.setAttribute(e,f)}if(b.children){var g=a(c),h=document.createElement("strong");h.className="select2-results__group";{a(h)}this.template(b,h);for(var i=[],j=0;j<b.children.length;j++){var k=b.children[j],l=this.option(k);i.push(l)}var m=a("<ul></ul>",{"class":"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b){var c=this,d=b.id+"-results";this.$results.attr("id",d),b.on("results:all",function(a){c.clear(),c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("results:append",function(a){c.append(a.data),b.isOpen()&&c.setClasses()}),b.on("query",function(a){c.showLoading(a)}),b.on("select",function(){b.isOpen()&&c.setClasses()}),b.on("unselect",function(){b.isOpen()&&c.setClasses()}),b.on("open",function(){c.$results.attr("aria-expanded","true"),c.$results.attr("aria-hidden","false"),c.setClasses(),c.ensureHighlightVisible()}),b.on("close",function(){c.$results.attr("aria-expanded","false"),c.$results.attr("aria-hidden","true"),c.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=c.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=c.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?c.trigger("close"):c.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a);if(0!==d){var e=d-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top,h=f.offset().top,i=c.$results.scrollTop()+(h-g);0===e?c.$results.scrollTop(0):0>h-g&&c.$results.scrollTop(i)}}),b.on("results:next",function(){var a=c.getHighlightedResults(),b=c.$results.find("[aria-selected]"),d=b.index(a),e=d+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=c.$results.offset().top+c.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=c.$results.scrollTop()+h-g;0===e?c.$results.scrollTop(0):h>g&&c.$results.scrollTop(i)}}),b.on("results:focus",function(a){a.element.addClass("select2-results__option--highlighted")}),b.on("results:message",function(a){c.displayMessage(a)}),a.fn.mousewheel&&this.$results.on("mousewheel",function(a){var b=c.$results.scrollTop(),d=c.$results.get(0).scrollHeight-c.$results.scrollTop()+a.deltaY,e=a.deltaY>0&&b-a.deltaY<=0,f=a.deltaY<0&&d<=c.$results.height();e?(c.$results.scrollTop(0),a.preventDefault(),a.stopPropagation()):f&&(c.$results.scrollTop(c.$results.get(0).scrollHeight-c.$results.height()),a.preventDefault(),a.stopPropagation())}),this.$results.on("mouseup",".select2-results__option[aria-selected]",function(b){var d=a(this),e=d.data("data");return"true"===d.attr("aria-selected")?void(c.options.get("multiple")?c.trigger("unselect",{originalEvent:b,data:e}):c.trigger("close")):void c.trigger("select",{originalEvent:b,data:e})}),this.$results.on("mouseenter",".select2-results__option[aria-selected]",function(){var b=a(this).data("data");c.getHighlightedResults().removeClass("select2-results__option--highlighted"),c.trigger("results:focus",{data:b,element:a(this)})})},c.prototype.getHighlightedResults=function(){var a=this.$results.find(".select2-results__option--highlighted");return a},c.prototype.destroy=function(){this.$results.remove()},c.prototype.ensureHighlightVisible=function(){var a=this.getHighlightedResults();if(0!==a.length){var b=this.$results.find("[aria-selected]"),c=b.index(a),d=this.$results.offset().top,e=a.offset().top,f=this.$results.scrollTop()+(e-d),g=e-d;f-=2*a.outerHeight(!1),2>=c?this.$results.scrollTop(0):(g>this.$results.outerHeight()||0>g)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){var a={BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46};return a}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('<span class="select2-selection" role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-expanded="false"></span>');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b,b},d.prototype.bind=function(a){var b=this,d=(a.id+"-container",a.id+"-results");this.container=a,this.$selection.on("focus",function(a){b.trigger("focus",a)}),this.$selection.on("blur",function(a){b.trigger("blur",a)}),this.$selection.on("keydown",function(a){b.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){b.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){b.update(a.data)}),a.on("open",function(){b.$selection.attr("aria-expanded","true"),b.$selection.attr("aria-owns",d),b._attachCloseHandler(a)}),a.on("close",function(){b.$selection.attr("aria-expanded","false"),b.$selection.removeAttr("aria-activedescendant"),b.$selection.removeAttr("aria-owns"),b.$selection.focus(),b._detachCloseHandler(a)}),a.on("enable",function(){b.$selection.attr("tabindex",b._tabindex)}),a.on("disable",function(){b.$selection.attr("tabindex","-1")})},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var c=a(b.target),d=c.closest(".select2"),e=a(".select2.select2-container--open");e.each(function(){var b=a(this);if(this!=d[0]){var c=b.data("element");c.select2("close")}})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){var c=b.find(".selection");c.append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html('<span class="select2-selection__rendered"></span><span class="select2-selection__arrow" role="presentation"><b role="presentation"></b></span>'),a},d.prototype.bind=function(a){var b=this;d.__super__.bind.apply(this,arguments);var c=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",c),this.$selection.attr("aria-labelledby",c),this.$selection.on("mousedown",function(a){1===a.which&&b.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(){}),this.$selection.on("blur",function(){}),a.on("selection:update",function(a){b.update(a.data)})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){return a("<span></span>")},d.prototype.update=function(a){if(0===a.length)return void this.clear();var b=a[0],c=this.display(b),d=this.$selection.find(".select2-selection__rendered");d.empty().append(c),d.prop("title",b.title||b.text)},d}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('<ul class="select2-selection__rendered"></ul>'),a},d.prototype.bind=function(){var b=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){b.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(c){var d=a(this),e=d.parent(),f=e.data("data");b.trigger("unselect",{originalEvent:c,data:f})})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a){var b=this.options.get("templateSelection"),c=this.options.get("escapeMarkup");return c(b(a))},d.prototype.selectionContainer=function(){var b=a('<li class="select2-selection__choice"><span class="select2-selection__choice__remove" role="presentation">&times;</span></li>');return b},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d<a.length;d++){var e=a[d],f=this.display(e),g=this.selectionContainer();g.append(f),g.prop("title",e.title||e.text),g.data("data",e),b.push(g)}var h=this.$selection.find(".select2-selection__rendered");c.appendMany(h,b)}},d}),b.define("select2/selection/placeholder",["../utils"],function(){function a(a,b,c){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c)}return a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.createPlaceholder=function(a,b){var c=this.selectionContainer();return c.html(this.display(b)),c.addClass("select2-selection__placeholder").removeClass("select2-selection__choice"),c},a.prototype.update=function(a,b){var c=1==b.length&&b[0].id!=this.placeholder.id,d=b.length>1;if(d||c)return a.call(this,b);this.clear();var e=this.createPlaceholder(this.placeholder);this.$selection.find(".select2-selection__rendered").append(e)},a}),b.define("select2/selection/allowClear",["jquery","../keys"],function(a,b){function c(){}return c.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),null==this.placeholder&&this.options.get("debug")&&window.console&&console.error&&console.error("Select2: The `allowClear` option should be used in combination with the `placeholder` option."),this.$selection.on("mousedown",".select2-selection__clear",function(a){d._handleClear(a)}),b.on("keypress",function(a){d._handleKeyboardClear(a,b)})},c.prototype._handleClear=function(a,b){if(!this.options.get("disabled")){var c=this.$selection.find(".select2-selection__clear");if(0!==c.length){b.stopPropagation();for(var d=c.data("data"),e=0;e<d.length;e++){var f={data:d[e]};if(this.trigger("unselect",f),f.prevented)return}this.$element.val(this.placeholder.id).trigger("change"),this.trigger("toggle")}}},c.prototype._handleKeyboardClear=function(a,c,d){d.isOpen()||(c.which==b.DELETE||c.which==b.BACKSPACE)&&this._handleClear(c)},c.prototype.update=function(b,c){if(b.call(this,c),!(this.$selection.find(".select2-selection__placeholder").length>0||0===c.length)){var d=a('<span class="select2-selection__clear">&times;</span>');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('<li class="select2-search select2-search--inline"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></li>');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus()}),b.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val(""),e.$search.focus()}),b.on("enable",function(){e.$search.prop("disabled",!1)}),b.on("disable",function(){e.$search.prop("disabled",!0)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e.trigger("blur",a)}),this.$selection.on("keydown",".select2-search--inline",function(a){a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented();var b=a.which;if(b===c.BACKSPACE&&""===e.$search.val()){var d=e.$searchContainer.prev(".select2-selection__choice");if(d.length>0){var f=d.data("data");e.searchRemoveChoice(f),a.preventDefault()}}}),this.$selection.on("input",".select2-search--inline",function(){e.$selection.off("keyup.search")}),this.$selection.on("keyup.search input",".select2-search--inline",function(a){e.handleSearch(a)})},d.prototype.createPlaceholder=function(a,b){this.$search.attr("placeholder",b.text)},d.prototype.update=function(a,b){this.$search.attr("placeholder",""),a.call(this,b),this.$selection.find(".select2-selection__rendered").append(this.$searchContainer),this.resizeSearch()},d.prototype.handleSearch=function(){if(this.resizeSearch(),!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},d.prototype.searchRemoveChoice=function(a,b){this.trigger("unselect",{data:b}),this.trigger("open"),this.$search.val(b.text+" ")},d.prototype.resizeSearch=function(){this.$search.css("width","25px");var a="";if(""!==this.$search.attr("placeholder"))a=this.$selection.find(".select2-selection__rendered").innerWidth();else{var b=this.$search.val().length+1;a=.75*b+"em"}this.$search.css("width",a)},d}),b.define("select2/selection/eventRelay",["jquery"],function(a){function b(){}return b.prototype.bind=function(b,c,d){var e=this,f=["open","opening","close","closing","select","selecting","unselect","unselecting"],g=["opening","closing","selecting","unselecting"];b.call(this,c,d),c.on("*",function(b,c){if(-1!==a.inArray(b,f)){c=c||{};var d=a.Event("select2:"+b,{params:c});e.$element.trigger(d),-1!==a.inArray(b,g)&&(c.prevented=d.isDefaultPrevented())}})},b}),b.define("select2/translation",["jquery","require"],function(a,b){function c(a){this.dict=a||{}}return c.prototype.all=function(){return this.dict},c.prototype.get=function(a){return this.dict[a]},c.prototype.extend=function(b){this.dict=a.extend({},b.all(),this.dict)},c._cache={},c.loadPath=function(a){if(!(a in c._cache)){var d=b(a);c._cache[a]=d}return new c(c._cache[a])},c}),b.define("select2/diacritics",[],function(){var a={"Ⓐ":"A","Ａ":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","Ｂ":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","Ｃ":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","Ｄ":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","Ǳ":"DZ","Ǆ":"DZ","ǲ":"Dz","ǅ":"Dz","Ⓔ":"E","Ｅ":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","Ｆ":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","Ｇ":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","Ｈ":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","Ｉ":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","Ｊ":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","Ｋ":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","Ｌ":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","Ǉ":"LJ","ǈ":"Lj","Ⓜ":"M","Ｍ":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","Ｎ":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","Ǌ":"NJ","ǋ":"Nj","Ⓞ":"O","Ｏ":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","Ｐ":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Ｑ":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","Ｒ":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","Ｓ":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","Ｔ":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","Ｕ":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","Ｖ":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","Ｗ":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","Ｘ":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Ｙ":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Ｚ":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","ａ":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","ｂ":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","ｃ":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","ｄ":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","ǳ":"dz","ǆ":"dz","ⓔ":"e","ｅ":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","ｆ":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","ｇ":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","ｈ":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","ｉ":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","ｊ":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","ｋ":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","ｌ":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","ǉ":"lj","ⓜ":"m","ｍ":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","ｎ":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ŉ":"n","ꞑ":"n","ꞥ":"n","ǌ":"nj","ⓞ":"o","ｏ":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","ｐ":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","ｑ":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","ｒ":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","ｓ":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","ｔ":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","ｕ":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","ｖ":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","ｗ":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","ｘ":"x","ẋ":"x","ẍ":"x","ⓨ":"y","ｙ":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","ｚ":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};return a}),b.define("select2/data/base",["../utils"],function(a){function b(){b.__super__.constructor.call(this)}return a.Extend(b,a.Observable),b.prototype.current=function(){throw new Error("The `current` method must be defined in child classes.")},b.prototype.query=function(){throw new Error("The `query` method must be defined in child classes.")},b.prototype.bind=function(){},b.prototype.destroy=function(){},b.prototype.generateResultId=function(b,c){var d=b.id+"-result-";return d+=a.generateChars(4),d+=null!=c.id?"-"+c.id.toString():"-"+a.generateChars(4)},b}),b.define("select2/data/select",["./base","../utils","jquery"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,a),d.prototype.current=function(a){var b=[],d=this;this.$element.find(":selected").each(function(){var a=c(this),e=d.item(a);b.push(e)}),a(b)},d.prototype.select=function(a){var b=this;if(a.selected=!0,c(a.element).is("option"))return a.element.selected=!0,void this.$element.trigger("change");if(this.$element.prop("multiple"))this.current(function(d){var e=[];a=[a],a.push.apply(a,d);for(var f=0;f<a.length;f++){var g=a[f].id;-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")});else{var d=a.id;this.$element.val(d),this.$element.trigger("change")}},d.prototype.unselect=function(a){var b=this;if(this.$element.prop("multiple"))return a.selected=!1,c(a.element).is("option")?(a.element.selected=!1,void this.$element.trigger("change")):void this.current(function(d){for(var e=[],f=0;f<d.length;f++){var g=d[f].id;g!==a.id&&-1===c.inArray(g,e)&&e.push(g)}b.$element.val(e),b.$element.trigger("change")})},d.prototype.bind=function(a){var b=this;this.container=a,a.on("select",function(a){b.select(a.data)}),a.on("unselect",function(a){b.unselect(a.data)})},d.prototype.destroy=function(){this.$element.find("*").each(function(){c.removeData(this,"data")})},d.prototype.query=function(a,b){var d=[],e=this,f=this.$element.children();f.each(function(){var b=c(this);if(b.is("option")||b.is("optgroup")){var f=e.item(b),g=e.matches(a,f);null!==g&&d.push(g)}}),b({results:d})},d.prototype.addOptions=function(a){b.appendMany(this.$element,a)},d.prototype.option=function(a){var b;a.children?(b=document.createElement("optgroup"),b.label=a.text):(b=document.createElement("option"),void 0!==b.textContent?b.textContent=a.text:b.innerText=a.text),a.id&&(b.value=a.id),a.disabled&&(b.disabled=!0),a.selected&&(b.selected=!0),a.title&&(b.title=a.title);var d=c(b),e=this._normalizeItem(a);return e.element=b,c.data(b,"data",e),d},d.prototype.item=function(a){var b={};
if(b=c.data(a[0],"data"),null!=b)return b;if(a.is("option"))b={id:a.val(),text:a.text(),disabled:a.prop("disabled"),selected:a.prop("selected"),title:a.prop("title")};else if(a.is("optgroup")){b={text:a.prop("label"),children:[],title:a.prop("title")};for(var d=a.children("option"),e=[],f=0;f<d.length;f++){var g=c(d[f]),h=this.item(g);e.push(h)}b.children=e}return b=this._normalizeItem(b),b.element=a[0],c.data(a[0],"data",b),b},d.prototype._normalizeItem=function(a){c.isPlainObject(a)||(a={id:a,text:a}),a=c.extend({},{text:""},a);var b={selected:!1,disabled:!1};return null!=a.id&&(a.id=a.id.toString()),null!=a.text&&(a.text=a.text.toString()),null==a._resultId&&a.id&&null!=this.container&&(a._resultId=this.generateResultId(this.container,a)),c.extend({},b,a)},d.prototype.matches=function(a,b){var c=this.options.get("matcher");return c(a,b)},d}),b.define("select2/data/array",["./select","../utils","jquery"],function(a,b,c){function d(a,b){var c=b.get("data")||[];d.__super__.constructor.call(this,a,b),this.addOptions(this.convertToOptions(c))}return b.Extend(d,a),d.prototype.select=function(a){var b=this.$element.find("option").filter(function(b,c){return c.value==a.id.toString()});0===b.length&&(b=this.option(a),this.addOptions(b)),d.__super__.select.call(this,a)},d.prototype.convertToOptions=function(a){function d(a){return function(){return c(this).val()==a.id}}for(var e=this,f=this.$element.find("option"),g=f.map(function(){return e.item(c(this)).id}).get(),h=[],i=0;i<a.length;i++){var j=this._normalizeItem(a[i]);if(c.inArray(j.id,g)>=0){var k=f.filter(d(j)),l=this.item(k),m=(c.extend(!0,{},l,j),this.option(l));k.replaceWith(m)}else{var n=this.option(j);if(j.children){var o=this.convertToOptions(j.children);b.appendMany(n,o)}h.push(n)}}return h},d}),b.define("select2/data/ajax",["./array","../utils","jquery"],function(a,b,c){function d(b,c){this.ajaxOptions=this._applyDefaults(c.get("ajax")),null!=this.ajaxOptions.processResults&&(this.processResults=this.ajaxOptions.processResults),a.__super__.constructor.call(this,b,c)}return b.Extend(d,a),d.prototype._applyDefaults=function(a){var b={data:function(a){return{q:a.term}},transport:function(a,b,d){var e=c.ajax(a);return e.then(b),e.fail(d),e}};return c.extend({},b,a,!0)},d.prototype.processResults=function(a){return a},d.prototype.query=function(a,b){function d(){var d=f.transport(f,function(d){var f=e.processResults(d,a);e.options.get("debug")&&window.console&&console.error&&(f&&f.results&&c.isArray(f.results)||console.error("Select2: The AJAX results did not return an array in the `results` key of the response.")),b(f)},function(){});e._request=d}var e=this;null!=this._request&&(c.isFunction(this._request.abort)&&this._request.abort(),this._request=null);var f=c.extend({type:"GET"},this.ajaxOptions);"function"==typeof f.url&&(f.url=f.url(a)),"function"==typeof f.data&&(f.data=f.data(a)),this.ajaxOptions.delay&&""!==a.term?(this._queryTimeout&&window.clearTimeout(this._queryTimeout),this._queryTimeout=window.setTimeout(d,this.ajaxOptions.delay)):d()},d}),b.define("select2/data/tags",["jquery"],function(a){function b(b,c,d){var e=d.get("tags"),f=d.get("createTag");if(void 0!==f&&(this.createTag=f),b.call(this,c,d),a.isArray(e))for(var g=0;g<e.length;g++){var h=e[g],i=this._normalizeItem(h),j=this.option(i);this.$element.append(j)}}return b.prototype.query=function(a,b,c){function d(a,f){for(var g=a.results,h=0;h<g.length;h++){var i=g[h],j=null!=i.children&&!d({results:i.children},!0),k=i.text===b.term;if(k||j)return f?!1:(a.data=g,void c(a))}if(f)return!0;var l=e.createTag(b);if(null!=l){var m=e.option(l);m.attr("data-select2-tag",!0),e.addOptions([m]),e.insertTag(g,l)}a.results=g,c(a)}var e=this;return this._removeOldTags(),null==b.term||null!=b.page?void a.call(this,b,c):void a.call(this,b,d)},b.prototype.createTag=function(b,c){var d=a.trim(c.term);return""===d?null:{id:d,text:d}},b.prototype.insertTag=function(a,b,c){b.unshift(c)},b.prototype._removeOldTags=function(){var b=(this._lastTag,this.$element.find("option[data-select2-tag]"));b.each(function(){this.selected||a(this).remove()})},b}),b.define("select2/data/tokenizer",["jquery"],function(a){function b(a,b,c){var d=c.get("tokenizer");void 0!==d&&(this.tokenizer=d),a.call(this,b,c)}return b.prototype.bind=function(a,b,c){a.call(this,b,c),this.$search=b.dropdown.$search||b.selection.$search||c.find(".select2-search__field")},b.prototype.query=function(a,b,c){function d(a){e.select(a)}var e=this;b.term=b.term||"";var f=this.tokenizer(b,this.options,d);f.term!==b.term&&(this.$search.length&&(this.$search.val(f.term),this.$search.focus()),b.term=f.term),a.call(this,b,c)},b.prototype.tokenizer=function(b,c,d,e){for(var f=d.get("tokenSeparators")||[],g=c.term,h=0,i=this.createTag||function(a){return{id:a.term,text:a.term}};h<g.length;){var j=g[h];if(-1!==a.inArray(j,f)){var k=g.substr(0,h),l=a.extend({},c,{term:k}),m=i(l);e(m),g=g.substr(h+1)||"",h=0}else h++}return{term:g}},b}),b.define("select2/data/minimumInputLength",[],function(){function a(a,b,c){this.minimumInputLength=c.get("minimumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",b.term.length<this.minimumInputLength?void this.trigger("results:message",{message:"inputTooShort",args:{minimum:this.minimumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumInputLength",[],function(){function a(a,b,c){this.maximumInputLength=c.get("maximumInputLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){return b.term=b.term||"",this.maximumInputLength>0&&b.term.length>this.maximumInputLength?void this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):void a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;return d.maximumSelectionLength>0&&f>=d.maximumSelectionLength?void d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):void a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('<span class="select2-dropdown"><span class="select2-results"></span></span>');return b.attr("dir",this.options.get("dir")),this.$dropdown=b,b},c.prototype.position=function(){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a){function b(){}return b.prototype.render=function(b){var c=b.call(this),d=a('<span class="select2-search select2-search--dropdown"><input class="select2-search__field" type="search" tabindex="-1" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" role="textbox" /></span>');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("results:all",function(a){if(null==a.query.term||""===a.query.term){var b=e.showSearch(a);b?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide")}})},b.prototype.handleSearch=function(){if(!this._keyUpPrevented){var a=this.$search.val();this.trigger("query",{term:a})}this._keyUpPrevented=!1},b.prototype.showSearch=function(){return!0},b}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;d>=0;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);if(!e.loading&&b){var c=e.$results.offset().top+e.$results.outerHeight(!1),d=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1);c+50>=d&&e.loadMore()}})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('<li class="option load-more" role="treeitem"></li>'),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(a,b,c){this.$dropdownParent=c.get("dropdownParent")||document.body,a.call(this,b,c)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a("<span></span>"),d=b.call(this);return c.append(d),this.$dropdownContainer=c,c},c.prototype._hideDropdown=function(){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c){var d=this,e="scroll.select2."+c.id,f="resize.select2."+c.id,g="orientationchange.select2."+c.id,h=this.$container.parents().filter(b.hasScroll);h.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),h.on(e,function(){var b=a(this).data("select2-scroll-position");a(this).scrollTop(b.y)}),a(window).on(e+" "+f+" "+g,function(){d._positionDropdown(),d._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c){var d="scroll.select2."+c.id,e="resize.select2."+c.id,f="orientationchange.select2."+c.id,g=this.$container.parents().filter(b.hasScroll);g.off(d),a(window).off(d+" "+e+" "+f)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=(this.$container.position(),this.$container.offset());f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h={height:this.$dropdown.outerHeight(!1)},i={top:b.scrollTop(),bottom:b.scrollTop()+b.height()},j=i.top<f.top-h.height,k=i.bottom>f.bottom+h.height,l={left:f.left,top:g.bottom};c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-h.height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){this.$dropdownContainer.width();var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function a(b){for(var c=0,d=0;d<b.length;d++){var e=b[d];e.children?c+=a(e.children):c++}return c}function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return a(c.data.results)<this.minimumResultsForSearch?!1:b.call(this,c)},b}),b.define("select2/dropdown/selectOnClose",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("close",function(){d._handleSelectOnClose()})},a.prototype._handleSelectOnClose=function(){var a=this.getHighlightedResults();a.length<1||this.trigger("select",{data:a.data("data")})},a}),b.define("select2/dropdown/closeOnSelect",[],function(){function a(){}return a.prototype.bind=function(a,b,c){var d=this;a.call(this,b,c),b.on("select",function(a){d._selectTriggered(a)}),b.on("unselect",function(a){d._selectTriggered(a)})},a.prototype._selectTriggered=function(a,b){var c=b.originalEvent;c&&c.ctrlKey||this.trigger("close")},a}),b.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(a){var b=a.input.length-a.maximum,c="Please delete "+b+" character";return 1!=b&&(c+="s"),c},inputTooShort:function(a){var b=a.minimum-a.input.length,c="Please enter "+b+" or more characters";return c},loadingMore:function(){return"Loading more results…"},maximumSelected:function(a){var b="You can only select "+a.maximum+" item";return 1!=a.maximum&&(b+="s"),b},noResults:function(){return"No results found"},searching:function(){return"Searching…"}}}),b.define("select2/defaults",["jquery","require","./results","./selection/single","./selection/multiple","./selection/placeholder","./selection/allowClear","./selection/search","./selection/eventRelay","./utils","./translation","./diacritics","./data/select","./data/array","./data/ajax","./data/tags","./data/tokenizer","./data/minimumInputLength","./data/maximumInputLength","./data/maximumSelectionLength","./dropdown","./dropdown/search","./dropdown/hidePlaceholder","./dropdown/infiniteScroll","./dropdown/attachBody","./dropdown/minimumResultsForSearch","./dropdown/selectOnClose","./dropdown/closeOnSelect","./i18n/en"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C){function D(){this.reset()}D.prototype.apply=function(l){if(l=a.extend({},this.defaults,l),null==l.dataAdapter){if(l.dataAdapter=null!=l.ajax?o:null!=l.data?n:m,l.minimumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,r)),l.maximumInputLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,s)),l.maximumSelectionLength>0&&(l.dataAdapter=j.Decorate(l.dataAdapter,t)),l.tags&&(l.dataAdapter=j.Decorate(l.dataAdapter,p)),(null!=l.tokenSeparators||null!=l.tokenizer)&&(l.dataAdapter=j.Decorate(l.dataAdapter,q)),null!=l.query){var C=b(l.amdBase+"compat/query");l.dataAdapter=j.Decorate(l.dataAdapter,C)}if(null!=l.initSelection){var D=b(l.amdBase+"compat/initSelection");l.dataAdapter=j.Decorate(l.dataAdapter,D)}}if(null==l.resultsAdapter&&(l.resultsAdapter=c,null!=l.ajax&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,x)),null!=l.placeholder&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,w)),l.selectOnClose&&(l.resultsAdapter=j.Decorate(l.resultsAdapter,A))),null==l.dropdownAdapter){if(l.multiple)l.dropdownAdapter=u;else{var E=j.Decorate(u,v);l.dropdownAdapter=E}if(0!==l.minimumResultsForSearch&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,z)),l.closeOnSelect&&(l.dropdownAdapter=j.Decorate(l.dropdownAdapter,B)),null!=l.dropdownCssClass||null!=l.dropdownCss||null!=l.adaptDropdownCssClass){var F=b(l.amdBase+"compat/dropdownCss");l.dropdownAdapter=j.Decorate(l.dropdownAdapter,F)}l.dropdownAdapter=j.Decorate(l.dropdownAdapter,y)}if(null==l.selectionAdapter){if(l.selectionAdapter=l.multiple?e:d,null!=l.placeholder&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,f)),l.allowClear&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,g)),l.multiple&&(l.selectionAdapter=j.Decorate(l.selectionAdapter,h)),null!=l.containerCssClass||null!=l.containerCss||null!=l.adaptContainerCssClass){var G=b(l.amdBase+"compat/containerCss");l.selectionAdapter=j.Decorate(l.selectionAdapter,G)}l.selectionAdapter=j.Decorate(l.selectionAdapter,i)}if("string"==typeof l.language)if(l.language.indexOf("-")>0){var H=l.language.split("-"),I=H[0];l.language=[l.language,I]}else l.language=[l.language];if(a.isArray(l.language)){var J=new k;l.language.push("en");for(var K=l.language,L=0;L<K.length;L++){var M=K[L],N={};try{N=k.loadPath(M)}catch(O){try{M=this.defaults.amdLanguageBase+M,N=k.loadPath(M)}catch(P){l.debug&&window.console&&console.warn&&console.warn('Select2: The language file for "'+M+'" could not be automatically loaded. A fallback will be used instead.');continue}}J.extend(N)}l.translations=J}else{var Q=k.loadPath(this.defaults.amdLanguageBase+"en"),R=new k(l.language);R.extend(Q),l.translations=R}return l},D.prototype.reset=function(){function b(a){function b(a){return l[a]||a}return a.replace(/[^\u0000-\u007E]/g,b)}function c(d,e){if(""===a.trim(d.term))return e;if(e.children&&e.children.length>0){for(var f=a.extend(!0,{},e),g=e.children.length-1;g>=0;g--){var h=e.children[g],i=c(d,h);null==i&&f.children.splice(g,1)}return f.children.length>0?f:c(d,f)}var j=b(e.text).toUpperCase(),k=b(d.term).toUpperCase();return j.indexOf(k)>-1?e:null}this.defaults={amdBase:"./",amdLanguageBase:"./i18n/",closeOnSelect:!0,debug:!1,dropdownAutoWidth:!1,escapeMarkup:j.escapeMarkup,language:C,matcher:c,minimumInputLength:0,maximumInputLength:0,maximumSelectionLength:0,minimumResultsForSearch:0,selectOnClose:!1,sorter:function(a){return a},templateResult:function(a){return a.text},templateSelection:function(a){return a.text},theme:"default",width:"resolve"}},D.prototype.set=function(b,c){var d=a.camelCase(b),e={};e[d]=c;var f=j._convertData(e);a.extend(this.defaults,f)};var E=new D;return E}),b.define("select2/options",["require","jquery","./defaults","./utils"],function(a,b,c,d){function e(b,e){if(this.options=b,null!=e&&this.fromElement(e),this.options=c.apply(this.options),e&&e.is("input")){var f=a(this.get("amdBase")+"compat/inputData");this.options.dataAdapter=d.Decorate(this.options.dataAdapter,f)}}return e.prototype.fromElement=function(a){var c=["select2"];null==this.options.multiple&&(this.options.multiple=a.prop("multiple")),null==this.options.disabled&&(this.options.disabled=a.prop("disabled")),null==this.options.language&&(a.prop("lang")?this.options.language=a.prop("lang").toLowerCase():a.closest("[lang]").prop("lang")&&(this.options.language=a.closest("[lang]").prop("lang"))),null==this.options.dir&&(this.options.dir=a.prop("dir")?a.prop("dir"):a.closest("[dir]").prop("dir")?a.closest("[dir]").prop("dir"):"ltr"),a.prop("disabled",this.options.disabled),a.prop("multiple",this.options.multiple),a.data("select2Tags")&&(this.options.debug&&window.console&&console.warn&&console.warn('Select2: The `data-select2-tags` attribute has been changed to use the `data-data` and `data-tags="true"` attributes and will be removed in future versions of Select2.'),a.data("data",a.data("select2Tags")),a.data("tags",!0)),a.data("ajaxUrl")&&(this.options.debug&&window.console&&console.warn&&console.warn("Select2: The `data-ajax-url` attribute has been changed to `data-ajax--url` and support for the old attribute will be removed in future versions of Select2."),a.attr("ajax--url",a.data("ajaxUrl")),a.data("ajax--url",a.data("ajaxUrl")));var e={};e=b.fn.jquery&&"1."==b.fn.jquery.substr(0,2)&&a[0].dataset?b.extend(!0,{},a[0].dataset,a.data()):a.data();var f=b.extend(!0,{},e);f=d._convertData(f);for(var g in f)b.inArray(g,c)>-1||(b.isPlainObject(this.options[g])?b.extend(this.options[g],f[g]):this.options[g]=f[g]);return this},e.prototype.get=function(a){return this.options[a]},e.prototype.set=function(a,b){this.options[a]=b},e}),b.define("select2/core",["jquery","./options","./utils","./keys"],function(a,b,c,d){var e=function(a,c){null!=a.data("select2")&&a.data("select2").destroy(),this.$element=a,this.id=this._generateId(a),c=c||{},this.options=new b(c,a),e.__super__.constructor.call(this);var d=a.attr("tabindex")||0;a.data("old-tabindex",d),a.attr("tabindex","-1");var f=this.options.get("dataAdapter");this.dataAdapter=new f(a,this.options);var g=this.render();this._placeContainer(g);var h=this.options.get("selectionAdapter");this.selection=new h(a,this.options),this.$selection=this.selection.render(),this.selection.position(this.$selection,g);var i=this.options.get("dropdownAdapter");this.dropdown=new i(a,this.options),this.$dropdown=this.dropdown.render(),this.dropdown.position(this.$dropdown,g);var j=this.options.get("resultsAdapter");this.results=new j(a,this.options,this.dataAdapter),this.$results=this.results.render(),this.results.position(this.$results,this.$dropdown);var k=this;this._bindAdapters(),this._registerDomEvents(),this._registerDataEvents(),this._registerSelectionEvents(),this._registerDropdownEvents(),this._registerResultsEvents(),this._registerEvents(),this.dataAdapter.current(function(a){k.trigger("selection:update",{data:a})}),a.addClass("select2-hidden-accessible"),a.attr("aria-hidden","true"),this._syncAttributes(),a.data("select2",this)};return c.Extend(e,c.Observable),e.prototype._generateId=function(a){var b="";return b=null!=a.attr("id")?a.attr("id"):null!=a.attr("name")?a.attr("name")+"-"+c.generateChars(2):c.generateChars(4),b="select2-"+b},e.prototype._placeContainer=function(a){a.insertAfter(this.$element);var b=this._resolveWidth(this.$element,this.options.get("width"));null!=b&&a.css("width",b)},e.prototype._resolveWidth=function(a,b){var c=/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;if("resolve"==b){var d=this._resolveWidth(a,"style");return null!=d?d:this._resolveWidth(a,"element")}if("element"==b){var e=a.outerWidth(!1);return 0>=e?"auto":e+"px"}if("style"==b){var f=a.attr("style");if("string"!=typeof f)return null;for(var g=f.split(";"),h=0,i=g.length;i>h;h+=1){var j=g[h].replace(/\s/g,""),k=j.match(c);if(null!==k&&k.length>=1)return k[1]}return null}return b},e.prototype._bindAdapters=function(){this.dataAdapter.bind(this,this.$container),this.selection.bind(this,this.$container),this.dropdown.bind(this,this.$container),this.results.bind(this,this.$container)},e.prototype._registerDomEvents=function(){var b=this;this.$element.on("change.select2",function(){b.dataAdapter.current(function(a){b.trigger("selection:update",{data:a})})}),this._sync=c.bind(this._syncAttributes,this),this.$element[0].attachEvent&&this.$element[0].attachEvent("onpropertychange",this._sync);var d=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;null!=d?(this._observer=new d(function(c){a.each(c,b._sync)}),this._observer.observe(this.$element[0],{attributes:!0,subtree:!1})):this.$element[0].addEventListener&&this.$element[0].addEventListener("DOMAttrModified",b._sync,!1)},e.prototype._registerDataEvents=function(){var a=this;this.dataAdapter.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerSelectionEvents=function(){var b=this,c=["toggle"];this.selection.on("toggle",function(){b.toggleDropdown()}),this.selection.on("*",function(d,e){-1===a.inArray(d,c)&&b.trigger(d,e)})},e.prototype._registerDropdownEvents=function(){var a=this;this.dropdown.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerResultsEvents=function(){var a=this;this.results.on("*",function(b,c){a.trigger(b,c)})},e.prototype._registerEvents=function(){var a=this;this.on("open",function(){a.$container.addClass("select2-container--open")}),this.on("close",function(){a.$container.removeClass("select2-container--open")}),this.on("enable",function(){a.$container.removeClass("select2-container--disabled")}),this.on("disable",function(){a.$container.addClass("select2-container--disabled")}),this.on("focus",function(){a.$container.addClass("select2-container--focus")}),this.on("blur",function(){a.$container.removeClass("select2-container--focus")}),this.on("query",function(b){a.isOpen()||a.trigger("open"),this.dataAdapter.query(b,function(c){a.trigger("results:all",{data:c,query:b})})}),this.on("query:append",function(b){this.dataAdapter.query(b,function(c){a.trigger("results:append",{data:c,query:b})})}),this.on("keypress",function(b){var c=b.which;a.isOpen()?c===d.ENTER?(a.trigger("results:select"),b.preventDefault()):c===d.SPACE&&b.ctrlKey?(a.trigger("results:toggle"),b.preventDefault()):c===d.UP?(a.trigger("results:previous"),b.preventDefault()):c===d.DOWN?(a.trigger("results:next"),b.preventDefault()):(c===d.ESC||c===d.TAB)&&(a.close(),b.preventDefault()):(c===d.ENTER||c===d.SPACE||(c===d.DOWN||c===d.UP)&&b.altKey)&&(a.open(),b.preventDefault())})},e.prototype._syncAttributes=function(){this.options.set("disabled",this.$element.prop("disabled")),this.options.get("disabled")?(this.isOpen()&&this.close(),this.trigger("disable")):this.trigger("enable")},e.prototype.trigger=function(a,b){var c=e.__super__.trigger,d={open:"opening",close:"closing",select:"selecting",unselect:"unselecting"};if(a in d){var f=d[a],g={prevented:!1,name:a,args:b};if(c.call(this,f,g),g.prevented)return void(b.prevented=!0)}c.call(this,a,b)},e.prototype.toggleDropdown=function(){this.options.get("disabled")||(this.isOpen()?this.close():this.open())},e.prototype.open=function(){this.isOpen()||(this.trigger("query",{}),this.trigger("open"))},e.prototype.close=function(){this.isOpen()&&this.trigger("close")},e.prototype.isOpen=function(){return this.$container.hasClass("select2-container--open")},e.prototype.enable=function(a){this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("enable")` method has been deprecated and will be removed in later Select2 versions. Use $element.prop("disabled") instead.'),(null==a||0===a.length)&&(a=[!0]);var b=!a[0];this.$element.prop("disabled",b)},e.prototype.data=function(){this.options.get("debug")&&arguments.length>0&&window.console&&console.warn&&console.warn('Select2: Data can no longer be set using `select2("data")`. You should consider setting the value instead using `$element.val()`.');var a=[];return this.dataAdapter.current(function(b){a=b}),a},e.prototype.val=function(b){if(this.options.get("debug")&&window.console&&console.warn&&console.warn('Select2: The `select2("val")` method has been deprecated and will be removed in later Select2 versions. Use $element.val() instead.'),null==b||0===b.length)return this.$element.val();var c=b[0];a.isArray(c)&&(c=a.map(c,function(a){return a.toString()})),this.$element.val(c).trigger("change")},e.prototype.destroy=function(){this.$container.remove(),this.$element[0].detachEvent&&this.$element[0].detachEvent("onpropertychange",this._sync),null!=this._observer?(this._observer.disconnect(),this._observer=null):this.$element[0].removeEventListener&&this.$element[0].removeEventListener("DOMAttrModified",this._sync,!1),this._sync=null,this.$element.off(".select2"),this.$element.attr("tabindex",this.$element.data("old-tabindex")),this.$element.removeClass("select2-hidden-accessible"),this.$element.attr("aria-hidden","false"),this.$element.removeData("select2"),this.dataAdapter.destroy(),this.selection.destroy(),this.dropdown.destroy(),this.results.destroy(),this.dataAdapter=null,this.selection=null,this.dropdown=null,this.results=null},e.prototype.render=function(){var b=a('<span class="select2 select2-container"><span class="selection"></span><span class="dropdown-wrapper" aria-hidden="true"></span></span>');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){function b(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&(f=d(this),null!=f&&g.push(f))})),b.attr("class",g.join(" "))}return{syncCssClasses:b}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;return this._isInitialized?void b.call(this,c):void this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `<select>` element instead."),a.call(this,b,c)}return b.prototype.current=function(b,c){function d(b,c){var e=[];return b.selected||-1!==a.inArray(b.id,c)?(b.selected=!0,e.push(b)):b.selected=!1,b.children&&e.push.apply(e,d(b.children,c)),e}for(var e=[],f=0;f<this._currentData.length;f++){var g=this._currentData[f];e.push.apply(e,d(g,this.$element.val().split(this._valueSeparator)))}c(e)},b.prototype.select=function(b,c){if(this.options.get("multiple")){var d=this.$element.val();d+=this._valueSeparator+c.id,this.$element.val(d),this.$element.trigger("change")}else this.current(function(b){a.map(b,function(a){a.selected=!1})}),this.$element.val(c.id),this.$element.trigger("change")},b.prototype.unselect=function(a,b){var c=this;b.selected=!1,this.current(function(a){for(var d=[],e=0;e<a.length;e++){var f=a[e];
b.id!=f.id&&d.push(f.id)}c.$element.val(d.join(c._valueSeparator)),c.$element.trigger("change")})},b.prototype.query=function(a,b,c){for(var d=[],e=0;e<this._currentData.length;e++){var f=this._currentData[e],g=this.matches(b,f);null!==g&&d.push(g)}c({results:d})},b.prototype.addOptions=function(b,c){var d=a.map(c,function(b){return a.data(b[0],"data")});this._currentData.push.apply(this._currentData,d)},b}),b.define("select2/compat/matcher",["jquery"],function(a){function b(b){function c(c,d){var e=a.extend(!0,{},d);if(null==c.term||""===a.trim(c.term))return e;if(d.children){for(var f=d.children.length-1;f>=0;f--){var g=d.children[f],h=b(c.term,g.text,g);h||e.children.splice(f,1)}if(e.children.length>0)return e}return b(c.term,d.text,d)?e:null}return c}return b}),b.define("select2/compat/query",[],function(){function a(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `query` option has been deprecated in favor of a custom data adapter that overrides the `query` method. Support will be removed for the `query` option in future versions of Select2."),a.call(this,b,c)}return a.prototype.query=function(a,b,c){b.callback=c;var d=this.options.get("query");d.call(null,b)},a}),b.define("select2/dropdown/attachContainer",[],function(){function a(a,b,c){a.call(this,b,c)}return a.prototype.position=function(a,b,c){var d=c.find(".dropdown-wrapper");d.append(b),b.addClass("select2-dropdown--below"),c.addClass("select2-container--below")},a}),b.define("select2/dropdown/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$dropdown.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("select2/selection/stopPropagation",[],function(){function a(){}return a.prototype.bind=function(a,b,c){a.call(this,b,c);var d=["blur","change","click","dblclick","focus","focusin","focusout","input","keydown","keyup","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseover","mouseup","search","touchend","touchstart"];this.$selection.on(d.join(" "),function(a){a.stopPropagation()})},a}),b.define("jquery.select2",["jquery","require","./select2/core","./select2/defaults"],function(a,b,c,d){if(b("jquery.mousewheel"),null==a.fn.select2){var e=["open","close","destroy"];a.fn.select2=function(b){if(b=b||{},"object"==typeof b)return this.each(function(){{var d=a.extend({},b,!0);new c(a(this),d)}}),this;if("string"==typeof b){var d=this.data("select2");null==d&&window.console&&console.error&&console.error("The select2('"+b+"') method was called on an element that is not using Select2.");var f=Array.prototype.slice.call(arguments,1),g=d[b](f);return a.inArray(b,e)>-1?this:g}throw new Error("Invalid arguments for Select2: "+b)}}return null==a.fn.select2.defaults&&(a.fn.select2.defaults=d),c}),function(c){"function"==typeof b.define&&b.define.amd?b.define("jquery.mousewheel",["jquery"],c):"object"==typeof exports?module.exports=c:c(a)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b),d=c["offsetParent"in a.fn?"offsetParent":"parent"]();return d.length||(d=a("body")),parseInt(d.css("fontSize"),10)||parseInt(c.css("fontSize"),10)||16},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})}),{define:b.define,require:b.require}}(),c=b.require("jquery.select2");return a.fn.select2.amd=b,c});
/**!

 @license
 handlebars v4.5.3

Copyright (C) 2011-2017 by Yehuda Katz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["Handlebars"] = factory();
	else
		root["Handlebars"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _handlebarsRuntime = __webpack_require__(2);

	var _handlebarsRuntime2 = _interopRequireDefault(_handlebarsRuntime);

	// Compiler imports

	var _handlebarsCompilerAst = __webpack_require__(40);

	var _handlebarsCompilerAst2 = _interopRequireDefault(_handlebarsCompilerAst);

	var _handlebarsCompilerBase = __webpack_require__(41);

	var _handlebarsCompilerCompiler = __webpack_require__(46);

	var _handlebarsCompilerJavascriptCompiler = __webpack_require__(49);

	var _handlebarsCompilerJavascriptCompiler2 = _interopRequireDefault(_handlebarsCompilerJavascriptCompiler);

	var _handlebarsCompilerVisitor = __webpack_require__(44);

	var _handlebarsCompilerVisitor2 = _interopRequireDefault(_handlebarsCompilerVisitor);

	var _handlebarsNoConflict = __webpack_require__(39);

	var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);

	var _create = _handlebarsRuntime2['default'].create;
	function create() {
	  var hb = _create();

	  hb.compile = function (input, options) {
	    return _handlebarsCompilerCompiler.compile(input, options, hb);
	  };
	  hb.precompile = function (input, options) {
	    return _handlebarsCompilerCompiler.precompile(input, options, hb);
	  };

	  hb.AST = _handlebarsCompilerAst2['default'];
	  hb.Compiler = _handlebarsCompilerCompiler.Compiler;
	  hb.JavaScriptCompiler = _handlebarsCompilerJavascriptCompiler2['default'];
	  hb.Parser = _handlebarsCompilerBase.parser;
	  hb.parse = _handlebarsCompilerBase.parse;
	  hb.parseWithoutProcessing = _handlebarsCompilerBase.parseWithoutProcessing;

	  return hb;
	}

	var inst = create();
	inst.create = create;

	_handlebarsNoConflict2['default'](inst);

	inst.Visitor = _handlebarsCompilerVisitor2['default'];

	inst['default'] = inst;

	exports['default'] = inst;
	module.exports = exports['default'];

/***/ }),
/* 1 */
/***/ (function(module, exports) {

	"use strict";

	exports["default"] = function (obj) {
	  return obj && obj.__esModule ? obj : {
	    "default": obj
	  };
	};

	exports.__esModule = true;

/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireWildcard = __webpack_require__(3)['default'];

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _handlebarsBase = __webpack_require__(4);

	var base = _interopRequireWildcard(_handlebarsBase);

	// Each of these augment the Handlebars object. No need to setup here.
	// (This is done to easily share code between commonjs and browse envs)

	var _handlebarsSafeString = __webpack_require__(33);

	var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString);

	var _handlebarsException = __webpack_require__(6);

	var _handlebarsException2 = _interopRequireDefault(_handlebarsException);

	var _handlebarsUtils = __webpack_require__(5);

	var Utils = _interopRequireWildcard(_handlebarsUtils);

	var _handlebarsRuntime = __webpack_require__(34);

	var runtime = _interopRequireWildcard(_handlebarsRuntime);

	var _handlebarsNoConflict = __webpack_require__(39);

	var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);

	// For compatibility and usage outside of module systems, make the Handlebars object a namespace
	function create() {
	  var hb = new base.HandlebarsEnvironment();

	  Utils.extend(hb, base);
	  hb.SafeString = _handlebarsSafeString2['default'];
	  hb.Exception = _handlebarsException2['default'];
	  hb.Utils = Utils;
	  hb.escapeExpression = Utils.escapeExpression;

	  hb.VM = runtime;
	  hb.template = function (spec) {
	    return runtime.template(spec, hb);
	  };

	  return hb;
	}

	var inst = create();
	inst.create = create;

	_handlebarsNoConflict2['default'](inst);

	inst['default'] = inst;

	exports['default'] = inst;
	module.exports = exports['default'];

/***/ }),
/* 3 */
/***/ (function(module, exports) {

	"use strict";

	exports["default"] = function (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;
	  }
	};

	exports.__esModule = true;

/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;
	exports.HandlebarsEnvironment = HandlebarsEnvironment;

	var _utils = __webpack_require__(5);

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	var _helpers = __webpack_require__(10);

	var _decorators = __webpack_require__(30);

	var _logger = __webpack_require__(32);

	var _logger2 = _interopRequireDefault(_logger);

	var VERSION = '4.5.3';
	exports.VERSION = VERSION;
	var COMPILER_REVISION = 8;
	exports.COMPILER_REVISION = COMPILER_REVISION;
	var LAST_COMPATIBLE_COMPILER_REVISION = 7;

	exports.LAST_COMPATIBLE_COMPILER_REVISION = LAST_COMPATIBLE_COMPILER_REVISION;
	var REVISION_CHANGES = {
	  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
	  2: '== 1.0.0-rc.3',
	  3: '== 1.0.0-rc.4',
	  4: '== 1.x.x',
	  5: '== 2.0.0-alpha.x',
	  6: '>= 2.0.0-beta.1',
	  7: '>= 4.0.0 <4.3.0',
	  8: '>= 4.3.0'
	};

	exports.REVISION_CHANGES = REVISION_CHANGES;
	var objectType = '[object Object]';

	function HandlebarsEnvironment(helpers, partials, decorators) {
	  this.helpers = helpers || {};
	  this.partials = partials || {};
	  this.decorators = decorators || {};

	  _helpers.registerDefaultHelpers(this);
	  _decorators.registerDefaultDecorators(this);
	}

	HandlebarsEnvironment.prototype = {
	  constructor: HandlebarsEnvironment,

	  logger: _logger2['default'],
	  log: _logger2['default'].log,

	  registerHelper: function registerHelper(name, fn) {
	    if (_utils.toString.call(name) === objectType) {
	      if (fn) {
	        throw new _exception2['default']('Arg not supported with multiple helpers');
	      }
	      _utils.extend(this.helpers, name);
	    } else {
	      this.helpers[name] = fn;
	    }
	  },
	  unregisterHelper: function unregisterHelper(name) {
	    delete this.helpers[name];
	  },

	  registerPartial: function registerPartial(name, partial) {
	    if (_utils.toString.call(name) === objectType) {
	      _utils.extend(this.partials, name);
	    } else {
	      if (typeof partial === 'undefined') {
	        throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined');
	      }
	      this.partials[name] = partial;
	    }
	  },
	  unregisterPartial: function unregisterPartial(name) {
	    delete this.partials[name];
	  },

	  registerDecorator: function registerDecorator(name, fn) {
	    if (_utils.toString.call(name) === objectType) {
	      if (fn) {
	        throw new _exception2['default']('Arg not supported with multiple decorators');
	      }
	      _utils.extend(this.decorators, name);
	    } else {
	      this.decorators[name] = fn;
	    }
	  },
	  unregisterDecorator: function unregisterDecorator(name) {
	    delete this.decorators[name];
	  }
	};

	var log = _logger2['default'].log;

	exports.log = log;
	exports.createFrame = _utils.createFrame;
	exports.logger = _logger2['default'];

/***/ }),
/* 5 */
/***/ (function(module, exports) {

	'use strict';

	exports.__esModule = true;
	exports.extend = extend;
	exports.indexOf = indexOf;
	exports.escapeExpression = escapeExpression;
	exports.isEmpty = isEmpty;
	exports.createFrame = createFrame;
	exports.blockParams = blockParams;
	exports.appendContextPath = appendContextPath;

	var escape = {
	  '&': '&amp;',
	  '<': '&lt;',
	  '>': '&gt;',
	  '"': '&quot;',
	  "'": '&#x27;',
	  '`': '&#x60;',
	  '=': '&#x3D;'
	};

	var badChars = /[&<>"'`=]/g,
	    possible = /[&<>"'`=]/;

	function escapeChar(chr) {
	  return escape[chr];
	}

	function extend(obj /* , ...source */) {
	  for (var i = 1; i < arguments.length; i++) {
	    for (var key in arguments[i]) {
	      if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
	        obj[key] = arguments[i][key];
	      }
	    }
	  }

	  return obj;
	}

	var toString = Object.prototype.toString;

	exports.toString = toString;
	// Sourced from lodash
	// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
	/* eslint-disable func-style */
	var isFunction = function isFunction(value) {
	  return typeof value === 'function';
	};
	// fallback for older versions of Chrome and Safari
	/* istanbul ignore next */
	if (isFunction(/x/)) {
	  exports.isFunction = isFunction = function (value) {
	    return typeof value === 'function' && toString.call(value) === '[object Function]';
	  };
	}
	exports.isFunction = isFunction;

	/* eslint-enable func-style */

	/* istanbul ignore next */
	var isArray = Array.isArray || function (value) {
	  return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
	};

	exports.isArray = isArray;
	// Older IE versions do not directly support indexOf so we must implement our own, sadly.

	function indexOf(array, value) {
	  for (var i = 0, len = array.length; i < len; i++) {
	    if (array[i] === value) {
	      return i;
	    }
	  }
	  return -1;
	}

	function escapeExpression(string) {
	  if (typeof string !== 'string') {
	    // don't escape SafeStrings, since they're already safe
	    if (string && string.toHTML) {
	      return string.toHTML();
	    } else if (string == null) {
	      return '';
	    } else if (!string) {
	      return string + '';
	    }

	    // Force a string conversion as this will be done by the append regardless and
	    // the regex test will do this transparently behind the scenes, causing issues if
	    // an object's to string has escaped characters in it.
	    string = '' + string;
	  }

	  if (!possible.test(string)) {
	    return string;
	  }
	  return string.replace(badChars, escapeChar);
	}

	function isEmpty(value) {
	  if (!value && value !== 0) {
	    return true;
	  } else if (isArray(value) && value.length === 0) {
	    return true;
	  } else {
	    return false;
	  }
	}

	function createFrame(object) {
	  var frame = extend({}, object);
	  frame._parent = object;
	  return frame;
	}

	function blockParams(params, ids) {
	  params.path = ids;
	  return params;
	}

	function appendContextPath(contextPath, id) {
	  return (contextPath ? contextPath + '.' : '') + id;
	}

/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _Object$defineProperty = __webpack_require__(7)['default'];

	exports.__esModule = true;

	var errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack'];

	function Exception(message, node) {
	  var loc = node && node.loc,
	      line = undefined,
	      endLineNumber = undefined,
	      column = undefined,
	      endColumn = undefined;

	  if (loc) {
	    line = loc.start.line;
	    endLineNumber = loc.end.line;
	    column = loc.start.column;
	    endColumn = loc.end.column;

	    message += ' - ' + line + ':' + column;
	  }

	  var tmp = Error.prototype.constructor.call(this, message);

	  // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
	  for (var idx = 0; idx < errorProps.length; idx++) {
	    this[errorProps[idx]] = tmp[errorProps[idx]];
	  }

	  /* istanbul ignore else */
	  if (Error.captureStackTrace) {
	    Error.captureStackTrace(this, Exception);
	  }

	  try {
	    if (loc) {
	      this.lineNumber = line;
	      this.endLineNumber = endLineNumber;

	      // Work around issue under safari where we can't directly set the column value
	      /* istanbul ignore next */
	      if (_Object$defineProperty) {
	        Object.defineProperty(this, 'column', {
	          value: column,
	          enumerable: true
	        });
	        Object.defineProperty(this, 'endColumn', {
	          value: endColumn,
	          enumerable: true
	        });
	      } else {
	        this.column = column;
	        this.endColumn = endColumn;
	      }
	    }
	  } catch (nop) {
	    /* Ignore if the browser is very particular */
	  }
	}

	Exception.prototype = new Error();

	exports['default'] = Exception;
	module.exports = exports['default'];

/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {

	module.exports = { "default": __webpack_require__(8), __esModule: true };

/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(9);
	module.exports = function defineProperty(it, key, desc){
	  return $.setDesc(it, key, desc);
	};

/***/ }),
/* 9 */
/***/ (function(module, exports) {

	var $Object = Object;
	module.exports = {
	  create:     $Object.create,
	  getProto:   $Object.getPrototypeOf,
	  isEnum:     {}.propertyIsEnumerable,
	  getDesc:    $Object.getOwnPropertyDescriptor,
	  setDesc:    $Object.defineProperty,
	  setDescs:   $Object.defineProperties,
	  getKeys:    $Object.keys,
	  getNames:   $Object.getOwnPropertyNames,
	  getSymbols: $Object.getOwnPropertySymbols,
	  each:       [].forEach
	};

/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;
	exports.registerDefaultHelpers = registerDefaultHelpers;
	exports.moveHelperToHooks = moveHelperToHooks;

	var _helpersBlockHelperMissing = __webpack_require__(11);

	var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing);

	var _helpersEach = __webpack_require__(12);

	var _helpersEach2 = _interopRequireDefault(_helpersEach);

	var _helpersHelperMissing = __webpack_require__(25);

	var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing);

	var _helpersIf = __webpack_require__(26);

	var _helpersIf2 = _interopRequireDefault(_helpersIf);

	var _helpersLog = __webpack_require__(27);

	var _helpersLog2 = _interopRequireDefault(_helpersLog);

	var _helpersLookup = __webpack_require__(28);

	var _helpersLookup2 = _interopRequireDefault(_helpersLookup);

	var _helpersWith = __webpack_require__(29);

	var _helpersWith2 = _interopRequireDefault(_helpersWith);

	function registerDefaultHelpers(instance) {
	  _helpersBlockHelperMissing2['default'](instance);
	  _helpersEach2['default'](instance);
	  _helpersHelperMissing2['default'](instance);
	  _helpersIf2['default'](instance);
	  _helpersLog2['default'](instance);
	  _helpersLookup2['default'](instance);
	  _helpersWith2['default'](instance);
	}

	function moveHelperToHooks(instance, helperName, keepHelper) {
	  if (instance.helpers[helperName]) {
	    instance.hooks[helperName] = instance.helpers[helperName];
	    if (!keepHelper) {
	      delete instance.helpers[helperName];
	    }
	  }
	}

/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	exports.__esModule = true;

	var _utils = __webpack_require__(5);

	exports['default'] = function (instance) {
	  instance.registerHelper('blockHelperMissing', function (context, options) {
	    var inverse = options.inverse,
	        fn = options.fn;

	    if (context === true) {
	      return fn(this);
	    } else if (context === false || context == null) {
	      return inverse(this);
	    } else if (_utils.isArray(context)) {
	      if (context.length > 0) {
	        if (options.ids) {
	          options.ids = [options.name];
	        }

	        return instance.helpers.each(context, options);
	      } else {
	        return inverse(this);
	      }
	    } else {
	      if (options.data && options.ids) {
	        var data = _utils.createFrame(options.data);
	        data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name);
	        options = { data: data };
	      }

	      return fn(context, options);
	    }
	  });
	};

	module.exports = exports['default'];

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global) {'use strict';

	var _Object$keys = __webpack_require__(13)['default'];

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _utils = __webpack_require__(5);

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	exports['default'] = function (instance) {
	  instance.registerHelper('each', function (context, options) {
	    if (!options) {
	      throw new _exception2['default']('Must pass iterator to #each');
	    }

	    var fn = options.fn,
	        inverse = options.inverse,
	        i = 0,
	        ret = '',
	        data = undefined,
	        contextPath = undefined;

	    if (options.data && options.ids) {
	      contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
	    }

	    if (_utils.isFunction(context)) {
	      context = context.call(this);
	    }

	    if (options.data) {
	      data = _utils.createFrame(options.data);
	    }

	    function execIteration(field, index, last) {
	      if (data) {
	        data.key = field;
	        data.index = index;
	        data.first = index === 0;
	        data.last = !!last;

	        if (contextPath) {
	          data.contextPath = contextPath + field;
	        }
	      }

	      ret = ret + fn(context[field], {
	        data: data,
	        blockParams: _utils.blockParams([context[field], field], [contextPath + field, null])
	      });
	    }

	    if (context && typeof context === 'object') {
	      if (_utils.isArray(context)) {
	        for (var j = context.length; i < j; i++) {
	          if (i in context) {
	            execIteration(i, i, i === context.length - 1);
	          }
	        }
	      } else if (global.Symbol && context[global.Symbol.iterator]) {
	        var newContext = [];
	        var iterator = context[global.Symbol.iterator]();
	        for (var it = iterator.next(); !it.done; it = iterator.next()) {
	          newContext.push(it.value);
	        }
	        context = newContext;
	        for (var j = context.length; i < j; i++) {
	          execIteration(i, i, i === context.length - 1);
	        }
	      } else {
	        (function () {
	          var priorKey = undefined;

	          _Object$keys(context).forEach(function (key) {
	            // We're running the iterations one step out of sync so we can detect
	            // the last iteration without have to scan the object twice and create
	            // an itermediate keys array.
	            if (priorKey !== undefined) {
	              execIteration(priorKey, i - 1);
	            }
	            priorKey = key;
	            i++;
	          });
	          if (priorKey !== undefined) {
	            execIteration(priorKey, i - 1, true);
	          }
	        })();
	      }
	    }

	    if (i === 0) {
	      ret = inverse(this);
	    }

	    return ret;
	  });
	};

	module.exports = exports['default'];
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

	module.exports = { "default": __webpack_require__(14), __esModule: true };

/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {

	__webpack_require__(15);
	module.exports = __webpack_require__(21).Object.keys;

/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {

	// 19.1.2.14 Object.keys(O)
	var toObject = __webpack_require__(16);

	__webpack_require__(18)('keys', function($keys){
	  return function keys(it){
	    return $keys(toObject(it));
	  };
	});

/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {

	// 7.1.13 ToObject(argument)
	var defined = __webpack_require__(17);
	module.exports = function(it){
	  return Object(defined(it));
	};

/***/ }),
/* 17 */
/***/ (function(module, exports) {

	// 7.2.1 RequireObjectCoercible(argument)
	module.exports = function(it){
	  if(it == undefined)throw TypeError("Can't call method on  " + it);
	  return it;
	};

/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {

	// most Object methods by ES6 should accept primitives
	var $export = __webpack_require__(19)
	  , core    = __webpack_require__(21)
	  , fails   = __webpack_require__(24);
	module.exports = function(KEY, exec){
	  var fn  = (core.Object || {})[KEY] || Object[KEY]
	    , exp = {};
	  exp[KEY] = exec(fn);
	  $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp);
	};

/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {

	var global    = __webpack_require__(20)
	  , core      = __webpack_require__(21)
	  , ctx       = __webpack_require__(22)
	  , PROTOTYPE = 'prototype';

	var $export = function(type, name, source){
	  var IS_FORCED = type & $export.F
	    , IS_GLOBAL = type & $export.G
	    , IS_STATIC = type & $export.S
	    , IS_PROTO  = type & $export.P
	    , IS_BIND   = type & $export.B
	    , IS_WRAP   = type & $export.W
	    , exports   = IS_GLOBAL ? core : core[name] || (core[name] = {})
	    , target    = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
	    , key, own, out;
	  if(IS_GLOBAL)source = name;
	  for(key in source){
	    // contains in native
	    own = !IS_FORCED && target && key in target;
	    if(own && key in exports)continue;
	    // export native or passed
	    out = own ? target[key] : source[key];
	    // prevent global pollution for namespaces
	    exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
	    // bind timers to global for call from export context
	    : IS_BIND && own ? ctx(out, global)
	    // wrap global constructors for prevent change them in library
	    : IS_WRAP && target[key] == out ? (function(C){
	      var F = function(param){
	        return this instanceof C ? new C(param) : C(param);
	      };
	      F[PROTOTYPE] = C[PROTOTYPE];
	      return F;
	    // make static versions for prototype methods
	    })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
	    if(IS_PROTO)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out;
	  }
	};
	// type bitmap
	$export.F = 1;  // forced
	$export.G = 2;  // global
	$export.S = 4;  // static
	$export.P = 8;  // proto
	$export.B = 16; // bind
	$export.W = 32; // wrap
	module.exports = $export;

/***/ }),
/* 20 */
/***/ (function(module, exports) {

	// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
	var global = module.exports = typeof window != 'undefined' && window.Math == Math
	  ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')();
	if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef

/***/ }),
/* 21 */
/***/ (function(module, exports) {

	var core = module.exports = {version: '1.2.6'};
	if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef

/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {

	// optional / simple context binding
	var aFunction = __webpack_require__(23);
	module.exports = function(fn, that, length){
	  aFunction(fn);
	  if(that === undefined)return fn;
	  switch(length){
	    case 1: return function(a){
	      return fn.call(that, a);
	    };
	    case 2: return function(a, b){
	      return fn.call(that, a, b);
	    };
	    case 3: return function(a, b, c){
	      return fn.call(that, a, b, c);
	    };
	  }
	  return function(/* ...args */){
	    return fn.apply(that, arguments);
	  };
	};

/***/ }),
/* 23 */
/***/ (function(module, exports) {

	module.exports = function(it){
	  if(typeof it != 'function')throw TypeError(it + ' is not a function!');
	  return it;
	};

/***/ }),
/* 24 */
/***/ (function(module, exports) {

	module.exports = function(exec){
	  try {
	    return !!exec();
	  } catch(e){
	    return true;
	  }
	};

/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	exports['default'] = function (instance) {
	  instance.registerHelper('helperMissing', function () /* [args, ]options */{
	    if (arguments.length === 1) {
	      // A missing field in a {{foo}} construct.
	      return undefined;
	    } else {
	      // Someone is actually trying to call something, blow up.
	      throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
	    }
	  });
	};

	module.exports = exports['default'];

/***/ }),
/* 26 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _utils = __webpack_require__(5);

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	exports['default'] = function (instance) {
	  instance.registerHelper('if', function (conditional, options) {
	    if (arguments.length != 2) {
	      throw new _exception2['default']('#if requires exactly one argument');
	    }
	    if (_utils.isFunction(conditional)) {
	      conditional = conditional.call(this);
	    }

	    // Default behavior is to render the positive path if the value is truthy and not empty.
	    // The `includeZero` option may be set to treat the condtional as purely not empty based on the
	    // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
	    if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) {
	      return options.inverse(this);
	    } else {
	      return options.fn(this);
	    }
	  });

	  instance.registerHelper('unless', function (conditional, options) {
	    if (arguments.length != 2) {
	      throw new _exception2['default']('#unless requires exactly one argument');
	    }
	    return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash });
	  });
	};

	module.exports = exports['default'];

/***/ }),
/* 27 */
/***/ (function(module, exports) {

	'use strict';

	exports.__esModule = true;

	exports['default'] = function (instance) {
	  instance.registerHelper('log', function () /* message, options */{
	    var args = [undefined],
	        options = arguments[arguments.length - 1];
	    for (var i = 0; i < arguments.length - 1; i++) {
	      args.push(arguments[i]);
	    }

	    var level = 1;
	    if (options.hash.level != null) {
	      level = options.hash.level;
	    } else if (options.data && options.data.level != null) {
	      level = options.data.level;
	    }
	    args[0] = level;

	    instance.log.apply(instance, args);
	  });
	};

	module.exports = exports['default'];

/***/ }),
/* 28 */
/***/ (function(module, exports) {

	'use strict';

	exports.__esModule = true;
	var dangerousPropertyRegex = /^(constructor|__defineGetter__|__defineSetter__|__lookupGetter__|__proto__)$/;

	exports.dangerousPropertyRegex = dangerousPropertyRegex;

	exports['default'] = function (instance) {
	  instance.registerHelper('lookup', function (obj, field) {
	    if (!obj) {
	      return obj;
	    }
	    if (dangerousPropertyRegex.test(String(field)) && !Object.prototype.propertyIsEnumerable.call(obj, field)) {
	      return undefined;
	    }
	    return obj[field];
	  });
	};

/***/ }),
/* 29 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _utils = __webpack_require__(5);

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	exports['default'] = function (instance) {
	  instance.registerHelper('with', function (context, options) {
	    if (arguments.length != 2) {
	      throw new _exception2['default']('#with requires exactly one argument');
	    }
	    if (_utils.isFunction(context)) {
	      context = context.call(this);
	    }

	    var fn = options.fn;

	    if (!_utils.isEmpty(context)) {
	      var data = options.data;
	      if (options.data && options.ids) {
	        data = _utils.createFrame(options.data);
	        data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);
	      }

	      return fn(context, {
	        data: data,
	        blockParams: _utils.blockParams([context], [data && data.contextPath])
	      });
	    } else {
	      return options.inverse(this);
	    }
	  });
	};

	module.exports = exports['default'];

/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;
	exports.registerDefaultDecorators = registerDefaultDecorators;

	var _decoratorsInline = __webpack_require__(31);

	var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline);

	function registerDefaultDecorators(instance) {
	  _decoratorsInline2['default'](instance);
	}

/***/ }),
/* 31 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	exports.__esModule = true;

	var _utils = __webpack_require__(5);

	exports['default'] = function (instance) {
	  instance.registerDecorator('inline', function (fn, props, container, options) {
	    var ret = fn;
	    if (!props.partials) {
	      props.partials = {};
	      ret = function (context, options) {
	        // Create a new partials stack frame prior to exec.
	        var original = container.partials;
	        container.partials = _utils.extend({}, original, props.partials);
	        var ret = fn(context, options);
	        container.partials = original;
	        return ret;
	      };
	    }

	    props.partials[options.args[0]] = options.fn;

	    return ret;
	  });
	};

	module.exports = exports['default'];

/***/ }),
/* 32 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	exports.__esModule = true;

	var _utils = __webpack_require__(5);

	var logger = {
	  methodMap: ['debug', 'info', 'warn', 'error'],
	  level: 'info',

	  // Maps a given level value to the `methodMap` indexes above.
	  lookupLevel: function lookupLevel(level) {
	    if (typeof level === 'string') {
	      var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());
	      if (levelMap >= 0) {
	        level = levelMap;
	      } else {
	        level = parseInt(level, 10);
	      }
	    }

	    return level;
	  },

	  // Can be overridden in the host environment
	  log: function log(level) {
	    level = logger.lookupLevel(level);

	    if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
	      var method = logger.methodMap[level];
	      if (!console[method]) {
	        // eslint-disable-line no-console
	        method = 'log';
	      }

	      for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	        message[_key - 1] = arguments[_key];
	      }

	      console[method].apply(console, message); // eslint-disable-line no-console
	    }
	  }
	};

	exports['default'] = logger;
	module.exports = exports['default'];

/***/ }),
/* 33 */
/***/ (function(module, exports) {

	// Build out our basic SafeString type
	'use strict';

	exports.__esModule = true;
	function SafeString(string) {
	  this.string = string;
	}

	SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
	  return '' + this.string;
	};

	exports['default'] = SafeString;
	module.exports = exports['default'];

/***/ }),
/* 34 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _Object$seal = __webpack_require__(35)['default'];

	var _interopRequireWildcard = __webpack_require__(3)['default'];

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;
	exports.checkRevision = checkRevision;
	exports.template = template;
	exports.wrapProgram = wrapProgram;
	exports.resolvePartial = resolvePartial;
	exports.invokePartial = invokePartial;
	exports.noop = noop;

	var _utils = __webpack_require__(5);

	var Utils = _interopRequireWildcard(_utils);

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	var _base = __webpack_require__(4);

	var _helpers = __webpack_require__(10);

	function checkRevision(compilerInfo) {
	  var compilerRevision = compilerInfo && compilerInfo[0] || 1,
	      currentRevision = _base.COMPILER_REVISION;

	  if (compilerRevision >= _base.LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= _base.COMPILER_REVISION) {
	    return;
	  }

	  if (compilerRevision < _base.LAST_COMPATIBLE_COMPILER_REVISION) {
	    var runtimeVersions = _base.REVISION_CHANGES[currentRevision],
	        compilerVersions = _base.REVISION_CHANGES[compilerRevision];
	    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 + ').');
	  } else {
	    // Use the embedded version info since the runtime doesn't know about this revision yet
	    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] + ').');
	  }
	}

	function template(templateSpec, env) {

	  /* istanbul ignore next */
	  if (!env) {
	    throw new _exception2['default']('No environment passed to template');
	  }
	  if (!templateSpec || !templateSpec.main) {
	    throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
	  }

	  templateSpec.main.decorator = templateSpec.main_d;

	  // Note: Using env.VM references rather than local var references throughout this section to allow
	  // for external users to override these as pseudo-supported APIs.
	  env.VM.checkRevision(templateSpec.compiler);

	  // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0)
	  var templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7;

	  function invokePartialWrapper(partial, context, options) {
	    if (options.hash) {
	      context = Utils.extend({}, context, options.hash);
	      if (options.ids) {
	        options.ids[0] = true;
	      }
	    }
	    partial = env.VM.resolvePartial.call(this, partial, context, options);

	    var optionsWithHooks = Utils.extend({}, options, { hooks: this.hooks });

	    var result = env.VM.invokePartial.call(this, partial, context, optionsWithHooks);

	    if (result == null && env.compile) {
	      options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
	      result = options.partials[options.name](context, optionsWithHooks);
	    }
	    if (result != null) {
	      if (options.indent) {
	        var lines = result.split('\n');
	        for (var i = 0, l = lines.length; i < l; i++) {
	          if (!lines[i] && i + 1 === l) {
	            break;
	          }

	          lines[i] = options.indent + lines[i];
	        }
	        result = lines.join('\n');
	      }
	      return result;
	    } else {
	      throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
	    }
	  }

	  // Just add water
	  var container = {
	    strict: function strict(obj, name, loc) {
	      if (!obj || !(name in obj)) {
	        throw new _exception2['default']('"' + name + '" not defined in ' + obj, { loc: loc });
	      }
	      return obj[name];
	    },
	    lookup: function lookup(depths, name) {
	      var len = depths.length;
	      for (var i = 0; i < len; i++) {
	        if (depths[i] && depths[i][name] != null) {
	          return depths[i][name];
	        }
	      }
	    },
	    lambda: function lambda(current, context) {
	      return typeof current === 'function' ? current.call(context) : current;
	    },

	    escapeExpression: Utils.escapeExpression,
	    invokePartial: invokePartialWrapper,

	    fn: function fn(i) {
	      var ret = templateSpec[i];
	      ret.decorator = templateSpec[i + '_d'];
	      return ret;
	    },

	    programs: [],
	    program: function program(i, data, declaredBlockParams, blockParams, depths) {
	      var programWrapper = this.programs[i],
	          fn = this.fn(i);
	      if (data || depths || blockParams || declaredBlockParams) {
	        programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
	      } else if (!programWrapper) {
	        programWrapper = this.programs[i] = wrapProgram(this, i, fn);
	      }
	      return programWrapper;
	    },

	    data: function data(value, depth) {
	      while (value && depth--) {
	        value = value._parent;
	      }
	      return value;
	    },
	    // An empty object to use as replacement for null-contexts
	    nullContext: _Object$seal({}),

	    noop: env.VM.noop,
	    compilerInfo: templateSpec.compiler
	  };

	  function ret(context) {
	    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

	    var data = options.data;

	    ret._setup(options);
	    if (!options.partial && templateSpec.useData) {
	      data = initData(context, data);
	    }
	    var depths = undefined,
	        blockParams = templateSpec.useBlockParams ? [] : undefined;
	    if (templateSpec.useDepths) {
	      if (options.depths) {
	        depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;
	      } else {
	        depths = [context];
	      }
	    }

	    function main(context /*, options*/) {
	      return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
	    }
	    main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
	    return main(context, options);
	  }
	  ret.isTop = true;

	  ret._setup = function (options) {
	    if (!options.partial) {
	      container.helpers = Utils.extend({}, env.helpers, options.helpers);

	      if (templateSpec.usePartial) {
	        container.partials = Utils.extend({}, env.partials, options.partials);
	      }
	      if (templateSpec.usePartial || templateSpec.useDecorators) {
	        container.decorators = Utils.extend({}, env.decorators, options.decorators);
	      }

	      container.hooks = {};

	      var keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7;
	      _helpers.moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);
	      _helpers.moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);
	    } else {
	      container.helpers = options.helpers;
	      container.partials = options.partials;
	      container.decorators = options.decorators;
	      container.hooks = options.hooks;
	    }
	  };

	  ret._child = function (i, data, blockParams, depths) {
	    if (templateSpec.useBlockParams && !blockParams) {
	      throw new _exception2['default']('must pass block params');
	    }
	    if (templateSpec.useDepths && !depths) {
	      throw new _exception2['default']('must pass parent depths');
	    }

	    return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
	  };
	  return ret;
	}

	function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
	  function prog(context) {
	    var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

	    var currentDepths = depths;
	    if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {
	      currentDepths = [context].concat(depths);
	    }

	    return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
	  }

	  prog = executeDecorators(fn, prog, container, depths, data, blockParams);

	  prog.program = i;
	  prog.depth = depths ? depths.length : 0;
	  prog.blockParams = declaredBlockParams || 0;
	  return prog;
	}

	/**
	 * This is currently part of the official API, therefore implementation details should not be changed.
	 */

	function resolvePartial(partial, context, options) {
	  if (!partial) {
	    if (options.name === '@partial-block') {
	      partial = options.data['partial-block'];
	    } else {
	      partial = options.partials[options.name];
	    }
	  } else if (!partial.call && !options.name) {
	    // This is a dynamic partial that returned a string
	    options.name = partial;
	    partial = options.partials[partial];
	  }
	  return partial;
	}

	function invokePartial(partial, context, options) {
	  // Use the current closure context to save the partial-block if this partial
	  var currentPartialBlock = options.data && options.data['partial-block'];
	  options.partial = true;
	  if (options.ids) {
	    options.data.contextPath = options.ids[0] || options.data.contextPath;
	  }

	  var partialBlock = undefined;
	  if (options.fn && options.fn !== noop) {
	    (function () {
	      options.data = _base.createFrame(options.data);
	      // Wrapper function to get access to currentPartialBlock from the closure
	      var fn = options.fn;
	      partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) {
	        var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

	        // Restore the partial-block from the closure for the execution of the block
	        // i.e. the part inside the block of the partial call.
	        options.data = _base.createFrame(options.data);
	        options.data['partial-block'] = currentPartialBlock;
	        return fn(context, options);
	      };
	      if (fn.partials) {
	        options.partials = Utils.extend({}, options.partials, fn.partials);
	      }
	    })();
	  }

	  if (partial === undefined && partialBlock) {
	    partial = partialBlock;
	  }

	  if (partial === undefined) {
	    throw new _exception2['default']('The partial ' + options.name + ' could not be found');
	  } else if (partial instanceof Function) {
	    return partial(context, options);
	  }
	}

	function noop() {
	  return '';
	}

	function initData(context, data) {
	  if (!data || !('root' in data)) {
	    data = data ? _base.createFrame(data) : {};
	    data.root = context;
	  }
	  return data;
	}

	function executeDecorators(fn, prog, container, depths, data, blockParams) {
	  if (fn.decorator) {
	    var props = {};
	    prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
	    Utils.extend(prog, props);
	  }
	  return prog;
	}

/***/ }),
/* 35 */
/***/ (function(module, exports, __webpack_require__) {

	module.exports = { "default": __webpack_require__(36), __esModule: true };

/***/ }),
/* 36 */
/***/ (function(module, exports, __webpack_require__) {

	__webpack_require__(37);
	module.exports = __webpack_require__(21).Object.seal;

/***/ }),
/* 37 */
/***/ (function(module, exports, __webpack_require__) {

	// 19.1.2.17 Object.seal(O)
	var isObject = __webpack_require__(38);

	__webpack_require__(18)('seal', function($seal){
	  return function seal(it){
	    return $seal && isObject(it) ? $seal(it) : it;
	  };
	});

/***/ }),
/* 38 */
/***/ (function(module, exports) {

	module.exports = function(it){
	  return typeof it === 'object' ? it !== null : typeof it === 'function';
	};

/***/ }),
/* 39 */
/***/ (function(module, exports) {

	/* WEBPACK VAR INJECTION */(function(global) {/* global window */
	'use strict';

	exports.__esModule = true;

	exports['default'] = function (Handlebars) {
	  /* istanbul ignore next */
	  var root = typeof global !== 'undefined' ? global : window,
	      $Handlebars = root.Handlebars;
	  /* istanbul ignore next */
	  Handlebars.noConflict = function () {
	    if (root.Handlebars === Handlebars) {
	      root.Handlebars = $Handlebars;
	    }
	    return Handlebars;
	  };
	};

	module.exports = exports['default'];
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ }),
/* 40 */
/***/ (function(module, exports) {

	'use strict';

	exports.__esModule = true;
	var AST = {
	  // Public API used to evaluate derived attributes regarding AST nodes
	  helpers: {
	    // a mustache is definitely a helper if:
	    // * it is an eligible helper, and
	    // * it has at least one parameter or hash segment
	    helperExpression: function helperExpression(node) {
	      return node.type === 'SubExpression' || (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!(node.params && node.params.length || node.hash);
	    },

	    scopedId: function scopedId(path) {
	      return (/^\.|this\b/.test(path.original)
	      );
	    },

	    // an ID is simple if it only has one part, and that part is not
	    // `..` or `this`.
	    simpleId: function simpleId(path) {
	      return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
	    }
	  }
	};

	// Must be exported as an object rather than the root of the module as the jison lexer
	// must modify the object to operate properly.
	exports['default'] = AST;
	module.exports = exports['default'];

/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	var _interopRequireWildcard = __webpack_require__(3)['default'];

	exports.__esModule = true;
	exports.parseWithoutProcessing = parseWithoutProcessing;
	exports.parse = parse;

	var _parser = __webpack_require__(42);

	var _parser2 = _interopRequireDefault(_parser);

	var _whitespaceControl = __webpack_require__(43);

	var _whitespaceControl2 = _interopRequireDefault(_whitespaceControl);

	var _helpers = __webpack_require__(45);

	var Helpers = _interopRequireWildcard(_helpers);

	var _utils = __webpack_require__(5);

	exports.parser = _parser2['default'];

	var yy = {};
	_utils.extend(yy, Helpers);

	function parseWithoutProcessing(input, options) {
	  // Just return if an already-compiled AST was passed in.
	  if (input.type === 'Program') {
	    return input;
	  }

	  _parser2['default'].yy = yy;

	  // Altering the shared object here, but this is ok as parser is a sync operation
	  yy.locInfo = function (locInfo) {
	    return new yy.SourceLocation(options && options.srcName, locInfo);
	  };

	  var ast = _parser2['default'].parse(input);

	  return ast;
	}

	function parse(input, options) {
	  var ast = parseWithoutProcessing(input, options);
	  var strip = new _whitespaceControl2['default'](options);

	  return strip.accept(ast);
	}

/***/ }),
/* 42 */
/***/ (function(module, exports) {

	// File ignored in coverage tests via setting in .istanbul.yml
	/* Jison generated parser */
	"use strict";

	exports.__esModule = true;
	var handlebars = (function () {
	    var parser = { trace: function trace() {},
	        yy: {},
	        symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "partialBlock": 12, "content": 13, "COMMENT": 14, "CONTENT": 15, "openRawBlock": 16, "rawBlock_repetition0": 17, "END_RAW_BLOCK": 18, "OPEN_RAW_BLOCK": 19, "helperName": 20, "openRawBlock_repetition0": 21, "openRawBlock_option0": 22, "CLOSE_RAW_BLOCK": 23, "openBlock": 24, "block_option0": 25, "closeBlock": 26, "openInverse": 27, "block_option1": 28, "OPEN_BLOCK": 29, "openBlock_repetition0": 30, "openBlock_option0": 31, "openBlock_option1": 32, "CLOSE": 33, "OPEN_INVERSE": 34, "openInverse_repetition0": 35, "openInverse_option0": 36, "openInverse_option1": 37, "openInverseChain": 38, "OPEN_INVERSE_CHAIN": 39, "openInverseChain_repetition0": 40, "openInverseChain_option0": 41, "openInverseChain_option1": 42, "inverseAndProgram": 43, "INVERSE": 44, "inverseChain": 45, "inverseChain_option0": 46, "OPEN_ENDBLOCK": 47, "OPEN": 48, "mustache_repetition0": 49, "mustache_option0": 50, "OPEN_UNESCAPED": 51, "mustache_repetition1": 52, "mustache_option1": 53, "CLOSE_UNESCAPED": 54, "OPEN_PARTIAL": 55, "partialName": 56, "partial_repetition0": 57, "partial_option0": 58, "openPartialBlock": 59, "OPEN_PARTIAL_BLOCK": 60, "openPartialBlock_repetition0": 61, "openPartialBlock_option0": 62, "param": 63, "sexpr": 64, "OPEN_SEXPR": 65, "sexpr_repetition0": 66, "sexpr_option0": 67, "CLOSE_SEXPR": 68, "hash": 69, "hash_repetition_plus0": 70, "hashSegment": 71, "ID": 72, "EQUALS": 73, "blockParams": 74, "OPEN_BLOCK_PARAMS": 75, "blockParams_repetition_plus0": 76, "CLOSE_BLOCK_PARAMS": 77, "path": 78, "dataName": 79, "STRING": 80, "NUMBER": 81, "BOOLEAN": 82, "UNDEFINED": 83, "NULL": 84, "DATA": 85, "pathSegments": 86, "SEP": 87, "$accept": 0, "$end": 1 },
	        terminals_: { 2: "error", 5: "EOF", 14: "COMMENT", 15: "CONTENT", 18: "END_RAW_BLOCK", 19: "OPEN_RAW_BLOCK", 23: "CLOSE_RAW_BLOCK", 29: "OPEN_BLOCK", 33: "CLOSE", 34: "OPEN_INVERSE", 39: "OPEN_INVERSE_CHAIN", 44: "INVERSE", 47: "OPEN_ENDBLOCK", 48: "OPEN", 51: "OPEN_UNESCAPED", 54: "CLOSE_UNESCAPED", 55: "OPEN_PARTIAL", 60: "OPEN_PARTIAL_BLOCK", 65: "OPEN_SEXPR", 68: "CLOSE_SEXPR", 72: "ID", 73: "EQUALS", 75: "OPEN_BLOCK_PARAMS", 77: "CLOSE_BLOCK_PARAMS", 80: "STRING", 81: "NUMBER", 82: "BOOLEAN", 83: "UNDEFINED", 84: "NULL", 85: "DATA", 87: "SEP" },
	        productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 5], [8, 5], [11, 5], [12, 3], [59, 5], [63, 1], [63, 1], [64, 5], [69, 1], [71, 3], [74, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [56, 1], [56, 1], [79, 2], [78, 1], [86, 3], [86, 1], [6, 0], [6, 2], [17, 0], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [49, 0], [49, 2], [50, 0], [50, 1], [52, 0], [52, 2], [53, 0], [53, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [66, 0], [66, 2], [67, 0], [67, 1], [70, 1], [70, 2], [76, 1], [76, 2]],
	        performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {

	            var $0 = $$.length - 1;
	            switch (yystate) {
	                case 1:
	                    return $$[$0 - 1];
	                    break;
	                case 2:
	                    this.$ = yy.prepareProgram($$[$0]);
	                    break;
	                case 3:
	                    this.$ = $$[$0];
	                    break;
	                case 4:
	                    this.$ = $$[$0];
	                    break;
	                case 5:
	                    this.$ = $$[$0];
	                    break;
	                case 6:
	                    this.$ = $$[$0];
	                    break;
	                case 7:
	                    this.$ = $$[$0];
	                    break;
	                case 8:
	                    this.$ = $$[$0];
	                    break;
	                case 9:
	                    this.$ = {
	                        type: 'CommentStatement',
	                        value: yy.stripComment($$[$0]),
	                        strip: yy.stripFlags($$[$0], $$[$0]),
	                        loc: yy.locInfo(this._$)
	                    };

	                    break;
	                case 10:
	                    this.$ = {
	                        type: 'ContentStatement',
	                        original: $$[$0],
	                        value: $$[$0],
	                        loc: yy.locInfo(this._$)
	                    };

	                    break;
	                case 11:
	                    this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
	                    break;
	                case 12:
	                    this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] };
	                    break;
	                case 13:
	                    this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$);
	                    break;
	                case 14:
	                    this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$);
	                    break;
	                case 15:
	                    this.$ = { open: $$[$0 - 5], path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
	                    break;
	                case 16:
	                    this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
	                    break;
	                case 17:
	                    this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
	                    break;
	                case 18:
	                    this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] };
	                    break;
	                case 19:
	                    var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$),
	                        program = yy.prepareProgram([inverse], $$[$0 - 1].loc);
	                    program.chained = true;

	                    this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true };

	                    break;
	                case 20:
	                    this.$ = $$[$0];
	                    break;
	                case 21:
	                    this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) };
	                    break;
	                case 22:
	                    this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
	                    break;
	                case 23:
	                    this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
	                    break;
	                case 24:
	                    this.$ = {
	                        type: 'PartialStatement',
	                        name: $$[$0 - 3],
	                        params: $$[$0 - 2],
	                        hash: $$[$0 - 1],
	                        indent: '',
	                        strip: yy.stripFlags($$[$0 - 4], $$[$0]),
	                        loc: yy.locInfo(this._$)
	                    };

	                    break;
	                case 25:
	                    this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
	                    break;
	                case 26:
	                    this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 4], $$[$0]) };
	                    break;
	                case 27:
	                    this.$ = $$[$0];
	                    break;
	                case 28:
	                    this.$ = $$[$0];
	                    break;
	                case 29:
	                    this.$ = {
	                        type: 'SubExpression',
	                        path: $$[$0 - 3],
	                        params: $$[$0 - 2],
	                        hash: $$[$0 - 1],
	                        loc: yy.locInfo(this._$)
	                    };

	                    break;
	                case 30:
	                    this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) };
	                    break;
	                case 31:
	                    this.$ = { type: 'HashPair', key: yy.id($$[$0 - 2]), value: $$[$0], loc: yy.locInfo(this._$) };
	                    break;
	                case 32:
	                    this.$ = yy.id($$[$0 - 1]);
	                    break;
	                case 33:
	                    this.$ = $$[$0];
	                    break;
	                case 34:
	                    this.$ = $$[$0];
	                    break;
	                case 35:
	                    this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) };
	                    break;
	                case 36:
	                    this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) };
	                    break;
	                case 37:
	                    this.$ = { type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$) };
	                    break;
	                case 38:
	                    this.$ = { type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$) };
	                    break;
	                case 39:
	                    this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) };
	                    break;
	                case 40:
	                    this.$ = $$[$0];
	                    break;
	                case 41:
	                    this.$ = $$[$0];
	                    break;
	                case 42:
	                    this.$ = yy.preparePath(true, $$[$0], this._$);
	                    break;
	                case 43:
	                    this.$ = yy.preparePath(false, $$[$0], this._$);
	                    break;
	                case 44:
	                    $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2];
	                    break;
	                case 45:
	                    this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }];
	                    break;
	                case 46:
	                    this.$ = [];
	                    break;
	                case 47:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 48:
	                    this.$ = [];
	                    break;
	                case 49:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 50:
	                    this.$ = [];
	                    break;
	                case 51:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 58:
	                    this.$ = [];
	                    break;
	                case 59:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 64:
	                    this.$ = [];
	                    break;
	                case 65:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 70:
	                    this.$ = [];
	                    break;
	                case 71:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 78:
	                    this.$ = [];
	                    break;
	                case 79:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 82:
	                    this.$ = [];
	                    break;
	                case 83:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 86:
	                    this.$ = [];
	                    break;
	                case 87:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 90:
	                    this.$ = [];
	                    break;
	                case 91:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 94:
	                    this.$ = [];
	                    break;
	                case 95:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 98:
	                    this.$ = [$$[$0]];
	                    break;
	                case 99:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	                case 100:
	                    this.$ = [$$[$0]];
	                    break;
	                case 101:
	                    $$[$0 - 1].push($$[$0]);
	                    break;
	            }
	        },
	        table: [{ 3: 1, 4: 2, 5: [2, 46], 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: [1, 12], 15: [1, 20], 16: 17, 19: [1, 23], 24: 15, 27: 16, 29: [1, 21], 34: [1, 22], 39: [2, 2], 44: [2, 2], 47: [2, 2], 48: [1, 13], 51: [1, 14], 55: [1, 18], 59: 19, 60: [1, 24] }, { 1: [2, 1] }, { 5: [2, 47], 14: [2, 47], 15: [2, 47], 19: [2, 47], 29: [2, 47], 34: [2, 47], 39: [2, 47], 44: [2, 47], 47: [2, 47], 48: [2, 47], 51: [2, 47], 55: [2, 47], 60: [2, 47] }, { 5: [2, 3], 14: [2, 3], 15: [2, 3], 19: [2, 3], 29: [2, 3], 34: [2, 3], 39: [2, 3], 44: [2, 3], 47: [2, 3], 48: [2, 3], 51: [2, 3], 55: [2, 3], 60: [2, 3] }, { 5: [2, 4], 14: [2, 4], 15: [2, 4], 19: [2, 4], 29: [2, 4], 34: [2, 4], 39: [2, 4], 44: [2, 4], 47: [2, 4], 48: [2, 4], 51: [2, 4], 55: [2, 4], 60: [2, 4] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 19: [2, 5], 29: [2, 5], 34: [2, 5], 39: [2, 5], 44: [2, 5], 47: [2, 5], 48: [2, 5], 51: [2, 5], 55: [2, 5], 60: [2, 5] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 19: [2, 6], 29: [2, 6], 34: [2, 6], 39: [2, 6], 44: [2, 6], 47: [2, 6], 48: [2, 6], 51: [2, 6], 55: [2, 6], 60: [2, 6] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 19: [2, 7], 29: [2, 7], 34: [2, 7], 39: [2, 7], 44: [2, 7], 47: [2, 7], 48: [2, 7], 51: [2, 7], 55: [2, 7], 60: [2, 7] }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 19: [2, 8], 29: [2, 8], 34: [2, 8], 39: [2, 8], 44: [2, 8], 47: [2, 8], 48: [2, 8], 51: [2, 8], 55: [2, 8], 60: [2, 8] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 19: [2, 9], 29: [2, 9], 34: [2, 9], 39: [2, 9], 44: [2, 9], 47: [2, 9], 48: [2, 9], 51: [2, 9], 55: [2, 9], 60: [2, 9] }, { 20: 25, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 36, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 37, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 4: 38, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 15: [2, 48], 17: 39, 18: [2, 48] }, { 20: 41, 56: 40, 64: 42, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 44, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 18: [2, 10], 19: [2, 10], 29: [2, 10], 34: [2, 10], 39: [2, 10], 44: [2, 10], 47: [2, 10], 48: [2, 10], 51: [2, 10], 55: [2, 10], 60: [2, 10] }, { 20: 45, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 46, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 47, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 41, 56: 48, 64: 42, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [2, 78], 49: 49, 65: [2, 78], 72: [2, 78], 80: [2, 78], 81: [2, 78], 82: [2, 78], 83: [2, 78], 84: [2, 78], 85: [2, 78] }, { 23: [2, 33], 33: [2, 33], 54: [2, 33], 65: [2, 33], 68: [2, 33], 72: [2, 33], 75: [2, 33], 80: [2, 33], 81: [2, 33], 82: [2, 33], 83: [2, 33], 84: [2, 33], 85: [2, 33] }, { 23: [2, 34], 33: [2, 34], 54: [2, 34], 65: [2, 34], 68: [2, 34], 72: [2, 34], 75: [2, 34], 80: [2, 34], 81: [2, 34], 82: [2, 34], 83: [2, 34], 84: [2, 34], 85: [2, 34] }, { 23: [2, 35], 33: [2, 35], 54: [2, 35], 65: [2, 35], 68: [2, 35], 72: [2, 35], 75: [2, 35], 80: [2, 35], 81: [2, 35], 82: [2, 35], 83: [2, 35], 84: [2, 35], 85: [2, 35] }, { 23: [2, 36], 33: [2, 36], 54: [2, 36], 65: [2, 36], 68: [2, 36], 72: [2, 36], 75: [2, 36], 80: [2, 36], 81: [2, 36], 82: [2, 36], 83: [2, 36], 84: [2, 36], 85: [2, 36] }, { 23: [2, 37], 33: [2, 37], 54: [2, 37], 65: [2, 37], 68: [2, 37], 72: [2, 37], 75: [2, 37], 80: [2, 37], 81: [2, 37], 82: [2, 37], 83: [2, 37], 84: [2, 37], 85: [2, 37] }, { 23: [2, 38], 33: [2, 38], 54: [2, 38], 65: [2, 38], 68: [2, 38], 72: [2, 38], 75: [2, 38], 80: [2, 38], 81: [2, 38], 82: [2, 38], 83: [2, 38], 84: [2, 38], 85: [2, 38] }, { 23: [2, 39], 33: [2, 39], 54: [2, 39], 65: [2, 39], 68: [2, 39], 72: [2, 39], 75: [2, 39], 80: [2, 39], 81: [2, 39], 82: [2, 39], 83: [2, 39], 84: [2, 39], 85: [2, 39] }, { 23: [2, 43], 33: [2, 43], 54: [2, 43], 65: [2, 43], 68: [2, 43], 72: [2, 43], 75: [2, 43], 80: [2, 43], 81: [2, 43], 82: [2, 43], 83: [2, 43], 84: [2, 43], 85: [2, 43], 87: [1, 50] }, { 72: [1, 35], 86: 51 }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 52: 52, 54: [2, 82], 65: [2, 82], 72: [2, 82], 80: [2, 82], 81: [2, 82], 82: [2, 82], 83: [2, 82], 84: [2, 82], 85: [2, 82] }, { 25: 53, 38: 55, 39: [1, 57], 43: 56, 44: [1, 58], 45: 54, 47: [2, 54] }, { 28: 59, 43: 60, 44: [1, 58], 47: [2, 56] }, { 13: 62, 15: [1, 20], 18: [1, 61] }, { 33: [2, 86], 57: 63, 65: [2, 86], 72: [2, 86], 80: [2, 86], 81: [2, 86], 82: [2, 86], 83: [2, 86], 84: [2, 86], 85: [2, 86] }, { 33: [2, 40], 65: [2, 40], 72: [2, 40], 80: [2, 40], 81: [2, 40], 82: [2, 40], 83: [2, 40], 84: [2, 40], 85: [2, 40] }, { 33: [2, 41], 65: [2, 41], 72: [2, 41], 80: [2, 41], 81: [2, 41], 82: [2, 41], 83: [2, 41], 84: [2, 41], 85: [2, 41] }, { 20: 64, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 65, 47: [1, 66] }, { 30: 67, 33: [2, 58], 65: [2, 58], 72: [2, 58], 75: [2, 58], 80: [2, 58], 81: [2, 58], 82: [2, 58], 83: [2, 58], 84: [2, 58], 85: [2, 58] }, { 33: [2, 64], 35: 68, 65: [2, 64], 72: [2, 64], 75: [2, 64], 80: [2, 64], 81: [2, 64], 82: [2, 64], 83: [2, 64], 84: [2, 64], 85: [2, 64] }, { 21: 69, 23: [2, 50], 65: [2, 50], 72: [2, 50], 80: [2, 50], 81: [2, 50], 82: [2, 50], 83: [2, 50], 84: [2, 50], 85: [2, 50] }, { 33: [2, 90], 61: 70, 65: [2, 90], 72: [2, 90], 80: [2, 90], 81: [2, 90], 82: [2, 90], 83: [2, 90], 84: [2, 90], 85: [2, 90] }, { 20: 74, 33: [2, 80], 50: 71, 63: 72, 64: 75, 65: [1, 43], 69: 73, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 72: [1, 79] }, { 23: [2, 42], 33: [2, 42], 54: [2, 42], 65: [2, 42], 68: [2, 42], 72: [2, 42], 75: [2, 42], 80: [2, 42], 81: [2, 42], 82: [2, 42], 83: [2, 42], 84: [2, 42], 85: [2, 42], 87: [1, 50] }, { 20: 74, 53: 80, 54: [2, 84], 63: 81, 64: 75, 65: [1, 43], 69: 82, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 83, 47: [1, 66] }, { 47: [2, 55] }, { 4: 84, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 47: [2, 20] }, { 20: 85, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 86, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 26: 87, 47: [1, 66] }, { 47: [2, 57] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 19: [2, 11], 29: [2, 11], 34: [2, 11], 39: [2, 11], 44: [2, 11], 47: [2, 11], 48: [2, 11], 51: [2, 11], 55: [2, 11], 60: [2, 11] }, { 15: [2, 49], 18: [2, 49] }, { 20: 74, 33: [2, 88], 58: 88, 63: 89, 64: 75, 65: [1, 43], 69: 90, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 65: [2, 94], 66: 91, 68: [2, 94], 72: [2, 94], 80: [2, 94], 81: [2, 94], 82: [2, 94], 83: [2, 94], 84: [2, 94], 85: [2, 94] }, { 5: [2, 25], 14: [2, 25], 15: [2, 25], 19: [2, 25], 29: [2, 25], 34: [2, 25], 39: [2, 25], 44: [2, 25], 47: [2, 25], 48: [2, 25], 51: [2, 25], 55: [2, 25], 60: [2, 25] }, { 20: 92, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 31: 93, 33: [2, 60], 63: 94, 64: 75, 65: [1, 43], 69: 95, 70: 76, 71: 77, 72: [1, 78], 75: [2, 60], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 33: [2, 66], 36: 96, 63: 97, 64: 75, 65: [1, 43], 69: 98, 70: 76, 71: 77, 72: [1, 78], 75: [2, 66], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 22: 99, 23: [2, 52], 63: 100, 64: 75, 65: [1, 43], 69: 101, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 33: [2, 92], 62: 102, 63: 103, 64: 75, 65: [1, 43], 69: 104, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 105] }, { 33: [2, 79], 65: [2, 79], 72: [2, 79], 80: [2, 79], 81: [2, 79], 82: [2, 79], 83: [2, 79], 84: [2, 79], 85: [2, 79] }, { 33: [2, 81] }, { 23: [2, 27], 33: [2, 27], 54: [2, 27], 65: [2, 27], 68: [2, 27], 72: [2, 27], 75: [2, 27], 80: [2, 27], 81: [2, 27], 82: [2, 27], 83: [2, 27], 84: [2, 27], 85: [2, 27] }, { 23: [2, 28], 33: [2, 28], 54: [2, 28], 65: [2, 28], 68: [2, 28], 72: [2, 28], 75: [2, 28], 80: [2, 28], 81: [2, 28], 82: [2, 28], 83: [2, 28], 84: [2, 28], 85: [2, 28] }, { 23: [2, 30], 33: [2, 30], 54: [2, 30], 68: [2, 30], 71: 106, 72: [1, 107], 75: [2, 30] }, { 23: [2, 98], 33: [2, 98], 54: [2, 98], 68: [2, 98], 72: [2, 98], 75: [2, 98] }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 73: [1, 108], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 23: [2, 44], 33: [2, 44], 54: [2, 44], 65: [2, 44], 68: [2, 44], 72: [2, 44], 75: [2, 44], 80: [2, 44], 81: [2, 44], 82: [2, 44], 83: [2, 44], 84: [2, 44], 85: [2, 44], 87: [2, 44] }, { 54: [1, 109] }, { 54: [2, 83], 65: [2, 83], 72: [2, 83], 80: [2, 83], 81: [2, 83], 82: [2, 83], 83: [2, 83], 84: [2, 83], 85: [2, 83] }, { 54: [2, 85] }, { 5: [2, 13], 14: [2, 13], 15: [2, 13], 19: [2, 13], 29: [2, 13], 34: [2, 13], 39: [2, 13], 44: [2, 13], 47: [2, 13], 48: [2, 13], 51: [2, 13], 55: [2, 13], 60: [2, 13] }, { 38: 55, 39: [1, 57], 43: 56, 44: [1, 58], 45: 111, 46: 110, 47: [2, 76] }, { 33: [2, 70], 40: 112, 65: [2, 70], 72: [2, 70], 75: [2, 70], 80: [2, 70], 81: [2, 70], 82: [2, 70], 83: [2, 70], 84: [2, 70], 85: [2, 70] }, { 47: [2, 18] }, { 5: [2, 14], 14: [2, 14], 15: [2, 14], 19: [2, 14], 29: [2, 14], 34: [2, 14], 39: [2, 14], 44: [2, 14], 47: [2, 14], 48: [2, 14], 51: [2, 14], 55: [2, 14], 60: [2, 14] }, { 33: [1, 113] }, { 33: [2, 87], 65: [2, 87], 72: [2, 87], 80: [2, 87], 81: [2, 87], 82: [2, 87], 83: [2, 87], 84: [2, 87], 85: [2, 87] }, { 33: [2, 89] }, { 20: 74, 63: 115, 64: 75, 65: [1, 43], 67: 114, 68: [2, 96], 69: 116, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 117] }, { 32: 118, 33: [2, 62], 74: 119, 75: [1, 120] }, { 33: [2, 59], 65: [2, 59], 72: [2, 59], 75: [2, 59], 80: [2, 59], 81: [2, 59], 82: [2, 59], 83: [2, 59], 84: [2, 59], 85: [2, 59] }, { 33: [2, 61], 75: [2, 61] }, { 33: [2, 68], 37: 121, 74: 122, 75: [1, 120] }, { 33: [2, 65], 65: [2, 65], 72: [2, 65], 75: [2, 65], 80: [2, 65], 81: [2, 65], 82: [2, 65], 83: [2, 65], 84: [2, 65], 85: [2, 65] }, { 33: [2, 67], 75: [2, 67] }, { 23: [1, 123] }, { 23: [2, 51], 65: [2, 51], 72: [2, 51], 80: [2, 51], 81: [2, 51], 82: [2, 51], 83: [2, 51], 84: [2, 51], 85: [2, 51] }, { 23: [2, 53] }, { 33: [1, 124] }, { 33: [2, 91], 65: [2, 91], 72: [2, 91], 80: [2, 91], 81: [2, 91], 82: [2, 91], 83: [2, 91], 84: [2, 91], 85: [2, 91] }, { 33: [2, 93] }, { 5: [2, 22], 14: [2, 22], 15: [2, 22], 19: [2, 22], 29: [2, 22], 34: [2, 22], 39: [2, 22], 44: [2, 22], 47: [2, 22], 48: [2, 22], 51: [2, 22], 55: [2, 22], 60: [2, 22] }, { 23: [2, 99], 33: [2, 99], 54: [2, 99], 68: [2, 99], 72: [2, 99], 75: [2, 99] }, { 73: [1, 108] }, { 20: 74, 63: 125, 64: 75, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 23], 14: [2, 23], 15: [2, 23], 19: [2, 23], 29: [2, 23], 34: [2, 23], 39: [2, 23], 44: [2, 23], 47: [2, 23], 48: [2, 23], 51: [2, 23], 55: [2, 23], 60: [2, 23] }, { 47: [2, 19] }, { 47: [2, 77] }, { 20: 74, 33: [2, 72], 41: 126, 63: 127, 64: 75, 65: [1, 43], 69: 128, 70: 76, 71: 77, 72: [1, 78], 75: [2, 72], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 24], 14: [2, 24], 15: [2, 24], 19: [2, 24], 29: [2, 24], 34: [2, 24], 39: [2, 24], 44: [2, 24], 47: [2, 24], 48: [2, 24], 51: [2, 24], 55: [2, 24], 60: [2, 24] }, { 68: [1, 129] }, { 65: [2, 95], 68: [2, 95], 72: [2, 95], 80: [2, 95], 81: [2, 95], 82: [2, 95], 83: [2, 95], 84: [2, 95], 85: [2, 95] }, { 68: [2, 97] }, { 5: [2, 21], 14: [2, 21], 15: [2, 21], 19: [2, 21], 29: [2, 21], 34: [2, 21], 39: [2, 21], 44: [2, 21], 47: [2, 21], 48: [2, 21], 51: [2, 21], 55: [2, 21], 60: [2, 21] }, { 33: [1, 130] }, { 33: [2, 63] }, { 72: [1, 132], 76: 131 }, { 33: [1, 133] }, { 33: [2, 69] }, { 15: [2, 12], 18: [2, 12] }, { 14: [2, 26], 15: [2, 26], 19: [2, 26], 29: [2, 26], 34: [2, 26], 47: [2, 26], 48: [2, 26], 51: [2, 26], 55: [2, 26], 60: [2, 26] }, { 23: [2, 31], 33: [2, 31], 54: [2, 31], 68: [2, 31], 72: [2, 31], 75: [2, 31] }, { 33: [2, 74], 42: 134, 74: 135, 75: [1, 120] }, { 33: [2, 71], 65: [2, 71], 72: [2, 71], 75: [2, 71], 80: [2, 71], 81: [2, 71], 82: [2, 71], 83: [2, 71], 84: [2, 71], 85: [2, 71] }, { 33: [2, 73], 75: [2, 73] }, { 23: [2, 29], 33: [2, 29], 54: [2, 29], 65: [2, 29], 68: [2, 29], 72: [2, 29], 75: [2, 29], 80: [2, 29], 81: [2, 29], 82: [2, 29], 83: [2, 29], 84: [2, 29], 85: [2, 29] }, { 14: [2, 15], 15: [2, 15], 19: [2, 15], 29: [2, 15], 34: [2, 15], 39: [2, 15], 44: [2, 15], 47: [2, 15], 48: [2, 15], 51: [2, 15], 55: [2, 15], 60: [2, 15] }, { 72: [1, 137], 77: [1, 136] }, { 72: [2, 100], 77: [2, 100] }, { 14: [2, 16], 15: [2, 16], 19: [2, 16], 29: [2, 16], 34: [2, 16], 44: [2, 16], 47: [2, 16], 48: [2, 16], 51: [2, 16], 55: [2, 16], 60: [2, 16] }, { 33: [1, 138] }, { 33: [2, 75] }, { 33: [2, 32] }, { 72: [2, 101], 77: [2, 101] }, { 14: [2, 17], 15: [2, 17], 19: [2, 17], 29: [2, 17], 34: [2, 17], 39: [2, 17], 44: [2, 17], 47: [2, 17], 48: [2, 17], 51: [2, 17], 55: [2, 17], 60: [2, 17] }],
	        defaultActions: { 4: [2, 1], 54: [2, 55], 56: [2, 20], 60: [2, 57], 73: [2, 81], 82: [2, 85], 86: [2, 18], 90: [2, 89], 101: [2, 53], 104: [2, 93], 110: [2, 19], 111: [2, 77], 116: [2, 97], 119: [2, 63], 122: [2, 69], 135: [2, 75], 136: [2, 32] },
	        parseError: function parseError(str, hash) {
	            throw new Error(str);
	        },
	        parse: function parse(input) {
	            var self = this,
	                stack = [0],
	                vstack = [null],
	                lstack = [],
	                table = this.table,
	                yytext = "",
	                yylineno = 0,
	                yyleng = 0,
	                recovering = 0,
	                TERROR = 2,
	                EOF = 1;
	            this.lexer.setInput(input);
	            this.lexer.yy = this.yy;
	            this.yy.lexer = this.lexer;
	            this.yy.parser = this;
	            if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {};
	            var yyloc = this.lexer.yylloc;
	            lstack.push(yyloc);
	            var ranges = this.lexer.options && this.lexer.options.ranges;
	            if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError;
	            function popStack(n) {
	                stack.length = stack.length - 2 * n;
	                vstack.length = vstack.length - n;
	                lstack.length = lstack.length - n;
	            }
	            function lex() {
	                var token;
	                token = self.lexer.lex() || 1;
	                if (typeof token !== "number") {
	                    token = self.symbols_[token] || token;
	                }
	                return token;
	            }
	            var symbol,
	                preErrorSymbol,
	                state,
	                action,
	                a,
	                r,
	                yyval = {},
	                p,
	                len,
	                newState,
	                expected;
	            while (true) {
	                state = stack[stack.length - 1];
	                if (this.defaultActions[state]) {
	                    action = this.defaultActions[state];
	                } else {
	                    if (symbol === null || typeof symbol == "undefined") {
	                        symbol = lex();
	                    }
	                    action = table[state] && table[state][symbol];
	                }
	                if (typeof action === "undefined" || !action.length || !action[0]) {
	                    var errStr = "";
	                    if (!recovering) {
	                        expected = [];
	                        for (p in table[state]) if (this.terminals_[p] && p > 2) {
	                            expected.push("'" + this.terminals_[p] + "'");
	                        }
	                        if (this.lexer.showPosition) {
	                            errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
	                        } else {
	                            errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
	                        }
	                        this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected });
	                    }
	                }
	                if (action[0] instanceof Array && action.length > 1) {
	                    throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
	                }
	                switch (action[0]) {
	                    case 1:
	                        stack.push(symbol);
	                        vstack.push(this.lexer.yytext);
	                        lstack.push(this.lexer.yylloc);
	                        stack.push(action[1]);
	                        symbol = null;
	                        if (!preErrorSymbol) {
	                            yyleng = this.lexer.yyleng;
	                            yytext = this.lexer.yytext;
	                            yylineno = this.lexer.yylineno;
	                            yyloc = this.lexer.yylloc;
	                            if (recovering > 0) recovering--;
	                        } else {
	                            symbol = preErrorSymbol;
	                            preErrorSymbol = null;
	                        }
	                        break;
	                    case 2:
	                        len = this.productions_[action[1]][1];
	                        yyval.$ = vstack[vstack.length - len];
	                        yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column };
	                        if (ranges) {
	                            yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
	                        }
	                        r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
	                        if (typeof r !== "undefined") {
	                            return r;
	                        }
	                        if (len) {
	                            stack = stack.slice(0, -1 * len * 2);
	                            vstack = vstack.slice(0, -1 * len);
	                            lstack = lstack.slice(0, -1 * len);
	                        }
	                        stack.push(this.productions_[action[1]][0]);
	                        vstack.push(yyval.$);
	                        lstack.push(yyval._$);
	                        newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
	                        stack.push(newState);
	                        break;
	                    case 3:
	                        return true;
	                }
	            }
	            return true;
	        }
	    };
	    /* Jison generated lexer */
	    var lexer = (function () {
	        var lexer = { EOF: 1,
	            parseError: function parseError(str, hash) {
	                if (this.yy.parser) {
	                    this.yy.parser.parseError(str, hash);
	                } else {
	                    throw new Error(str);
	                }
	            },
	            setInput: function setInput(input) {
	                this._input = input;
	                this._more = this._less = this.done = false;
	                this.yylineno = this.yyleng = 0;
	                this.yytext = this.matched = this.match = '';
	                this.conditionStack = ['INITIAL'];
	                this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 };
	                if (this.options.ranges) this.yylloc.range = [0, 0];
	                this.offset = 0;
	                return this;
	            },
	            input: function input() {
	                var ch = this._input[0];
	                this.yytext += ch;
	                this.yyleng++;
	                this.offset++;
	                this.match += ch;
	                this.matched += ch;
	                var lines = ch.match(/(?:\r\n?|\n).*/g);
	                if (lines) {
	                    this.yylineno++;
	                    this.yylloc.last_line++;
	                } else {
	                    this.yylloc.last_column++;
	                }
	                if (this.options.ranges) this.yylloc.range[1]++;

	                this._input = this._input.slice(1);
	                return ch;
	            },
	            unput: function unput(ch) {
	                var len = ch.length;
	                var lines = ch.split(/(?:\r\n?|\n)/g);

	                this._input = ch + this._input;
	                this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
	                //this.yyleng -= len;
	                this.offset -= len;
	                var oldLines = this.match.split(/(?:\r\n?|\n)/g);
	                this.match = this.match.substr(0, this.match.length - 1);
	                this.matched = this.matched.substr(0, this.matched.length - 1);

	                if (lines.length - 1) this.yylineno -= lines.length - 1;
	                var r = this.yylloc.range;

	                this.yylloc = { first_line: this.yylloc.first_line,
	                    last_line: this.yylineno + 1,
	                    first_column: this.yylloc.first_column,
	                    last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
	                };

	                if (this.options.ranges) {
	                    this.yylloc.range = [r[0], r[0] + this.yyleng - len];
	                }
	                return this;
	            },
	            more: function more() {
	                this._more = true;
	                return this;
	            },
	            less: function less(n) {
	                this.unput(this.match.slice(n));
	            },
	            pastInput: function pastInput() {
	                var past = this.matched.substr(0, this.matched.length - this.match.length);
	                return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
	            },
	            upcomingInput: function upcomingInput() {
	                var next = this.match;
	                if (next.length < 20) {
	                    next += this._input.substr(0, 20 - next.length);
	                }
	                return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
	            },
	            showPosition: function showPosition() {
	                var pre = this.pastInput();
	                var c = new Array(pre.length + 1).join("-");
	                return pre + this.upcomingInput() + "\n" + c + "^";
	            },
	            next: function next() {
	                if (this.done) {
	                    return this.EOF;
	                }
	                if (!this._input) this.done = true;

	                var token, match, tempMatch, index, col, lines;
	                if (!this._more) {
	                    this.yytext = '';
	                    this.match = '';
	                }
	                var rules = this._currentRules();
	                for (var i = 0; i < rules.length; i++) {
	                    tempMatch = this._input.match(this.rules[rules[i]]);
	                    if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
	                        match = tempMatch;
	                        index = i;
	                        if (!this.options.flex) break;
	                    }
	                }
	                if (match) {
	                    lines = match[0].match(/(?:\r\n?|\n).*/g);
	                    if (lines) this.yylineno += lines.length;
	                    this.yylloc = { first_line: this.yylloc.last_line,
	                        last_line: this.yylineno + 1,
	                        first_column: this.yylloc.last_column,
	                        last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length };
	                    this.yytext += match[0];
	                    this.match += match[0];
	                    this.matches = match;
	                    this.yyleng = this.yytext.length;
	                    if (this.options.ranges) {
	                        this.yylloc.range = [this.offset, this.offset += this.yyleng];
	                    }
	                    this._more = false;
	                    this._input = this._input.slice(match[0].length);
	                    this.matched += match[0];
	                    token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]);
	                    if (this.done && this._input) this.done = false;
	                    if (token) return token;else return;
	                }
	                if (this._input === "") {
	                    return this.EOF;
	                } else {
	                    return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno });
	                }
	            },
	            lex: function lex() {
	                var r = this.next();
	                if (typeof r !== 'undefined') {
	                    return r;
	                } else {
	                    return this.lex();
	                }
	            },
	            begin: function begin(condition) {
	                this.conditionStack.push(condition);
	            },
	            popState: function popState() {
	                return this.conditionStack.pop();
	            },
	            _currentRules: function _currentRules() {
	                return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
	            },
	            topState: function topState() {
	                return this.conditionStack[this.conditionStack.length - 2];
	            },
	            pushState: function begin(condition) {
	                this.begin(condition);
	            } };
	        lexer.options = {};
	        lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {

	            function strip(start, end) {
	                return yy_.yytext = yy_.yytext.substring(start, yy_.yyleng - end + start);
	            }

	            var YYSTATE = YY_START;
	            switch ($avoiding_name_collisions) {
	                case 0:
	                    if (yy_.yytext.slice(-2) === "\\\\") {
	                        strip(0, 1);
	                        this.begin("mu");
	                    } else if (yy_.yytext.slice(-1) === "\\") {
	                        strip(0, 1);
	                        this.begin("emu");
	                    } else {
	                        this.begin("mu");
	                    }
	                    if (yy_.yytext) return 15;

	                    break;
	                case 1:
	                    return 15;
	                    break;
	                case 2:
	                    this.popState();
	                    return 15;

	                    break;
	                case 3:
	                    this.begin('raw');return 15;
	                    break;
	                case 4:
	                    this.popState();
	                    // Should be using `this.topState()` below, but it currently
	                    // returns the second top instead of the first top. Opened an
	                    // issue about it at https://github.com/zaach/jison/issues/291
	                    if (this.conditionStack[this.conditionStack.length - 1] === 'raw') {
	                        return 15;
	                    } else {
	                        strip(5, 9);
	                        return 'END_RAW_BLOCK';
	                    }

	                    break;
	                case 5:
	                    return 15;
	                    break;
	                case 6:
	                    this.popState();
	                    return 14;

	                    break;
	                case 7:
	                    return 65;
	                    break;
	                case 8:
	                    return 68;
	                    break;
	                case 9:
	                    return 19;
	                    break;
	                case 10:
	                    this.popState();
	                    this.begin('raw');
	                    return 23;

	                    break;
	                case 11:
	                    return 55;
	                    break;
	                case 12:
	                    return 60;
	                    break;
	                case 13:
	                    return 29;
	                    break;
	                case 14:
	                    return 47;
	                    break;
	                case 15:
	                    this.popState();return 44;
	                    break;
	                case 16:
	                    this.popState();return 44;
	                    break;
	                case 17:
	                    return 34;
	                    break;
	                case 18:
	                    return 39;
	                    break;
	                case 19:
	                    return 51;
	                    break;
	                case 20:
	                    return 48;
	                    break;
	                case 21:
	                    this.unput(yy_.yytext);
	                    this.popState();
	                    this.begin('com');

	                    break;
	                case 22:
	                    this.popState();
	                    return 14;

	                    break;
	                case 23:
	                    return 48;
	                    break;
	                case 24:
	                    return 73;
	                    break;
	                case 25:
	                    return 72;
	                    break;
	                case 26:
	                    return 72;
	                    break;
	                case 27:
	                    return 87;
	                    break;
	                case 28:
	                    // ignore whitespace
	                    break;
	                case 29:
	                    this.popState();return 54;
	                    break;
	                case 30:
	                    this.popState();return 33;
	                    break;
	                case 31:
	                    yy_.yytext = strip(1, 2).replace(/\\"/g, '"');return 80;
	                    break;
	                case 32:
	                    yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 80;
	                    break;
	                case 33:
	                    return 85;
	                    break;
	                case 34:
	                    return 82;
	                    break;
	                case 35:
	                    return 82;
	                    break;
	                case 36:
	                    return 83;
	                    break;
	                case 37:
	                    return 84;
	                    break;
	                case 38:
	                    return 81;
	                    break;
	                case 39:
	                    return 75;
	                    break;
	                case 40:
	                    return 77;
	                    break;
	                case 41:
	                    return 72;
	                    break;
	                case 42:
	                    yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1');return 72;
	                    break;
	                case 43:
	                    return 'INVALID';
	                    break;
	                case 44:
	                    return 5;
	                    break;
	            }
	        };
	        lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{(?=[^\/]))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]+?(?=(\{\{\{\{)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#>)/, /^(?:\{\{(~)?#\*?)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?\*?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[(\\\]|[^\]])*\])/, /^(?:.)/, /^(?:$)/];
	        lexer.conditions = { "mu": { "rules": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [6], "inclusive": false }, "raw": { "rules": [3, 4, 5], "inclusive": false }, "INITIAL": { "rules": [0, 1, 44], "inclusive": true } };
	        return lexer;
	    })();
	    parser.lexer = lexer;
	    function Parser() {
	        this.yy = {};
	    }Parser.prototype = parser;parser.Parser = Parser;
	    return new Parser();
	})();exports["default"] = handlebars;
	module.exports = exports["default"];

/***/ }),
/* 43 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _visitor = __webpack_require__(44);

	var _visitor2 = _interopRequireDefault(_visitor);

	function WhitespaceControl() {
	  var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

	  this.options = options;
	}
	WhitespaceControl.prototype = new _visitor2['default']();

	WhitespaceControl.prototype.Program = function (program) {
	  var doStandalone = !this.options.ignoreStandalone;

	  var isRoot = !this.isRootSeen;
	  this.isRootSeen = true;

	  var body = program.body;
	  for (var i = 0, l = body.length; i < l; i++) {
	    var current = body[i],
	        strip = this.accept(current);

	    if (!strip) {
	      continue;
	    }

	    var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
	        _isNextWhitespace = isNextWhitespace(body, i, isRoot),
	        openStandalone = strip.openStandalone && _isPrevWhitespace,
	        closeStandalone = strip.closeStandalone && _isNextWhitespace,
	        inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;

	    if (strip.close) {
	      omitRight(body, i, true);
	    }
	    if (strip.open) {
	      omitLeft(body, i, true);
	    }

	    if (doStandalone && inlineStandalone) {
	      omitRight(body, i);

	      if (omitLeft(body, i)) {
	        // If we are on a standalone node, save the indent info for partials
	        if (current.type === 'PartialStatement') {
	          // Pull out the whitespace from the final line
	          current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
	        }
	      }
	    }
	    if (doStandalone && openStandalone) {
	      omitRight((current.program || current.inverse).body);

	      // Strip out the previous content node if it's whitespace only
	      omitLeft(body, i);
	    }
	    if (doStandalone && closeStandalone) {
	      // Always strip the next node
	      omitRight(body, i);

	      omitLeft((current.inverse || current.program).body);
	    }
	  }

	  return program;
	};

	WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) {
	  this.accept(block.program);
	  this.accept(block.inverse);

	  // Find the inverse program that is involed with whitespace stripping.
	  var program = block.program || block.inverse,
	      inverse = block.program && block.inverse,
	      firstInverse = inverse,
	      lastInverse = inverse;

	  if (inverse && inverse.chained) {
	    firstInverse = inverse.body[0].program;

	    // Walk the inverse chain to find the last inverse that is actually in the chain.
	    while (lastInverse.chained) {
	      lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
	    }
	  }

	  var strip = {
	    open: block.openStrip.open,
	    close: block.closeStrip.close,

	    // Determine the standalone candiacy. Basically flag our content as being possibly standalone
	    // so our parent can determine if we actually are standalone
	    openStandalone: isNextWhitespace(program.body),
	    closeStandalone: isPrevWhitespace((firstInverse || program).body)
	  };

	  if (block.openStrip.close) {
	    omitRight(program.body, null, true);
	  }

	  if (inverse) {
	    var inverseStrip = block.inverseStrip;

	    if (inverseStrip.open) {
	      omitLeft(program.body, null, true);
	    }

	    if (inverseStrip.close) {
	      omitRight(firstInverse.body, null, true);
	    }
	    if (block.closeStrip.open) {
	      omitLeft(lastInverse.body, null, true);
	    }

	    // Find standalone else statments
	    if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) {
	      omitLeft(program.body);
	      omitRight(firstInverse.body);
	    }
	  } else if (block.closeStrip.open) {
	    omitLeft(program.body, null, true);
	  }

	  return strip;
	};

	WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) {
	  return mustache.strip;
	};

	WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) {
	  /* istanbul ignore next */
	  var strip = node.strip || {};
	  return {
	    inlineStandalone: true,
	    open: strip.open,
	    close: strip.close
	  };
	};

	function isPrevWhitespace(body, i, isRoot) {
	  if (i === undefined) {
	    i = body.length;
	  }

	  // Nodes that end with newlines are considered whitespace (but are special
	  // cased for strip operations)
	  var prev = body[i - 1],
	      sibling = body[i - 2];
	  if (!prev) {
	    return isRoot;
	  }

	  if (prev.type === 'ContentStatement') {
	    return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original);
	  }
	}
	function isNextWhitespace(body, i, isRoot) {
	  if (i === undefined) {
	    i = -1;
	  }

	  var next = body[i + 1],
	      sibling = body[i + 2];
	  if (!next) {
	    return isRoot;
	  }

	  if (next.type === 'ContentStatement') {
	    return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original);
	  }
	}

	// Marks the node to the right of the position as omitted.
	// I.e. {{foo}}' ' will mark the ' ' node as omitted.
	//
	// If i is undefined, then the first child will be marked as such.
	//
	// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
	// content is met.
	function omitRight(body, i, multiple) {
	  var current = body[i == null ? 0 : i + 1];
	  if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) {
	    return;
	  }

	  var original = current.value;
	  current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '');
	  current.rightStripped = current.value !== original;
	}

	// Marks the node to the left of the position as omitted.
	// I.e. ' '{{foo}} will mark the ' ' node as omitted.
	//
	// If i is undefined then the last child will be marked as such.
	//
	// If mulitple is truthy then all whitespace will be stripped out until non-whitespace
	// content is met.
	function omitLeft(body, i, multiple) {
	  var current = body[i == null ? body.length - 1 : i - 1];
	  if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) {
	    return;
	  }

	  // We omit the last node if it's whitespace only and not preceded by a non-content node.
	  var original = current.value;
	  current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
	  current.leftStripped = current.value !== original;
	  return current.leftStripped;
	}

	exports['default'] = WhitespaceControl;
	module.exports = exports['default'];

/***/ }),
/* 44 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	function Visitor() {
	  this.parents = [];
	}

	Visitor.prototype = {
	  constructor: Visitor,
	  mutating: false,

	  // Visits a given value. If mutating, will replace the value if necessary.
	  acceptKey: function acceptKey(node, name) {
	    var value = this.accept(node[name]);
	    if (this.mutating) {
	      // Hacky sanity check: This may have a few false positives for type for the helper
	      // methods but will generally do the right thing without a lot of overhead.
	      if (value && !Visitor.prototype[value.type]) {
	        throw new _exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
	      }
	      node[name] = value;
	    }
	  },

	  // Performs an accept operation with added sanity check to ensure
	  // required keys are not removed.
	  acceptRequired: function acceptRequired(node, name) {
	    this.acceptKey(node, name);

	    if (!node[name]) {
	      throw new _exception2['default'](node.type + ' requires ' + name);
	    }
	  },

	  // Traverses a given array. If mutating, empty respnses will be removed
	  // for child elements.
	  acceptArray: function acceptArray(array) {
	    for (var i = 0, l = array.length; i < l; i++) {
	      this.acceptKey(array, i);

	      if (!array[i]) {
	        array.splice(i, 1);
	        i--;
	        l--;
	      }
	    }
	  },

	  accept: function accept(object) {
	    if (!object) {
	      return;
	    }

	    /* istanbul ignore next: Sanity code */
	    if (!this[object.type]) {
	      throw new _exception2['default']('Unknown type: ' + object.type, object);
	    }

	    if (this.current) {
	      this.parents.unshift(this.current);
	    }
	    this.current = object;

	    var ret = this[object.type](object);

	    this.current = this.parents.shift();

	    if (!this.mutating || ret) {
	      return ret;
	    } else if (ret !== false) {
	      return object;
	    }
	  },

	  Program: function Program(program) {
	    this.acceptArray(program.body);
	  },

	  MustacheStatement: visitSubExpression,
	  Decorator: visitSubExpression,

	  BlockStatement: visitBlock,
	  DecoratorBlock: visitBlock,

	  PartialStatement: visitPartial,
	  PartialBlockStatement: function PartialBlockStatement(partial) {
	    visitPartial.call(this, partial);

	    this.acceptKey(partial, 'program');
	  },

	  ContentStatement: function ContentStatement() /* content */{},
	  CommentStatement: function CommentStatement() /* comment */{},

	  SubExpression: visitSubExpression,

	  PathExpression: function PathExpression() /* path */{},

	  StringLiteral: function StringLiteral() /* string */{},
	  NumberLiteral: function NumberLiteral() /* number */{},
	  BooleanLiteral: function BooleanLiteral() /* bool */{},
	  UndefinedLiteral: function UndefinedLiteral() /* literal */{},
	  NullLiteral: function NullLiteral() /* literal */{},

	  Hash: function Hash(hash) {
	    this.acceptArray(hash.pairs);
	  },
	  HashPair: function HashPair(pair) {
	    this.acceptRequired(pair, 'value');
	  }
	};

	function visitSubExpression(mustache) {
	  this.acceptRequired(mustache, 'path');
	  this.acceptArray(mustache.params);
	  this.acceptKey(mustache, 'hash');
	}
	function visitBlock(block) {
	  visitSubExpression.call(this, block);

	  this.acceptKey(block, 'program');
	  this.acceptKey(block, 'inverse');
	}
	function visitPartial(partial) {
	  this.acceptRequired(partial, 'name');
	  this.acceptArray(partial.params);
	  this.acceptKey(partial, 'hash');
	}

	exports['default'] = Visitor;
	module.exports = exports['default'];

/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;
	exports.SourceLocation = SourceLocation;
	exports.id = id;
	exports.stripFlags = stripFlags;
	exports.stripComment = stripComment;
	exports.preparePath = preparePath;
	exports.prepareMustache = prepareMustache;
	exports.prepareRawBlock = prepareRawBlock;
	exports.prepareBlock = prepareBlock;
	exports.prepareProgram = prepareProgram;
	exports.preparePartialBlock = preparePartialBlock;

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	function validateClose(open, close) {
	  close = close.path ? close.path.original : close;

	  if (open.path.original !== close) {
	    var errorNode = { loc: open.path.loc };

	    throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode);
	  }
	}

	function SourceLocation(source, locInfo) {
	  this.source = source;
	  this.start = {
	    line: locInfo.first_line,
	    column: locInfo.first_column
	  };
	  this.end = {
	    line: locInfo.last_line,
	    column: locInfo.last_column
	  };
	}

	function id(token) {
	  if (/^\[.*\]$/.test(token)) {
	    return token.substring(1, token.length - 1);
	  } else {
	    return token;
	  }
	}

	function stripFlags(open, close) {
	  return {
	    open: open.charAt(2) === '~',
	    close: close.charAt(close.length - 3) === '~'
	  };
	}

	function stripComment(comment) {
	  return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, '');
	}

	function preparePath(data, parts, loc) {
	  loc = this.locInfo(loc);

	  var original = data ? '@' : '',
	      dig = [],
	      depth = 0;

	  for (var i = 0, l = parts.length; i < l; i++) {
	    var part = parts[i].part,

	    // If we have [] syntax then we do not treat path references as operators,
	    // i.e. foo.[this] resolves to approximately context.foo['this']
	    isLiteral = parts[i].original !== part;
	    original += (parts[i].separator || '') + part;

	    if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
	      if (dig.length > 0) {
	        throw new _exception2['default']('Invalid path: ' + original, { loc: loc });
	      } else if (part === '..') {
	        depth++;
	      }
	    } else {
	      dig.push(part);
	    }
	  }

	  return {
	    type: 'PathExpression',
	    data: data,
	    depth: depth,
	    parts: dig,
	    original: original,
	    loc: loc
	  };
	}

	function prepareMustache(path, params, hash, open, strip, locInfo) {
	  // Must use charAt to support IE pre-10
	  var escapeFlag = open.charAt(3) || open.charAt(2),
	      escaped = escapeFlag !== '{' && escapeFlag !== '&';

	  var decorator = /\*/.test(open);
	  return {
	    type: decorator ? 'Decorator' : 'MustacheStatement',
	    path: path,
	    params: params,
	    hash: hash,
	    escaped: escaped,
	    strip: strip,
	    loc: this.locInfo(locInfo)
	  };
	}

	function prepareRawBlock(openRawBlock, contents, close, locInfo) {
	  validateClose(openRawBlock, close);

	  locInfo = this.locInfo(locInfo);
	  var program = {
	    type: 'Program',
	    body: contents,
	    strip: {},
	    loc: locInfo
	  };

	  return {
	    type: 'BlockStatement',
	    path: openRawBlock.path,
	    params: openRawBlock.params,
	    hash: openRawBlock.hash,
	    program: program,
	    openStrip: {},
	    inverseStrip: {},
	    closeStrip: {},
	    loc: locInfo
	  };
	}

	function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
	  if (close && close.path) {
	    validateClose(openBlock, close);
	  }

	  var decorator = /\*/.test(openBlock.open);

	  program.blockParams = openBlock.blockParams;

	  var inverse = undefined,
	      inverseStrip = undefined;

	  if (inverseAndProgram) {
	    if (decorator) {
	      throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram);
	    }

	    if (inverseAndProgram.chain) {
	      inverseAndProgram.program.body[0].closeStrip = close.strip;
	    }

	    inverseStrip = inverseAndProgram.strip;
	    inverse = inverseAndProgram.program;
	  }

	  if (inverted) {
	    inverted = inverse;
	    inverse = program;
	    program = inverted;
	  }

	  return {
	    type: decorator ? 'DecoratorBlock' : 'BlockStatement',
	    path: openBlock.path,
	    params: openBlock.params,
	    hash: openBlock.hash,
	    program: program,
	    inverse: inverse,
	    openStrip: openBlock.strip,
	    inverseStrip: inverseStrip,
	    closeStrip: close && close.strip,
	    loc: this.locInfo(locInfo)
	  };
	}

	function prepareProgram(statements, loc) {
	  if (!loc && statements.length) {
	    var firstLoc = statements[0].loc,
	        lastLoc = statements[statements.length - 1].loc;

	    /* istanbul ignore else */
	    if (firstLoc && lastLoc) {
	      loc = {
	        source: firstLoc.source,
	        start: {
	          line: firstLoc.start.line,
	          column: firstLoc.start.column
	        },
	        end: {
	          line: lastLoc.end.line,
	          column: lastLoc.end.column
	        }
	      };
	    }
	  }

	  return {
	    type: 'Program',
	    body: statements,
	    strip: {},
	    loc: loc
	  };
	}

	function preparePartialBlock(open, program, close, locInfo) {
	  validateClose(open, close);

	  return {
	    type: 'PartialBlockStatement',
	    name: open.path,
	    params: open.params,
	    hash: open.hash,
	    program: program,
	    openStrip: open.strip,
	    closeStrip: close && close.strip,
	    loc: this.locInfo(locInfo)
	  };
	}

/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {

	/* eslint-disable new-cap */

	'use strict';

	var _Object$create = __webpack_require__(47)['default'];

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;
	exports.Compiler = Compiler;
	exports.precompile = precompile;
	exports.compile = compile;

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	var _utils = __webpack_require__(5);

	var _ast = __webpack_require__(40);

	var _ast2 = _interopRequireDefault(_ast);

	var slice = [].slice;

	function Compiler() {}

	// the foundHelper register will disambiguate helper lookup from finding a
	// function in a context. This is necessary for mustache compatibility, which
	// requires that context functions in blocks are evaluated by blockHelperMissing,
	// and then proceed as if the resulting value was provided to blockHelperMissing.

	Compiler.prototype = {
	  compiler: Compiler,

	  equals: function equals(other) {
	    var len = this.opcodes.length;
	    if (other.opcodes.length !== len) {
	      return false;
	    }

	    for (var i = 0; i < len; i++) {
	      var opcode = this.opcodes[i],
	          otherOpcode = other.opcodes[i];
	      if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
	        return false;
	      }
	    }

	    // We know that length is the same between the two arrays because they are directly tied
	    // to the opcode behavior above.
	    len = this.children.length;
	    for (var i = 0; i < len; i++) {
	      if (!this.children[i].equals(other.children[i])) {
	        return false;
	      }
	    }

	    return true;
	  },

	  guid: 0,

	  compile: function compile(program, options) {
	    this.sourceNode = [];
	    this.opcodes = [];
	    this.children = [];
	    this.options = options;
	    this.stringParams = options.stringParams;
	    this.trackIds = options.trackIds;

	    options.blockParams = options.blockParams || [];

	    options.knownHelpers = _utils.extend(_Object$create(null), {
	      'helperMissing': true,
	      'blockHelperMissing': true,
	      'each': true,
	      'if': true,
	      'unless': true,
	      'with': true,
	      'log': true,
	      'lookup': true
	    }, options.knownHelpers);

	    return this.accept(program);
	  },

	  compileProgram: function compileProgram(program) {
	    var childCompiler = new this.compiler(),
	        // eslint-disable-line new-cap
	    result = childCompiler.compile(program, this.options),
	        guid = this.guid++;

	    this.usePartial = this.usePartial || result.usePartial;

	    this.children[guid] = result;
	    this.useDepths = this.useDepths || result.useDepths;

	    return guid;
	  },

	  accept: function accept(node) {
	    /* istanbul ignore next: Sanity code */
	    if (!this[node.type]) {
	      throw new _exception2['default']('Unknown type: ' + node.type, node);
	    }

	    this.sourceNode.unshift(node);
	    var ret = this[node.type](node);
	    this.sourceNode.shift();
	    return ret;
	  },

	  Program: function Program(program) {
	    this.options.blockParams.unshift(program.blockParams);

	    var body = program.body,
	        bodyLength = body.length;
	    for (var i = 0; i < bodyLength; i++) {
	      this.accept(body[i]);
	    }

	    this.options.blockParams.shift();

	    this.isSimple = bodyLength === 1;
	    this.blockParams = program.blockParams ? program.blockParams.length : 0;

	    return this;
	  },

	  BlockStatement: function BlockStatement(block) {
	    transformLiteralToPath(block);

	    var program = block.program,
	        inverse = block.inverse;

	    program = program && this.compileProgram(program);
	    inverse = inverse && this.compileProgram(inverse);

	    var type = this.classifySexpr(block);

	    if (type === 'helper') {
	      this.helperSexpr(block, program, inverse);
	    } else if (type === 'simple') {
	      this.simpleSexpr(block);

	      // now that the simple mustache is resolved, we need to
	      // evaluate it by executing `blockHelperMissing`
	      this.opcode('pushProgram', program);
	      this.opcode('pushProgram', inverse);
	      this.opcode('emptyHash');
	      this.opcode('blockValue', block.path.original);
	    } else {
	      this.ambiguousSexpr(block, program, inverse);

	      // now that the simple mustache is resolved, we need to
	      // evaluate it by executing `blockHelperMissing`
	      this.opcode('pushProgram', program);
	      this.opcode('pushProgram', inverse);
	      this.opcode('emptyHash');
	      this.opcode('ambiguousBlockValue');
	    }

	    this.opcode('append');
	  },

	  DecoratorBlock: function DecoratorBlock(decorator) {
	    var program = decorator.program && this.compileProgram(decorator.program);
	    var params = this.setupFullMustacheParams(decorator, program, undefined),
	        path = decorator.path;

	    this.useDecorators = true;
	    this.opcode('registerDecorator', params.length, path.original);
	  },

	  PartialStatement: function PartialStatement(partial) {
	    this.usePartial = true;

	    var program = partial.program;
	    if (program) {
	      program = this.compileProgram(partial.program);
	    }

	    var params = partial.params;
	    if (params.length > 1) {
	      throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial);
	    } else if (!params.length) {
	      if (this.options.explicitPartialContext) {
	        this.opcode('pushLiteral', 'undefined');
	      } else {
	        params.push({ type: 'PathExpression', parts: [], depth: 0 });
	      }
	    }

	    var partialName = partial.name.original,
	        isDynamic = partial.name.type === 'SubExpression';
	    if (isDynamic) {
	      this.accept(partial.name);
	    }

	    this.setupFullMustacheParams(partial, program, undefined, true);

	    var indent = partial.indent || '';
	    if (this.options.preventIndent && indent) {
	      this.opcode('appendContent', indent);
	      indent = '';
	    }

	    this.opcode('invokePartial', isDynamic, partialName, indent);
	    this.opcode('append');
	  },
	  PartialBlockStatement: function PartialBlockStatement(partialBlock) {
	    this.PartialStatement(partialBlock);
	  },

	  MustacheStatement: function MustacheStatement(mustache) {
	    this.SubExpression(mustache);

	    if (mustache.escaped && !this.options.noEscape) {
	      this.opcode('appendEscaped');
	    } else {
	      this.opcode('append');
	    }
	  },
	  Decorator: function Decorator(decorator) {
	    this.DecoratorBlock(decorator);
	  },

	  ContentStatement: function ContentStatement(content) {
	    if (content.value) {
	      this.opcode('appendContent', content.value);
	    }
	  },

	  CommentStatement: function CommentStatement() {},

	  SubExpression: function SubExpression(sexpr) {
	    transformLiteralToPath(sexpr);
	    var type = this.classifySexpr(sexpr);

	    if (type === 'simple') {
	      this.simpleSexpr(sexpr);
	    } else if (type === 'helper') {
	      this.helperSexpr(sexpr);
	    } else {
	      this.ambiguousSexpr(sexpr);
	    }
	  },
	  ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
	    var path = sexpr.path,
	        name = path.parts[0],
	        isBlock = program != null || inverse != null;

	    this.opcode('getContext', path.depth);

	    this.opcode('pushProgram', program);
	    this.opcode('pushProgram', inverse);

	    path.strict = true;
	    this.accept(path);

	    this.opcode('invokeAmbiguous', name, isBlock);
	  },

	  simpleSexpr: function simpleSexpr(sexpr) {
	    var path = sexpr.path;
	    path.strict = true;
	    this.accept(path);
	    this.opcode('resolvePossibleLambda');
	  },

	  helperSexpr: function helperSexpr(sexpr, program, inverse) {
	    var params = this.setupFullMustacheParams(sexpr, program, inverse),
	        path = sexpr.path,
	        name = path.parts[0];

	    if (this.options.knownHelpers[name]) {
	      this.opcode('invokeKnownHelper', params.length, name);
	    } else if (this.options.knownHelpersOnly) {
	      throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
	    } else {
	      path.strict = true;
	      path.falsy = true;

	      this.accept(path);
	      this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path));
	    }
	  },

	  PathExpression: function PathExpression(path) {
	    this.addDepth(path.depth);
	    this.opcode('getContext', path.depth);

	    var name = path.parts[0],
	        scoped = _ast2['default'].helpers.scopedId(path),
	        blockParamId = !path.depth && !scoped && this.blockParamIndex(name);

	    if (blockParamId) {
	      this.opcode('lookupBlockParam', blockParamId, path.parts);
	    } else if (!name) {
	      // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
	      this.opcode('pushContext');
	    } else if (path.data) {
	      this.options.data = true;
	      this.opcode('lookupData', path.depth, path.parts, path.strict);
	    } else {
	      this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped);
	    }
	  },

	  StringLiteral: function StringLiteral(string) {
	    this.opcode('pushString', string.value);
	  },

	  NumberLiteral: function NumberLiteral(number) {
	    this.opcode('pushLiteral', number.value);
	  },

	  BooleanLiteral: function BooleanLiteral(bool) {
	    this.opcode('pushLiteral', bool.value);
	  },

	  UndefinedLiteral: function UndefinedLiteral() {
	    this.opcode('pushLiteral', 'undefined');
	  },

	  NullLiteral: function NullLiteral() {
	    this.opcode('pushLiteral', 'null');
	  },

	  Hash: function Hash(hash) {
	    var pairs = hash.pairs,
	        i = 0,
	        l = pairs.length;

	    this.opcode('pushHash');

	    for (; i < l; i++) {
	      this.pushParam(pairs[i].value);
	    }
	    while (i--) {
	      this.opcode('assignToHash', pairs[i].key);
	    }
	    this.opcode('popHash');
	  },

	  // HELPERS
	  opcode: function opcode(name) {
	    this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
	  },

	  addDepth: function addDepth(depth) {
	    if (!depth) {
	      return;
	    }

	    this.useDepths = true;
	  },

	  classifySexpr: function classifySexpr(sexpr) {
	    var isSimple = _ast2['default'].helpers.simpleId(sexpr.path);

	    var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);

	    // a mustache is an eligible helper if:
	    // * its id is simple (a single part, not `this` or `..`)
	    var isHelper = !isBlockParam && _ast2['default'].helpers.helperExpression(sexpr);

	    // if a mustache is an eligible helper but not a definite
	    // helper, it is ambiguous, and will be resolved in a later
	    // pass or at runtime.
	    var isEligible = !isBlockParam && (isHelper || isSimple);

	    // if ambiguous, we can possibly resolve the ambiguity now
	    // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
	    if (isEligible && !isHelper) {
	      var _name = sexpr.path.parts[0],
	          options = this.options;
	      if (options.knownHelpers[_name]) {
	        isHelper = true;
	      } else if (options.knownHelpersOnly) {
	        isEligible = false;
	      }
	    }

	    if (isHelper) {
	      return 'helper';
	    } else if (isEligible) {
	      return 'ambiguous';
	    } else {
	      return 'simple';
	    }
	  },

	  pushParams: function pushParams(params) {
	    for (var i = 0, l = params.length; i < l; i++) {
	      this.pushParam(params[i]);
	    }
	  },

	  pushParam: function pushParam(val) {
	    var value = val.value != null ? val.value : val.original || '';

	    if (this.stringParams) {
	      if (value.replace) {
	        value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.');
	      }

	      if (val.depth) {
	        this.addDepth(val.depth);
	      }
	      this.opcode('getContext', val.depth || 0);
	      this.opcode('pushStringParam', value, val.type);

	      if (val.type === 'SubExpression') {
	        // SubExpressions get evaluated and passed in
	        // in string params mode.
	        this.accept(val);
	      }
	    } else {
	      if (this.trackIds) {
	        var blockParamIndex = undefined;
	        if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) {
	          blockParamIndex = this.blockParamIndex(val.parts[0]);
	        }
	        if (blockParamIndex) {
	          var blockParamChild = val.parts.slice(1).join('.');
	          this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
	        } else {
	          value = val.original || value;
	          if (value.replace) {
	            value = value.replace(/^this(?:\.|$)/, '').replace(/^\.\//, '').replace(/^\.$/, '');
	          }

	          this.opcode('pushId', val.type, value);
	        }
	      }
	      this.accept(val);
	    }
	  },

	  setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) {
	    var params = sexpr.params;
	    this.pushParams(params);

	    this.opcode('pushProgram', program);
	    this.opcode('pushProgram', inverse);

	    if (sexpr.hash) {
	      this.accept(sexpr.hash);
	    } else {
	      this.opcode('emptyHash', omitEmpty);
	    }

	    return params;
	  },

	  blockParamIndex: function blockParamIndex(name) {
	    for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
	      var blockParams = this.options.blockParams[depth],
	          param = blockParams && _utils.indexOf(blockParams, name);
	      if (blockParams && param >= 0) {
	        return [depth, param];
	      }
	    }
	  }
	};

	function precompile(input, options, env) {
	  if (input == null || typeof input !== 'string' && input.type !== 'Program') {
	    throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input);
	  }

	  options = options || {};
	  if (!('data' in options)) {
	    options.data = true;
	  }
	  if (options.compat) {
	    options.useDepths = true;
	  }

	  var ast = env.parse(input, options),
	      environment = new env.Compiler().compile(ast, options);
	  return new env.JavaScriptCompiler().compile(environment, options);
	}

	function compile(input, options, env) {
	  if (options === undefined) options = {};

	  if (input == null || typeof input !== 'string' && input.type !== 'Program') {
	    throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input);
	  }

	  options = _utils.extend({}, options);
	  if (!('data' in options)) {
	    options.data = true;
	  }
	  if (options.compat) {
	    options.useDepths = true;
	  }

	  var compiled = undefined;

	  function compileInput() {
	    var ast = env.parse(input, options),
	        environment = new env.Compiler().compile(ast, options),
	        templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
	    return env.template(templateSpec);
	  }

	  // Template is only compiled on first use and cached after that point.
	  function ret(context, execOptions) {
	    if (!compiled) {
	      compiled = compileInput();
	    }
	    return compiled.call(this, context, execOptions);
	  }
	  ret._setup = function (setupOptions) {
	    if (!compiled) {
	      compiled = compileInput();
	    }
	    return compiled._setup(setupOptions);
	  };
	  ret._child = function (i, data, blockParams, depths) {
	    if (!compiled) {
	      compiled = compileInput();
	    }
	    return compiled._child(i, data, blockParams, depths);
	  };
	  return ret;
	}

	function argEquals(a, b) {
	  if (a === b) {
	    return true;
	  }

	  if (_utils.isArray(a) && _utils.isArray(b) && a.length === b.length) {
	    for (var i = 0; i < a.length; i++) {
	      if (!argEquals(a[i], b[i])) {
	        return false;
	      }
	    }
	    return true;
	  }
	}

	function transformLiteralToPath(sexpr) {
	  if (!sexpr.path.parts) {
	    var literal = sexpr.path;
	    // Casting to string here to make false and 0 literal values play nicely with the rest
	    // of the system.
	    sexpr.path = {
	      type: 'PathExpression',
	      data: false,
	      depth: 0,
	      parts: [literal.original + ''],
	      original: literal.original + '',
	      loc: literal.loc
	    };
	  }
	}

/***/ }),
/* 47 */
/***/ (function(module, exports, __webpack_require__) {

	module.exports = { "default": __webpack_require__(48), __esModule: true };

/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(9);
	module.exports = function create(P, D){
	  return $.create(P, D);
	};

/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var _Object$keys = __webpack_require__(13)['default'];

	var _interopRequireDefault = __webpack_require__(1)['default'];

	exports.__esModule = true;

	var _base = __webpack_require__(4);

	var _exception = __webpack_require__(6);

	var _exception2 = _interopRequireDefault(_exception);

	var _utils = __webpack_require__(5);

	var _codeGen = __webpack_require__(50);

	var _codeGen2 = _interopRequireDefault(_codeGen);

	var _helpersLookup = __webpack_require__(28);

	function Literal(value) {
	  this.value = value;
	}

	function JavaScriptCompiler() {}

	JavaScriptCompiler.prototype = {
	  // PUBLIC API: You can override these methods in a subclass to provide
	  // alternative compiled forms for name lookup and buffering semantics
	  nameLookup: function nameLookup(parent, name /* , type*/) {
	    if (_helpersLookup.dangerousPropertyRegex.test(name)) {
	      var isEnumerable = [this.aliasable('container.propertyIsEnumerable'), '.call(', parent, ',', JSON.stringify(name), ')'];
	      return ['(', isEnumerable, '?', _actualLookup(), ' : undefined)'];
	    }
	    return _actualLookup();

	    function _actualLookup() {
	      if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
	        return [parent, '.', name];
	      } else {
	        return [parent, '[', JSON.stringify(name), ']'];
	      }
	    }
	  },
	  depthedLookup: function depthedLookup(name) {
	    return [this.aliasable('container.lookup'), '(depths, "', name, '")'];
	  },

	  compilerInfo: function compilerInfo() {
	    var revision = _base.COMPILER_REVISION,
	        versions = _base.REVISION_CHANGES[revision];
	    return [revision, versions];
	  },

	  appendToBuffer: function appendToBuffer(source, location, explicit) {
	    // Force a source as this simplifies the merge logic.
	    if (!_utils.isArray(source)) {
	      source = [source];
	    }
	    source = this.source.wrap(source, location);

	    if (this.environment.isSimple) {
	      return ['return ', source, ';'];
	    } else if (explicit) {
	      // This is a case where the buffer operation occurs as a child of another
	      // construct, generally braces. We have to explicitly output these buffer
	      // operations to ensure that the emitted code goes in the correct location.
	      return ['buffer += ', source, ';'];
	    } else {
	      source.appendToBuffer = true;
	      return source;
	    }
	  },

	  initializeBuffer: function initializeBuffer() {
	    return this.quotedString('');
	  },
	  // END PUBLIC API

	  compile: function compile(environment, options, context, asObject) {
	    this.environment = environment;
	    this.options = options;
	    this.stringParams = this.options.stringParams;
	    this.trackIds = this.options.trackIds;
	    this.precompile = !asObject;

	    this.name = this.environment.name;
	    this.isChild = !!context;
	    this.context = context || {
	      decorators: [],
	      programs: [],
	      environments: []
	    };

	    this.preamble();

	    this.stackSlot = 0;
	    this.stackVars = [];
	    this.aliases = {};
	    this.registers = { list: [] };
	    this.hashes = [];
	    this.compileStack = [];
	    this.inlineStack = [];
	    this.blockParams = [];

	    this.compileChildren(environment, options);

	    this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat;
	    this.useBlockParams = this.useBlockParams || environment.useBlockParams;

	    var opcodes = environment.opcodes,
	        opcode = undefined,
	        firstLoc = undefined,
	        i = undefined,
	        l = undefined;

	    for (i = 0, l = opcodes.length; i < l; i++) {
	      opcode = opcodes[i];

	      this.source.currentLocation = opcode.loc;
	      firstLoc = firstLoc || opcode.loc;
	      this[opcode.opcode].apply(this, opcode.args);
	    }

	    // Flush any trailing content that might be pending.
	    this.source.currentLocation = firstLoc;
	    this.pushSource('');

	    /* istanbul ignore next */
	    if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
	      throw new _exception2['default']('Compile completed with content left on stack');
	    }

	    if (!this.decorators.isEmpty()) {
	      this.useDecorators = true;

	      this.decorators.prepend('var decorators = container.decorators;\n');
	      this.decorators.push('return fn;');

	      if (asObject) {
	        this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]);
	      } else {
	        this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n');
	        this.decorators.push('}\n');
	        this.decorators = this.decorators.merge();
	      }
	    } else {
	      this.decorators = undefined;
	    }

	    var fn = this.createFunctionContext(asObject);
	    if (!this.isChild) {
	      var ret = {
	        compiler: this.compilerInfo(),
	        main: fn
	      };

	      if (this.decorators) {
	        ret.main_d = this.decorators; // eslint-disable-line camelcase
	        ret.useDecorators = true;
	      }

	      var _context = this.context;
	      var programs = _context.programs;
	      var decorators = _context.decorators;

	      for (i = 0, l = programs.length; i < l; i++) {
	        if (programs[i]) {
	          ret[i] = programs[i];
	          if (decorators[i]) {
	            ret[i + '_d'] = decorators[i];
	            ret.useDecorators = true;
	          }
	        }
	      }

	      if (this.environment.usePartial) {
	        ret.usePartial = true;
	      }
	      if (this.options.data) {
	        ret.useData = true;
	      }
	      if (this.useDepths) {
	        ret.useDepths = true;
	      }
	      if (this.useBlockParams) {
	        ret.useBlockParams = true;
	      }
	      if (this.options.compat) {
	        ret.compat = true;
	      }

	      if (!asObject) {
	        ret.compiler = JSON.stringify(ret.compiler);

	        this.source.currentLocation = { start: { line: 1, column: 0 } };
	        ret = this.objectLiteral(ret);

	        if (options.srcName) {
	          ret = ret.toStringWithSourceMap({ file: options.destName });
	          ret.map = ret.map && ret.map.toString();
	        } else {
	          ret = ret.toString();
	        }
	      } else {
	        ret.compilerOptions = this.options;
	      }

	      return ret;
	    } else {
	      return fn;
	    }
	  },

	  preamble: function preamble() {
	    // track the last context pushed into place to allow skipping the
	    // getContext opcode when it would be a noop
	    this.lastContext = 0;
	    this.source = new _codeGen2['default'](this.options.srcName);
	    this.decorators = new _codeGen2['default'](this.options.srcName);
	  },

	  createFunctionContext: function createFunctionContext(asObject) {
	    // istanbul ignore next

	    var _this = this;

	    var varDeclarations = '';

	    var locals = this.stackVars.concat(this.registers.list);
	    if (locals.length > 0) {
	      varDeclarations += ', ' + locals.join(', ');
	    }

	    // Generate minimizer alias mappings
	    //
	    // When using true SourceNodes, this will update all references to the given alias
	    // as the source nodes are reused in situ. For the non-source node compilation mode,
	    // aliases will not be used, but this case is already being run on the client and
	    // we aren't concern about minimizing the template size.
	    var aliasCount = 0;
	    _Object$keys(this.aliases).forEach(function (alias) {
	      var node = _this.aliases[alias];
	      if (node.children && node.referenceCount > 1) {
	        varDeclarations += ', alias' + ++aliasCount + '=' + alias;
	        node.children[0] = 'alias' + aliasCount;
	      }
	    });

	    var params = ['container', 'depth0', 'helpers', 'partials', 'data'];

	    if (this.useBlockParams || this.useDepths) {
	      params.push('blockParams');
	    }
	    if (this.useDepths) {
	      params.push('depths');
	    }

	    // Perform a second pass over the output to merge content when possible
	    var source = this.mergeSource(varDeclarations);

	    if (asObject) {
	      params.push(source);

	      return Function.apply(this, params);
	    } else {
	      return this.source.wrap(['function(', params.join(','), ') {\n  ', source, '}']);
	    }
	  },
	  mergeSource: function mergeSource(varDeclarations) {
	    var isSimple = this.environment.isSimple,
	        appendOnly = !this.forceBuffer,
	        appendFirst = undefined,
	        sourceSeen = undefined,
	        bufferStart = undefined,
	        bufferEnd = undefined;
	    this.source.each(function (line) {
	      if (line.appendToBuffer) {
	        if (bufferStart) {
	          line.prepend('  + ');
	        } else {
	          bufferStart = line;
	        }
	        bufferEnd = line;
	      } else {
	        if (bufferStart) {
	          if (!sourceSeen) {
	            appendFirst = true;
	          } else {
	            bufferStart.prepend('buffer += ');
	          }
	          bufferEnd.add(';');
	          bufferStart = bufferEnd = undefined;
	        }

	        sourceSeen = true;
	        if (!isSimple) {
	          appendOnly = false;
	        }
	      }
	    });

	    if (appendOnly) {
	      if (bufferStart) {
	        bufferStart.prepend('return ');
	        bufferEnd.add(';');
	      } else if (!sourceSeen) {
	        this.source.push('return "";');
	      }
	    } else {
	      varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());

	      if (bufferStart) {
	        bufferStart.prepend('return buffer + ');
	        bufferEnd.add(';');
	      } else {
	        this.source.push('return buffer;');
	      }
	    }

	    if (varDeclarations) {
	      this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
	    }

	    return this.source.merge();
	  },

	  // [blockValue]
	  //
	  // On stack, before: hash, inverse, program, value
	  // On stack, after: return value of blockHelperMissing
	  //
	  // The purpose of this opcode is to take a block of the form
	  // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
	  // replace it on the stack with the result of properly
	  // invoking blockHelperMissing.
	  blockValue: function blockValue(name) {
	    var blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'),
	        params = [this.contextName(0)];
	    this.setupHelperArgs(name, 0, params);

	    var blockName = this.popStack();
	    params.splice(1, 0, blockName);

	    this.push(this.source.functionCall(blockHelperMissing, 'call', params));
	  },

	  // [ambiguousBlockValue]
	  //
	  // On stack, before: hash, inverse, program, value
	  // Compiler value, before: lastHelper=value of last found helper, if any
	  // On stack, after, if no lastHelper: same as [blockValue]
	  // On stack, after, if lastHelper: value
	  ambiguousBlockValue: function ambiguousBlockValue() {
	    // We're being a bit cheeky and reusing the options value from the prior exec
	    var blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'),
	        params = [this.contextName(0)];
	    this.setupHelperArgs('', 0, params, true);

	    this.flushInline();

	    var current = this.topStack();
	    params.splice(1, 0, current);

	    this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']);
	  },

	  // [appendContent]
	  //
	  // On stack, before: ...
	  // On stack, after: ...
	  //
	  // Appends the string value of `content` to the current buffer
	  appendContent: function appendContent(content) {
	    if (this.pendingContent) {
	      content = this.pendingContent + content;
	    } else {
	      this.pendingLocation = this.source.currentLocation;
	    }

	    this.pendingContent = content;
	  },

	  // [append]
	  //
	  // On stack, before: value, ...
	  // On stack, after: ...
	  //
	  // Coerces `value` to a String and appends it to the current buffer.
	  //
	  // If `value` is truthy, or 0, it is coerced into a string and appended
	  // Otherwise, the empty string is appended
	  append: function append() {
	    if (this.isInline()) {
	      this.replaceStack(function (current) {
	        return [' != null ? ', current, ' : ""'];
	      });

	      this.pushSource(this.appendToBuffer(this.popStack()));
	    } else {
	      var local = this.popStack();
	      this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
	      if (this.environment.isSimple) {
	        this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
	      }
	    }
	  },

	  // [appendEscaped]
	  //
	  // On stack, before: value, ...
	  // On stack, after: ...
	  //
	  // Escape `value` and append it to the buffer
	  appendEscaped: function appendEscaped() {
	    this.pushSource(this.appendToBuffer([this.aliasable('container.escapeExpression'), '(', this.popStack(), ')']));
	  },

	  // [getContext]
	  //
	  // On stack, before: ...
	  // On stack, after: ...
	  // Compiler value, after: lastContext=depth
	  //
	  // Set the value of the `lastContext` compiler value to the depth
	  getContext: function getContext(depth) {
	    this.lastContext = depth;
	  },

	  // [pushContext]
	  //
	  // On stack, before: ...
	  // On stack, after: currentContext, ...
	  //
	  // Pushes the value of the current context onto the stack.
	  pushContext: function pushContext() {
	    this.pushStackLiteral(this.contextName(this.lastContext));
	  },

	  // [lookupOnContext]
	  //
	  // On stack, before: ...
	  // On stack, after: currentContext[name], ...
	  //
	  // Looks up the value of `name` on the current context and pushes
	  // it onto the stack.
	  lookupOnContext: function lookupOnContext(parts, falsy, strict, scoped) {
	    var i = 0;

	    if (!scoped && this.options.compat && !this.lastContext) {
	      // The depthed query is expected to handle the undefined logic for the root level that
	      // is implemented below, so we evaluate that directly in compat mode
	      this.push(this.depthedLookup(parts[i++]));
	    } else {
	      this.pushContext();
	    }

	    this.resolvePath('context', parts, i, falsy, strict);
	  },

	  // [lookupBlockParam]
	  //
	  // On stack, before: ...
	  // On stack, after: blockParam[name], ...
	  //
	  // Looks up the value of `parts` on the given block param and pushes
	  // it onto the stack.
	  lookupBlockParam: function lookupBlockParam(blockParamId, parts) {
	    this.useBlockParams = true;

	    this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
	    this.resolvePath('context', parts, 1);
	  },

	  // [lookupData]
	  //
	  // On stack, before: ...
	  // On stack, after: data, ...
	  //
	  // Push the data lookup operator
	  lookupData: function lookupData(depth, parts, strict) {
	    if (!depth) {
	      this.pushStackLiteral('data');
	    } else {
	      this.pushStackLiteral('container.data(data, ' + depth + ')');
	    }

	    this.resolvePath('data', parts, 0, true, strict);
	  },

	  resolvePath: function resolvePath(type, parts, i, falsy, strict) {
	    // istanbul ignore next

	    var _this2 = this;

	    if (this.options.strict || this.options.assumeObjects) {
	      this.push(strictLookup(this.options.strict && strict, this, parts, type));
	      return;
	    }

	    var len = parts.length;
	    for (; i < len; i++) {
	      /* eslint-disable no-loop-func */
	      this.replaceStack(function (current) {
	        var lookup = _this2.nameLookup(current, parts[i], type);
	        // We want to ensure that zero and false are handled properly if the context (falsy flag)
	        // needs to have the special handling for these values.
	        if (!falsy) {
	          return [' != null ? ', lookup, ' : ', current];
	        } else {
	          // Otherwise we can use generic falsy handling
	          return [' && ', lookup];
	        }
	      });
	      /* eslint-enable no-loop-func */
	    }
	  },

	  // [resolvePossibleLambda]
	  //
	  // On stack, before: value, ...
	  // On stack, after: resolved value, ...
	  //
	  // If the `value` is a lambda, replace it on the stack by
	  // the return value of the lambda
	  resolvePossibleLambda: function resolvePossibleLambda() {
	    this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
	  },

	  // [pushStringParam]
	  //
	  // On stack, before: ...
	  // On stack, after: string, currentContext, ...
	  //
	  // This opcode is designed for use in string mode, which
	  // provides the string value of a parameter along with its
	  // depth rather than resolving it immediately.
	  pushStringParam: function pushStringParam(string, type) {
	    this.pushContext();
	    this.pushString(type);

	    // If it's a subexpression, the string result
	    // will be pushed after this opcode.
	    if (type !== 'SubExpression') {
	      if (typeof string === 'string') {
	        this.pushString(string);
	      } else {
	        this.pushStackLiteral(string);
	      }
	    }
	  },

	  emptyHash: function emptyHash(omitEmpty) {
	    if (this.trackIds) {
	      this.push('{}'); // hashIds
	    }
	    if (this.stringParams) {
	      this.push('{}'); // hashContexts
	      this.push('{}'); // hashTypes
	    }
	    this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
	  },
	  pushHash: function pushHash() {
	    if (this.hash) {
	      this.hashes.push(this.hash);
	    }
	    this.hash = { values: {}, types: [], contexts: [], ids: [] };
	  },
	  popHash: function popHash() {
	    var hash = this.hash;
	    this.hash = this.hashes.pop();

	    if (this.trackIds) {
	      this.push(this.objectLiteral(hash.ids));
	    }
	    if (this.stringParams) {
	      this.push(this.objectLiteral(hash.contexts));
	      this.push(this.objectLiteral(hash.types));
	    }

	    this.push(this.objectLiteral(hash.values));
	  },

	  // [pushString]
	  //
	  // On stack, before: ...
	  // On stack, after: quotedString(string), ...
	  //
	  // Push a quoted version of `string` onto the stack
	  pushString: function pushString(string) {
	    this.pushStackLiteral(this.quotedString(string));
	  },

	  // [pushLiteral]
	  //
	  // On stack, before: ...
	  // On stack, after: value, ...
	  //
	  // Pushes a value onto the stack. This operation prevents
	  // the compiler from creating a temporary variable to hold
	  // it.
	  pushLiteral: function pushLiteral(value) {
	    this.pushStackLiteral(value);
	  },

	  // [pushProgram]
	  //
	  // On stack, before: ...
	  // On stack, after: program(guid), ...
	  //
	  // Push a program expression onto the stack. This takes
	  // a compile-time guid and converts it into a runtime-accessible
	  // expression.
	  pushProgram: function pushProgram(guid) {
	    if (guid != null) {
	      this.pushStackLiteral(this.programExpression(guid));
	    } else {
	      this.pushStackLiteral(null);
	    }
	  },

	  // [registerDecorator]
	  //
	  // On stack, before: hash, program, params..., ...
	  // On stack, after: ...
	  //
	  // Pops off the decorator's parameters, invokes the decorator,
	  // and inserts the decorator into the decorators list.
	  registerDecorator: function registerDecorator(paramSize, name) {
	    var foundDecorator = this.nameLookup('decorators', name, 'decorator'),
	        options = this.setupHelperArgs(name, paramSize);

	    this.decorators.push(['fn = ', this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]), ' || fn;']);
	  },

	  // [invokeHelper]
	  //
	  // On stack, before: hash, inverse, program, params..., ...
	  // On stack, after: result of helper invocation
	  //
	  // Pops off the helper's parameters, invokes the helper,
	  // and pushes the helper's return value onto the stack.
	  //
	  // If the helper is not found, `helperMissing` is called.
	  invokeHelper: function invokeHelper(paramSize, name, isSimple) {
	    var nonHelper = this.popStack(),
	        helper = this.setupHelper(paramSize, name);

	    var possibleFunctionCalls = [];

	    if (isSimple) {
	      // direct call to helper
	      possibleFunctionCalls.push(helper.name);
	    }
	    // call a function from the input object
	    possibleFunctionCalls.push(nonHelper);
	    if (!this.options.strict) {
	      possibleFunctionCalls.push(this.aliasable('container.hooks.helperMissing'));
	    }

	    var functionLookupCode = ['(', this.itemsSeparatedBy(possibleFunctionCalls, '||'), ')'];
	    var functionCall = this.source.functionCall(functionLookupCode, 'call', helper.callParams);
	    this.push(functionCall);
	  },

	  itemsSeparatedBy: function itemsSeparatedBy(items, separator) {
	    var result = [];
	    result.push(items[0]);
	    for (var i = 1; i < items.length; i++) {
	      result.push(separator, items[i]);
	    }
	    return result;
	  },
	  // [invokeKnownHelper]
	  //
	  // On stack, before: hash, inverse, program, params..., ...
	  // On stack, after: result of helper invocation
	  //
	  // This operation is used when the helper is known to exist,
	  // so a `helperMissing` fallback is not required.
	  invokeKnownHelper: function invokeKnownHelper(paramSize, name) {
	    var helper = this.setupHelper(paramSize, name);
	    this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
	  },

	  // [invokeAmbiguous]
	  //
	  // On stack, before: hash, inverse, program, params..., ...
	  // On stack, after: result of disambiguation
	  //
	  // This operation is used when an expression like `{{foo}}`
	  // is provided, but we don't know at compile-time whether it
	  // is a helper or a path.
	  //
	  // This operation emits more code than the other options,
	  // and can be avoided by passing the `knownHelpers` and
	  // `knownHelpersOnly` flags at compile-time.
	  invokeAmbiguous: function invokeAmbiguous(name, helperCall) {
	    this.useRegister('helper');

	    var nonHelper = this.popStack();

	    this.emptyHash();
	    var helper = this.setupHelper(0, name, helperCall);

	    var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');

	    var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
	    if (!this.options.strict) {
	      lookup[0] = '(helper = ';
	      lookup.push(' != null ? helper : ', this.aliasable('container.hooks.helperMissing'));
	    }

	    this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']);
	  },

	  // [invokePartial]
	  //
	  // On stack, before: context, ...
	  // On stack after: result of partial invocation
	  //
	  // This operation pops off a context, invokes a partial with that context,
	  // and pushes the result of the invocation back.
	  invokePartial: function invokePartial(isDynamic, name, indent) {
	    var params = [],
	        options = this.setupParams(name, 1, params);

	    if (isDynamic) {
	      name = this.popStack();
	      delete options.name;
	    }

	    if (indent) {
	      options.indent = JSON.stringify(indent);
	    }
	    options.helpers = 'helpers';
	    options.partials = 'partials';
	    options.decorators = 'container.decorators';

	    if (!isDynamic) {
	      params.unshift(this.nameLookup('partials', name, 'partial'));
	    } else {
	      params.unshift(name);
	    }

	    if (this.options.compat) {
	      options.depths = 'depths';
	    }
	    options = this.objectLiteral(options);
	    params.push(options);

	    this.push(this.source.functionCall('container.invokePartial', '', params));
	  },

	  // [assignToHash]
	  //
	  // On stack, before: value, ..., hash, ...
	  // On stack, after: ..., hash, ...
	  //
	  // Pops a value off the stack and assigns it to the current hash
	  assignToHash: function assignToHash(key) {
	    var value = this.popStack(),
	        context = undefined,
	        type = undefined,
	        id = undefined;

	    if (this.trackIds) {
	      id = this.popStack();
	    }
	    if (this.stringParams) {
	      type = this.popStack();
	      context = this.popStack();
	    }

	    var hash = this.hash;
	    if (context) {
	      hash.contexts[key] = context;
	    }
	    if (type) {
	      hash.types[key] = type;
	    }
	    if (id) {
	      hash.ids[key] = id;
	    }
	    hash.values[key] = value;
	  },

	  pushId: function pushId(type, name, child) {
	    if (type === 'BlockParam') {
	      this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : ''));
	    } else if (type === 'PathExpression') {
	      this.pushString(name);
	    } else if (type === 'SubExpression') {
	      this.pushStackLiteral('true');
	    } else {
	      this.pushStackLiteral('null');
	    }
	  },

	  // HELPERS

	  compiler: JavaScriptCompiler,

	  compileChildren: function compileChildren(environment, options) {
	    var children = environment.children,
	        child = undefined,
	        compiler = undefined;

	    for (var i = 0, l = children.length; i < l; i++) {
	      child = children[i];
	      compiler = new this.compiler(); // eslint-disable-line new-cap

	      var existing = this.matchExistingProgram(child);

	      if (existing == null) {
	        this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
	        var index = this.context.programs.length;
	        child.index = index;
	        child.name = 'program' + index;
	        this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
	        this.context.decorators[index] = compiler.decorators;
	        this.context.environments[index] = child;

	        this.useDepths = this.useDepths || compiler.useDepths;
	        this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
	        child.useDepths = this.useDepths;
	        child.useBlockParams = this.useBlockParams;
	      } else {
	        child.index = existing.index;
	        child.name = 'program' + existing.index;

	        this.useDepths = this.useDepths || existing.useDepths;
	        this.useBlockParams = this.useBlockParams || existing.useBlockParams;
	      }
	    }
	  },
	  matchExistingProgram: function matchExistingProgram(child) {
	    for (var i = 0, len = this.context.environments.length; i < len; i++) {
	      var environment = this.context.environments[i];
	      if (environment && environment.equals(child)) {
	        return environment;
	      }
	    }
	  },

	  programExpression: function programExpression(guid) {
	    var child = this.environment.children[guid],
	        programParams = [child.index, 'data', child.blockParams];

	    if (this.useBlockParams || this.useDepths) {
	      programParams.push('blockParams');
	    }
	    if (this.useDepths) {
	      programParams.push('depths');
	    }

	    return 'container.program(' + programParams.join(', ') + ')';
	  },

	  useRegister: function useRegister(name) {
	    if (!this.registers[name]) {
	      this.registers[name] = true;
	      this.registers.list.push(name);
	    }
	  },

	  push: function push(expr) {
	    if (!(expr instanceof Literal)) {
	      expr = this.source.wrap(expr);
	    }

	    this.inlineStack.push(expr);
	    return expr;
	  },

	  pushStackLiteral: function pushStackLiteral(item) {
	    this.push(new Literal(item));
	  },

	  pushSource: function pushSource(source) {
	    if (this.pendingContent) {
	      this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
	      this.pendingContent = undefined;
	    }

	    if (source) {
	      this.source.push(source);
	    }
	  },

	  replaceStack: function replaceStack(callback) {
	    var prefix = ['('],
	        stack = undefined,
	        createdStack = undefined,
	        usedLiteral = undefined;

	    /* istanbul ignore next */
	    if (!this.isInline()) {
	      throw new _exception2['default']('replaceStack on non-inline');
	    }

	    // We want to merge the inline statement into the replacement statement via ','
	    var top = this.popStack(true);

	    if (top instanceof Literal) {
	      // Literals do not need to be inlined
	      stack = [top.value];
	      prefix = ['(', stack];
	      usedLiteral = true;
	    } else {
	      // Get or create the current stack name for use by the inline
	      createdStack = true;
	      var _name = this.incrStack();

	      prefix = ['((', this.push(_name), ' = ', top, ')'];
	      stack = this.topStack();
	    }

	    var item = callback.call(this, stack);

	    if (!usedLiteral) {
	      this.popStack();
	    }
	    if (createdStack) {
	      this.stackSlot--;
	    }
	    this.push(prefix.concat(item, ')'));
	  },

	  incrStack: function incrStack() {
	    this.stackSlot++;
	    if (this.stackSlot > this.stackVars.length) {
	      this.stackVars.push('stack' + this.stackSlot);
	    }
	    return this.topStackName();
	  },
	  topStackName: function topStackName() {
	    return 'stack' + this.stackSlot;
	  },
	  flushInline: function flushInline() {
	    var inlineStack = this.inlineStack;
	    this.inlineStack = [];
	    for (var i = 0, len = inlineStack.length; i < len; i++) {
	      var entry = inlineStack[i];
	      /* istanbul ignore if */
	      if (entry instanceof Literal) {
	        this.compileStack.push(entry);
	      } else {
	        var stack = this.incrStack();
	        this.pushSource([stack, ' = ', entry, ';']);
	        this.compileStack.push(stack);
	      }
	    }
	  },
	  isInline: function isInline() {
	    return this.inlineStack.length;
	  },

	  popStack: function popStack(wrapped) {
	    var inline = this.isInline(),
	        item = (inline ? this.inlineStack : this.compileStack).pop();

	    if (!wrapped && item instanceof Literal) {
	      return item.value;
	    } else {
	      if (!inline) {
	        /* istanbul ignore next */
	        if (!this.stackSlot) {
	          throw new _exception2['default']('Invalid stack pop');
	        }
	        this.stackSlot--;
	      }
	      return item;
	    }
	  },

	  topStack: function topStack() {
	    var stack = this.isInline() ? this.inlineStack : this.compileStack,
	        item = stack[stack.length - 1];

	    /* istanbul ignore if */
	    if (item instanceof Literal) {
	      return item.value;
	    } else {
	      return item;
	    }
	  },

	  contextName: function contextName(context) {
	    if (this.useDepths && context) {
	      return 'depths[' + context + ']';
	    } else {
	      return 'depth' + context;
	    }
	  },

	  quotedString: function quotedString(str) {
	    return this.source.quotedString(str);
	  },

	  objectLiteral: function objectLiteral(obj) {
	    return this.source.objectLiteral(obj);
	  },

	  aliasable: function aliasable(name) {
	    var ret = this.aliases[name];
	    if (ret) {
	      ret.referenceCount++;
	      return ret;
	    }

	    ret = this.aliases[name] = this.source.wrap(name);
	    ret.aliasable = true;
	    ret.referenceCount = 1;

	    return ret;
	  },

	  setupHelper: function setupHelper(paramSize, name, blockHelper) {
	    var params = [],
	        paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
	    var foundHelper = this.nameLookup('helpers', name, 'helper'),
	        callContext = this.aliasable(this.contextName(0) + ' != null ? ' + this.contextName(0) + ' : (container.nullContext || {})');

	    return {
	      params: params,
	      paramsInit: paramsInit,
	      name: foundHelper,
	      callParams: [callContext].concat(params)
	    };
	  },

	  setupParams: function setupParams(helper, paramSize, params) {
	    var options = {},
	        contexts = [],
	        types = [],
	        ids = [],
	        objectArgs = !params,
	        param = undefined;

	    if (objectArgs) {
	      params = [];
	    }

	    options.name = this.quotedString(helper);
	    options.hash = this.popStack();

	    if (this.trackIds) {
	      options.hashIds = this.popStack();
	    }
	    if (this.stringParams) {
	      options.hashTypes = this.popStack();
	      options.hashContexts = this.popStack();
	    }

	    var inverse = this.popStack(),
	        program = this.popStack();

	    // Avoid setting fn and inverse if neither are set. This allows
	    // helpers to do a check for `if (options.fn)`
	    if (program || inverse) {
	      options.fn = program || 'container.noop';
	      options.inverse = inverse || 'container.noop';
	    }

	    // The parameters go on to the stack in order (making sure that they are evaluated in order)
	    // so we need to pop them off the stack in reverse order
	    var i = paramSize;
	    while (i--) {
	      param = this.popStack();
	      params[i] = param;

	      if (this.trackIds) {
	        ids[i] = this.popStack();
	      }
	      if (this.stringParams) {
	        types[i] = this.popStack();
	        contexts[i] = this.popStack();
	      }
	    }

	    if (objectArgs) {
	      options.args = this.source.generateArray(params);
	    }

	    if (this.trackIds) {
	      options.ids = this.source.generateArray(ids);
	    }
	    if (this.stringParams) {
	      options.types = this.source.generateArray(types);
	      options.contexts = this.source.generateArray(contexts);
	    }

	    if (this.options.data) {
	      options.data = 'data';
	    }
	    if (this.useBlockParams) {
	      options.blockParams = 'blockParams';
	    }
	    return options;
	  },

	  setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) {
	    var options = this.setupParams(helper, paramSize, params);
	    options.loc = JSON.stringify(this.source.currentLocation);
	    options = this.objectLiteral(options);
	    if (useRegister) {
	      this.useRegister('options');
	      params.push('options');
	      return ['options=', options];
	    } else if (params) {
	      params.push(options);
	      return '';
	    } else {
	      return options;
	    }
	  }
	};

	(function () {
	  var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' ');

	  var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};

	  for (var i = 0, l = reservedWords.length; i < l; i++) {
	    compilerWords[reservedWords[i]] = true;
	  }
	})();

	JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
	  return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
	};

	function strictLookup(requireTerminal, compiler, parts, type) {
	  var stack = compiler.popStack(),
	      i = 0,
	      len = parts.length;
	  if (requireTerminal) {
	    len--;
	  }

	  for (; i < len; i++) {
	    stack = compiler.nameLookup(stack, parts[i], type);
	  }

	  if (requireTerminal) {
	    return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ', ', JSON.stringify(compiler.source.currentLocation), ' )'];
	  } else {
	    return stack;
	  }
	}

	exports['default'] = JavaScriptCompiler;
	module.exports = exports['default'];

/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {

	/* global define */
	'use strict';

	var _Object$keys = __webpack_require__(13)['default'];

	exports.__esModule = true;

	var _utils = __webpack_require__(5);

	var SourceNode = undefined;

	try {
	  /* istanbul ignore next */
	  if (false) {
	    // We don't support this in AMD environments. For these environments, we asusme that
	    // they are running on the browser and thus have no need for the source-map library.
	    var SourceMap = require('source-map');
	    SourceNode = SourceMap.SourceNode;
	  }
	} catch (err) {}
	/* NOP */

	/* istanbul ignore if: tested but not covered in istanbul due to dist build  */
	if (!SourceNode) {
	  SourceNode = function (line, column, srcFile, chunks) {
	    this.src = '';
	    if (chunks) {
	      this.add(chunks);
	    }
	  };
	  /* istanbul ignore next */
	  SourceNode.prototype = {
	    add: function add(chunks) {
	      if (_utils.isArray(chunks)) {
	        chunks = chunks.join('');
	      }
	      this.src += chunks;
	    },
	    prepend: function prepend(chunks) {
	      if (_utils.isArray(chunks)) {
	        chunks = chunks.join('');
	      }
	      this.src = chunks + this.src;
	    },
	    toStringWithSourceMap: function toStringWithSourceMap() {
	      return { code: this.toString() };
	    },
	    toString: function toString() {
	      return this.src;
	    }
	  };
	}

	function castChunk(chunk, codeGen, loc) {
	  if (_utils.isArray(chunk)) {
	    var ret = [];

	    for (var i = 0, len = chunk.length; i < len; i++) {
	      ret.push(codeGen.wrap(chunk[i], loc));
	    }
	    return ret;
	  } else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
	    // Handle primitives that the SourceNode will throw up on
	    return chunk + '';
	  }
	  return chunk;
	}

	function CodeGen(srcFile) {
	  this.srcFile = srcFile;
	  this.source = [];
	}

	CodeGen.prototype = {
	  isEmpty: function isEmpty() {
	    return !this.source.length;
	  },
	  prepend: function prepend(source, loc) {
	    this.source.unshift(this.wrap(source, loc));
	  },
	  push: function push(source, loc) {
	    this.source.push(this.wrap(source, loc));
	  },

	  merge: function merge() {
	    var source = this.empty();
	    this.each(function (line) {
	      source.add(['  ', line, '\n']);
	    });
	    return source;
	  },

	  each: function each(iter) {
	    for (var i = 0, len = this.source.length; i < len; i++) {
	      iter(this.source[i]);
	    }
	  },

	  empty: function empty() {
	    var loc = this.currentLocation || { start: {} };
	    return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
	  },
	  wrap: function wrap(chunk) {
	    var loc = arguments.length <= 1 || arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1];

	    if (chunk instanceof SourceNode) {
	      return chunk;
	    }

	    chunk = castChunk(chunk, this, loc);

	    return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
	  },

	  functionCall: function functionCall(fn, type, params) {
	    params = this.generateList(params);
	    return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
	  },

	  quotedString: function quotedString(str) {
	    return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
	    .replace(/\u2029/g, '\\u2029') + '"';
	  },

	  objectLiteral: function objectLiteral(obj) {
	    // istanbul ignore next

	    var _this = this;

	    var pairs = [];

	    _Object$keys(obj).forEach(function (key) {
	      var value = castChunk(obj[key], _this);
	      if (value !== 'undefined') {
	        pairs.push([_this.quotedString(key), ':', value]);
	      }
	    });

	    var ret = this.generateList(pairs);
	    ret.prepend('{');
	    ret.add('}');
	    return ret;
	  },

	  generateList: function generateList(entries) {
	    var ret = this.empty();

	    for (var i = 0, len = entries.length; i < len; i++) {
	      if (i) {
	        ret.add(',');
	      }

	      ret.add(castChunk(entries[i], this));
	    }

	    return ret;
	  },

	  generateArray: function generateArray(entries) {
	    var ret = this.generateList(entries);
	    ret.prepend('[');
	    ret.add(']');

	    return ret;
	  }
	};

	exports['default'] = CodeGen;
	module.exports = exports['default'];

/***/ })
/******/ ])
});
;
//! moment.js

;(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
		typeof define === 'function' && define.amd ? define(factory) :
			global.moment = factory()
}(this, (function () { 'use strict';

	var hookCallback;

	function hooks () {
		return hookCallback.apply(null, arguments);
	}

	// This is done to register the method called with moment()
	// without creating circular dependencies.
	function setHookCallback (callback) {
		hookCallback = callback;
	}

	function isArray(input) {
		return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]';
	}

	function isObject(input) {
		// IE8 will treat undefined and null as object if it wasn't for
		// input != null
		return input != null && Object.prototype.toString.call(input) === '[object Object]';
	}

	function isObjectEmpty(obj) {
		if (Object.getOwnPropertyNames) {
			return (Object.getOwnPropertyNames(obj).length === 0);
		} else {
			var k;
			for (k in obj) {
				if (obj.hasOwnProperty(k)) {
					return false;
				}
			}
			return true;
		}
	}

	function isUndefined(input) {
		return input === void 0;
	}

	function isNumber(input) {
		return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]';
	}

	function isDate(input) {
		return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]';
	}

	function map(arr, fn) {
		var res = [], i;
		for (i = 0; i < arr.length; ++i) {
			res.push(fn(arr[i], i));
		}
		return res;
	}

	function hasOwnProp(a, b) {
		return Object.prototype.hasOwnProperty.call(a, b);
	}

	function extend(a, b) {
		for (var i in b) {
			if (hasOwnProp(b, i)) {
				a[i] = b[i];
			}
		}

		if (hasOwnProp(b, 'toString')) {
			a.toString = b.toString;
		}

		if (hasOwnProp(b, 'valueOf')) {
			a.valueOf = b.valueOf;
		}

		return a;
	}

	function createUTC (input, format, locale, strict) {
		return createLocalOrUTC(input, format, locale, strict, true).utc();
	}

	function defaultParsingFlags() {
		// We need to deep clone this object.
		return {
			empty           : false,
			unusedTokens    : [],
			unusedInput     : [],
			overflow        : -2,
			charsLeftOver   : 0,
			nullInput       : false,
			invalidMonth    : null,
			invalidFormat   : false,
			userInvalidated : false,
			iso             : false,
			parsedDateParts : [],
			meridiem        : null,
			rfc2822         : false,
			weekdayMismatch : false
		};
	}

	function getParsingFlags(m) {
		if (m._pf == null) {
			m._pf = defaultParsingFlags();
		}
		return m._pf;
	}

	var some;
	if (Array.prototype.some) {
		some = Array.prototype.some;
	} else {
		some = function (fun) {
			var t = Object(this);
			var len = t.length >>> 0;

			for (var i = 0; i < len; i++) {
				if (i in t && fun.call(this, t[i], i, t)) {
					return true;
				}
			}

			return false;
		};
	}

	function isValid(m) {
		if (m._isValid == null) {
			var flags = getParsingFlags(m);
			var parsedParts = some.call(flags.parsedDateParts, function (i) {
				return i != null;
			});
			var isNowValid = !isNaN(m._d.getTime()) &&
				flags.overflow < 0 &&
				!flags.empty &&
				!flags.invalidMonth &&
				!flags.invalidWeekday &&
				!flags.weekdayMismatch &&
				!flags.nullInput &&
				!flags.invalidFormat &&
				!flags.userInvalidated &&
				(!flags.meridiem || (flags.meridiem && parsedParts));

			if (m._strict) {
				isNowValid = isNowValid &&
					flags.charsLeftOver === 0 &&
					flags.unusedTokens.length === 0 &&
					flags.bigHour === undefined;
			}

			if (Object.isFrozen == null || !Object.isFrozen(m)) {
				m._isValid = isNowValid;
			}
			else {
				return isNowValid;
			}
		}
		return m._isValid;
	}

	function createInvalid (flags) {
		var m = createUTC(NaN);
		if (flags != null) {
			extend(getParsingFlags(m), flags);
		}
		else {
			getParsingFlags(m).userInvalidated = true;
		}

		return m;
	}

	// Plugins that add properties should also add the key here (null value),
	// so we can properly clone ourselves.
	var momentProperties = hooks.momentProperties = [];

	function copyConfig(to, from) {
		var i, prop, val;

		if (!isUndefined(from._isAMomentObject)) {
			to._isAMomentObject = from._isAMomentObject;
		}
		if (!isUndefined(from._i)) {
			to._i = from._i;
		}
		if (!isUndefined(from._f)) {
			to._f = from._f;
		}
		if (!isUndefined(from._l)) {
			to._l = from._l;
		}
		if (!isUndefined(from._strict)) {
			to._strict = from._strict;
		}
		if (!isUndefined(from._tzm)) {
			to._tzm = from._tzm;
		}
		if (!isUndefined(from._isUTC)) {
			to._isUTC = from._isUTC;
		}
		if (!isUndefined(from._offset)) {
			to._offset = from._offset;
		}
		if (!isUndefined(from._pf)) {
			to._pf = getParsingFlags(from);
		}
		if (!isUndefined(from._locale)) {
			to._locale = from._locale;
		}

		if (momentProperties.length > 0) {
			for (i = 0; i < momentProperties.length; i++) {
				prop = momentProperties[i];
				val = from[prop];
				if (!isUndefined(val)) {
					to[prop] = val;
				}
			}
		}

		return to;
	}

	var updateInProgress = false;

	// Moment prototype object
	function Moment(config) {
		copyConfig(this, config);
		this._d = new Date(config._d != null ? config._d.getTime() : NaN);
		if (!this.isValid()) {
			this._d = new Date(NaN);
		}
		// Prevent infinite loop in case updateOffset creates new moment
		// objects.
		if (updateInProgress === false) {
			updateInProgress = true;
			hooks.updateOffset(this);
			updateInProgress = false;
		}
	}

	function isMoment (obj) {
		return obj instanceof Moment || (obj != null && obj._isAMomentObject != null);
	}

	function absFloor (number) {
		if (number < 0) {
			// -0 -> 0
			return Math.ceil(number) || 0;
		} else {
			return Math.floor(number);
		}
	}

	function toInt(argumentForCoercion) {
		var coercedNumber = +argumentForCoercion,
			value = 0;

		if (coercedNumber !== 0 && isFinite(coercedNumber)) {
			value = absFloor(coercedNumber);
		}

		return value;
	}

	// compare two arrays, return the number of differences
	function compareArrays(array1, array2, dontConvert) {
		var len = Math.min(array1.length, array2.length),
			lengthDiff = Math.abs(array1.length - array2.length),
			diffs = 0,
			i;
		for (i = 0; i < len; i++) {
			if ((dontConvert && array1[i] !== array2[i]) ||
				(!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
				diffs++;
			}
		}
		return diffs + lengthDiff;
	}

	function warn(msg) {
		if (hooks.suppressDeprecationWarnings === false &&
			(typeof console !==  'undefined') && console.warn) {
			console.warn('Deprecation warning: ' + msg);
		}
	}

	function deprecate(msg, fn) {
		var firstTime = true;

		return extend(function () {
			if (hooks.deprecationHandler != null) {
				hooks.deprecationHandler(null, msg);
			}
			if (firstTime) {
				var args = [];
				var arg;
				for (var i = 0; i < arguments.length; i++) {
					arg = '';
					if (typeof arguments[i] === 'object') {
						arg += '\n[' + i + '] ';
						for (var key in arguments[0]) {
							arg += key + ': ' + arguments[0][key] + ', ';
						}
						arg = arg.slice(0, -2); // Remove trailing comma and space
					} else {
						arg = arguments[i];
					}
					args.push(arg);
				}
				warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack);
				firstTime = false;
			}
			return fn.apply(this, arguments);
		}, fn);
	}

	var deprecations = {};

	function deprecateSimple(name, msg) {
		if (hooks.deprecationHandler != null) {
			hooks.deprecationHandler(name, msg);
		}
		if (!deprecations[name]) {
			warn(msg);
			deprecations[name] = true;
		}
	}

	hooks.suppressDeprecationWarnings = false;
	hooks.deprecationHandler = null;

	function isFunction(input) {
		return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
	}

	function set (config) {
		var prop, i;
		for (i in config) {
			prop = config[i];
			if (isFunction(prop)) {
				this[i] = prop;
			} else {
				this['_' + i] = prop;
			}
		}
		this._config = config;
		// Lenient ordinal parsing accepts just a number in addition to
		// number + (possibly) stuff coming from _dayOfMonthOrdinalParse.
		// TODO: Remove "ordinalParse" fallback in next major release.
		this._dayOfMonthOrdinalParseLenient = new RegExp(
			(this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) +
			'|' + (/\d{1,2}/).source);
	}

	function mergeConfigs(parentConfig, childConfig) {
		var res = extend({}, parentConfig), prop;
		for (prop in childConfig) {
			if (hasOwnProp(childConfig, prop)) {
				if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) {
					res[prop] = {};
					extend(res[prop], parentConfig[prop]);
					extend(res[prop], childConfig[prop]);
				} else if (childConfig[prop] != null) {
					res[prop] = childConfig[prop];
				} else {
					delete res[prop];
				}
			}
		}
		for (prop in parentConfig) {
			if (hasOwnProp(parentConfig, prop) &&
				!hasOwnProp(childConfig, prop) &&
				isObject(parentConfig[prop])) {
				// make sure changes to properties don't modify parent config
				res[prop] = extend({}, res[prop]);
			}
		}
		return res;
	}

	function Locale(config) {
		if (config != null) {
			this.set(config);
		}
	}

	var keys;

	if (Object.keys) {
		keys = Object.keys;
	} else {
		keys = function (obj) {
			var i, res = [];
			for (i in obj) {
				if (hasOwnProp(obj, i)) {
					res.push(i);
				}
			}
			return res;
		};
	}

	var defaultCalendar = {
		sameDay : '[Today at] LT',
		nextDay : '[Tomorrow at] LT',
		nextWeek : 'dddd [at] LT',
		lastDay : '[Yesterday at] LT',
		lastWeek : '[Last] dddd [at] LT',
		sameElse : 'L'
	};

	function calendar (key, mom, now) {
		var output = this._calendar[key] || this._calendar['sameElse'];
		return isFunction(output) ? output.call(mom, now) : output;
	}

	var defaultLongDateFormat = {
		LTS  : 'h:mm:ss A',
		LT   : 'h:mm A',
		L    : 'MM/DD/YYYY',
		LL   : 'MMMM D, YYYY',
		LLL  : 'MMMM D, YYYY h:mm A',
		LLLL : 'dddd, MMMM D, YYYY h:mm A'
	};

	function longDateFormat (key) {
		var format = this._longDateFormat[key],
			formatUpper = this._longDateFormat[key.toUpperCase()];

		if (format || !formatUpper) {
			return format;
		}

		this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) {
			return val.slice(1);
		});

		return this._longDateFormat[key];
	}

	var defaultInvalidDate = 'Invalid date';

	function invalidDate () {
		return this._invalidDate;
	}

	var defaultOrdinal = '%d';
	var defaultDayOfMonthOrdinalParse = /\d{1,2}/;

	function ordinal (number) {
		return this._ordinal.replace('%d', number);
	}

	var defaultRelativeTime = {
		future : 'in %s',
		past   : '%s ago',
		s  : 'a few seconds',
		ss : '%d seconds',
		m  : 'a minute',
		mm : '%d minutes',
		h  : 'an hour',
		hh : '%d hours',
		d  : 'a day',
		dd : '%d days',
		M  : 'a month',
		MM : '%d months',
		y  : 'a year',
		yy : '%d years'
	};

	function relativeTime (number, withoutSuffix, string, isFuture) {
		var output = this._relativeTime[string];
		return (isFunction(output)) ?
			output(number, withoutSuffix, string, isFuture) :
			output.replace(/%d/i, number);
	}

	function pastFuture (diff, output) {
		var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
		return isFunction(format) ? format(output) : format.replace(/%s/i, output);
	}

	var aliases = {};

	function addUnitAlias (unit, shorthand) {
		var lowerCase = unit.toLowerCase();
		aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;
	}

	function normalizeUnits(units) {
		return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;
	}

	function normalizeObjectUnits(inputObject) {
		var normalizedInput = {},
			normalizedProp,
			prop;

		for (prop in inputObject) {
			if (hasOwnProp(inputObject, prop)) {
				normalizedProp = normalizeUnits(prop);
				if (normalizedProp) {
					normalizedInput[normalizedProp] = inputObject[prop];
				}
			}
		}

		return normalizedInput;
	}

	var priorities = {};

	function addUnitPriority(unit, priority) {
		priorities[unit] = priority;
	}

	function getPrioritizedUnits(unitsObj) {
		var units = [];
		for (var u in unitsObj) {
			units.push({unit: u, priority: priorities[u]});
		}
		units.sort(function (a, b) {
			return a.priority - b.priority;
		});
		return units;
	}

	function zeroFill(number, targetLength, forceSign) {
		var absNumber = '' + Math.abs(number),
			zerosToFill = targetLength - absNumber.length,
			sign = number >= 0;
		return (sign ? (forceSign ? '+' : '') : '-') +
			Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber;
	}

	var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g;

	var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g;

	var formatFunctions = {};

	var formatTokenFunctions = {};

	// token:    'M'
	// padded:   ['MM', 2]
	// ordinal:  'Mo'
	// callback: function () { this.month() + 1 }
	function addFormatToken (token, padded, ordinal, callback) {
		var func = callback;
		if (typeof callback === 'string') {
			func = function () {
				return this[callback]();
			};
		}
		if (token) {
			formatTokenFunctions[token] = func;
		}
		if (padded) {
			formatTokenFunctions[padded[0]] = function () {
				return zeroFill(func.apply(this, arguments), padded[1], padded[2]);
			};
		}
		if (ordinal) {
			formatTokenFunctions[ordinal] = function () {
				return this.localeData().ordinal(func.apply(this, arguments), token);
			};
		}
	}

	function removeFormattingTokens(input) {
		if (input.match(/\[[\s\S]/)) {
			return input.replace(/^\[|\]$/g, '');
		}
		return input.replace(/\\/g, '');
	}

	function makeFormatFunction(format) {
		var array = format.match(formattingTokens), i, length;

		for (i = 0, length = array.length; i < length; i++) {
			if (formatTokenFunctions[array[i]]) {
				array[i] = formatTokenFunctions[array[i]];
			} else {
				array[i] = removeFormattingTokens(array[i]);
			}
		}

		return function (mom) {
			var output = '', i;
			for (i = 0; i < length; i++) {
				output += isFunction(array[i]) ? array[i].call(mom, format) : array[i];
			}
			return output;
		};
	}

	// format date using native date object
	function formatMoment(m, format) {
		if (!m.isValid()) {
			return m.localeData().invalidDate();
		}

		format = expandFormat(format, m.localeData());
		formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format);

		return formatFunctions[format](m);
	}

	function expandFormat(format, locale) {
		var i = 5;

		function replaceLongDateFormatTokens(input) {
			return locale.longDateFormat(input) || input;
		}

		localFormattingTokens.lastIndex = 0;
		while (i >= 0 && localFormattingTokens.test(format)) {
			format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
			localFormattingTokens.lastIndex = 0;
			i -= 1;
		}

		return format;
	}

	var match1         = /\d/;            //       0 - 9
	var match2         = /\d\d/;          //      00 - 99
	var match3         = /\d{3}/;         //     000 - 999
	var match4         = /\d{4}/;         //    0000 - 9999
	var match6         = /[+-]?\d{6}/;    // -999999 - 999999
	var match1to2      = /\d\d?/;         //       0 - 99
	var match3to4      = /\d\d\d\d?/;     //     999 - 9999
	var match5to6      = /\d\d\d\d\d\d?/; //   99999 - 999999
	var match1to3      = /\d{1,3}/;       //       0 - 999
	var match1to4      = /\d{1,4}/;       //       0 - 9999
	var match1to6      = /[+-]?\d{1,6}/;  // -999999 - 999999

	var matchUnsigned  = /\d+/;           //       0 - inf
	var matchSigned    = /[+-]?\d+/;      //    -inf - inf

	var matchOffset    = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z
	var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z

	var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123

	// any word (or two) characters or numbers including two/three word month in arabic.
	// includes scottish gaelic two word and hyphenated months
	var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;

	var regexes = {};

	function addRegexToken (token, regex, strictRegex) {
		regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) {
			return (isStrict && strictRegex) ? strictRegex : regex;
		};
	}

	function getParseRegexForToken (token, config) {
		if (!hasOwnProp(regexes, token)) {
			return new RegExp(unescapeFormat(token));
		}

		return regexes[token](config._strict, config._locale);
	}

	// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
	function unescapeFormat(s) {
		return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
			return p1 || p2 || p3 || p4;
		}));
	}

	function regexEscape(s) {
		return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
	}

	var tokens = {};

	function addParseToken (token, callback) {
		var i, func = callback;
		if (typeof token === 'string') {
			token = [token];
		}
		if (isNumber(callback)) {
			func = function (input, array) {
				array[callback] = toInt(input);
			};
		}
		for (i = 0; i < token.length; i++) {
			tokens[token[i]] = func;
		}
	}

	function addWeekParseToken (token, callback) {
		addParseToken(token, function (input, array, config, token) {
			config._w = config._w || {};
			callback(input, config._w, config, token);
		});
	}

	function addTimeToArrayFromToken(token, input, config) {
		if (input != null && hasOwnProp(tokens, token)) {
			tokens[token](input, config._a, config, token);
		}
	}

	var YEAR = 0;
	var MONTH = 1;
	var DATE = 2;
	var HOUR = 3;
	var MINUTE = 4;
	var SECOND = 5;
	var MILLISECOND = 6;
	var WEEK = 7;
	var WEEKDAY = 8;

	// FORMATTING

	addFormatToken('Y', 0, 0, function () {
		var y = this.year();
		return y <= 9999 ? '' + y : '+' + y;
	});

	addFormatToken(0, ['YY', 2], 0, function () {
		return this.year() % 100;
	});

	addFormatToken(0, ['YYYY',   4],       0, 'year');
	addFormatToken(0, ['YYYYY',  5],       0, 'year');
	addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');

	// ALIASES

	addUnitAlias('year', 'y');

	// PRIORITIES

	addUnitPriority('year', 1);

	// PARSING

	addRegexToken('Y',      matchSigned);
	addRegexToken('YY',     match1to2, match2);
	addRegexToken('YYYY',   match1to4, match4);
	addRegexToken('YYYYY',  match1to6, match6);
	addRegexToken('YYYYYY', match1to6, match6);

	addParseToken(['YYYYY', 'YYYYYY'], YEAR);
	addParseToken('YYYY', function (input, array) {
		array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input);
	});
	addParseToken('YY', function (input, array) {
		array[YEAR] = hooks.parseTwoDigitYear(input);
	});
	addParseToken('Y', function (input, array) {
		array[YEAR] = parseInt(input, 10);
	});

	// HELPERS

	function daysInYear(year) {
		return isLeapYear(year) ? 366 : 365;
	}

	function isLeapYear(year) {
		return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
	}

	// HOOKS

	hooks.parseTwoDigitYear = function (input) {
		return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
	};

	// MOMENTS

	var getSetYear = makeGetSet('FullYear', true);

	function getIsLeapYear () {
		return isLeapYear(this.year());
	}

	function makeGetSet (unit, keepTime) {
		return function (value) {
			if (value != null) {
				set$1(this, unit, value);
				hooks.updateOffset(this, keepTime);
				return this;
			} else {
				return get(this, unit);
			}
		};
	}

	function get (mom, unit) {
		return mom.isValid() ?
			mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN;
	}

	function set$1 (mom, unit, value) {
		if (mom.isValid() && !isNaN(value)) {
			if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) {
				mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month()));
			}
			else {
				mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);
			}
		}
	}

	// MOMENTS

	function stringGet (units) {
		units = normalizeUnits(units);
		if (isFunction(this[units])) {
			return this[units]();
		}
		return this;
	}


	function stringSet (units, value) {
		if (typeof units === 'object') {
			units = normalizeObjectUnits(units);
			var prioritized = getPrioritizedUnits(units);
			for (var i = 0; i < prioritized.length; i++) {
				this[prioritized[i].unit](units[prioritized[i].unit]);
			}
		} else {
			units = normalizeUnits(units);
			if (isFunction(this[units])) {
				return this[units](value);
			}
		}
		return this;
	}

	function mod(n, x) {
		return ((n % x) + x) % x;
	}

	var indexOf;

	if (Array.prototype.indexOf) {
		indexOf = Array.prototype.indexOf;
	} else {
		indexOf = function (o) {
			// I know
			var i;
			for (i = 0; i < this.length; ++i) {
				if (this[i] === o) {
					return i;
				}
			}
			return -1;
		};
	}

	function daysInMonth(year, month) {
		if (isNaN(year) || isNaN(month)) {
			return NaN;
		}
		var modMonth = mod(month, 12);
		year += (month - modMonth) / 12;
		return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2);
	}

	// FORMATTING

	addFormatToken('M', ['MM', 2], 'Mo', function () {
		return this.month() + 1;
	});

	addFormatToken('MMM', 0, 0, function (format) {
		return this.localeData().monthsShort(this, format);
	});

	addFormatToken('MMMM', 0, 0, function (format) {
		return this.localeData().months(this, format);
	});

	// ALIASES

	addUnitAlias('month', 'M');

	// PRIORITY

	addUnitPriority('month', 8);

	// PARSING

	addRegexToken('M',    match1to2);
	addRegexToken('MM',   match1to2, match2);
	addRegexToken('MMM',  function (isStrict, locale) {
		return locale.monthsShortRegex(isStrict);
	});
	addRegexToken('MMMM', function (isStrict, locale) {
		return locale.monthsRegex(isStrict);
	});

	addParseToken(['M', 'MM'], function (input, array) {
		array[MONTH] = toInt(input) - 1;
	});

	addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
		var month = config._locale.monthsParse(input, token, config._strict);
		// if we didn't find a month name, mark the date as invalid.
		if (month != null) {
			array[MONTH] = month;
		} else {
			getParsingFlags(config).invalidMonth = input;
		}
	});

	// LOCALES

	var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/;
	var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
	function localeMonths (m, format) {
		if (!m) {
			return isArray(this._months) ? this._months :
				this._months['standalone'];
		}
		return isArray(this._months) ? this._months[m.month()] :
			this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()];
	}

	var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');
	function localeMonthsShort (m, format) {
		if (!m) {
			return isArray(this._monthsShort) ? this._monthsShort :
				this._monthsShort['standalone'];
		}
		return isArray(this._monthsShort) ? this._monthsShort[m.month()] :
			this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()];
	}

	function handleStrictParse(monthName, format, strict) {
		var i, ii, mom, llc = monthName.toLocaleLowerCase();
		if (!this._monthsParse) {
			// this is not used
			this._monthsParse = [];
			this._longMonthsParse = [];
			this._shortMonthsParse = [];
			for (i = 0; i < 12; ++i) {
				mom = createUTC([2000, i]);
				this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase();
				this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase();
			}
		}

		if (strict) {
			if (format === 'MMM') {
				ii = indexOf.call(this._shortMonthsParse, llc);
				return ii !== -1 ? ii : null;
			} else {
				ii = indexOf.call(this._longMonthsParse, llc);
				return ii !== -1 ? ii : null;
			}
		} else {
			if (format === 'MMM') {
				ii = indexOf.call(this._shortMonthsParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._longMonthsParse, llc);
				return ii !== -1 ? ii : null;
			} else {
				ii = indexOf.call(this._longMonthsParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._shortMonthsParse, llc);
				return ii !== -1 ? ii : null;
			}
		}
	}

	function localeMonthsParse (monthName, format, strict) {
		var i, mom, regex;

		if (this._monthsParseExact) {
			return handleStrictParse.call(this, monthName, format, strict);
		}

		if (!this._monthsParse) {
			this._monthsParse = [];
			this._longMonthsParse = [];
			this._shortMonthsParse = [];
		}

		// TODO: add sorting
		// Sorting makes sure if one month (or abbr) is a prefix of another
		// see sorting in computeMonthsParse
		for (i = 0; i < 12; i++) {
			// make the regex if we don't have it already
			mom = createUTC([2000, i]);
			if (strict && !this._longMonthsParse[i]) {
				this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
				this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');
			}
			if (!strict && !this._monthsParse[i]) {
				regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
				this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
			}
			// test the regex
			if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
				return i;
			} else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
				return i;
			} else if (!strict && this._monthsParse[i].test(monthName)) {
				return i;
			}
		}
	}

	// MOMENTS

	function setMonth (mom, value) {
		var dayOfMonth;

		if (!mom.isValid()) {
			// No op
			return mom;
		}

		if (typeof value === 'string') {
			if (/^\d+$/.test(value)) {
				value = toInt(value);
			} else {
				value = mom.localeData().monthsParse(value);
				// TODO: Another silent failure?
				if (!isNumber(value)) {
					return mom;
				}
			}
		}

		dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));
		mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);
		return mom;
	}

	function getSetMonth (value) {
		if (value != null) {
			setMonth(this, value);
			hooks.updateOffset(this, true);
			return this;
		} else {
			return get(this, 'Month');
		}
	}

	function getDaysInMonth () {
		return daysInMonth(this.year(), this.month());
	}

	var defaultMonthsShortRegex = matchWord;
	function monthsShortRegex (isStrict) {
		if (this._monthsParseExact) {
			if (!hasOwnProp(this, '_monthsRegex')) {
				computeMonthsParse.call(this);
			}
			if (isStrict) {
				return this._monthsShortStrictRegex;
			} else {
				return this._monthsShortRegex;
			}
		} else {
			if (!hasOwnProp(this, '_monthsShortRegex')) {
				this._monthsShortRegex = defaultMonthsShortRegex;
			}
			return this._monthsShortStrictRegex && isStrict ?
				this._monthsShortStrictRegex : this._monthsShortRegex;
		}
	}

	var defaultMonthsRegex = matchWord;
	function monthsRegex (isStrict) {
		if (this._monthsParseExact) {
			if (!hasOwnProp(this, '_monthsRegex')) {
				computeMonthsParse.call(this);
			}
			if (isStrict) {
				return this._monthsStrictRegex;
			} else {
				return this._monthsRegex;
			}
		} else {
			if (!hasOwnProp(this, '_monthsRegex')) {
				this._monthsRegex = defaultMonthsRegex;
			}
			return this._monthsStrictRegex && isStrict ?
				this._monthsStrictRegex : this._monthsRegex;
		}
	}

	function computeMonthsParse () {
		function cmpLenRev(a, b) {
			return b.length - a.length;
		}

		var shortPieces = [], longPieces = [], mixedPieces = [],
			i, mom;
		for (i = 0; i < 12; i++) {
			// make the regex if we don't have it already
			mom = createUTC([2000, i]);
			shortPieces.push(this.monthsShort(mom, ''));
			longPieces.push(this.months(mom, ''));
			mixedPieces.push(this.months(mom, ''));
			mixedPieces.push(this.monthsShort(mom, ''));
		}
		// Sorting makes sure if one month (or abbr) is a prefix of another it
		// will match the longer piece.
		shortPieces.sort(cmpLenRev);
		longPieces.sort(cmpLenRev);
		mixedPieces.sort(cmpLenRev);
		for (i = 0; i < 12; i++) {
			shortPieces[i] = regexEscape(shortPieces[i]);
			longPieces[i] = regexEscape(longPieces[i]);
		}
		for (i = 0; i < 24; i++) {
			mixedPieces[i] = regexEscape(mixedPieces[i]);
		}

		this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
		this._monthsShortRegex = this._monthsRegex;
		this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
		this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
	}

	function createDate (y, m, d, h, M, s, ms) {
		// can't just apply() to create a date:
		// https://stackoverflow.com/q/181348
		var date = new Date(y, m, d, h, M, s, ms);

		// the date constructor remaps years 0-99 to 1900-1999
		if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
			date.setFullYear(y);
		}
		return date;
	}

	function createUTCDate (y) {
		var date = new Date(Date.UTC.apply(null, arguments));

		// the Date.UTC function remaps years 0-99 to 1900-1999
		if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
			date.setUTCFullYear(y);
		}
		return date;
	}

	// start-of-first-week - start-of-year
	function firstWeekOffset(year, dow, doy) {
		var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
			fwd = 7 + dow - doy,
			// first-week day local weekday -- which local weekday is fwd
			fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;

		return -fwdlw + fwd - 1;
	}

	// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
	function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
		var localWeekday = (7 + weekday - dow) % 7,
			weekOffset = firstWeekOffset(year, dow, doy),
			dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset,
			resYear, resDayOfYear;

		if (dayOfYear <= 0) {
			resYear = year - 1;
			resDayOfYear = daysInYear(resYear) + dayOfYear;
		} else if (dayOfYear > daysInYear(year)) {
			resYear = year + 1;
			resDayOfYear = dayOfYear - daysInYear(year);
		} else {
			resYear = year;
			resDayOfYear = dayOfYear;
		}

		return {
			year: resYear,
			dayOfYear: resDayOfYear
		};
	}

	function weekOfYear(mom, dow, doy) {
		var weekOffset = firstWeekOffset(mom.year(), dow, doy),
			week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1,
			resWeek, resYear;

		if (week < 1) {
			resYear = mom.year() - 1;
			resWeek = week + weeksInYear(resYear, dow, doy);
		} else if (week > weeksInYear(mom.year(), dow, doy)) {
			resWeek = week - weeksInYear(mom.year(), dow, doy);
			resYear = mom.year() + 1;
		} else {
			resYear = mom.year();
			resWeek = week;
		}

		return {
			week: resWeek,
			year: resYear
		};
	}

	function weeksInYear(year, dow, doy) {
		var weekOffset = firstWeekOffset(year, dow, doy),
			weekOffsetNext = firstWeekOffset(year + 1, dow, doy);
		return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
	}

	// FORMATTING

	addFormatToken('w', ['ww', 2], 'wo', 'week');
	addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');

	// ALIASES

	addUnitAlias('week', 'w');
	addUnitAlias('isoWeek', 'W');

	// PRIORITIES

	addUnitPriority('week', 5);
	addUnitPriority('isoWeek', 5);

	// PARSING

	addRegexToken('w',  match1to2);
	addRegexToken('ww', match1to2, match2);
	addRegexToken('W',  match1to2);
	addRegexToken('WW', match1to2, match2);

	addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {
		week[token.substr(0, 1)] = toInt(input);
	});

	// HELPERS

	// LOCALES

	function localeWeek (mom) {
		return weekOfYear(mom, this._week.dow, this._week.doy).week;
	}

	var defaultLocaleWeek = {
		dow : 0, // Sunday is the first day of the week.
		doy : 6  // The week that contains Jan 1st is the first week of the year.
	};

	function localeFirstDayOfWeek () {
		return this._week.dow;
	}

	function localeFirstDayOfYear () {
		return this._week.doy;
	}

	// MOMENTS

	function getSetWeek (input) {
		var week = this.localeData().week(this);
		return input == null ? week : this.add((input - week) * 7, 'd');
	}

	function getSetISOWeek (input) {
		var week = weekOfYear(this, 1, 4).week;
		return input == null ? week : this.add((input - week) * 7, 'd');
	}

	// FORMATTING

	addFormatToken('d', 0, 'do', 'day');

	addFormatToken('dd', 0, 0, function (format) {
		return this.localeData().weekdaysMin(this, format);
	});

	addFormatToken('ddd', 0, 0, function (format) {
		return this.localeData().weekdaysShort(this, format);
	});

	addFormatToken('dddd', 0, 0, function (format) {
		return this.localeData().weekdays(this, format);
	});

	addFormatToken('e', 0, 0, 'weekday');
	addFormatToken('E', 0, 0, 'isoWeekday');

	// ALIASES

	addUnitAlias('day', 'd');
	addUnitAlias('weekday', 'e');
	addUnitAlias('isoWeekday', 'E');

	// PRIORITY
	addUnitPriority('day', 11);
	addUnitPriority('weekday', 11);
	addUnitPriority('isoWeekday', 11);

	// PARSING

	addRegexToken('d',    match1to2);
	addRegexToken('e',    match1to2);
	addRegexToken('E',    match1to2);
	addRegexToken('dd',   function (isStrict, locale) {
		return locale.weekdaysMinRegex(isStrict);
	});
	addRegexToken('ddd',   function (isStrict, locale) {
		return locale.weekdaysShortRegex(isStrict);
	});
	addRegexToken('dddd',   function (isStrict, locale) {
		return locale.weekdaysRegex(isStrict);
	});

	addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
		var weekday = config._locale.weekdaysParse(input, token, config._strict);
		// if we didn't get a weekday name, mark the date as invalid
		if (weekday != null) {
			week.d = weekday;
		} else {
			getParsingFlags(config).invalidWeekday = input;
		}
	});

	addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {
		week[token] = toInt(input);
	});

	// HELPERS

	function parseWeekday(input, locale) {
		if (typeof input !== 'string') {
			return input;
		}

		if (!isNaN(input)) {
			return parseInt(input, 10);
		}

		input = locale.weekdaysParse(input);
		if (typeof input === 'number') {
			return input;
		}

		return null;
	}

	function parseIsoWeekday(input, locale) {
		if (typeof input === 'string') {
			return locale.weekdaysParse(input) % 7 || 7;
		}
		return isNaN(input) ? null : input;
	}

	// LOCALES

	var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
	function localeWeekdays (m, format) {
		if (!m) {
			return isArray(this._weekdays) ? this._weekdays :
				this._weekdays['standalone'];
		}
		return isArray(this._weekdays) ? this._weekdays[m.day()] :
			this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()];
	}

	var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');
	function localeWeekdaysShort (m) {
		return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort;
	}

	var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');
	function localeWeekdaysMin (m) {
		return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin;
	}

	function handleStrictParse$1(weekdayName, format, strict) {
		var i, ii, mom, llc = weekdayName.toLocaleLowerCase();
		if (!this._weekdaysParse) {
			this._weekdaysParse = [];
			this._shortWeekdaysParse = [];
			this._minWeekdaysParse = [];

			for (i = 0; i < 7; ++i) {
				mom = createUTC([2000, 1]).day(i);
				this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase();
				this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase();
				this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase();
			}
		}

		if (strict) {
			if (format === 'dddd') {
				ii = indexOf.call(this._weekdaysParse, llc);
				return ii !== -1 ? ii : null;
			} else if (format === 'ddd') {
				ii = indexOf.call(this._shortWeekdaysParse, llc);
				return ii !== -1 ? ii : null;
			} else {
				ii = indexOf.call(this._minWeekdaysParse, llc);
				return ii !== -1 ? ii : null;
			}
		} else {
			if (format === 'dddd') {
				ii = indexOf.call(this._weekdaysParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._shortWeekdaysParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._minWeekdaysParse, llc);
				return ii !== -1 ? ii : null;
			} else if (format === 'ddd') {
				ii = indexOf.call(this._shortWeekdaysParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._weekdaysParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._minWeekdaysParse, llc);
				return ii !== -1 ? ii : null;
			} else {
				ii = indexOf.call(this._minWeekdaysParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._weekdaysParse, llc);
				if (ii !== -1) {
					return ii;
				}
				ii = indexOf.call(this._shortWeekdaysParse, llc);
				return ii !== -1 ? ii : null;
			}
		}
	}

	function localeWeekdaysParse (weekdayName, format, strict) {
		var i, mom, regex;

		if (this._weekdaysParseExact) {
			return handleStrictParse$1.call(this, weekdayName, format, strict);
		}

		if (!this._weekdaysParse) {
			this._weekdaysParse = [];
			this._minWeekdaysParse = [];
			this._shortWeekdaysParse = [];
			this._fullWeekdaysParse = [];
		}

		for (i = 0; i < 7; i++) {
			// make the regex if we don't have it already

			mom = createUTC([2000, 1]).day(i);
			if (strict && !this._fullWeekdaysParse[i]) {
				this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i');
				this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i');
				this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i');
			}
			if (!this._weekdaysParse[i]) {
				regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
				this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
			}
			// test the regex
			if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
				return i;
			} else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
				return i;
			} else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) {
				return i;
			} else if (!strict && this._weekdaysParse[i].test(weekdayName)) {
				return i;
			}
		}
	}

	// MOMENTS

	function getSetDayOfWeek (input) {
		if (!this.isValid()) {
			return input != null ? this : NaN;
		}
		var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
		if (input != null) {
			input = parseWeekday(input, this.localeData());
			return this.add(input - day, 'd');
		} else {
			return day;
		}
	}

	function getSetLocaleDayOfWeek (input) {
		if (!this.isValid()) {
			return input != null ? this : NaN;
		}
		var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
		return input == null ? weekday : this.add(input - weekday, 'd');
	}

	function getSetISODayOfWeek (input) {
		if (!this.isValid()) {
			return input != null ? this : NaN;
		}

		// behaves the same as moment#day except
		// as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
		// as a setter, sunday should belong to the previous week.

		if (input != null) {
			var weekday = parseIsoWeekday(input, this.localeData());
			return this.day(this.day() % 7 ? weekday : weekday - 7);
		} else {
			return this.day() || 7;
		}
	}

	var defaultWeekdaysRegex = matchWord;
	function weekdaysRegex (isStrict) {
		if (this._weekdaysParseExact) {
			if (!hasOwnProp(this, '_weekdaysRegex')) {
				computeWeekdaysParse.call(this);
			}
			if (isStrict) {
				return this._weekdaysStrictRegex;
			} else {
				return this._weekdaysRegex;
			}
		} else {
			if (!hasOwnProp(this, '_weekdaysRegex')) {
				this._weekdaysRegex = defaultWeekdaysRegex;
			}
			return this._weekdaysStrictRegex && isStrict ?
				this._weekdaysStrictRegex : this._weekdaysRegex;
		}
	}

	var defaultWeekdaysShortRegex = matchWord;
	function weekdaysShortRegex (isStrict) {
		if (this._weekdaysParseExact) {
			if (!hasOwnProp(this, '_weekdaysRegex')) {
				computeWeekdaysParse.call(this);
			}
			if (isStrict) {
				return this._weekdaysShortStrictRegex;
			} else {
				return this._weekdaysShortRegex;
			}
		} else {
			if (!hasOwnProp(this, '_weekdaysShortRegex')) {
				this._weekdaysShortRegex = defaultWeekdaysShortRegex;
			}
			return this._weekdaysShortStrictRegex && isStrict ?
				this._weekdaysShortStrictRegex : this._weekdaysShortRegex;
		}
	}

	var defaultWeekdaysMinRegex = matchWord;
	function weekdaysMinRegex (isStrict) {
		if (this._weekdaysParseExact) {
			if (!hasOwnProp(this, '_weekdaysRegex')) {
				computeWeekdaysParse.call(this);
			}
			if (isStrict) {
				return this._weekdaysMinStrictRegex;
			} else {
				return this._weekdaysMinRegex;
			}
		} else {
			if (!hasOwnProp(this, '_weekdaysMinRegex')) {
				this._weekdaysMinRegex = defaultWeekdaysMinRegex;
			}
			return this._weekdaysMinStrictRegex && isStrict ?
				this._weekdaysMinStrictRegex : this._weekdaysMinRegex;
		}
	}


	function computeWeekdaysParse () {
		function cmpLenRev(a, b) {
			return b.length - a.length;
		}

		var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [],
			i, mom, minp, shortp, longp;
		for (i = 0; i < 7; i++) {
			// make the regex if we don't have it already
			mom = createUTC([2000, 1]).day(i);
			minp = this.weekdaysMin(mom, '');
			shortp = this.weekdaysShort(mom, '');
			longp = this.weekdays(mom, '');
			minPieces.push(minp);
			shortPieces.push(shortp);
			longPieces.push(longp);
			mixedPieces.push(minp);
			mixedPieces.push(shortp);
			mixedPieces.push(longp);
		}
		// Sorting makes sure if one weekday (or abbr) is a prefix of another it
		// will match the longer piece.
		minPieces.sort(cmpLenRev);
		shortPieces.sort(cmpLenRev);
		longPieces.sort(cmpLenRev);
		mixedPieces.sort(cmpLenRev);
		for (i = 0; i < 7; i++) {
			shortPieces[i] = regexEscape(shortPieces[i]);
			longPieces[i] = regexEscape(longPieces[i]);
			mixedPieces[i] = regexEscape(mixedPieces[i]);
		}

		this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i');
		this._weekdaysShortRegex = this._weekdaysRegex;
		this._weekdaysMinRegex = this._weekdaysRegex;

		this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i');
		this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
		this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
	}

	// FORMATTING

	function hFormat() {
		return this.hours() % 12 || 12;
	}

	function kFormat() {
		return this.hours() || 24;
	}

	addFormatToken('H', ['HH', 2], 0, 'hour');
	addFormatToken('h', ['hh', 2], 0, hFormat);
	addFormatToken('k', ['kk', 2], 0, kFormat);

	addFormatToken('hmm', 0, 0, function () {
		return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2);
	});

	addFormatToken('hmmss', 0, 0, function () {
		return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) +
			zeroFill(this.seconds(), 2);
	});

	addFormatToken('Hmm', 0, 0, function () {
		return '' + this.hours() + zeroFill(this.minutes(), 2);
	});

	addFormatToken('Hmmss', 0, 0, function () {
		return '' + this.hours() + zeroFill(this.minutes(), 2) +
			zeroFill(this.seconds(), 2);
	});

	function meridiem (token, lowercase) {
		addFormatToken(token, 0, 0, function () {
			return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);
		});
	}

	meridiem('a', true);
	meridiem('A', false);

	// ALIASES

	addUnitAlias('hour', 'h');

	// PRIORITY
	addUnitPriority('hour', 13);

	// PARSING

	function matchMeridiem (isStrict, locale) {
		return locale._meridiemParse;
	}

	addRegexToken('a',  matchMeridiem);
	addRegexToken('A',  matchMeridiem);
	addRegexToken('H',  match1to2);
	addRegexToken('h',  match1to2);
	addRegexToken('k',  match1to2);
	addRegexToken('HH', match1to2, match2);
	addRegexToken('hh', match1to2, match2);
	addRegexToken('kk', match1to2, match2);

	addRegexToken('hmm', match3to4);
	addRegexToken('hmmss', match5to6);
	addRegexToken('Hmm', match3to4);
	addRegexToken('Hmmss', match5to6);

	addParseToken(['H', 'HH'], HOUR);
	addParseToken(['k', 'kk'], function (input, array, config) {
		var kInput = toInt(input);
		array[HOUR] = kInput === 24 ? 0 : kInput;
	});
	addParseToken(['a', 'A'], function (input, array, config) {
		config._isPm = config._locale.isPM(input);
		config._meridiem = input;
	});
	addParseToken(['h', 'hh'], function (input, array, config) {
		array[HOUR] = toInt(input);
		getParsingFlags(config).bigHour = true;
	});
	addParseToken('hmm', function (input, array, config) {
		var pos = input.length - 2;
		array[HOUR] = toInt(input.substr(0, pos));
		array[MINUTE] = toInt(input.substr(pos));
		getParsingFlags(config).bigHour = true;
	});
	addParseToken('hmmss', function (input, array, config) {
		var pos1 = input.length - 4;
		var pos2 = input.length - 2;
		array[HOUR] = toInt(input.substr(0, pos1));
		array[MINUTE] = toInt(input.substr(pos1, 2));
		array[SECOND] = toInt(input.substr(pos2));
		getParsingFlags(config).bigHour = true;
	});
	addParseToken('Hmm', function (input, array, config) {
		var pos = input.length - 2;
		array[HOUR] = toInt(input.substr(0, pos));
		array[MINUTE] = toInt(input.substr(pos));
	});
	addParseToken('Hmmss', function (input, array, config) {
		var pos1 = input.length - 4;
		var pos2 = input.length - 2;
		array[HOUR] = toInt(input.substr(0, pos1));
		array[MINUTE] = toInt(input.substr(pos1, 2));
		array[SECOND] = toInt(input.substr(pos2));
	});

	// LOCALES

	function localeIsPM (input) {
		// IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
		// Using charAt should be more compatible.
		return ((input + '').toLowerCase().charAt(0) === 'p');
	}

	var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i;
	function localeMeridiem (hours, minutes, isLower) {
		if (hours > 11) {
			return isLower ? 'pm' : 'PM';
		} else {
			return isLower ? 'am' : 'AM';
		}
	}


	// MOMENTS

	// Setting the hour should keep the time, because the user explicitly
	// specified which hour they want. So trying to maintain the same hour (in
	// a new timezone) makes sense. Adding/subtracting hours does not follow
	// this rule.
	var getSetHour = makeGetSet('Hours', true);

	var baseConfig = {
		calendar: defaultCalendar,
		longDateFormat: defaultLongDateFormat,
		invalidDate: defaultInvalidDate,
		ordinal: defaultOrdinal,
		dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse,
		relativeTime: defaultRelativeTime,

		months: defaultLocaleMonths,
		monthsShort: defaultLocaleMonthsShort,

		week: defaultLocaleWeek,

		weekdays: defaultLocaleWeekdays,
		weekdaysMin: defaultLocaleWeekdaysMin,
		weekdaysShort: defaultLocaleWeekdaysShort,

		meridiemParse: defaultLocaleMeridiemParse
	};

	// internal storage for locale config files
	var locales = {};
	var localeFamilies = {};
	var globalLocale;

	function normalizeLocale(key) {
		return key ? key.toLowerCase().replace('_', '-') : key;
	}

	// pick the locale from the array
	// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
	// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
	function chooseLocale(names) {
		var i = 0, j, next, locale, split;

		while (i < names.length) {
			split = normalizeLocale(names[i]).split('-');
			j = split.length;
			next = normalizeLocale(names[i + 1]);
			next = next ? next.split('-') : null;
			while (j > 0) {
				locale = loadLocale(split.slice(0, j).join('-'));
				if (locale) {
					return locale;
				}
				if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
					//the next array item is better than a shallower substring of this one
					break;
				}
				j--;
			}
			i++;
		}
		return globalLocale;
	}

	function loadLocale(name) {
		var oldLocale = null;
		// TODO: Find a better way to register and load all the locales in Node
		if (!locales[name] && (typeof module !== 'undefined') &&
			module && module.exports) {
			try {
				oldLocale = globalLocale._abbr;
				var aliasedRequire = require;
				aliasedRequire('./locale/' + name);
				getSetGlobalLocale(oldLocale);
			} catch (e) {}
		}
		return locales[name];
	}

	// This function will load locale and then set the global locale.  If
	// no arguments are passed in, it will simply return the current global
	// locale key.
	function getSetGlobalLocale (key, values) {
		var data;
		if (key) {
			if (isUndefined(values)) {
				data = getLocale(key);
			}
			else {
				data = defineLocale(key, values);
			}

			if (data) {
				// moment.duration._locale = moment._locale = data;
				globalLocale = data;
			}
			else {
				if ((typeof console !==  'undefined') && console.warn) {
					//warn user if arguments are passed but the locale could not be set
					console.warn('Locale ' + key +  ' not found. Did you forget to load it?');
				}
			}
		}

		return globalLocale._abbr;
	}

	function defineLocale (name, config) {
		if (config !== null) {
			var locale, parentConfig = baseConfig;
			config.abbr = name;
			if (locales[name] != null) {
				deprecateSimple('defineLocaleOverride',
					'use moment.updateLocale(localeName, config) to change ' +
					'an existing locale. moment.defineLocale(localeName, ' +
					'config) should only be used for creating a new locale ' +
					'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
				parentConfig = locales[name]._config;
			} else if (config.parentLocale != null) {
				if (locales[config.parentLocale] != null) {
					parentConfig = locales[config.parentLocale]._config;
				} else {
					locale = loadLocale(config.parentLocale);
					if (locale != null) {
						parentConfig = locale._config;
					} else {
						if (!localeFamilies[config.parentLocale]) {
							localeFamilies[config.parentLocale] = [];
						}
						localeFamilies[config.parentLocale].push({
							name: name,
							config: config
						});
						return null;
					}
				}
			}
			locales[name] = new Locale(mergeConfigs(parentConfig, config));

			if (localeFamilies[name]) {
				localeFamilies[name].forEach(function (x) {
					defineLocale(x.name, x.config);
				});
			}

			// backwards compat for now: also set the locale
			// make sure we set the locale AFTER all child locales have been
			// created, so we won't end up with the child locale set.
			getSetGlobalLocale(name);


			return locales[name];
		} else {
			// useful for testing
			delete locales[name];
			return null;
		}
	}

	function updateLocale(name, config) {
		if (config != null) {
			var locale, tmpLocale, parentConfig = baseConfig;
			// MERGE
			tmpLocale = loadLocale(name);
			if (tmpLocale != null) {
				parentConfig = tmpLocale._config;
			}
			config = mergeConfigs(parentConfig, config);
			locale = new Locale(config);
			locale.parentLocale = locales[name];
			locales[name] = locale;

			// backwards compat for now: also set the locale
			getSetGlobalLocale(name);
		} else {
			// pass null for config to unupdate, useful for tests
			if (locales[name] != null) {
				if (locales[name].parentLocale != null) {
					locales[name] = locales[name].parentLocale;
				} else if (locales[name] != null) {
					delete locales[name];
				}
			}
		}
		return locales[name];
	}

	// returns locale data
	function getLocale (key) {
		var locale;

		if (key && key._locale && key._locale._abbr) {
			key = key._locale._abbr;
		}

		if (!key) {
			return globalLocale;
		}

		if (!isArray(key)) {
			//short-circuit everything else
			locale = loadLocale(key);
			if (locale) {
				return locale;
			}
			key = [key];
		}

		return chooseLocale(key);
	}

	function listLocales() {
		return keys(locales);
	}

	function checkOverflow (m) {
		var overflow;
		var a = m._a;

		if (a && getParsingFlags(m).overflow === -2) {
			overflow =
				a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :
					a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :
						a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :
							a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :
								a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :
									a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :
										-1;

			if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
				overflow = DATE;
			}
			if (getParsingFlags(m)._overflowWeeks && overflow === -1) {
				overflow = WEEK;
			}
			if (getParsingFlags(m)._overflowWeekday && overflow === -1) {
				overflow = WEEKDAY;
			}

			getParsingFlags(m).overflow = overflow;
		}

		return m;
	}

	// Pick the first defined of two or three arguments.
	function defaults(a, b, c) {
		if (a != null) {
			return a;
		}
		if (b != null) {
			return b;
		}
		return c;
	}

	function currentDateArray(config) {
		// hooks is actually the exported moment object
		var nowValue = new Date(hooks.now());
		if (config._useUTC) {
			return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()];
		}
		return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
	}

	// convert an array to a date.
	// the array should mirror the parameters below
	// note: all values past the year are optional and will default to the lowest possible value.
	// [year, month, day , hour, minute, second, millisecond]
	function configFromArray (config) {
		var i, date, input = [], currentDate, expectedWeekday, yearToUse;

		if (config._d) {
			return;
		}

		currentDate = currentDateArray(config);

		//compute day of the year from weeks and weekdays
		if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
			dayOfYearFromWeekInfo(config);
		}

		//if the day of the year is set, figure out what it is
		if (config._dayOfYear != null) {
			yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);

			if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) {
				getParsingFlags(config)._overflowDayOfYear = true;
			}

			date = createUTCDate(yearToUse, 0, config._dayOfYear);
			config._a[MONTH] = date.getUTCMonth();
			config._a[DATE] = date.getUTCDate();
		}

		// Default to current date.
		// * if no year, month, day of month are given, default to today
		// * if day of month is given, default month and year
		// * if month is given, default only year
		// * if year is given, don't default anything
		for (i = 0; i < 3 && config._a[i] == null; ++i) {
			config._a[i] = input[i] = currentDate[i];
		}

		// Zero out whatever was not defaulted, including time
		for (; i < 7; i++) {
			config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
		}

		// Check for 24:00:00.000
		if (config._a[HOUR] === 24 &&
			config._a[MINUTE] === 0 &&
			config._a[SECOND] === 0 &&
			config._a[MILLISECOND] === 0) {
			config._nextDay = true;
			config._a[HOUR] = 0;
		}

		config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);
		expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay();

		// Apply timezone offset from input. The actual utcOffset can be changed
		// with parseZone.
		if (config._tzm != null) {
			config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);
		}

		if (config._nextDay) {
			config._a[HOUR] = 24;
		}

		// check for mismatching day of week
		if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) {
			getParsingFlags(config).weekdayMismatch = true;
		}
	}

	function dayOfYearFromWeekInfo(config) {
		var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow;

		w = config._w;
		if (w.GG != null || w.W != null || w.E != null) {
			dow = 1;
			doy = 4;

			// TODO: We need to take the current isoWeekYear, but that depends on
			// how we interpret now (local, utc, fixed offset). So create
			// a now version of current config (take local/utc/offset flags, and
			// create now).
			weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);
			week = defaults(w.W, 1);
			weekday = defaults(w.E, 1);
			if (weekday < 1 || weekday > 7) {
				weekdayOverflow = true;
			}
		} else {
			dow = config._locale._week.dow;
			doy = config._locale._week.doy;

			var curWeek = weekOfYear(createLocal(), dow, doy);

			weekYear = defaults(w.gg, config._a[YEAR], curWeek.year);

			// Default to current week.
			week = defaults(w.w, curWeek.week);

			if (w.d != null) {
				// weekday -- low day numbers are considered next week
				weekday = w.d;
				if (weekday < 0 || weekday > 6) {
					weekdayOverflow = true;
				}
			} else if (w.e != null) {
				// local weekday -- counting starts from begining of week
				weekday = w.e + dow;
				if (w.e < 0 || w.e > 6) {
					weekdayOverflow = true;
				}
			} else {
				// default to begining of week
				weekday = dow;
			}
		}
		if (week < 1 || week > weeksInYear(weekYear, dow, doy)) {
			getParsingFlags(config)._overflowWeeks = true;
		} else if (weekdayOverflow != null) {
			getParsingFlags(config)._overflowWeekday = true;
		} else {
			temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy);
			config._a[YEAR] = temp.year;
			config._dayOfYear = temp.dayOfYear;
		}
	}

	// iso 8601 regex
	// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
	var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;
	var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/;

	var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/;

	var isoDates = [
		['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/],
		['YYYY-MM-DD', /\d{4}-\d\d-\d\d/],
		['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/],
		['GGGG-[W]WW', /\d{4}-W\d\d/, false],
		['YYYY-DDD', /\d{4}-\d{3}/],
		['YYYY-MM', /\d{4}-\d\d/, false],
		['YYYYYYMMDD', /[+-]\d{10}/],
		['YYYYMMDD', /\d{8}/],
		// YYYYMM is NOT allowed by the standard
		['GGGG[W]WWE', /\d{4}W\d{3}/],
		['GGGG[W]WW', /\d{4}W\d{2}/, false],
		['YYYYDDD', /\d{7}/]
	];

	// iso time formats and regexes
	var isoTimes = [
		['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
		['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
		['HH:mm:ss', /\d\d:\d\d:\d\d/],
		['HH:mm', /\d\d:\d\d/],
		['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/],
		['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/],
		['HHmmss', /\d\d\d\d\d\d/],
		['HHmm', /\d\d\d\d/],
		['HH', /\d\d/]
	];

	var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;

	// date from iso format
	function configFromISO(config) {
		var i, l,
			string = config._i,
			match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string),
			allowTime, dateFormat, timeFormat, tzFormat;

		if (match) {
			getParsingFlags(config).iso = true;

			for (i = 0, l = isoDates.length; i < l; i++) {
				if (isoDates[i][1].exec(match[1])) {
					dateFormat = isoDates[i][0];
					allowTime = isoDates[i][2] !== false;
					break;
				}
			}
			if (dateFormat == null) {
				config._isValid = false;
				return;
			}
			if (match[3]) {
				for (i = 0, l = isoTimes.length; i < l; i++) {
					if (isoTimes[i][1].exec(match[3])) {
						// match[2] should be 'T' or space
						timeFormat = (match[2] || ' ') + isoTimes[i][0];
						break;
					}
				}
				if (timeFormat == null) {
					config._isValid = false;
					return;
				}
			}
			if (!allowTime && timeFormat != null) {
				config._isValid = false;
				return;
			}
			if (match[4]) {
				if (tzRegex.exec(match[4])) {
					tzFormat = 'Z';
				} else {
					config._isValid = false;
					return;
				}
			}
			config._f = dateFormat + (timeFormat || '') + (tzFormat || '');
			configFromStringAndFormat(config);
		} else {
			config._isValid = false;
		}
	}

	// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3
	var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/;

	function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
		var result = [
			untruncateYear(yearStr),
			defaultLocaleMonthsShort.indexOf(monthStr),
			parseInt(dayStr, 10),
			parseInt(hourStr, 10),
			parseInt(minuteStr, 10)
		];

		if (secondStr) {
			result.push(parseInt(secondStr, 10));
		}

		return result;
	}

	function untruncateYear(yearStr) {
		var year = parseInt(yearStr, 10);
		if (year <= 49) {
			return 2000 + year;
		} else if (year <= 999) {
			return 1900 + year;
		}
		return year;
	}

	function preprocessRFC2822(s) {
		// Remove comments and folding whitespace and replace multiple-spaces with a single space
		return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	}

	function checkWeekday(weekdayStr, parsedInput, config) {
		if (weekdayStr) {
			// TODO: Replace the vanilla JS Date object with an indepentent day-of-week check.
			var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr),
				weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay();
			if (weekdayProvided !== weekdayActual) {
				getParsingFlags(config).weekdayMismatch = true;
				config._isValid = false;
				return false;
			}
		}
		return true;
	}

	var obsOffsets = {
		UT: 0,
		GMT: 0,
		EDT: -4 * 60,
		EST: -5 * 60,
		CDT: -5 * 60,
		CST: -6 * 60,
		MDT: -6 * 60,
		MST: -7 * 60,
		PDT: -7 * 60,
		PST: -8 * 60
	};

	function calculateOffset(obsOffset, militaryOffset, numOffset) {
		if (obsOffset) {
			return obsOffsets[obsOffset];
		} else if (militaryOffset) {
			// the only allowed military tz is Z
			return 0;
		} else {
			var hm = parseInt(numOffset, 10);
			var m = hm % 100, h = (hm - m) / 100;
			return h * 60 + m;
		}
	}

	// date and time from ref 2822 format
	function configFromRFC2822(config) {
		var match = rfc2822.exec(preprocessRFC2822(config._i));
		if (match) {
			var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]);
			if (!checkWeekday(match[1], parsedArray, config)) {
				return;
			}

			config._a = parsedArray;
			config._tzm = calculateOffset(match[8], match[9], match[10]);

			config._d = createUTCDate.apply(null, config._a);
			config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);

			getParsingFlags(config).rfc2822 = true;
		} else {
			config._isValid = false;
		}
	}

	// date from iso format or fallback
	function configFromString(config) {
		var matched = aspNetJsonRegex.exec(config._i);

		if (matched !== null) {
			config._d = new Date(+matched[1]);
			return;
		}

		configFromISO(config);
		if (config._isValid === false) {
			delete config._isValid;
		} else {
			return;
		}

		configFromRFC2822(config);
		if (config._isValid === false) {
			delete config._isValid;
		} else {
			return;
		}

		// Final attempt, use Input Fallback
		hooks.createFromInputFallback(config);
	}

	hooks.createFromInputFallback = deprecate(
		'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' +
		'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' +
		'discouraged and will be removed in an upcoming major release. Please refer to ' +
		'http://momentjs.com/guides/#/warnings/js-date/ for more info.',
		function (config) {
			config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));
		}
	);

	// constant that refers to the ISO standard
	hooks.ISO_8601 = function () {};

	// constant that refers to the RFC 2822 form
	hooks.RFC_2822 = function () {};

	// date from string and format string
	function configFromStringAndFormat(config) {
		// TODO: Move this to another part of the creation flow to prevent circular deps
		if (config._f === hooks.ISO_8601) {
			configFromISO(config);
			return;
		}
		if (config._f === hooks.RFC_2822) {
			configFromRFC2822(config);
			return;
		}
		config._a = [];
		getParsingFlags(config).empty = true;

		// This array is used to make a Date, either with `new Date` or `Date.UTC`
		var string = '' + config._i,
			i, parsedInput, tokens, token, skipped,
			stringLength = string.length,
			totalParsedInputLength = 0;

		tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];

		for (i = 0; i < tokens.length; i++) {
			token = tokens[i];
			parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
			// console.log('token', token, 'parsedInput', parsedInput,
			//         'regex', getParseRegexForToken(token, config));
			if (parsedInput) {
				skipped = string.substr(0, string.indexOf(parsedInput));
				if (skipped.length > 0) {
					getParsingFlags(config).unusedInput.push(skipped);
				}
				string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
				totalParsedInputLength += parsedInput.length;
			}
			// don't parse if it's not a known token
			if (formatTokenFunctions[token]) {
				if (parsedInput) {
					getParsingFlags(config).empty = false;
				}
				else {
					getParsingFlags(config).unusedTokens.push(token);
				}
				addTimeToArrayFromToken(token, parsedInput, config);
			}
			else if (config._strict && !parsedInput) {
				getParsingFlags(config).unusedTokens.push(token);
			}
		}

		// add remaining unparsed input length to the string
		getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
		if (string.length > 0) {
			getParsingFlags(config).unusedInput.push(string);
		}

		// clear _12h flag if hour is <= 12
		if (config._a[HOUR] <= 12 &&
			getParsingFlags(config).bigHour === true &&
			config._a[HOUR] > 0) {
			getParsingFlags(config).bigHour = undefined;
		}

		getParsingFlags(config).parsedDateParts = config._a.slice(0);
		getParsingFlags(config).meridiem = config._meridiem;
		// handle meridiem
		config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);

		configFromArray(config);
		checkOverflow(config);
	}


	function meridiemFixWrap (locale, hour, meridiem) {
		var isPm;

		if (meridiem == null) {
			// nothing to do
			return hour;
		}
		if (locale.meridiemHour != null) {
			return locale.meridiemHour(hour, meridiem);
		} else if (locale.isPM != null) {
			// Fallback
			isPm = locale.isPM(meridiem);
			if (isPm && hour < 12) {
				hour += 12;
			}
			if (!isPm && hour === 12) {
				hour = 0;
			}
			return hour;
		} else {
			// this is not supposed to happen
			return hour;
		}
	}

	// date from string and array of format strings
	function configFromStringAndArray(config) {
		var tempConfig,
			bestMoment,

			scoreToBeat,
			i,
			currentScore;

		if (config._f.length === 0) {
			getParsingFlags(config).invalidFormat = true;
			config._d = new Date(NaN);
			return;
		}

		for (i = 0; i < config._f.length; i++) {
			currentScore = 0;
			tempConfig = copyConfig({}, config);
			if (config._useUTC != null) {
				tempConfig._useUTC = config._useUTC;
			}
			tempConfig._f = config._f[i];
			configFromStringAndFormat(tempConfig);

			if (!isValid(tempConfig)) {
				continue;
			}

			// if there is any input that was not parsed add a penalty for that format
			currentScore += getParsingFlags(tempConfig).charsLeftOver;

			//or tokens
			currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;

			getParsingFlags(tempConfig).score = currentScore;

			if (scoreToBeat == null || currentScore < scoreToBeat) {
				scoreToBeat = currentScore;
				bestMoment = tempConfig;
			}
		}

		extend(config, bestMoment || tempConfig);
	}

	function configFromObject(config) {
		if (config._d) {
			return;
		}

		var i = normalizeObjectUnits(config._i);
		config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) {
			return obj && parseInt(obj, 10);
		});

		configFromArray(config);
	}

	function createFromConfig (config) {
		var res = new Moment(checkOverflow(prepareConfig(config)));
		if (res._nextDay) {
			// Adding is smart enough around DST
			res.add(1, 'd');
			res._nextDay = undefined;
		}

		return res;
	}

	function prepareConfig (config) {
		var input = config._i,
			format = config._f;

		config._locale = config._locale || getLocale(config._l);

		if (input === null || (format === undefined && input === '')) {
			return createInvalid({nullInput: true});
		}

		if (typeof input === 'string') {
			config._i = input = config._locale.preparse(input);
		}

		if (isMoment(input)) {
			return new Moment(checkOverflow(input));
		} else if (isDate(input)) {
			config._d = input;
		} else if (isArray(format)) {
			configFromStringAndArray(config);
		} else if (format) {
			configFromStringAndFormat(config);
		}  else {
			configFromInput(config);
		}

		if (!isValid(config)) {
			config._d = null;
		}

		return config;
	}

	function configFromInput(config) {
		var input = config._i;
		if (isUndefined(input)) {
			config._d = new Date(hooks.now());
		} else if (isDate(input)) {
			config._d = new Date(input.valueOf());
		} else if (typeof input === 'string') {
			configFromString(config);
		} else if (isArray(input)) {
			config._a = map(input.slice(0), function (obj) {
				return parseInt(obj, 10);
			});
			configFromArray(config);
		} else if (isObject(input)) {
			configFromObject(config);
		} else if (isNumber(input)) {
			// from milliseconds
			config._d = new Date(input);
		} else {
			hooks.createFromInputFallback(config);
		}
	}

	function createLocalOrUTC (input, format, locale, strict, isUTC) {
		var c = {};

		if (locale === true || locale === false) {
			strict = locale;
			locale = undefined;
		}

		if ((isObject(input) && isObjectEmpty(input)) ||
			(isArray(input) && input.length === 0)) {
			input = undefined;
		}
		// object construction must be done this way.
		// https://github.com/moment/moment/issues/1423
		c._isAMomentObject = true;
		c._useUTC = c._isUTC = isUTC;
		c._l = locale;
		c._i = input;
		c._f = format;
		c._strict = strict;

		return createFromConfig(c);
	}

	function createLocal (input, format, locale, strict) {
		return createLocalOrUTC(input, format, locale, strict, false);
	}

	var prototypeMin = deprecate(
		'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/',
		function () {
			var other = createLocal.apply(null, arguments);
			if (this.isValid() && other.isValid()) {
				return other < this ? this : other;
			} else {
				return createInvalid();
			}
		}
	);

	var prototypeMax = deprecate(
		'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/',
		function () {
			var other = createLocal.apply(null, arguments);
			if (this.isValid() && other.isValid()) {
				return other > this ? this : other;
			} else {
				return createInvalid();
			}
		}
	);

	// Pick a moment m from moments so that m[fn](other) is true for all
	// other. This relies on the function fn to be transitive.
	//
	// moments should either be an array of moment objects or an array, whose
	// first element is an array of moment objects.
	function pickBy(fn, moments) {
		var res, i;
		if (moments.length === 1 && isArray(moments[0])) {
			moments = moments[0];
		}
		if (!moments.length) {
			return createLocal();
		}
		res = moments[0];
		for (i = 1; i < moments.length; ++i) {
			if (!moments[i].isValid() || moments[i][fn](res)) {
				res = moments[i];
			}
		}
		return res;
	}

	// TODO: Use [].sort instead?
	function min () {
		var args = [].slice.call(arguments, 0);

		return pickBy('isBefore', args);
	}

	function max () {
		var args = [].slice.call(arguments, 0);

		return pickBy('isAfter', args);
	}

	var now = function () {
		return Date.now ? Date.now() : +(new Date());
	};

	var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond'];

	function isDurationValid(m) {
		for (var key in m) {
			if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) {
				return false;
			}
		}

		var unitHasDecimal = false;
		for (var i = 0; i < ordering.length; ++i) {
			if (m[ordering[i]]) {
				if (unitHasDecimal) {
					return false; // only allow non-integers for smallest unit
				}
				if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) {
					unitHasDecimal = true;
				}
			}
		}

		return true;
	}

	function isValid$1() {
		return this._isValid;
	}

	function createInvalid$1() {
		return createDuration(NaN);
	}

	function Duration (duration) {
		var normalizedInput = normalizeObjectUnits(duration),
			years = normalizedInput.year || 0,
			quarters = normalizedInput.quarter || 0,
			months = normalizedInput.month || 0,
			weeks = normalizedInput.week || 0,
			days = normalizedInput.day || 0,
			hours = normalizedInput.hour || 0,
			minutes = normalizedInput.minute || 0,
			seconds = normalizedInput.second || 0,
			milliseconds = normalizedInput.millisecond || 0;

		this._isValid = isDurationValid(normalizedInput);

		// representation for dateAddRemove
		this._milliseconds = +milliseconds +
			seconds * 1e3 + // 1000
			minutes * 6e4 + // 1000 * 60
			hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
		// Because of dateAddRemove treats 24 hours as different from a
		// day when working around DST, we need to store them separately
		this._days = +days +
			weeks * 7;
		// It is impossible to translate months into days without knowing
		// which months you are are talking about, so we have to store
		// it separately.
		this._months = +months +
			quarters * 3 +
			years * 12;

		this._data = {};

		this._locale = getLocale();

		this._bubble();
	}

	function isDuration (obj) {
		return obj instanceof Duration;
	}

	function absRound (number) {
		if (number < 0) {
			return Math.round(-1 * number) * -1;
		} else {
			return Math.round(number);
		}
	}

	// FORMATTING

	function offset (token, separator) {
		addFormatToken(token, 0, 0, function () {
			var offset = this.utcOffset();
			var sign = '+';
			if (offset < 0) {
				offset = -offset;
				sign = '-';
			}
			return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);
		});
	}

	offset('Z', ':');
	offset('ZZ', '');

	// PARSING

	addRegexToken('Z',  matchShortOffset);
	addRegexToken('ZZ', matchShortOffset);
	addParseToken(['Z', 'ZZ'], function (input, array, config) {
		config._useUTC = true;
		config._tzm = offsetFromString(matchShortOffset, input);
	});

	// HELPERS

	// timezone chunker
	// '+10:00' > ['10',  '00']
	// '-1530'  > ['-15', '30']
	var chunkOffset = /([\+\-]|\d\d)/gi;

	function offsetFromString(matcher, string) {
		var matches = (string || '').match(matcher);

		if (matches === null) {
			return null;
		}

		var chunk   = matches[matches.length - 1] || [];
		var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];
		var minutes = +(parts[1] * 60) + toInt(parts[2]);

		return minutes === 0 ?
			0 :
			parts[0] === '+' ? minutes : -minutes;
	}

	// Return a moment from input, that is local/utc/zone equivalent to model.
	function cloneWithOffset(input, model) {
		var res, diff;
		if (model._isUTC) {
			res = model.clone();
			diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf();
			// Use low-level api, because this fn is low-level api.
			res._d.setTime(res._d.valueOf() + diff);
			hooks.updateOffset(res, false);
			return res;
		} else {
			return createLocal(input).local();
		}
	}

	function getDateOffset (m) {
		// On Firefox.24 Date#getTimezoneOffset returns a floating point.
		// https://github.com/moment/moment/pull/1871
		return -Math.round(m._d.getTimezoneOffset() / 15) * 15;
	}

	// HOOKS

	// This function will be called whenever a moment is mutated.
	// It is intended to keep the offset in sync with the timezone.
	hooks.updateOffset = function () {};

	// MOMENTS

	// keepLocalTime = true means only change the timezone, without
	// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->
	// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset
	// +0200, so we adjust the time as needed, to be valid.
	//
	// Keeping the time actually adds/subtracts (one hour)
	// from the actual represented time. That is why we call updateOffset
	// a second time. In case it wants us to change the offset again
	// _changeInProgress == true case, then we have to adjust, because
	// there is no such time in the given timezone.
	function getSetOffset (input, keepLocalTime, keepMinutes) {
		var offset = this._offset || 0,
			localAdjust;
		if (!this.isValid()) {
			return input != null ? this : NaN;
		}
		if (input != null) {
			if (typeof input === 'string') {
				input = offsetFromString(matchShortOffset, input);
				if (input === null) {
					return this;
				}
			} else if (Math.abs(input) < 16 && !keepMinutes) {
				input = input * 60;
			}
			if (!this._isUTC && keepLocalTime) {
				localAdjust = getDateOffset(this);
			}
			this._offset = input;
			this._isUTC = true;
			if (localAdjust != null) {
				this.add(localAdjust, 'm');
			}
			if (offset !== input) {
				if (!keepLocalTime || this._changeInProgress) {
					addSubtract(this, createDuration(input - offset, 'm'), 1, false);
				} else if (!this._changeInProgress) {
					this._changeInProgress = true;
					hooks.updateOffset(this, true);
					this._changeInProgress = null;
				}
			}
			return this;
		} else {
			return this._isUTC ? offset : getDateOffset(this);
		}
	}

	function getSetZone (input, keepLocalTime) {
		if (input != null) {
			if (typeof input !== 'string') {
				input = -input;
			}

			this.utcOffset(input, keepLocalTime);

			return this;
		} else {
			return -this.utcOffset();
		}
	}

	function setOffsetToUTC (keepLocalTime) {
		return this.utcOffset(0, keepLocalTime);
	}

	function setOffsetToLocal (keepLocalTime) {
		if (this._isUTC) {
			this.utcOffset(0, keepLocalTime);
			this._isUTC = false;

			if (keepLocalTime) {
				this.subtract(getDateOffset(this), 'm');
			}
		}
		return this;
	}

	function setOffsetToParsedOffset () {
		if (this._tzm != null) {
			this.utcOffset(this._tzm, false, true);
		} else if (typeof this._i === 'string') {
			var tZone = offsetFromString(matchOffset, this._i);
			if (tZone != null) {
				this.utcOffset(tZone);
			}
			else {
				this.utcOffset(0, true);
			}
		}
		return this;
	}

	function hasAlignedHourOffset (input) {
		if (!this.isValid()) {
			return false;
		}
		input = input ? createLocal(input).utcOffset() : 0;

		return (this.utcOffset() - input) % 60 === 0;
	}

	function isDaylightSavingTime () {
		return (
			this.utcOffset() > this.clone().month(0).utcOffset() ||
			this.utcOffset() > this.clone().month(5).utcOffset()
		);
	}

	function isDaylightSavingTimeShifted () {
		if (!isUndefined(this._isDSTShifted)) {
			return this._isDSTShifted;
		}

		var c = {};

		copyConfig(c, this);
		c = prepareConfig(c);

		if (c._a) {
			var other = c._isUTC ? createUTC(c._a) : createLocal(c._a);
			this._isDSTShifted = this.isValid() &&
				compareArrays(c._a, other.toArray()) > 0;
		} else {
			this._isDSTShifted = false;
		}

		return this._isDSTShifted;
	}

	function isLocal () {
		return this.isValid() ? !this._isUTC : false;
	}

	function isUtcOffset () {
		return this.isValid() ? this._isUTC : false;
	}

	function isUtc () {
		return this.isValid() ? this._isUTC && this._offset === 0 : false;
	}

	// ASP.NET json date format regex
	var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;

	// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
	// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
	// and further modified to allow for strings containing both week and day
	var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;

	function createDuration (input, key) {
		var duration = input,
			// matching against regexp is expensive, do it on demand
			match = null,
			sign,
			ret,
			diffRes;

		if (isDuration(input)) {
			duration = {
				ms : input._milliseconds,
				d  : input._days,
				M  : input._months
			};
		} else if (isNumber(input)) {
			duration = {};
			if (key) {
				duration[key] = input;
			} else {
				duration.milliseconds = input;
			}
		} else if (!!(match = aspNetRegex.exec(input))) {
			sign = (match[1] === '-') ? -1 : 1;
			duration = {
				y  : 0,
				d  : toInt(match[DATE])                         * sign,
				h  : toInt(match[HOUR])                         * sign,
				m  : toInt(match[MINUTE])                       * sign,
				s  : toInt(match[SECOND])                       * sign,
				ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
			};
		} else if (!!(match = isoRegex.exec(input))) {
			sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1;
			duration = {
				y : parseIso(match[2], sign),
				M : parseIso(match[3], sign),
				w : parseIso(match[4], sign),
				d : parseIso(match[5], sign),
				h : parseIso(match[6], sign),
				m : parseIso(match[7], sign),
				s : parseIso(match[8], sign)
			};
		} else if (duration == null) {// checks for null or undefined
			duration = {};
		} else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
			diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));

			duration = {};
			duration.ms = diffRes.milliseconds;
			duration.M = diffRes.months;
		}

		ret = new Duration(duration);

		if (isDuration(input) && hasOwnProp(input, '_locale')) {
			ret._locale = input._locale;
		}

		return ret;
	}

	createDuration.fn = Duration.prototype;
	createDuration.invalid = createInvalid$1;

	function parseIso (inp, sign) {
		// We'd normally use ~~inp for this, but unfortunately it also
		// converts floats to ints.
		// inp may be undefined, so careful calling replace on it.
		var res = inp && parseFloat(inp.replace(',', '.'));
		// apply sign while we're at it
		return (isNaN(res) ? 0 : res) * sign;
	}

	function positiveMomentsDifference(base, other) {
		var res = {milliseconds: 0, months: 0};

		res.months = other.month() - base.month() +
			(other.year() - base.year()) * 12;
		if (base.clone().add(res.months, 'M').isAfter(other)) {
			--res.months;
		}

		res.milliseconds = +other - +(base.clone().add(res.months, 'M'));

		return res;
	}

	function momentsDifference(base, other) {
		var res;
		if (!(base.isValid() && other.isValid())) {
			return {milliseconds: 0, months: 0};
		}

		other = cloneWithOffset(other, base);
		if (base.isBefore(other)) {
			res = positiveMomentsDifference(base, other);
		} else {
			res = positiveMomentsDifference(other, base);
			res.milliseconds = -res.milliseconds;
			res.months = -res.months;
		}

		return res;
	}

	// TODO: remove 'name' arg after deprecation is removed
	function createAdder(direction, name) {
		return function (val, period) {
			var dur, tmp;
			//invert the arguments, but complain about it
			if (period !== null && !isNaN(+period)) {
				deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
					'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
				tmp = val; val = period; period = tmp;
			}

			val = typeof val === 'string' ? +val : val;
			dur = createDuration(val, period);
			addSubtract(this, dur, direction);
			return this;
		};
	}

	function addSubtract (mom, duration, isAdding, updateOffset) {
		var milliseconds = duration._milliseconds,
			days = absRound(duration._days),
			months = absRound(duration._months);

		if (!mom.isValid()) {
			// No op
			return;
		}

		updateOffset = updateOffset == null ? true : updateOffset;

		if (months) {
			setMonth(mom, get(mom, 'Month') + months * isAdding);
		}
		if (days) {
			set$1(mom, 'Date', get(mom, 'Date') + days * isAdding);
		}
		if (milliseconds) {
			mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding);
		}
		if (updateOffset) {
			hooks.updateOffset(mom, days || months);
		}
	}

	var add      = createAdder(1, 'add');
	var subtract = createAdder(-1, 'subtract');

	function getCalendarFormat(myMoment, now) {
		var diff = myMoment.diff(now, 'days', true);
		return diff < -6 ? 'sameElse' :
			diff < -1 ? 'lastWeek' :
				diff < 0 ? 'lastDay' :
					diff < 1 ? 'sameDay' :
						diff < 2 ? 'nextDay' :
							diff < 7 ? 'nextWeek' : 'sameElse';
	}

	function calendar$1 (time, formats) {
		// We want to compare the start of today, vs this.
		// Getting start-of-today depends on whether we're local/utc/offset or not.
		var now = time || createLocal(),
			sod = cloneWithOffset(now, this).startOf('day'),
			format = hooks.calendarFormat(this, sod) || 'sameElse';

		var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]);

		return this.format(output || this.localeData().calendar(format, this, createLocal(now)));
	}

	function clone () {
		return new Moment(this);
	}

	function isAfter (input, units) {
		var localInput = isMoment(input) ? input : createLocal(input);
		if (!(this.isValid() && localInput.isValid())) {
			return false;
		}
		units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
		if (units === 'millisecond') {
			return this.valueOf() > localInput.valueOf();
		} else {
			return localInput.valueOf() < this.clone().startOf(units).valueOf();
		}
	}

	function isBefore (input, units) {
		var localInput = isMoment(input) ? input : createLocal(input);
		if (!(this.isValid() && localInput.isValid())) {
			return false;
		}
		units = normalizeUnits(!isUndefined(units) ? units : 'millisecond');
		if (units === 'millisecond') {
			return this.valueOf() < localInput.valueOf();
		} else {
			return this.clone().endOf(units).valueOf() < localInput.valueOf();
		}
	}

	function isBetween (from, to, units, inclusivity) {
		inclusivity = inclusivity || '()';
		return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) &&
			(inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units));
	}

	function isSame (input, units) {
		var localInput = isMoment(input) ? input : createLocal(input),
			inputMs;
		if (!(this.isValid() && localInput.isValid())) {
			return false;
		}
		units = normalizeUnits(units || 'millisecond');
		if (units === 'millisecond') {
			return this.valueOf() === localInput.valueOf();
		} else {
			inputMs = localInput.valueOf();
			return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf();
		}
	}

	function isSameOrAfter (input, units) {
		return this.isSame(input, units) || this.isAfter(input,units);
	}

	function isSameOrBefore (input, units) {
		return this.isSame(input, units) || this.isBefore(input,units);
	}

	function diff (input, units, asFloat) {
		var that,
			zoneDelta,
			output;

		if (!this.isValid()) {
			return NaN;
		}

		that = cloneWithOffset(input, this);

		if (!that.isValid()) {
			return NaN;
		}

		zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4;

		units = normalizeUnits(units);

		switch (units) {
			case 'year': output = monthDiff(this, that) / 12; break;
			case 'month': output = monthDiff(this, that); break;
			case 'quarter': output = monthDiff(this, that) / 3; break;
			case 'second': output = (this - that) / 1e3; break; // 1000
			case 'minute': output = (this - that) / 6e4; break; // 1000 * 60
			case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60
			case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst
			case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst
			default: output = this - that;
		}

		return asFloat ? output : absFloor(output);
	}

	function monthDiff (a, b) {
		// difference in months
		var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
			// b is in (anchor - 1 month, anchor + 1 month)
			anchor = a.clone().add(wholeMonthDiff, 'months'),
			anchor2, adjust;

		if (b - anchor < 0) {
			anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
			// linear across the month
			adjust = (b - anchor) / (anchor - anchor2);
		} else {
			anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
			// linear across the month
			adjust = (b - anchor) / (anchor2 - anchor);
		}

		//check for negative zero, return zero if negative zero
		return -(wholeMonthDiff + adjust) || 0;
	}

	hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';
	hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]';

	function toString () {
		return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');
	}

	function toISOString(keepOffset) {
		if (!this.isValid()) {
			return null;
		}
		var utc = keepOffset !== true;
		var m = utc ? this.clone().utc() : this;
		if (m.year() < 0 || m.year() > 9999) {
			return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ');
		}
		if (isFunction(Date.prototype.toISOString)) {
			// native implementation is ~50x faster, use it when we can
			if (utc) {
				return this.toDate().toISOString();
			} else {
				return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z'));
			}
		}
		return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ');
	}

	/**
	 * Return a human readable representation of a moment that can
	 * also be evaluated to get a new moment which is the same
	 *
	 * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects
	 */
	function inspect () {
		if (!this.isValid()) {
			return 'moment.invalid(/* ' + this._i + ' */)';
		}
		var func = 'moment';
		var zone = '';
		if (!this.isLocal()) {
			func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone';
			zone = 'Z';
		}
		var prefix = '[' + func + '("]';
		var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY';
		var datetime = '-MM-DD[T]HH:mm:ss.SSS';
		var suffix = zone + '[")]';

		return this.format(prefix + year + datetime + suffix);
	}

	function format (inputString) {
		if (!inputString) {
			inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat;
		}
		var output = formatMoment(this, inputString);
		return this.localeData().postformat(output);
	}

	function from (time, withoutSuffix) {
		if (this.isValid() &&
			((isMoment(time) && time.isValid()) ||
				createLocal(time).isValid())) {
			return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
		} else {
			return this.localeData().invalidDate();
		}
	}

	function fromNow (withoutSuffix) {
		return this.from(createLocal(), withoutSuffix);
	}

	function to (time, withoutSuffix) {
		if (this.isValid() &&
			((isMoment(time) && time.isValid()) ||
				createLocal(time).isValid())) {
			return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix);
		} else {
			return this.localeData().invalidDate();
		}
	}

	function toNow (withoutSuffix) {
		return this.to(createLocal(), withoutSuffix);
	}

	// If passed a locale key, it will set the locale for this
	// instance.  Otherwise, it will return the locale configuration
	// variables for this instance.
	function locale (key) {
		var newLocaleData;

		if (key === undefined) {
			return this._locale._abbr;
		} else {
			newLocaleData = getLocale(key);
			if (newLocaleData != null) {
				this._locale = newLocaleData;
			}
			return this;
		}
	}

	var lang = deprecate(
		'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',
		function (key) {
			if (key === undefined) {
				return this.localeData();
			} else {
				return this.locale(key);
			}
		}
	);

	function localeData () {
		return this._locale;
	}

	function startOf (units) {
		units = normalizeUnits(units);
		// the following switch intentionally omits break keywords
		// to utilize falling through the cases.
		switch (units) {
			case 'year':
				this.month(0);
			/* falls through */
			case 'quarter':
			case 'month':
				this.date(1);
			/* falls through */
			case 'week':
			case 'isoWeek':
			case 'day':
			case 'date':
				this.hours(0);
			/* falls through */
			case 'hour':
				this.minutes(0);
			/* falls through */
			case 'minute':
				this.seconds(0);
			/* falls through */
			case 'second':
				this.milliseconds(0);
		}

		// weeks are a special case
		if (units === 'week') {
			this.weekday(0);
		}
		if (units === 'isoWeek') {
			this.isoWeekday(1);
		}

		// quarters are also special
		if (units === 'quarter') {
			this.month(Math.floor(this.month() / 3) * 3);
		}

		return this;
	}

	function endOf (units) {
		units = normalizeUnits(units);
		if (units === undefined || units === 'millisecond') {
			return this;
		}

		// 'date' is an alias for 'day', so it should be considered as such.
		if (units === 'date') {
			units = 'day';
		}

		return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
	}

	function valueOf () {
		return this._d.valueOf() - ((this._offset || 0) * 60000);
	}

	function unix () {
		return Math.floor(this.valueOf() / 1000);
	}

	function toDate () {
		return new Date(this.valueOf());
	}

	function toArray () {
		var m = this;
		return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];
	}

	function toObject () {
		var m = this;
		return {
			years: m.year(),
			months: m.month(),
			date: m.date(),
			hours: m.hours(),
			minutes: m.minutes(),
			seconds: m.seconds(),
			milliseconds: m.milliseconds()
		};
	}

	function toJSON () {
		// new Date(NaN).toJSON() === null
		return this.isValid() ? this.toISOString() : null;
	}

	function isValid$2 () {
		return isValid(this);
	}

	function parsingFlags () {
		return extend({}, getParsingFlags(this));
	}

	function invalidAt () {
		return getParsingFlags(this).overflow;
	}

	function creationData() {
		return {
			input: this._i,
			format: this._f,
			locale: this._locale,
			isUTC: this._isUTC,
			strict: this._strict
		};
	}

	// FORMATTING

	addFormatToken(0, ['gg', 2], 0, function () {
		return this.weekYear() % 100;
	});

	addFormatToken(0, ['GG', 2], 0, function () {
		return this.isoWeekYear() % 100;
	});

	function addWeekYearFormatToken (token, getter) {
		addFormatToken(0, [token, token.length], 0, getter);
	}

	addWeekYearFormatToken('gggg',     'weekYear');
	addWeekYearFormatToken('ggggg',    'weekYear');
	addWeekYearFormatToken('GGGG',  'isoWeekYear');
	addWeekYearFormatToken('GGGGG', 'isoWeekYear');

	// ALIASES

	addUnitAlias('weekYear', 'gg');
	addUnitAlias('isoWeekYear', 'GG');

	// PRIORITY

	addUnitPriority('weekYear', 1);
	addUnitPriority('isoWeekYear', 1);


	// PARSING

	addRegexToken('G',      matchSigned);
	addRegexToken('g',      matchSigned);
	addRegexToken('GG',     match1to2, match2);
	addRegexToken('gg',     match1to2, match2);
	addRegexToken('GGGG',   match1to4, match4);
	addRegexToken('gggg',   match1to4, match4);
	addRegexToken('GGGGG',  match1to6, match6);
	addRegexToken('ggggg',  match1to6, match6);

	addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {
		week[token.substr(0, 2)] = toInt(input);
	});

	addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {
		week[token] = hooks.parseTwoDigitYear(input);
	});

	// MOMENTS

	function getSetWeekYear (input) {
		return getSetWeekYearHelper.call(this,
			input,
			this.week(),
			this.weekday(),
			this.localeData()._week.dow,
			this.localeData()._week.doy);
	}

	function getSetISOWeekYear (input) {
		return getSetWeekYearHelper.call(this,
			input, this.isoWeek(), this.isoWeekday(), 1, 4);
	}

	function getISOWeeksInYear () {
		return weeksInYear(this.year(), 1, 4);
	}

	function getWeeksInYear () {
		var weekInfo = this.localeData()._week;
		return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
	}

	function getSetWeekYearHelper(input, week, weekday, dow, doy) {
		var weeksTarget;
		if (input == null) {
			return weekOfYear(this, dow, doy).year;
		} else {
			weeksTarget = weeksInYear(input, dow, doy);
			if (week > weeksTarget) {
				week = weeksTarget;
			}
			return setWeekAll.call(this, input, week, weekday, dow, doy);
		}
	}

	function setWeekAll(weekYear, week, weekday, dow, doy) {
		var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy),
			date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear);

		this.year(date.getUTCFullYear());
		this.month(date.getUTCMonth());
		this.date(date.getUTCDate());
		return this;
	}

	// FORMATTING

	addFormatToken('Q', 0, 'Qo', 'quarter');

	// ALIASES

	addUnitAlias('quarter', 'Q');

	// PRIORITY

	addUnitPriority('quarter', 7);

	// PARSING

	addRegexToken('Q', match1);
	addParseToken('Q', function (input, array) {
		array[MONTH] = (toInt(input) - 1) * 3;
	});

	// MOMENTS

	function getSetQuarter (input) {
		return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
	}

	// FORMATTING

	addFormatToken('D', ['DD', 2], 'Do', 'date');

	// ALIASES

	addUnitAlias('date', 'D');

	// PRIORITY
	addUnitPriority('date', 9);

	// PARSING

	addRegexToken('D',  match1to2);
	addRegexToken('DD', match1to2, match2);
	addRegexToken('Do', function (isStrict, locale) {
		// TODO: Remove "ordinalParse" fallback in next major release.
		return isStrict ?
			(locale._dayOfMonthOrdinalParse || locale._ordinalParse) :
			locale._dayOfMonthOrdinalParseLenient;
	});

	addParseToken(['D', 'DD'], DATE);
	addParseToken('Do', function (input, array) {
		array[DATE] = toInt(input.match(match1to2)[0]);
	});

	// MOMENTS

	var getSetDayOfMonth = makeGetSet('Date', true);

	// FORMATTING

	addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');

	// ALIASES

	addUnitAlias('dayOfYear', 'DDD');

	// PRIORITY
	addUnitPriority('dayOfYear', 4);

	// PARSING

	addRegexToken('DDD',  match1to3);
	addRegexToken('DDDD', match3);
	addParseToken(['DDD', 'DDDD'], function (input, array, config) {
		config._dayOfYear = toInt(input);
	});

	// HELPERS

	// MOMENTS

	function getSetDayOfYear (input) {
		var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
		return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
	}

	// FORMATTING

	addFormatToken('m', ['mm', 2], 0, 'minute');

	// ALIASES

	addUnitAlias('minute', 'm');

	// PRIORITY

	addUnitPriority('minute', 14);

	// PARSING

	addRegexToken('m',  match1to2);
	addRegexToken('mm', match1to2, match2);
	addParseToken(['m', 'mm'], MINUTE);

	// MOMENTS

	var getSetMinute = makeGetSet('Minutes', false);

	// FORMATTING

	addFormatToken('s', ['ss', 2], 0, 'second');

	// ALIASES

	addUnitAlias('second', 's');

	// PRIORITY

	addUnitPriority('second', 15);

	// PARSING

	addRegexToken('s',  match1to2);
	addRegexToken('ss', match1to2, match2);
	addParseToken(['s', 'ss'], SECOND);

	// MOMENTS

	var getSetSecond = makeGetSet('Seconds', false);

	// FORMATTING

	addFormatToken('S', 0, 0, function () {
		return ~~(this.millisecond() / 100);
	});

	addFormatToken(0, ['SS', 2], 0, function () {
		return ~~(this.millisecond() / 10);
	});

	addFormatToken(0, ['SSS', 3], 0, 'millisecond');
	addFormatToken(0, ['SSSS', 4], 0, function () {
		return this.millisecond() * 10;
	});
	addFormatToken(0, ['SSSSS', 5], 0, function () {
		return this.millisecond() * 100;
	});
	addFormatToken(0, ['SSSSSS', 6], 0, function () {
		return this.millisecond() * 1000;
	});
	addFormatToken(0, ['SSSSSSS', 7], 0, function () {
		return this.millisecond() * 10000;
	});
	addFormatToken(0, ['SSSSSSSS', 8], 0, function () {
		return this.millisecond() * 100000;
	});
	addFormatToken(0, ['SSSSSSSSS', 9], 0, function () {
		return this.millisecond() * 1000000;
	});


	// ALIASES

	addUnitAlias('millisecond', 'ms');

	// PRIORITY

	addUnitPriority('millisecond', 16);

	// PARSING

	addRegexToken('S',    match1to3, match1);
	addRegexToken('SS',   match1to3, match2);
	addRegexToken('SSS',  match1to3, match3);

	var token;
	for (token = 'SSSS'; token.length <= 9; token += 'S') {
		addRegexToken(token, matchUnsigned);
	}

	function parseMs(input, array) {
		array[MILLISECOND] = toInt(('0.' + input) * 1000);
	}

	for (token = 'S'; token.length <= 9; token += 'S') {
		addParseToken(token, parseMs);
	}
	// MOMENTS

	var getSetMillisecond = makeGetSet('Milliseconds', false);

	// FORMATTING

	addFormatToken('z',  0, 0, 'zoneAbbr');
	addFormatToken('zz', 0, 0, 'zoneName');

	// MOMENTS

	function getZoneAbbr () {
		return this._isUTC ? 'UTC' : '';
	}

	function getZoneName () {
		return this._isUTC ? 'Coordinated Universal Time' : '';
	}

	var proto = Moment.prototype;

	proto.add               = add;
	proto.calendar          = calendar$1;
	proto.clone             = clone;
	proto.diff              = diff;
	proto.endOf             = endOf;
	proto.format            = format;
	proto.from              = from;
	proto.fromNow           = fromNow;
	proto.to                = to;
	proto.toNow             = toNow;
	proto.get               = stringGet;
	proto.invalidAt         = invalidAt;
	proto.isAfter           = isAfter;
	proto.isBefore          = isBefore;
	proto.isBetween         = isBetween;
	proto.isSame            = isSame;
	proto.isSameOrAfter     = isSameOrAfter;
	proto.isSameOrBefore    = isSameOrBefore;
	proto.isValid           = isValid$2;
	proto.lang              = lang;
	proto.locale            = locale;
	proto.localeData        = localeData;
	proto.max               = prototypeMax;
	proto.min               = prototypeMin;
	proto.parsingFlags      = parsingFlags;
	proto.set               = stringSet;
	proto.startOf           = startOf;
	proto.subtract          = subtract;
	proto.toArray           = toArray;
	proto.toObject          = toObject;
	proto.toDate            = toDate;
	proto.toISOString       = toISOString;
	proto.inspect           = inspect;
	proto.toJSON            = toJSON;
	proto.toString          = toString;
	proto.unix              = unix;
	proto.valueOf           = valueOf;
	proto.creationData      = creationData;
	proto.year       = getSetYear;
	proto.isLeapYear = getIsLeapYear;
	proto.weekYear    = getSetWeekYear;
	proto.isoWeekYear = getSetISOWeekYear;
	proto.quarter = proto.quarters = getSetQuarter;
	proto.month       = getSetMonth;
	proto.daysInMonth = getDaysInMonth;
	proto.week           = proto.weeks        = getSetWeek;
	proto.isoWeek        = proto.isoWeeks     = getSetISOWeek;
	proto.weeksInYear    = getWeeksInYear;
	proto.isoWeeksInYear = getISOWeeksInYear;
	proto.date       = getSetDayOfMonth;
	proto.day        = proto.days             = getSetDayOfWeek;
	proto.weekday    = getSetLocaleDayOfWeek;
	proto.isoWeekday = getSetISODayOfWeek;
	proto.dayOfYear  = getSetDayOfYear;
	proto.hour = proto.hours = getSetHour;
	proto.minute = proto.minutes = getSetMinute;
	proto.second = proto.seconds = getSetSecond;
	proto.millisecond = proto.milliseconds = getSetMillisecond;
	proto.utcOffset            = getSetOffset;
	proto.utc                  = setOffsetToUTC;
	proto.local                = setOffsetToLocal;
	proto.parseZone            = setOffsetToParsedOffset;
	proto.hasAlignedHourOffset = hasAlignedHourOffset;
	proto.isDST                = isDaylightSavingTime;
	proto.isLocal              = isLocal;
	proto.isUtcOffset          = isUtcOffset;
	proto.isUtc                = isUtc;
	proto.isUTC                = isUtc;
	proto.zoneAbbr = getZoneAbbr;
	proto.zoneName = getZoneName;
	proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
	proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
	proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);
	proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone);
	proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted);

	function createUnix (input) {
		return createLocal(input * 1000);
	}

	function createInZone () {
		return createLocal.apply(null, arguments).parseZone();
	}

	function preParsePostFormat (string) {
		return string;
	}

	var proto$1 = Locale.prototype;

	proto$1.calendar        = calendar;
	proto$1.longDateFormat  = longDateFormat;
	proto$1.invalidDate     = invalidDate;
	proto$1.ordinal         = ordinal;
	proto$1.preparse        = preParsePostFormat;
	proto$1.postformat      = preParsePostFormat;
	proto$1.relativeTime    = relativeTime;
	proto$1.pastFuture      = pastFuture;
	proto$1.set             = set;

	proto$1.months            =        localeMonths;
	proto$1.monthsShort       =        localeMonthsShort;
	proto$1.monthsParse       =        localeMonthsParse;
	proto$1.monthsRegex       = monthsRegex;
	proto$1.monthsShortRegex  = monthsShortRegex;
	proto$1.week = localeWeek;
	proto$1.firstDayOfYear = localeFirstDayOfYear;
	proto$1.firstDayOfWeek = localeFirstDayOfWeek;

	proto$1.weekdays       =        localeWeekdays;
	proto$1.weekdaysMin    =        localeWeekdaysMin;
	proto$1.weekdaysShort  =        localeWeekdaysShort;
	proto$1.weekdaysParse  =        localeWeekdaysParse;

	proto$1.weekdaysRegex       =        weekdaysRegex;
	proto$1.weekdaysShortRegex  =        weekdaysShortRegex;
	proto$1.weekdaysMinRegex    =        weekdaysMinRegex;

	proto$1.isPM = localeIsPM;
	proto$1.meridiem = localeMeridiem;

	function get$1 (format, index, field, setter) {
		var locale = getLocale();
		var utc = createUTC().set(setter, index);
		return locale[field](utc, format);
	}

	function listMonthsImpl (format, index, field) {
		if (isNumber(format)) {
			index = format;
			format = undefined;
		}

		format = format || '';

		if (index != null) {
			return get$1(format, index, field, 'month');
		}

		var i;
		var out = [];
		for (i = 0; i < 12; i++) {
			out[i] = get$1(format, i, field, 'month');
		}
		return out;
	}

	// ()
	// (5)
	// (fmt, 5)
	// (fmt)
	// (true)
	// (true, 5)
	// (true, fmt, 5)
	// (true, fmt)
	function listWeekdaysImpl (localeSorted, format, index, field) {
		if (typeof localeSorted === 'boolean') {
			if (isNumber(format)) {
				index = format;
				format = undefined;
			}

			format = format || '';
		} else {
			format = localeSorted;
			index = format;
			localeSorted = false;

			if (isNumber(format)) {
				index = format;
				format = undefined;
			}

			format = format || '';
		}

		var locale = getLocale(),
			shift = localeSorted ? locale._week.dow : 0;

		if (index != null) {
			return get$1(format, (index + shift) % 7, field, 'day');
		}

		var i;
		var out = [];
		for (i = 0; i < 7; i++) {
			out[i] = get$1(format, (i + shift) % 7, field, 'day');
		}
		return out;
	}

	function listMonths (format, index) {
		return listMonthsImpl(format, index, 'months');
	}

	function listMonthsShort (format, index) {
		return listMonthsImpl(format, index, 'monthsShort');
	}

	function listWeekdays (localeSorted, format, index) {
		return listWeekdaysImpl(localeSorted, format, index, 'weekdays');
	}

	function listWeekdaysShort (localeSorted, format, index) {
		return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort');
	}

	function listWeekdaysMin (localeSorted, format, index) {
		return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin');
	}

	getSetGlobalLocale('en', {
		dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/,
		ordinal : function (number) {
			var b = number % 10,
				output = (toInt(number % 100 / 10) === 1) ? 'th' :
					(b === 1) ? 'st' :
						(b === 2) ? 'nd' :
							(b === 3) ? 'rd' : 'th';
			return number + output;
		}
	});

	// Side effect imports

	hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);
	hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);

	var mathAbs = Math.abs;

	function abs () {
		var data           = this._data;

		this._milliseconds = mathAbs(this._milliseconds);
		this._days         = mathAbs(this._days);
		this._months       = mathAbs(this._months);

		data.milliseconds  = mathAbs(data.milliseconds);
		data.seconds       = mathAbs(data.seconds);
		data.minutes       = mathAbs(data.minutes);
		data.hours         = mathAbs(data.hours);
		data.months        = mathAbs(data.months);
		data.years         = mathAbs(data.years);

		return this;
	}

	function addSubtract$1 (duration, input, value, direction) {
		var other = createDuration(input, value);

		duration._milliseconds += direction * other._milliseconds;
		duration._days         += direction * other._days;
		duration._months       += direction * other._months;

		return duration._bubble();
	}

	// supports only 2.0-style add(1, 's') or add(duration)
	function add$1 (input, value) {
		return addSubtract$1(this, input, value, 1);
	}

	// supports only 2.0-style subtract(1, 's') or subtract(duration)
	function subtract$1 (input, value) {
		return addSubtract$1(this, input, value, -1);
	}

	function absCeil (number) {
		if (number < 0) {
			return Math.floor(number);
		} else {
			return Math.ceil(number);
		}
	}

	function bubble () {
		var milliseconds = this._milliseconds;
		var days         = this._days;
		var months       = this._months;
		var data         = this._data;
		var seconds, minutes, hours, years, monthsFromDays;

		// if we have a mix of positive and negative values, bubble down first
		// check: https://github.com/moment/moment/issues/2166
		if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
			(milliseconds <= 0 && days <= 0 && months <= 0))) {
			milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
			days = 0;
			months = 0;
		}

		// The following code bubbles up values, see the tests for
		// examples of what that means.
		data.milliseconds = milliseconds % 1000;

		seconds           = absFloor(milliseconds / 1000);
		data.seconds      = seconds % 60;

		minutes           = absFloor(seconds / 60);
		data.minutes      = minutes % 60;

		hours             = absFloor(minutes / 60);
		data.hours        = hours % 24;

		days += absFloor(hours / 24);

		// convert days to months
		monthsFromDays = absFloor(daysToMonths(days));
		months += monthsFromDays;
		days -= absCeil(monthsToDays(monthsFromDays));

		// 12 months -> 1 year
		years = absFloor(months / 12);
		months %= 12;

		data.days   = days;
		data.months = months;
		data.years  = years;

		return this;
	}

	function daysToMonths (days) {
		// 400 years have 146097 days (taking into account leap year rules)
		// 400 years have 12 months === 4800
		return days * 4800 / 146097;
	}

	function monthsToDays (months) {
		// the reverse of daysToMonths
		return months * 146097 / 4800;
	}

	function as (units) {
		if (!this.isValid()) {
			return NaN;
		}
		var days;
		var months;
		var milliseconds = this._milliseconds;

		units = normalizeUnits(units);

		if (units === 'month' || units === 'year') {
			days   = this._days   + milliseconds / 864e5;
			months = this._months + daysToMonths(days);
			return units === 'month' ? months : months / 12;
		} else {
			// handle milliseconds separately because of floating point math errors (issue #1867)
			days = this._days + Math.round(monthsToDays(this._months));
			switch (units) {
				case 'week'   : return days / 7     + milliseconds / 6048e5;
				case 'day'    : return days         + milliseconds / 864e5;
				case 'hour'   : return days * 24    + milliseconds / 36e5;
				case 'minute' : return days * 1440  + milliseconds / 6e4;
				case 'second' : return days * 86400 + milliseconds / 1000;
				// Math.floor prevents floating point math errors here
				case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
				default: throw new Error('Unknown unit ' + units);
			}
		}
	}

	// TODO: Use this.as('ms')?
	function valueOf$1 () {
		if (!this.isValid()) {
			return NaN;
		}
		return (
			this._milliseconds +
			this._days * 864e5 +
			(this._months % 12) * 2592e6 +
			toInt(this._months / 12) * 31536e6
		);
	}

	function makeAs (alias) {
		return function () {
			return this.as(alias);
		};
	}

	var asMilliseconds = makeAs('ms');
	var asSeconds      = makeAs('s');
	var asMinutes      = makeAs('m');
	var asHours        = makeAs('h');
	var asDays         = makeAs('d');
	var asWeeks        = makeAs('w');
	var asMonths       = makeAs('M');
	var asYears        = makeAs('y');

	function clone$1 () {
		return createDuration(this);
	}

	function get$2 (units) {
		units = normalizeUnits(units);
		return this.isValid() ? this[units + 's']() : NaN;
	}

	function makeGetter(name) {
		return function () {
			return this.isValid() ? this._data[name] : NaN;
		};
	}

	var milliseconds = makeGetter('milliseconds');
	var seconds      = makeGetter('seconds');
	var minutes      = makeGetter('minutes');
	var hours        = makeGetter('hours');
	var days         = makeGetter('days');
	var months       = makeGetter('months');
	var years        = makeGetter('years');

	function weeks () {
		return absFloor(this.days() / 7);
	}

	var round = Math.round;
	var thresholds = {
		ss: 44,         // a few seconds to seconds
		s : 45,         // seconds to minute
		m : 45,         // minutes to hour
		h : 22,         // hours to day
		d : 26,         // days to month
		M : 11          // months to year
	};

	// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
	function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
		return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
	}

	function relativeTime$1 (posNegDuration, withoutSuffix, locale) {
		var duration = createDuration(posNegDuration).abs();
		var seconds  = round(duration.as('s'));
		var minutes  = round(duration.as('m'));
		var hours    = round(duration.as('h'));
		var days     = round(duration.as('d'));
		var months   = round(duration.as('M'));
		var years    = round(duration.as('y'));

		var a = seconds <= thresholds.ss && ['s', seconds]  ||
			seconds < thresholds.s   && ['ss', seconds] ||
			minutes <= 1             && ['m']           ||
			minutes < thresholds.m   && ['mm', minutes] ||
			hours   <= 1             && ['h']           ||
			hours   < thresholds.h   && ['hh', hours]   ||
			days    <= 1             && ['d']           ||
			days    < thresholds.d   && ['dd', days]    ||
			months  <= 1             && ['M']           ||
			months  < thresholds.M   && ['MM', months]  ||
			years   <= 1             && ['y']           || ['yy', years];

		a[2] = withoutSuffix;
		a[3] = +posNegDuration > 0;
		a[4] = locale;
		return substituteTimeAgo.apply(null, a);
	}

	// This function allows you to set the rounding function for relative time strings
	function getSetRelativeTimeRounding (roundingFunction) {
		if (roundingFunction === undefined) {
			return round;
		}
		if (typeof(roundingFunction) === 'function') {
			round = roundingFunction;
			return true;
		}
		return false;
	}

	// This function allows you to set a threshold for relative time strings
	function getSetRelativeTimeThreshold (threshold, limit) {
		if (thresholds[threshold] === undefined) {
			return false;
		}
		if (limit === undefined) {
			return thresholds[threshold];
		}
		thresholds[threshold] = limit;
		if (threshold === 's') {
			thresholds.ss = limit - 1;
		}
		return true;
	}

	function humanize (withSuffix) {
		if (!this.isValid()) {
			return this.localeData().invalidDate();
		}

		var locale = this.localeData();
		var output = relativeTime$1(this, !withSuffix, locale);

		if (withSuffix) {
			output = locale.pastFuture(+this, output);
		}

		return locale.postformat(output);
	}

	var abs$1 = Math.abs;

	function sign(x) {
		return ((x > 0) - (x < 0)) || +x;
	}

	function toISOString$1() {
		// for ISO strings we do not use the normal bubbling rules:
		//  * milliseconds bubble up until they become hours
		//  * days do not bubble at all
		//  * months bubble up until they become years
		// This is because there is no context-free conversion between hours and days
		// (think of clock changes)
		// and also not between days and months (28-31 days per month)
		if (!this.isValid()) {
			return this.localeData().invalidDate();
		}

		var seconds = abs$1(this._milliseconds) / 1000;
		var days         = abs$1(this._days);
		var months       = abs$1(this._months);
		var minutes, hours, years;

		// 3600 seconds -> 60 minutes -> 1 hour
		minutes           = absFloor(seconds / 60);
		hours             = absFloor(minutes / 60);
		seconds %= 60;
		minutes %= 60;

		// 12 months -> 1 year
		years  = absFloor(months / 12);
		months %= 12;


		// inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
		var Y = years;
		var M = months;
		var D = days;
		var h = hours;
		var m = minutes;
		var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : '';
		var total = this.asSeconds();

		if (!total) {
			// this is the same as C#'s (Noda) and python (isodate)...
			// but not other JS (goog.date)
			return 'P0D';
		}

		var totalSign = total < 0 ? '-' : '';
		var ymSign = sign(this._months) !== sign(total) ? '-' : '';
		var daysSign = sign(this._days) !== sign(total) ? '-' : '';
		var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : '';

		return totalSign + 'P' +
			(Y ? ymSign + Y + 'Y' : '') +
			(M ? ymSign + M + 'M' : '') +
			(D ? daysSign + D + 'D' : '') +
			((h || m || s) ? 'T' : '') +
			(h ? hmsSign + h + 'H' : '') +
			(m ? hmsSign + m + 'M' : '') +
			(s ? hmsSign + s + 'S' : '');
	}

	var proto$2 = Duration.prototype;

	proto$2.isValid        = isValid$1;
	proto$2.abs            = abs;
	proto$2.add            = add$1;
	proto$2.subtract       = subtract$1;
	proto$2.as             = as;
	proto$2.asMilliseconds = asMilliseconds;
	proto$2.asSeconds      = asSeconds;
	proto$2.asMinutes      = asMinutes;
	proto$2.asHours        = asHours;
	proto$2.asDays         = asDays;
	proto$2.asWeeks        = asWeeks;
	proto$2.asMonths       = asMonths;
	proto$2.asYears        = asYears;
	proto$2.valueOf        = valueOf$1;
	proto$2._bubble        = bubble;
	proto$2.clone          = clone$1;
	proto$2.get            = get$2;
	proto$2.milliseconds   = milliseconds;
	proto$2.seconds        = seconds;
	proto$2.minutes        = minutes;
	proto$2.hours          = hours;
	proto$2.days           = days;
	proto$2.weeks          = weeks;
	proto$2.months         = months;
	proto$2.years          = years;
	proto$2.humanize       = humanize;
	proto$2.toISOString    = toISOString$1;
	proto$2.toString       = toISOString$1;
	proto$2.toJSON         = toISOString$1;
	proto$2.locale         = locale;
	proto$2.localeData     = localeData;

	proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1);
	proto$2.lang = lang;

	// Side effect imports

	// FORMATTING

	addFormatToken('X', 0, 0, 'unix');
	addFormatToken('x', 0, 0, 'valueOf');

	// PARSING

	addRegexToken('x', matchSigned);
	addRegexToken('X', matchTimestamp);
	addParseToken('X', function (input, array, config) {
		config._d = new Date(parseFloat(input, 10) * 1000);
	});
	addParseToken('x', function (input, array, config) {
		config._d = new Date(toInt(input));
	});

	// Side effect imports


	hooks.version = '2.22.2';

	setHookCallback(createLocal);

	hooks.fn                    = proto;
	hooks.min                   = min;
	hooks.max                   = max;
	hooks.now                   = now;
	hooks.utc                   = createUTC;
	hooks.unix                  = createUnix;
	hooks.months                = listMonths;
	hooks.isDate                = isDate;
	hooks.locale                = getSetGlobalLocale;
	hooks.invalid               = createInvalid;
	hooks.duration              = createDuration;
	hooks.isMoment              = isMoment;
	hooks.weekdays              = listWeekdays;
	hooks.parseZone             = createInZone;
	hooks.localeData            = getLocale;
	hooks.isDuration            = isDuration;
	hooks.monthsShort           = listMonthsShort;
	hooks.weekdaysMin           = listWeekdaysMin;
	hooks.defineLocale          = defineLocale;
	hooks.updateLocale          = updateLocale;
	hooks.locales               = listLocales;
	hooks.weekdaysShort         = listWeekdaysShort;
	hooks.normalizeUnits        = normalizeUnits;
	hooks.relativeTimeRounding  = getSetRelativeTimeRounding;
	hooks.relativeTimeThreshold = getSetRelativeTimeThreshold;
	hooks.calendarFormat        = getCalendarFormat;
	hooks.prototype             = proto;

	// currently HTML5 input type only supports 24-hour formats
	hooks.HTML5_FMT = {
		DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm',             // <input type="datetime-local" />
		DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',  // <input type="datetime-local" step="1" />
		DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',   // <input type="datetime-local" step="0.001" />
		DATE: 'YYYY-MM-DD',                             // <input type="date" />
		TIME: 'HH:mm',                                  // <input type="time" />
		TIME_SECONDS: 'HH:mm:ss',                       // <input type="time" step="1" />
		TIME_MS: 'HH:mm:ss.SSS',                        // <input type="time" step="0.001" />
		WEEK: 'YYYY-[W]WW',                             // <input type="week" />
		MONTH: 'YYYY-MM'                                // <input type="month" />
	};

	return hooks;

})));

//! moment-timezone.js
//! version : 0.5.43
//! Copyright (c) JS Foundation and other contributors
//! license : MIT
//! github.com/moment/moment-timezone

(function (root, factory) {
	"use strict";

	/*global define*/
	if (typeof module === 'object' && module.exports) {
		module.exports = factory(require('moment')); // Node
	} else if (typeof define === 'function' && define.amd) {
		define(['moment'], factory);                 // AMD
	} else {
		factory(root.moment);                        // Browser
	}
}(this, function (moment) {
	"use strict";

	// Resolves es6 module loading issue
	if (moment.version === undefined && moment.default) {
		moment = moment.default;
	}

	// Do not load moment-timezone a second time.
	// if (moment.tz !== undefined) {
	// 	logError('Moment Timezone ' + moment.tz.version + ' was already loaded ' + (moment.tz.dataVersion ? 'with data from ' : 'without any data') + moment.tz.dataVersion);
	// 	return moment;
	// }

	var VERSION = "0.5.43",
		zones = {},
		links = {},
		countries = {},
		names = {},
		guesses = {},
		cachedGuess;

	if (!moment || typeof moment.version !== 'string') {
		logError('Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/');
	}

	var momentVersion = moment.version.split('.'),
		major = +momentVersion[0],
		minor = +momentVersion[1];

	// Moment.js version check
	if (major < 2 || (major === 2 && minor < 6)) {
		logError('Moment Timezone requires Moment.js >= 2.6.0. You are using Moment.js ' + moment.version + '. See momentjs.com');
	}

	/************************************
		Unpacking
	************************************/

	function charCodeToInt(charCode) {
		if (charCode > 96) {
			return charCode - 87;
		} else if (charCode > 64) {
			return charCode - 29;
		}
		return charCode - 48;
	}

	function unpackBase60(string) {
		var i = 0,
			parts = string.split('.'),
			whole = parts[0],
			fractional = parts[1] || '',
			multiplier = 1,
			num,
			out = 0,
			sign = 1;

		// handle negative numbers
		if (string.charCodeAt(0) === 45) {
			i = 1;
			sign = -1;
		}

		// handle digits before the decimal
		for (i; i < whole.length; i++) {
			num = charCodeToInt(whole.charCodeAt(i));
			out = 60 * out + num;
		}

		// handle digits after the decimal
		for (i = 0; i < fractional.length; i++) {
			multiplier = multiplier / 60;
			num = charCodeToInt(fractional.charCodeAt(i));
			out += num * multiplier;
		}

		return out * sign;
	}

	function arrayToInt (array) {
		for (var i = 0; i < array.length; i++) {
			array[i] = unpackBase60(array[i]);
		}
	}

	function intToUntil (array, length) {
		for (var i = 0; i < length; i++) {
			array[i] = Math.round((array[i - 1] || 0) + (array[i] * 60000)); // minutes to milliseconds
		}

		array[length - 1] = Infinity;
	}

	function mapIndices (source, indices) {
		var out = [], i;

		for (i = 0; i < indices.length; i++) {
			out[i] = source[indices[i]];
		}

		return out;
	}

	function unpack (string) {
		var data = string.split('|'),
			offsets = data[2].split(' '),
			indices = data[3].split(''),
			untils  = data[4].split(' ');

		arrayToInt(offsets);
		arrayToInt(indices);
		arrayToInt(untils);

		intToUntil(untils, indices.length);

		return {
			name       : data[0],
			abbrs      : mapIndices(data[1].split(' '), indices),
			offsets    : mapIndices(offsets, indices),
			untils     : untils,
			population : data[5] | 0
		};
	}

	/************************************
		Zone object
	************************************/

	function Zone (packedString) {
		if (packedString) {
			this._set(unpack(packedString));
		}
	}

	Zone.prototype = {
		_set : function (unpacked) {
			this.name       = unpacked.name;
			this.abbrs      = unpacked.abbrs;
			this.untils     = unpacked.untils;
			this.offsets    = unpacked.offsets;
			this.population = unpacked.population;
		},

		_index : function (timestamp) {
			var target = +timestamp,
				untils = this.untils,
				i;

			for (i = 0; i < untils.length; i++) {
				if (target < untils[i]) {
					return i;
				}
			}
		},

		countries : function () {
			var zone_name = this.name;
			return Object.keys(countries).filter(function (country_code) {
				return countries[country_code].zones.indexOf(zone_name) !== -1;
			});
		},

		parse : function (timestamp) {
			var target  = +timestamp,
				offsets = this.offsets,
				untils  = this.untils,
				max     = untils.length - 1,
				offset, offsetNext, offsetPrev, i;

			for (i = 0; i < max; i++) {
				offset     = offsets[i];
				offsetNext = offsets[i + 1];
				offsetPrev = offsets[i ? i - 1 : i];

				if (offset < offsetNext && tz.moveAmbiguousForward) {
					offset = offsetNext;
				} else if (offset > offsetPrev && tz.moveInvalidForward) {
					offset = offsetPrev;
				}

				if (target < untils[i] - (offset * 60000)) {
					return offsets[i];
				}
			}

			return offsets[max];
		},

		abbr : function (mom) {
			return this.abbrs[this._index(mom)];
		},

		offset : function (mom) {
			logError("zone.offset has been deprecated in favor of zone.utcOffset");
			return this.offsets[this._index(mom)];
		},

		utcOffset : function (mom) {
			return this.offsets[this._index(mom)];
		}
	};

	/************************************
		Country object
	************************************/

	function Country (country_name, zone_names) {
		this.name = country_name;
		this.zones = zone_names;
	}

	/************************************
		Current Timezone
	************************************/

	function OffsetAt(at) {
		var timeString = at.toTimeString();
		var abbr = timeString.match(/\([a-z ]+\)/i);
		if (abbr && abbr[0]) {
			// 17:56:31 GMT-0600 (CST)
			// 17:56:31 GMT-0600 (Central Standard Time)
			abbr = abbr[0].match(/[A-Z]/g);
			abbr = abbr ? abbr.join('') : undefined;
		} else {
			// 17:56:31 CST
			// 17:56:31 GMT+0800 (台北標準時間)
			abbr = timeString.match(/[A-Z]{3,5}/g);
			abbr = abbr ? abbr[0] : undefined;
		}

		if (abbr === 'GMT') {
			abbr = undefined;
		}

		this.at = +at;
		this.abbr = abbr;
		this.offset = at.getTimezoneOffset();
	}

	function ZoneScore(zone) {
		this.zone = zone;
		this.offsetScore = 0;
		this.abbrScore = 0;
	}

	ZoneScore.prototype.scoreOffsetAt = function (offsetAt) {
		this.offsetScore += Math.abs(this.zone.utcOffset(offsetAt.at) - offsetAt.offset);
		if (this.zone.abbr(offsetAt.at).replace(/[^A-Z]/g, '') !== offsetAt.abbr) {
			this.abbrScore++;
		}
	};

	function findChange(low, high) {
		var mid, diff;

		while ((diff = ((high.at - low.at) / 12e4 | 0) * 6e4)) {
			mid = new OffsetAt(new Date(low.at + diff));
			if (mid.offset === low.offset) {
				low = mid;
			} else {
				high = mid;
			}
		}

		return low;
	}

	function userOffsets() {
		var startYear = new Date().getFullYear() - 2,
			last = new OffsetAt(new Date(startYear, 0, 1)),
			offsets = [last],
			change, next, i;

		for (i = 1; i < 48; i++) {
			next = new OffsetAt(new Date(startYear, i, 1));
			if (next.offset !== last.offset) {
				change = findChange(last, next);
				offsets.push(change);
				offsets.push(new OffsetAt(new Date(change.at + 6e4)));
			}
			last = next;
		}

		for (i = 0; i < 4; i++) {
			offsets.push(new OffsetAt(new Date(startYear + i, 0, 1)));
			offsets.push(new OffsetAt(new Date(startYear + i, 6, 1)));
		}

		return offsets;
	}

	function sortZoneScores (a, b) {
		if (a.offsetScore !== b.offsetScore) {
			return a.offsetScore - b.offsetScore;
		}
		if (a.abbrScore !== b.abbrScore) {
			return a.abbrScore - b.abbrScore;
		}
		if (a.zone.population !== b.zone.population) {
			return b.zone.population - a.zone.population;
		}
		return b.zone.name.localeCompare(a.zone.name);
	}

	function addToGuesses (name, offsets) {
		var i, offset;
		arrayToInt(offsets);
		for (i = 0; i < offsets.length; i++) {
			offset = offsets[i];
			guesses[offset] = guesses[offset] || {};
			guesses[offset][name] = true;
		}
	}

	function guessesForUserOffsets (offsets) {
		var offsetsLength = offsets.length,
			filteredGuesses = {},
			out = [],
			i, j, guessesOffset;

		for (i = 0; i < offsetsLength; i++) {
			guessesOffset = guesses[offsets[i].offset] || {};
			for (j in guessesOffset) {
				if (guessesOffset.hasOwnProperty(j)) {
					filteredGuesses[j] = true;
				}
			}
		}

		for (i in filteredGuesses) {
			if (filteredGuesses.hasOwnProperty(i)) {
				out.push(names[i]);
			}
		}

		return out;
	}

	function rebuildGuess () {

		// use Intl API when available and returning valid time zone
		try {
			var intlName = Intl.DateTimeFormat().resolvedOptions().timeZone;
			if (intlName && intlName.length > 3) {
				var name = names[normalizeName(intlName)];
				if (name) {
					return name;
				}
				logError("Moment Timezone found " + intlName + " from the Intl api, but did not have that data loaded.");
			}
		} catch (e) {
			// Intl unavailable, fall back to manual guessing.
		}

		var offsets = userOffsets(),
			offsetsLength = offsets.length,
			guesses = guessesForUserOffsets(offsets),
			zoneScores = [],
			zoneScore, i, j;

		for (i = 0; i < guesses.length; i++) {
			zoneScore = new ZoneScore(getZone(guesses[i]), offsetsLength);
			for (j = 0; j < offsetsLength; j++) {
				zoneScore.scoreOffsetAt(offsets[j]);
			}
			zoneScores.push(zoneScore);
		}

		zoneScores.sort(sortZoneScores);

		return zoneScores.length > 0 ? zoneScores[0].zone.name : undefined;
	}

	function guess (ignoreCache) {
		if (!cachedGuess || ignoreCache) {
			cachedGuess = rebuildGuess();
		}
		return cachedGuess;
	}

	/************************************
		Global Methods
	************************************/

	function normalizeName (name) {
		return (name || '').toLowerCase().replace(/\//g, '_');
	}

	function addZone (packed) {
		var i, name, split, normalized;

		if (typeof packed === "string") {
			packed = [packed];
		}

		for (i = 0; i < packed.length; i++) {
			split = packed[i].split('|');
			name = split[0];
			normalized = normalizeName(name);
			zones[normalized] = packed[i];
			names[normalized] = name;
			addToGuesses(normalized, split[2].split(' '));
		}
	}

	function getZone (name, caller) {

		name = normalizeName(name);

		var zone = zones[name];
		var link;

		if (zone instanceof Zone) {
			return zone;
		}

		if (typeof zone === 'string') {
			zone = new Zone(zone);
			zones[name] = zone;
			return zone;
		}

		// Pass getZone to prevent recursion more than 1 level deep
		if (links[name] && caller !== getZone && (link = getZone(links[name], getZone))) {
			zone = zones[name] = new Zone();
			zone._set(link);
			zone.name = names[name];
			return zone;
		}

		return null;
	}

	function getNames () {
		var i, out = [];

		for (i in names) {
			if (names.hasOwnProperty(i) && (zones[i] || zones[links[i]]) && names[i]) {
				out.push(names[i]);
			}
		}

		return out.sort();
	}

	function getCountryNames () {
		return Object.keys(countries);
	}

	function addLink (aliases) {
		var i, alias, normal0, normal1;

		if (typeof aliases === "string") {
			aliases = [aliases];
		}

		for (i = 0; i < aliases.length; i++) {
			alias = aliases[i].split('|');

			normal0 = normalizeName(alias[0]);
			normal1 = normalizeName(alias[1]);

			links[normal0] = normal1;
			names[normal0] = alias[0];

			links[normal1] = normal0;
			names[normal1] = alias[1];
		}
	}

	function addCountries (data) {
		var i, country_code, country_zones, split;
		if (!data || !data.length) return;
		for (i = 0; i < data.length; i++) {
			split = data[i].split('|');
			country_code = split[0].toUpperCase();
			country_zones = split[1].split(' ');
			countries[country_code] = new Country(
				country_code,
				country_zones
			);
		}
	}

	function getCountry (name) {
		name = name.toUpperCase();
		return countries[name] || null;
	}

	function zonesForCountry(country, with_offset) {
		country = getCountry(country);

		if (!country) return null;

		var zones = country.zones.sort();

		if (with_offset) {
			return zones.map(function (zone_name) {
				var zone = getZone(zone_name);
				return {
					name: zone_name,
					offset: zone.utcOffset(new Date())
				};
			});
		}

		return zones;
	}

	function loadData (data) {
		addZone(data.zones);
		addLink(data.links);
		addCountries(data.countries);
		tz.dataVersion = data.version;
	}

	function zoneExists (name) {
		if (!zoneExists.didShowError) {
			zoneExists.didShowError = true;
				logError("moment.tz.zoneExists('" + name + "') has been deprecated in favor of !moment.tz.zone('" + name + "')");
		}
		return !!getZone(name);
	}

	function needsOffset (m) {
		var isUnixTimestamp = (m._f === 'X' || m._f === 'x');
		return !!(m._a && (m._tzm === undefined) && !isUnixTimestamp);
	}

	function logError (message) {
		if (typeof console !== 'undefined' && typeof console.error === 'function') {
			console.error(message);
		}
	}

	/************************************
		moment.tz namespace
	************************************/

	function tz (input) {
		var args = Array.prototype.slice.call(arguments, 0, -1),
			name = arguments[arguments.length - 1],
			zone = getZone(name),
			out  = moment.utc.apply(null, args);

		if (zone && !moment.isMoment(input) && needsOffset(out)) {
			out.add(zone.parse(out), 'minutes');
		}

		out.tz(name);

		return out;
	}

	tz.version      = VERSION;
	tz.dataVersion  = '';
	tz._zones       = zones;
	tz._links       = links;
	tz._names       = names;
	tz._countries	= countries;
	tz.add          = addZone;
	tz.link         = addLink;
	tz.load         = loadData;
	tz.zone         = getZone;
	tz.zoneExists   = zoneExists; // deprecated in 0.1.0
	tz.guess        = guess;
	tz.names        = getNames;
	tz.Zone         = Zone;
	tz.unpack       = unpack;
	tz.unpackBase60 = unpackBase60;
	tz.needsOffset  = needsOffset;
	tz.moveInvalidForward   = true;
	tz.moveAmbiguousForward = false;
	tz.countries    = getCountryNames;
	tz.zonesForCountry = zonesForCountry;

	/************************************
		Interface with Moment.js
	************************************/

	var fn = moment.fn;

	moment.tz = tz;

	moment.defaultZone = null;

	moment.updateOffset = function (mom, keepTime) {
		var zone = moment.defaultZone,
			offset;

		if (mom._z === undefined) {
			if (zone && needsOffset(mom) && !mom._isUTC) {
				mom._d = moment.utc(mom._a)._d;
				mom.utc().add(zone.parse(mom), 'minutes');
			}
			mom._z = zone;
		}
		if (mom._z) {
			offset = mom._z.utcOffset(mom);
			if (Math.abs(offset) < 16) {
				offset = offset / 60;
			}
			if (mom.utcOffset !== undefined) {
				var z = mom._z;
				mom.utcOffset(-offset, keepTime);
				mom._z = z;
			} else {
				mom.zone(offset, keepTime);
			}
		}
	};

	fn.tz = function (name, keepTime) {
		if (name) {
			if (typeof name !== 'string') {
				throw new Error('Time zone name must be a string, got ' + name + ' [' + typeof name + ']');
			}
			this._z = getZone(name);
			if (this._z) {
				moment.updateOffset(this, keepTime);
			} else {
				logError("Moment Timezone has no data for " + name + ". See http://momentjs.com/timezone/docs/#/data-loading/.");
			}
			return this;
		}
		if (this._z) { return this._z.name; }
	};

	function abbrWrap (old) {
		return function () {
			if (this._z) { return this._z.abbr(this); }
			return old.call(this);
		};
	}

	function resetZoneWrap (old) {
		return function () {
			this._z = null;
			return old.apply(this, arguments);
		};
	}

	function resetZoneWrap2 (old) {
		return function () {
			if (arguments.length > 0) this._z = null;
			return old.apply(this, arguments);
		};
	}

	fn.zoneName  = abbrWrap(fn.zoneName);
	fn.zoneAbbr  = abbrWrap(fn.zoneAbbr);
	fn.utc       = resetZoneWrap(fn.utc);
	fn.local     = resetZoneWrap(fn.local);
	fn.utcOffset = resetZoneWrap2(fn.utcOffset);

	moment.tz.setDefault = function(name) {
		if (major < 2 || (major === 2 && minor < 9)) {
			logError('Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js ' + moment.version + '.');
		}
		moment.defaultZone = name ? getZone(name) : null;
		return moment;
	};

	// Cloning a moment should include the _z property.
	var momentProperties = moment.momentProperties;
	if (Object.prototype.toString.call(momentProperties) === '[object Array]') {
		// moment 2.8.1+
		momentProperties.push('_z');
		momentProperties.push('_a');
	} else if (momentProperties) {
		// moment 2.7.0
		momentProperties._z = null;
	}

	loadData({
		"version": "2023c",
		"zones": [
			"Africa/Abidjan|GMT|0|0||48e5",
			"Africa/Nairobi|EAT|-30|0||47e5",
			"Africa/Algiers|CET|-10|0||26e5",
			"Africa/Lagos|WAT|-10|0||17e6",
			"Africa/Khartoum|CAT|-20|0||51e5",
			"Africa/Cairo|EET EEST|-20 -30|0101010101010|29NW0 1cL0 1cN0 1fz0 1a10 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0|15e6",
			"Africa/Casablanca|+00 +01|0 -10|010101010101010101010101|1Vq20 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0 2600 e00 28M0 e00 2600 gM0|32e5",
			"Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|11e6",
			"Africa/Johannesburg|SAST|-20|0||84e5",
			"Africa/Juba|EAT CAT|-30 -20|01|24nx0|",
			"Africa/Sao_Tome|GMT WAT|0 -10|010|1UQN0 2q00|",
			"Africa/Tripoli|EET|-20|0||11e5",
			"America/Adak|HST HDT|a0 90|01010101010101010101010|1VkA0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|326",
			"America/Anchorage|AKST AKDT|90 80|01010101010101010101010|1Vkz0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|30e4",
			"America/Santo_Domingo|AST|40|0||29e5",
			"America/Fortaleza|-03|30|0||34e5",
			"America/Asuncion|-03 -04|30 40|01010101010101010101010|1Vq30 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0|28e5",
			"America/Panama|EST|50|0||15e5",
			"America/Mexico_City|CST CDT|60 50|01010101010|1VsU0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|20e6",
			"America/Managua|CST|60|0||22e5",
			"America/Caracas|-04|40|0||29e5",
			"America/Lima|-05|50|0||11e6",
			"America/Denver|MST MDT|70 60|01010101010101010101010|1Vkx0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|26e5",
			"America/Campo_Grande|-03 -04|30 40|0101|1Vc30 1HB0 FX0|77e4",
			"America/Chicago|CST CDT|60 50|01010101010101010101010|1Vkw0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|92e5",
			"America/Chihuahua|MST MDT CST|70 60 60|01010101012|1VsV0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|81e4",
			"America/Ciudad_Juarez|MST MDT CST|70 60 60|010101010120101010101010|1Vkx0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1wn0 cm0 EP0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|",
			"America/Phoenix|MST|70|0||42e5",
			"America/Whitehorse|PST PDT MST|80 70 70|0101012|1Vky0 1zb0 Op0 1zb0 Op0 1z90|23e3",
			"America/New_York|EST EDT|50 40|01010101010101010101010|1Vkv0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|21e6",
			"America/Los_Angeles|PST PDT|80 70|01010101010101010101010|1Vky0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|15e6",
			"America/Halifax|AST ADT|40 30|01010101010101010101010|1Vku0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|39e4",
			"America/Godthab|-03 -02 -01|30 20 10|0101010101012121212121|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 2so0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|17e3",
			"America/Grand_Turk|AST EDT EST|40 40 50|01212121212121212121212|1Vkv0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|37e2",
			"America/Havana|CST CDT|50 40|01010101010101010101010|1Vkt0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0|21e5",
			"America/Mazatlan|MST MDT|70 60|01010101010|1VsV0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|44e4",
			"America/Metlakatla|AKST AKDT PST|90 80 80|012010101010101010101010|1Vkz0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|14e2",
			"America/Miquelon|-03 -02|30 20|01010101010101010101010|1Vkt0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|61e2",
			"America/Noronha|-02|20|0||30e2",
			"America/Ojinaga|MST MDT CST CDT|70 60 60 50|01010101012323232323232|1Vkx0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1wn0 Rc0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|23e3",
			"America/Santiago|-03 -04|30 40|01010101010101010101010|1VJD0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|62e5",
			"America/Sao_Paulo|-02 -03|20 30|0101|1Vc20 1HB0 FX0|20e6",
			"Atlantic/Azores|-01 +00|10 0|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|25e4",
			"America/St_Johns|NST NDT|3u 2u|01010101010101010101010|1Vktu 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|11e4",
			"Antarctica/Casey|+11 +08|-b0 -80|0101010|1Vkh0 1o30 14k0 1kr0 12l0 1o01|10",
			"Asia/Bangkok|+07|-70|0||15e6",
			"Asia/Vladivostok|+10|-a0|0||60e4",
			"Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1VsE0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|40e5",
			"Asia/Tashkent|+05|-50|0||23e5",
			"Pacific/Auckland|NZDT NZST|-d0 -c0|01010101010101010101010|1VsC0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00|14e5",
			"Europe/Istanbul|+03|-30|0||13e6",
			"Antarctica/Troll|+00 +02|0 -20|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|40",
			"Asia/Dhaka|+06|-60|0||16e6",
			"Asia/Amman|EET EEST +03|-20 -30 -30|01010101012|1VrW0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 LA0 1C00|25e5",
			"Asia/Kamchatka|+12|-c0|0||18e4",
			"Asia/Dubai|+04|-40|0||39e5",
			"Asia/Beirut|EET EEST|-20 -30|01010101010101010101010|1VpW0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0|22e5",
			"Asia/Kuala_Lumpur|+08|-80|0||71e5",
			"Asia/Kolkata|IST|-5u|0||15e6",
			"Asia/Chita|+09|-90|0||33e4",
			"Asia/Shanghai|CST|-80|0||23e6",
			"Asia/Colombo|+0530|-5u|0||22e5",
			"Asia/Damascus|EET EEST +03|-20 -30 -30|01010101012|1VrW0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0|26e5",
			"Europe/Athens|EET EEST|-20 -30|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|35e5",
			"Asia/Gaza|EET EEST|-20 -30|01010101010101010101010|1Vpz0 1qL0 11c0 1on0 11B0 1o00 11A0 1qo0 XA0 1qp0 1cN0 1cL0 17d0 1in0 14p0 1lb0 11B0 1nX0 11B0 1qL0 WN0 1qL0|18e5",
			"Asia/Hong_Kong|HKT|-80|0||73e5",
			"Asia/Jakarta|WIB|-70|0||31e6",
			"Asia/Jayapura|WIT|-90|0||26e4",
			"Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010|1Vpc0 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0|81e4",
			"Asia/Kabul|+0430|-4u|0||46e5",
			"Asia/Karachi|PKT|-50|0||24e6",
			"Asia/Kathmandu|+0545|-5J|0||12e5",
			"Asia/Sakhalin|+11|-b0|0||58e4",
			"Asia/Makassar|WITA|-80|0||15e5",
			"Asia/Manila|PST|-80|0||24e6",
			"Asia/Pyongyang|KST KST|-8u -90|01|1VGf0|29e5",
			"Asia/Qyzylorda|+06 +05|-60 -50|01|1Xei0|73e4",
			"Asia/Rangoon|+0630|-6u|0||48e5",
			"Asia/Seoul|KST|-90|0||23e6",
			"Asia/Tehran|+0330 +0430|-3u -4u|01010101010|1VoIu 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0|14e6",
			"Asia/Tokyo|JST|-90|0||38e6",
			"Europe/Lisbon|WET WEST|0 -10|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|27e5",
			"Atlantic/Cape_Verde|-01|10|0||50e4",
			"Australia/Adelaide|ACDT ACST|-au -9u|01010101010101010101010|1VsEu 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|11e5",
			"Australia/Brisbane|AEST|-a0|0||20e5",
			"Australia/Darwin|ACST|-9u|0||12e4",
			"Australia/Eucla|+0845|-8J|0||368",
			"Australia/Lord_Howe|+11 +1030|-b0 -au|01010101010101010101010|1VsD0 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu|347",
			"Australia/Perth|AWST|-80|0||18e5",
			"Pacific/Easter|-05 -06|50 60|01010101010101010101010|1VJD0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|30e2",
			"Europe/Dublin|GMT IST|0 -10|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|12e5",
			"Etc/GMT-1|+01|-10|0||",
			"Pacific/Tongatapu|+13|-d0|0||75e3",
			"Pacific/Kiritimati|+14|-e0|0||51e2",
			"Etc/GMT-2|+02|-20|0||",
			"Pacific/Tahiti|-10|a0|0||18e4",
			"Pacific/Niue|-11|b0|0||12e2",
			"Etc/GMT+12|-12|c0|0||",
			"Pacific/Galapagos|-06|60|0||25e3",
			"Etc/GMT+7|-07|70|0||",
			"Pacific/Pitcairn|-08|80|0||56",
			"Pacific/Gambier|-09|90|0||125",
			"Etc/UTC|UTC|0|0||",
			"Europe/London|GMT BST|0 -10|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|10e6",
			"Europe/Chisinau|EET EEST|-20 -30|01010101010101010101010|1Vq00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|67e4",
			"Europe/Moscow|MSK|-30|0||16e6",
			"Europe/Volgograd|MSK +04|-30 -40|010|1WQL0 5gn0|10e5",
			"Pacific/Honolulu|HST|a0|0||37e4",
			"MET|MET MEST|-10 -20|01010101010101010101010|1Vq10 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|",
			"Pacific/Chatham|+1345 +1245|-dJ -cJ|01010101010101010101010|1VsC0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00|600",
			"Pacific/Apia|+14 +13|-e0 -d0|01010101|1VsC0 1cM0 1fA0 1a00 1fA0 1a00 1fA0|37e3",
			"Pacific/Fiji|+13 +12|-d0 -c0|01010101|1UVO0 1VA0 s00 20o0 pc0 2hc0 bc0|88e4",
			"Pacific/Guam|ChST|-a0|0||17e4",
			"Pacific/Marquesas|-0930|9u|0||86e2",
			"Pacific/Pago_Pago|SST|b0|0||37e2",
			"Pacific/Norfolk|+11 +12|-b0 -c0|01010101010101010101|219P0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|25e4"
		],
		"links": [
			"Africa/Abidjan|Africa/Accra",
			"Africa/Abidjan|Africa/Bamako",
			"Africa/Abidjan|Africa/Banjul",
			"Africa/Abidjan|Africa/Bissau",
			"Africa/Abidjan|Africa/Conakry",
			"Africa/Abidjan|Africa/Dakar",
			"Africa/Abidjan|Africa/Freetown",
			"Africa/Abidjan|Africa/Lome",
			"Africa/Abidjan|Africa/Monrovia",
			"Africa/Abidjan|Africa/Nouakchott",
			"Africa/Abidjan|Africa/Ouagadougou",
			"Africa/Abidjan|Africa/Timbuktu",
			"Africa/Abidjan|America/Danmarkshavn",
			"Africa/Abidjan|Atlantic/Reykjavik",
			"Africa/Abidjan|Atlantic/St_Helena",
			"Africa/Abidjan|Etc/GMT",
			"Africa/Abidjan|Etc/GMT+0",
			"Africa/Abidjan|Etc/GMT-0",
			"Africa/Abidjan|Etc/GMT0",
			"Africa/Abidjan|Etc/Greenwich",
			"Africa/Abidjan|GMT",
			"Africa/Abidjan|GMT+0",
			"Africa/Abidjan|GMT-0",
			"Africa/Abidjan|GMT0",
			"Africa/Abidjan|Greenwich",
			"Africa/Abidjan|Iceland",
			"Africa/Algiers|Africa/Tunis",
			"Africa/Cairo|Egypt",
			"Africa/Casablanca|Africa/El_Aaiun",
			"Africa/Johannesburg|Africa/Maseru",
			"Africa/Johannesburg|Africa/Mbabane",
			"Africa/Khartoum|Africa/Blantyre",
			"Africa/Khartoum|Africa/Bujumbura",
			"Africa/Khartoum|Africa/Gaborone",
			"Africa/Khartoum|Africa/Harare",
			"Africa/Khartoum|Africa/Kigali",
			"Africa/Khartoum|Africa/Lubumbashi",
			"Africa/Khartoum|Africa/Lusaka",
			"Africa/Khartoum|Africa/Maputo",
			"Africa/Khartoum|Africa/Windhoek",
			"Africa/Lagos|Africa/Bangui",
			"Africa/Lagos|Africa/Brazzaville",
			"Africa/Lagos|Africa/Douala",
			"Africa/Lagos|Africa/Kinshasa",
			"Africa/Lagos|Africa/Libreville",
			"Africa/Lagos|Africa/Luanda",
			"Africa/Lagos|Africa/Malabo",
			"Africa/Lagos|Africa/Ndjamena",
			"Africa/Lagos|Africa/Niamey",
			"Africa/Lagos|Africa/Porto-Novo",
			"Africa/Nairobi|Africa/Addis_Ababa",
			"Africa/Nairobi|Africa/Asmara",
			"Africa/Nairobi|Africa/Asmera",
			"Africa/Nairobi|Africa/Dar_es_Salaam",
			"Africa/Nairobi|Africa/Djibouti",
			"Africa/Nairobi|Africa/Kampala",
			"Africa/Nairobi|Africa/Mogadishu",
			"Africa/Nairobi|Indian/Antananarivo",
			"Africa/Nairobi|Indian/Comoro",
			"Africa/Nairobi|Indian/Mayotte",
			"Africa/Tripoli|Europe/Kaliningrad",
			"Africa/Tripoli|Libya",
			"America/Adak|America/Atka",
			"America/Adak|US/Aleutian",
			"America/Anchorage|America/Juneau",
			"America/Anchorage|America/Nome",
			"America/Anchorage|America/Sitka",
			"America/Anchorage|America/Yakutat",
			"America/Anchorage|US/Alaska",
			"America/Campo_Grande|America/Cuiaba",
			"America/Caracas|America/Boa_Vista",
			"America/Caracas|America/Guyana",
			"America/Caracas|America/La_Paz",
			"America/Caracas|America/Manaus",
			"America/Caracas|America/Porto_Velho",
			"America/Caracas|Brazil/West",
			"America/Caracas|Etc/GMT+4",
			"America/Chicago|America/Indiana/Knox",
			"America/Chicago|America/Indiana/Tell_City",
			"America/Chicago|America/Knox_IN",
			"America/Chicago|America/Matamoros",
			"America/Chicago|America/Menominee",
			"America/Chicago|America/North_Dakota/Beulah",
			"America/Chicago|America/North_Dakota/Center",
			"America/Chicago|America/North_Dakota/New_Salem",
			"America/Chicago|America/Rainy_River",
			"America/Chicago|America/Rankin_Inlet",
			"America/Chicago|America/Resolute",
			"America/Chicago|America/Winnipeg",
			"America/Chicago|CST6CDT",
			"America/Chicago|Canada/Central",
			"America/Chicago|US/Central",
			"America/Chicago|US/Indiana-Starke",
			"America/Denver|America/Boise",
			"America/Denver|America/Cambridge_Bay",
			"America/Denver|America/Edmonton",
			"America/Denver|America/Inuvik",
			"America/Denver|America/Shiprock",
			"America/Denver|America/Yellowknife",
			"America/Denver|Canada/Mountain",
			"America/Denver|MST7MDT",
			"America/Denver|Navajo",
			"America/Denver|US/Mountain",
			"America/Fortaleza|America/Araguaina",
			"America/Fortaleza|America/Argentina/Buenos_Aires",
			"America/Fortaleza|America/Argentina/Catamarca",
			"America/Fortaleza|America/Argentina/ComodRivadavia",
			"America/Fortaleza|America/Argentina/Cordoba",
			"America/Fortaleza|America/Argentina/Jujuy",
			"America/Fortaleza|America/Argentina/La_Rioja",
			"America/Fortaleza|America/Argentina/Mendoza",
			"America/Fortaleza|America/Argentina/Rio_Gallegos",
			"America/Fortaleza|America/Argentina/Salta",
			"America/Fortaleza|America/Argentina/San_Juan",
			"America/Fortaleza|America/Argentina/San_Luis",
			"America/Fortaleza|America/Argentina/Tucuman",
			"America/Fortaleza|America/Argentina/Ushuaia",
			"America/Fortaleza|America/Bahia",
			"America/Fortaleza|America/Belem",
			"America/Fortaleza|America/Buenos_Aires",
			"America/Fortaleza|America/Catamarca",
			"America/Fortaleza|America/Cayenne",
			"America/Fortaleza|America/Cordoba",
			"America/Fortaleza|America/Jujuy",
			"America/Fortaleza|America/Maceio",
			"America/Fortaleza|America/Mendoza",
			"America/Fortaleza|America/Montevideo",
			"America/Fortaleza|America/Paramaribo",
			"America/Fortaleza|America/Punta_Arenas",
			"America/Fortaleza|America/Recife",
			"America/Fortaleza|America/Rosario",
			"America/Fortaleza|America/Santarem",
			"America/Fortaleza|Antarctica/Palmer",
			"America/Fortaleza|Antarctica/Rothera",
			"America/Fortaleza|Atlantic/Stanley",
			"America/Fortaleza|Etc/GMT+3",
			"America/Godthab|America/Nuuk",
			"America/Halifax|America/Glace_Bay",
			"America/Halifax|America/Goose_Bay",
			"America/Halifax|America/Moncton",
			"America/Halifax|America/Thule",
			"America/Halifax|Atlantic/Bermuda",
			"America/Halifax|Canada/Atlantic",
			"America/Havana|Cuba",
			"America/Lima|America/Bogota",
			"America/Lima|America/Eirunepe",
			"America/Lima|America/Guayaquil",
			"America/Lima|America/Porto_Acre",
			"America/Lima|America/Rio_Branco",
			"America/Lima|Brazil/Acre",
			"America/Lima|Etc/GMT+5",
			"America/Los_Angeles|America/Ensenada",
			"America/Los_Angeles|America/Santa_Isabel",
			"America/Los_Angeles|America/Tijuana",
			"America/Los_Angeles|America/Vancouver",
			"America/Los_Angeles|Canada/Pacific",
			"America/Los_Angeles|Mexico/BajaNorte",
			"America/Los_Angeles|PST8PDT",
			"America/Los_Angeles|US/Pacific",
			"America/Managua|America/Belize",
			"America/Managua|America/Costa_Rica",
			"America/Managua|America/El_Salvador",
			"America/Managua|America/Guatemala",
			"America/Managua|America/Regina",
			"America/Managua|America/Swift_Current",
			"America/Managua|America/Tegucigalpa",
			"America/Managua|Canada/Saskatchewan",
			"America/Mazatlan|Mexico/BajaSur",
			"America/Mexico_City|America/Bahia_Banderas",
			"America/Mexico_City|America/Merida",
			"America/Mexico_City|America/Monterrey",
			"America/Mexico_City|Mexico/General",
			"America/New_York|America/Detroit",
			"America/New_York|America/Fort_Wayne",
			"America/New_York|America/Indiana/Indianapolis",
			"America/New_York|America/Indiana/Marengo",
			"America/New_York|America/Indiana/Petersburg",
			"America/New_York|America/Indiana/Vevay",
			"America/New_York|America/Indiana/Vincennes",
			"America/New_York|America/Indiana/Winamac",
			"America/New_York|America/Indianapolis",
			"America/New_York|America/Iqaluit",
			"America/New_York|America/Kentucky/Louisville",
			"America/New_York|America/Kentucky/Monticello",
			"America/New_York|America/Louisville",
			"America/New_York|America/Montreal",
			"America/New_York|America/Nassau",
			"America/New_York|America/Nipigon",
			"America/New_York|America/Pangnirtung",
			"America/New_York|America/Port-au-Prince",
			"America/New_York|America/Thunder_Bay",
			"America/New_York|America/Toronto",
			"America/New_York|Canada/Eastern",
			"America/New_York|EST5EDT",
			"America/New_York|US/East-Indiana",
			"America/New_York|US/Eastern",
			"America/New_York|US/Michigan",
			"America/Noronha|Atlantic/South_Georgia",
			"America/Noronha|Brazil/DeNoronha",
			"America/Noronha|Etc/GMT+2",
			"America/Panama|America/Atikokan",
			"America/Panama|America/Cancun",
			"America/Panama|America/Cayman",
			"America/Panama|America/Coral_Harbour",
			"America/Panama|America/Jamaica",
			"America/Panama|EST",
			"America/Panama|Jamaica",
			"America/Phoenix|America/Creston",
			"America/Phoenix|America/Dawson_Creek",
			"America/Phoenix|America/Fort_Nelson",
			"America/Phoenix|America/Hermosillo",
			"America/Phoenix|MST",
			"America/Phoenix|US/Arizona",
			"America/Santiago|Chile/Continental",
			"America/Santo_Domingo|America/Anguilla",
			"America/Santo_Domingo|America/Antigua",
			"America/Santo_Domingo|America/Aruba",
			"America/Santo_Domingo|America/Barbados",
			"America/Santo_Domingo|America/Blanc-Sablon",
			"America/Santo_Domingo|America/Curacao",
			"America/Santo_Domingo|America/Dominica",
			"America/Santo_Domingo|America/Grenada",
			"America/Santo_Domingo|America/Guadeloupe",
			"America/Santo_Domingo|America/Kralendijk",
			"America/Santo_Domingo|America/Lower_Princes",
			"America/Santo_Domingo|America/Marigot",
			"America/Santo_Domingo|America/Martinique",
			"America/Santo_Domingo|America/Montserrat",
			"America/Santo_Domingo|America/Port_of_Spain",
			"America/Santo_Domingo|America/Puerto_Rico",
			"America/Santo_Domingo|America/St_Barthelemy",
			"America/Santo_Domingo|America/St_Kitts",
			"America/Santo_Domingo|America/St_Lucia",
			"America/Santo_Domingo|America/St_Thomas",
			"America/Santo_Domingo|America/St_Vincent",
			"America/Santo_Domingo|America/Tortola",
			"America/Santo_Domingo|America/Virgin",
			"America/Sao_Paulo|Brazil/East",
			"America/St_Johns|Canada/Newfoundland",
			"America/Whitehorse|America/Dawson",
			"America/Whitehorse|Canada/Yukon",
			"Asia/Bangkok|Antarctica/Davis",
			"Asia/Bangkok|Asia/Barnaul",
			"Asia/Bangkok|Asia/Ho_Chi_Minh",
			"Asia/Bangkok|Asia/Hovd",
			"Asia/Bangkok|Asia/Krasnoyarsk",
			"Asia/Bangkok|Asia/Novokuznetsk",
			"Asia/Bangkok|Asia/Novosibirsk",
			"Asia/Bangkok|Asia/Phnom_Penh",
			"Asia/Bangkok|Asia/Saigon",
			"Asia/Bangkok|Asia/Tomsk",
			"Asia/Bangkok|Asia/Vientiane",
			"Asia/Bangkok|Etc/GMT-7",
			"Asia/Bangkok|Indian/Christmas",
			"Asia/Chita|Asia/Dili",
			"Asia/Chita|Asia/Khandyga",
			"Asia/Chita|Asia/Yakutsk",
			"Asia/Chita|Etc/GMT-9",
			"Asia/Chita|Pacific/Palau",
			"Asia/Dhaka|Antarctica/Vostok",
			"Asia/Dhaka|Asia/Almaty",
			"Asia/Dhaka|Asia/Bishkek",
			"Asia/Dhaka|Asia/Dacca",
			"Asia/Dhaka|Asia/Kashgar",
			"Asia/Dhaka|Asia/Omsk",
			"Asia/Dhaka|Asia/Qostanay",
			"Asia/Dhaka|Asia/Thimbu",
			"Asia/Dhaka|Asia/Thimphu",
			"Asia/Dhaka|Asia/Urumqi",
			"Asia/Dhaka|Etc/GMT-6",
			"Asia/Dhaka|Indian/Chagos",
			"Asia/Dubai|Asia/Baku",
			"Asia/Dubai|Asia/Muscat",
			"Asia/Dubai|Asia/Tbilisi",
			"Asia/Dubai|Asia/Yerevan",
			"Asia/Dubai|Etc/GMT-4",
			"Asia/Dubai|Europe/Astrakhan",
			"Asia/Dubai|Europe/Samara",
			"Asia/Dubai|Europe/Saratov",
			"Asia/Dubai|Europe/Ulyanovsk",
			"Asia/Dubai|Indian/Mahe",
			"Asia/Dubai|Indian/Mauritius",
			"Asia/Dubai|Indian/Reunion",
			"Asia/Gaza|Asia/Hebron",
			"Asia/Hong_Kong|Hongkong",
			"Asia/Jakarta|Asia/Pontianak",
			"Asia/Jerusalem|Asia/Tel_Aviv",
			"Asia/Jerusalem|Israel",
			"Asia/Kamchatka|Asia/Anadyr",
			"Asia/Kamchatka|Etc/GMT-12",
			"Asia/Kamchatka|Kwajalein",
			"Asia/Kamchatka|Pacific/Funafuti",
			"Asia/Kamchatka|Pacific/Kwajalein",
			"Asia/Kamchatka|Pacific/Majuro",
			"Asia/Kamchatka|Pacific/Nauru",
			"Asia/Kamchatka|Pacific/Tarawa",
			"Asia/Kamchatka|Pacific/Wake",
			"Asia/Kamchatka|Pacific/Wallis",
			"Asia/Kathmandu|Asia/Katmandu",
			"Asia/Kolkata|Asia/Calcutta",
			"Asia/Kuala_Lumpur|Asia/Brunei",
			"Asia/Kuala_Lumpur|Asia/Choibalsan",
			"Asia/Kuala_Lumpur|Asia/Irkutsk",
			"Asia/Kuala_Lumpur|Asia/Kuching",
			"Asia/Kuala_Lumpur|Asia/Singapore",
			"Asia/Kuala_Lumpur|Asia/Ulaanbaatar",
			"Asia/Kuala_Lumpur|Asia/Ulan_Bator",
			"Asia/Kuala_Lumpur|Etc/GMT-8",
			"Asia/Kuala_Lumpur|Singapore",
			"Asia/Makassar|Asia/Ujung_Pandang",
			"Asia/Rangoon|Asia/Yangon",
			"Asia/Rangoon|Indian/Cocos",
			"Asia/Sakhalin|Asia/Magadan",
			"Asia/Sakhalin|Asia/Srednekolymsk",
			"Asia/Sakhalin|Etc/GMT-11",
			"Asia/Sakhalin|Pacific/Bougainville",
			"Asia/Sakhalin|Pacific/Efate",
			"Asia/Sakhalin|Pacific/Guadalcanal",
			"Asia/Sakhalin|Pacific/Kosrae",
			"Asia/Sakhalin|Pacific/Noumea",
			"Asia/Sakhalin|Pacific/Pohnpei",
			"Asia/Sakhalin|Pacific/Ponape",
			"Asia/Seoul|ROK",
			"Asia/Shanghai|Asia/Chongqing",
			"Asia/Shanghai|Asia/Chungking",
			"Asia/Shanghai|Asia/Harbin",
			"Asia/Shanghai|Asia/Macao",
			"Asia/Shanghai|Asia/Macau",
			"Asia/Shanghai|Asia/Taipei",
			"Asia/Shanghai|PRC",
			"Asia/Shanghai|ROC",
			"Asia/Tashkent|Antarctica/Mawson",
			"Asia/Tashkent|Asia/Aqtau",
			"Asia/Tashkent|Asia/Aqtobe",
			"Asia/Tashkent|Asia/Ashgabat",
			"Asia/Tashkent|Asia/Ashkhabad",
			"Asia/Tashkent|Asia/Atyrau",
			"Asia/Tashkent|Asia/Dushanbe",
			"Asia/Tashkent|Asia/Oral",
			"Asia/Tashkent|Asia/Samarkand",
			"Asia/Tashkent|Asia/Yekaterinburg",
			"Asia/Tashkent|Etc/GMT-5",
			"Asia/Tashkent|Indian/Kerguelen",
			"Asia/Tashkent|Indian/Maldives",
			"Asia/Tehran|Iran",
			"Asia/Tokyo|Japan",
			"Asia/Vladivostok|Antarctica/DumontDUrville",
			"Asia/Vladivostok|Asia/Ust-Nera",
			"Asia/Vladivostok|Etc/GMT-10",
			"Asia/Vladivostok|Pacific/Chuuk",
			"Asia/Vladivostok|Pacific/Port_Moresby",
			"Asia/Vladivostok|Pacific/Truk",
			"Asia/Vladivostok|Pacific/Yap",
			"Atlantic/Azores|America/Scoresbysund",
			"Atlantic/Cape_Verde|Etc/GMT+1",
			"Australia/Adelaide|Australia/Broken_Hill",
			"Australia/Adelaide|Australia/South",
			"Australia/Adelaide|Australia/Yancowinna",
			"Australia/Brisbane|Australia/Lindeman",
			"Australia/Brisbane|Australia/Queensland",
			"Australia/Darwin|Australia/North",
			"Australia/Lord_Howe|Australia/LHI",
			"Australia/Perth|Australia/West",
			"Australia/Sydney|Antarctica/Macquarie",
			"Australia/Sydney|Australia/ACT",
			"Australia/Sydney|Australia/Canberra",
			"Australia/Sydney|Australia/Currie",
			"Australia/Sydney|Australia/Hobart",
			"Australia/Sydney|Australia/Melbourne",
			"Australia/Sydney|Australia/NSW",
			"Australia/Sydney|Australia/Tasmania",
			"Australia/Sydney|Australia/Victoria",
			"Etc/UTC|Etc/UCT",
			"Etc/UTC|Etc/Universal",
			"Etc/UTC|Etc/Zulu",
			"Etc/UTC|UCT",
			"Etc/UTC|UTC",
			"Etc/UTC|Universal",
			"Etc/UTC|Zulu",
			"Europe/Athens|Asia/Famagusta",
			"Europe/Athens|Asia/Nicosia",
			"Europe/Athens|EET",
			"Europe/Athens|Europe/Bucharest",
			"Europe/Athens|Europe/Helsinki",
			"Europe/Athens|Europe/Kiev",
			"Europe/Athens|Europe/Kyiv",
			"Europe/Athens|Europe/Mariehamn",
			"Europe/Athens|Europe/Nicosia",
			"Europe/Athens|Europe/Riga",
			"Europe/Athens|Europe/Sofia",
			"Europe/Athens|Europe/Tallinn",
			"Europe/Athens|Europe/Uzhgorod",
			"Europe/Athens|Europe/Vilnius",
			"Europe/Athens|Europe/Zaporozhye",
			"Europe/Chisinau|Europe/Tiraspol",
			"Europe/Dublin|Eire",
			"Europe/Istanbul|Antarctica/Syowa",
			"Europe/Istanbul|Asia/Aden",
			"Europe/Istanbul|Asia/Baghdad",
			"Europe/Istanbul|Asia/Bahrain",
			"Europe/Istanbul|Asia/Istanbul",
			"Europe/Istanbul|Asia/Kuwait",
			"Europe/Istanbul|Asia/Qatar",
			"Europe/Istanbul|Asia/Riyadh",
			"Europe/Istanbul|Etc/GMT-3",
			"Europe/Istanbul|Europe/Minsk",
			"Europe/Istanbul|Turkey",
			"Europe/Lisbon|Atlantic/Canary",
			"Europe/Lisbon|Atlantic/Faeroe",
			"Europe/Lisbon|Atlantic/Faroe",
			"Europe/Lisbon|Atlantic/Madeira",
			"Europe/Lisbon|Portugal",
			"Europe/Lisbon|WET",
			"Europe/London|Europe/Belfast",
			"Europe/London|Europe/Guernsey",
			"Europe/London|Europe/Isle_of_Man",
			"Europe/London|Europe/Jersey",
			"Europe/London|GB",
			"Europe/London|GB-Eire",
			"Europe/Moscow|Europe/Kirov",
			"Europe/Moscow|Europe/Simferopol",
			"Europe/Moscow|W-SU",
			"Europe/Paris|Africa/Ceuta",
			"Europe/Paris|Arctic/Longyearbyen",
			"Europe/Paris|Atlantic/Jan_Mayen",
			"Europe/Paris|CET",
			"Europe/Paris|Europe/Amsterdam",
			"Europe/Paris|Europe/Andorra",
			"Europe/Paris|Europe/Belgrade",
			"Europe/Paris|Europe/Berlin",
			"Europe/Paris|Europe/Bratislava",
			"Europe/Paris|Europe/Brussels",
			"Europe/Paris|Europe/Budapest",
			"Europe/Paris|Europe/Busingen",
			"Europe/Paris|Europe/Copenhagen",
			"Europe/Paris|Europe/Gibraltar",
			"Europe/Paris|Europe/Ljubljana",
			"Europe/Paris|Europe/Luxembourg",
			"Europe/Paris|Europe/Madrid",
			"Europe/Paris|Europe/Malta",
			"Europe/Paris|Europe/Monaco",
			"Europe/Paris|Europe/Oslo",
			"Europe/Paris|Europe/Podgorica",
			"Europe/Paris|Europe/Prague",
			"Europe/Paris|Europe/Rome",
			"Europe/Paris|Europe/San_Marino",
			"Europe/Paris|Europe/Sarajevo",
			"Europe/Paris|Europe/Skopje",
			"Europe/Paris|Europe/Stockholm",
			"Europe/Paris|Europe/Tirane",
			"Europe/Paris|Europe/Vaduz",
			"Europe/Paris|Europe/Vatican",
			"Europe/Paris|Europe/Vienna",
			"Europe/Paris|Europe/Warsaw",
			"Europe/Paris|Europe/Zagreb",
			"Europe/Paris|Europe/Zurich",
			"Europe/Paris|Poland",
			"Pacific/Auckland|Antarctica/McMurdo",
			"Pacific/Auckland|Antarctica/South_Pole",
			"Pacific/Auckland|NZ",
			"Pacific/Chatham|NZ-CHAT",
			"Pacific/Easter|Chile/EasterIsland",
			"Pacific/Galapagos|Etc/GMT+6",
			"Pacific/Gambier|Etc/GMT+9",
			"Pacific/Guam|Pacific/Saipan",
			"Pacific/Honolulu|HST",
			"Pacific/Honolulu|Pacific/Johnston",
			"Pacific/Honolulu|US/Hawaii",
			"Pacific/Kiritimati|Etc/GMT-14",
			"Pacific/Niue|Etc/GMT+11",
			"Pacific/Pago_Pago|Pacific/Midway",
			"Pacific/Pago_Pago|Pacific/Samoa",
			"Pacific/Pago_Pago|US/Samoa",
			"Pacific/Pitcairn|Etc/GMT+8",
			"Pacific/Tahiti|Etc/GMT+10",
			"Pacific/Tahiti|Pacific/Rarotonga",
			"Pacific/Tongatapu|Etc/GMT-13",
			"Pacific/Tongatapu|Pacific/Enderbury",
			"Pacific/Tongatapu|Pacific/Fakaofo",
			"Pacific/Tongatapu|Pacific/Kanton"
		],
		"countries": [
			"AD|Europe/Andorra",
			"AE|Asia/Dubai",
			"AF|Asia/Kabul",
			"AG|America/Puerto_Rico America/Antigua",
			"AI|America/Puerto_Rico America/Anguilla",
			"AL|Europe/Tirane",
			"AM|Asia/Yerevan",
			"AO|Africa/Lagos Africa/Luanda",
			"AQ|Antarctica/Casey Antarctica/Davis Antarctica/Mawson Antarctica/Palmer Antarctica/Rothera Antarctica/Troll Asia/Urumqi Pacific/Auckland Pacific/Port_Moresby Asia/Riyadh Antarctica/McMurdo Antarctica/DumontDUrville Antarctica/Syowa Antarctica/Vostok",
			"AR|America/Argentina/Buenos_Aires America/Argentina/Cordoba America/Argentina/Salta America/Argentina/Jujuy America/Argentina/Tucuman America/Argentina/Catamarca America/Argentina/La_Rioja America/Argentina/San_Juan America/Argentina/Mendoza America/Argentina/San_Luis America/Argentina/Rio_Gallegos America/Argentina/Ushuaia",
			"AS|Pacific/Pago_Pago",
			"AT|Europe/Vienna",
			"AU|Australia/Lord_Howe Antarctica/Macquarie Australia/Hobart Australia/Melbourne Australia/Sydney Australia/Broken_Hill Australia/Brisbane Australia/Lindeman Australia/Adelaide Australia/Darwin Australia/Perth Australia/Eucla",
			"AW|America/Puerto_Rico America/Aruba",
			"AX|Europe/Helsinki Europe/Mariehamn",
			"AZ|Asia/Baku",
			"BA|Europe/Belgrade Europe/Sarajevo",
			"BB|America/Barbados",
			"BD|Asia/Dhaka",
			"BE|Europe/Brussels",
			"BF|Africa/Abidjan Africa/Ouagadougou",
			"BG|Europe/Sofia",
			"BH|Asia/Qatar Asia/Bahrain",
			"BI|Africa/Maputo Africa/Bujumbura",
			"BJ|Africa/Lagos Africa/Porto-Novo",
			"BL|America/Puerto_Rico America/St_Barthelemy",
			"BM|Atlantic/Bermuda",
			"BN|Asia/Kuching Asia/Brunei",
			"BO|America/La_Paz",
			"BQ|America/Puerto_Rico America/Kralendijk",
			"BR|America/Noronha America/Belem America/Fortaleza America/Recife America/Araguaina America/Maceio America/Bahia America/Sao_Paulo America/Campo_Grande America/Cuiaba America/Santarem America/Porto_Velho America/Boa_Vista America/Manaus America/Eirunepe America/Rio_Branco",
			"BS|America/Toronto America/Nassau",
			"BT|Asia/Thimphu",
			"BW|Africa/Maputo Africa/Gaborone",
			"BY|Europe/Minsk",
			"BZ|America/Belize",
			"CA|America/St_Johns America/Halifax America/Glace_Bay America/Moncton America/Goose_Bay America/Toronto America/Iqaluit America/Winnipeg America/Resolute America/Rankin_Inlet America/Regina America/Swift_Current America/Edmonton America/Cambridge_Bay America/Inuvik America/Dawson_Creek America/Fort_Nelson America/Whitehorse America/Dawson America/Vancouver America/Panama America/Puerto_Rico America/Phoenix America/Blanc-Sablon America/Atikokan America/Creston",
			"CC|Asia/Yangon Indian/Cocos",
			"CD|Africa/Maputo Africa/Lagos Africa/Kinshasa Africa/Lubumbashi",
			"CF|Africa/Lagos Africa/Bangui",
			"CG|Africa/Lagos Africa/Brazzaville",
			"CH|Europe/Zurich",
			"CI|Africa/Abidjan",
			"CK|Pacific/Rarotonga",
			"CL|America/Santiago America/Punta_Arenas Pacific/Easter",
			"CM|Africa/Lagos Africa/Douala",
			"CN|Asia/Shanghai Asia/Urumqi",
			"CO|America/Bogota",
			"CR|America/Costa_Rica",
			"CU|America/Havana",
			"CV|Atlantic/Cape_Verde",
			"CW|America/Puerto_Rico America/Curacao",
			"CX|Asia/Bangkok Indian/Christmas",
			"CY|Asia/Nicosia Asia/Famagusta",
			"CZ|Europe/Prague",
			"DE|Europe/Zurich Europe/Berlin Europe/Busingen",
			"DJ|Africa/Nairobi Africa/Djibouti",
			"DK|Europe/Berlin Europe/Copenhagen",
			"DM|America/Puerto_Rico America/Dominica",
			"DO|America/Santo_Domingo",
			"DZ|Africa/Algiers",
			"EC|America/Guayaquil Pacific/Galapagos",
			"EE|Europe/Tallinn",
			"EG|Africa/Cairo",
			"EH|Africa/El_Aaiun",
			"ER|Africa/Nairobi Africa/Asmara",
			"ES|Europe/Madrid Africa/Ceuta Atlantic/Canary",
			"ET|Africa/Nairobi Africa/Addis_Ababa",
			"FI|Europe/Helsinki",
			"FJ|Pacific/Fiji",
			"FK|Atlantic/Stanley",
			"FM|Pacific/Kosrae Pacific/Port_Moresby Pacific/Guadalcanal Pacific/Chuuk Pacific/Pohnpei",
			"FO|Atlantic/Faroe",
			"FR|Europe/Paris",
			"GA|Africa/Lagos Africa/Libreville",
			"GB|Europe/London",
			"GD|America/Puerto_Rico America/Grenada",
			"GE|Asia/Tbilisi",
			"GF|America/Cayenne",
			"GG|Europe/London Europe/Guernsey",
			"GH|Africa/Abidjan Africa/Accra",
			"GI|Europe/Gibraltar",
			"GL|America/Nuuk America/Danmarkshavn America/Scoresbysund America/Thule",
			"GM|Africa/Abidjan Africa/Banjul",
			"GN|Africa/Abidjan Africa/Conakry",
			"GP|America/Puerto_Rico America/Guadeloupe",
			"GQ|Africa/Lagos Africa/Malabo",
			"GR|Europe/Athens",
			"GS|Atlantic/South_Georgia",
			"GT|America/Guatemala",
			"GU|Pacific/Guam",
			"GW|Africa/Bissau",
			"GY|America/Guyana",
			"HK|Asia/Hong_Kong",
			"HN|America/Tegucigalpa",
			"HR|Europe/Belgrade Europe/Zagreb",
			"HT|America/Port-au-Prince",
			"HU|Europe/Budapest",
			"ID|Asia/Jakarta Asia/Pontianak Asia/Makassar Asia/Jayapura",
			"IE|Europe/Dublin",
			"IL|Asia/Jerusalem",
			"IM|Europe/London Europe/Isle_of_Man",
			"IN|Asia/Kolkata",
			"IO|Indian/Chagos",
			"IQ|Asia/Baghdad",
			"IR|Asia/Tehran",
			"IS|Africa/Abidjan Atlantic/Reykjavik",
			"IT|Europe/Rome",
			"JE|Europe/London Europe/Jersey",
			"JM|America/Jamaica",
			"JO|Asia/Amman",
			"JP|Asia/Tokyo",
			"KE|Africa/Nairobi",
			"KG|Asia/Bishkek",
			"KH|Asia/Bangkok Asia/Phnom_Penh",
			"KI|Pacific/Tarawa Pacific/Kanton Pacific/Kiritimati",
			"KM|Africa/Nairobi Indian/Comoro",
			"KN|America/Puerto_Rico America/St_Kitts",
			"KP|Asia/Pyongyang",
			"KR|Asia/Seoul",
			"KW|Asia/Riyadh Asia/Kuwait",
			"KY|America/Panama America/Cayman",
			"KZ|Asia/Almaty Asia/Qyzylorda Asia/Qostanay Asia/Aqtobe Asia/Aqtau Asia/Atyrau Asia/Oral",
			"LA|Asia/Bangkok Asia/Vientiane",
			"LB|Asia/Beirut",
			"LC|America/Puerto_Rico America/St_Lucia",
			"LI|Europe/Zurich Europe/Vaduz",
			"LK|Asia/Colombo",
			"LR|Africa/Monrovia",
			"LS|Africa/Johannesburg Africa/Maseru",
			"LT|Europe/Vilnius",
			"LU|Europe/Brussels Europe/Luxembourg",
			"LV|Europe/Riga",
			"LY|Africa/Tripoli",
			"MA|Africa/Casablanca",
			"MC|Europe/Paris Europe/Monaco",
			"MD|Europe/Chisinau",
			"ME|Europe/Belgrade Europe/Podgorica",
			"MF|America/Puerto_Rico America/Marigot",
			"MG|Africa/Nairobi Indian/Antananarivo",
			"MH|Pacific/Tarawa Pacific/Kwajalein Pacific/Majuro",
			"MK|Europe/Belgrade Europe/Skopje",
			"ML|Africa/Abidjan Africa/Bamako",
			"MM|Asia/Yangon",
			"MN|Asia/Ulaanbaatar Asia/Hovd Asia/Choibalsan",
			"MO|Asia/Macau",
			"MP|Pacific/Guam Pacific/Saipan",
			"MQ|America/Martinique",
			"MR|Africa/Abidjan Africa/Nouakchott",
			"MS|America/Puerto_Rico America/Montserrat",
			"MT|Europe/Malta",
			"MU|Indian/Mauritius",
			"MV|Indian/Maldives",
			"MW|Africa/Maputo Africa/Blantyre",
			"MX|America/Mexico_City America/Cancun America/Merida America/Monterrey America/Matamoros America/Chihuahua America/Ciudad_Juarez America/Ojinaga America/Mazatlan America/Bahia_Banderas America/Hermosillo America/Tijuana",
			"MY|Asia/Kuching Asia/Singapore Asia/Kuala_Lumpur",
			"MZ|Africa/Maputo",
			"NA|Africa/Windhoek",
			"NC|Pacific/Noumea",
			"NE|Africa/Lagos Africa/Niamey",
			"NF|Pacific/Norfolk",
			"NG|Africa/Lagos",
			"NI|America/Managua",
			"NL|Europe/Brussels Europe/Amsterdam",
			"NO|Europe/Berlin Europe/Oslo",
			"NP|Asia/Kathmandu",
			"NR|Pacific/Nauru",
			"NU|Pacific/Niue",
			"NZ|Pacific/Auckland Pacific/Chatham",
			"OM|Asia/Dubai Asia/Muscat",
			"PA|America/Panama",
			"PE|America/Lima",
			"PF|Pacific/Tahiti Pacific/Marquesas Pacific/Gambier",
			"PG|Pacific/Port_Moresby Pacific/Bougainville",
			"PH|Asia/Manila",
			"PK|Asia/Karachi",
			"PL|Europe/Warsaw",
			"PM|America/Miquelon",
			"PN|Pacific/Pitcairn",
			"PR|America/Puerto_Rico",
			"PS|Asia/Gaza Asia/Hebron",
			"PT|Europe/Lisbon Atlantic/Madeira Atlantic/Azores",
			"PW|Pacific/Palau",
			"PY|America/Asuncion",
			"QA|Asia/Qatar",
			"RE|Asia/Dubai Indian/Reunion",
			"RO|Europe/Bucharest",
			"RS|Europe/Belgrade",
			"RU|Europe/Kaliningrad Europe/Moscow Europe/Simferopol Europe/Kirov Europe/Volgograd Europe/Astrakhan Europe/Saratov Europe/Ulyanovsk Europe/Samara Asia/Yekaterinburg Asia/Omsk Asia/Novosibirsk Asia/Barnaul Asia/Tomsk Asia/Novokuznetsk Asia/Krasnoyarsk Asia/Irkutsk Asia/Chita Asia/Yakutsk Asia/Khandyga Asia/Vladivostok Asia/Ust-Nera Asia/Magadan Asia/Sakhalin Asia/Srednekolymsk Asia/Kamchatka Asia/Anadyr",
			"RW|Africa/Maputo Africa/Kigali",
			"SA|Asia/Riyadh",
			"SB|Pacific/Guadalcanal",
			"SC|Asia/Dubai Indian/Mahe",
			"SD|Africa/Khartoum",
			"SE|Europe/Berlin Europe/Stockholm",
			"SG|Asia/Singapore",
			"SH|Africa/Abidjan Atlantic/St_Helena",
			"SI|Europe/Belgrade Europe/Ljubljana",
			"SJ|Europe/Berlin Arctic/Longyearbyen",
			"SK|Europe/Prague Europe/Bratislava",
			"SL|Africa/Abidjan Africa/Freetown",
			"SM|Europe/Rome Europe/San_Marino",
			"SN|Africa/Abidjan Africa/Dakar",
			"SO|Africa/Nairobi Africa/Mogadishu",
			"SR|America/Paramaribo",
			"SS|Africa/Juba",
			"ST|Africa/Sao_Tome",
			"SV|America/El_Salvador",
			"SX|America/Puerto_Rico America/Lower_Princes",
			"SY|Asia/Damascus",
			"SZ|Africa/Johannesburg Africa/Mbabane",
			"TC|America/Grand_Turk",
			"TD|Africa/Ndjamena",
			"TF|Asia/Dubai Indian/Maldives Indian/Kerguelen",
			"TG|Africa/Abidjan Africa/Lome",
			"TH|Asia/Bangkok",
			"TJ|Asia/Dushanbe",
			"TK|Pacific/Fakaofo",
			"TL|Asia/Dili",
			"TM|Asia/Ashgabat",
			"TN|Africa/Tunis",
			"TO|Pacific/Tongatapu",
			"TR|Europe/Istanbul",
			"TT|America/Puerto_Rico America/Port_of_Spain",
			"TV|Pacific/Tarawa Pacific/Funafuti",
			"TW|Asia/Taipei",
			"TZ|Africa/Nairobi Africa/Dar_es_Salaam",
			"UA|Europe/Simferopol Europe/Kyiv",
			"UG|Africa/Nairobi Africa/Kampala",
			"UM|Pacific/Pago_Pago Pacific/Tarawa Pacific/Midway Pacific/Wake",
			"US|America/New_York America/Detroit America/Kentucky/Louisville America/Kentucky/Monticello America/Indiana/Indianapolis America/Indiana/Vincennes America/Indiana/Winamac America/Indiana/Marengo America/Indiana/Petersburg America/Indiana/Vevay America/Chicago America/Indiana/Tell_City America/Indiana/Knox America/Menominee America/North_Dakota/Center America/North_Dakota/New_Salem America/North_Dakota/Beulah America/Denver America/Boise America/Phoenix America/Los_Angeles America/Anchorage America/Juneau America/Sitka America/Metlakatla America/Yakutat America/Nome America/Adak Pacific/Honolulu",
			"UY|America/Montevideo",
			"UZ|Asia/Samarkand Asia/Tashkent",
			"VA|Europe/Rome Europe/Vatican",
			"VC|America/Puerto_Rico America/St_Vincent",
			"VE|America/Caracas",
			"VG|America/Puerto_Rico America/Tortola",
			"VI|America/Puerto_Rico America/St_Thomas",
			"VN|Asia/Bangkok Asia/Ho_Chi_Minh",
			"VU|Pacific/Efate",
			"WF|Pacific/Tarawa Pacific/Wallis",
			"WS|Pacific/Apia",
			"YE|Asia/Riyadh Asia/Aden",
			"YT|Africa/Nairobi Indian/Mayotte",
			"ZA|Africa/Johannesburg",
			"ZM|Africa/Maputo Africa/Lusaka",
			"ZW|Africa/Maputo Africa/Harare"
		]
	});


	return moment;
}));

var words;

function CroutonLocalization(language) {
	this.language = language;
	this.words = {
		"ar": {
			"days_of_the_week": ["", "الأحد", "الاثنين", "الثلاثاء", "الأربعاء ", "الخميس", "الجمعة", "السبت"],
			"weekday": "يوم عمل",
			"city": "مدينة",
			"cities": "المدن",
			"groups": "مجموعات",
			"areas": "المناطق",
			"regions": "المناطق",
			"locations": "المواقع",
			"counties": "المقاطعات",
			"states": "المقاطعات",
			"postal_codes": "الرموز البريدية",
			"formats": "الأشكال",
			"map": "خريطة",
			"neighborhood": "الحي",
			"near_me": "بالقرب مني",
			"text_search": "البحث عن النص",
			"click_search": "انقر فوق البحث",
			"pan_and_zoom": "عموم + التكبير",
			"languages": "اللغات",
			"common_needs": "الاحتياجات المشتركة",
			"meeting_count": "الاجتماعات الأسبوعية:",
			"venue_types": "أنواع المكان",
			"venue_type_choices": {
				IN_PERSON: "شخصيا",
				VIRTUAL: "افتراضي",
			},
			"service_body_types": {
				AS: "لجنة خدمات المنطق",
				RS: "لجنة خدمات الإقلي.م",
				ZF: "منتدى المنطقة",
				MA: "لجنة خدمات العاصمة",
				LS: "خدمة المنتديات المحلية",
				GS: "Group Support Forum",
			},
			"css-direction": 'bmlt-rtl',
			"share": "مشاركة",
			'google_directions': 'اتجاهات جوجل للاجتماع',
			'apple_directions': 'اتجاهات جوجل للاجتماع',
			"no_meetings_for_this_day": "لا توجد اجتماعات لهذا اليوم.",
			'all': 'الجميع',
			'menu': 'القائمة',
			'search for meetings': 'البحث عن الاجتماعات',
			'show meetings near...': 'أظهر الاجتماعات بالقرب من...',
			'filter meetings': 'سرد الاجتماعات',
			'visible meeting list': 'قائمة الاجتماعات المرئية',
			'enter a city or zip code': 'أدخل المدينة أو الرمز البريدي',
			'toggle fullscreen mode': 'تبديل وضع ملء الشاشة',
			'close': "قريب",
			"bmlt2ics": "Add to your calendar",
			'meeting page': "صفحة الاجتماع",
			'meeting details': "تفاصيل الاجتماع",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"get_directions": "احصل على الاتجاهات",
			"select_map_app": "اختر تطبيق الخرائط",
			"apple_maps": "خرائط آبل",
			"apple_maps_desc": "فتح في تطبيق خرائط آبل",
			"google_maps": "خرائط جوجل",
			"google_maps_desc_mobile": "فتح في تطبيق خرائط جوجل",
			"waze": "وايز",
			"waze_desc": "فتح في تطبيق وايز",
			'address_lookup_fail': 'تعذر العثور على العنوان. يرجى المحاولة مرة أخرى.',
		},
		"cs": {
			"days_of_the_week": ["", "Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota"],
			"weekday": "Den v týdnu",
			"city": "Město",
			"cities": "Město",
			"groups": "Skupina",
			"areas": "Oblasti",
			"regions": "Regiony",
			"locations": "Místo",
			"counties": "Okres",
			"states": "Spolkové země",
			"postal_codes": "PSČ",
			"formats": "Formáty",
			"map": "Mapa",
			"neighborhood": "Sousedství",
			"near_me": "V mém okolí",
			"text_search": "Textové vyhledávání",
			"click_search": "Vyhledávání kliknutím",
			"pan_and_zoom": "Posunout + Zoom",
			"languages": "Jazyky",
			"common_needs": "Běžné potřeby",
			"meeting_count": "Týdenní setkání:",
			"venue_types": "Druhy míst setkání",
			"venue_type_choices": {
				"IN_PERSON": "Živé setkání",
				"VIRTUAL": "Online setkání"
			},
			"service_body_types": {
			},
			"share": "Sdílet",
			"google_directions": "Plánovač tras Google",
			"apple_directions": "Plánovač tras Apple",
			"no_meetings_for_this_day": "Na tento den nejsou žádná setkání.",
			"css-textalign": "",
			"css-floatdirection": "",
			"all": "Jakékoli",
			"menu": "Menu",
			"search for meetings": "Hledat setkání",
			"show meetings near...": "Setkání v jiných městech",
			"filter meetings": "Filtr pro jazyk, formát atd.",
			"visible meeting list": "Viditelný seznam setkání jako tabulka",
			"enter a city or zip code": "Město nebo PSČ",
			"toggle fullscreen mode": "Přepnout režim celé obrazovky",
			"close": "Zavřít",
			"bmlt2ics": "Přidat do kalendáře",
			"meeting page": "Stránka setkání",
			"meeting details": "Podrobnosti o setkání",
			"report update": "Nahlásit aktualizaci",
			"filter by visibility": "Zobrazit pouze setkání, která jsou aktuálně na mapě",
			"go": "Jít!",
			"get_directions": "Získat pokyny",
			"select_map_app": "Vyberte aplikaci pro mapy",
			"apple_maps": "Apple Mapy",
			"apple_maps_desc": "Otevřít v aplikaci Apple Mapy",
			"google_maps": "Mapy Google",
			"distance": "Vzdálenost",
			"google_maps_desc_mobile": "Otevřít v aplikaci Mapy Google",
			"waze": "Waze",
			"waze_desc": "Otevřít v aplikaci Waze",
			"remember my choice": "Zapamatovat si moji volbu",
			"zoomed-out-message": "Nemůžeme prohledat celou oblast pro setkání. Přibližte si prosím nebo proveďte nové vyhledávání.",
			"sorted by distance": "Seřazeno podle vzdálenosti",
			"address_lookup_fail": "Adresu se nepodařilo najít. Zkuste to prosím znovu.",
			"contact": "Kontakt",
		},
		"da-DK": {
			"days_of_the_week": ["", "Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag"],
			"weekday": 'Ugedag',
			"city": "By",
			"cities": "Byer",
			"groups": "Grupper",
			"areas": "Områder",
			"regions": "Regions",
			"locations": "Lokalite",
			"counties": "Amter",
			"states": "Provinser",
			"postal_codes": "Post nummer",
			"formats": "Struktur",
			"map": "Kort",
			"neighborhood": "Neighborhood",
			"near_me": "Find nearby meetings",
			"text_search": "Find meetings there",
			"click_search": "Find meetings near to a point on the map",
			"pan_and_zoom": "Pan + Zoom",
			"languages": "Languages",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			'all': 'All',
			'menu': 'Menu',
			"bmlt2ics": "Add to your calendar",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"distance": "Afstand",
			"get_directions": "Få vejvisning",
			"select_map_app": "Vælg kortapp",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Åbn i Apple Maps app",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Åbn i Google Maps app",
			"waze": "Waze",
			"waze_desc": "Åbn i Waze app",
			"sorted by distance": "Sorteret efter Afstand",
			"address_lookup_fail": "Adressen kunne ikke findes. Prøv venligst igen.",
			"contact": "Kontakt",
		},
		"de-DE": {
			"days_of_the_week": ["", "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
			"weekday": 'Wochentag',
			"city": "Stadt",
			"cities": "Städte",
			"groups": "Gruppen",
			"areas": "Gebiete",
			"regions": "Regions",
			"locations": "Orte",
			"counties": "Landkreise",
			"states": "Bundesländer",
			"postal_codes": "PLZ",
			"formats": "Formate",
			"map": "Karte",
			"neighborhood": "Nachbarschaft",
			"near_me": "In meiner Nähe",
			"text_search": "Textsuche",
			"click_search": "Klicksuche",
			"pan_and_zoom": "Schwenken + Zoomen",
			"languages": "Sprachen",
			"common_needs": "Common Needs",
			"meeting_count": "Wöchentliche Meetings:",
			"venue_types": "Treffpunktarten",
			"venue_type_choices": {
				IN_PERSON: "Präsenz-Meetings",
				VIRTUAL: "Online-Meetings",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "Teilen",
			'google_directions': 'Google Routenplaner',
			'apple_directions': 'Apple Routenplaner',
			"no_meetings_for_this_day": "Keine Meetings an diesem Tag.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'Alle',
			'menu': 'Menu',
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Meetings in andere Städten',
			'filter meetings': 'Filter für Sprache, Format usw.',
			'visible meeting list': 'Sichtbare Meetings als Tabelle',
			'enter a city or zip code': 'Stadt oder PLZ',
			'toggle fullscreen mode': 'Umschalten Vollbildmodus',
			'close': "Schliessen",
			"bmlt2ics": "Zu Kalender hinzufügen",
			'meeting page': "Meeting Seite",
			'meeting details': "Genaueres zum Meeting",
			'report update': "Report an Update",
			'filter by visibility': "Zeige nur Meetings, die gerade auf dem Karte stehen",
			'go': "Los!",
			"get_directions": "Wegbeschreibung",
			"select_map_app": "Karten-App auswählen",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "In Apple Maps App öffnen",
			"google_maps": "Google Maps",
			"distance": "Entfernung",
			"google_maps_desc_mobile": "In Google Maps App öffnen",
			"waze": "Waze",
			"waze_desc": "In Waze App öffnen",
			"remember my choice": "Auswahl speichern",
			"zoomed-out-message": "Wir können nicht die ganze Fläche nach Meetings durchsuchen.  Bitte reinzoomen oder eine neue Suche machen.",
			"sorted by distance": "Sortiert nach Entfernung",
			"address_lookup_fail": "Die Adresse konnte nicht gefunden werden. Bitte versuchen Sie es erneut.",
			"contact": "Kontakt",
			"distance": "Entfernung",
			"all meetings": "Alle Meetings",
			'upcoming meetings': "Nächste 24 Stunden",
		},
		'el-GR': {
			"days_of_the_week": ["", "Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"],
						"weekday": "Ημέρες",
			"city": "Πόλη",
			"cities": "Πόλεις",
			"groups": "Ομάδες",
			"areas": "ΕΥΠ",
			"regions": "ΔΕΥΔ",
			"locations": "Τοποθεσίες",
			"counties": "Νομοί",
			"states": "Διαμερίσματα",
			"postal_codes": "Ταχυδρομικοί Κώδικες",
			"formats": "Θέματα ομάδων",
			"map": "Χάρτης",
			"neighborhood": "Συνοικία",
			"near_me": "Κοντά μου",
			"text_search": "Αναζήτηση κειμένου",
			"click_search": "Κλικ για αναζήτηση",
			"pan_and_zoom": "Μετακίνηση και ζουμ",
			"languages": "Γλώσσες",
			"common_needs": "Ειδικού ενδιαφέροντος",
			"meeting_count": "Σύνολο ομάδων",
			"google_directions": "Οδηγίες Google",
			"apple_directions": "Οδηγίες Apple",
			"venue_types": "Τύποι ομάδων",
			"venue_type_choices": {
				IN_PERSON: "Φυσικές",
				VIRTUAL: "Διαδικτυακές"
			},
			"service_body_types": {
				AS:	"ΕΥΠ",
				RS:	"ΕΥΔ",
				ZF:	"ZF",
				MA: "MA",
				LS:	"LS",
				GS:	"Αυτόνομη ομάδα",
			},
			"share": "Κοινοποίηση",
			"no_meetings_for_this_day": "Δεν έχει ομάδες αυτή την ημέρα",
			"css-textalign": "",
			"css-floatdirection": "",
			"all": "",
			"menu":	"Μενού",
			"search for meetings":	"Αναζήτηση ομάδων",
			"show meetings near...": "Εμφάνιση ομάδων κοντά σε..",
			"filter meetings": "Φίλτραρε τις ομάδες",
			"visible meeting list": "Λίστα ορατών ομάδων",
			"enter a city or zip code": "Εισαγάγετε μια πόλη ή ταχυδρομικό κώδικα",
			"toggle fullscreen mode": "Εναλλαγη λειτουργίας πλήρους οθόνης",
			"close": "Κλείσιμο",
			"bmlt2ics": "Προσθήκη στο ημερολόγιό σας",
			"meeting page": "Σελίδα ομάδας",
			"meeting details": "Πληροφορίες ομάδας",
			"report update": "Ανέφερε ενημέρωση",
			"filter by visibility": "Φίλτραρε ανα ορατές ομάδες",
			"open search dialog": "’νοιξε αναζήτηση",
			"go": "Έναρξη",
			"get_directions": "Λάβετε οδηγίες",
			"select_map_app": "Διαλέξτε εφαρμογή χάρτη",
			"apple_maps": "Χάρτες Apple",
			"apple_maps_desc": "Χάρτες Apple σε υπολογιστή",
			"google_maps": "Χαρτες Google",
			"google_maps_desc_mobile": "Χάρτες Google υπολογιστή κινητού",
			"waze": "Waze",
			"waze_desc": "Waze Desc",
			"zoomed-out-message": "Μήνυμα Απομακρυνσης Ζοομ",
			"sorted by distance": "Κατάταξη βάσει απόστασης",
			"address_lookup_fail": "Αδυναμία εύρεσης διεύθυνσης",
			"contact": "Επικοινωνία",
			"distance": "Απόσταση",
			"join this meeting online": "Διαδικτυακή ομάδα",
			"this meeting is in": "Αυτή η ομάδα ανήκει στην",
			"location": "Τοποθεσία",
			"remember my choice": "Θυμήσου την επιλογή μου",
			"adjust search": "Προσαρμογή αναζήτησης",
			"this number represents": "Αυτός ο αριθμός αντιπροσωπ",
			"radius of search in $$": "Ακτίνα αναζήτησης σε $$",
			"miles": "miles",
			"km": "km",
			"approx. number of meetings in result": "Περίπου αριθμός ομάδων στο αποτέλεσμα",
			"back": "Πίσω",
			"meeting info": "Πληροφορίες ομάδας",
			"more info": "Περισσότερα",
			"address": "Διεύθυνση",
			"comments": "Σχόλια",
			"facility is temporarily closed": "Η εγκατάσταση είναι προσωρινά κλειστή",
			"meets virtually": "Διαδικτυακή ομάδα",
			"meets in person": "Φυσική ομάδα",
			"meets virtually and in person": "Διαδικτυακή και φυσική ομάδα",
			"all meetings": "Όλες οι ομάδες",
			"upcoming meetings": "Προσεχείς ομάδες",
		},
		"en-AU": {
			"days_of_the_week": ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			"weekday": "Weekday",
			"city": "City",
			"cities": "Cities",
			"groups": "Groups",
			"areas": "Areas",
			"regions": "Regions",
			"locations": "Locations",
			"counties": "Counties",
			"states": "States",
			"postal_codes": "Postcodes",
			"formats": "Formats",
			"map": "Map",
			"neighborhood": "Neighbourhood",
			"near_me": "Find nearby meetings",
			"text_search": "Find meetings there",
			"click_search": "Find meetings near to a point on the map",
			"languages": "Languages",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			"bmlt2ics": "Add to your calendar",
			'all': 'All',
			'menu': 'Menu',
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city and state',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			'open search dialog': "Open Search Dialog",
			"get_directions": "Get Directions",
			"select_map_app": "Select Map App",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Open in Apple Maps app",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Open in Google Maps app",
			"waze": "Waze",
			"waze_desc": "Open in Waze app",
			"zoomed-out-message": "We can't search the entire area for meetings. Please zoom in or do a new search.",
			"sorted by distance": "Sorted by Distance",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},
		"en-CA": {
			"days_of_the_week": ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			"weekday": "Weekday",
			"city": "City",
			"cities": "Cities",
			"groups": "Groups",
			"areas": "Areas",
			"regions": "Regions",
			"locations": "Locations",
			"counties": "Counties",
			"states": "Provinces",
			"postal_codes": "Postal Codes",
			"formats": "Formats",
			"map": "Map",
			"neighborhood": "Neighborhood",
			"near_me": "Find nearby meetings",
			"text_search": "Find meetings there",
			"click_search": "Find meetings near to a point on the map",
			"pan_and_zoom": "Pan + Zoom",
			"languages": "Languages",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': 'Menu',
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			"bmlt2ics": "Add to your calendar",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'open search dialog': "Open Search Dialog",
			'go': "Go!",
			"get_directions": "Get Directions",
			"select_map_app": "Select Map App",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Open in Apple Maps app",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Open in Google Maps app",
			"waze": "Waze",
			"waze_desc": "Open in Waze app",
			"zoomed-out-message": "We can't search the entire area for meetings. Please zoom in or do a new search.",
			"sorted by distance": "Sorted by Distance",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},
		"en-NZ": {
			"days_of_the_week": ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			"weekday": "Weekday",
			"city": "City",
			"cities": "Cities",
			"groups": "Groups",
			"areas": "Areas",
			"regions": "Regions",
			"locations": "Locations",
			"counties": "Counties",
			"states": "States",
			"postal_codes": "Postcodes",
			"formats": "Formats",
			"map": "Map",
			"neighborhood": "Neighborhood",
			"near_me": "Find nearby meetings",
			"text_search": "Find meetings there",
			"click_search": "Find meetings near to a point on the map",
			"pan_and_zoom": "Pan + Zoom",
			"languages": "Languages",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': 'Menu',
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			"bmlt2ics": "Add to your calendar",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'open search dialog': "Open Search Dialog",
			'go': "Go!",
			"get_directions": "Get Directions",
			"select_map_app": "Select Map App",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Open in Apple Maps app",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Open in Google Maps app",
			"waze": "Waze",
			"waze_desc": "Open in Waze app",
			"zoomed-out-message": "We can't search the entire area for meetings. Please zoom in or do a new search.",
			"sorted by distance": "Sorted by Distance",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},
		"en-UK": {
			"days_of_the_week": ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			"weekday": "Weekday",
			"city": "City",
			"cities": "Cities",
			"groups": "Groups",
			"areas": "Areas",
			"regions": "Regions",
			"locations": "Locations",
			"counties": "Counties",
			"states": "States",
			"postal_codes": "Postcodes",
			"formats": "Formats",
			"map": "Map",
			"neighborhood": "Neighborhood",
			"near_me": "Find nearby meetings",
			"text_search": "Find meetings there",
			"click_search": "Find meetings near to a point on the map",
			"pan_and_zoom": "Pan + Zoom",
			"languages": "Languages",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': "Menu",
			"bmlt2ics": "Add to your calendar",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'open search dialog': "Open Search Dialog",
			'go': "Go!",
			"get_directions": "Get Directions",
			"select_map_app": "Select Map App",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Open in Apple Maps app",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Open in Google Maps app",
			"waze": "Waze",
			"waze_desc": "Open in Waze app",
			"zoomed-out-message": "We can't search the entire area for meetings. Please zoom in or do a new search.",
			"sorted by distance": "Sorted by Distance",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},

		"en-US": {
			"days_of_the_week": ["", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			"weekday": "Weekday",
			"city": "City",
			"cities": "Cities",
			"groups": "Groups",
			"areas": "Areas",
			"regions": "Regions",
			"locations": "Locations",
			"counties": "Counties",
			"states": "States",
			"postal_codes": "Zips",
			"formats": "Formats",
			"map": "Map",
			"neighborhood": "Neighborhood",
			"near_me": "Find nearby meetings",
			"text_search": "Find meetings there",
			"click_search": "Find meetings near to a point on the map",
			"pan_and_zoom": "Pan + Zoom",
			"languages": "Languages",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': "Menu",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			"bmlt2ics": "Add to your calendar",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'open search dialog': "Open Search Dialog",
			'go': "Go!",
			"get_directions": "Get Directions",
			"select_map_app": "Select Map App",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Open in Apple Maps app",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Open in Google Maps app",
			"waze": "Waze",
			"waze_desc": "Open in Waze app",
			"zoomed-out-message": "We can't search the entire area for meetings. Please zoom in or do a new search.",
			"sorted by distance": "Sorted by Distance",
			"address_lookup_fail": "The address could not be found. Please try again.",
			"contact": "Contact",
			"distance": "Distance",
			"join this meeting online": "Join this meeting online",
			"this meeting is in": "This meeting is in",
			"location": "Location",
			"remember my choice": "Remember my choice",
			"facility is temporarily closed": "FACILITY IS TEMPORARILY CLOSED",
			"meets virtually": "MEETS VIRTUALLY",
			"meets in person": "MEETS IN PERSON",
			"meets virtually and in person": "MEETS VIRTUALLY AND IN PERSON",
			"adjust search": "Adjust Search",
			"this number represents": "This number represents",
			"radius of search in $$": "Radius of search in $$",
			"miles": "miles",
			"km": "km",
			"approx. number of meetings in result": "Approx. number of meetings in result",
			"back": "Back",
			"meeting info": "Meeting Info",
			"address": "Address",
			"comments": "Comments",
			"more info": "More Info",
			"all meetings": "All Meetings",
			'upcoming meetings': "Upcoming Meetings",
		},
		"es-US": {
			"days_of_the_week": ["", "Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],
			"weekday": "Día de la semana",
			"city": "Ciudad",
			"cities": "Ciudades",
			"groups": "Grupos",
			"areas": "Áreas",
			"regions": "Regiones",
			"locations": "Ubicaciones",
			"counties": "Provincias",
			"states": "Comunidad Autónoma",
			"postal_codes": "Códigos postales",
			"formats": "Formatos",
			"map": "Mapa",
			"neighborhood": "Distrito",
			"near_me": "Sitios cercanos",
			"text_search": "Búsqueda de texto",
			"click_search": "Buscar en Google",
			"pan_and_zoom": "Paneo y Zoom",
			"languages": "Idiomas",
			"common_needs": "Necesidades comunes",
			"meeting_count": "Número de reuniones encontradas",
			"Weekly Meetings": "Reuniones semanales",
			"venue_types": "Tipos de espacios",
			"venue_type_choices": {
				IN_PERSON: "Presencial",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Cómite de servicio de Área",
				RS: "Comité regional de servicio",
				ZF: "Foro Zonal",
				MA: "Comité metropolitano de servicio",
				LS: "Foro de servicio local",
				GS: "Foro de apoyo a grupos",
			},
			"share": "compartir",
			"no_meetings_for_this_day": "No hay reuniones en este día",
			'css-textalign': '',
			'google_directions': 'Indicaciones de Google',
			'apple_directions': 'Indicaciones de Apple',
			'css-floatdirection': "Dirección float-CSS",
			'all': 'Todos',
			'menu': "Menú",
			'search for meetings': 'Buscar reuniones',
			'show meetings near...': 'Mostrar reuniones cercanas...',
			'filter meetings': 'Filtrar reuniones',
			'visible meeting list': 'Listado visible de reuniones',
			'enter a city or zip code': 'Introduce una ciudad o un código postal',
			'toggle fullscreen mode': 'Modo pantalla completa',
			'close': "Cerrar",
			"bmlt2ics": "Añadir a calendario",
			'meeting page': "Página de la reunión",
			'meeting details': "Detalles de la reunión",
			'report update': "Actualización de informe",
			'filter by visibility': "Listar solo estas reuniones",
			'go': "¡Adelante!",
			"distance": "Distancia",
			"get_directions": "Obtener Direcciones",
			"select_map_app": "Seleccionar Aplicación de Mapas",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Abrir en la aplicación Apple Maps",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Abrir en la aplicación Google Maps",
			"waze": "Waze",
			"waze_desc": "Abrir en la aplicación Waze",
			"zoomed-out-message": "No podemos buscar reuniones en toda la zona. Por favor, acérquese o haga una nueva búsqueda.",
			"sorted by distance": "Ordenado por distancia",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},
		"fa-IR": {
			"days_of_the_week": ["", 'یَکشَنب', 'دوشَنبه', 'سه‌شنبه', 'چهار شنبه', 'پَنج شَنبه', 'جُمعه', 'شَنبه'],
			"weekday": "ایام هفته",
			"city": "شهر",
			"cities": "شهرها",
			"groups": "گروه ها",
			"areas": "نواحی",
			"regions": "مناطق",
			"locations": "آدرسها",
			"counties": "بخشها",
			"states": "استان ها",
			"postal_codes:": "کد پستی",
			"formats": "فرمت ها",
			"map": "نقشه",
			"neighborhood": "محله",
			"near_me": "جلسات نزدیک من را پیدا کن",
			"text_search": "جلسات اینجا را پیدا کن",
			"click_search": "پیدا کردن جلسات نزدیک به یک نقطه روی نقشه",
			"pan_and_zoom": "حرکت + بزرگنمایی",
			"languages": "زبانها",
			"common_needs": "خصوصیات مشترک",
			"meeting_count": "جلسات هفتگی:",
			"venue_types": "انواع مکان",
			"venue_type_choices": {
				"IN_PERSON": "حضوری",
				"VIRTUAL": "لینک جلسه مجازی",
			},
			"service_body_types": {
				"AS": "کمیته خدمات ناحیه",
				"RS": "کمیته خدمات منطقه‌ای",
				"ZF": "انجمن منطقه‌ای",
				"MA": "کمیته خدمات کلان‌شهریe",
				"LS": "انجمن خدمات محلی",
				"GS": "انجمن پشتیبانی گروه",
			},
			"share": "اشتراک گذاری",
			"google_directions": "مسیرهای Google به جلسه",
			"apple_directions": "مسیرهای Apple به جلسه",
			"no_meetings_for_this_day": "هیچ جلسه ای در این روز وجود ندارد",
			"css-direction": "bmlt-rtl",
			"bootstrap-popover-placement": "left",
			"adjust search": "تنظیم جستجو",
			"this number represents": "این عدد نشان دهنده",
			"radius of search in $$": "شعاع جستجو بر حسب $$",
			"miles": "مایل",
			"km": "کیلومتر",
			"approx. number of meetings in result": "تعداد تقریبی جلسات در نتیجه",
			"back": "بازگشت",
			"all": "همه",
			"menu": " منوی",
			"search for meetings": "جستجوی جلسه ها",
			"show meetings near...": "نمایش جلسات نزدیک",
			"filter meetings": "فیلتر جلسات",
			"visible meeting list": "جلسات قابل مشاهده به عنوان لیست",
			"enter a city or zip code": "شهر یا کد پستی را وارد کنید",
			"toggle fullscreen mode": "تغییر حالت تمام صفحه",
			"close": "بستن",
			"bmlt2ics": "به تقویم خود اضافه کنید",
			"meeting page": "صفحه جلسه",
			"meeting details": "جزئیات جلسه",
			"report update": "گزارش به‌روزرسانی",
			"filter by visibility": "فقط این جلسات را فهرست کنید",
			"go": "برو",
			"distance": "فاصله",
			"get_directions": "دریافت مسیر",
			"select_map_app": "انتخاب برنامه نقشه",
			"apple_maps": "نقشه اپل",
			"apple_maps_desc": "باز کردن در برنامه نقشه اپل",
			"google_maps": "گوگل مپس",
			"google_maps_desc_mobile": "باز کردن در برنامه گوگل مپس",
			"waze": "ویوز",
			"waze_desc": "باز کردن در برنامه ویز",
			"sorted by distance": "مرتب کردن بر اساس فاصله",
			"more info": "اطلاعات بیشتر",
			"css-direction": 'bmlt-rtl',
			"css-textalign": "style='text-align: right;'",
			'address': 'آدرس',
			'meeting info': 'ویژگی',
			'comments': 'توضیحات',
			'group details': 'نمایش گروه',
			"address_lookup_fail": "آدرس پیدا نشد. لطفا دوباره تلاش کنید.",
		},
		"fr-CA": {
			"days_of_the_week": ["", "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
			"weekday": "Journée",
			"city": "Ville",
			"cities": "Villes",
			"groups": "Groupes",
			"areas": "ASL",
			"regions": "Regions",
			"locations": "Emplacements",
			"counties": "Régions",
			"states": "Provinces",
			"postal_codes": "Codes postaux",
			"formats": "Formats",
			"map": "Carte",
			"neighborhood": "Quartier",
			"near_me": "À côté de moi",
			"text_search": "Recherche textuelle",
			"click_search": "Recherche au clic",
			"pan_and_zoom": "Panoramique + Zoom",
			"languages": "Langages",
			"common_needs": "Besoins",
			"meeting_count": "Nombre de réunions par semaine",
			"venue_types": "Types de lieux",
			"venue_type_choices": {
				IN_PERSON: "Physique",
				VIRTUAL: "Virtuel",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "Partager",
			"google_directions": "Itinéraire sur Google Maps",
			'apple_directions': 'Itinéraire sur Apple Maps',
			"no_meetings_for_this_day": "Pas de réunion aujourd'hui.",
			"css-textalign": "",
			"css-floatdirection": "css-floatdirection",
			"all": "Tout",
			"menu": "Menu",
			"search for meetings": "Rechercher des réunions",
			"show meetings near...": "Afficher les réunions près de...",
			"filter meetings": "Filtrer les réunions",
			"visible meeting list": "Liste des réunions visibles",
			"enter a city or zip code": "Entrer une ville ou un code postal",
			"toggle fullscreen mode": "Basculer en mode plein écran",
			"close": "Fermer",
			"bmlt2ics": "Ajouter au calendrier",
			"meeting page": "Page de la réunion",
			"meeting details": "Détails de la réunion",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"distance": "Distance",
			"get_directions": "Obtenir l'itinéraire",
			"select_map_app": "Sélectionner l'application de cartes",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Ouvrir dans l'application Apple Maps",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Ouvrir dans l'application Google Maps",
			"waze": "Waze",
			"waze_desc": "Ouvrir dans l'application Waze",
			"sorted by distance": "Trié par distance",
			"address_lookup_fail": "L'adresse est introuvable. Veuillez réessayer.",
		},
		"it-IT": {
			"days_of_the_week": ["", "Domenica", " Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"],
			"weekday": "Giorno",
			"city": "Città",
			"cities": "Città",
			"groups": "Gruppi",
			"areas": "Aree",
			"regions": "Regione",
			"locations": "Località",
			"counties": "Province",
			"states": "Regione",
			"postal_codes": "CAP",
			"formats": "Formati",
			"map": "Mappa",
			"neighborhood": "Quartiere",
			"near_me": "Vicino a me",
			"text_search": "Ricerca testuale",
			"click_search": "Fare click su cerca",
			"pan_and_zoom": "Panoramica e zoom",
			"languages": "Lingue",
			"common_needs": "Bisogni comuni",
			"meeting_count": "Incontri settimanali:",
			"venue_types": "Tipologia di locali",
			"venue_type_choices": {
				IN_PERSON: "Riunione fisica",
				VIRTUAL: "Riunione virtuale",
			},
			"service_body_types": {
				AS: "Comitato area",
				RS: "Comitato di regione",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Forum supporto gruppi"
			},
			"share": "Condividi",
			'google_directions': 'Mappa',
			'apple_directions': 'Mappa',
			"no_meetings_for_this_day": "Nessuna riunione per questo giorno.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'Tutti',
			'menu': "Menu",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Mostra incontri nelle vicinanze..',
			'filter meetings': 'Filtrare le riunioni',
			'visible meeting list': 'Elenco riunioni visibile',
			'enter a city or zip code': 'Inserire una città o un codice postale',
			'toggle fullscreen mode': 'Attiva/disattiva la modalità a schermo intero',
			'close': "Close",
			"bmlt2ics": "Aggiungi al tuo calendario",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"distance": "Distanza",
			"get_directions": "Ottieni Indicazioni",
			"select_map_app": "Seleziona App Mappe",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Apri nell'app Apple Maps",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Apri nell'app Google Maps",
			"waze": "Waze",
			"waze_desc": "Apri nell'app Waze",
			"sorted by distance": "Ordinati per distanza",
			"address_lookup_fail": "L'indirizzo non è stato trovato. Per favore riprova.",
		},
		"nl-NL": {
			"days_of_the_week": ["", "Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag"],
			"weekday": "Dag van de week",
			"city": "Stad",
			"cities": "Steden",
			"groups": "Groepen",
			"areas": "Gebieden",
			"regions": "Regions",
			"locations": "Locaties",
			"counties": "Landen",
			"states": "Provincies",
			"postal_codes": "Postcodes",
			"formats": "Formats",
			"map": "Kaart",
			"neighborhood": "Buurt",
			"near_me": "Bij mij in de buurt",
			"text_search": "Zoek op tekst",
			"click_search": "Klik om te zoeken",
			"pan_and_zoom": "Pan + Zoom",
			"languages": "Talen",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Soorten locaties",
			"venue_type_choices": {
				IN_PERSON: "Fysiek",
				VIRTUAL: "Online",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': "Menu",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			"bmlt2ics": "Add to your calendar",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"get_directions": "Routebeschrijving",
			"select_map_app": "Kies Kaart App",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Openen in Apple Maps app",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Openen in Google Maps app",
			"waze": "Waze",
			"waze_desc": "Openen in Waze app",
			"sorted by distance": "Gesorteerd op afstand",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},
		"pl-PL": {
			"days_of_the_week": ["", "Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"],
			"weekday": "Dzień tygodnia",
			"city": "Miasto",
			"cities": "Miasta",
			"groups": "Grupy",
			"areas": "Okręgi",
			"regions": "Regions",
			"locations": "Lokalizacje",
			"counties": "Powiaty",
			"states": "Województwa",
			"postal_codes": "Kody pocztowe",
			"formats": "Formaty",
			"map": "Mapa",
			"neighborhood": "Sąsiedztwo",
			"near_me": "Blisko Mnie",
			"text_search": "Wpisz",
			"click_search": "Kliknij na mapie",
			"pan_and_zoom": "Przesuń powiększ",
			"languages": "Języki",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': "Menu",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			"bmlt2ics": "Add to your calendar",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"distance": "Odległość",
			"get_directions": "Pobierz Wskazówki",
			"select_map_app": "Wybierz Aplikację Map",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Otwórz w aplikacji Apple Maps",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Otwórz w aplikacji Google Maps",
			"waze": "Waze",
			"waze_desc": "Otwórz w aplikacji Waze",
			"sorted by distance": "Posortowane według odległości",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},
		"pt-BR": {
			"days_of_the_week": ["", "Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"],
			"weekday": "Dia da semana",
			"city": "Cidade",
			"cities": "Cidades",
			"groups": "Grupos",
			"areas": "Áreas",
			"regions": "Regions",
			"locations": "Localizações",
			"counties": "Municípios",
			"states": "Estados",
			"postal_codes": "CEPs",
			"formats": "Formatos",
			"map": "Mapa",
			"neighborhood": "Bairro",
			"near_me": "Minha Localização",
			"text_search": "digite um endereço",
			"click_search": "Clique no local",
			"pan_and_zoom": "Panorâmico + Zoom",
			"languages": "Idiomas",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "tipos de reunião",
			"venue_type_choices": {
				IN_PERSON: "Presencial",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "Compartilhar",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': "Menu",
			"bmlt2ics": "Add to your calendar",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"distance": "Distância",
			"get_directions": "Obter Direções",
			"select_map_app": "Selecionar Aplicativo de Mapas",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Abrir no aplicativo Apple Maps",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Abrir no aplicativo Google Maps",
			"waze": "Waze",
			"waze_desc": "Abrir no aplicativo Waze",
			"sorted by distance": "Classificado por distância",
			"address_lookup_fail": "The address could not be found. Please try again.",
		},
		"ru-RU": {
			"days_of_the_week": ["", "Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"],
			"weekday": "будний день",
			"city": "Город",
			"cities": "Города",
			"groups": "Группы",
			"areas": "Зоны",
			"regions": "Regions",
			"locations": "Локации",
			"counties": "Страны",
			"states": "Штаты",
			"postal_codes": "Индексы (почтовые)",
			"formats": "Форматы",
			"map": "Карта",
			"neighborhood": "Соседство",
			"near_me": "Около меня",
			"text_search": "Поиск текста",
			"click_search": "Нажмите Поиск",
			"pan_and_zoom": "Pan + Zoom",
			"languages": "Языки",
			"common_needs": "Common Needs",
			"meeting_count": "Еженедельные собрания:",
			"venue_types": "Типы собрания",
			"venue_type_choices": {
				IN_PERSON: "Офлайн",
				VIRTUAL: "Онлайн",
			},
			"share": "поделиться",
			'google_directions': 'На карте',
			'apple_directions': 'На карте',
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"no_meetings_for_this_day": "В этот день собраний нет",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': "Меню",
			"bmlt2ics": "Добавить в календарь",
			'search for meetings': 'Поиск собраний',
			'show meetings near...': 'Показывать собрания рядом с...',
			'filter meetings': 'Фильтровать собрания',
			'visible meeting list': 'Собрания в виде списка',
			'enter a city or zip code': 'Введите город или почтовый индек',
			'toggle fullscreen mode': 'Включить полноэкранный режим',
			'close': "Закрыть",
			'meeting page': "Страница собрания",
			'meeting details': "Подробности собрания",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"distance": "Расстояние",
			"get_directions": "Проложить маршрут",
			"select_map_app": "Выбрать приложение карт",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Открыть в приложении Apple Maps",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Открыть в приложении Google Maps",
			"waze": "Waze",
			"waze_desc": "Открыть в приложении Waze",
			"sorted by distance": "Сортировка по расстоянию",
			"address_lookup_fail": "Адрес не найден. Пожалуйста, попробуйте еще раз.",
		},
		"sk": {
			"days_of_the_week": ["", "Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"],
			"weekday": "Deň v týždni",
			"city": "Mesto",
			"cities": "Mesto",
			"groups": "Skupina",
			"areas": "Oblasti",
			"regions": "Región",
			"locations": "Miesto",
			"counties": "Okres",
			"states": "Spolkové krajiny",
			"postal_codes": "PSČ",
			"formats": "Formáty",
			"map": "Mapa",
			"neighborhood": "Susedstvo",
			"near_me": "V mojej blízkosti",
			"text_search": "Textové vyhľadávanie",
			"click_search": "Vyhľadávanie kliknutím",
			"pan_and_zoom": "Posúvanie + Zoomovanie",
			"languages": "Jazek",
			"common_needs": "Bežné potreby",
			"meeting_count": "Týždenné stretnutia:",
			"venue_types": "Typy miest stretnutí",
			"venue_type_choices": {
				"IN_PERSON": "Osobné stretnutia",
				"VIRTUAL": "Živé stretnutia"
			},
			"service_body_types": {
			},
			"share": "Zdieľať",
			"google_directions": "Plánovač trás Google",
			"apple_directions": "Plánovač trás Apple",
			"no_meetings_for_this_day": "Žiadne stretnutia v tento deň.",
			"css-textalign": "",
			"css-floatdirection": "",
			"all": "Akékoľvek",
			"menu": "Menu",
			"search for meetings": "Hľadať stretnutia",
			"show meetings near...": "Stretnutia v iných mestách",
			"filter meetings": "Filter pre jazyk, formát atď.",
			"visible meeting list": "Viditeľné stretnutia ako tabuľka",
			"enter a city or zip code": "Mesto alebo PSČ",
			"toggle fullscreen mode": "Prepnúť režim celej obrazovky",
			"close": "Zavrieť",
			"bmlt2ics": "Pridať do kalendára",
			"meeting page": "Stránka stretnutia",
			"meeting details": "Podrobnosti o stretnutí",
			"report update": "Nahlásiť aktualizáciu",
			"filter by visibility": "Zobraziť iba stretnutia, ktoré sú práve na mape",
			"go": "Ísť!",
			"get_directions": "Získať trasu",
			"select_map_app": "Vyberte aplikáciu pre mapy",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Otvoriť v aplikácii Apple Maps",
			"google_maps": "Google Maps",
			"distance": "Vzdialenosť",
			"google_maps_desc_mobile": "Otvoriť v aplikácii Google Maps",
			"waze": "Waze",
			"waze_desc": "Otvoriť v aplikácii Waze",
			"remember my choice": "Zapamätať si moju voľbu",
			"zoomed-out-message": "Nemôžeme prehľadať celú oblasť pre stretnutia. Prosím, priblížte alebo vykonajte nové vyhľadávanie.",
			"sorted by distance": "Zoradené podľa vzdialenosti",
			"address_lookup_fail": "Adresa sa nenašla. Skúste to znova prosím.",
		},
		"sv-SE": {
			"days_of_the_week": ["", "Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"],
			"weekday": "Veckodag",
			"city": "Stad",
			"cities": "Städer",
			"groups": "Grupper",
			"areas": "Distrikt",
			"regions": "Regions",
			"locations": "Plats",
			"counties": "Land",
			"states": "Stater",
			"postal_codes": "Postnummer",
			"formats": "Format",
			"map": "Karta",
			"neighborhood": "Region",
			"near_me": "Nära mig",
			"text_search": "Söktext",
			"click_search": "Sök",
			"pan_and_zoom": "Panorera + Zooma",
			"languages": "Språk",
			"common_needs": "Common Needs",
			"meeting_count": "Weekly Meetings:",
			"venue_types": "Venue Types",
			"venue_type_choices": {
				IN_PERSON: "In Person",
				VIRTUAL: "Virtual",
			},
			"service_body_types": {
				AS: "Area Service Committee",
				RS: "Regional Service Committee",
				ZF: "Zonal Forum",
				MA: "Metropolitan Service Committee",
				LS: "Local Service Forum",
				GS: "Group Support Forum"
			},
			"share": "share",
			'google_directions': 'Google directions to meeting',
			'apple_directions': 'Apple directions to meeting',
			"no_meetings_for_this_day": "No meetings for this day.",
			'css-textalign': '',
			'css-floatdirection': '',
			'all': 'All',
			'menu': "Menu",
			'search for meetings': 'Search for meetings',
			'show meetings near...': 'Show meetings near...',
			'filter meetings': 'Filter meetings',
			'visible meeting list': 'Visible meetings as list',
			'enter a city or zip code': 'Enter a city or zip code',
			'toggle fullscreen mode': 'Toggle fullscreen mode',
			'close': "Close",
			"bmlt2ics": "Add to your calendar",
			'meeting page': "Meeting Page",
			'meeting details': "Meeting Details",
			'report update': "Report an Update",
			'filter by visibility': "List only these meetings",
			'go': "Go!",
			"get_directions": "Få vägbeskrivning",
			"select_map_app": "Välj kartapp",
			"apple_maps": "Apple Maps",
			"apple_maps_desc": "Öppna i Apple Maps-appen",
			"google_maps": "Google Maps",
			"google_maps_desc_mobile": "Öppna i Google Maps-appen",
			"waze": "Waze",
			"waze_desc": "Öppna i Waze-appen",
			"sorted by distance": "Sorterade efter avstånd",
			"address_lookup_fail": "The address could not be found. Please try again.",
		}
	};
}

CroutonLocalization.prototype.getDayOfTheWeekWord = function(day_id) {
	return this.words[this.language]['days_of_the_week'][day_id];
};

CroutonLocalization.prototype.getWord = function(word) {
	const ret = this.words[this.language][word.toLowerCase()];
	if(typeof ret === 'undefined') {
		if(word === 'css-direction') return '';
		if(word === 'bootstrap-popover-placement') return 'right';
		return word;
	}
	return ret;
};

CroutonLocalization.prototype.getVenueType = function(type) {
	return this.words[this.language]['venue_type_choices'][type];
}

CroutonLocalization.prototype.getServiceBodyType = function(type) {
	return this.words[this.language]['service_body_types'][type];
}

CroutonLocalization.prototype.getAllLanguages = function() {
	return Object.keys(this.words);
}
CroutonLocalization.prototype.getTranslations = function(targetLanguage) {
	return Object.entries(this.words['en-US']).map((entries) => {
		return {
			key: entries[0],
			english: entries[1],
			translation: this.words[targetLanguage][entries[0]] ?? ''
		}
	});
}
CroutonLocalization.prototype.filterCustomTranslations = function(language, translations) {
	if (!this.words[language]) return translations;
	return Object.fromEntries(Object.entries(translations).reduce((carry, entries) => {
		let translation = this.words[language][entries[0]];
		let new_translation = entries[1];
		if (Array.isArray(translation)
			|| typeof translation === 'object') {
			translation = JSON.stringify(translation);
			new_translation = JSON.stringify(new_translation);
		}
		if (translation !== new_translation) carry.push(entries);
		return carry;
	}, []));
}
CroutonLocalization.prototype.customizeTranslations = function(translations) {
	Object.entries(translations).forEach((language_entry) => {
		const language = language_entry[0];
		if (!this.words[language]) this.words[language] = {};
		Object.entries(language_entry[1]).forEach((entries) => {
			this.words[language][entries[0]] = entries[1];
		});
	});
}
function CroutonHandlebarsExtensions() {
	CroutonHandlebarsExtensions.prototype.registerHelpers = function() {
		crouton_Handlebars.registerHelper('getDayOfTheWeek', function(day_id) {
			return hbs_Crouton.localization.getDayOfTheWeekWord(day_id);
		});

		crouton_Handlebars.registerHelper('getWord', function(word) {
			var translation = hbs_Crouton.localization.getWord(word);
			if(typeof translation !== 'undefined') return translation;
			console.log("no translation for '" + word + "'");
			// if none found, return the untranslated - better than nothing.
			return word;
		});

		crouton_Handlebars.registerHelper('formatDataPointer', function(str) {
			return convertToPunyCode(str);
		});

		crouton_Handlebars.registerHelper('call', function(fn, str) {
			return fn(str);
		});

		crouton_Handlebars.registerHelper('canShare', function(data, options) {
			return navigator.share ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		crouton_Handlebars.registerHelper('isOS', function(options) {
			if(isIOSDevice()) {
				return getTrueResult(options, this);
			} else {
				return getFalseResult(options, this);
			}
		});
		crouton_Handlebars.registerHelper('reportUpdateEnabled', function(data, options) {
			return crouton.config.report_update_url !== "" ? getTrueResult(options, this) : getFalseResult(options, this)
		});

		crouton_Handlebars.registerHelper('reportUpdateUrl', function() {
			return crouton.config.report_update_url;
		});
		crouton_Handlebars.registerHelper('ifGroup', function(data, options) {
			return (data.hasOwnProperty('membersOfGroup') && data.membersOfGroup.length > 1)
				? options.fn(this)
				: options.inverse(this);
		});
		crouton_Handlebars.registerHelper('groupsConfigured', function(data, options) {
			if (crouton.config.groups) {
				return getTrueResult(options, this);
			} else {
				return getFalseResult(options, this);
			}
		});
		/**
		 * @deprecated Since version 3.12.2, will be removed in a future version.
		 */
		crouton_Handlebars.registerHelper('isVirtual', function(data, options) {
			return ((data['venue_type'] === venueType.HYBRID || data['venue_type'] === venueType.VIRTUAL) || ((inArray(getMasterFormatId('HY', data), getFormats(data)) && !inArray(getMasterFormatId('TC', data), getFormats(data)))
				|| inArray(getMasterFormatId('VM', data), getFormats(data))))
				&& (data['virtual_meeting_link'] || data['phone_meeting_number'] || data['virtual_meeting_additional_info']) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		/**
		 * Assumes consistent set of venue type formats (enforced for newly edited meetings in root server 2.16.0 or greater)
		 */
		crouton_Handlebars.registerHelper('isVirtualOnly', function(data, options) {
			return data['venue_type'] === venueType.VIRTUAL || inArray(getMasterFormatId('VM', data), getFormats(data)) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		/**
		 * @deprecated Since version 3.12.2 will be removed in a future version.
		 */
		crouton_Handlebars.registerHelper('isHybrid', function(data, options) {
			return data['venue_type'] === venueType.HYBRID || inArray(getMasterFormatId('HY', data), getFormats(data)) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		/**
		 * Assumes consistent set of venue type formats (enforced for newly edited meetings in root server 2.16.0 or greater)
		 */
		crouton_Handlebars.registerHelper('isHybridOnly', function(data, options) {
			return data['venue_type'] === venueType.HYBRID || inArray(getMasterFormatId('HY', data), getFormats(data)) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		crouton_Handlebars.registerHelper('isTemporarilyClosed', function(data, options) {
			return inArray(getMasterFormatId('TC', data), getFormats(data)) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		crouton_Handlebars.registerHelper('isNotTemporarilyClosed', function(data, options) {
			return !inArray(getMasterFormatId('TC', data), getFormats(data)) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		/**
		 * Assumes consistent set of venue type formats (enforced for newly edited meetings in root server 2.16.0 or greater)
		 */
		crouton_Handlebars.registerHelper('isInPersonOrHybrid', function(data, options) {
			return data['venue_type'] !== venueType.VIRTUAL && !inArray(getMasterFormatId('VM', data), getFormats(data)) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		/**
		 * Assumes consistent set of venue type formats (enforced for newly edited meetings in root server 2.16.0 or greater)
		 */
		crouton_Handlebars.registerHelper('isInPersonOnly', function(data, options) {
			return data['venue_type'] === venueType.IN_PERSON || (!inArray(getMasterFormatId('VM', data), getFormats(data))
				&& !inArray(getMasterFormatId('HY', data), getFormats(data))) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		/**
		 * Assumes consistent set of venue type formats (enforced for newly edited meetings in root server 2.16.0 or greater)
		 */
		crouton_Handlebars.registerHelper('isVirtualOrHybrid', function(data, options) {
			return (data['venue_type'] === venueType.VIRTUAL || data['venue_type'] === venueType.HYBRID) || inArray(getMasterFormatId('VM', data), getFormats(data))
				|| inArray(getMasterFormatId('HY', data), getFormats(data)) ? getTrueResult(options, this) : getFalseResult(options, this);
		});

		crouton_Handlebars.registerHelper('hasFormats', function(formats, data, options) {
			var allFound = false;
			var formatsResponse = data['formats'].split(",")
			var formatsParam = formats.split(",");
			for(var i = 0;i < formatsParam.length;i++) {
				allFound = inArray(formatsParam[i], formatsResponse);
			}

			return allFound ? getTrueResult(options, this) : getFalseResult(options, this);
		});
		crouton_Handlebars.registerHelper('temporarilyClosed', function(data, options) {
			if(data['formats_expanded'].getArrayItemByObjectKeyValue('id', getMasterFormatId('TC', data)) !== undefined) {
				return data['formats_expanded'].getArrayItemByObjectKeyValue('id', getMasterFormatId('TC', data))['description'];
			} else {
				return crouton.localization.getWord("FACILITY IS TEMPORARILY CLOSED");
			}
		});

		crouton_Handlebars.registerHelper('meetsVirtually', function(data, options) {
			if(data['formats_expanded'].getArrayItemByObjectKeyValue('id', getMasterFormatId('VM', data)) !== undefined) {
				return data['formats_expanded'].getArrayItemByObjectKeyValue('id', getMasterFormatId('VM', data))['description'];
			} else {
				return crouton.localization.getWord("MEETS VIRTUALLY");
			}
		});

		crouton_Handlebars.registerHelper('meetsHybrid', function(data, options) {
			if(data['formats_expanded'].getArrayItemByObjectKeyValue('id', getMasterFormatId('HY', data)) !== undefined) {
				return data['formats_expanded'].getArrayItemByObjectKeyValue('id', getMasterFormatId('HY', data))['description'];
			} else {
				return crouton.localization.getWord("MEETS VIRTUALLY AND IN PERSON");
			}
		});

		crouton_Handlebars.registerHelper('qrCode', function(link, options) {
			return new crouton_Handlebars.SafeString("<img alt='qrcode' src='https://quickchart.io/qr?size=100&text=" + encodeURIComponent(link) + "'>");
		});

		crouton_Handlebars.registerHelper('formatDataFromArray', function(arr) {
			var finalValues = [];
			for(var i = 0;i < arr.length;i++) {
				finalValues.push(convertToPunyCode(arr[i]));
			}

			return finalValues.join(" ");
		});

		crouton_Handlebars.registerHelper('formatDataPointerFormats', function(formatsExpanded) {
			var finalFormats = [];
			for(var i = 0;i < formatsExpanded.length;i++) {
				finalFormats.push(convertToPunyCode(formatsExpanded[i]['name']));
			}
			return finalFormats.join(" ");
		});

		crouton_Handlebars.registerHelper('formatDataKeyFormats', function(formatsExpanded) {
			var finalFormats = [];
			for(var i = 0;i < formatsExpanded.length;i++) {
				finalFormats.push(convertToPunyCode(formatsExpanded[i]['key']));
			}
			return finalFormats.join(" ");
		});

		crouton_Handlebars.registerHelper('formatLink', function(text) {
			if(text.indexOf('tel:') === 0 || text.indexOf('http') === 0) {
				return new crouton_Handlebars.SafeString("<a href='" + text + "' target='_blank'>" + text + "</a>");
			} else {
				return text;
			}
		});

		crouton_Handlebars.registerHelper('webLinkify', function(text) {
			return new crouton_Handlebars.SafeString("<a href='" + text + "' target='_blank'>" + text + "</a>");
		});

		crouton_Handlebars.registerHelper('phoneLinkify', function(text) {
			return new crouton_Handlebars.SafeString("<a href='tel:" + text + "' target='_blank'>" + text + "</a>");
		});

		crouton_Handlebars.registerHelper('ifEquals', function(arg1, arg2, options) {
			return (arg1 === arg2) ? options.fn(this) : options.inverse(this);
		});

		crouton_Handlebars.registerHelper('greaterThan', function(arg1, arg2, options) {
			return (arg1 > arg2) ? options.fn(this) : options.inverse(this);
		});

		crouton_Handlebars.registerHelper('lessThan', function(arg1, arg2, options) {
			return (arg1 < arg2) ? options.fn(this) : options.inverse(this);
		});

		crouton_Handlebars.registerHelper('times', function(n, block) {
			var accum = '';
			for(var i = 1;i <= n;++i)
				accum += block.fn(i);
			return accum;
		});
		crouton_Handlebars.registerHelper('hasObserverLine', function(name, phone, email) {
			if(name && name.length > 0) return true;
			if(phone && phone.length > 0) return true;
			if(email && email.length > 0) return true;
			return false;
		});
		crouton_Handlebars.registerHelper('hasBMLT2ics', function() {return crouton.config['bmlt2ics'].length > 0;});
		crouton_Handlebars.registerHelper('BMLT2ics', function() {return crouton.config['bmlt2ics'];});
		function getTrueResult(options, ctx) {
			return options.fn !== undefined ? options.fn(ctx) : true;
		}

		function getFalseResult(options, ctx) {
			return options.inverse !== undefined ? options.inverse(ctx) : false;
		}
	}
	CroutonHandlebarsExtensions.prototype.registerPartials = function(groups = false) {
		crouton_Handlebars.registerPartial('tableRows', hbs_Crouton.templates['tableRows']);
		crouton_Handlebars.registerPartial('meetingDetails', hbs_Crouton.templates['meetingDetails']);
		crouton_Handlebars.registerPartial("groupStackedRow", hbs_Crouton.templates['groupStackedRow']);
		crouton_Handlebars.registerPartial("meetingStackedRow", hbs_Crouton.templates['meetingStackedRow']);
		crouton_Handlebars.registerPartial('groupDetails', hbs_Crouton.templates['groupDetails']);
		crouton_Handlebars.registerPartial('bydays', hbs_Crouton.templates['byday']);
		crouton_Handlebars.registerPartial('weekdays', hbs_Crouton.templates['weekdays']);
		crouton_Handlebars.registerPartial('meetingsPlaceholders', hbs_Crouton.templates['meetingsPlaceholders']);
		crouton_Handlebars.registerPartial('header', hbs_Crouton.templates['header']);
		crouton_Handlebars.registerPartial('byfields', hbs_Crouton.templates['byfield']);
		crouton_Handlebars.registerPartial('formatPopup', hbs_Crouton.templates['formatPopup']);
		crouton_Handlebars.registerPartial('meetingModal', "<a tabindex='0' href='#' onclick='crouton.meetingModal({{this.id_bigint}})'><span class='glyphicon glyphicon-search' aria-hidden='true'></span>{{this.meeting_name}}</a>");
		crouton_Handlebars.registerPartial('meetingLink', `
			{{#if this.meeting_details_url}}
				<a href='{{{this.meeting_details_url}}}'><span class='glyphicon glyphicon-search' aria-hidden='true'></span>{{this.meeting_name}}</a>
			{{else}}
				{{this.meeting_name}}
			{{/if}}
		`);
		crouton_Handlebars.registerPartial('icsButton',
			'<a href="{{BMLT2ics}}?meeting-id={{id_bigint}}" download="{{meeting_name}}.ics" class="share-button btn btn-primary btn-xs" ><span class="glyphicon glyphicon-download-alt"></span> {{getWord "bmlt2ics"}}</a>');
		crouton_Handlebars.registerPartial('offerIcsButton', "{{#if (hasBMLT2ics)}}{{> icsButton}}<br/>{{/if}}");
		crouton_Handlebars.registerPartial('directionsButton', hbs_Crouton.templates['directionsButton']);
		crouton_Handlebars.registerPartial('attendVirtual', hbs_Crouton.templates['attendVirtual']);
		crouton_Handlebars.registerPartial('meetingDetailsButton', hbs_Crouton.templates['meetingDetailsButton']);
		crouton_Handlebars.registerPartial('distance', `
<div class='meeting-distance{{#unless this.distance}} hide{{/unless}}' data-id='{{this.id_bigint}}'>
{{getWord 'Distance'}}: {{this.distance}}
</div>`);
		crouton_Handlebars.registerPartial('formatDescriptions', `
			{{#if formats_expanded}}
            	<h4>{{getWord "Meeting Info"}}</h4>
            	<ul>
            		{{#each formats_expanded}}
                		<li>{{description}}</li>
            		{{/each}}
            	</ul>
            	<br/>
        	{{/if}}
		`);
		crouton_Handlebars.registerPartial('formatKeys', `
				{{#if this.formats}}
				<a
				   class="bmlt-formats btn btn-primary btn-xs"
				   title=""
				   data-html="true"
				   tabindex="0"
				   data-trigger="focus"
				   role="button"
				   data-toggle="popover"
				   data-original-title=""
				   data-placement="{{{getWord 'bootstrap-popover-placement'}}}"
				   data-content="{{> (selectFormatPopup) }}">
                    <span class="glyphicon glyphicon-search"
						  aria-hidden="true"
						  data-toggle="popover"
						  data-trigger="focus"
						  data-html="true"
						  role="button"></span>{{ this.formats }}
				</a>
			{{/if}}
			`
		)

		crouton_Handlebars.registerPartial('observerLine', `
{{#if (hasObserverLine name phone email) }}
<div class='observerLine'>{{getWord "Contact"}}: {{name}} <a href='tel:{{phone}}'>{{phone}}</a> <a href='mailto:{{email}}'>{{email}}</a></div>
</div>{{/if}}`);
	}
}

this["hbs_Crouton"] = this["hbs_Crouton"] || {};
this["hbs_Crouton"]["templates"] = this["hbs_Crouton"]["templates"] || {};
this["hbs_Crouton"]["templates"]["attendVirtual"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "            <h4>"
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(alias1,"Join this meeting online",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":2,"column":16},"end":{"line":2,"column":54}}}))
    + "</h4>\n"
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"virtual_meeting_link") : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":3,"column":12},"end":{"line":8,"column":19}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"phone_meeting_number") : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":9,"column":12},"end":{"line":14,"column":19}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"virtual_meeting_additional_info") : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":15,"column":12},"end":{"line":17,"column":19}}})) != null ? stack1 : "")
    + "            <br/>\n";
},"1":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "                <div>"
    + container.escapeExpression((lookupProperty(helpers,"webLinkify")||(depth0 && lookupProperty(depth0,"webLinkify"))||container.hooks.helperMissing).call(alias1,(depth0 != null ? lookupProperty(depth0,"virtual_meeting_link") : depth0),{"name":"webLinkify","hash":{},"data":data,"loc":{"start":{"line":4,"column":21},"end":{"line":4,"column":61}}}))
    + "</div>\n"
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"show_qrcode") : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":5,"column":16},"end":{"line":7,"column":23}}})) != null ? stack1 : "");
},"2":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "                    <div class=\"qrcode\">"
    + container.escapeExpression((lookupProperty(helpers,"qrCode")||(depth0 && lookupProperty(depth0,"qrCode"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? lookupProperty(depth0,"virtual_meeting_link") : depth0),{"name":"qrCode","hash":{},"data":data,"loc":{"start":{"line":6,"column":40},"end":{"line":6,"column":71}}}))
    + "</div>\n";
},"3":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "                <div>"
    + container.escapeExpression((lookupProperty(helpers,"phoneLinkify")||(depth0 && lookupProperty(depth0,"phoneLinkify"))||container.hooks.helperMissing).call(alias1,(depth0 != null ? lookupProperty(depth0,"phone_meeting_number") : depth0),{"name":"phoneLinkify","hash":{},"data":data,"loc":{"start":{"line":10,"column":21},"end":{"line":10,"column":63}}}))
    + "</div>\n"
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"show_qrcode") : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":11,"column":16},"end":{"line":13,"column":23}}})) != null ? stack1 : "");
},"4":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "                    <div class=\"qrcode\">"
    + container.escapeExpression((lookupProperty(helpers,"qrCode")||(depth0 && lookupProperty(depth0,"qrCode"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? lookupProperty(depth0,"phone_meeting_number") : depth0),{"name":"qrCode","hash":{},"data":data,"loc":{"start":{"line":12,"column":40},"end":{"line":12,"column":76}}}))
    + "</div>\n";
},"5":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "                "
    + container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"virtual_meeting_additional_info") : depth0), depth0))
    + "\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = (lookupProperty(helpers,"isVirtualOrHybrid")||(depth0 && lookupProperty(depth0,"isVirtualOrHybrid"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),depth0,{"name":"isVirtualOrHybrid","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":1,"column":8},"end":{"line":19,"column":30}}})) != null ? stack1 : "");
},"useData":true});
this["hbs_Crouton"]["templates"]["byday"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.lambda, alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "            <div class=\"meeting-group\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":3,"column":39},"end":{"line":3,"column":68}}})) != null ? stack1 : "")
    + ">\n                <div class=\"group-header\">"
    + alias4(alias3((depth0 != null ? lookupProperty(depth0,"day") : depth0), depth0))
    + "</div>\n                <div class=\"group-table-div\">\n                    <table class='bmlt-table table table-hover table-bordered tablesaw tablesaw-stack "
    + alias4((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":6,"column":102},"end":{"line":6,"column":129}}}))
    + "'>\n                        <tbody class=\"h-"
    + alias4(alias3((depth0 != null ? lookupProperty(depth0,"day") : depth0), depth0))
    + "\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingsPlaceholders"),(depth0 != null ? lookupProperty(depth0,"meetings") : depth0),{"name":"meetingsPlaceholders","data":data,"indent":"                            ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "                        </tbody>\n                    </table>\n                </div>\n            </div>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<div id=\"bmlt-table-div\">\n"
    + ((stack1 = lookupProperty(helpers,"each").call(depth0 != null ? depth0 : (container.nullContext || {}),depth0,{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":2,"column":8},"end":{"line":13,"column":17}}})) != null ? stack1 : "")
    + "</div>\n";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["byfield"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, helper, alias1=container.escapeExpression, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "            <div class=\"meeting-group "
    + alias1(container.lambda((depth0 != null ? lookupProperty(depth0,"accordionState") : depth0), depth0))
    + "\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":3,"column":63},"end":{"line":3,"column":92}}})) != null ? stack1 : "")
    + ">\n                <div class=\"group-header\">"
    + alias1(((helper = (helper = lookupProperty(helpers,"key") || (data && lookupProperty(data,"key"))) != null ? helper : alias3),(typeof helper === "function" ? helper.call(alias2,{"name":"key","hash":{},"data":data,"loc":{"start":{"line":4,"column":42},"end":{"line":4,"column":50}}}) : helper)))
    + "</div>\n                <div class=\"group-table-div\">\n					<table class='bmlt-table table table-hover table-bordered tablesaw tablesaw-stack "
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":6,"column":87},"end":{"line":6,"column":114}}}))
    + "'>\n                    	<tbody class=\"byfield.hbs\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingsPlaceholders"),(depth0 != null ? lookupProperty(depth0,"group") : depth0),{"name":"meetingsPlaceholders","data":data,"indent":"                        \t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "                    	</tbody>\n                	</table>\n				</div>\n            </div>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<div id=\"bmlt-table-div\">\n"
    + ((stack1 = lookupProperty(helpers,"each").call(depth0 != null ? depth0 : (container.nullContext || {}),depth0,{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":2,"column":8},"end":{"line":13,"column":17}}})) != null ? stack1 : "")
    + "    </table>\n</div>";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["directionsButton"] = Handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "            <div class=\"bootstrap-bmlt\">\n                <button data-latitude=\""
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"latitude") : depth0), depth0))
    + "\" data-longitude=\""
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"longitude") : depth0), depth0))
    + "\" class=\"btn btn-primary bmlt-xs get-directions-modal\">\n                    <span class=\"glyphicon glyphicon-road\"></span> "
    + alias2((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"get_directions",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":3,"column":67},"end":{"line":3,"column":95}}}))
    + "\n                </button>\n            </div>\n";
},"useData":true});
this["hbs_Crouton"]["templates"]["formatPopup"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3="function", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <tr>\n            <td class='formats_key'>"
    + alias4(((helper = (helper = lookupProperty(helpers,"key") || (depth0 != null ? lookupProperty(depth0,"key") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"key","hash":{},"data":data,"loc":{"start":{"line":4,"column":36},"end":{"line":4,"column":43}}}) : helper)))
    + "</td>\n            <td class='formats_name'>"
    + alias4(((helper = (helper = lookupProperty(helpers,"name") || (depth0 != null ? lookupProperty(depth0,"name") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data,"loc":{"start":{"line":5,"column":37},"end":{"line":5,"column":45}}}) : helper)))
    + "</td>\n            <td class='formats_description'>"
    + alias4(((helper = (helper = lookupProperty(helpers,"description") || (depth0 != null ? lookupProperty(depth0,"description") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"description","hash":{},"data":data,"loc":{"start":{"line":6,"column":44},"end":{"line":6,"column":59}}}) : helper)))
    + "</td>\n        </tr>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<table class='bmlt_a_format table-bordered "
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":1,"column":43},"end":{"line":1,"column":70}}}))
    + "'>\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"formats_expanded") : depth0),{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":2,"column":4},"end":{"line":8,"column":13}}})) != null ? stack1 : "")
    + "</table>";
},"useData":true});
this["hbs_Crouton"]["templates"]["group3ColumnRow"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=container.lambda, alias2=container.escapeExpression, alias3=depth0 != null ? depth0 : (container.nullContext || {}), alias4=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "				<a href=\"javascript:void(0);\" class=\"share-button btn btn-primary btn-xs\" onclick='navigator.share({ text: JSON.stringify(\""
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"formatted_day") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"start_time_formatted") : depth0), depth0))
    + " - "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"end_time_formatted") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"meeting_name") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"location_text") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"formatted_address") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"formatted_location_info") : depth0), depth0))
    + ((stack1 = lookupProperty(helpers,"if").call(alias3,(depth0 != null ? lookupProperty(depth0,"virtual_meeting_additional_info") : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":17,"column":314},"end":{"line":17,"column":406}}})) != null ? stack1 : "")
    + "\"), url: \""
    + ((stack1 = (lookupProperty(helpers,"isVirtualOrHybrid")||(depth0 && lookupProperty(depth0,"isVirtualOrHybrid"))||alias4).call(alias3,depth0,{"name":"isVirtualOrHybrid","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":17,"column":416},"end":{"line":17,"column":603}}})) != null ? stack1 : "")
    + ((stack1 = (lookupProperty(helpers,"isInPersonOrHybrid")||(depth0 && lookupProperty(depth0,"isInPersonOrHybrid"))||alias4).call(alias3,depth0,{"name":"isInPersonOrHybrid","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":17,"column":603},"end":{"line":17,"column":881}}})) != null ? stack1 : "")
    + "\"})'><span class=\"glyphicon glyphicon-share\"></span>  "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"share_word") : depth0), depth0))
    + "</a>\n";
},"1":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return " "
    + container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"virtual_meeting_additional_info") : depth0), depth0));
},"2":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"virtual_meeting_link") : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":17,"column":443},"end":{"line":17,"column":512}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"phone_meeting_number") : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":17,"column":512},"end":{"line":17,"column":581}}})) != null ? stack1 : "");
},"3":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"virtual_meeting_link") : depth0), depth0));
},"4":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"phone_meeting_number") : depth0), depth0));
},"5":function(container,depth0,helpers,partials,data) {
    var stack1, helper, options, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    }, buffer = 
  " ";
  stack1 = ((helper = (helper = lookupProperty(helpers,"isOS") || (depth0 != null ? lookupProperty(depth0,"isOS") : depth0)) != null ? helper : container.hooks.helperMissing),(options={"name":"isOS","hash":{},"fn":container.program(6, data, 0),"inverse":container.program(7, data, 0),"data":data,"loc":{"start":{"line":17,"column":632},"end":{"line":17,"column":858}}}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper));
  if (!lookupProperty(helpers,"isOS")) { stack1 = container.hooks.blockHelperMissing.call(depth0,stack1,options)}
  if (stack1 != null) { buffer += stack1; }
  return buffer;
},"6":function(container,depth0,helpers,partials,data) {
    var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return " https://maps.apple.com/?daddr="
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"latitude") : depth0), depth0))
    + ","
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"longitude") : depth0), depth0))
    + " ";
},"7":function(container,depth0,helpers,partials,data) {
    var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return " https://www.google.com/maps/search/?api=1&amp;query="
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"latitude") : depth0), depth0))
    + ","
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"longitude") : depth0), depth0))
    + "&amp;q="
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"latitude") : depth0), depth0))
    + ","
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"longitude") : depth0), depth0));
},"8":function(container,depth0,helpers,partials,data) {
    var helper, alias1=container.escapeExpression, alias2=container.lambda, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "				<a href=\""
    + alias1(((helper = (helper = lookupProperty(helpers,"reportUpdateUrl") || (depth0 != null ? lookupProperty(depth0,"reportUpdateUrl") : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"reportUpdateUrl","hash":{},"data":data,"loc":{"start":{"line":20,"column":13},"end":{"line":20,"column":34}}}) : helper)))
    + "?meeting_id="
    + alias1(alias2((depth0 != null ? lookupProperty(depth0,"id_bigint") : depth0), depth0))
    + "\" class=\"share-button btn btn-primary btn-xs edit-button\" target=\"_blank\"><span class=\"glyphicon glyphicon-edit\"></span> "
    + alias1(alias2((depth0 != null ? lookupProperty(depth0,"report_update_word") : depth0), depth0))
    + "</a>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.lambda, alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<td class=\"bmlt-column1\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":54}}})) != null ? stack1 : "")
    + ">\n			<div class='meeting-name'>\n				<a tabindex='0' href='#' onclick='crouton.meetingModal("
    + alias4(alias3((depth0 != null ? lookupProperty(depth0,"id_bigint") : depth0), depth0))
    + ")'><span class='glyphicon glyphicon-search' aria-hidden='true'></span>"
    + alias4(alias3((depth0 != null ? lookupProperty(depth0,"meeting_name") : depth0), depth0))
    + "</a>\n			</div>\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"formatKeys"),depth0,{"name":"formatKeys","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "			<div class=\"bmlt-comments\">"
    + alias4((lookupProperty(helpers,"formatLink")||(depth0 && lookupProperty(depth0,"formatLink"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"formatted_comments") : depth0),{"name":"formatLink","hash":{},"data":data,"loc":{"start":{"line":6,"column":30},"end":{"line":6,"column":68}}}))
    + "</div>\n			<div class=\"bmlt-observer\">"
    + ((stack1 = container.invokePartial((lookupProperty(helpers,"selectObserver")||(depth0 && lookupProperty(depth0,"selectObserver"))||alias2).call(alias1,{"name":"selectObserver","hash":{},"data":data,"loc":{"start":{"line":7,"column":34},"end":{"line":7,"column":50}}}),depth0,{"data":data,"helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "</div>\n		</td>\n		<td class=\"bmlt-column2\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":9,"column":27},"end":{"line":9,"column":56}}})) != null ? stack1 : "")
    + ">\n			<div class=\"meeting-data-template\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"groupData"),depth0,{"name":"groupData","data":data,"indent":"\t\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "			</div>\n		</td>\n		<td class=\"bmlt-column3\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"metaDataTemplate"),depth0,{"name":"metaDataTemplate","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + ((stack1 = (lookupProperty(helpers,"canShare")||(depth0 && lookupProperty(depth0,"canShare"))||alias2).call(alias1,depth0,{"name":"canShare","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":16,"column":3},"end":{"line":18,"column":16}}})) != null ? stack1 : "")
    + ((stack1 = (lookupProperty(helpers,"reportUpdateEnabled")||(depth0 && lookupProperty(depth0,"reportUpdateEnabled"))||alias2).call(alias1,depth0,{"name":"reportUpdateEnabled","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":19,"column":3},"end":{"line":21,"column":27}}})) != null ? stack1 : "")
    + ((stack1 = container.invokePartial(lookupProperty(partials,"offerIcsButton"),depth0,{"name":"offerIcsButton","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "		</td>\n";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["groupDetails"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "            	<div class=\"col-md-3 mb-2 box-shadow\">\n                    <div class=\"card-body\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"memberDetails"),depth0,{"name":"memberDetails","data":data,"indent":"                        ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "                    </div>\n                </div>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<div class=\"card group "
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":50}}}))
    + "\">\n    <div class=\"card-body\">\n        <div class=\"card-title header-elements\" style=\"display: flex; justify-content:space-between; align-items:center;\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"groupTitle"),depth0,{"name":"groupTitle","data":data,"indent":"            ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "        </div>\n        <div class=\"row\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":6,"column":25},"end":{"line":6,"column":54}}})) != null ? stack1 : "")
    + ">\n                <div class=\"col-md-4\">\n                    "
    + ((stack1 = ((helper = (helper = lookupProperty(helpers,"crouton_map") || (depth0 != null ? lookupProperty(depth0,"crouton_map") : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"crouton_map","hash":{},"data":data,"loc":{"start":{"line":8,"column":20},"end":{"line":8,"column":37}}}) : helper))) != null ? stack1 : "")
    + "\n                </div>\n                <div class=\"col-md-7 box-shadow\" style=\"margin-inline-start:10px;\">\n                    <div class=\"card-body\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"groupDetailsContents"),depth0,{"name":"groupDetailsContents","data":data,"indent":"                        ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "                    </div>\n                </div>\n        </div>\n        <div class=\"row card-meeting-row\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":16,"column":42},"end":{"line":16,"column":71}}})) != null ? stack1 : "")
    + ">\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"membersOfGroup") : depth0),{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":17,"column":12},"end":{"line":23,"column":21}}})) != null ? stack1 : "")
    + "        </div>\n    </div>\n</div>";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["groupStackedRow"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "            	<div class=\"col-md-3 mb-2 box-shadow\">\n                    <div class=\"card-body\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"memberDetails"),depth0,{"name":"memberDetails","data":data,"indent":"                        ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "                    </div>\n                </div>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<div class=\"card group\">\n    <div class=\"card-body\">\n        <div class=\"card-title header-elements\" style=\"display: flex; justify-content:space-between; align-items:center;\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"groupTitle"),depth0,{"name":"groupTitle","data":data,"indent":"            ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "        </div>\n        <div class=\"row\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":6,"column":25},"end":{"line":6,"column":54}}})) != null ? stack1 : "")
    + ">\n                <div class=\"col-md-8 box-shadow\" style=\"margin-inline-start:10px;\">\n                    <div class=\"card-body\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"groupDetailsContents"),depth0,{"name":"groupDetailsContents","data":data,"indent":"                        ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "                    </div>\n                </div>\n        </div>\n        <div class=\"row card-meeting-row\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":13,"column":42},"end":{"line":13,"column":71}}})) != null ? stack1 : "")
    + ">\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"membersOfGroup") : depth0),{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":14,"column":12},"end":{"line":20,"column":21}}})) != null ? stack1 : "")
    + "        </div>\n    </div>\n</div>";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["header"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data,blockParams,depths) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = lookupProperty(helpers,"if").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"include_weekday_button") : stack1),{"name":"if","hash":{},"fn":container.program(1, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":3,"column":4},"end":{"line":5,"column":11}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"grouping_buttons") : stack1),{"name":"each","hash":{},"fn":container.program(2, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":6,"column":4},"end":{"line":8,"column":13}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"formattype_grouping_buttons") : stack1),{"name":"each","hash":{},"fn":container.program(3, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":9,"column":4},"end":{"line":11,"column":13}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"map_page") : stack1),{"name":"if","hash":{},"fn":container.program(4, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":12,"column":4},"end":{"line":14,"column":11}}})) != null ? stack1 : "")
    + "\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,(depth0 != null ? lookupProperty(depth0,"dropdownData") : depth0),{"name":"each","hash":{},"fn":container.program(5, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":16,"column":4},"end":{"line":25,"column":13}}})) != null ? stack1 : "")
    + "    </div>\n";
},"1":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div class=\"bmlt-button-container\"><a id=\"day\" tabindex=0 class=\"btn btn-primary btn-sm\">"
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"weekday",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":4,"column":97},"end":{"line":4,"column":118}}}))
    + "</a></div>\n";
},"2":function(container,depth0,helpers,partials,data) {
    var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div class=\"bmlt-button-container\"><a id=\"groupingButton_"
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"field") : depth0), depth0))
    + "\" tabindex=0 data-field=\""
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"title") : depth0), depth0))
    + "\" class=\"groupingButton groupingButtonLogic btn btn-primary btn-sm\">"
    + alias2((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? lookupProperty(depth0,"title") : depth0),{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":7,"column":186},"end":{"line":7,"column":208}}}))
    + "</a></div>\n";
},"3":function(container,depth0,helpers,partials,data) {
    var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div class=\"bmlt-button-container\"><a id=\"groupingButton_"
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"field") : depth0), depth0))
    + "\"tabindex=0 data-field=\""
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"field") : depth0), depth0))
    + "\" class=\"groupingButton groupingButtonLogic btn btn-primary btn-sm\">"
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"title") : depth0), depth0))
    + "</a></div>\n";
},"4":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div class=\"bmlt-button-container\"><a id=\"groupingButton_embeddedMapPage\" tabindex=0 data-field=\"embeddedMapPage\" class=\"groupingButton btn btn-primary btn-sm\">"
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"map",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":13,"column":168},"end":{"line":13,"column":185}}}))
    + "</a></div>\n";
},"5":function(container,depth0,helpers,partials,data,blockParams,depths) {
    var stack1, helper, alias1=container.escapeExpression, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "	<div class=\"bmlt-dropdown-container\">\n		<select class=\"crouton-select filter-dropdown\" style=\"width:"
    + alias1(container.lambda(((stack1 = (depths[1] != null ? lookupProperty(depths[1],"config") : depths[1])) != null ? lookupProperty(stack1,"dropdown_width") : stack1), depth0))
    + ";\" data-placeholder=\""
    + alias1(((helper = (helper = lookupProperty(helpers,"placeholder") || (depth0 != null ? lookupProperty(depth0,"placeholder") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"placeholder","hash":{},"data":data,"loc":{"start":{"line":18,"column":116},"end":{"line":18,"column":131}}}) : helper)))
    + "\" data-pointer=\""
    + alias1(((helper = (helper = lookupProperty(helpers,"pointer") || (depth0 != null ? lookupProperty(depth0,"pointer") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"pointer","hash":{},"data":data,"loc":{"start":{"line":18,"column":147},"end":{"line":18,"column":158}}}) : helper)))
    + "\" id="
    + alias1(((helper = (helper = lookupProperty(helpers,"elementId") || (depth0 != null ? lookupProperty(depth0,"elementId") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"elementId","hash":{},"data":data,"loc":{"start":{"line":18,"column":163},"end":{"line":18,"column":176}}}) : helper)))
    + ">\n		    <option value=\"a-\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"all",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":19,"column":25},"end":{"line":19,"column":42}}}))
    + " "
    + alias1(((helper = (helper = lookupProperty(helpers,"placeholder") || (depth0 != null ? lookupProperty(depth0,"placeholder") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"placeholder","hash":{},"data":data,"loc":{"start":{"line":19,"column":43},"end":{"line":19,"column":58}}}) : helper)))
    + "</option>\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias2,(lookupProperty(helpers,"call")||(depth0 && lookupProperty(depth0,"call"))||alias3).call(alias2,(depth0 != null ? lookupProperty(depth0,"uniqueData") : depth0),((stack1 = (depths[1] != null ? lookupProperty(depths[1],"meetings") : depths[1])) != null ? lookupProperty(stack1,"meetingData") : stack1),{"name":"call","hash":{},"data":data,"loc":{"start":{"line":20,"column":14},"end":{"line":20,"column":55}}}),{"name":"each","hash":{},"fn":container.program(6, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":20,"column":6},"end":{"line":22,"column":15}}})) != null ? stack1 : "")
    + "		</select>\n	</div>\n";
},"6":function(container,depth0,helpers,partials,data,blockParams,depths) {
    var alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "			    <option value=\"a-"
    + alias3((lookupProperty(helpers,"call")||(depth0 && lookupProperty(depth0,"call"))||alias2).call(alias1,(depths[1] != null ? lookupProperty(depths[1],"objectPointer") : depths[1]),depth0,{"name":"call","hash":{},"data":data,"loc":{"start":{"line":21,"column":24},"end":{"line":21,"column":54}}}))
    + "\">"
    + alias3((lookupProperty(helpers,"call")||(depth0 && lookupProperty(depth0,"call"))||alias2).call(alias1,(depths[1] != null ? lookupProperty(depths[1],"optionName") : depths[1]),depth0,{"name":"call","hash":{},"data":data,"loc":{"start":{"line":21,"column":56},"end":{"line":21,"column":83}}}))
    + "</option>\n";
},"7":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = (lookupProperty(helpers,"ifEquals")||(depth0 && lookupProperty(depth0,"ifEquals"))||container.hooks.helperMissing).call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"view_by") : stack1),"weekdays",{"name":"ifEquals","hash":{},"fn":container.program(8, data, 0),"inverse":container.program(9, data, 0),"data":data,"loc":{"start":{"line":30,"column":4},"end":{"line":34,"column":17}}})) != null ? stack1 : "")
    + "        <ul class=\"nav nav-tabs\">\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"day_sequence") : stack1),{"name":"each","hash":{},"fn":container.program(10, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":36,"column":12},"end":{"line":38,"column":21}}})) != null ? stack1 : "")
    + "        </ul>\n    </div>\n";
},"8":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div class=\"bmlt-page "
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":31,"column":30},"end":{"line":31,"column":57}}}))
    + " show\" id=\"nav-days\">\n";
},"9":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div class=\"bmlt-page "
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":33,"column":30},"end":{"line":33,"column":57}}}))
    + " hide\" id=\"nav-days\">\n";
},"10":function(container,depth0,helpers,partials,data) {
    var alias1=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "                <li><a href=\"#tab"
    + alias1(container.lambda(depth0, depth0))
    + "\" data-toggle=\"tab\">"
    + alias1((lookupProperty(helpers,"getDayOfTheWeek")||(depth0 && lookupProperty(depth0,"getDayOfTheWeek"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),depth0,{"name":"getDayOfTheWeek","hash":{},"data":data,"loc":{"start":{"line":37,"column":61},"end":{"line":37,"column":85}}}))
    + "</a></li>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data,blockParams,depths) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return container.escapeExpression((lookupProperty(helpers,"startup")||(depth0 && lookupProperty(depth0,"startup"))||container.hooks.helperMissing).call(alias1,depth0,{"name":"startup","hash":{},"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}}))
    + "\n"
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"header") : stack1),{"name":"if","hash":{},"fn":container.program(0, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":2,"column":0},"end":{"line":27,"column":7}}})) != null ? stack1 : "")
    + "\n"
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"has_tabs") : stack1),{"name":"if","hash":{},"fn":container.program(7, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":29,"column":0},"end":{"line":41,"column":7}}})) != null ? stack1 : "");
},"useData":true,"useDepths":true});
this["hbs_Crouton"]["templates"]["main"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "		<div id=\"byfield_"
    + alias3(((helper = (helper = lookupProperty(helpers,"key") || (data && lookupProperty(data,"key"))) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data,"loc":{"start":{"line":6,"column":19},"end":{"line":6,"column":29}}}) : helper)))
    + "\" class=\"bmlt-page "
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":6,"column":48},"end":{"line":6,"column":75}}}))
    + " hide\" >\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"byfields"),depth0,{"name":"byfields","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "		</div>\n";
},"1":function(container,depth0,helpers,partials,data) {
    var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "		<div id=\"byfield_"
    + alias3(((helper = (helper = lookupProperty(helpers,"key") || (data && lookupProperty(data,"key"))) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"key","hash":{},"data":data,"loc":{"start":{"line":11,"column":19},"end":{"line":11,"column":29}}}) : helper)))
    + "\" class=\"bmlt-page "
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":11,"column":48},"end":{"line":11,"column":75}}}))
    + " hide\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"byfields"),depth0,{"name":"byfields","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "		</div>\n";
},"2":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "    	<div id=\"byfield_embeddedMapPage\" class=\"bmlt-map bmlt-page "
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":16,"column":65},"end":{"line":16,"column":92}}}))
    + " hide\">\n		</div>\n";
},"3":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div id=\"bmlt_incubator\" class=\"bmlt-page "
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":20,"column":50},"end":{"line":20,"column":77}}}))
    + " hide\">\n            <table class='bmlt-table table table-hover table-bordered tablesaw tablesaw-stack "
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":21,"column":94},"end":{"line":21,"column":121}}}))
    + "'>\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"tableRows"),((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"allMeetings") : stack1),{"name":"tableRows","data":data,"indent":"                ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "            </table>\n        </div>\n";
},"4":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div id=\"byday\" class=\"bmlt-page "
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":26,"column":41},"end":{"line":26,"column":68}}}))
    + " hide\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"bydays"),((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"bydays") : stack1),{"name":"bydays","data":data,"indent":"            ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "        </div>\n        <div id=\"tabs-content\" class=\"bmlt-page "
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":29,"column":48},"end":{"line":29,"column":75}}}))
    + "\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"weekdays"),((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"weekdays") : stack1),{"name":"weekdays","data":data,"indent":"            ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "        </div>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<div id=\"bmlt-tabs-table\">\n    <div id=\"bmlt-header\" class=\"bmlt-header "
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":2,"column":45},"end":{"line":2,"column":72}}}))
    + " hide\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"header"),depth0,{"name":"header","data":data,"indent":"        ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "    </div>\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"groupingButtons") : stack1),{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":5,"column":1},"end":{"line":9,"column":10}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"each").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"formattypeGroupingButtons") : stack1),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":10,"column":4},"end":{"line":14,"column":10}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"map_page") : stack1),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":15,"column":4},"end":{"line":18,"column":11}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"config") : depth0)) != null ? lookupProperty(stack1,"groups") : stack1),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.program(4, data, 0),"data":data,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":11}}})) != null ? stack1 : "")
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingCountTemplate"),depth0,{"name":"meetingCountTemplate","data":data,"indent":"    ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "</div>\n";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["mapMenu"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <button id=\"filterMeetings\" style=\"display: block;\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Filter meetings",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":9,"column":60},"end":{"line":9,"column":89}}}))
    + "</button>\n        <button id=\"showAsTable\" style=\"display: block;\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"visible meeting list",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":10,"column":57},"end":{"line":10,"column":91}}}))
    + "</button>\n";
},"1":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <button id=\"filterTable\" style=\"display: block;\"><span id=\"filteringByVisibility\"></span>"
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"filter by visibility",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":12,"column":97},"end":{"line":12,"column":131}}}))
    + "</button>\n";
},"2":function(container,depth0,helpers,partials,data,blockParams,depths) {
    var stack1, helper, alias1=container.escapeExpression, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, alias4="function", lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "	        <div class=\"bmlt-dropdown-container\">\n		        <select class=\"crouton-select filter-dropdown\" style=\"width:"
    + alias1(container.lambda(((stack1 = (depths[1] != null ? lookupProperty(depths[1],"config") : depths[1])) != null ? lookupProperty(stack1,"dropdown_width") : stack1), depth0))
    + ";\" data-placeholder=\""
    + alias1(((helper = (helper = lookupProperty(helpers,"placeholder") || (depth0 != null ? lookupProperty(depth0,"placeholder") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"placeholder","hash":{},"data":data,"loc":{"start":{"line":21,"column":124},"end":{"line":21,"column":139}}}) : helper)))
    + "\" data-pointer=\""
    + alias1(((helper = (helper = lookupProperty(helpers,"pointer") || (depth0 != null ? lookupProperty(depth0,"pointer") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"pointer","hash":{},"data":data,"loc":{"start":{"line":21,"column":155},"end":{"line":21,"column":166}}}) : helper)))
    + "\" id="
    + alias1(((helper = (helper = lookupProperty(helpers,"elementId") || (depth0 != null ? lookupProperty(depth0,"elementId") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"elementId","hash":{},"data":data,"loc":{"start":{"line":21,"column":171},"end":{"line":21,"column":184}}}) : helper)))
    + ">\n		            <option value=\"a-\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"all",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":22,"column":33},"end":{"line":22,"column":50}}}))
    + " "
    + alias1(((helper = (helper = lookupProperty(helpers,"placeholder") || (depth0 != null ? lookupProperty(depth0,"placeholder") : depth0)) != null ? helper : alias3),(typeof helper === alias4 ? helper.call(alias2,{"name":"placeholder","hash":{},"data":data,"loc":{"start":{"line":22,"column":51},"end":{"line":22,"column":66}}}) : helper)))
    + "</option>\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias2,(lookupProperty(helpers,"call")||(depth0 && lookupProperty(depth0,"call"))||alias3).call(alias2,(depth0 != null ? lookupProperty(depth0,"uniqueData") : depth0),((stack1 = (depths[1] != null ? lookupProperty(depths[1],"meetings") : depths[1])) != null ? lookupProperty(stack1,"meetingData") : stack1),{"name":"call","hash":{},"data":data,"loc":{"start":{"line":23,"column":22},"end":{"line":23,"column":63}}}),{"name":"each","hash":{},"fn":container.program(3, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":23,"column":14},"end":{"line":25,"column":23}}})) != null ? stack1 : "")
    + "		        </select>\n	        </div>\n";
},"3":function(container,depth0,helpers,partials,data,blockParams,depths) {
    var alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "			            <option value=\"a-"
    + alias3((lookupProperty(helpers,"call")||(depth0 && lookupProperty(depth0,"call"))||alias2).call(alias1,(depths[1] != null ? lookupProperty(depths[1],"objectPointer") : depths[1]),depth0,{"name":"call","hash":{},"data":data,"loc":{"start":{"line":24,"column":32},"end":{"line":24,"column":62}}}))
    + "\">"
    + alias3((lookupProperty(helpers,"call")||(depth0 && lookupProperty(depth0,"call"))||alias2).call(alias1,(depths[1] != null ? lookupProperty(depths[1],"optionName") : depths[1]),depth0,{"name":"call","hash":{},"data":data,"loc":{"start":{"line":24,"column":64},"end":{"line":24,"column":91}}}))
    + "</option>\n";
},"4":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = container.invokePartial(lookupProperty(partials,"tableRows"),(depth0 != null ? lookupProperty(depth0,"meetings") : depth0),{"name":"tableRows","data":data,"indent":"            ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data,blockParams,depths) {
    var stack1, alias1=container.escapeExpression, alias2=depth0 != null ? depth0 : (container.nullContext || {}), alias3=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<button id=\"map-menu-button\" class=\"menu-button\" title=\"Erweiterte Suche\" style=\"width: 95px;\">\n    <span class=\"menu-button-childSmall\" style=\"background-image: url('"
    + alias1(container.lambda((depth0 != null ? lookupProperty(depth0,"menuImage") : depth0), depth0))
    + "');\"></span>\n    <span class=\"menu-button-label\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"Menu",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":3,"column":36},"end":{"line":3,"column":54}}}))
    + "</span>\n</button>\n    <div id=\"map-menu-dropdown\" class=\"menu-dropdown\">\n        <button id=\"lookupLocation\" style=\"display: block;\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"Show meetings near...",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":6,"column":60},"end":{"line":6,"column":95}}}))
    + "</button>\n        <button id=\"nearbyMeetings\" style=\"display: block;\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"near_me",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":7,"column":60},"end":{"line":7,"column":81}}}))
    + "</button>\n"
    + ((stack1 = lookupProperty(helpers,"if").call(alias2,(depth0 != null ? lookupProperty(depth0,"dropdownData") : depth0),{"name":"if","hash":{},"fn":container.program(0, data, 0, blockParams, depths),"inverse":container.program(1, data, 0, blockParams, depths),"data":data,"loc":{"start":{"line":8,"column":8},"end":{"line":13,"column":15}}})) != null ? stack1 : "")
    + "        <button id=\"fullscreenMode\" style=\"display: block;\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"Toggle fullscreen mode",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":14,"column":60},"end":{"line":14,"column":96}}}))
    + "</button>\n    </div>\n<div id=\"filter_modal\" class=\"modal\" style=\"display: none;\">\n	<div class=\"modal-content\">\n        <span class=\"modal-title\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"Filter meetings",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":18,"column":34},"end":{"line":18,"column":63}}}))
    + "</span><span id=\"close_filter\" class=\"modal-close\">×</span>\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias2,(depth0 != null ? lookupProperty(depth0,"dropdownData") : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":19,"column":8},"end":{"line":28,"column":17}}})) != null ? stack1 : "")
    + "    </div>\n</div>\n<div id=\"table_page\" class=\"bmlt-page "
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":31,"column":38},"end":{"line":31,"column":65}}}))
    + " hide\" >\n    <div id=\"bmlt-maptable-header\"><span class=\"map-list-title\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"Visible meeting list",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":32,"column":64},"end":{"line":32,"column":98}}}))
    + "</span><span id=\"close_table\" class=\"table-close\">X</span></div>\n    <div id=\"bmlt-maptable-div\"  style=\"position:relative; overflow-y:scroll;\">\n\n        <table class='bmlt-table table table-striped table-hover table-bordered tablesaw tablesaw-stack "
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":35,"column":104},"end":{"line":35,"column":131}}}))
    + "'>\n"
    + ((stack1 = lookupProperty(helpers,"each").call(alias2,((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"bydays") : stack1),{"name":"each","hash":{},"fn":container.program(4, data, 0, blockParams, depths),"inverse":container.noop,"data":data,"loc":{"start":{"line":36,"column":8},"end":{"line":38,"column":17}}})) != null ? stack1 : "")
    + "        </table>\n    </div>\n</div>\n<div id=\"geocoding_modal\" class=\"modal\" style=\"display: none;\">\n	<div id=\"search_content\" class=\"modal-content\">\n		<span class=\"modal-title\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"Show meetings near...",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":44,"column":28},"end":{"line":44,"column":63}}}))
    + "</span><span id=\"close_search\" class=\"modal-close\">x</span>\n        <p></p>\n        <div class=\"modal-search\">\n            "
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"Enter a city or zip code",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":47,"column":12},"end":{"line":47,"column":50}}}))
    + "\n            <input id=\"goto-text\" type=\"text\">\n            <button id=\"goto-button\" class=\"filter-button\">"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias3).call(alias2,"go",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":49,"column":59},"end":{"line":49,"column":75}}}))
    + "</button>\n        </div>\n  	</div>\n</div>\n\n";
},"usePartial":true,"useData":true,"useDepths":true});
this["hbs_Crouton"]["templates"]["mapSearch"] = Handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<button id=\"map-search-button\" class=\"menu-button\" title=\""
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Open Search Dialog",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":1,"column":58},"end":{"line":1,"column":90}}}))
    + "\">\n    <span class=\"menu-button-label\" style=\"position:initial;\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Search for meetings",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":2,"column":62},"end":{"line":2,"column":95}}}))
    + "</span>\n</button>\n<div id=\"bmltsearch_modal\" class=\"modal\" style=\"display: none;\">\n    <div id=\"bmltsearch_content\" class=\"modal-content\">\n        <span id=\"close_search\" class=\"modal-close\">x</span>\n        <div id=\"modal-search-page\">\n            <div class=\"modal-title\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Search for meetings",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":8,"column":37},"end":{"line":8,"column":70}}}))
    + "</div>\n            <div id=\"zoomed-out-message\" class=\"hide\">\n                <p>"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"zoomed-out-message",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":10,"column":19},"end":{"line":10,"column":51}}}))
    + "</p>\n            </div>\n            <div id=\"modal-search-box\" class=\"modal-search\">\n                <input id=\"bmltsearch-goto-text\" type=\"text\"\n                    placeholder=\""
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Enter a city or zip code",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":14,"column":33},"end":{"line":14,"column":71}}}))
    + "\" style=\"margin-bottom:5px;\">\n                <button id=\"bmltsearch-text-button\" class=\"filter-button\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"text_search",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":15,"column":74},"end":{"line":15,"column":99}}}))
    + "</button>\n            </div>\n            <div class=\"modal-search\">\n                <button id=\"bmltsearch-nearbyMeetings\" class=\"filter-button\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"near_me",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":18,"column":77},"end":{"line":18,"column":98}}}))
    + "</button>\n            </div>\n            <div class=\"modal-search\">\n                <button id=\"bmltsearch-clicksearch\" class=\"filter-button\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"click_search",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":21,"column":74},"end":{"line":21,"column":100}}}))
    + "</button>\n            </div>\n            <button id=\"show-search-parameters\" class=\"advanced-search-button\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Adjust Search",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":23,"column":79},"end":{"line":23,"column":106}}}))
    + "</button>\n        </div>\n        <div id=\"modal-seach-parameters\">\n            <div class=\"modal-title\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Adjust Search",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":26,"column":37},"end":{"line":26,"column":64}}}))
    + "</div>\n            <input type=\"number\" id=\"search_parameter\" name=\"search_parameter\" maxlength=\"3\" size=\"3\">\n            <p>"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"This number represents",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":28,"column":15},"end":{"line":28,"column":51}}}))
    + ":</p>\n            <input type=\"radio\" id=\"search_radius\" name=\"map_search_type\" value=\"radius\">\n            <label id=\"search_radius_label\" for=\"search_radius\"></label><br>\n            <input type=\"radio\" id=\"search_count\" name=\"map_search_type\" value=\"count\">\n            <label for=\"search_count\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Approx. number of meetings in result",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":32,"column":38},"end":{"line":32,"column":88}}}))
    + "</label><br>\n            <button id=\"show-search-page\" class=\"advanced-search-button\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Back",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":33,"column":73},"end":{"line":33,"column":91}}}))
    + "</button>\n        </div>\n    </div>\n</div>";
},"useData":true});
this["hbs_Crouton"]["templates"]["meeting3ColumnRow"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=container.lambda, alias2=container.escapeExpression, alias3=depth0 != null ? depth0 : (container.nullContext || {}), alias4=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "				<a href=\"javascript:void(0);\" class=\"share-button btn btn-primary btn-xs\" onclick='navigator.share({ text: JSON.stringify(\""
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"formatted_day") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"start_time_formatted") : depth0), depth0))
    + " - "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"end_time_formatted") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"meeting_name") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"location_text") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"formatted_address") : depth0), depth0))
    + " "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"formatted_location_info") : depth0), depth0))
    + ((stack1 = lookupProperty(helpers,"if").call(alias3,(depth0 != null ? lookupProperty(depth0,"virtual_meeting_additional_info") : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":12,"column":314},"end":{"line":12,"column":406}}})) != null ? stack1 : "")
    + "\"), url: \""
    + ((stack1 = (lookupProperty(helpers,"isVirtualOrHybrid")||(depth0 && lookupProperty(depth0,"isVirtualOrHybrid"))||alias4).call(alias3,depth0,{"name":"isVirtualOrHybrid","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":12,"column":416},"end":{"line":12,"column":603}}})) != null ? stack1 : "")
    + ((stack1 = (lookupProperty(helpers,"isInPersonOrHybrid")||(depth0 && lookupProperty(depth0,"isInPersonOrHybrid"))||alias4).call(alias3,depth0,{"name":"isInPersonOrHybrid","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":12,"column":603},"end":{"line":12,"column":881}}})) != null ? stack1 : "")
    + "\"})'><span class=\"glyphicon glyphicon-share\"></span>  "
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"share_word") : depth0), depth0))
    + "</a>\n";
},"1":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return " "
    + container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"virtual_meeting_additional_info") : depth0), depth0));
},"2":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"virtual_meeting_link") : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":12,"column":443},"end":{"line":12,"column":512}}})) != null ? stack1 : "")
    + ((stack1 = lookupProperty(helpers,"if").call(alias1,(depth0 != null ? lookupProperty(depth0,"phone_meeting_number") : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":12,"column":512},"end":{"line":12,"column":581}}})) != null ? stack1 : "");
},"3":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"virtual_meeting_link") : depth0), depth0));
},"4":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"phone_meeting_number") : depth0), depth0));
},"5":function(container,depth0,helpers,partials,data) {
    var stack1, helper, options, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    }, buffer = 
  " ";
  stack1 = ((helper = (helper = lookupProperty(helpers,"isOS") || (depth0 != null ? lookupProperty(depth0,"isOS") : depth0)) != null ? helper : container.hooks.helperMissing),(options={"name":"isOS","hash":{},"fn":container.program(6, data, 0),"inverse":container.program(7, data, 0),"data":data,"loc":{"start":{"line":12,"column":632},"end":{"line":12,"column":858}}}),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),options) : helper));
  if (!lookupProperty(helpers,"isOS")) { stack1 = container.hooks.blockHelperMissing.call(depth0,stack1,options)}
  if (stack1 != null) { buffer += stack1; }
  return buffer;
},"6":function(container,depth0,helpers,partials,data) {
    var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return " https://maps.apple.com/?daddr="
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"latitude") : depth0), depth0))
    + ","
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"longitude") : depth0), depth0))
    + " ";
},"7":function(container,depth0,helpers,partials,data) {
    var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return " https://www.google.com/maps/search/?api=1&amp;query="
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"latitude") : depth0), depth0))
    + ","
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"longitude") : depth0), depth0))
    + "&amp;q="
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"latitude") : depth0), depth0))
    + ","
    + alias2(alias1((depth0 != null ? lookupProperty(depth0,"longitude") : depth0), depth0));
},"8":function(container,depth0,helpers,partials,data) {
    var helper, alias1=container.escapeExpression, alias2=container.lambda, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "				<a href=\""
    + alias1(((helper = (helper = lookupProperty(helpers,"reportUpdateUrl") || (depth0 != null ? lookupProperty(depth0,"reportUpdateUrl") : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"reportUpdateUrl","hash":{},"data":data,"loc":{"start":{"line":15,"column":13},"end":{"line":15,"column":34}}}) : helper)))
    + "?meeting_id="
    + alias1(alias2((depth0 != null ? lookupProperty(depth0,"id_bigint") : depth0), depth0))
    + "\" class=\"share-button btn btn-primary btn-xs edit-button\" target=\"_blank\"><span class=\"glyphicon glyphicon-edit\"></span> "
    + alias1(alias2((depth0 != null ? lookupProperty(depth0,"report_update_word") : depth0), depth0))
    + "</a>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "		<td class=\"bmlt-column1\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":56}}})) != null ? stack1 : "")
    + ">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingTimesTemplate"),depth0,{"name":"meetingTimesTemplate","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "		</td>\n		<td class=\"bmlt-column2\" "
    + ((stack1 = (lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-textAlign",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":4,"column":27},"end":{"line":4,"column":56}}})) != null ? stack1 : "")
    + ">\n			<div class=\"meeting-data-template\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingDataTemplate"),depth0,{"name":"meetingDataTemplate","data":data,"indent":"\t\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "			</div>\n		</td>\n		<td class=\"bmlt-column3\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"metaDataTemplate"),depth0,{"name":"metaDataTemplate","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + ((stack1 = (lookupProperty(helpers,"canShare")||(depth0 && lookupProperty(depth0,"canShare"))||alias2).call(alias1,depth0,{"name":"canShare","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":11,"column":3},"end":{"line":13,"column":16}}})) != null ? stack1 : "")
    + ((stack1 = (lookupProperty(helpers,"reportUpdateEnabled")||(depth0 && lookupProperty(depth0,"reportUpdateEnabled"))||alias2).call(alias1,depth0,{"name":"reportUpdateEnabled","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":14,"column":3},"end":{"line":16,"column":27}}})) != null ? stack1 : "")
    + ((stack1 = container.invokePartial(lookupProperty(partials,"offerIcsButton"),depth0,{"name":"offerIcsButton","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "		</td>";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["meetingDetails"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, helper, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "                        <td id=\"meetingpage_map_td\">"
    + ((stack1 = ((helper = (helper = lookupProperty(helpers,"crouton_map") || (depth0 != null ? lookupProperty(depth0,"crouton_map") : depth0)) != null ? helper : container.hooks.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"crouton_map","hash":{},"data":data,"loc":{"start":{"line":11,"column":52},"end":{"line":11,"column":69}}}) : helper))) != null ? stack1 : "")
    + "</td>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "\n		<table id=\"meeting-details-table\" class=\"bmlt-table  "
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":2,"column":55},"end":{"line":2,"column":82}}}))
    + " table table-striped table-hover table-bordered tablesaw tablesaw-stack meeting-details\">\n			<thead>\n        		<th id=\"meeting-details-title\" colspan=\"2\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingpageTitleTemplate"),depth0,{"name":"meetingpageTitleTemplate","data":data,"indent":"\t\t    \t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "	    		</th>\n    		</thead>\n    		<tbody>\n        		<tr id=\"meeting-details-contents\">\n"
    + ((stack1 = (lookupProperty(helpers,"isInPersonOrHybrid")||(depth0 && lookupProperty(depth0,"isInPersonOrHybrid"))||alias2).call(alias1,depth0,{"name":"isInPersonOrHybrid","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":10,"column":20},"end":{"line":12,"column":43}}})) != null ? stack1 : "")
    + "                    <td style=\"vertical-align:top;\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingDetailsContentsTemplate"),depth0,{"name":"meetingDetailsContentsTemplate","data":data,"indent":"           \t\t\t    ","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "                    </td>\n        		</tr>\n    		</tbody>\n		</table>";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["meetingDetailsButton"] = Handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var alias1=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "            <div>\n		        <a onclick='crouton.meetingModal("
    + alias1(container.lambda((depth0 != null ? lookupProperty(depth0,"id_bigint") : depth0), depth0))
    + ")' tabindex='0' href='#' class='map-button btn btn-primary btn-xs'>\n				    <span class='glyphicon glyphicon-search' aria-hidden='true'></span>\n					"
    + alias1((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"meeting details",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":4,"column":5},"end":{"line":4,"column":34}}}))
    + "\n				</a>\n		    </div>\n";
},"useData":true});
this["hbs_Crouton"]["templates"]["meetingModal"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    return "group-modal";
},"1":function(container,depth0,helpers,partials,data) {
    return "meeting-modal";
},"2":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = container.invokePartial(lookupProperty(partials,"groupDetails"),depth0,{"name":"groupDetails","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
},"3":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = container.invokePartial(lookupProperty(partials,"meetingDetails"),depth0,{"name":"meetingDetails","data":data,"indent":"\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "\n	<div id=\"meeting_modal\" class=\"modal bootstrap-bmlt\" style=\"display: none;\" tabindex=\"-1\" >\n	<div class=\"modal-content "
    + ((stack1 = (lookupProperty(helpers,"ifGroup")||(depth0 && lookupProperty(depth0,"ifGroup"))||alias2).call(alias1,depth0,{"name":"ifGroup","hash":{},"fn":container.program(0, data, 0),"inverse":container.program(1, data, 0),"data":data,"loc":{"start":{"line":3,"column":27},"end":{"line":3,"column":88}}})) != null ? stack1 : "")
    + "\">\n        <span class=\"modal-title\">"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Meeting Details",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":4,"column":34},"end":{"line":4,"column":63}}}))
    + "</span><span id=\"close_meeting_details\" class=\"modal-close\" style=\"position: absolute;right: 5px;top:10px;\">x</span>\n"
    + ((stack1 = (lookupProperty(helpers,"ifGroup")||(depth0 && lookupProperty(depth0,"ifGroup"))||alias2).call(alias1,depth0,{"name":"ifGroup","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(3, data, 0),"data":data,"loc":{"start":{"line":5,"column":8},"end":{"line":9,"column":14}}})) != null ? stack1 : "")
    + "		<div>\n			<a class=\"map-button btn btn-primary btn-xs\" href=\""
    + ((stack1 = container.lambda((depth0 != null ? lookupProperty(depth0,"meeting_details_url") : depth0), depth0)) != null ? stack1 : "")
    + "\" tabindex=\"0\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"float:left\">\n				"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Meeting Page",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":12,"column":4},"end":{"line":12,"column":30}}}))
    + "</a>\n			<a class=\"map-button btn btn-primary btn-xs modal-close\" tabindex=\"0\" style=\"float:right\">\n				"
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"Close",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":14,"column":4},"end":{"line":14,"column":23}}}))
    + "</a>\n		</div>\n		<div class=\"swipe-buttons\">\n			<span class=\"modal-right\">&gt;</span>\n			<span class=\"modal-left\">&lt;</span>\n		</div>\n	</div></div>";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["meetingStackedRow"] = Handlebars.template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "\n            <h4>\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingpageTitleTemplate"),depth0,{"name":"meetingpageTitleTemplate","data":data,"indent":"\t\t    \t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "            </h4>\n        	<div class=\"meeting-details-contents\" style=\"vertical-align:top;\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"meetingDetailsContentsTemplate"),depth0,{"name":"meetingDetailsContentsTemplate","data":data,"indent":"           \t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "            </div>";
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["meetingsPlaceholders"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<tr class=\"bmlt-data-row-placeholder hide\" data-meetingId=\"meeting-data-row-"
    + container.escapeExpression(container.lambda((depth0 != null ? lookupProperty(depth0,"id_bigint") : depth0), depth0))
    + "\">\n    <td class=\"bmlt-column-placeholder hide\" colspan=\"3\"></td>\n</tr>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = lookupProperty(helpers,"each").call(depth0 != null ? depth0 : (container.nullContext || {}),depth0,{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":5,"column":9}}})) != null ? stack1 : "");
},"useData":true});
this["hbs_Crouton"]["templates"]["tableRows"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "	"
    + alias3((lookupProperty(helpers,"enrich")||(depth0 && lookupProperty(depth0,"enrich"))||alias2).call(alias1,depth0,{"name":"enrich","hash":{},"data":data,"loc":{"start":{"line":2,"column":1},"end":{"line":2,"column":16}}}))
    + "\n	<tr class=\"bmlt-data-row\"\n		id=\"meeting-data-row-"
    + alias3(container.lambda((depth0 != null ? lookupProperty(depth0,"id_bigint") : depth0), depth0))
    + "\"\n		data-cities=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"location_municipality") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":5,"column":15},"end":{"line":5,"column":63}}}))
    + "\"\n		data-groups=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"meeting_name") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":6,"column":15},"end":{"line":6,"column":54}}}))
    + "\"\n		data-locations=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"location_text") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":7,"column":18},"end":{"line":7,"column":58}}}))
    + "\"\n		data-zips=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"location_postal_code_1") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":8,"column":13},"end":{"line":8,"column":62}}}))
    + "\"\n		data-formats=\""
    + alias3((lookupProperty(helpers,"formatDataPointerFormats")||(depth0 && lookupProperty(depth0,"formatDataPointerFormats"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"formats_expanded") : depth0),{"name":"formatDataPointerFormats","hash":{},"data":data,"loc":{"start":{"line":9,"column":16},"end":{"line":9,"column":66}}}))
    + "\"\n		data-areas=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"service_body_bigint") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":10,"column":14},"end":{"line":10,"column":60}}}))
    + "\"\n		data-regions=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"parentServiceBodyName") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":11,"column":16},"end":{"line":11,"column":64}}}))
    + "\"\n		data-counties=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"location_sub_province") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":12,"column":17},"end":{"line":12,"column":65}}}))
    + "\"\n		data-neighborhoods=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"location_neighborhood") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":13,"column":22},"end":{"line":13,"column":70}}}))
    + "\"\n		data-states=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"location_province") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":14,"column":15},"end":{"line":14,"column":59}}}))
    + "\"\n		data-venues=\""
    + alias3((lookupProperty(helpers,"formatDataFromArray")||(depth0 && lookupProperty(depth0,"formatDataFromArray"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"venue_type_name") : depth0),{"name":"formatDataFromArray","hash":{},"data":data,"loc":{"start":{"line":15,"column":15},"end":{"line":15,"column":59}}}))
    + "\"\n		data-weekdays=\""
    + alias3((lookupProperty(helpers,"formatDataPointer")||(depth0 && lookupProperty(depth0,"formatDataPointer"))||alias2).call(alias1,(depth0 != null ? lookupProperty(depth0,"formatted_day") : depth0),{"name":"formatDataPointer","hash":{},"data":data,"loc":{"start":{"line":16,"column":17},"end":{"line":16,"column":57}}}))
    + "\">\n"
    + ((stack1 = container.invokePartial(lookupProperty(partials,"tableDataRow"),depth0,{"name":"tableDataRow","data":data,"indent":"\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "")
    + "	</tr>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = lookupProperty(helpers,"each").call(depth0 != null ? depth0 : (container.nullContext || {}),depth0,{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":19,"column":9}}})) != null ? stack1 : "");
},"usePartial":true,"useData":true});
this["hbs_Crouton"]["templates"]["weekdays"] = Handlebars.template({"0":function(container,depth0,helpers,partials,data) {
    var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "        <div id='tab"
    + alias3(((helper = (helper = lookupProperty(helpers,"day") || (depth0 != null ? lookupProperty(depth0,"day") : depth0)) != null ? helper : alias2),(typeof helper === "function" ? helper.call(alias1,{"name":"day","hash":{},"data":data,"loc":{"start":{"line":3,"column":20},"end":{"line":3,"column":29}}}) : helper)))
    + "' class='tab-pane'>\n            <div id=\"bmlt-table-div\">\n                <table class='bmlt-table table table-hover table-bordered tablesaw tablesaw-stack "
    + alias3((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||alias2).call(alias1,"css-direction",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":5,"column":98},"end":{"line":5,"column":125}}}))
    + "'>\n                    <tbody class=\"weekdays.hbs\">\n"
    + ((stack1 = (lookupProperty(helpers,"greaterThan")||(depth0 && lookupProperty(depth0,"greaterThan"))||alias2).call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"length") : stack1),0,{"name":"greaterThan","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":7,"column":6},"end":{"line":9,"column":22}}})) != null ? stack1 : "")
    + ((stack1 = (lookupProperty(helpers,"lessThan")||(depth0 && lookupProperty(depth0,"lessThan"))||alias2).call(alias1,((stack1 = (depth0 != null ? lookupProperty(depth0,"meetings") : depth0)) != null ? lookupProperty(stack1,"length") : stack1),1,{"name":"lessThan","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":10,"column":6},"end":{"line":16,"column":19}}})) != null ? stack1 : "")
    + "                    </tbody>\n                </table>\n            </div>\n        </div>\n";
},"1":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return ((stack1 = container.invokePartial(lookupProperty(partials,"tableRows"),(depth0 != null ? lookupProperty(depth0,"meetings") : depth0),{"name":"tableRows","data":data,"indent":"\t\t\t\t\t\t\t","helpers":helpers,"partials":partials,"decorators":container.decorators})) != null ? stack1 : "");
},"2":function(container,depth0,helpers,partials,data) {
    var lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "							<tr>\n								<td>\n									"
    + container.escapeExpression((lookupProperty(helpers,"getWord")||(depth0 && lookupProperty(depth0,"getWord"))||container.hooks.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),"no_meetings_for_this_day",{"name":"getWord","hash":{},"data":data,"loc":{"start":{"line":13,"column":9},"end":{"line":13,"column":47}}}))
    + "\n								</td>\n							</tr>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
          return parent[propertyName];
        }
        return undefined
    };

  return "<div class=\"tab-content\">\n"
    + ((stack1 = lookupProperty(helpers,"each").call(depth0 != null ? depth0 : (container.nullContext || {}),depth0,{"name":"each","hash":{},"fn":container.program(0, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":2,"column":4},"end":{"line":21,"column":13}}})) != null ? stack1 : "")
    + "</div>\n";
},"usePartial":true,"useData":true});
var croutonDefaultTemplates = {

	meeting_data_template: [
		"{{#isTemporarilyClosed this}}",
		"    <div class='temporarilyClosed'><span class='glyphicon glyphicon-flag'></span> {{temporarilyClosed this}}</div>",
		"{{/isTemporarilyClosed}}",
		"<div class='meeting-name'>{{> meetingModal this}}</div>",
		"<div class='location-text'>{{this.location_text}}</div>",
		"<div class='meeting-address'>{{this.formatted_address}}</div>",
		"<div class='location-information'>{{this.formatted_location_info}}</div>",
		"{{#if this.virtual_meeting_additional_info}}",
		"    <div class='meeting-additional-info'>{{this.virtual_meeting_additional_info}}</div>",
		"{{/if}}",
		"{{> distance }}"
	].join('\n'),

	metadata_template: [
		"{{> attendVirtual }}",
		"{{#isNotTemporarilyClosed this}}",
		"    {{#unless (hasFormats 'VM' this)}}",
		"	 {{> meetingDetailsButton this}}",
		"    {{/unless}}",
		"{{/isNotTemporarilyClosed}}"
	].join('\n'),

	observer_template: [
		"{{> observerLine name=contact_name_1 phone=contact_phone_1 email=contact_email_1 }}",
		"{{> observerLine name=contact_name_2 phone=contact_phone_2 email=contact_email_2 }}",
		"{{#if this.wheelchair}}<div aria-hidden='true' style='font-style:normal; font-size:x-large;'>&#x267F;</div>{{/if}}"
	].join('\n'),

	meeting_count_template: [
		"{{#if this.config.has_meeting_count}}",
		"<span class='bmlt_tabs_meeting_count'>{{getWord 'meeting_count'}} <span id='bmlt_tabs_meeting_count-live'>{{this.meetings.meetingCount}}</span></span>",
		"{{/if}}"
	].join('\n'),


	meetingpage_title_template: [
		"{{this.formatted_day}} {{this.start_time_formatted}} - {{this.end_time_formatted}}: {{this.meeting_name}}"
	].join('\n'),
	meetingdetails_contents_template: `
		{{#isInPersonOrHybrid this}}
       		<h4>{{getWord "Location"}}</h4>
        	{{#isTemporarilyClosed this}}
            	<div class="temporarilyClosed">{{temporarilyClosed this}}</div>
        	{{/isTemporarilyClosed}}
            <div class="location-text">{{{this.location_text}}}</div>
            <div class="meeting-address">{{this.formatted_address}}</div>
            <div class="location-information">{{{this.formatted_location_info}}}</div>
			{{> directionsButton this}}
            <br/>
        {{/isInPersonOrHybrid}}
		{{> attendVirtual }}
        <br/>
        {{> formatDescriptions }}
        <h4>{{getWord "Contact"}}</h4>
        {{getWord "This meeting is in"}} <a href="{{serviceBodyUrl}}">{{serviceBodyName}}</a><br/>
		{{> offerIcsButton}}`,
	marker_contents_template:
	`<h4>{{meeting_name}}</h4>
	<div class="active">
		<div class="marker_div_location_text">{{{this.location_text}}}</div>
		<div class="marker_div_location_address">{{this.formatted_address}}</div>
		<div class="marker_div_location_info">{{{this.formatted_location_info}}}</div>
		<div class="marker_div_location_maplink">
		{{#if this.meeting_details_url}}
			<a href="{{this.meeting_details_url}}" target="_blank">{{getWord "more info"}}</a>
		{{/if}}
		</div>
		<div class="marker_div_formats">
		{{#each this.formats_expanded}}{{#if @index}}; {{/if}}{{this.name}}{{/each}}
		</div>
	</div>
	`,
	meeting_times_template: `
		<div class="bmlt-day">{{this.formatted_day}}</div>
		{{#ifEquals this.duration_time "24:00:00"}}
			<div class="bmlt-time-2">{{this.start_time_formatted}}</div>
		{{else}}
			<div class="bmlt-time-2">{{this.start_time_formatted}} - {{this.end_time_formatted}}</div>
		{{/ifEquals}}
		{{> formatKeys }}
		<div class="bmlt-comments">{{formatLink this.formatted_comments}}</div>
		<div class="bmlt-observer">{{> (selectObserver) }}</div>
	`,

	group_data_template: `
		<div class='location-text'>{{this.location_text}}</div>
		<div class='meeting-address'>{{this.formatted_address}}</div>
		<div class='location-information'>{{this.formatted_location_info}}
		{{#if this.virtual_meeting_additional_info}}
			<div class='meeting-additional-info'>{{this.virtual_meeting_additional_info}}</div>
		{{/if}}
		{{> distance }}
		<div class="bmlt-group-meetings">
			{{#each this.membersOfGroup}}
				<div class="bmlt-group-meeting">
					{{this.formatted_day}}: {{this.start_time_formatted}}
				</div>
			{{/each}}
		</div>
		`,
	group_title_template: `
	    <h5 style="font-size: 120%;" class="m-0 me-2 mb-2">{{this.meeting_name}}</h5>
        {{distance}}
        {{> directionsButton this}}
    `,
	group_details_contents_template: `
	    <div class="card-text">
        	{{#isInPersonOrHybrid this}}
            	<div class="card-title header-elements">
                	<h4 class="m-0 me-2">{{getWord 'Address'}}</h4>
    	        </div>
         	   	<div class="location-text">{{{this.location_text}}}</div>
            	<div class="meeting-address">{{this.formatted_address}}</div>
            	<div class="location-information">{{{this.formatted_location_info}}}</div>
            	<br/>
        	{{/isInPersonOrHybrid}}
			{{> attendVirtual }}
    	</div>
        {{> formatDescriptions }}
        <div class="card-title header-elements">
            <h4 class="m-0 me-2">{{getWord 'Comments'}}</h4>
        </div>
        <div class="card-text">
			<div class="bmlt-comments">{{formatLink this.formatted_comments}}</div>
			<div class="bmlt-observer">
                {{> observerLine name=contact_name_1 phone=contact_phone_1 email=contact_email_1 }}
		        {{> observerLine name=contact_name_2 phone=contact_phone_2 email=contact_email_2 }}
			</div>
    	</div>`,
	member_details_template: `
        <div class="card-title header-elements">
            <h5 class="m-0 me-2">
        		<div class="bmlt-day">{{this.formatted_day}}</div>
				{{#ifEquals this.duration_time "24:00:00"}}
					<div class="bmlt-time-2">{{this.start_time_formatted}}</div>
				{{else}}
					<div class="bmlt-time-2">{{this.start_time_formatted}} - {{this.end_time_formatted}}</div>
				{{/ifEquals}}
            </h5>
        </div>
        <div class="card-text">
            <div class="row mb-2">
                <div class="col-md-12">
                    {{#if formats_expanded}}
                        <ul>
                            {{#each formats_expanded}}
                                <li>{{description}}</li>
                            {{/each}}
                        </ul>
                        <br/>
                    {{/if}}
                </div>
            </div>
        </div>`,
}



/*! https://mths.be/punycode v1.4.1 by @mathias */
;(function(root) {

	/** Detect free variables */
	var freeExports = typeof exports == 'object' && exports &&
		!exports.nodeType && exports;
	var freeModule = typeof module == 'object' && module &&
		!module.nodeType && module;
	var freeGlobal = typeof global == 'object' && global;
	if (
		freeGlobal.global === freeGlobal ||
		freeGlobal.window === freeGlobal ||
		freeGlobal.self === freeGlobal
	) {
		root = freeGlobal;
	}

	/**
	 * The `punycode` object.
	 * @name punycode
	 * @type Object
	 */
	var punycode,

	/** Highest positive signed 32-bit float value */
	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1

	/** Bootstring parameters */
	base = 36,
	tMin = 1,
	tMax = 26,
	skew = 38,
	damp = 700,
	initialBias = 72,
	initialN = 128, // 0x80
	delimiter = '-', // '\x2D'

	/** Regular expressions */
	regexPunycode = /^xn--/,
	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators

	/** Error messages */
	errors = {
		'overflow': 'Overflow: input needs wider integers to process',
		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
		'invalid-input': 'Invalid input'
	},

	/** Convenience shortcuts */
	baseMinusTMin = base - tMin,
	floor = Math.floor,
	stringFromCharCode = String.fromCharCode,

	/** Temporary variable */
	key;

	/*--------------------------------------------------------------------------*/

	/**
	 * A generic error utility function.
	 * @private
	 * @param {String} type The error type.
	 * @returns {Error} Throws a `RangeError` with the applicable error message.
	 */
	function error(type) {
		throw new RangeError(errors[type]);
	}

	/**
	 * A generic `Array#map` utility function.
	 * @private
	 * @param {Array} array The array to iterate over.
	 * @param {Function} callback The function that gets called for every array
	 * item.
	 * @returns {Array} A new array of values returned by the callback function.
	 */
	function map(array, fn) {
		var length = array.length;
		var result = [];
		while (length--) {
			result[length] = fn(array[length]);
		}
		return result;
	}

	/**
	 * A simple `Array#map`-like wrapper to work with domain name strings or email
	 * addresses.
	 * @private
	 * @param {String} domain The domain name or email address.
	 * @param {Function} callback The function that gets called for every
	 * character.
	 * @returns {Array} A new string of characters returned by the callback
	 * function.
	 */
	function mapDomain(string, fn) {
		var parts = string.split('@');
		var result = '';
		if (parts.length > 1) {
			// In email addresses, only the domain name should be punycoded. Leave
			// the local part (i.e. everything up to `@`) intact.
			result = parts[0] + '@';
			string = parts[1];
		}
		// Avoid `split(regex)` for IE8 compatibility. See #17.
		string = string.replace(regexSeparators, '\x2E');
		var labels = string.split('.');
		var encoded = map(labels, fn).join('.');
		return result + encoded;
	}

	/**
	 * Creates an array containing the numeric code points of each Unicode
	 * character in the string. While JavaScript uses UCS-2 internally,
	 * this function will convert a pair of surrogate halves (each of which
	 * UCS-2 exposes as separate characters) into a single code point,
	 * matching UTF-16.
	 * @see `punycode.ucs2.encode`
	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
	 * @memberOf punycode.ucs2
	 * @name decode
	 * @param {String} string The Unicode input string (UCS-2).
	 * @returns {Array} The new array of code points.
	 */
	function ucs2decode(string) {
		var output = [],
		    counter = 0,
		    length = string.length,
		    value,
		    extra;
		while (counter < length) {
			value = string.charCodeAt(counter++);
			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
				// high surrogate, and there is a next character
				extra = string.charCodeAt(counter++);
				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
				} else {
					// unmatched surrogate; only append this code unit, in case the next
					// code unit is the high surrogate of a surrogate pair
					output.push(value);
					counter--;
				}
			} else {
				output.push(value);
			}
		}
		return output;
	}

	/**
	 * Creates a string based on an array of numeric code points.
	 * @see `punycode.ucs2.decode`
	 * @memberOf punycode.ucs2
	 * @name encode
	 * @param {Array} codePoints The array of numeric code points.
	 * @returns {String} The new Unicode string (UCS-2).
	 */
	function ucs2encode(array) {
		return map(array, function(value) {
			var output = '';
			if (value > 0xFFFF) {
				value -= 0x10000;
				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
				value = 0xDC00 | value & 0x3FF;
			}
			output += stringFromCharCode(value);
			return output;
		}).join('');
	}

	/**
	 * Converts a basic code point into a digit/integer.
	 * @see `digitToBasic()`
	 * @private
	 * @param {Number} codePoint The basic numeric code point value.
	 * @returns {Number} The numeric value of a basic code point (for use in
	 * representing integers) in the range `0` to `base - 1`, or `base` if
	 * the code point does not represent a value.
	 */
	function basicToDigit(codePoint) {
		if (codePoint - 48 < 10) {
			return codePoint - 22;
		}
		if (codePoint - 65 < 26) {
			return codePoint - 65;
		}
		if (codePoint - 97 < 26) {
			return codePoint - 97;
		}
		return base;
	}

	/**
	 * Converts a digit/integer into a basic code point.
	 * @see `basicToDigit()`
	 * @private
	 * @param {Number} digit The numeric value of a basic code point.
	 * @returns {Number} The basic code point whose value (when used for
	 * representing integers) is `digit`, which needs to be in the range
	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
	 * used; else, the lowercase form is used. The behavior is undefined
	 * if `flag` is non-zero and `digit` has no uppercase form.
	 */
	function digitToBasic(digit, flag) {
		//  0..25 map to ASCII a..z or A..Z
		// 26..35 map to ASCII 0..9
		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
	}

	/**
	 * Bias adaptation function as per section 3.4 of RFC 3492.
	 * https://tools.ietf.org/html/rfc3492#section-3.4
	 * @private
	 */
	function adapt(delta, numPoints, firstTime) {
		var k = 0;
		delta = firstTime ? floor(delta / damp) : delta >> 1;
		delta += floor(delta / numPoints);
		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
			delta = floor(delta / baseMinusTMin);
		}
		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
	}

	/**
	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
	 * symbols.
	 * @memberOf punycode
	 * @param {String} input The Punycode string of ASCII-only symbols.
	 * @returns {String} The resulting string of Unicode symbols.
	 */
	function decode(input) {
		// Don't use UCS-2
		var output = [],
		    inputLength = input.length,
		    out,
		    i = 0,
		    n = initialN,
		    bias = initialBias,
		    basic,
		    j,
		    index,
		    oldi,
		    w,
		    k,
		    digit,
		    t,
		    /** Cached calculation results */
		    baseMinusT;

		// Handle the basic code points: let `basic` be the number of input code
		// points before the last delimiter, or `0` if there is none, then copy
		// the first basic code points to the output.

		basic = input.lastIndexOf(delimiter);
		if (basic < 0) {
			basic = 0;
		}

		for (j = 0; j < basic; ++j) {
			// if it's not a basic code point
			if (input.charCodeAt(j) >= 0x80) {
				error('not-basic');
			}
			output.push(input.charCodeAt(j));
		}

		// Main decoding loop: start just after the last delimiter if any basic code
		// points were copied; start at the beginning otherwise.

		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {

			// `index` is the index of the next character to be consumed.
			// Decode a generalized variable-length integer into `delta`,
			// which gets added to `i`. The overflow checking is easier
			// if we increase `i` as we go, then subtract off its starting
			// value at the end to obtain `delta`.
			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {

				if (index >= inputLength) {
					error('invalid-input');
				}

				digit = basicToDigit(input.charCodeAt(index++));

				if (digit >= base || digit > floor((maxInt - i) / w)) {
					error('overflow');
				}

				i += digit * w;
				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);

				if (digit < t) {
					break;
				}

				baseMinusT = base - t;
				if (w > floor(maxInt / baseMinusT)) {
					error('overflow');
				}

				w *= baseMinusT;

			}

			out = output.length + 1;
			bias = adapt(i - oldi, out, oldi == 0);

			// `i` was supposed to wrap around from `out` to `0`,
			// incrementing `n` each time, so we'll fix that now:
			if (floor(i / out) > maxInt - n) {
				error('overflow');
			}

			n += floor(i / out);
			i %= out;

			// Insert `n` at position `i` of the output
			output.splice(i++, 0, n);

		}

		return ucs2encode(output);
	}

	/**
	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
	 * Punycode string of ASCII-only symbols.
	 * @memberOf punycode
	 * @param {String} input The string of Unicode symbols.
	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
	 */
	function encode(input) {
		var n,
		    delta,
		    handledCPCount,
		    basicLength,
		    bias,
		    j,
		    m,
		    q,
		    k,
		    t,
		    currentValue,
		    output = [],
		    /** `inputLength` will hold the number of code points in `input`. */
		    inputLength,
		    /** Cached calculation results */
		    handledCPCountPlusOne,
		    baseMinusT,
		    qMinusT;

		// Convert the input in UCS-2 to Unicode
		input = ucs2decode(input);

		// Cache the length
		inputLength = input.length;

		// Initialize the state
		n = initialN;
		delta = 0;
		bias = initialBias;

		// Handle the basic code points
		for (j = 0; j < inputLength; ++j) {
			currentValue = input[j];
			if (currentValue < 0x80) {
				output.push(stringFromCharCode(currentValue));
			}
		}

		handledCPCount = basicLength = output.length;

		// `handledCPCount` is the number of code points that have been handled;
		// `basicLength` is the number of basic code points.

		// Finish the basic string - if it is not empty - with a delimiter
		if (basicLength) {
			output.push(delimiter);
		}

		// Main encoding loop:
		while (handledCPCount < inputLength) {

			// All non-basic code points < n have been handled already. Find the next
			// larger one:
			for (m = maxInt, j = 0; j < inputLength; ++j) {
				currentValue = input[j];
				if (currentValue >= n && currentValue < m) {
					m = currentValue;
				}
			}

			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
			// but guard against overflow
			handledCPCountPlusOne = handledCPCount + 1;
			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
				error('overflow');
			}

			delta += (m - n) * handledCPCountPlusOne;
			n = m;

			for (j = 0; j < inputLength; ++j) {
				currentValue = input[j];

				if (currentValue < n && ++delta > maxInt) {
					error('overflow');
				}

				if (currentValue == n) {
					// Represent delta as a generalized variable-length integer
					for (q = delta, k = base; /* no condition */; k += base) {
						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
						if (q < t) {
							break;
						}
						qMinusT = q - t;
						baseMinusT = base - t;
						output.push(
							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
						);
						q = floor(qMinusT / baseMinusT);
					}

					output.push(stringFromCharCode(digitToBasic(q, 0)));
					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
					delta = 0;
					++handledCPCount;
				}
			}

			++delta;
			++n;

		}
		return output.join('');
	}

	/**
	 * Converts a Punycode string representing a domain name or an email address
	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
	 * it doesn't matter if you call it on a string that has already been
	 * converted to Unicode.
	 * @memberOf punycode
	 * @param {String} input The Punycoded domain name or email address to
	 * convert to Unicode.
	 * @returns {String} The Unicode representation of the given Punycode
	 * string.
	 */
	function toUnicode(input) {
		return mapDomain(input, function(string) {
			return regexPunycode.test(string)
				? decode(string.slice(4).toLowerCase())
				: string;
		});
	}

	/**
	 * Converts a Unicode string representing a domain name or an email address to
	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
	 * i.e. it doesn't matter if you call it with a domain that's already in
	 * ASCII.
	 * @memberOf punycode
	 * @param {String} input The domain name or email address to convert, as a
	 * Unicode string.
	 * @returns {String} The Punycode representation of the given domain name or
	 * email address.
	 */
	function toASCII(input) {
		return mapDomain(input, function(string) {
			return regexNonASCII.test(string)
				? 'xn--' + encode(string)
				: string;
		});
	}

	/*--------------------------------------------------------------------------*/

	/** Define the public API */
	punycode = {
		/**
		 * A string representing the current Punycode.js version number.
		 * @memberOf punycode
		 * @type String
		 */
		'version': '1.4.1',
		/**
		 * An object of methods to convert from JavaScript's internal character
		 * representation (UCS-2) to Unicode code points, and back.
		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
		 * @memberOf punycode
		 * @type Object
		 */
		'ucs2': {
			'decode': ucs2decode,
			'encode': ucs2encode
		},
		'decode': decode,
		'encode': encode,
		'toASCII': toASCII,
		'toUnicode': toUnicode
	};

	/** Expose `punycode` */
	// Some AMD build optimizers, like r.js, check for specific condition patterns
	// like the following:
	if (
		typeof define == 'function' &&
		typeof define.amd == 'object' &&
		define.amd
	) {
		define('punycode', function() {
			return punycode;
		});
	} else if (freeExports && freeModule) {
		if (module.exports == freeExports) {
			// in Node.js, io.js, or RingoJS v0.8.0+
			freeModule.exports = punycode;
		} else {
			// in Narwhal or RingoJS v0.7.0-
			for (key in punycode) {
				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
			}
		}
	} else {
		// in Rhino or a web browser
		root.punycode = punycode;
	}

}(this));

var defaultOptions = {
	timeout: 300000,
	jsonpCallback: 'callback',
	jsonpCallbackFunction: null,
};

function generateCallbackFunction() {
	return 'jsonp_' + Date.now().toString() + '_' + Math.ceil(Math.random() * 100000).toString();
}

function clearFunction(functionName) {
	// IE8 throws an exception when you try to delete a property on window
	// http://stackoverflow.com/a/1824228/751089
	try {
		delete window[functionName];
	} catch (e) {
		window[functionName] = undefined;
	}
}

function removeScript(scriptId) {
	var script = document.getElementById(scriptId);
	if (script) {
		document.getElementsByTagName('head')[0].removeChild(script);
	}
}

function fetchJsonp(_url, options) {
	if (!options) {
		options = {};
	}
	// to avoid param reassign
	var url = _url;
	var timeout = options.timeout || defaultOptions.timeout;
	var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;

	var timeoutId;

	return new Promise(function (resolve, reject) {
		var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
		var scriptId = jsonpCallback + '_' + callbackFunction;

		window[callbackFunction] = function (response) {
			resolve({
				ok: true,
				// keep consistent with fetch API
				json: function () { return Promise.resolve(response); },
			});

			if (timeoutId) clearTimeout(timeoutId);

			removeScript(scriptId);

			clearFunction(callbackFunction);
		};

		// Check if the user set their own params, and if not add a ? to start a list of params
		url += (url.indexOf('?') === -1) ? '?' : '&';

		var jsonpScript = document.createElement('script');
		jsonpScript.setAttribute('src', url + jsonpCallback + '=' + callbackFunction);
		if (options.charset) {
			jsonpScript.setAttribute('charset', options.charset);
		}
		if (options.nonce) {
			jsonpScript.setAttribute('nonce', options.nonce);
		}
		if (options.referrerPolicy) {
			jsonpScript.setAttribute('referrerPolicy', options.referrerPolicy);
		}
		jsonpScript.id = scriptId;
		document.getElementsByTagName('head')[0].appendChild(jsonpScript);

		timeoutId = setTimeout(function () {
			reject(new Error('JSONP request to ' + _url + ' timed out'));

			clearFunction(callbackFunction);
			removeScript(scriptId);
			window[callbackFunction] = function () {
				clearFunction(callbackFunction);
			};
		}, timeout);

		// Caught if got 404/500
		jsonpScript.onerror = function () {
			reject(new Error('JSONP request to ' + _url + ' failed'));

			clearFunction(callbackFunction);
			removeScript(scriptId);
			if (timeoutId) clearTimeout(timeoutId);
		};
	});
}

// export as global function
/*
let local;
if (typeof global !== 'undefined') {
  local = global;
} else if (typeof self !== 'undefined') {
  local = self;
} else {
  try {
    local = Function('return this')();
  } catch (e) {
    throw new Error('polyfill failed because global object is unavailable in this environment');
  }
}
local.fetchJsonp = fetchJsonp;
*/


(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
		typeof define === 'function' && define.amd ? define(factory) :
			(factory());
}(this, (function () { 'use strict';

	/**
	 * @this {Promise}
	 */
	function finallyConstructor(callback) {
		var constructor = this.constructor;
		return this.then(
			function(value) {
				// @ts-ignore
				return constructor.resolve(callback()).then(function() {
					return value;
				});
			},
			function(reason) {
				// @ts-ignore
				return constructor.resolve(callback()).then(function() {
					// @ts-ignore
					return constructor.reject(reason);
				});
			}
		);
	}

	function allSettled(arr) {
		var P = this;
		return new P(function(resolve, reject) {
			if (!(arr && typeof arr.length !== 'undefined')) {
				return reject(
					new TypeError(
						typeof arr +
						' ' +
						arr +
						' is not iterable(cannot read property Symbol(Symbol.iterator))'
					)
				);
			}
			var args = Array.prototype.slice.call(arr);
			if (args.length === 0) return resolve([]);
			var remaining = args.length;

			function res(i, val) {
				if (val && (typeof val === 'object' || typeof val === 'function')) {
					var then = val.then;
					if (typeof then === 'function') {
						then.call(
							val,
							function(val) {
								res(i, val);
							},
							function(e) {
								args[i] = { status: 'rejected', reason: e };
								if (--remaining === 0) {
									resolve(args);
								}
							}
						);
						return;
					}
				}
				args[i] = { status: 'fulfilled', value: val };
				if (--remaining === 0) {
					resolve(args);
				}
			}

			for (var i = 0; i < args.length; i++) {
				res(i, args[i]);
			}
		});
	}

// Store setTimeout reference so promise-polyfill will be unaffected by
// other code modifying setTimeout (like sinon.useFakeTimers())
	var setTimeoutFunc = setTimeout;
// @ts-ignore
	var setImmediateFunc = typeof setImmediate !== 'undefined' ? setImmediate : null;

	function isArray(x) {
		return Boolean(x && typeof x.length !== 'undefined');
	}

	function noop() {}

// Polyfill for Function.prototype.bind
	function bind(fn, thisArg) {
		return function() {
			fn.apply(thisArg, arguments);
		};
	}

	/**
	 * @constructor
	 * @param {Function} fn
	 */
	function Promise(fn) {
		if (!(this instanceof Promise))
			throw new TypeError('Promises must be constructed via new');
		if (typeof fn !== 'function') throw new TypeError('not a function');
		/** @type {!number} */
		this._state = 0;
		/** @type {!boolean} */
		this._handled = false;
		/** @type {Promise|undefined} */
		this._value = undefined;
		/** @type {!Array<!Function>} */
		this._deferreds = [];

		doResolve(fn, this);
	}

	function handle(self, deferred) {
		while (self._state === 3) {
			self = self._value;
		}
		if (self._state === 0) {
			self._deferreds.push(deferred);
			return;
		}
		self._handled = true;
		Promise._immediateFn(function() {
			var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
			if (cb === null) {
				(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
				return;
			}
			var ret;
			try {
				ret = cb(self._value);
			} catch (e) {
				reject(deferred.promise, e);
				return;
			}
			resolve(deferred.promise, ret);
		});
	}

	function resolve(self, newValue) {
		try {
			// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
			if (newValue === self)
				throw new TypeError('A promise cannot be resolved with itself.');
			if (
				newValue &&
				(typeof newValue === 'object' || typeof newValue === 'function')
			) {
				var then = newValue.then;
				if (newValue instanceof Promise) {
					self._state = 3;
					self._value = newValue;
					finale(self);
					return;
				} else if (typeof then === 'function') {
					doResolve(bind(then, newValue), self);
					return;
				}
			}
			self._state = 1;
			self._value = newValue;
			finale(self);
		} catch (e) {
			reject(self, e);
		}
	}

	function reject(self, newValue) {
		self._state = 2;
		self._value = newValue;
		finale(self);
	}

	function finale(self) {
		if (self._state === 2 && self._deferreds.length === 0) {
			Promise._immediateFn(function() {
				if (!self._handled) {
					Promise._unhandledRejectionFn(self._value);
				}
			});
		}

		for (var i = 0, len = self._deferreds.length; i < len; i++) {
			handle(self, self._deferreds[i]);
		}
		self._deferreds = null;
	}

	/**
	 * @constructor
	 */
	function Handler(onFulfilled, onRejected, promise) {
		this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
		this.onRejected = typeof onRejected === 'function' ? onRejected : null;
		this.promise = promise;
	}

	/**
	 * Take a potentially misbehaving resolver function and make sure
	 * onFulfilled and onRejected are only called once.
	 *
	 * Makes no guarantees about asynchrony.
	 */
	function doResolve(fn, self) {
		var done = false;
		try {
			fn(
				function(value) {
					if (done) return;
					done = true;
					resolve(self, value);
				},
				function(reason) {
					if (done) return;
					done = true;
					reject(self, reason);
				}
			);
		} catch (ex) {
			if (done) return;
			done = true;
			reject(self, ex);
		}
	}

	Promise.prototype['catch'] = function(onRejected) {
		return this.then(null, onRejected);
	};

	Promise.prototype.then = function(onFulfilled, onRejected) {
		// @ts-ignore
		var prom = new this.constructor(noop);

		handle(this, new Handler(onFulfilled, onRejected, prom));
		return prom;
	};

	Promise.prototype['finally'] = finallyConstructor;

	Promise.all = function(arr) {
		return new Promise(function(resolve, reject) {
			if (!isArray(arr)) {
				return reject(new TypeError('Promise.all accepts an array'));
			}

			var args = Array.prototype.slice.call(arr);
			if (args.length === 0) return resolve([]);
			var remaining = args.length;

			function res(i, val) {
				try {
					if (val && (typeof val === 'object' || typeof val === 'function')) {
						var then = val.then;
						if (typeof then === 'function') {
							then.call(
								val,
								function(val) {
									res(i, val);
								},
								reject
							);
							return;
						}
					}
					args[i] = val;
					if (--remaining === 0) {
						resolve(args);
					}
				} catch (ex) {
					reject(ex);
				}
			}

			for (var i = 0; i < args.length; i++) {
				res(i, args[i]);
			}
		});
	};

	Promise.allSettled = allSettled;

	Promise.resolve = function(value) {
		if (value && typeof value === 'object' && value.constructor === Promise) {
			return value;
		}

		return new Promise(function(resolve) {
			resolve(value);
		});
	};

	Promise.reject = function(value) {
		return new Promise(function(resolve, reject) {
			reject(value);
		});
	};

	Promise.race = function(arr) {
		return new Promise(function(resolve, reject) {
			if (!isArray(arr)) {
				return reject(new TypeError('Promise.race accepts an array'));
			}

			for (var i = 0, len = arr.length; i < len; i++) {
				Promise.resolve(arr[i]).then(resolve, reject);
			}
		});
	};

// Use polyfill for setImmediate for performance gains
	Promise._immediateFn =
		// @ts-ignore
		(typeof setImmediateFunc === 'function' &&
			function(fn) {
				// @ts-ignore
				setImmediateFunc(fn);
			}) ||
		function(fn) {
			setTimeoutFunc(fn, 0);
		};

	Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
		if (typeof console !== 'undefined' && console) {
			console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
		}
	};

	/** @suppress {undefinedVars} */
	var globalNS = (function() {
		// the only reliable means to get the global object is
		// `Function('return this')()`
		// However, this causes CSP violations in Chrome apps.
		if (typeof self !== 'undefined') {
			return self;
		}
		if (typeof window !== 'undefined') {
			return window;
		}
		if (typeof global !== 'undefined') {
			return global;
		}
		throw new Error('unable to locate global object');
	})();

// Expose the polyfill if Promise is undefined or set to a
// non-function value. The latter can be due to a named HTMLElement
// being exposed by browsers for legacy reasons.
// https://github.com/taylorhakes/promise-polyfill/issues/114
	if (typeof globalNS['Promise'] !== 'function') {
		globalNS['Promise'] = Promise;
	} else {
		if (!globalNS.Promise.prototype['finally']) {
			globalNS.Promise.prototype['finally'] = finallyConstructor;
		}
		if (!globalNS.Promise.allSettled) {
			globalNS.Promise.allSettled = allSettled;
		}
	}

})));

var crouton_Handlebars = Handlebars.noConflict();
// These are extension points
crouton_Handlebars.registerHelper("startup", () => '');
crouton_Handlebars.registerHelper("enrich", () => '');
crouton_Handlebars.registerHelper("log", (x) => console.log(x));
crouton_Handlebars.registerHelper('selectFormatPopup', () => "formatPopup");
crouton_Handlebars.registerHelper('selectObserver', () => "observerTemplate");


function Crouton(config) {
	var self = this;
	self.mutex = false;
	self.filtering = false;
	self.masterFormatCodes = [];
	self.currentView = "weekday";
	self.distanceTabAllowed = false;
	self.config = {
		version: '4.1.11',             // CroutonJS version for debugging
		on_complete: null,            // Javascript function to callback when data querying is completed.
		root_server: null,			  // The root server to use.
		placeholder_id: "bmlt-tabs",  // The DOM id that will be used for rendering
		map_max_zoom: 15,		      // Maximum zoom for the display map
		time_format: "h:mm a",        // The format for time
		language: "en-US",            // Default language translation, available translations listed here: https://github.com/bmlt-enabled/crouton/blob/master/croutonjs/src/js/crouton-localization.js
		has_tabs: true,               // Shows the day tabs
		filter_tabs: 20,   		  // Whether to show weekday tabs on filtering.
		filter_visible: 0,		  // whether entries in table should be limited to those visible in map
		header: true,                 // Shows the dropdowns and buttons
		include_weekday_button: true, // Shows the weekday button
		int_include_unpublished: 0,	  // Includes unpublished meeting
		grouping_buttons: [
			{'title': 'City', 'field': 'location_municipality'},
			{'title': 'Distance', 'field': 'distance_in_km'},
		],
		formattype_grouping_buttons: [],
		default_filter_dropdown: "",  // Sets the default format for the dropdowns, the names will match the `has_` fields dropdowns without `has_.  Example: `formats=closed`.
		show_map: "embed",            // Shows the map with pins
		map_search: null, 			  // Start search with map click (ex {"latitude":x,"longitude":y,"width":-10,"zoom":10}
		has_days: false,			  // Shows the days of the week dropdown
		has_cities: true,             // Shows the cities dropdown
		has_formats: true,            // Shows the formats dropdown
		has_groups: false,            // Shows the groups dropdown
		has_locations: true,          // Shows the locations dropdown
		has_zip_codes: false,         // Shows the zip codes dropdown
		has_areas: false,             // Shows the areas dropdown
		has_regions: false,			  // Shows the regions dropdown
		has_states: false,            // Shows the states dropdown
		has_sub_province: false,      // Shows the sub province dropdown (counties)
		has_neighborhoods: false,     // Shows the neighborhood dropdown
		has_languages: false,		  // Shows the language dropdown
		has_common_needs: false, 	  // Shows the Common Needs dropdown
		has_venues: true,		      // Shows the venue types dropdown
		has_meeting_count: false,	  // Shows the meeting count
		recurse_service_bodies: false,// Recurses service bodies when making service bodies request
		service_body: [],             // Array of service bodies to return data for.
		formats: [],		  		  // Return only meetings with these formats (format shared-id, not key-string)
		venue_types: [],			  // Return only meetings with this venue type (1, 2 or 3)
		meeting_details_href: '',	  // Link to the meeting details page
		virtual_meeting_details_href: '', // Link to the virtual meeting details page
		bmlt2ics: '',				  // URL of feed to generate ICS files from meetings
		exclude_zip_codes: [],        // List of zip codes to exclude
		extra_meetings: [],           // List of id_bigint of meetings to include
		native_lang: '',				  // The implied language of meetings with no explicit language specied.  May be there as second language, but it still doesn't make sense to search for it.
		auto_tz_adjust: false,        // Will auto adjust the time zone, by default will assume the timezone is local time
		base_tz: null,                // In conjunction with auto_tz_adjust the timezone to base from.  Choices are listed here: https://github.com/bmlt-enabled/crouton/blob/master/croutonjs/src/js/moment-timezone.js#L623
		custom_query: null,			  // Enables overriding the services related queries for a custom one
		sort_keys: "start_time",	  // Controls sort keys on the query
		int_start_day_id: 1,          // Controls the first day of the week sequence.  Sunday is 1.
		view_by: "weekday",           // TODO: replace with using the first choice in grouping_buttons as the default view_by.
		show_qrcode: false,  		  // Determines whether or not to show the QR code for virtual / phone meetings if they exist.
		force_rootserver_in_querystring: true, // Set to false to shorten generated meeting detail query strings
		force_timeformat_in_querystring: true, // Set to false to shorten generated meeting detail query strings
		force_language_in_querystring: true, // Set to false to shorten generated meeting detail query strings
		theme: "jack",                // Allows for setting pre-packaged themes.  Choices are listed here:  https://github.com/bmlt-enabled/crouton/blob/master/croutonjs/src/templates/themes
		report_update_url: "",   	  // URL to edit a meeting for BMLT-workflow plugin
		meeting_data_template: croutonDefaultTemplates.meeting_data_template,
		metadata_template: croutonDefaultTemplates.metadata_template,
		observer_template: croutonDefaultTemplates.observer_template,
		meeting_count_template: croutonDefaultTemplates.meeting_count_template,
		meetingpage_title_template: croutonDefaultTemplates.meetingpage_title_template,
		meetingdetails_contents_template: croutonDefaultTemplates.meetingdetails_contents_template,
		meeting_times_template: croutonDefaultTemplates.meeting_times_template,
		group_data_template: croutonDefaultTemplates.group_data_template,
		group_title_template: croutonDefaultTemplates.group_title_template,
		group_details_template: croutonDefaultTemplates.group_details_contents_template,
		member_details_template: croutonDefaultTemplates.member_details_template,
		lat: 0,
		lng: 0,
		zoom: 10,
		clustering: 12,
		nominatimUrl: 'https://nominatim.openstreetmap.org/',
		tileUrl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
		tileOptions: {
			attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
			maxZoom: 18
		},
		minZoom: 6,
		maxZoom: 17,
		distance_units: 'miles',
		noMap: false,
		maxTomatoWidth: 160,
		caption: false,
		groups: false,
		details_table: false,
	};

	self.setConfig(config);
	Crouton.prototype.searchByCoordinates = function(latitude, longitude, width, fitBounds=true) {
		const original_query = self.config['custom_query'];
		self.config['custom_query'] = (self.config['custom_query'] !== null ? self.config['custom_query'] : "")
			+ "&lat_val=" + latitude + "&long_val=" + longitude
			+ (self.config['distance_units'] === "km" ? '&geo_width_km=' : '&geo_width=') + width;
		self.meetingSearch(function() {
				self.config.refresh_map=1;
				self.config.show_map = 1;
				self.reset();
				self.render(false, fitBounds);
		});
		self.config['custom_query'] = original_query;
	};

	self.getMeetings = function(url,cb=null) {
		var promises = [fetchJsonp(this.config['root_server'] + url).then(function(response) { return response.json(); })];

		if (self.config['extra_meetings'].length > 0) {
			var extra_meetings_query = "";
			for (var i = 0; i < self.config['extra_meetings'].length; i++) {
				extra_meetings_query += "&meeting_ids[]=" + self.config["extra_meetings"][i];
			}
			const regex = /&services\[\]=\d+/;
			url = url.replace(regex, '');
			promises.push(fetchJsonp(self.config['root_server'] + url + extra_meetings_query).then(function (response) { return response.json(); }));
		}

		return Promise.all(promises)
			.then(function(data) {
				var mainMeetings = data[0];
				var extraMeetings;
				var jsonMeetings = JSON.stringify(mainMeetings['meetings']);
				if (data.length === 2) {
					extraMeetings = data[1];
				}
				if (jsonMeetings === "{}" || jsonMeetings === "[]") {
					var fullUrl = self.config['root_server'] + url
					console.log("Could not find any meetings for the criteria specified with the query <a href=\"" + fullUrl + "\" target=_blank>" + fullUrl + "</a>");
					jQuery('#' + self.config['placeholder_id']).html("No meetings found.");
					self.meetingData = [];
					self.formatsData = [];
					self.mutex = false;
					cb && cb();
					return;
				}
				if (self.config['exclude_zip_codes'].length > 0) {
					mainMeetings['meetings'] = mainMeetings['meetings'].filter(function(m) { return !inArray(m['location_postal_code_1'], self.config['exclude_zip_codes']); } );
				}
				self.meetingData = mainMeetings['meetings'];
				self.formatsData = mainMeetings['formats'];
				if (extraMeetings) {
					self.meetingData = self.meetingData.concat(extraMeetings['meetings']);
				}
				cb && cb();
				self.mutex = false;
			});
	};
	self.mutex = true;

	self.meetingSearch = function(cb=null) {
		var url = '/client_interface/jsonp/?switcher=GetSearchResults&get_used_formats&lang_enum=' + self.config['short_language'];

		if (self.config['formats']) {
			url += self.config['formats'].reduce(function(prev,id) {
				return prev +'&formats[]='+id;
			}, '');
			if (self.config['formatComparisonOp'] === 'OR') url += '&formats_comparison_operator=OR';
		}
		if (self.config.map_search && !Array.isArray(self.config['venue_types'])) {
			self.config['venue_types'] = [];
		}
		if (self.config.map_search && self.config['venue_types'].length === 0) {
			self.config['venue_types'].push('-2');
		}
		if (self.config['venue_types']) {
			url += self.config['venue_types'].reduce(function(prev,id) {
				return prev +'&venue_types[]='+id;
			}, '');
		}
		if (self.config['int_include_unpublished'] === 1) {
			url += "&advanced_published=0"
		} else if (self.config['int_include_unpublished'] === -1) {
			url += "&advanced_published=-1"
		}

		if (self.config['custom_query'] != null) {
			url += self.config['custom_query'] + '&sort_keys='  + self.config['sort_keys'];
			return self.getMeetings(url,cb);
		} else if (self.config['service_body'].length > 0) {
			for (var i = 0; i < self.config['service_body'].length; i++) {
				url += '&services[]=' + self.config['service_body'][i];
			}

			if (self.config['recurse_service_bodies']) {
				url += '&recursive=1';
			}

			url += '&sort_keys=' + self.config['sort_keys'];

			return self.getMeetings(url,cb);
		} else {
			return new Promise(function(resolve, reject) {
				self.meetingData = [];
				self.formatsData = [];
				self.mutex = false;
				resolve([]);
			});
		}
	};

	self.lock = function(callback) {
		var self = this;
		var lock_id = setInterval(function() {
			if (!self.mutex) {
				clearInterval(lock_id);
				callback();
			}
		}, 100);
	};

	self.dayTab = function(day_id) {
		self.hideAllPages();
		jQuery('.nav-tabs a[href="#tab' + day_id + '"]').tab('show');
		jQuery("#" + day_id).removeClass("hide").addClass("show");
	};
	self.dayTabFromId = function(id) {
		day_id = self.meetingData.find((m)=>m.id_bigint == id).weekday_tinyint;
		self.dayTab(day_id);
	};
	self.showPage = function (id) {
		jQuery(id+" .bmlt-data-row-placeholder").each(function() {
			const meetingId = this.dataset.meetingid;
			const placeHolder = jQuery(this);
			const placeholderText = this.outerHTML;
			const meetingRow = jQuery("#"+meetingId);
			meetingRow.before(placeholderText);
			placeHolder.replaceWith(meetingRow);
		});
		self.addStripes();
		jQuery(id).removeClass("hide").addClass("show");
	};

	self.showView = function (viewName, showingNow=0) {
		if (viewName === 'distance' && !self.distanceTabAllowed) {
			viewName = self.config.groups ? 'city' : 'day';
		}
		self.currentView = viewName;
		if (showingNow > 0) {
			self.showingNow = showingNow;
		} else showingNow = self.showingNow ? self.showingNow : self.meetingData.length; ;

		if (viewName.endsWith('day')) {
			if (!self.config['has_tabs'] || (self.config['filter_tabs'] && self.config['filter_tabs'] >= showingNow)) {
				self.byDayView();

				jQuery("#byday").find('.meeting-group').each(function(index) {
					if (jQuery(this).find(".bmlt-data-row.hide").length === jQuery(this).find(".bmlt-data-row").length)
						jQuery(this).addClass("hide");
					else jQuery(this).removeClass('hide');
				});
			} else {
				self.dayView();
			}
		} else if (viewName=='map') {
			self.mapView();
		} else if (jQuery('#groupingButton_'+viewName).length == 0) {
			self.groupedView(self.config.grouping_buttons.find((bf) => bf.title.toLowerCase() === viewName.toLowerCase()).field);
		} else {
			self.groupedView(viewName);
		}
	};

	self.byDayView = function () {
		self.lowlightButton(".groupingButton");
		self.highlightButton("#day");
		jQuery('.bmlt-page').each(function (index) {
			self.hidePage("#" + this.id);
			return;
		});
		self.hidePage("#days");
		self.showPage("#byday");
		self.hidePage("#nav-days");
		self.hidePage("#tabs-content");
	};

	self.dayView = function () {
		self.lowlightButton(".groupingButton");
		self.highlightButton("#day");
		jQuery('.bmlt-page').each(function (index) {
			self.hidePage("#" + this.id);
			return;
		});
		jQuery("#days").removeClass("hide").addClass("show");
		jQuery("#nav-days").removeClass("hide").addClass("show")
		self.showPage("#tabs-content");
	};

	self.groupedView = function (field) {
		if (field.includes('distance') && !self.distanceTabAllowed) {
			self.dayView();
			return;
		}
		self.lowlightButton("#day");
		self.lowlightButton(".groupingButton");
		self.highlightButton("#groupingButton_" + field);
		jQuery('.bmlt-page').each(function (index) {
			self.hidePage("#" + this.id);
			self.showPage("#byfield_" + field);
			jQuery("#byfield_" + field).find('.meeting-group').each(function(index) {
				if (jQuery(this).find(".bmlt-data-row.hide").length === jQuery(this).find(".bmlt-data-row").length)
					jQuery(this).addClass("hide");
				else jQuery(this).removeClass('hide');
			});
		});
	}
	self.mapView = function() {
		self.lowlightButton("#day");
		self.lowlightButton(".groupingButton");
		self.highlightButton("#groupingButton_embeddedMapPage");
		self.groupedView("embeddedMapPage", false);
		croutonMap.showMap(false,false);
	}
	self.lowlightButton = function (id) {
		jQuery(id).removeClass("buttonHighlight").addClass("buttonLowlight");
	};

	self.highlightButton = function (id) {
		jQuery(id).removeClass("buttonLowlight").addClass("buttonHighlight");
	};

	self.hidePage = function (id) {
		jQuery(id).removeClass("show").addClass("hide");
	};

	self.hideAllPages = function (id) {
		jQuery("#tab-pane").removeClass("show").addClass("hide");
	};
	self.addStripes = function() {
		jQuery(".bmlt-data-row").removeClass("evenRow");
		jQuery(".bmlt-data-row").removeClass("oddRow");
		jQuery(".bmlt-data-row:not(.hide)").each(function (index, value) {
			jQuery(value).addClass((index % 2) ? 'oddRow' : 'evenRow');
		});
	}
	self.calcShowingNow = function() {
		var showingNow = [];
		jQuery(".bmlt-data-row:not(.hide)").each(function (index, value) {
			const rowId = value.id.split("-");
			showingNow.push(rowId[rowId.length-1]);
		});
		showingNow = [...new Set(showingNow)];
		return showingNow;
	}
	self.filterMeetingsFromView = function () {
		jQuery(".group-header").removeClass("hide");
		jQuery(".meeting-group").removeClass("hide");
		jQuery(".bmlt-data-row").removeClass("hide");
		jQuery(".filter-dropdown").each(function(index, filter) {
			const dataValue = filter.value.replace("a-", "");
			if (dataValue === "") return;
			const dataType = filter.getAttribute("data-pointer").toLowerCase();
			if (dataType !== "formats" && dataType !== "languages" && dataType !== "venues" && dataType !== "common_needs") {
				jQuery(".bmlt-data-row").not("[data-" + dataType + "='" + dataValue + "']").addClass("hide");
			} else {
				jQuery(".bmlt-data-row").not("[data-" + dataType + "~='" + dataValue + "']").addClass("hide");
			}
		});
		this.addStripes();
		var showingNow = this.calcShowingNow();
		self.updateMeetingCount(showingNow);
		self.updateFilters();
		if (croutonMap) croutonMap.fillMap(showingNow);
		self.showView(self.currentView, showingNow.length);
	};
	self.resetFilter = function () {
		croutonMap.filterVisible(false);
		if ((self.config.map_page && self.filtering) || self.config.show_map) croutonMap.fillMap();
		self.filtering = false;
		self.updateFilters();
		self.updateMeetingCount();
		jQuery(".filter-dropdown").val(null).trigger("change");
		jQuery(".group-header").removeClass("hide");
		jQuery(".meeting-group").removeClass("hide");
		jQuery(".bmlt-data-row").removeClass("hide");
		jQuery(".evenRow").removeClass("evenRow");
		jQuery(".oddRow").removeClass("oddRow");
	};
	self.updateFilters = function() {
		if (!self.dropdownData) return;
		const getId = function (row) {return row.id.replace("meeting-data-row-", "")};
		// The options available for this filter have to take into account all other filters, but ignore the
		// filter itself (otherwise there's only one option!)
		self.dropdownData.forEach(function(dropdown, index) {
			let hidden = [];
			jQuery(".filter-dropdown").each(function(index, filter) {
				if (filter.id === dropdown.elementId) return;
				const dataValue = filter.value.replace("a-", "");
				if (dataValue === "") return;
				filteringDropdown = true;
				const dataType = filter.getAttribute("data-pointer").toLowerCase();
				if (dataType !== "formats" && dataType !== "languages" && dataType !== "venues" && dataType !== "common_needs") {
					jQuery(".bmlt-data-row").not("[data-" + dataType + "='" + dataValue + "']").each((i,item) => hidden.push(getId(item)));
				} else {
					jQuery(".bmlt-data-row").not("[data-" + dataType + "~='" + dataValue + "']").each((i,item) => hidden.push(getId(item)));
				}
			});
			hidden = [...new Set(hidden)];
			let showing = self.meetingData.filter((m) => !(hidden.includes(m.id_bigint)));
			dropdown.optionsShowing = dropdown.uniqueData(showing).map((o) => dropdown.optionName(o));
		});
	}
	self.renderStandaloneMap = function (selector, context, callback=null, fitBounds=true) {
		hbs_Crouton['localization'] = self.localization;
		window.crouton = self;
		self.setUpPartials();
		croutonMap.initialize(self.createBmltMapElement(),self.meetingData,context,null,fitBounds,callback,self.config['noMap']);
	}
	self.retrieveGeolocation = function() {
		return new Promise((resolve, reject) => {
			if (window.storedGeolocation) {
				resolve(window.storedGeolocation);
			} else if (navigator.geolocation) {
				navigator.geolocation.getCurrentPosition((position) => {
					window.storedGeolocation = {
						latitude: position.coords.latitude,
						longitude: position.coords.longitude
					};
					resolve(window.storedGeolocation);
				}, (error) => {
					reject(new Error('Error getting geolocation: ' + error.message));
				});
			} else {
				reject(new Error('Geolocation is not supported by this browser.'));
			}
		});
	};
	self.getCurrentLocation = function(callback) {
		self.gretrieveGeolocation().then(position => {
			callback(position);
		}).catch(error => {
			jQuery('.geo').removeClass("hide").addClass("show").html(`<p>${error.message}</p>`);
		});
	};
	self.renderView = function (selector, context, callback, fitBounds) {
		hbs_Crouton['localization'] = self.localization;
		var template = hbs_Crouton.templates['main'];
		jQuery(selector).html(template(context));
		callback();
	};
	self.updateMeetingCount = function(showingNow=null) {
		var self = this;
		let meetingCount = self.meetingData.length;
		if (self.meetingCountCallback) self.meetingCountCallback(meetingCount);
		if (self.groupCountCallback) self.groupCountCallback(
			self.config.groups ? self.config.meetingData.length : self.convertToGroups(self.config.meetingData).length
		);
		addLive = function(id) {return id+", "+id+"-live"};
		if (showingNow !== null) {
			meetingCount = showingNow.length;
			addLive = function(id) {return id+"-live"};
		}
		self.showingNowCount = meetingCount;
		jQuery(".crouton_root_service_body").each(function() {
			var text = "";
			var field = 'name';
			if (this.dataset.field) field = this.dataset.field;
			if (self.config['service_body'].length > 0) {
				const sb = self.getServiceBodyDetails(self.config['service_body'][0]);
				if (sb) text = sb[field] ? sb[field] : "";
			}
			jQuery(this).text(text);
		});
		jQuery(addLive('#bmlt_tabs_meeting_count')).text(meetingCount);
		jQuery(addLive('#bmlt_tabs_group_count')).each(function(){
			var filteredMeetings = self.meetingData;
			if (showingNow!==null) filteredMeetings = self.meetingData.filter((m) => showingNow.includes(m.id_bigint));
			const groups = self.config.groups ? filteredMeetings : self.convertToGroups([...filteredMeetings]);
			jQuery(this).text(arrayUnique(groups).length);
		});
		jQuery(addLive('#bmlt_tabs_service_body_names')).each(function() {
			var filteredMeetings = self.meetingData;
			if (showingNow!==null) filteredMeetings = self.meetingData.filter((m) => showingNow.includes(m.id_bigint));
			var ids = getUniqueValuesOfKey(filteredMeetings, 'service_body_bigint');
			var me = this;
			self.getServiceBodies(ids, false).then(function (service_bodies) {
				var n = service_bodies.length;
				var names = service_bodies.map((m)=>m['name']);
				names.sort();
				var ret = "";
				if (n===1) {
					ret = names[0];
				}
				else {
					ret = names[0];
					for (var j = 1; j < n-1; j++) {
						ret += ', ';
						ret += names[j];
					}
					ret += ' and ' + names[n-1];
				}
				jQuery(me).text(ret);
			});
		});
	}
	self.getServiceBodies = function(service_bodies_id, requires_parents=true) {
		var url = this.config['root_server'] + '/client_interface/jsonp/?switcher=GetServiceBodies'
			+ (requires_parents ? '&parents=1' : '') + getServiceBodiesQueryString(service_bodies_id);
		return fetchJsonp(url)
			.then(function(response) {
				return response.json();
			});
	};

	self.getMasterFormats = function() {
		var url = this.config['root_server'] + '/client_interface/jsonp/?switcher=GetFormats&lang_enum=en&key_strings[]=TC&key_strings[]=VM&key_strings[]=HY';
		return fetchJsonp(url)
			.then(function(response) {
				return response.json();
			});
	}

	self.errorHandler = function(msg) {
		jQuery('.geo').removeClass("hide").addClass("show").html('');
	};

	self.handlebars = function(meetingDetailsData, elements) {
		var mustDoMap = false;
		handlebarMapOptions = [];
		crouton_Handlebars.registerHelper('crouton_map', function(options) {
			mustDoMap = true;
			self.handlebarMapOptions = options.hash;
			if (!self.handlebarMapOptions.zoom) self.handlebarMapOptions.zoom = 14;
			self.handlebarMapOptions.lat = parseFloat(meetingDetailsData.latitude);
			self.handlebarMapOptions.lng = parseFloat(meetingDetailsData.longitude);
			return "<div id='bmlt-handlebars-map' class='bmlt-map'></div>"
		});
		var parser = new DOMParser();

		while (elements.length > 0) {
			var element = elements.item(0);
			if (!element.firstChild) {
				console.log('<bmlt-handlebar> tag must have at least one child');
				element.remove();
				continue;
			}
			var templateString = '';
			if (element.firstChild.nodeType === 1) {
				if (!element.firstChild.firstChild || element.firstChild.firstChild.nodeType !== 3) {
					console.log('<bmlt-handlebar> tag: cannot find textnode');
					element.remove();
					continue;
				}
				templateString = element.firstChild.firstChild.textContent;
			} else if (element.firstChild.nodeType === 3) {
				templateString = element.firstChild.textContent;
			}
			var handlebarResult;
			try {
				var template = crouton_Handlebars.compile(templateString);
				handlebarResult = template(meetingDetailsData);
			} catch (e) {
				console.log(e);
				handlebarResult = e.message;
			}
			var htmlDecode = parser.parseFromString('<body>'+handlebarResult+'</body>', "text/html");
			if (!htmlDecode.body || !htmlDecode.body.firstChild) {
				console.log('<bmlt-handlebar> tag: could not parse the Handlebars result');
				element.replaceWith('<bmlt-handlebar> tag: could not parse the Handlebars result');
				continue;
			}
			var firstPart = htmlDecode.body.firstChild;
			var brothers = [];
			var thisPart = firstPart;
			var nextPart = null;
			while (nextPart = thisPart.nextSibling) {
				thisPart = nextPart;
				brothers.push(thisPart);
			}
			element.replaceWith(firstPart);
			if (brothers) firstPart.after(...brothers);
		}
		if (mustDoMap) {
			croutonMap.loadPopupMap("bmlt-handlebars-map", meetingDetailsData, self.handlebarMapOptions);
		}
	}
	self.meetingCountCallback = null;
	self.grouoCountCallback = null;
	Crouton.prototype.meetingCount = function(f) {
		self.meetingCountCallback = f;
	}
	Crouton.prototype.groupCount = function(f) {
		self.groupCountCallback = f;
	}
	Crouton.prototype.filterNext24 = function(filterNow = true) {
		if (!filterNow) {
			jQuery("#filter-dropdown-next24").val('a-');
			self.filterMeetingsFromView();
			return;
		}
		const date = new Date();
		const dayNow = date.getDay();
		const hour = date.getHours();
		const mins = date.getMinutes();
		const next24 = self.meetingData.filter(function(meeting) {
			var weekday = meeting.weekday_tinyint - 1;
			if (weekday == dayNow) {
				var time = meeting.start_time.toString().split(':');
				var meetingHour = parseInt(time[0]);
				if (meetingHour > hour) {
					return true;
				}
				if (meetingHour == hour) {
					if (parseInt(time[1]) > mins) {
						return true;
					}
				}
			} else if (weekday == (dayNow + 1) % 7) {
				return true;
			}
			return false;
		}).map((m)=>m.id_bigint);
		jQuery(".bmlt-data-row").each(function(index,row) {
			row.dataset.next24 = (next24.includes(row.id.split('-').pop())) ? '1' : '0';
		});
		jQuery("#filter-dropdown-next24").val('a-1');
		self.filterMeetingsFromView();
	}

	self.toFarsinNumber = function( n ) {
		const farsiDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
		const ampm = {'AM':'صبح', 'PM':'بعدازظهر'};
		n = n.replace(/\d/g, x => farsiDigits[x]);
		n = n.replace(/AM|am/g, ampm['AM']);
		n = n.replace(/PM|pm/g, x => ampm['PM']);
		return n;
	}
	self.enrichMeetings = function (meetingData) {
		var meetings = [];

		let queryStringChar = '?';
		if (self.config.meeting_details_href) {
			if (self.config.meeting_details_href.indexOf('?') >= 0) queryStringChar = '&';
		}
		for (var m = 0; m < meetingData.length; m++) {
			meetingData[m]['formatted_comments'] = meetingData[m]['comments'];
			var duration = meetingData[m]['duration_time'].split(":");
			// convert from bmlt day to iso day
			meetingData[m]['start_time_raw'] = this.getAdjustedDateTime(
				parseInt(meetingData[m]['weekday_tinyint']) === 1 ? 7 : parseInt(meetingData[m]['weekday_tinyint']) - 1,
				meetingData[m]['start_time'],
				meetingData[m]['time_zone']
			);
			meetingData[m]['start_time_formatted'] = meetingData[m]['start_time_raw'].format(self.config['time_format']);
			meetingData[m]['end_time_formatted'] = meetingData[m]['start_time_raw']
				.clone()
				.add(duration[0], 'hours')
				.add(duration[1], 'minutes')
				.format(self.config['time_format']);
			if (self.config.language === 'fa-IR') {
				meetingData[m]['start_time_formatted'] = self.toFarsinNumber(meetingData[m]['start_time_formatted']);
				meetingData[m]['end_time_formatted'] = self.toFarsinNumber(meetingData[m]['end_time_formatted']);
			}

			// back to bmlt day
			meetingData[m]['day_of_the_week'] = meetingData[m]['start_time_raw'].isoWeekday() === 7 ? 1 : meetingData[m]['start_time_raw'].isoWeekday() + 1;
			meetingData[m]['formatted_day'] = self.localization.getDayOfTheWeekWord(meetingData[m]['day_of_the_week']);

			var formats = meetingData[m]['formats'].split(",");
			var formats_expanded = [];
			let formatRootServer = self.formatsData.filter((f)=>f['root_server_uri'] == meetingData[m]['root_server_uri']);
			meetingData[m]['wheelchair'] = false;
			for (var f = 0; f < formats.length; f++) {
				for (var g = 0; g < formatRootServer.length; g++) {
					if (formats[f] === formatRootServer[g]['key_string']) {
						if (formatRootServer[g]['world_id'] == 'WCHR') meetingData[m]['wheelchair'] = true;
						formats_expanded.push(
							{
								"id": formatRootServer[g]['id'],
								"key": formats[f],
								"name": formatRootServer[g]['name_string'],
								"description": formatRootServer[g]['description_string'],
								"type": formatRootServer[g]['format_type_enum'],
							}
						)
					}
				}
			}

			meetingData[m]['venue_type'] = parseInt(meetingData[m]['venue_type']);
			meetingData[m]['venue_type_name'] = getVenueTypeName(meetingData[m]);
			meetingData[m]['formats_expanded'] = formats_expanded;
			var addressParts = [
				meetingData[m]['location_street'],
				meetingData[m]['location_municipality'].trim(),
				meetingData[m]['location_province'].trim(),
				meetingData[m]['location_postal_code_1'].trim()
			];
			addressParts.clean();
			meetingData[m]['formatted_address'] = addressParts.join(", ");
			meetingData[m]['formatted_location_info'] =
				meetingData[m]['location_info'] != null
					? meetingData[m]['location_info'].replace('/(http|https):\/\/([A-Za-z0-9\._\-\/\?=&;%,]+)/i', '<a style="text-decoration: underline;" href="$1://$2" target="_blank">$1://$2</a>')
					: "";
			meetingData[m]['map_word'] = self.localization.getWord('map');
			meetingData[m]['share_word'] = self.localization.getWord('share');
			meetingData[m]['report_update_word'] = self.localization.getWord('report update');
			meetingData[m]['show_qrcode'] = self.config['show_qrcode'];
			for (var k in meetingData[m]) {
				if (meetingData[m].hasOwnProperty(k) && typeof meetingData[m][k] === 'string') {
					if (meetingData[m][k].indexOf('#@-@#') !== -1) {
						var split = meetingData[m][k].split('#@-@#');
						meetingData[m][k] = split[split.length - 1];
					}
				}
			}

			var serviceBodyInfo = self.getServiceBodyDetails(meetingData[m]['service_body_bigint'])
			meetingData[m]['serviceBodyUrl'] = serviceBodyInfo["url"];
			meetingData[m]['serviceBodyPhone'] = serviceBodyInfo["helpline"];
			meetingData[m]['serviceBodyName'] = serviceBodyInfo["name"];
			meetingData[m]['serviceBodyDescription'] = serviceBodyInfo["description"];
			meetingData[m]['serviceBodyContactEmail'] = serviceBodyInfo["contact_email"];
			meetingData[m]['serviceBodyType'] = self.localization.getServiceBodyType(serviceBodyInfo["type"]);

			var parentBodyInfo = self.getServiceBodyDetails(serviceBodyInfo["parent_id"]);
			if (parentBodyInfo !== undefined) {
				meetingData[m]['parentServiceBodyId'] = serviceBodyInfo["parent_id"];
				meetingData[m]['parentServiceBodyUrl'] = parentBodyInfo["url"];
				meetingData[m]['parentServiceBodyPhone'] = parentBodyInfo["helpline"];
				meetingData[m]['parentServiceBodyName'] = parentBodyInfo["name"];
				meetingData[m]['parentServiceBodyDescription'] = parentBodyInfo["description"];
				meetingData[m]['parentServiceBodyType'] = self.localization.getServiceBodyType(parentBodyInfo["type"]);
			}

			meetingData[m]['meeting_details_url'] = '';
			if (self.config.meeting_details_href) {
				meetingData[m]['meeting_details_url'] = self.config.meeting_details_href;
				if (meetingData[m]['venue_type'] === 2 && self.config.virtual_meeting_details_href ) {
					meetingData[m]['meeting_details_url'] = self.config.virtual_meeting_details_href;
				}
				meetingData[m]['meeting_details_url'] += queryStringChar + ('meeting-id=' + meetingData[m]['id_bigint']
													   + '&language=' + self.config.language
													   + '&time_format=' + encodeURIComponent(self.config.time_format)
													   + (self.config.force_rootserver_in_querystring ? '&root_server=' + encodeURIComponent(self.config.root_server) : '')
													);
			}
			this.calculateDistance(meetingData[m]);
			meetings.push(meetingData[m])
		}
		if (self.config.groups) {
			return self.convertToGroups(meetings);
		}
		return meetings;
	};
	self.convertToGroups = function(meetings) {
		if (!meetings || !meetings.length) return [];
		if (meetings[0].hasOwnProperty('membersOfGroup')) return meetings;
		if (!meetings[0].hasOwnProperty('group_id')) {
			meetings.forEach((meeting) =>
				meeting['group_id'] = meeting['service_body_bigint'] + '|' + meeting['meeting_name'] +
					((meeting['venue_type'] != 2) ? ('|' + parseFloat(meeting['latitude']).toFixed(6) + '|' + parseFloat(meeting['longitude']).toFixed(6))
												 : meeting['virtual_meeting_link'] + '|' + meeting['virtual_meeting_additional_info']));
		}
		// There are so many, I think this is faster than using reduce.
		const sorted = meetings.sort((a,b) => {
			if (a['group_id'] < b['group_id']) return -1;
			if (a['group_id'] > b['group_id']) return 1;
			return 0;
		});
		const groups = [];
		let last = null;
		sorted.forEach(function (meeting) {
			if (!meeting['group_id']) {
				groups.push(meeting);
				meeting['membersOfGroup'] = [meeting];
			} else if (!last || meeting['group_id'] != last['group_id']) {
				groups.push(meeting);
				last = meeting;
				last['membersOfGroup'] = [Object.assign({}, last)];
			} else {
				last['membersOfGroup'].push(meeting);
			}
		});
		groups.forEach(function(group) {
			if (group['membersOfGroup'].length > 1) {
				let commonFormats = group['formats'].split(',');
				group['membersOfGroup'].forEach(function(member) {
					const memberFormats = member['formats'].split(',');
					commonFormats = commonFormats.filter(value => memberFormats.includes(value));
				});
				group['formats'] = commonFormats.join(',');
				if (group['formats_expanded']) group['formats_expanded'] = group['formats_expanded'].filter((format) => commonFormats.includes(format['key']));
				group['membersOfGroup'].forEach(function(member) {
					member['formats'] = member['formats'].split(',').filter((f) => !commonFormats.includes(f)).join(',');
					if (member['formats_expanded']) member['formats_expanded'] = member['formats_expanded'].filter((format) => !commonFormats.includes(format['key']));
				});
			}
		});
		return groups;
	}
	Crouton.prototype.updateDistances = function(initial=false) {
		const self = this;
		var knt = 0;
		jQuery('.meeting-distance').each(function(index) {
			const jThis = jQuery(this);
			const id = jQuery(this).data('id');
			if (!id) return;
			knt++;
			const m = self.meetingData.find((m) => m.id_bigint==id);
			self.calculateDistance(m);
			if (m['distance'] == '') {
				if (!jThis.hasClass('hide')) jThis.addClass('hide');
			} else {
				jThis.removeClass('hide');
				jQuery(this).html(self.localization.getWord('Distance')+': '+m['distance']);
				jQuery(this).closest('tr').data('distance', m['distance_in_km']);
			}
		});
		const parent = jQuery('#byfield_distance_in_km tbody');
		if (parent.length == 0) return;
		if (knt === 0) {
			parent.children().each(function (index) {
				if (!this.id) return;
				const id = this.id.replace("meeting-data-row-", "");
				const m = self.meetingData.find((m) => m.id_bigint==id);
				if (!m) return;
				self.calculateDistance(m);
				if (m['distance'] != '') {
					jQuery(this).data('distance', m['distance_in_km']);
					knt++;
				}
			});
		}
		const sorted = parent.children().sort(function (a, b) {
			const idA =parseFloat( jQuery(a).data('meetingid').replace("meeting-data-row-", ""));
			const idB =parseFloat( jQuery(b).data('meetingid').replace("meeting-data-row-", ""));
			const dataA = self.meetingData.find((m) => m.id_bigint==idA);
			const dataB = self.meetingData.find((m) => m.id_bigint==idB);
			const distanceA = dataA ? parseFloat(dataA['distance_in_km']) : Number.POSITIVE_INFINITY;
			const distanceB = dataB ? parseFloat(dataB['distance_in_km']) : Number.POSITIVE_INFINITY;
      		return (distanceA < distanceB) ? -1 : (distanceA > distanceB) ? 1 : 0;
   		});
		parent.html(sorted);
		jQuery("#byfield_distance_in_km tbody .bmlt-data-row").css({cursor: "pointer"});
		jQuery("#byfield_distance_in_km tbody .bmlt-data-row").click(function (e) {
			if (e.target.tagName !== 'A')
				croutonMap.rowClick(parseInt(this.id.replace("meeting-data-row-", "")));
		});
		if (knt > 0) {
			jQuery('#groupingButton_distance_in_km').removeClass('hide');
			self.distanceTabAllowed = true;
			if (initial && self.config.view_by === "distance") self.groupedView("distance_in_km");
		}
	}
	self.registerPartial = function(name, template) {
		crouton_Handlebars.registerPartial(name, crouton_Handlebars.compile(template));
	};
	self.setUpPartials = function() {
		crouton_Handlebars.registerPartial('tableDataRow',
			self.config.groups
			? (self.config.details_table
				? "<td>{{> groupStackedRow}}</td>"
				: hbs_Crouton.templates['group3ColumnRow'])
			: (self.config.details_table
				? "<td>{{> meetingStackedRow}}</td>"
				: hbs_Crouton.templates['meeting3ColumnRow'])
			);


			self.registerPartial("meetingDataTemplate", self.config['meeting_data_template']);
			self.registerPartial("meetingDataTemplate", self.config['meeting_data_template']);
			self.registerPartial("metaDataTemplate", self.config['metadata_template']);
			self.registerPartial("observerTemplate", self.config['observer_template']);
			self.registerPartial("meetingpageTitleTemplate", self.config['meetingpage_title_template']);
			self.registerPartial("meetingDetailsContentsTemplate", self.config['meetingdetails_contents_template']);
			self.registerPartial("meetingCountTemplate", self.config['meeting_count_template']);
			self.registerPartial("meetingTimesTemplate", self.config['meeting_times_template']);
			self.registerPartial("groupData", self.config['group_data_template']);
			self.registerPartial("groupDetailsContents", self.config['group_details_template']);
			self.registerPartial("memberDetails", self.config['member_details_template']);
			self.registerPartial("groupTitle", self.config['group_title_template']);

			const handlebarsExtensions = new CroutonHandlebarsExtensions();
			handlebarsExtensions.registerHelpers();
			handlebarsExtensions.registerPartials(self.config.groups);
	}
	self.calculateDistance = function(meetingData) {
		meetingData['distance'] = '';
		if (meetingData['venue_type'] != 2) {
			const point = {"lat": meetingData['latitude'], "lng": meetingData['longitude']};
			const distances = croutonMap.getDistanceFromSearch(point);
			if (distances) {
				meetingData['distance_in_km'] = distances.km;
				meetingData['distance_in_miles'] = distances.miles;

				if (self.config['distance_units'] === "km") {
					if (meetingData['distance_in_km']) {
						const d = meetingData['distance_in_km'];
						if (d < 1) {
							meetingData['distance'] = Math.round( d * 1000) + 'm';
						}
						else {
							meetingData['distance'] = (Math.round(d * 10) / 10).toFixed(1) + 'km';
						}
					}
				} else if (meetingData['distance_in_miles']) {
					const d = meetingData['distance_in_miles'];
					meetingData['distance'] = (Math.round(d * 100) / 100).toFixed(2) + ' miles';
				}
			}
		}
	}
	self.showMessage = function(message) {
		jQuery("#" + self.config['placeholder_id']).html("crouton: " + message);
		jQuery("#" + self.config['placeholder_id']).removeClass("hide");
	};
	self.getUsedVenueType = function(meetings) {
		let venueTypes = getUniqueValuesOfKey(meetings, 'venue_type');
		if (venueTypes.includes(3)) return Object.values(self.localization.getWord("venue_type_choices"));
		if (venueTypes.length === 2) return Object.values(self.localization.getWord("venue_type_choices"));
		if (venueTypes[0] === 1) return [self.localization.getWord("venue_type_choices").IN_PERSON];
		return [self.localization.getWord("venue_type_choices").VIRTUAL];
	}
	self.getUsedVisibility = function(meetings) {
		return [{name: 'Visible', value: 1}];
	}
	self.getUsedNext24 = function(meetings) {
		return [{name: 'Next24', value: 1}];
	}
	self.isEmpty = function(obj) {
		for (var key in obj) {
			if(obj.hasOwnProperty(key))
				return false;
		}
		return true;
	};
	self.createBmltMapElement = function() {
		if (!document.getElementById('bmlt-map')) {
			jQuery("#bmlt-tabs").before("<div id='bmlt-map' class='bootstrap-bmlt bmlt-map "+self.localization.getWord('css-direction')+" bmlt_map_container_div'></div>");
		}
		return 'bmlt-map';
	}
	if (typeof window.croutonMap === 'undefined') {
		window.croutonMap = new MeetingMap(self.config);
		if (self.config['map_search']) self.searchMap();
		else self.meetingSearch();
	}
	else if (!window.croutonMap.hasMapSearch()) self.meetingSearch();
}

Crouton.prototype.setConfig = function(config) {
	var self = this;
	const deprecatedNames = {
		button_filters: 'grouping_buttons',
		button_format_filters: 'formattype_grouping_buttons',
	}
	for (var propertyName in deprecatedNames) {
		if (config.hasOwnProperty(propertyName)) {
			config[deprecatedNames[propertyName]] = config[propertyName];
			delete config[deprecatedNames[propertyName]];
		}
	}
	for (var propertyName in config) {
		if (propertyName.indexOf("_template") > 0 && config[propertyName].trim() === "") {
			continue;
		} else if (propertyName.indexOf("int_") === -1) {
			if (config[propertyName] === "1" || config[propertyName] === 1) {
				self.config[propertyName] = true;
			} else if (config[propertyName] === "0" || config[propertyName] === 0) {
				self.config[propertyName] = false;
			} else {
				self.config[propertyName] = config[propertyName];
			}
		} else {
			self.config[propertyName] = parseInt(config[propertyName] || 0);
		}
	}
	if (self.config.show_map === "embed") {
		self.config.show_map = false;
		self.config.map_page = true;
	}
	self.config["day_sequence"] = [];
	self.config.day_sequence.push(self.config.int_start_day_id);
	for (var i = 1; i < 7; i++) {
		var next_day = self.config.day_sequence[i - 1] + 1;
		if (next_day > 7) {
			self.config.day_sequence.push(next_day - 7);
		} else {
			self.config.day_sequence.push(next_day);
		}
	}
	if (self.config.groups) {
		self.config["view_by"] = "city";
		self.config["include_weekday_button"] = false;
		self.config["has_tabs"] = false;
	}
	if (self.config["view_by"].endsWith('day')) {
		self.config["include_weekday_button"] = true;
	}
	self.currentView = self.config["view_by"];

	// https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
	// We hardcode override Dansk because of a legacy issue in the root server that doesn't follow ISO 639 standards.
	self.config['short_language'] = self.config['language'] === "da-DK" ? "dk" : self.config['language'].substring(0, 2);
	self.localization = new CroutonLocalization(self.config['language']);
	if (config.custom_translations && config.custom_translations.trim() !== "") {
		try {
			self.localization.customizeTranslations(JSON.parse(config.custom_translations));
		} catch (e) {
			console.log("Error parsing custom translations: " + e.message);
		}
	}
};

Crouton.prototype.reset = function() {
	var self = this;
	jQuery("#custom-css").remove();
	jQuery("#" + self.config["placeholder_id"]).html("");
};

Crouton.prototype.doFilters = function() {
	return this.filterMeetingsFromView();
}
Crouton.prototype.getServiceBodyDetails = function(serviceBodyId) {
	var self = this;
	for (var s = 0; s < self.all_service_bodies.length; s++) {
		var service_body = self.all_service_bodies[s];
		if (service_body['id'] === serviceBodyId) {
			return service_body;
		}
	}
}

Crouton.prototype.doHandlebars = function() {
	var elements = document.getElementsByTagName('bmlt-handlebar');
	if (elements.length === 0) {
		console.log('No <bmlt-handlebar> tags found');
		return;
	};
	var self = this;
	self.lock(function() {
		if (self.isEmpty(self.meetingData)) {
			for (let i = 0; i < elements.length; i++) {
				var element = elements.item(i);
				element.innerHTML = "Meeting not found!";
			}
			return;
		}
		var promises = [self.getServiceBodies([self.meetingData[0]['service_body_bigint']])];
		Promise.all(promises)
			.then(function(data) {
				hbs_Crouton['localization'] = self.localization;
				self.all_service_bodies = [];
				var service_bodies = data[0];
				for (var i = 0; i < service_bodies.length; i++) {
					self.all_service_bodies.push(service_bodies[i]);
				}
				var enrichedMeetingData = self.enrichMeetings(self.meetingData);
				self.setUpPartials();
				var customStartupTemplate = crouton_Handlebars.compile('{{startup}}');
				customStartupTemplate(enrichedMeetingData);
				var customEnrichTemplate = crouton_Handlebars.compile('{{enrich this}}');
				customEnrichTemplate(enrichedMeetingData[0]);

				self.handlebars(enrichedMeetingData[0], elements);
				jQuery('.get-directions-modal').on('click', openDirectionsModal);
			});
	});
};

Crouton.prototype.meetingModal = function(meetingId) {
	let self = this;
	this.openMeetingModal(self.meetingData.find((m) => m.id_bigint == meetingId));
	return;
}
Crouton.prototype.openMeetingModal = function(meeting) {
	let self = this;
	crouton_Handlebars.registerHelper('crouton_map', function() {
		return "<div id='bmlt-handlebars-map' class='bmlt-map'></div>"
	});
	let template = hbs_Crouton.templates['meetingModal'];
	const tabs = document.getElementById('bmlt-tabs');
	let div = document.createElement('div');
	tabs.appendChild(div);
	div.innerHTML = template(meeting);
	[...tabs.getElementsByClassName('modal-close')].forEach((elem)=>elem.addEventListener('click', (e)=>{croutonMap.closeModalWindow(e.target); document.getElementById('meeting_modal').remove()}));
	let mm = document.getElementById('meeting_modal');
	document.body.appendChild(mm);
	jQuery('#meeting_modal .get-directions-modal').on('click', openDirectionsModal);
	croutonMap.openModalWindow(mm, true);
	croutonMap.loadPopupMap("bmlt-handlebars-map", meeting, {
		lat: parseFloat(meeting.latitude),
		lng: parseFloat(meeting.longitude),
		zoom: 14
	});
	let visibleMeetings = jQuery('.bmlt-data-row:visible');
	let index = -1;
	const prefix = "meeting-data-row-";
	for (k=0; k<visibleMeetings.length; k++) {
		if (visibleMeetings[k].id===prefix+meeting.id_bigint) {
			index = k;
			break;
		}
	};
	let doSwipe = function(swipedir) {
		switch(swipedir) {
			case 'left':
				index = index+1;
				break;
			case 'right':
				index = index-1;
				break;
			default:
				index = -1;
		}
		if (index >= 0 && index < visibleMeetings.length) {
			const newMeeting = visibleMeetings[index];
			meetingId = newMeeting.id.substring(prefix.length);
			mm.getElementsByClassName('modal-close').item(0).dispatchEvent(new MouseEvent("click"));
			self.meetingModal(meetingId);
		}
	}
	swipedetect(mm, doSwipe);
	if (index <= 0) {
		jQuery(".modal-left").addClass("hide");
	} else {
		mm.getElementsByClassName('modal-left').item(0).addEventListener("click", ev=>doSwipe("right"));
	}
	if (index >= visibleMeetings.length-1) {
		jQuery(".modal-right").addClass("hide");
	} else {
		mm.getElementsByClassName('modal-right').item(0).addEventListener("click", ev=>doSwipe("left"));
	}
}
Crouton.prototype.searchMap = function() {
	var self = this;
	self.distanceTabAllowed = true;
	if (!self.config.map_search || typeof self.config.map_search !== 'object') {
		self.config.map_search = {
			width: -50,
			auto: true,
			zoom: 14
		};
	} else {
		if (!self.config.map_search.width) self.config.map_search.width = -50;
		if (!self.config.map_search.location && !self.config.map_search.coordinates_search)
			self.config.map_search.auto = true;
		if (!self.config.map_search.zoom) {
			self.config.map_search.zoom = 14;
		}
	}
	self.config['map_page'] = false;
	self.config['show_map'] = false;
	var body = jQuery("body");
	if (self.config['theme'] !== '') {
		body.append("<div id='custom-css'><link rel='stylesheet' type='text/css' href='" + self.config['template_path'] + '/themes/' + self.config['theme'] + ".css'>");
	}

	body.append("<div id='custom-css'><style type='text/css'>" + self.config['custom_css'] + "</style></div>");

	self.meetingData = null;
	self.renderStandaloneMap("#" + self.config['placeholder_id'], {
		"config": self.config,
		"meetings": {
			"weekdays": [],
			"groupingButtons": [],
			"formattypeGroupingButtons": [],
			"bydays": [],
			"meetingCount": 0,
			"meetingData": []
		},
		"dropdownData": [],
		"location": {'latitude':0,'longitude':0,'zoom':10}  // TODO: Where is this used?
	});
}
Crouton.prototype.render = function(doMeetingMap = false, fitBounds=true) {
	var self = this;

	self.lock(function() {
		var body = jQuery("body");
		if (self.config['theme'] !== '') {
			body.append("<div id='custom-css'><link rel='stylesheet' type='text/css' href='" + self.config['template_path'] + '/themes/' + self.config['theme'] + ".css'>");
		}

		body.append("<div id='custom-css'><style type='text/css'>" + self.config['custom_css'] + "</style></div>");

		if (self.isEmpty(self.meetingData)) {
			jQuery('#please-wait').remove();
			self.showMessage("No meetings found for parameters specified.");
			alert("No meetings found for parameters specified.");
			if (self.config['refresh_map']) {
				croutonMap.refreshMeetings(self.meetingData, fitBounds, true);
			}
			return;
		}

		self.unique_service_bodies_ids = getUniqueValuesOfKey(self.meetingData, 'service_body_bigint').sort();
		var promises = [self.getMasterFormats(), self.getServiceBodies(self.unique_service_bodies_ids)];
		Promise.all(promises)
			.then(function(data) {
				self.all_service_bodies = [];
				self.masterFormatCodes = data[0];
				var service_bodies = data[1];
				//TODO: why does he do this???
				for (var i = 0; i < service_bodies.length; i++) {
					self.all_service_bodies.push(service_bodies[i]);
				}
				if (!jQuery.isEmptyObject(self.formatsData)) {
					self.formatsData = self.formatsData.sortByKey('name_string');
				}

				var enrichedMeetingData = self.enrichMeetings(self.meetingData);
				if (self.config.groups) self.meetingData = enrichedMeetingData;
				self.setUpPartials();

				enrichedMeetingData.sort(function (a, b) {
					if (a['start_time_raw'] < b['start_time_raw']) {
						return -1;
					}

					if (a['start_time_raw'] > b['start_time_raw']) {
						return 1;
					}

					return 0;
				});

				var day_counter = 0;
				var byDayData = [];
				var groupingButtonsData = {};
				var formattypeGroupingButtonsData = {};
				var weekdaysData = [];
				while (day_counter < 7) {
					var day = self.config.day_sequence[day_counter];
					var daysOfTheWeekMeetings = enrichedMeetingData.filterByObjectKeyValue('day_of_the_week', day);
					weekdaysData.push({
						"day": day,
						"meetings": daysOfTheWeekMeetings
					});

					byDayData.push({
						"day": self.localization.getDayOfTheWeekWord(day),
						"meetings": daysOfTheWeekMeetings
					});

					for (var f = 0; f < self.config.grouping_buttons.length; f++) {
						var groupByName = self.config.grouping_buttons[f]['field'];
						if (groupByName.startsWith('distance')) continue;
						var groupByData = getUniqueValuesOfKey(daysOfTheWeekMeetings, groupByName).sort();
						for (var i = 0; i < groupByData.length; i++) {
							var groupByMeetings = daysOfTheWeekMeetings.filterByObjectKeyValue(groupByName, groupByData[i]);
							if (groupingButtonsData.hasOwnProperty(groupByName) && groupingButtonsData[groupByName].hasOwnProperty(groupByData[i])) {
								groupingButtonsData[groupByName][groupByData[i]] = groupingButtonsData[groupByName][groupByData[i]].concat(groupByMeetings);
							} else if (groupingButtonsData.hasOwnProperty(groupByName)) {
								groupingButtonsData[groupByName][groupByData[i]] = groupByMeetings;
							} else {
								groupingButtonsData[groupByName] = {};
								groupingButtonsData[groupByName][groupByData[i]] = groupByMeetings;
							}

						}
					}

					for (var f = 0; f < self.config.formattype_grouping_buttons.length; f++) {
						const groupByName = self.config.formattype_grouping_buttons[f]['field'];
						const accordionState = self.config.formattype_grouping_buttons[f].hasOwnProperty('accordionState')
							? self.config.grouping_buttons[b]['accordionState'] : '';
						var groupByData = getUniqueFormatsOfType(daysOfTheWeekMeetings, groupByName);
						if (groupByName=='LANG' && self.config.native_lang && self.config.native_lang.length > 0) {
							groupByData = groupByData.filter((f) => f.key != self.config.native_lang);
						}
						for (var i = 0; i < groupByData.length; i++) {
							var groupByMeetings = daysOfTheWeekMeetings.filter((item) => item.formats_expanded.map(f => f.key).indexOf(groupByData[i].key) >= 0);
							if (formattypeGroupingButtonsData.hasOwnProperty(groupByName) && formattypeGroupingButtonsData[groupByName].hasOwnProperty(groupByData[i].description)) {
								formattypeGroupingButtonsData[groupByName][groupByData[i].description].group = formattypeGroupingButtonsData[groupByName][groupByData[i].description].group.concat(groupByMeetings);
							} else if (formattypeGroupingButtonsData.hasOwnProperty(groupByName)) {
								formattypeGroupingButtonsData[groupByName][groupByData[i].description] = {};
								formattypeGroupingButtonsData[groupByName][groupByData[i].description].accordionState = accordionState;
								formattypeGroupingButtonsData[groupByName][groupByData[i].description].group = groupByMeetings;
							} else {
								formattypeGroupingButtonsData[groupByName] = {};
								formattypeGroupingButtonsData[groupByName][groupByData[i].description] = {};
								formattypeGroupingButtonsData[groupByName][groupByData[i].description].accordionState = accordionState;
								formattypeGroupingButtonsData[groupByName][groupByData[i].description].group = groupByMeetings;
							}
						}
					}
					day_counter++;
				}

				var groupingButtonsDataSorted = {};
				for (var b = 0; b < self.config.grouping_buttons.length; b++) {
					const groupByName = self.config.grouping_buttons[b]['field'];
					const accordionState = self.config.grouping_buttons[b].hasOwnProperty('accordionState')
						? self.config.grouping_buttons[b]['accordionState'] : '';
					groupingButtonsDataSorted[groupByName] = {};
					if (groupByName.startsWith('distance')) {
						groupingButtonsDataSorted[groupByName][self.localization.getWord('Sorted by Distance')] = {};
						if (self.config.map_search) {
							groupingButtonsDataSorted[groupByName][self.localization.getWord('Sorted by Distance')].group = [...self.meetingData].sort((a,b) => a['distance_in_km'] - b['distance_in_km']);
						} else { // when not crouton_map, sorting byy distance is triggered by an action in meeting_map.
							groupingButtonsDataSorted[groupByName][self.localization.getWord('Sorted by Distance')].group = [...self.meetingData].filter(m => m.venue_type != 2);
						}
						groupingButtonsDataSorted[groupByName][self.localization.getWord('Sorted by Distance')].accordionState = 'non-collapsable';
						continue;
					}
					var sortKey = [];

					for (var groupingButtonsDataItem in groupingButtonsData[groupByName]) {
						sortKey.push(groupingButtonsDataItem);
					}

					sortKey.sort();

					for (var s = 0; s < sortKey.length; s++) {
						groupingButtonsDataSorted[groupByName][sortKey[s]] = {};
						groupingButtonsDataSorted[groupByName][sortKey[s]].group = groupingButtonsData[groupByName][sortKey[s]];
						groupingButtonsDataSorted[groupByName][sortKey[s]].accordionState = accordionState;
					}
				}

				self.dayNamesSequenced = self.config.day_sequence.map((d)=>self.localization.getDayOfTheWeekWord(d));
				self.dropdownData = [];
				if (self.config.has_days) self.dropdownData.push(
					{placeholder: self.localization.getWord('weekday'), pointer: 'weekdays', elementId: "filter-dropdown-weekdays",
					 uniqueData: (meetings) => sortListByList(getUniqueValuesOfKey(meetings, "formatted_day"), self.dayNamesSequenced),
					 objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_states) self.dropdownData.push(
					{placeholder: self.localization.getWord('states'), pointer: 'States', elementId: "filter-dropdown-states",
						uniqueData: (meetings) => getUniqueValuesOfKey(meetings, 'location_province').sort(),
						objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_sub_province) self.dropdownData.push(
					{placeholder: self.localization.getWord('counties'), pointer: 'Counties', elementId: "filter-dropdown-sub_province",
						uniqueData: (meetings) => getUniqueValuesOfKey(meetings, 'location_sub_province').sort(),
						objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_cities) self.dropdownData.push(
					{placeholder: self.localization.getWord('cities'), pointer: 'Cities', elementId: "filter-dropdown-cities",
					 uniqueData: (meetings) => getUniqueValuesOfKey(meetings, 'location_municipality').sort(),
					 objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_neighborhoods) self.dropdownData.push(
					{placeholder: self.localization.getWord('neighborhood'), pointer: 'Neighborhoods', elementId: "filter-dropdown-neighborhoods",
						uniqueData: (meetings) => getUniqueValuesOfKey(meetings, 'location_neighborhood').sort(),
						objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_zip_codes) self.dropdownData.push(
					{placeholder: self.localization.getWord('postal_codes'), pointer: 'Zips', elementId: "filter-dropdown-zipcodes",
						uniqueData: (meetings) => getUniqueValuesOfKey(meetings, 'location_postal_code_1').sort(),
						objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_locations) self.dropdownData.push(
					{placeholder: self.localization.getWord('locations'), pointer: 'Locations', elementId: "filter-dropdown-locations",
						uniqueData: (meetings) => getUniqueValuesOfKey(meetings, 'location_text').map((s)=>s.replace(/(<([^>]+)>)/gi, "")).sort(),
						objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_regions) self.dropdownData.push(
					{placeholder: self.localization.getWord('regions'), pointer: 'Regions', elementId: "filter-dropdown-regions",
						uniqueData: (meetings) => self.all_service_bodies.filter((sb)=>getUniqueValuesOfKey(meetings,'parentServiceBodyId').includes(sb.id)).sortByKey('name'),
						objectPointer: (a) => convertToPunyCode(a.name), optionName: (a)=>a.name});
				if (self.config.has_areas) self.dropdownData.push(
					{placeholder: self.localization.getWord('areas'), pointer: 'Areas', elementId: "filter-dropdown-areas",
						uniqueData: (meetings) => self.all_service_bodies.filter((sb)=>getUniqueValuesOfKey(meetings,'service_body_bigint').includes(sb.id)).sortByKey('name'),
						objectPointer: (a) => a.id, optionName: (a)=>a.name});
				if (self.config.has_groups) self.dropdownData.push(
					{placeholder: self.localization.getWord('groups'), pointer: 'Groups', elementId: "filter-dropdown-groups",
					uniqueData: (meetings) => getUniqueValuesOfKey(meetings, 'meeting_name').sort(),
					objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_venues) self.dropdownData.push(
					{placeholder: self.localization.getWord('venue_types'), pointer: 'Venues', elementId: "filter-dropdown-venues",
						uniqueData: (meetings) => self.getUsedVenueType(meetings),
						objectPointer: convertToPunyCode, optionName: (s)=>s});
				if (self.config.has_formats) self.dropdownData.push(
					{placeholder: self.localization.getWord('formats'), pointer: 'Formats', elementId: "filter-dropdown-formats",
						uniqueData: (meetings) => getUniqueFormats(meetings),
						objectPointer: (f) => convertToPunyCode(f.name), optionName: (f)=>f.name});
				if (self.config.has_languages) self.dropdownData.push(
					{placeholder: self.localization.getWord('languages'), pointer: 'Formats', elementId: "filter-dropdown-languages",
						uniqueData: (meetings) => getUniqueFormatsOfType(meetings, 'LANG').filter((f)=>f.key!==self.config.native_lang),
						objectPointer: (f) => convertToPunyCode(f.name), optionName: (f)=>f.name});
				if (self.config.has_common_needs) self.dropdownData.push(
					{placeholder: self.localization.getWord('common_needs'), pointer: 'Formats', elementId: "filter-dropdown-commonneeds",
						uniqueData: (meetings) => getUniqueFormatsOfType(meetings, 'FC3'),
						objectPointer: (f) => convertToPunyCode(f.name), optionName: (f)=>f.name});
				if (doMeetingMap || self.config.show_map || self.config.map_page) self.dropdownData.push(
					{placeholder: '', pointer: 'visible', elementId: "filter-dropdown-visibile",
						uniqueData: (meetings) => self.getUsedVisibility(meetings),
						objectPointer: (s)=>s.value, optionName: (s)=>s.name});
				if (doMeetingMap) self.dropdownData.push(
					{placeholder: '', pointer: 'next24', elementId: "filter-dropdown-next24",
						uniqueData: (meetings) => self.getUsedNext24(meetings),
						objectPointer: (s)=>s.value, optionName: (s)=>s.name});
				let renderer = doMeetingMap ? self.renderStandaloneMap : self.renderView;
				renderer("#" + self.config['placeholder_id'], {
					"config": self.config,
					"meetings": {
						"allMeetings": self.meetingData,
						"weekdays": weekdaysData,
						"groupingButtons": groupingButtonsDataSorted,
						"formattypeGroupingButtons": formattypeGroupingButtonsData,
						"bydays": byDayData,
						"meetingCount": self.meetingData.length,
						"meetingData": self.meetingData
					},
					"dropdownData": self.dropdownData
				}, function () {
					if (!self.config.map_search) {
						jQuery('#groupingButton_distance_in_km').addClass('hide');
					}
					self.addStripes();
					self.calcShowingNow()
					self.updateMeetingCount();
					jQuery('#please-wait').remove();
					if (self.config['map_search'] != null || self.config['show_map']) {
						jQuery(".bmlt-data-row").css({cursor: "pointer"});
						jQuery(".bmlt-data-row").click(function (e) {
							if (e.target.tagName !== 'A')
								croutonMap.rowClick(parseInt(this.id.replace("meeting-data-row-", "")));
						});
					}

					jQuery("#" + self.config['placeholder_id']).addClass("bootstrap-bmlt");
					jQuery("#filter-dropdown-visibile").removeClass("crouton-select").addClass("hide");
					jQuery("#filter-dropdown-next24").removeClass("crouton-select").addClass("hide");
					jQuery(".crouton-select").select2({
						dropdownAutoWidth: true,
						allowClear: false,
						width: "resolve",
						minimumResultsForSearch: 1,
						dropdownCssClass: 'bmlt-drop',
						matcher: function(params, data) {
							if (data.id === "a-")
								return data;
							elementId = data.element.parentElement.id;
							if (params.hasOwnProperty('term')) {
								if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) < 0)
									return null;
							}
							dropdown = self.dropdownData.find((dropdown) => dropdown.elementId === elementId);
							if (typeof dropdown === 'undefined')
								return data;

							if (typeof dropdown.optionsShowing === 'undefined')
								return data;
							if (dropdown.optionsShowing.includes(data.text))
								return data;
							return null;
						}
					});

					jQuery('[data-toggle="popover"]').popover().click(function(e) {e.preventDefault(); e.stopPropagation()});
					jQuery('html').on('click', function (e) {
						if (jQuery(e.target).data('toggle') !== 'popover') {
							jQuery('[data-toggle="popover"]').popover('hide');
						}
					});

					jQuery('.filter-dropdown').on('select2:select', function (e) {
						self.filterMeetingsFromView();
					});

					jQuery("#day").on('click', function () {
						self.showView('day');
					});

					jQuery(".groupingButtonLogic").on('click', function (e) {
						self.showView(e.target.attributes['data-field'].value);
					});
					jQuery('#groupingButton_embeddedMapPage').on('click', function (e) {
						self.showView('map')
					});
					jQuery('.meeting-group:not(.non-collapsable) .group-header').on('click', function(e) {
						jQuery(e.target.parentElement).toggleClass('closed');
					});
					jQuery('.get-directions-modal').on('click', openDirectionsModal);

					jQuery('.directions-map-modal-close').on('click', function (e) {
						closeDirectionsMapModal()
					});
					if (self.config['has_tabs']) {
						jQuery('.nav-tabs a').on('click', function (e) {
							e.preventDefault();
							jQuery(this).tab('show');
						});

						var d = new Date();
						var n = d.getDay();
						n++;
						jQuery('.nav-tabs a[href="#tab' + n + '"]').tab('show');
						jQuery('#tab' + n).show();
					}

					jQuery('.bmlt-header').removeClass("hide").addClass("show");
					jQuery(".bmlt-tabs").removeClass("hide").addClass("show");

					if (self.config['default_filter_dropdown'] !== "") {
						var filter = self.config['default_filter_dropdown'].toLowerCase().split("=");
						jQuery("#filter-dropdown-" + filter[0]).val('a-' + filter[1]).trigger('change').trigger('select2:select');
					}
					let fitBoundsInitial = !self.config['lat'] && !self.config['lng'];
					if (self.config['show_map'] && !self.config['refresh_map'] && !doMeetingMap) {
						croutonMap.initialize(self.createBmltMapElement(), self.meetingData, null, null, fitBoundsInitial);
						jQuery("#bmlt-map").removeClass("hide");
					}
					if (self.config['map_page'] && !doMeetingMap) {
						if (self.meetingData.filter(m => m.venue_type != 2).length==0) {
							jQuery('#groupingButton_embeddedMapPage').addClass('hide');
						}
						else croutonMap.initialize('byfield_embeddedMapPage', self.meetingData, null, null, fitBoundsInitial);
					}
					if (self.config['refresh_map']) {
						croutonMap.refreshMeetings(self.meetingData, fitBounds, true);
					}
					if (self.config['view_by'] == 'map' && !self.config['map_page'])
						self.config['view_by'] = 'day';
						self.showView(self.config['view_by'], self.meetingData.length);
					if (self.config['on_complete'] != null && isFunction(self.config['on_complete'])) {
						self.config['on_complete']();
					}
				}, !doMeetingMap);
			});
		});
	Crouton.prototype.forceShowMap = function() {
		if (this.config.map_page && jQuery('#byfield_embeddedMapPage').hasClass('hide')) {
			this.mapView();
		}
	}
};

// [deprecated] Retire after root server 2.16.4 is rolled out everywhere.
function getMasterFormatId(code, data) {
	for (var f = 0; f < crouton.masterFormatCodes.length; f++) {
		var format = crouton.masterFormatCodes[f];
		if (format['key_string'] === code && format['root_server_uri'] === data['root_server_uri']) {
			return format['id'];
		}
	}
}

// [deprecated] Retire after root server 2.16.4 is rolled out everywhere.
var masterFormatVenueType = {
	IN_PERSON: "IN_PERSON",
	VIRTUAL: "VIRTUAL",
}

var venueType = {
	IN_PERSON: 1,
	VIRTUAL: 2,
	HYBRID: 3,
}

function getVenueTypeName(data) {
	if (data['venue_type'] === venueType.HYBRID || inArray(getMasterFormatId('HY', data), getFormats(data))) {
		return [crouton.localization.getVenueType(masterFormatVenueType.VIRTUAL), crouton.localization.getVenueType(masterFormatVenueType.IN_PERSON)];
	} else if (data['venue_type'] === venueType.VIRTUAL || inArray(getMasterFormatId('VM', data), getFormats(data))) {
		return [crouton.localization.getVenueType(masterFormatVenueType.VIRTUAL)];
	} else {
		return [crouton.localization.getVenueType(masterFormatVenueType.IN_PERSON)];
	}
}

// TODO: Change this logic when https://github.com/bmlt-enabled/bmlt-root-server/issues/353 is released and rolled out everywhere.
function getFormats(data) {
	return data['formats'] !== "" ? data['format_shared_id_list'].split(",") : [];
}

function convertToPunyCode(str) {
	return str !== undefined ? punycode.toASCII(str.toLowerCase()).replace(/\W|_/g, "-") : "";
}

function getUniqueValuesOfKey(array, key){
	return array.reduce(function(carry, item){
		if(item[key] && !~carry.indexOf(item[key])) carry.push(item[key]);
		return carry;
	}, []);
}

function getValuesFromObject(o) {
	var arr = [];
	for (key in o) {
		if (o.hasOwnProperty(key)) {
			arr.push(o[key]);
		}
	}

	return arr;
}
function getUniqueFormats(array){
	return array.reduce(function(carry, val){
		if (!(val.formats_expanded)) return carry;
		return carry.concat(val.formats_expanded.filter((item) => carry.map(f => f.key).indexOf(item.key) < 0));
	},[]).sortByKey('name');
}
function getUniqueFormatsOfType(array, type){
	return array.reduce(function(carry, val){
		if (!(val.formats_expanded)) return carry;
		var fmts = val.formats_expanded.filter((item) => item.type===type);
		if (fmts) {
			carry = carry.concat(fmts.filter((item) => carry.map(f => f.key).indexOf(item.key) < 0));
		}
		return carry;
	},[]).sortByKey('name');
}
Crouton.prototype.renderMeetingCount = function() {
	var self = this;
	self.lock(function() {
		self.updateMeetingCount()
	});
}
Crouton.prototype.simulateFilterDropdown = function() {
	self = this;
	jQuery('.bmlt-page:not(#byfield_embeddedMapPage)').each(function () {
		self.hidePage(this);
	});
	self.filterMeetingsFromView();
}
Crouton.prototype.getAdjustedDateTime = function(meeting_day, meeting_time, meeting_time_zone) {
	var timeZoneAware = this.config['auto_tz_adjust'] === true || this.config['auto_tz_adjust'] === "true";
	var meeting_date_time_obj;
	if (timeZoneAware) {
		if (!meeting_time_zone) {
			meeting_time_zone = "UTC";
		}
    	// Get an object that represents the meeting in its time zone
    	meeting_date_time_obj = moment.tz(meeting_time_zone).set({
    		hour: meeting_time.split(":")[0],
    		minute: meeting_time.split(":")[1],
    		second: 0
    	}).isoWeekday(meeting_day);

    	// Convert meeting to target (local) time zone
    	meeting_date_time_obj = meeting_date_time_obj.clone().tz(moment.tz.guess());
	} else {
    	meeting_date_time_obj = moment().set({
    		hour: meeting_time.split(":")[0],
    		minute: meeting_time.split(":")[1],
    		second: 0
    	}).isoWeekday(meeting_day);
	}

	var now = timeZoneAware ? moment.tz(moment.tz.guess()) : moment();
	if (now > meeting_date_time_obj) {
		meeting_date_time_obj.add(1, 'weeks');
	} else if (now.isoWeekday() == meeting_date_time_obj.isoWeekday() && meeting_date_time_obj.diff(now, 'days') == 0) {
		meeting_date_time_obj.add(1, 'weeks');
	}

	return meeting_date_time_obj;
};

function arrayUnique(a, b, c) {
	b = a.length;
	while (c = --b)
		while (c--) a[b] !== a[c] || a.splice(c, 1);
	return a
}

function sortListByList(source, truth) {
	var goal = [];
	for (var x = 0; x < truth.length; x++) {
		for (var y = 0; y < source.length; y++) {
			if (truth[x] === source[y]) {
				goal.push(source[y])
			}
		}
	}

	return goal;
}

function inArray(needle, haystack) {
	return haystack.indexOf(needle) !== -1;
}

function isFunction(functionToCheck) {
	return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}

function getServiceBodiesQueryString(service_bodies_id) {
	var service_bodies_query = "";
	for (var x = 0; x < service_bodies_id.length; x++) {
		service_bodies_query += "&services[]=" + service_bodies_id[x];
	}
	return service_bodies_query;
}

Array.prototype.clone = function() {
	return this.slice();
}

Array.prototype.filterByObjectKeyValue = function(key, value) {
	var ret = [];
	for (var i = 0; i < this.length; i++) {
		if (this[i][key] === value) {
			ret.push(this[i])
		}
	}

	return ret;
};

Array.prototype.getArrayItemByObjectKeyValue = function(key, value) {
	for (var i = 0; i < this.length; i++) {
		if (this[i][key] === value) {
			return this[i];
		}
	}
};

Array.prototype.clean = function() {
	for (var i = 0; i < this.length; i++) {
		if (this[i] === "") {
			this.splice(i, 1);
			i--;
		}
	}
	return this;
};

Array.prototype.sortByKey = function (key) {
	this.sort(function (a, b) {
		if (a[key] < b[key])
			return -1;
		if (a[key] > b[key])
			return 1;
		return 0;
	});
	return this;
};
function swipedetect(el, callback){

    var touchsurface = el,
    swipedir,
    startX,
    startY,
    distX,
    distY,
    threshold = 150, //required min distance traveled to be considered swipe
    restraint = 100, // maximum distance allowed at the same time in perpendicular direction
    handleswipe = callback || function(swipedir){}

    touchsurface.addEventListener('touchstart', function(e){
        var touchobj = e.changedTouches[0]
        swipedir = 'none'
        startX = touchobj.pageX
        startY = touchobj.pageY
    }, false)


    touchsurface.addEventListener('touchend', function(e){
		if (!e.cancelable) return;
        var touchobj = e.changedTouches[0]
        distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface
        distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface
    	if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint){ // 2nd condition for horizontal swipe met
            swipedir = (distX < 0)? 'left' : 'right' // if dist traveled is negative, it indicates left swipe
			handleswipe(swipedir)
			e.preventDefault()
        }
    }, false)
}
function isIOSDevice() {
    if (navigator.userAgentData && navigator.userAgentData.platform) {
        if (navigator.userAgentData.platform === 'iOS') {
            return true;
        }
    }
    const userAgent = navigator.userAgent || navigator.vendor || window.opera;
    const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
    const isIPadOS = navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1 && !window.MSStream;
    return isIOS || isIPadOS;
}

function isAndroidDevice() {
    return /Android/i.test(navigator.userAgent);
}

function isMobileDevice() {
    return isIOSDevice() || isAndroidDevice() || /Mobi|Android/i.test(navigator.userAgent);
}

function createDirectionsOptions() {
    const options = [];
    const isIOS = isIOSDevice();

    // Apple Maps (iOS only)
    if (isIOS) {
        options.push({
            name: crouton.localization.getWord('apple_maps'),
            description: crouton.localization.getWord('apple_maps_desc'),
            icon: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23007AFF'%3E%3Cpath d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z'/%3E%3C/svg%3E",
            url: 'https://maps.apple.com/?daddr=${latitude},${longitude}'
        });
    }

    // Google Maps (always available)
    options.push({
        name: crouton.localization.getWord('google_maps'),
        description: crouton.localization.getWord('google_maps_desc_mobile'),
        icon: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234285f4'%3E%3Cpath d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z'/%3E%3C/svg%3E",
        url: 'https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}'
    });

    // Waze (always available)
    options.push({
        name: crouton.localization.getWord('waze'),
        description: crouton.localization.getWord('waze_desc'),
        icon: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2300D4FF'%3E%3Cpath d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z'/%3E%3C/svg%3E",
        url: 'https://waze.com/ul?ll=${latitude},${longitude}&navigate=yes'
    });

    return options;
}
function openDirectionsModal(e) {
	const latitude = jQuery(this).data('latitude');
	const longitude = jQuery(this).data('longitude');

	const savedUrl = localStorage.getItem("croutonDirectionsURL");
	if (savedUrl && savedUrl != null) {
		openDirections(savedUrl, latitude, longitude, false);
		return;
	}
	if (!document.getElementById('directionsMapModal')) {
		const word = crouton.localization.getWord("select_map_app");
		e.target.insertAdjacentHTML("afterend",
`<div id="directionsMapModal" class="directions-map-modal remove-after-use">
                <div class="directions-map-modal-content">
                    <span class="directions-map-modal-close">×</span>
                    <h3>`+word+`</h3>
                    <div id="directionsMapOptions"></div>
                </div>
</div>`
		);
	}
	const modal = document.getElementById('directionsMapModal');
	const optionsContainer = document.getElementById('directionsMapOptions');

	if (!optionsContainer) {
		window.open(`https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}`, '_blank');
		return;
	}

	optionsContainer.innerHTML = '';

	const options = createDirectionsOptions();

	options.forEach(option => {
		const optionElement = document.createElement('div');
		optionElement.className = 'directions-map-option';
		optionElement.onclick = () => openDirections(option.url, latitude, longitude);

		optionElement.innerHTML = `
            <img src="${option.icon}" alt="${option.name}" class="directions-map-option-icon">
            <div class="directions-map-option-text">
                <div class="directions-map-option-title">${option.name}</div>
                <div class="directions-map-option-desc">${option.description}</div>
            </div>
        `;

		optionsContainer.appendChild(optionElement);
	});
	const label = crouton.localization.getWord('Remember my choice');
	const rememberChoiceElement = document.createElement('div');
	rememberChoiceElement.className = 'directions-remember-choice-div';
	rememberChoiceElement.innerHTML =
`<input type="checkbox" id="rememberDirectionsChoice" name="rememberDirectionsChoice" value="1">
<label for="rememberDirectionsChoice">`+label+`</label>`
	;
	optionsContainer.appendChild(rememberChoiceElement);
	jQuery('html').on('click', '.directions-map-modal-close', closeDirectionsModal);
	// Show modal
	modal.style.display = 'block';
}

function closeDirectionsModal() {
		const modal = document.getElementById('directionsMapModal');
		modal.style.display = 'none';
		if (modal.className.includes('remove-after-use')) modal.remove();
}

function openDirections(url, latitude, longitude, fromModal = true) {
	const save = jQuery('#rememberDirectionsChoice');
	if (fromModal && save.length && save.is(":checked")) localStorage.setItem("croutonDirectionsURL", url);
	url = url.replaceAll('${latitude}', latitude);
	url = url.replaceAll('${longitude}', longitude);
	window.open(url, '_blank');
	if (fromModal) closeDirectionsModal();
}

function MeetingMap(inConfig) {
	/****************************************************************************************
	 *										CLASS VARIABLES									*
	 ****************************************************************************************/

	var gDelegate = new MapDelegate(inConfig);
	var gModalDelegate = null;
	var gInDiv = null;
	const config = inConfig;
	if (!config.maxZoom) config.maxZoom = 17;
	if (!config.minZoom) config.minZoom = 6;
	if (!config.marker_contents_template) config.marker_contents_template = croutonDefaultTemplates.marker_contents_template;
	var gAllMeetings = [];
	var gMeetingIdsFromCrouton = null;
	var gSearchPoint = false;
	var loadedCallbackFunction = null;
	var loadedCallbackArgs = [];
	var oldBounds = false;
	var isMouseDown = false;
	function preloadApiLoadedCallback(f,a) {
		loadedCallbackFunction = f;
		loadedCallbackArgs = a;
	}
	function apiLoadedCallback() {
		loadedCallbackFunction(...loadedCallbackArgs);
	}

	function retrieveGeolocation() {
		return new Promise((resolve, reject) => {
			if (window.storedGeolocation) {
				resolve(window.storedGeolocation);
			} else if (navigator.geolocation) {
				navigator.geolocation.getCurrentPosition((position) => {
					window.storedGeolocation = {
						latitude: position.coords.latitude,
						longitude: position.coords.longitude
					};
					resolve(window.storedGeolocation);
				}, (error) => {
					reject(new Error('Error getting geolocation: ' + error.message));
				});
			} else {
				reject(new Error('Geolocation is not supported by this browser.'));
			}
		});
	}
	function isFilterVisible() {
		return config.filter_visible && config.filter_visible == 1;
	}
	/************************************************************************************//**
	 *	\brief Load the map and set it up.													*
	 ****************************************************************************************/

	function loadMap(inDiv, menuContext, handlebarMapOptions=null,cb=null,hide=false) {
		if (inDiv) {
			crouton_Handlebars.registerPartial("markerContentsTemplate", crouton_Handlebars.compile(config['marker_contents_template']));
			gInDiv = inDiv;
			createThrobber(inDiv);
			if (!config.map_search) showThrobber();
			else {
				if (!config.map_search.width) config.map_search.width = -50;
				if (!config.map_search.location && !config.map_search.coordinates_search)
					config.map_search.auto = true;
				if (config.map_search.latitude || config.map_search.longitude) {
					config.lat = config.map_search.latitude;
					config.lng = config.map_search.longitude;
				}
				if (config.map_search.zoom) {
					config.zoom = config.map_search.zoom;
				}
			}
			let loc = {latitude: config.lat, longitude: config.lng, zoom: config.zoom};
			if (handlebarMapOptions) loc = {latitude: handlebarMapOptions.lat, longitude: handlebarMapOptions.lng};
			if (gDelegate.createMap(inDiv, loc, hide)) {
				// crouton_map and filter_visible triggers a query, Otherwise, redraw markers
				if (config.map_search && isFilterVisible()) {
					gDelegate.addListener('idle', triggerCroutonMapNewQuery, false);
				} else {
					gDelegate.addListener('zoomend', function (ev) {
						if (shouldRedrawMarkers() && gAllMeetings) {
							if (listOnlyVisible) {
								const oldValue = filterVisible(false);
								searchResponseCallback();
								filterVisible(oldValue);
							} else searchResponseCallback();
						}
					}, false);
				}
				// set up control buttons in map
				if (config.map_search) gDelegate.addControl(createSearchButton(), 'topleft', cb);
				else {
					const menuImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAb0lEQVRYR2NkGGDAOMD2M4w6YDQEUEJg8eLF/7t2PqVpuixzl2aIjY2F2wtn0MNymM+QHTF4HAByHT1CAWcU0DTi8Rg+mg0HVwgMaCKkh+Wj5QAoBEbLAfQyaXBlw4EojkfbA6PtgdFcMBoCoyEAAJZTVCFyqxytAAAAAElFTkSuQmCC";
					if (menuContext) {
						menuContext.menuImage = menuImage;
						gDelegate.addControl(createNext24Toggle(), 'topleft');
						gDelegate.addControl(createMenuButton(menuContext), 'topright', cb);
					} else {
						menuContext = {menuImage: menuImage, config: config, dropdownData:false};
						gDelegate.addControl(createMenuButton(menuContext), 'topright', cb);
					}
				}
				if (config.caption) {
					const wrapper= document.createElement('div');
					wrapper.innerHTML= '<div class="map-caption">'+config.caption.replace('\n','<br/>')+'</div>';
					gDelegate.addControl(wrapper.firstChild, 'bottomleft', cb);
				}
			}
		};
	};
	var gSearchModal;
	function createSearchButton() {
		const template = hbs_Crouton.templates['mapSearch'];
		const controlDiv = document.createElement('div');
		const params = {};
		controlDiv.innerHTML = template(params);
		controlDiv.querySelector("#map-search-button").addEventListener('click', showBmltSearchDialog);
		controlDiv.querySelector("#bmltsearch-nearbyMeetings").addEventListener('click', nearMeSearch);
		controlDiv.querySelector("#bmltsearch-goto-text").addEventListener('keypress', function (event) {
			if (event.key === "Enter") {
				event.preventDefault();
				document.getElementById("bmltsearch-text-button").click();
			}
		});
		controlDiv.querySelector("#bmltsearch-text-button").addEventListener('click', function () {
			let text = document.getElementById("bmltsearch-goto-text").value.trim();
			if (text === "") return;
			showThrobber();
			gDelegate.callGeocoder(text, null, mapSearchGeocode);
			clearMessageAndClose(gSearchModal);
		});
		controlDiv.querySelector("#modal-seach-parameters").style.display = 'none';
		controlDiv.querySelector("#show-search-parameters").addEventListener('click', function (e) {
			const controlDiv = e.target.parentElement.parentElement;
			let w = config.map_search.width;
			let checked = '#search_radius';
			if (w < 0) {
				w = -w;
				checked = '#search_count';
			}
			controlDiv.querySelector(checked).checked = true;
			controlDiv.querySelector('#search_parameter').value = w;
			controlDiv.querySelector("#modal-seach-parameters").style.display = 'block';
			controlDiv.querySelector("#modal-search-page").style.display = 'none';
			controlDiv.querySelector("#search_radius_label").innerHTML = crouton.localization.getWord('Radius of search in $$').replace('$$', crouton.config.distance_units);
		});
		controlDiv.querySelector("#show-search-page").addEventListener('click', function (e) {
			const controlDiv = e.target.parentElement.parentElement;
			let w = controlDiv.querySelector('#search_parameter').value;
			if (controlDiv.querySelector('#search_count')) {
				w = -Math.round(w);
				if (w == 0) w = -1;
			}
			config.map_search.width = w;
			controlDiv.querySelector("#modal-seach-parameters").style.display = 'none';
			controlDiv.querySelector("#modal-search-page").style.display = 'block';
		});

		controlDiv.querySelector("#bmltsearch-clicksearch").addEventListener('click', clickSearch);
		[...controlDiv.getElementsByClassName('modal-close')].forEach((elem)=>elem.addEventListener('click', (e)=>clearMessageAndClose(e.target)));
		gSearchModal = controlDiv.querySelector("#bmltsearch_modal");
		gSearchModal.parentElement.removeChild(gSearchModal);

		return controlDiv;
	}
	var next24status = false;
	function createNext24Toggle() {
		const toggleSrc = `
	<div id="next24_toggle" title="Next24_toggle" style="background: rgba(0, 0, 0, 0); cursor: pointer;">
		 <div class="onoffswitch">
			 <input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="next24onoffswitch"/>
			 <label class="onoffswitch-label" for="next24onoffswitch">
				 <span class="onoffswitch-inner"></span>
				 <span class="onoffswitch-switch"></span>
			 </label>
		 </div>
	</div>`;
		let rules = `.onoffswitch-inner:before {
		content: "__text1__";
		padding-left: 10px;
		background-color: #2d5c88; color: #FFFFFF;
		}
		.onoffswitch-inner:after {
		content: "__text2__";
		padding-left: 30px;
		background-color: #EEEEEE; color: #2d5c88;
		text-align: left;
		}`
			.replace("__text1__", crouton.localization.getWord("Upcoming Meetings"))
			.replace("__text2__", crouton.localization.getWord("All Meetings"));
		var controlDiv = document.createElement('div');
		controlDiv.innerHTML = toggleSrc;
		controlDiv.querySelector(".onoffswitch").addEventListener('click', function (event) {
			if (event.pointerId < 0) return;
			next24status = !next24status;
			fitDuringFilter = false;
			crouton.filterNext24(next24status);
			fitDuringFilter = true;
		});
		let style = document.createElement('style');
    	style.innerHTML = rules;
   		document.head.appendChild(style);
		return controlDiv;
	}
	function createMenuButton(menuContext) {
		var template = hbs_Crouton.templates['mapMenu'];
		var controlDiv = document.createElement('div');
		controlDiv.innerHTML = template(menuContext);
		controlDiv.querySelector("#nearbyMeetings").addEventListener('click', function (e) {
			retrieveGeolocation().then(position => {
				filterVisible(false);
				gDelegate.setViewToPosition(position, filterMeetingsAndBounds, filterVisible);
				gSearchPoint = {"lat": position.latitude, "lng": position.longitude};
				crouton.updateDistances();

			}).catch(error => {
				console.log(error.message);
				jQuery('.geo').removeClass("hide").addClass("show").html(`<p>${error.message}</p>`);
			});
			dropdownContent = document.getElementById("map-menu-dropdown").style.display = "none";
		});

		controlDiv.querySelector("#lookupLocation").addEventListener('click', showGeocodingDialog);
		if (menuContext && menuContext.dropdownData) {
			controlDiv.querySelector("#filterMeetings").addEventListener('click', showFilterDialog);
			controlDiv.querySelector("#showAsTable").addEventListener('click', showListView);
		} else {
			controlDiv.querySelector("#filterTable").addEventListener('click', toggleVisible);
		}
		controlDiv.querySelector("#fullscreenMode").addEventListener('click', toggleFullscreen);
		controlDiv.querySelector("#map-menu-button").addEventListener('click', function (e) {
			let dropdownContent = document.getElementById("map-menu-dropdown");
			if (dropdownContent.style.display == "inline-block") {
				dropdownContent.style.display = "none";
			} else {
				jQuery("#filteringByVisibility").html(listOnlyVisible?'&#10004;':'');
				dropdownContent.style.display = "inline-block";
			}
		});
		[...controlDiv.getElementsByClassName('modal-close')].forEach((elem)=>elem.addEventListener('click', (e)=>closeModalWindow(e.target)));
		controlDiv.querySelector("#close_table").addEventListener('click', hideListView);
		controlDiv.querySelector("#goto-text").addEventListener('keydown', function (event) {
			if (event && event.key == "Enter") {
				closeModalWindow(event.target);
				lookupLocation(g_suspendedFullscreen);
			}
		});
		controlDiv.querySelector("#goto-button").addEventListener('click', function (event) {
			closeModalWindow(event.target);
			lookupLocation(g_suspendedFullscreen);
		});

		return controlDiv;
	}
	function hasMapSearch() {
		return 'map_search' in config;
	}
	function loadFromCrouton(inDiv_id, meetings_responseObject, menuContext = null, handlebarMapOptions = null, fitBounds = true, callback, hide) {
		if (!gDelegate.isApiLoaded()) {
			preloadApiLoadedCallback(loadFromCrouton, [inDiv_id, meetings_responseObject, menuContext, handlebarMapOptions, fitBounds, callback, hide]);
			gDelegate.loadApi();
			return;
		}
		let inDiv = document.getElementById(inDiv_id);
		loadMap(inDiv, menuContext, handlebarMapOptions, callback, hide);
		loadAllMeetings(meetings_responseObject, fitBounds, true);
	};
	function loadPopupMap(inDiv_id, meeting, handlebarMapOptions = null) {
		if (!gDelegate.isApiLoaded()) {
			preloadApiLoadedCallback(loadPopupMap, [inDiv_id, meeting, handlebarMapOptions]);
			gDelegate.loadApi();
			return;
		}
		let inDiv = document.getElementById(inDiv_id);
		if (!inDiv) return;
		let delegate = new MapDelegate(config);
		if (handlebarMapOptions) loc = {latitude: handlebarMapOptions.lat, longitude: handlebarMapOptions.lng, zoom: handlebarMapOptions.zoom};
		if (delegate.createMap(inDiv, loc)) {
			const marker = delegate.createMarker([meeting.latitude, meeting.longitude], false, null);
			delegate.bindPopup(marker, null, meeting.id_bigint, false);
			delegate.addClusterLayer();
			gModalDelegate = delegate;
		}
	};
	var fitDuringFilter = true;
	function filterFromCrouton(filter) {
		gMeetingIdsFromCrouton = filter;
		if (gAllMeetings)
			searchResponseCallback(fitDuringFilter && !listOnlyVisible);
	};
	function clearMessageAndClose(modal) {
		jQuery('#zoomed-out-message').not('.hide').addClass('hide');
		closeModalWindow(modal);
	}
	function nearMeSearch() {
		retrieveGeolocation().then(position => {
			showThrobber();
			gSearchPoint = {"lat": position.latitude, "lng": position.longitude};
			crouton.searchByCoordinates(position.latitude, position.longitude, config.map_search.width);
			if (activeModal == gSearchModal) clearMessageAndClose(gSearchModal);
		}).catch(error => {
			console.log(error.message);
			if (activeModal != gSearchModal) showBmltSearchDialog();
		});
	};
	function clickSearch(e) {
		croutonMap.showMap(false,false);
		gDelegate.clickSearch(e, function(lat,lng) {
			showThrobber();
			gSearchPoint = {"lat": lat, "lng": lng};
			crouton.searchByCoordinates(lat, lng, config.map_search.width);
		});
		clearMessageAndClose(gSearchModal);
	}
	function createThrobber(inDiv) {
		if (!inDiv.myThrobber) {
			inDiv.myThrobber = document.createElement("div");
			if (inDiv.myThrobber) {
				inDiv.myThrobber.id = inDiv.id + 'Throbber_div';
				inDiv.myThrobber.className = 'bmlt_map_throbber_div';
				inDiv.myThrobber.style.display = 'none';
				inDiv.appendChild(inDiv.myThrobber);
				var img = document.createElement("img");

				if (img) {
					img.src = config.BMLTPlugin_images ? config.BMLTPlugin_images + "/Throbber.gif"
					: "data:image/gif;base64, ";
					img.className = 'bmlt_mapThrobber_img';
					img.id = inDiv.id + 'Throbber_img';
					img.alt = 'AJAX Throbber';
					inDiv.myThrobber.appendChild(img);
				} else {
					inDiv.myThrobber = null;
				};
			};
		};
	};
	function showThrobber() {
		if (gInDiv.myThrobber) {
			gInDiv.myThrobber.style.display = 'block';
		};
	};
	function hideThrobber() {
		if (gInDiv.myThrobber) {
			gInDiv.myThrobber.style.display = 'none';
		};
	};
	function mapSearchGeocode(resp) {
		showThrobber();
		if (document.getElementById("bmltsearch-goto-text"))
			document.getElementById("bmltsearch-goto-text").value = "";
		let latlng = gDelegate.getGeocodeCenter(resp);
		if (!latlng) {
			hideThrobber();
			return;
		}
		gSearchPoint = {"lat": latlng.lat, "lng": latlng.lng};
		crouton.searchByCoordinates(latlng.lat, latlng.lng, config.map_search.width);
	}
	function loadAllMeetings(meetings_responseObject, fitBounds=true, fitAll=false) {
		if (meetings_responseObject === null && config.map_search) {
			if (config.map_search.auto) nearMeSearch();
			else if (config.map_search.coordinates_search) {
				showThrobber();
				config.map_search.coordinates_search = false;
				gSearchPoint = {"lat": config.map_search.latitude, "lng": config.map_search.longitude};
				crouton.searchByCoordinates(config.map_search.latitude, config.map_search.longitude, config.map_search.width);
			}
			else if (config.map_search.location) gDelegate.callGeocoder(config.map_search.location, null, mapSearchGeocode);
			else showBmltSearchDialog();
			return;
		}
		gAllMeetings = meetings_responseObject.filter(m => m.venue_type != 2);
		if (fitBounds) {
			let lat_lngs = gAllMeetings.reduce(function(a,m) {a.push([m.latitude, m.longitude]); return a;},[]);
			const maxRadius = config.maxTomatoWidth/2.0;
			if (gSearchPoint) lat_lngs.push([gSearchPoint.lat, gSearchPoint.lng]);
			if (config.map_search && isFilterVisible()) {
				lat_lngs.sort((a,b) =>  getDistance({"lat":a[0],"lng":a[1]},gSearchPoint) - getDistance({"lat":b[0],"lng":b[1]},gSearchPoint));
				while (getLatLngRadius(lat_lngs) > maxRadius && lat_lngs.length > 3) {
					lat_lngs = lat_lngs.slice(0, lat_lngs.length/2);
				}
				if (getLatLngRadius(lat_lngs) > maxRadius)
					lat_lngs = lat_lngs.slice(1,1);
			}
			if (lat_lngs.length > 0) gDelegate.fitBounds(lat_lngs);
		}
		searchResponseCallback();
		hideThrobber();
		if (isFilterVisible() || config.centerMe || config.goto) crouton.forceShowMap();
		if (config.centerMe) {
			if (navigator.geolocation) {
				navigator.geolocation.getCurrentPosition(
					function (position) {
						coords = {latitude: position.coords.latitude, longitude: position.coords.longitude};
						filterVisible(false);
						if (config.zoom) gDelegate.setZoom(false, config.zoom);
						gDelegate.setViewToPosition(coords, filterMeetingsAndBounds, () => {
							filterVisible(isFilterVisible());
						});
						gSearchPoint = {"lat": position.coords.latitude, "lng": position.coords.longitude};
						crouton.updateDistances(true);
					},
					showGeocodingDialog
				);
			} else if (fitAll) {
				showGeocodingDialog();
			}
		} else {
			if ((!config.centerMe && !config.goto) && !(config.map_search && isFilterVisible())) {
			  gDelegate.afterInit(()=>filterVisible(isFilterVisible()));
			}
			if (config.goto) gDelegate.callGeocoder(config.goto, isFilterVisible() ? resetVisibleThenFilterMeetingsAndBounds : setVisibleThenFilterMeetingsAndBounds);
		}
	}
	function createCityHash(allMeetings) {
		return allMeetings.reduce(function(prev, meeting) {
			if (prev.hasOwnProperty(meeting.location_municipality))
				prev[meeting.location_municipality].push(meeting);
			else
				prev[meeting.location_municipality] = [meeting];
			return prev;
		}, {});
	}
	var g_suspendedFullscreen = false;
	var g_overflowX;
	var activeModal = null;
	var swipableModal = false;
	function closeModalWindow(modal) {
		gDelegate.modalOff();
		activeModal = null;
		if (!modal.classList.contains("modal"))
			return closeModalWindow(modal.parentNode);
		modal.style.display = "none";
		if (g_suspendedFullscreen) {
			g_suspendedFullscreen = false;
			if (!isFullscreen()) {
				toggleFullscreen();
			}
		}
		if (swipableModal) {
			const body = document.body;
			const scrollY = body.style.top;
			body.style.overflowX = g_overflowX;
			body.style.position = '';
			body.style.top = '';
			window.scrollTo(0, parseInt(scrollY || '0') * -1);
		}
	}
	document.addEventListener("keydown", function(event) {
		if (activeModal && event.key == "Escape") {
			closeModalWindow(activeModal);
		}
	}, true);
	function openModalWindow(modal,swipe=false) {
		if (isFullscreen()) {
			g_suspendedFullscreen = true;
			toggleFullscreen();
		}
		if (!modal) return;
		modal.style.display = "block";
		swipableModal = swipe;
		modal.focus();
		activeModal = modal;
		dd = document.getElementById("map-menu-dropdown");
		if (dd) dd.style.display = "none";
		gDelegate.modalOn();
		if (swipableModal) {
			const body = document.body;
			g_overflowX = body.style.overflowX;
			const newTop = -window.scrollY+'px';
			body.style.overflowX = 'hidden';
			body.style.position = 'fixed';
			body.style.width="100%";
			body.style.setProperty('top', newTop, 'important');
		}
	}
	function showFilterDialog(e) {
		openModalWindow(document.getElementById('filter_modal'));
	}
	function showBmltSearchDialog(e) {
		if (!document.getElementById('bmltsearch_modal')) gInDiv.appendChild(gSearchModal);
		if (gDelegate.isMapDefined())
			jQuery('#bmltsearch-clicksearch').parent().show();
		else
			jQuery('#bmltsearch-clicksearch').parent().hide();
		openModalWindow(gSearchModal);
	}
	function showGeocodingDialog(e=null) {
		openModalWindow(document.getElementById('geocoding_modal'));
	}
	function showListView(e=null) {
		filterVisible();
		jQuery("#bmlt-tabs").append(jQuery("#table_page"));
		jQuery("#table_page").removeClass("hide");
		jQuery("#bmlt-map").css("display", "none");
		jQuery("#table_page").css("max-height", jQuery("#bmlt-map").height());
		jQuery("#bmlt-maptable-div").css("height", jQuery("#bmlt-map").height()-jQuery("#bmlt-maptable-header").height());
		document.getElementById("map-menu-dropdown").style.display = "none";
	}
	function hideListView(e=null) {
		filterVisible(false);
		jQuery("#table_page").addClass("hide");
		jQuery("#bmlt-map").css("display", "block");
	}
	function resetVisibleThenFilterMeetingsAndBounds(bounds, center=null) {
		filterVisible(false);
		const ret = filterMeetingsAndBounds(bounds);
		filterVisible(true);
		if (gSearchPoint.lat != center.lat || gSearchPoint.lng != center.lng) {
			gSearchPoint = center;
			crouton.updateDistances();
		}
		return ret;
	}
	function setVisibleThenFilterMeetingsAndBounds(bounds, center=null) {
		filterVisible(false);
		const ret = filterMeetingsAndBounds(bounds);
		if (gSearchPoint.lat != center.lat || gSearchPoint.lng != center.lng) {
			gSearchPoint = center;
			crouton.updateDistances();
		}
		return ret;
	}
	function lookupLocation(fullscreen) {
		if (document.getElementById('goto-text').value != '') {
			if (fullscreen) {
				gDelegate.addListener('idle', function () {
					gDelegate.callGeocoder(document.getElementById('goto-text').value, resetVisibleThenFilterMeetingsAndBounds);
				}, true);
			} else {
				gDelegate.callGeocoder(document.getElementById('goto-text').value, resetVisibleThenFilterMeetingsAndBounds);
			}
		} else {
			alert("");
		};
		return true;
	};
	function searchResponseCallback(expand = false) {
		if (!gAllMeetings || !gAllMeetings.length) {
			return;
		};
		try {
			drawMarkers(expand);
			if (gSearchPoint) {
				gDelegate.markSearchPoint([gSearchPoint.lat, gSearchPoint.lng]);
			}
		} catch (e) {
			console.log(e);
			gDelegate.addListener('projection_changed', function (ev) {
				drawMarkers(expand);
				if (gSearchPoint) {
					gDelegate.markSearchPoint([gSearchPoint.lat, gSearchPoint.lng]);
				}
			}, true);
		}
	};
	/****************************************************************************************
	 *									CREATING MARKERS									*
	 ****************************************************************************************/
	var prevUseMarkerCluster;
	function useMarkerCluster() {
		if (config.groups) return true;
		if (typeof gDelegate.getZoom() === 'undefined') return true;
		if (typeof config.clustering === 'undefined') return false;
		return gDelegate.getZoom() < config.clustering;
	}
	function shouldRedrawMarkers() {
		if (typeof prevUseMarkerCluster === 'undefined') return true;
		if (prevUseMarkerCluster !== useMarkerCluster()) {
			prevUseMarkerCluster = useMarkerCluster();
			return true;
		}
		if (useMarkerCluster()===false) {
			return true;
		}
		return false;
	}
	function drawMarkers(expand = false) {
		if (!gDelegate.isMapDefined()) return;
		const openMarker = gDelegate.getOpenMarker();
		gDelegate.clearAllMarkers();
		gDelegate.removeClusterLayer();
		// This calculates which markers are the red "multi" markers.
		const filtered = filterMeetings(gAllMeetings);
		const overlap_map = config.groups ? filtered
			:	((useMarkerCluster() || filtered.length == 1)
				? filtered.map((m)=>[m])
				: mapOverlappingMarkersInCity(filtered));

		if (useMarkerCluster()) gDelegate.createClusterLayer();
		// Draw the meeting markers.
		markerCreator = config.groups ? createGroupMarker : createMapMarker;
		overlap_map.forEach(function (marker) {
			markerCreator(marker, openMarker);
		});
		gDelegate.addClusterLayer();
		if (expand) {
			const lat_lngs = filtered.reduce(function(a,m) {a.push([m.latitude, m.longitude]); return a;},[]);
			gDelegate.fitBounds(lat_lngs);
		}
	};
	function mapOverlappingMarkersInCity(in_meeting_array)	///< Used to draw the markers when done.
	{
		var tolerance = 8;	/* This is how many pixels we allow. */

		var ret = new Array;
		// We create this hash because we limit looking for "matches" to within one city.
		for (const [city, meetings] of Object.entries(createCityHash(in_meeting_array))) {
			// create a tmp object so we can mark which items haven't been matched yet.
			var tmp = meetings.map((meeting) => {
				item = new Object;
				item.matched = false;
				item.meeting = meeting;
				item.coords = gDelegate.fromLatLngToPoint(meeting.latitude, meeting.longitude);
				return item;
			});
			tmp.reduce(function(prev, item, index) {
				if (item.matched) return prev;
				matches = [item.meeting];
				var outer_coords = item.coords;
				for (c2 = index+1; c2<meetings.length; c2++) {
					if (tmp[c2].matched) continue;
					var inner_coords = tmp[c2].coords;

					var xmin = outer_coords.x - tolerance;
					var xmax = outer_coords.x + tolerance;
					var ymin = outer_coords.y - tolerance;
					var ymax = outer_coords.y + tolerance;

					/* We have an overlap. */
					if ((inner_coords.x >= xmin) && (inner_coords.x <= xmax) && (inner_coords.y >= ymin) && (inner_coords.y <= ymax)) {
						matches.push(tmp[c2].meeting);
						tmp[c2].matched = true;
					}
				}
				matches.sort(sortMeetingSearchResponseCallback)
				prev.push(matches);
				return prev;
			}, ret);
		}

		return ret;
	};
	function sortMeetingSearchResponseCallback(mtg_a, mtg_b) {
	var weekday_score_a = parseInt(mtg_a.weekday_tinyint, 10);
	var weekday_score_b = parseInt(mtg_b.weekday_tinyint, 10);

	if (weekday_score_a < config.start_week) {
		weekday_score_a += 7;
	}

	if (weekday_score_b < config.start_week) {
		weekday_score_b += 7;
	}

	if (weekday_score_a < weekday_score_b) {
		return -1;
	}
	else if (weekday_score_a > weekday_score_b) {
		return 1;
	};
	var time_a = mtg_a.start_time.toString().split(':');
	var time_b = mtg_b.start_time.toString().split(':');
	if (parseInt(time_a[0]) < parseInt(time_b[0])) {
		return -1;
	}
	if (parseInt(time_a[0]) > parseInt(time_b[0])) {
		return 1;
	}
	if (parseInt(time_a[1]) < parseInt(time_b[1])) {
		return -1;
	}
	if (parseInt(time_a[1]) > parseInt(time_b[1])) {
		return 1;
	}
	return 0;
};
	const markerTemplateSrc = `
	<div class="accordion">
	{{#each this}}<div>
			<input type="radio" name="panel" id="panel-{{this.id_bigint}}" {{#unless @index}}checked{{/unless}}/>
			<label for="panel-{{this.id_bigint}}">{{this.formatted_day}} {{this.start_time_formatted}}</label>
			<div class="marker_div_meeting" id="{{this.id_bigint}}">
				{{> markerContentsTemplate}}
			</div>
	</div>{{/each}}
	</div>
	`;
	const markerTemplate = crouton_Handlebars.compile(markerTemplateSrc);

	/************************************************************************************//**
	 *	 \brief	This creates a single meeting's marker on the map.							*
	 ****************************************************************************************/
	function createMapMarker(meetings, openMarker) {
		var main_point = [meetings[0].latitude, meetings[0].longitude];
		const marker_html = markerTemplate(meetings);
		const marker = gDelegate.createMarker(main_point, (meetings.length > 1), null);
		gDelegate.bindPopup(marker, marker_html, meetings.map((m)=>parseInt(m.id_bigint)), openMarker);
	};
	function createGroupMarker(group, openMarker) {
		var main_point = [group.latitude, group.longitude];
		const marker = gDelegate.createMarker(main_point, group['membersOfGroup'].length > 1, null);
		gDelegate.addMarkerCallback(marker, function() {
			crouton.openMeetingModal(group);
		});
	};
	var listOnlyVisible = false;
	var listener = null;
	function filterBounds(bounds) {
		return gAllMeetings.filter((meeting) => gDelegate.contains(bounds, meeting.latitude, meeting.longitude));
	}
	function onDragStart() {
		isMouseDown = true;
		// if no [crouton_map], then show all meetings
		if (!config.map_search) filterVisible(false);
		gDelegate.addListener('dragend', onDragEnd, true);
	}
	function onDragEnd() {
		isMouseDown = false;
		// if no [crouton_map], then turn filter visible back on.
		if (config.map_search && isFilterVisible()) triggerCroutonMapNewQuery(null);
		else filterVisible(true);
	}
	function triggerCroutonMapNewQuery(ev) {
		if (isMouseDown) return;
		gMeetingIdsFromCrouton = null;
		corners = gDelegate.getCorners();
		if (oldBounds && gDelegate.contains(oldBounds,corners.ne.lat,corners.ne.lng)
					  && gDelegate.contains(oldBounds,corners.sw.lat,corners.sw.lng)) {
			filterVisible();
		} else if (getScreenRadius('km') > config.maxTomatoWidth) {
			jQuery('#zoomed-out-message').removeClass('hide');
			showBmltSearchDialog(null);
		} else {
			oldBounds = gDelegate.getBounds();
			showThrobber();
			crouton.searchByCoordinates(gDelegate.getCenter().lat, gDelegate.getCenter().lng, getScreenRadius(), false);
		}
	}
	function filterVisible(on=true) {
		if (on==listOnlyVisible && !config.map_search) return on;
		let mtgs = on ? filterBounds(gDelegate.getBounds()) : gAllMeetings;
		let visible = mtgs.map((m)=>m.id_bigint);
		jQuery(".bmlt-data-row").each(function(index,row) {
			row.dataset.visible = (visible.includes(row.id.split('-').pop())) ? '1' : '0';
		});
		jQuery("#byday").removeClass('hide');
		jQuery("#filter-dropdown-visibile").val(on?'a-1':'');
		fitDuringFilter = false;
		crouton.simulateFilterDropdown();
		fitDuringFilter = true;
		jQuery("#filteringByVisibility").html(on?'&#10004;':'');
		listOnlyVisible = on;
		if (on) listener = gDelegate.addListener('dragstart', onDragStart, true);
		else if (listener) {
			gDelegate.removeListener(listener);
			listener = null;
		}
		return !on;
	}
	function toggleVisible() {
		filterVisible(!listOnlyVisible);
	}
	function filterBounds(bounds) {
		var ret = gAllMeetings.filter((meeting) =>
			gDelegate.contains(bounds, meeting.latitude, meeting.longitude));
		return ret;
	}
	function focusOnMeeting(meetingId) {
		let meeting = gAllMeetings.find((meeting) => meeting.id_bigint == meetingId);
		if (!meeting) return;
		if ((gDelegate.getZoom()>=14) && gDelegate.contains(gDelegate.getBounds(), meeting.latitude, meeting.longitude)) {
			gDelegate.openMarker(meetingId);
		} else {
			gDelegate.setViewToPosition({latitude: meeting.latitude, longitude: meeting.longitude}, filterMeetingsAndBounds, function() {gDelegate.openMarker(meetingId);});
		}
	}
	function filterMeetingsAndBounds(bounds) {
		return filterMeetings(filterBounds(bounds));
	}
	function filterMeetings(in_meetings_array) {
		var ret = in_meetings_array.filter(m => m.venue_type != 2);
		if (gMeetingIdsFromCrouton != null) {
			return ret.filter((m) => gMeetingIdsFromCrouton.includes(m.id_bigint));
		}
		return ret;
	}
	var _isPseudoFullscreen = false;
	function isFullscreen() {
		var fullscreenElement =
			document.fullscreenElement ||
			document.mozFullScreenElement ||
			document.webkitFullscreenElement ||
			document.msFullscreenElement;

		return (fullscreenElement === gInDiv) || _isPseudoFullscreen;
	}
	function toggleFullscreen(options) {
		var container = gInDiv;
		if (isFullscreen()) {
			if (options && options.pseudoFullscreen) {
				_setFullscreen(false);
			} else if (document.exitFullscreen) {
				document.exitFullscreen();
			} else if (document.mozCancelFullScreen) {
				document.mozCancelFullScreen();
			} else if (document.webkitCancelFullScreen) {
				document.webkitCancelFullScreen();
			} else if (document.msExitFullscreen) {
				document.msExitFullscreen();
			} else {
				_disablePseudoFullscreen(container);
			}
		} else {
			if (options && options.pseudoFullscreen) {
				_setFullscreen(true);
			} else if (container.requestFullscreen) {
				container.requestFullscreen();
			} else if (container.mozRequestFullScreen) {
				container.mozRequestFullScreen();
			} else if (container.webkitRequestFullscreen) {
				container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
			} else if (container.msRequestFullscreen) {
				container.msRequestFullscreen();
			} else {
				_enablePseudoFullscreen(container);
			}
		}
	}
	var _isPseudoFullscreen = false;
	function _setFullscreen(fullscreen) {
		_isPseudoFullscreen = fullscreen;
		var container = gInDiv;
		if (fullscreen) {
			L.DomUtil.addClass(container, 'leaflet-pseudo-fullscreen');
		} else {
			L.DomUtil.removeClass(container, 'leaflet-pseudo-fullscreen');
		}
		gDelegate.invalidateSize();
	}
	function showMap(isModal=false, fitBounds=true) {
		if (isModal && gModalDelegate) {
			gModalDelegate.invalidateSize();
			return;
		}
		gDelegate.invalidateSize();
		if (!gAllMeetings) return;
		if (fitBounds) gDelegate.fitBounds(
			((gMeetingIdsFromCrouton) ? gAllMeetings.filter((m) => gMeetingIdsFromCrouton.includes(m.id_bigint)) : gAllMeetings)
				.reduce(function(a,m) {a.push([m.latitude, m.longitude]); return a;},[])
		);
	}
	function rad(x) {
  		return x * Math.PI / 180;
	}

	function getDistance(p1, p2) {
		var R = 6378137; // Earth’s mean radius in meter
		var dLat = rad(p2.lat - p1.lat);
		var dLong = rad(p2.lng - p1.lng);
		var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    		Math.cos(rad(p1.lat)) * Math.cos(rad(p2.lat)) *
    		Math.sin(dLong / 2) * Math.sin(dLong / 2);
		var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
		var d = R * c;
  		return d; // returns the distance in meter
	}
	function getDistanceFromSearch(p) {
		if (!gSearchPoint) return false;
		const d = getDistance(p, gSearchPoint);
		return {"km": d/1000.0, "miles": d*0.00062137119};
	}
	function getScreenRadius(units=false) {
		if (!units) units = crouton.config.distance_units;
		return getBoundsRadius(gDelegate.getCorners(), units);
	}
	function getBoundsRadius(corners, units = 'km') {
		return (getDistance(corners.ne, corners.sw)/2000.0) * ((units == 'km') ? 1.0 : 0.62137119);
	}
	function getLatLngRadius(lat_lngs) {
		return getBoundsRadius(gDelegate.getCorners(lat_lngs), 'km');
	}
	/****************************************************************************************
	 *								MAIN FUNCTIONAL INTERFACE								*
	 ****************************************************************************************/
	this.initialize = loadFromCrouton;
	this.showMap = showMap;
	this.fillMap = filterFromCrouton;
	this.rowClick = focusOnMeeting;
	this.apiLoadedCallback = apiLoadedCallback;
	this.refreshMeetings = loadAllMeetings;
	this.getDistanceFromSearch = getDistanceFromSearch;
	this.openModalWindow = openModalWindow;
	this.closeModalWindow = closeModalWindow;
	this.loadPopupMap = loadPopupMap;
	this.filterVisible = filterVisible;
	this.hasMapSearch = hasMapSearch;
};
MeetingMap.prototype.initialize = null;
MeetingMap.prototype.showMap = null;
MeetingMap.prototype.fillMap = null;
MeetingMap.prototype.rowClick = null;
MeetingMap.prototype.apiLoadedCallback = null;
MeetingMap.prototype.refreshMeetings = null;
MeetingMap.prototype.getDistanceFromSearch = null;

MeetingMap.prototype.openModalWindow = null;
MeetingMap.prototype.closeModalWindow = null;
MeetingMap.prototype.loadPopupMap = null;
MeetingMap.prototype.filterVisible = null;
MeetingMap.prototype.hasMapSearch = null;
