window.hbfwc                       = window.hbfwc || {};
hbfwc.filters                      = function ($) {
	const { __, _x, _n, _nx, sprintf } = wp.i18n;
	const filter = {
		init: function () {
			const d = this;

			d.filterInit();
			d.convertNumberFields();
			d.pointerActions();
			d.initFlex();
			d.ajaxified();
		},
		filterInit: function () {
			const d  = this;
			const wr = $( '.availability-filter__dates' );
			const df = wr.data( 'output-format' );

			moment.suppressDeprecationWarnings = true;
			wr.daterangepicker(
				{
					opens: 'right',
					showDropdowns: false,
					autoUpdateInput: false,
					startDate: wr.find( 'input[name="checkin"]' ).val(),
					endDate: wr.find( 'input[name="checkout"]' ).val(),
					minDate: wr.data( 'mindate' ),
					locale: {
						format: 'MM/DD/YYYY',
						daysOfWeek: hbfwc.cal_string.locale.daysOfWeek,
						monthNames: hbfwc.cal_string.locale.monthNames
					},
					autoApply: true,
					showCancel: false,
				}
			);

			wr.on(
				'apply.daterangepicker',
				function (ev, picker) {
					const unixCi = picker.startDate.format( 'MM/DD/YYYY' );
					const unixCo = picker.endDate.format( 'MM/DD/YYYY' );

					$( this ).find( 'input[name="checkin"]' ).val( unixCi ).trigger( 'change' );
					$( this ).find( 'input[name="checkout"]' ).val( unixCo ).trigger( 'change' );
					$( this ).find( '.availability-filter__content' ).text( d.dateFormat( df, unixCi ) + ' – ' + d.dateFormat( df, unixCo ) );

				}
			);

			$( document.body ).on(
				'change',
				'#adults, #children, #rooms',
				function (e) {
					const $dropdown = $( this ).closest( '.availability-filter__dd' );
					const $parents  = $( this ).closest( '.availability-filter__room' );
					const $inputID  = this.id;
					const $val      = $( this ).val();

					if ( $inputID === 'adults' ) {
						$parents.find( '.content-adults' ).text( sprintf( /* translators: Number of adults */ _n( '%d Adult', '%d Adults', parseInt( $val ), 'hotel-booking-for-woocommerce' ), $val ) );
					} else if ( $inputID === 'children' ) {
						$parents.find( '.content-children' ).text( sprintf( /* translators: Number of children */ _n( '%d Child', '%d Children', parseInt( $val ), 'hotel-booking-for-woocommerce' ), $val ) );

						if ( $( '#hhbfwc-children-age-slider__' + (parseInt( $val ) + 1) ).length ) {
							$( '#hhbfwc-children-age-slider__' + (parseInt( $val ) + 1) ).remove();
						}

						if ( parseInt( $val ) < 1 ) {
							return false;
						}

						for (var i = 1; i <= parseInt( $val ); i++) {
							if ( $( '#hhbfwc-children-age-slider__' + i ).length < 1 ) {
								let chtemp = $( '#hbfwc-children-age-slider-template' ).html();
								chtemp     = chtemp.replaceAll( '{{number}}', i );
								$( chtemp ).appendTo( $dropdown );
							}
						}
					} else if ( $inputID === 'rooms' ) {
						$parents.find( '.content-rooms' ).text( sprintf( /* translators: Number of rooms */ _n( '%d Room', '%d Rooms', parseInt( $val ), 'hotel-booking-for-woocommerce' ), $val ) );
					}

				}
			);
		},
		convertNumberFields: function () {
			const d            = this;
			const inputNumbers = $( "input.hbfgwc-with-buttons" );

			inputNumbers.each(
				function () {
					const t = $( this );
					t.wrap( "<div class=\"hbfgwc-quantity-number\"></div>" );

					if ( t.hasClass('converted') ) return;

					t.addClass('converted');

					$( '<button type="button" class="hbfwc-minus-button">&ndash;</button>' ).insertBefore( t );
					$( '<button type="button" class="hbfwc-plus-button">&plus;</button>' ).insertAfter( t );

					t.on(
						'click focus',
						function () {
							$( this ).blur();
						}
					)
				}
			);

			$( document.body ).on(
				'click',
				'.hbfwc-minus-button, .hbfwc-plus-button',
				function (e) {
					e.preventDefault();
					let inputNum = $( e.target ).parent().find( "input[type='number']" );
					if ( inputNum.is(':disabled') ) {
						return false;
					}
					inputNum.data( 'hbfwcPreviousValue', inputNum.val() );
					inputNum.data( 'hbfwcConfirmedQty', inputNum.val() );
					$( this ).hasClass( 'hbfwc-minus-button' ) ? inputNum[0].stepDown() : inputNum[0].stepUp();
					inputNum.trigger( 'change' );
				}
			);
		},
		pointerActions: function () {
			const d = this;
			$( document.body ).on(
				'click',
				'.availability-filter__room',
				function (e) {
					const _t = this;
					if (e.target === this || e.target.className.indexOf( "availability-filter" ) !== -1 ) {
						e.preventDefault();
						$( '.hbfwc-activated' ).not( this ).removeClass( 'hbfwc-activated' );
						$( this ).toggleClass( 'hbfwc-activated' );
					}

					$( 'body' ).on(
						'click',
						function (ev) {
							if ( ! ev.target.closest( '.availability-filter__room' ) && ev.target !== _t) {
								$( _t ).removeClass( 'hbfwc-activated' );
							}
						}
					);
				}
			).on(
				'click',
				'.hbfwc-button__rate-popup',
				function (e) {
					e.preventDefault();
					const rate_id = $( this ).data( 'rate_id' );
					$( '#hbfwc-rate-popup-' + rate_id ).addClass( 'is_called' );
					$( '#hbfwc-rate-popup-' + rate_id ).attr('tabindex', '-1');
					setTimeout(() => $( '#hbfwc-rate-popup-' + rate_id ).focus(), 300);
				}
			).on(
				'click',
				'.hbfwc-rate__popup-close',
				function (e) {
					e.preventDefault();
					$( this ).closest( '.hbfwc-rate__popup' ).removeClass( 'is_called' );
				}
			).on(
				'click',
				'.hbfwc-rate__popup',
				function (e) {
					if ( ! e.target.closest( '.hbfwc-rate__popup-wrapper' ) ) {
						e.preventDefault();
						$( this ).find( '.hbfwc-rate__popup-close' ).trigger( 'click' );
					}
				}
			).on(
				'click',
				'.hbfwc-button__popup, .hbfwc-product-gallery__image a',
				function (e) {
					e.preventDefault();
					const $this = $(this);
					$this.closest( '.product-type-accommodation' ).find( '.hbfwc-product-popup' ).addClass( 'is_called' );
					$this.closest( '.product-type-accommodation' ).find( '.hbfwc-product-popup' ).attr('tabindex', '-1');
					$this.closest( '.product-type-accommodation' ).find( '.hbfwc-product-popup .hbfwc-product__gallery' ).flexslider(
						{
							selector: '.hbfwc-product-gallery__wrapper > .hbfwc-product-gallery__image',
							slideshow: false,
							directionNav: false
						}
					);
					setTimeout(() => $this.closest( '.product-type-accommodation' ).find( '.hbfwc-product-popup' ).focus(), 300);
				}
			).on(
				'click',
				'.hbfwc-product__popup-close',
				function (e) {
					e.preventDefault();
					$( this ).closest( '.hbfwc-product-popup' ).removeClass( 'is_called' );
				}
			).on(
				'click',
				'.hbfwc-product-popup',
				function (e) {
					if ( ! e.target.closest( '.hbfwc-product-popup__wrap' ) ) {
						e.preventDefault();
						$( this ).find( '.hbfwc-product__popup-close' ).trigger( 'click' );
					}
				}
			).on(
				'click',
				'.hbfwc-info-indicator',
				function (e) {
					e.preventDefault();
				}
			);
		},
		dateFormat: function (format,date) {
			if ( ! date || date === "") {
				date = new Date();
			} else if (typeof('date') !== 'object') {
				date = new Date( date.replace( /-/g,"/" ) ); // attempt to convert string to date object
			}

			var string = '',
				mo     = date.getMonth(),   // month (0-11)
				m1     = mo + 1,			    // month (1-12)
				dow    = date.getDay(),    // day of week (0-6)
				d      = date.getDate(),     // day of the month (1-31)
				y      = date.getFullYear(), // 1999 or 2003
				h      = date.getHours(),    // hour (0-23)
				mi     = date.getMinutes(), // minute (0-59)
				s      = date.getSeconds();  // seconds (0-59)

			for (var i = 0, len = format.length; i < len; i++) {
				switch (format[i]) {
					case 'j': // Day of the month without leading zeros  (1 to 31)
						string += d;
						break;

					case 'd': // Day of the month, 2 digits with leading zeros (01 to 31)
						string += (d < 10) ? "0" + d : d;
						break;

					case 'l': // (lowercase 'L') A full textual representation of the day of the week
						var days = hbfwc.cal_string.date_l;
						string  += days[dow];
						break;

					case 'w': // Numeric representation of the day of the week (0=Sunday,1=Monday,...6=Saturday)
						string += dow;
						break;

					case 'D': // A textual representation of a day, three letters
						days    = hbfwc.cal_string.date_D;
						string += days[dow];
						break;

					case 'm': // Numeric representation of a month, with leading zeros (01 to 12)
						string += (m1 < 10) ? "0" + m1 : m1;
						break;

					case 'n': // Numeric representation of a month, without leading zeros (1 to 12)
						string += m1;
						break;

					case 'F': // A full textual representation of a month, such as January or March
						var months = hbfwc.cal_string.date_F;
						string    += months[mo];
						break;

					case 'M': // A short textual representation of a month, three letters (Jan - Dec)
						months  = hbfwc.cal_string.date_M;
						string += months[mo];
						break;

					case 'Y': // A full numeric representation of a year, 4 digits (1999 OR 2003)
						string += y;
						break;

					case 'y': // A two digit representation of a year (99 OR 03)
						string += y.toString().slice( -2 );
						break;

					case 'H': // 24-hour format of an hour with leading zeros (00 to 23)
						string += (h < 10) ? "0" + h : h;
						break;

					case 'g': // 12-hour format of an hour without leading zeros (1 to 12)
						var hour = (h === 0) ? 12 : h;
						string  += (hour > 12) ? hour - 12 : hour;
						break;

					case 'h': // 12-hour format of an hour with leading zeros (01 to 12)
						hour    = (h === 0) ? 12 : h;
						hour    = ( hour > 12) ? hour - 12 : hour;
						string += (hour < 10) ? "0" + hour : hour;
						break;

					case 'a': // Lowercase Ante meridiem and Post meridiem (am or pm)
						string += (h < 12) ? "am" : "pm";
						break;

					case 'i': // Minutes with leading zeros (00 to 59)
						string += (mi < 10) ? "0" + mi : mi;
						break;

					case 's': // Seconds, with leading zeros (00 to 59)
						string += (s < 10) ? "0" + s : s;
						break;

					case 'c': // ISO 8601 date (eg: 2012-11-20T18:05:54.944Z)
						string += date.toISOString();
						break;

					default:
						string += format[i];
				}
			}

			return string;
		},
		initFlex: function () {
			const [d, $flex] = [this, $( '.hbfwc-product__gallery' )];

			if ( $flex.length ) {
				$flex.each(
					function () {
						$( this ).flexslider(
							{
								selector: '.hbfwc-product-gallery__wrapper > .hbfwc-product-gallery__image',
								slideshow: false,
								directionNav: false
							}
						);
					}
				);
			}
		},
		ajaxified: function () {
			const _d    = this;
			let onAjax  = false;
			let defText = $( '.hbfwc-expand-cart' ).length > 0 ? $( '.hbfwc-expand-cart' ).text() : false;

			$( document.body ).on(
				'submit',
				'.hbfwc-ajax-rest__form',
				function (e) {
					e.preventDefault();
					const t = this;
					if ( onAjax ) {
						return false;
					}

					const roomId = $( t ).find( '[name=add-to-cart]' ).val();
					const addons = e.extraData?.addons || [];

					if ( ( addons.length < 1 && $('.hbfwc-addon-popup').length < 1 ) && Array.isArray(window.hbfwcAddons) && window.hbfwcAddons.length > 0) {

						const addonsForRoom = window.hbfwcAddons.filter(addon => {
							const ids = addon.room_ids.map(Number);
							return ids.length === 0 || ids.includes( parseInt(roomId) );
						});

						if ( addonsForRoom.length > 0 ) {
							_d.openAddonPopup(addonsForRoom, t);
							return false;
						}
					}

					onAjax = true;
					$( '#hbfwc-cart__mini' ).addClass( 'hbfwc-ajax-load' );
					$( t ).find( '[type=submit]' ).addClass( 'rest-loading' );

					const mainFormData = $(t).serializeArray();
					const mergedData = [...mainFormData, ...addons];

					$.ajax(
						{
							type: 'POST',
							url: hbfwc.rest_add_cart,
							dataType: 'json',
							headers: {
								'Nonce': hbfwc.rest_nonce
							},
							data: {
								id: $( t ).find( '[name=add-to-cart]' ).val(),
								quantity: $( t ).find( '[name=qty]' ).val(),
								hbfwc: $.param( mergedData )
							}
						}
					).done(
						function (response) {
							const qtyBtn = $( '<div class="hbfgwc-quantity-number"><button type="button" class="hbfwc-minus-button">&ndash;</button><input type="number" value="' + response.items.at( -1 ).quantity + '" name="qty" min="0" step="1" class="rest-qty__action" data-key="' + response.items.at( -1 ).key + '" /><button type="button" class="hbfwc-plus-button">&plus;</button></div>' )
							qtyBtn.insertAfter( $( t ) );
							$( t ).hide();
						}
					).always(
						function (xhr) {
							if ( typeof xhr.status !== 'undefined' ) {
									_d.buildNotice( xhr.responseJSON.message );
									$( '#hbfwc-cart__mini' ).removeClass( 'hbfwc-ajax-load' );
							} else {
								_d.updateCart();
							}
							onAjax = false;
							$( t ).find( '[type=submit]' ).removeClass( 'rest-loading' );
						}
					);
				}
			).on(
				'change',
				'.rest-qty__action',
				function () {
					const [t,vl,ky] = [this,$( this ).val(), $( this ).data( 'key' )];
					let previousQty = parseInt( $( t ).data( 'hbfwcPreviousValue' ), 10 );

					if ( isNaN( previousQty ) ) {
						previousQty = parseInt( $( t ).data( 'hbfwcConfirmedQty' ), 10 );
					}

					if ( isNaN( previousQty ) ) {
						previousQty = parseInt( vl, 10 );
					}

					if ( onAjax ) {
						return false;
					}
					onAjax = true;
					$( '#hbfwc-cart__mini' ).addClass( 'hbfwc-ajax-load' );
					$( t ).closest( '.hbfgwc-quantity-number' ).addClass( 'rest-loading' );

					// Allow extensions (e.g. room picker) to intercept before the REST call.
					const beforeQtyEvt = $.Event( 'hbfwcBeforeCartQtyChange' );
					$( document.body ).trigger( beforeQtyEvt, {
						input:         t,
						value:         vl,
						previousValue: previousQty,
						key:           ky,
						updateCart:    _d.updateCart.bind( _d ),
					} );
					if ( beforeQtyEvt.isDefaultPrevented() ) {
						onAjax = false;
						$( '#hbfwc-cart__mini' ).removeClass( 'hbfwc-ajax-load' );
						$( t ).closest( '.hbfgwc-quantity-number' ).removeClass( 'rest-loading' );
						return;
					}

					if ( parseInt( vl ) < 1 ) {
						$.ajax(
							{
								type: 'POST',
								url: hbfwc.rest_remove_item,
								dataType: 'json',
								headers: {
									'Nonce': hbfwc.rest_nonce
								},
								data: {
									key: ky
								}
							}
						).done(
							function (response) {
								_d.updateCart();
								$( t ).closest( '.hbfwc-room__rate-action' ).find( '.hbfwc-ajax-rest__form' ).show();
								$( t ).closest( '.hbfgwc-quantity-number' ).remove();
							}
						).always(
							function () {
								onAjax = false;
							}
						);
					} else {
						$.ajax(
							{
								type: 'POST',
								url: hbfwc.rest_update_item,
								dataType: 'json',
								headers: {
									'Nonce': hbfwc.rest_nonce
								},
								data: {
									key: ky,
									quantity: vl
								}
							}
						).done(
							function (response) {
								$( t ).closest( '.hbfgwc-quantity-number' ).removeClass( 'rest-loading' );
							}
						).always(
							function (xhr) {
								if ( typeof xhr.status !== 'undefined' ) {
									_d.buildNotice( xhr.responseJSON.message )
									$( t ).val( vl - 1 );
									$( t ).closest( '.hbfgwc-quantity-number' ).removeClass( 'rest-loading' );
									$( '#hbfwc-cart__mini' ).removeClass( 'hbfwc-ajax-load' );
								} else {
									_d.updateCart();
								}
								onAjax = false;
							}
						);
					}
				}
			).on(
				'click focus',
				'.rest-qty__action',
				function () {
					$( this ).blur();
				}
			).on(
				'click',
				'.hbfwc-expand-cart',
				function (e) {
					e.preventDefault();
					const b = this;

					if ( false === defText ) {
						defText = $( b ).text();
					}

					if ( $( '#hbfwc-cart__mini' ).find( 'h3, ul.hbfwc-mini-cart__items' ).is( ':hidden' ) ) {
						$( '#hbfwc-cart__mini' ).find( 'h3, ul.hbfwc-mini-cart__items' ).css( {display: 'block'} );
						$( b ).text( __( 'Hide cart', 'hotel-booking-for-woocommerce' ) );
					} else {
						$( '#hbfwc-cart__mini' ).find( 'h3, ul.hbfwc-mini-cart__items' ).css( {display: ''} );
						$( b ).text( defText );
					}
				}
			).on(
				'click',
				'.hbfwc_remove_item',
				function(e) {
					e.preventDefault();
					const [t,ky] = [this, $( this ).data( 'key' )];

					if ( onAjax ) {
						return false;
					}
					onAjax = true;
					$( '#hbfwc-cart__mini' ).addClass( 'hbfwc-ajax-load' );
					$.ajax(
						{
							type: 'POST',
							url: hbfwc.rest_remove_item,
							dataType: 'json',
							headers: {
								'Nonce': hbfwc.rest_nonce
							},
							data: {
								key: ky
							}
						}
					).done(
						function (response) {
							_d.updateCart();
							const tb = $('.rest-qty__action[data-key='+ky+']');
							if ( tb.length ) {
								tb.closest( '.hbfwc-room__rate-action' ).find( '.hbfwc-ajax-rest__form' ).show();
								tb.closest( '.hbfgwc-quantity-number' ).remove();
							}
						}
					).always(
						function () {
							onAjax = false;
						}
					);
				}
			);
		},
		updateCart: function () {
			const url = new URL(window.location.href);
			url.searchParams.set('nocache', Date.now());

			$('#hbfwc-cart__mini').load(
				url.toString() + " #hbfwc-cart__mini>*",
				function () {
					$('#hbfwc-cart__mini').removeClass('hbfwc-ajax-load');
				}
			);
		},
		buildNotice: function (msg) {
			const _d = this;
			const dv = $('<div id="bfwc-notice-popup" />');

			if ($('#bfwc-notice-popup').length < 1) {
				$(dv).appendTo('body');
				$('<p />').appendTo('#bfwc-notice-popup');
			}

			// Split by <br/>
			const container = $('#bfwc-notice-popup > p');
			container.empty();

			msg.split(/<br\s*\/?>/i).forEach(function (line, index, arr) {
				container.append(_d.parseStartsToNode(line));
				if (index < arr.length - 1) {
					container.append(document.createElement('br'));
				}
			});

			$('#bfwc-notice-popup').addClass('is_called');

			$('#bfwc-notice-popup').off('click').on('click', function () {
				$(this).removeClass('is_called');
			});
		},
		parseStartsToNode: function( text ) {
			const frag  = document.createDocumentFragment();
			const regex = /(\*\*\*([^*]+)\*\*\*|\*\*([^*]+)\*\*)/g;

			let lastIndex = 0;
			let match;

			text = text.replaceAll(' &quot;', ' **"');
			text = text.replaceAll('&quot; ', '"** ');

			while ( ( match = regex.exec( text ) ) !== null ) {
				// text before match
				if ( match.index > lastIndex ) {
					frag.appendChild(
						document.createTextNode( text.slice( lastIndex, match.index ) )
					);
				}

				// ***text***
				if ( match[2] ) {
					const em = document.createElement( 'em' );
					em.textContent = match[2];
					frag.appendChild( em );
				}
				// **text**
				else if ( match[3] ) {
					const strong = document.createElement( 'strong' );
					strong.textContent = match[3];
					frag.appendChild( strong );
				}

				lastIndex = regex.lastIndex;
			}

			// text left
			if ( lastIndex < text.length ) {
				frag.appendChild(
					document.createTextNode( text.slice( lastIndex ) )
				);
			}

			return frag;
		},
		openAddonPopup: function(addons, form) {
			const overlay = document.createElement('div');
			overlay.className = 'hbfwc-addon-overlay';

			const popup = document.createElement('div');
			popup.className = 'hbfwc-addon-popup';

			const title = document.createElement('h2');
			title.textContent = __( 'Select Add-ons', 'hotel-booking-for-woocommerce' );
			popup.appendChild(title);

			// Add-on list
			addons.forEach(addon => {
				const wrapper = document.createElement('div');
				wrapper.className = 'hbfwc-addon-popup-item';

				const label = document.createElement('label');

				const checkbox = document.createElement('input');
				checkbox.type = 'checkbox';
				checkbox.name = `addon[${addon.id}]`;
				checkbox.value = addon.id;
				checkbox.checked = addon.required;
				checkbox.disabled = addon.required;

				const content = document.createElement('div');
				const titleEl = document.createElement('strong');
				titleEl.textContent = addon.title;

				const descEl = document.createElement('div');
				descEl.className = 'hbfwc-addon-popup-item-description';
				descEl.innerHTML = addon.description || '';

				const priceEl = document.createElement('div');
				priceEl.className = 'hbfwc-addon-popup-item-price';
				let pricing = addon.price_html;
				if ( addon.type === 'quantity_based' ) {
					pricing += ' / ' + addon.unit;

					if ( addon.by_nights ) {
						pricing += ' ' + __( '/ night', 'hotel-booking-for-woocommerce' );
					}
				}
				priceEl.innerHTML = '<span class="addonPrice">' + pricing + '</span>';
				if (addon.type === 'quantity_based' && !addon.by_guests) {
					const quantityInput = document.createElement('input');
					quantityInput.type = 'number';
					quantityInput.name = `addon_quantity[${addon.id}]`;
					quantityInput.min = addon.min ?? 1;
					quantityInput.max = addon.max ?? 99;
					quantityInput.value = addon.min ?? 1;
					quantityInput.disabled = !checkbox.checked;
					priceEl.appendChild(quantityInput);

					checkbox.addEventListener('change', () => {
						quantityInput.disabled = !checkbox.checked;
						if (checkbox.checked) {
							quantityInput.focus();
						}
					});
				}

				content.appendChild(titleEl);
				content.appendChild(descEl);
				content.appendChild(priceEl);
				content.style.flex = '1 1 0';
				content.style.width = '100%';

				if ( addon.required ) {
					const hdCb = document.createElement('input');
					hdCb.type = 'hidden';
					hdCb.name = `addon[${addon.id}]`;
					hdCb.value = addon.id;
					label.appendChild(hdCb);
				}

				label.appendChild(checkbox);
				label.appendChild(content);
				wrapper.appendChild(label);
				popup.appendChild(wrapper);
			});

			const buttonWrapper = document.createElement('div');
			buttonWrapper.className = 'hbfwc-addon-popup-buttons-wrap';

			const cancelBtn = document.createElement('button');
			cancelBtn.className = 'button alt wp-element-button hbfwc-addon-popup-button-cancel';
			cancelBtn.textContent = __( 'Cancel', 'hotel-booking-for-woocommerce' );
			cancelBtn.type = 'button';
			cancelBtn.addEventListener('click', () => {
				document.body.removeChild(overlay);
			});

			const continueBtn = document.createElement('button');
			continueBtn.className = 'button alt wp-element-button hbfwc-addon-popup-button-go';
			continueBtn.textContent = __( 'Continue Booking', 'hotel-booking-for-woocommerce' );
			continueBtn.type = 'button';
			continueBtn.addEventListener('click', () => {
				const selectedAddons = $(popup).find(':input').serializeArray();
				$(form).trigger({
					type: 'submit',
					extraData: {
						addons: selectedAddons
					}
				});
				document.body.removeChild(overlay);
			});

			buttonWrapper.appendChild(cancelBtn);
			buttonWrapper.appendChild(continueBtn);
			popup.appendChild(buttonWrapper);
			overlay.appendChild(popup);
			document.body.appendChild(overlay);
			
			popup.setAttribute('tabindex', '-1');
			popup.focus();
		}
	};
	filter.init();
	return filter;
}(window.jQuery);