PageSourceSearch

https://www.pecc.org/media/com_miniteklivesearch/js/miniteklivesearch.js?1faddd

js pecc.org collected 2026-09-24 21:29:55 UTC 74,399 bytes, 1,746 lines download raw bytes

1((document, Joomla) => {
2    "use strict";
3
4    class MinitekLiveSearch {
5        constructor(params, formId, searchUrl, autosuggestUrl) {
6            const self = this;
7            const options = Joomla.getOptions("com_miniteklivesearch");
8            this.site_path = options.site_path;
9            this.orOperator = options.orOperator;
10            this.andOperator = options.andOperator;
11            this.notOperator = options.notOperator;
12
13            this.params = params;
14            this.formId = parseInt(formId, 10);
15            this.searchUrl =
16                this.site_path + searchUrl + "&form=" + this.formId;
17            this.autosuggestUrl = autosuggestUrl;
18
19            this.timer;
20            this.mls_ajax_request;
21            this.suggest_ajax_request;
22            this.showAutosuggest = parseInt(this.params.show_autosuggest);
23            this.appendToUrl = parseInt(this.params.append_to_url);
24            this.highlight = parseInt(this.params.mls_highlight_terms);
25            this.sidebar = this.params.filters_position == "sidebar";
26            this.openFilters = parseInt(this.params.open_filters);
27            this.form = document.querySelector("#mls-" + this.formId);
28            this.mls_clear_input = this.form.querySelector(".mls-clear-input");
29            this.mls_query_link = this.form.querySelector(".mls-query-link");
30            this.mls_input_tools = this.form.querySelector(".mls-input-tools");
31            this.mls_suggest_panel =
32                this.form.querySelector(".mls-suggest-panel");
33            this.mls_popular = this.form.querySelector(".mls-popular");
34            this.mls_suggestions = this.form.querySelector(".mls-suggestions");
35            this.keepFiltersOpen = this.sidebar && this.openFilters;
36            this.scrollToTop = this.params.mls_scroll_to_top ?? 1;
37            this.scrollToTop = parseInt(this.scrollToTop);
38
39            this.togglePanels();
40            this.submitForm();
41
42            // Show clear input button and input link on page load
43            if (this.form.querySelector(".mls-input").value) {
44                this.form.querySelector(
45                    ".mls-input-bar .input-group-addon i.fa-search"
46                ).style.display = "none";
47                this.mls_clear_input.style.display = "block";
48                if (this.mls_query_link)
49                    this.mls_query_link.style.display = "flex";
50            }
51
52            this.mls_clear_input.addEventListener("click", function (e) {
53                e.preventDefault();
54                self.clearInput();
55            });
56
57            this.bindSearchInput();
58            this.initSuggestions();
59            this.openSuggestions();
60            this.saveSearch();
61            this.initMapFilters();
62            this.initDateFilters();
63            this.dropdownLayout();
64            this.clickEvents();
65        }
66
67        togglePanels() {
68            const self = this;
69            const mls_toggle = self.form.querySelectorAll(".mls-toggle");
70
71            if (mls_toggle) {
72                mls_toggle.forEach((item) => {
73                    item.addEventListener("click", function (e) {
74                        e.preventDefault();
75                        const panel = item.getAttribute("data-panel");
76                        self.mls_input_tools
77                            .querySelector(
78                                ".mls-toggle[data-panel='" + panel + "']"
79                            )
80                            .classList.toggle("mls-btn-open");
81
82                        if (
83                            self.mls_input_tools
84                                .querySelector(
85                                    ".mls-toggle[data-panel='" + panel + "']"
86                                )
87                                .classList.contains("mls-btn-open")
88                        )
89                            self.form.querySelector(
90                                ".mls-" + panel + "-panel"
91                            ).style.display = "block";
92                        else
93                            self.form.querySelector(
94                                ".mls-" + panel + "-panel"
95                            ).style.display = "none";
96                    });
97                });
98            }
99        }
100
101        submitForm() {
102            const self = this;
103            const q = self.form.querySelector(".mls-input");
104            var _value = q.value;
105
106            // Check if there is a pending ajax request
107            if (typeof self.mls_ajax_request !== "undefined")
108                self.mls_ajax_request.abort();
109
110            if (_value.trim().length > 0) {
111                if (self.form.querySelector(".mls-save-search"))
112                    self.form
113                        .querySelector(".mls-save-search")
114                        .removeAttribute("disabled");
115
116                self.form.querySelector(".mls-loader").style.display = "flex";
117                self.form.querySelector(
118                    ".mls-input-bar .input-group-addon i.fa-search"
119                ).style.display = "none";
120                self.mls_clear_input.style.display = "none";
121                if (self.mls_query_link)
122                    self.mls_query_link.style.display = "none";
123
124                // Serialize form data
125                var data = new FormData(self.form);
126                var _data = "";
127                var _dates = "";
128                var d1_exists = false;
129                var d2_exists = false;
130
131                for (var p of data) {
132                    if (p[0] == "mls-search-title") continue;
133
134                    if (
135                        p[0] == "w1" ||
136                        p[0] == "d1" ||
137                        p[0] == "w2" ||
138                        p[0] == "d2"
139                    )
140                        _dates += "&" + p[0] + "=" + p[1];
141                    else _data += "&" + p[0] + "=" + p[1];
142
143                    if (p[0] == "d1" && p[1]) d1_exists = true;
144                    if (p[0] == "d2" && p[1]) d2_exists = true;
145                }
146
147                // Add dates if they exist
148                if (d1_exists || d2_exists) _data += _dates;
149
150                // Execute new ajax request
151                self.mls_ajax_request = Joomla.request({
152                    url: self.searchUrl,
153                    method: "POST",
154                    data: _data,
155                    onSuccess: (response, xhr) => {
156                        let q_now = self.form
157                            .querySelector(".mls-input")
158                            .value.trim();
159
160                        // Abort if input is empty by the time this request has finished
161                        if (q_now.length == 0) {
162                            self.clearInput();
163                            return;
164                        }
165
166                        let action = self.form.action;
167
168                        self.form.querySelector(".mls-results").innerHTML =
169                            response;
170                        self.form.querySelector(".mls-loader").style.display =
171                            "none";
172                        self.mls_clear_input.style.display = "block";
173                        if (self.mls_query_link) {
174                            self.updateQueryLink(_data, action);
175                            self.mls_query_link.style.display = "flex";
176                        }
177
178                        if (
179                            self.form.querySelector(
180                                ".mls-dropdown .mls-results"
181                            )
182                        )
183                            self.form.querySelector(
184                                ".mls-dropdown .mls-results"
185                            ).style.display = "block";
186
187                        if (self.appendToUrl) self.appendUrl(_data, action);
188
189                        // Highlight terms
190                        if (self.highlight) {
191                            let terms = _value.trim();
192                            new Mark(
193                                self.form.querySelector(".js-highlight")
194                            ).mark(terms, {
195                                exclude: [
196                                    ".bg-primary",
197                                    ".bg-secondary",
198                                    ".mls-tag",
199                                    ".result-url a",
200                                ],
201                            });
202                        }
203                    },
204                    onError: (xhr) => {
205                        if (xhr.status > 0)
206                            Joomla.renderMessages(
207                                Joomla.ajaxErrorsMessages(xhr)
208                            );
209                    },
210                });
211            }
212        }
213
214        clearInput(focus = true) {
215            const self = this;
216
217            if (self.form.querySelector(".mls-save-search"))
218                self.form
219                    .querySelector(".mls-save-search")
220                    .setAttribute("disabled", "");
221
222            self.form.querySelector(
223                ".mls-input-bar .input-group-addon i.fa-search"
224            ).style.display = "block";
225            self.mls_clear_input.style.display = "none";
226            if (self.mls_query_link) self.mls_query_link.style.display = "none";
227            self.form.querySelector(".mls-loader").style.display = "none";
228            self.form.querySelector(".mls-input").value = "";
229
230            if (focus) self.form.querySelector(".mls-input").focus();
231
232            if (self.mls_suggest_panel) {
233                if (self.mls_popular) self.mls_popular.classList.add("visible");
234
235                if (self.mls_suggestions) {
236                    self.mls_suggestions.classList.remove("visible");
237                    self.mls_suggestions.querySelector("ul").innerHTML = "";
238                }
239
240                self.mls_suggest_panel
241                    .querySelectorAll("ul li")
242                    .forEach((a) => {
243                        a.classList.remove("selected");
244                    });
245            }
246
247            if (self.form.querySelector(".mls-empty-search"))
248                self.form.querySelector(".mls-empty-search").style.display =
249                    "block";
250
251            if (self.form.querySelector(".mls-results-inner"))
252                self.form.querySelector(".mls-results-inner").remove();
253
254            self.clearUrl();
255        }
256
257        // Update query link
258        updateQueryLink(data, action, start = 0) {
259            const self = this;
260            let url = self.getNewUrl(data, action, (start = 0));
261            self.mls_query_link.href = url;
262        }
263
264        // Append search params to url
265        appendUrl(data, action, start = 0) {
266            const self = this;
267            let url = self.getNewUrl(data, action, (start = 0));
268            window.history.pushState({}, "", url);
269        }
270
271        // Clear search params from url
272        clearUrl() {
273            let url = new URL(window.location) + "?";
274            url = url.substring(0, url.indexOf("?"));
275            window.history.pushState({}, "", url);
276        }
277
278        // Construct new url
279        getNewUrl(data, action, start = 0) {
280            let url_data = data;
281            var ajax_regex = /([&]ajax=[0-9])/g;
282            url_data = url_data.replace(ajax_regex, "");
283            var module_regex = /([&]moduleid=[0-9])/g;
284            url_data = url_data.replace(module_regex, "");
285            url_data = url_data.substring(1);
286            if (start > 0) url_data += "&start=" + start;
287
288            return action + "?" + url_data;
289        }
290
291        bindSearchInput() {
292            const self = this;
293
294            self.form.addEventListener("input", function (e) {
295                const mls_input = self.form.querySelector(".mls-input");
296                let trim_q = mls_input.value.trimStart();
297                trim_q = trim_q.replace(/\s\s+/g, " ");
298                mls_input.value = trim_q;
299
300                // Close popular searches
301                if (self.mls_suggest_panel) {
302                    if (trim_q) {
303                        if (self.mls_popular)
304                            self.mls_popular.classList.remove("visible");
305
306                        self.mls_suggest_panel
307                            .querySelectorAll("ul li")
308                            .forEach((a) => {
309                                a.classList.remove("selected");
310                            });
311                    }
312                }
313
314                if (!trim_q) self.clearInput(false);
315
316                // Wait for 500ms before submitting form
317                window.clearTimeout(self.timer);
318                self.timer = window.setTimeout(function () {
319                    self.submitForm();
320                }, 500);
321
322                return false;
323            });
324        }
325
326        // Open suggestions when clicking input
327        openSuggestions() {
328            const self = this;
329
330            ["click", "ontouchstart"].forEach((evt) =>
331                self.form
332                    .querySelector(".mls-input")
333                    .addEventListener(evt, function (e) {
334                        const mls_input = self.form.querySelector(".mls-input");
335                        let trim_q = mls_input.value.trimStart();
336                        trim_q = trim_q.replace(/\s\s+/g, " ");
337
338                        if (self.mls_suggest_panel) {
339                            if (
340                                (!trim_q &&
341                                    self.mls_popular &&
342                                    self.mls_popular.querySelectorAll("ul li")
343                                        .length > 0) ||
344                                (self.mls_suggestions &&
345                                    self.mls_suggestions.querySelectorAll(
346                                        "ul li"
347                                    ).length > 0)
348                            ) {
349                                self.mls_suggest_panel.style.display = "block";
350                            }
351
352                            if (!trim_q) {
353                                if (self.mls_suggestions)
354                                    self.mls_suggestions.querySelector(
355                                        "ul"
356                                    ).innerHTML = "";
357
358                                if (self.mls_popular)
359                                    self.mls_popular.classList.add("visible");
360                            } else {
361                                if (
362                                    self.mls_suggestions.querySelectorAll(
363                                        "ul li"
364                                    ).length
365                                )
366                                    self.mls_suggestions.classList.add(
367                                        "visible"
368                                    );
369                            }
370                        }
371                    })
372            );
373        }
374
375        saveSearch() {
376            const self = this;
377
378            if (self.form.querySelector(".mls-search-title")) {
379                self.form
380                    .querySelector(".mls-save-search")
381                    .addEventListener("click", function (e) {
382                        if (self.form.querySelectorAll(".mls-message"))
383                            self.form
384                                .querySelectorAll(".mls-message")
385                                .forEach((a) => {
386                                    a.style.display = "none";
387                                });
388
389                        let title =
390                            self.form.querySelector(".mls-search-title").value;
391
392                        if (title.length == 0) {
393                            self.form
394                                .querySelector(".mls-search-title")
395                                .classList.add("invalid");
396
397                            if (self.form.querySelector(".mls-title-empty"))
398                                self.form.querySelector(
399                                    ".mls-title-empty"
400                                ).style.display = "inline-block";
401                            else
402                                Joomla.renderMessages({
403                                    error: [
404                                        Joomla.Text._(
405                                            "COM_MINITEKLIVESEARCH_MESSAGE_ENTER_SEARCH_TITLE"
406                                        ),
407                                    ],
408                                });
409                        } else {
410                            self.form
411                                .querySelector(".mls-search-title")
412                                .classList.remove("invalid");
413
414                            let form_id = self.form.getAttribute("data-form");
415                            let Itemid = self.form.getAttribute("data-itemid");
416
417                            let url = new URL(window.location);
418                            let search_params = new URLSearchParams(
419                                url.search
420                            ).toString();
421
422                            let data = {
423                                title: title,
424                                form_id: parseInt(form_id, 10),
425                                Itemid: parseInt(Itemid, 10),
426                                search_params: search_params,
427                            };
428
429                            // Show loader
430                            self.form.querySelector(
431                                ".mls-save-loader"
432                            ).style.display = "inline-block";
433
434                            // Ajax request
435                            Joomla.request({
436                                url:
437                                    self.site_path +
438                                    "index.php?option=com_miniteklivesearch&task=saveSearch",
439                                method: "POST",
440                                data: JSON.stringify(data),
441                                onSuccess: (response, xhr) => {
442                                    response = JSON.parse(response);
443
444                                    // Error
445                                    if (
446                                        response.status === -1 ||
447                                        response.status === 0
448                                    ) {
449                                        if (
450                                            self.form.querySelector(
451                                                ".mls-save-error"
452                                            )
453                                        )
454                                            self.form.querySelector(
455                                                ".mls-save-error"
456                                            ).style.display = "inline-block";
457                                        else
458                                            Joomla.renderMessages({
459                                                error: [response.message],
460                                            });
461                                    }
462                                    // Success
463                                    else if (response.status === 1) {
464                                        if (
465                                            self.form.querySelector(
466                                                ".mls-save-success"
467                                            )
468                                        )
469                                            self.form.querySelector(
470                                                ".mls-save-success"
471                                            ).style.display = "inline-block";
472                                        else
473                                            Joomla.renderMessages({
474                                                message: [response.message],
475                                            });
476                                    }
477
478                                    // Hide loader
479                                    self.form.querySelector(
480                                        ".mls-save-loader"
481                                    ).style.display = "none";
482                                },
483                                onError: (xhr) => {
484                                    if (xhr.status > 0)
485                                        Joomla.renderMessages(
486                                            Joomla.ajaxErrorsMessages(xhr)
487                                        );
488                                },
489                            });
490                        }
491                    });
492            }
493        }
494
495        // Pagination
496        submitPage(link_href) {
497            const self = this;
498
499            if (typeof self.mls_ajax_request !== "undefined")
500                self.mls_ajax_request.abort();
501
502            self.form.querySelector(".mls-loader").style.display = "flex";
503            self.form.querySelector(".mls-page-loader-wrap").style.display =
504                "block";
505            self.form.querySelector(
506                ".mls-input-bar .input-group-addon i.fa-search"
507            ).style.display = "none";
508            self.mls_clear_input.style.display = "none";
509            if (self.mls_query_link) self.mls_query_link.style.display = "none";
510
511            // Serialize form data
512            var data = new FormData(self.form);
513            var _data = "";
514            var _dates = "";
515            var d1_exists = false;
516            var d2_exists = false;
517
518            for (var p of data) {
519                if (p[0] == "mls-search-title") continue;
520
521                if (
522                    p[0] == "w1" ||
523                    p[0] == "d1" ||
524                    p[0] == "w2" ||
525                    p[0] == "d2"
526                )
527                    _dates += "&" + p[0] + "=" + p[1];
528                else _data += "&" + p[0] + "=" + p[1];
529
530                if (p[0] == "d1" && p[1]) d1_exists = true;
531                if (p[0] == "d2" && p[1]) d2_exists = true;
532            }
533
534            // Add dates if they exist
535            if (d1_exists || d2_exists) _data += _dates;
536
537            // Get page
538            var start = parseInt(link_href.split("&start=").pop(), 10);
539
540            self.mls_ajax_request = Joomla.request({
541                url: link_href + "&form=" + self.formId,
542                method: "POST",
543                data: _data,
544                onSuccess: (response, xhr) => {
545                    self.form.querySelector(".mls-results").innerHTML =
546                        response;
547                    self.form.querySelector(".mls-loader").style.display =
548                        "none";
549                    self.mls_clear_input.style.display = "block";
550
551                    let action = self.form.action;
552
553                    if (self.mls_query_link) {
554                        self.updateQueryLink(_data, action);
555                        self.mls_query_link.style.display = "flex";
556                    }
557
558                    if (this.scrollToTop) self.form.scrollIntoView();
559
560                    // Append search params to url
561                    if (self.appendToUrl) self.appendUrl(_data, action, start);
562
563                    // Highlight terms
564                    if (self.highlight) {
565                        const _value =
566                            self.form.querySelector(".mls-input").value;
567                        let terms = _value.trim();
568                        new Mark(self.form.querySelector(".js-highlight")).mark(
569                            terms,
570                            {
571                                exclude: [
572                                    ".bg-primary",
573                                    ".bg-secondary",
574                                    ".mls-tag",
575                                    ".result-url a",
576                                ],
577                            }
578                        );
579                    }
580                },
581                onError: (xhr) => {
582                    if (xhr.status > 0)
583                        Joomla.renderMessages(Joomla.ajaxErrorsMessages(xhr));
584                },
585            });
586        }
587
588        onInputChange(target, url) {
589            const self = this;
590
591            if (typeof self.suggest_ajax_request !== "undefined")
592                self.suggest_ajax_request.abort();
593
594            const ul = self.mls_suggestions.querySelector("ul");
595
596            if (target.value.length == 1) {
597                self.mls_suggest_panel.style.display = "none";
598            } else if (target.value.length > 1) {
599                Joomla.request({
600                    url: "".concat(url, "&q=").concat(target.value),
601                    method: "GET",
602                    data: {
603                        q: target.value,
604                    },
605                    perform: true,
606                    headers: {
607                        "Content-Type": "application/x-www-form-urlencoded",
608                    },
609                    onSuccess: (resp) => {
610                        const response = JSON.parse(resp);
611
612                        if (
613                            Object.prototype.toString.call(
614                                response.suggestions
615                            ) === "[object Array]" &&
616                            response.suggestions.length
617                        ) {
618                            ul.innerHTML = "";
619
620                            response.suggestions.forEach((suggestion) => {
621                                const li = document.createElement("li");
622                                const a = document.createElement("a");
623                                a.href = "#";
624                                a.innerText = suggestion;
625                                li.appendChild(a);
626                                ul.appendChild(li);
627                                a.addEventListener(
628                                    "click",
629                                    self.onSuggestionClick.bind(self)
630                                );
631                            });
632
633                            self.mls_suggestions.classList.add("visible");
634                            self.mls_suggest_panel.style.display = "block";
635                        } else {
636                            self.mls_suggest_panel.style.display = "none";
637                        }
638                    },
639                    onError: (xhr) => {
640                        if (xhr.status > 0) {
641                            Joomla.renderMessages(
642                                Joomla.ajaxErrorsMessages(xhr)
643                            );
644                        }
645                    },
646                });
647            }
648        }
649
650        onSuggestionClick(e) {
651            const self = this;
652
653            e.preventDefault();
654            self.form.querySelector(".mls-input").value = e.target.innerText;
655            self.mls_suggest_panel.style.display = "none";
656
657            if (self.mls_popular) self.mls_popular.classList.remove("visible");
658            if (self.mls_suggestions)
659                self.mls_suggestions.classList.remove("visible");
660
661            self.submitForm();
662        }
663
664        initSuggestions() {
665            const self = this;
666
667            if (self.mls_suggest_panel) {
668                // Close on click outside
669                document.addEventListener(
670                    "mouseup",
671                    self.closeSuggestions.bind(self),
672                    false
673                );
674                document.addEventListener(
675                    "touchend",
676                    self.closeSuggestions.bind(self),
677                    false
678                );
679
680                // Click suggestions
681                if (self.mls_suggest_panel) {
682                    if (self.mls_suggest_panel.querySelectorAll("ul")) {
683                        self.mls_suggest_panel
684                            .querySelectorAll("ul")
685                            .forEach((ul) => {
686                                ul.querySelectorAll("li a").forEach((a) => {
687                                    a.addEventListener(
688                                        "click",
689                                        self.onSuggestionClick.bind(self)
690                                    );
691                                });
692                            });
693                    }
694                }
695
696                const searchInputs = [].slice.call(
697                    self.form.querySelectorAll(".mls-input")
698                );
699
700                searchInputs.forEach((searchInput) => {
701                    // Suggestions on input
702                    if (self.showAutosuggest > 0) {
703                        searchInput.addEventListener("input", function () {
704                            var lastChar = searchInput.value.substring(
705                                searchInput.value.length - 1
706                            );
707
708                            if (lastChar != " ")
709                                self.onInputChange(
710                                    searchInput,
711                                    self.autosuggestUrl
712                                );
713                        });
714                    }
715
716                    // Navigate suggestions
717                    var liSelected;
718                    var index = -1;
719
720                    searchInput.addEventListener("keydown", function (e) {
721                        if (
722                            e.isComposing ||
723                            e.key === "Process" ||
724                            e.keyCode === 229
725                        )
726                            return;
727                        else if (
728                            e.keyCode === 40 ||
729                            e.keyCode === 38 ||
730                            e.keyCode === 13
731                        ) {
732                            var ul = self.form.querySelector(
733                                ".mls-panel-items.visible ul"
734                            );
735
736                            if (!ul) return;
737
738                            var len = ul.getElementsByTagName("li").length - 1;
739
740                            if (len < 0) return;
741
742                            liSelected = ul.querySelector("li.selected");
743                        } else return;
744
745                        if (e.keyCode === 40) {
746                            // Down
747                            index++;
748
749                            if (liSelected) {
750                                liSelected.classList.remove("selected");
751                                let next = ul.getElementsByTagName("li")[index];
752
753                                if (typeof next !== undefined && index <= len) {
754                                    liSelected = next;
755                                } else {
756                                    index = 0;
757                                    liSelected =
758                                        ul.getElementsByTagName("li")[0];
759                                }
760
761                                liSelected.classList.add("selected");
762                            } else {
763                                index = 0;
764                                liSelected = ul.getElementsByTagName("li")[0];
765                                liSelected.classList.add("selected");
766                            }
767                        } else if (e.keyCode === 38) {
768                            // Up
769                            if (liSelected) {
770                                liSelected.classList.remove("selected");
771                                index--;
772                                let next = ul.getElementsByTagName("li")[index];
773
774                                if (typeof next !== undefined && index >= 0) {
775                                    liSelected = next;
776                                } else {
777                                    index = len;
778                                    liSelected =
779                                        ul.getElementsByTagName("li")[len];
780                                }
781
782                                liSelected.classList.add("selected");
783                            } else {
784                                index = 0;
785                                liSelected = ul.getElementsByTagName("li")[len];
786                                liSelected.classList.add("selected");
787                            }
788                        } else if (e.keyCode === 13) {
789                            // Enter
790                            e.preventDefault();
791
792                            if (liSelected)
793                                self.form.querySelector(".mls-input").value =
794                                    liSelected.innerText;
795
796                            self.mls_suggest_panel.style.display = "none";
797
798                            if (self.mls_popular)
799                                self.mls_popular.classList.remove("visible");
800                            if (self.mls_suggestions)
801                                self.mls_suggestions.classList.remove(
802                                    "visible"
803                                );
804
805                            self.submitForm();
806
807                            return false;
808                        }
809                    });
810                });
811            }
812        }
813
814        closeSuggestions(e) {
815            const self = this;
816
817            if (
818                !e.target.closest(".mls-suggest-panel") &&
819                !e.target.closest(".mls-input")
820            ) {
821                if (self.mls_popular)
822                    self.mls_popular.classList.remove("visible");
823                if (self.mls_suggestions)
824                    self.mls_suggestions.classList.remove("visible");
825
826                if (self.mls_suggest_panel) {
827                    self.mls_suggest_panel.style.display = "none";
828                    self.mls_suggest_panel
829                        .querySelectorAll("ul li")
830                        .forEach((a) => {
831                            a.classList.remove("selected");
832                        });
833                }
834            }
835        }
836
837        initMapFilters() {
838            const self = this;
839
840            if (self.form.querySelector(".mls-maps-panel")) {
841                self.countFilters();
842
843                // Calculate filters width
844                if (
845                    !self.sidebar &&
846                    self.form.querySelectorAll(".mls-filters-type")
847                ) {
848                    var mls_types_width = 0;
849                    self.form
850                        .querySelectorAll(".mls-filters-type")
851                        .forEach((a) => {
852                            mls_types_width += a.offsetWidth;
853                        });
854
855                    if (self.form.querySelector(".mls-filters-types")) {
856                        self.form.querySelector(
857                            ".mls-filters-types"
858                        ).style.width = mls_types_width + 1 + "px";
859                    }
860                }
861
862                // Select filter
863                const mls_type = self.form.querySelectorAll(".mls-type");
864
865                if (mls_type) {
866                    mls_type.forEach((filter) => {
867                        // Check if filter is checked on page load
868                        if (filter.checked) {
869                            filter
870                                .closest(".controls")
871                                .classList.add("mls-checked");
872                        }
873
874                        // Toggle filters box if keep filters open is disabled
875                        if (self.sidebar && !self.keepFiltersOpen) {
876                            var filter_id = filter.getAttribute("data-id");
877
878                            filter
879                                .closest("label")
880                                .addEventListener("click", function (e) {
881                                    self.form
882                                        .querySelectorAll(
883                                            '.mls-filters-group-box[data-filter="' +
884                                                filter_id +
885                                                '"]'
886                                        )
887                                        .forEach((a) => {
888                                            if (
889                                                !a.classList.contains(
890                                                    "mls-filters-hidden"
891                                                )
892                                            ) {
893                                                e.preventDefault();
894
895                                                if (
896                                                    !a.style.display ||
897                                                    a.style.display == "none"
898                                                )
899                                                    a.style.display = "block";
900                                                else a.style.display = "none";
901                                            }
902                                        });
903                                });
904                        }
905
906                        filter.addEventListener("change", function (e) {
907                            var filter_id = filter.getAttribute("data-id");
908
909                            if (!self.keepFiltersOpen)
910                                self.form
911                                    .querySelectorAll(".mls-filters-group-box")
912                                    .forEach((a) => {
913                                        a.style.display = "none";
914                                    });
915
916                            if (filter.checked) {
917                                filter
918                                    .closest(".controls")
919                                    .classList.add("mls-checked");
920                                mls_type.forEach((a) => {
921                                    a.closest(".controls").classList.remove(
922                                        "mls-active"
923                                    );
924                                });
925                            } else {
926                                if (
927                                    filter
928                                        .closest(".controls")
929                                        .classList.contains("mls-active")
930                                ) {
931                                    mls_type.forEach((a) => {
932                                        a.closest(".controls").classList.remove(
933                                            "mls-active"
934                                        );
935                                    });
936                                } else {
937                                    mls_type.forEach((a) => {
938                                        a.closest(".controls").classList.remove(
939                                            "mls-active"
940                                        );
941                                    });
942
943                                    if (!self.sidebar || !self.keepFiltersOpen)
944                                        filter
945                                            .closest(".controls")
946                                            .classList.add("mls-active");
947
948                                    self.form
949                                        .querySelectorAll(
950                                            '.mls-filters-group-box[data-filter="' +
951                                                filter_id +
952                                                '"]'
953                                        )
954                                        .forEach((a) => {
955                                            if (
956                                                !a.classList.contains(
957                                                    "mls-filters-hidden"
958                                                )
959                                            )
960                                                a.style.display = "block";
961                                        });
962                                }
963
964                                filter.checked = true;
965                            }
966
967                            // Check all children if none is selected
968                            let children_selected = self.form.querySelectorAll(
969                                '.filter-node:checked[data-filter="' +
970                                    filter_id +
971                                    '"]'
972                            ).length;
973
974                            if (!children_selected) {
975                                self.form
976                                    .querySelectorAll(
977                                        '.filter-node[data-filter="' +
978                                            filter_id +
979                                            '"]'
980                                    )
981                                    .forEach((a) => {
982                                        a.checked = true;
983                                    });
984                            }
985
986                            self.countFilters();
987                        });
988                    });
989                }
990
991                // Show more children nodes
992                const mls_more_items = self.form.querySelectorAll(".mls-more");
993
994                mls_more_items.forEach((selector) => {
995                    selector.addEventListener("click", function (e) {
996                        selector
997                            .closest(".mls-filters-column")
998                            .querySelectorAll(".control-group")
999                            .forEach((a) => {
1000                                a.classList.remove("mls-hidden");
1001                            });
1002
1003                        selector.style.display = "none";
1004                    });
1005                });
1006
1007                // Expand filter
1008                const mls_select_type =
1009                    self.form.querySelectorAll(".mls-select-type");
1010
1011                mls_select_type.forEach((selector) => {
1012                    selector.addEventListener("click", function (e) {
1013                        var filter_id = selector
1014                            .closest(".controls")
1015                            .querySelector(".mls-type")
1016                            .getAttribute("data-id");
1017
1018                        if (!self.keepFiltersOpen)
1019                            self.form
1020                                .querySelectorAll(".mls-filters-group-box")
1021                                .forEach((a) => {
1022                                    a.style.display = "none";
1023                                });
1024
1025                        self.form
1026                            .querySelectorAll(
1027                                '.mls-filters-group-box[data-filter="' +
1028                                    filter_id +
1029                                    '"]'
1030                            )
1031                            .forEach((a) => {
1032                                if (!a.classList.contains("mls-filters-hidden"))
1033                                    a.style.display = "block";
1034                            });
1035                        self.form.querySelectorAll(".mls-type").forEach((a) => {
1036                            a.closest(".controls").classList.remove(
1037                                "mls-active"
1038                            );
1039                        });
1040
1041                        selector
1042                            .closest(".controls")
1043                            .classList.add("mls-checked");
1044
1045                        if (!self.sidebar || !self.keepFiltersOpen)
1046                            selector
1047                                .closest(".controls")
1048                                .classList.add("mls-active");
1049
1050                        selector
1051                            .closest(".controls")
1052                            .querySelector(".mls-type").checked = true;
1053
1054                        // Check all children
1055                        self.form
1056                            .querySelectorAll(
1057                                '.filter-node[data-filter="' + filter_id + '"]'
1058                            )
1059                            .forEach((a) => {
1060                                a.checked = true;
1061                            });
1062
1063                        self.countFilters();
1064                        self.submitForm();
1065                    });
1066                });
1067
1068                // Remove filter
1069                const mls_uncheck_type =
1070                    self.form.querySelectorAll(".mls-uncheck-type");
1071
1072                mls_uncheck_type.forEach((selector) => {
1073                    selector.addEventListener("click", function (e) {
1074                        var filter_id = selector.getAttribute("data-filter");
1075                        selector
1076                            .closest(".controls")
1077                            .querySelector(".mls-type").checked = false;
1078                        selector
1079                            .closest(".controls")
1080                            .classList.remove("mls-checked");
1081                        self.form
1082                            .querySelectorAll(".mls-filters-type .controls")
1083                            .forEach((a) => {
1084                                a.classList.remove("mls-active");
1085                            });
1086
1087                        if (!self.keepFiltersOpen)
1088                            self.form
1089                                .querySelectorAll(".mls-filters-group-box")
1090                                .forEach((a) => {
1091                                    a.style.display = "none";
1092                                });
1093
1094                        // Uncheck all children
1095                        self.form
1096                            .querySelectorAll(
1097                                '.filter-node[data-filter="' + filter_id + '"]'
1098                            )
1099                            .forEach((a) => {
1100                                a.checked = false;
1101                            });
1102
1103                        self.countFilters();
1104                        self.submitForm();
1105                    });
1106                });
1107
1108                // Select all children nodes
1109                const select_all =
1110                    self.form.querySelectorAll(".mls-select-all");
1111
1112                select_all.forEach((selector) => {
1113                    selector.addEventListener("click", function (e) {
1114                        const filter_id = selector.getAttribute("data-filter");
1115
1116                        selector
1117                            .closest(".mls-group-box")
1118                            .querySelectorAll(".filter-node")
1119                            .forEach((a) => {
1120                                a.checked = true;
1121                            });
1122
1123                        if (filter_id) {
1124                            // Select type
1125                            self.form.querySelector(
1126                                '.mls-type[data-id="' + filter_id + '"]'
1127                            ).checked = true;
1128
1129                            if (!self.sidebar || !self.keepFiltersOpen)
1130                                self.form
1131                                    .querySelector(
1132                                        '.mls-type[data-id="' + filter_id + '"]'
1133                                    )
1134                                    .closest(".controls")
1135                                    .classList.add("mls-active");
1136
1137                            self.form
1138                                .querySelector(
1139                                    '.mls-type[data-id="' + filter_id + '"]'
1140                                )
1141                                .closest(".controls")
1142                                .classList.add("mls-checked");
1143                        }
1144
1145                        self.countFilters();
1146                        self.submitForm();
1147                    });
1148                });
1149
1150                // Deselect all children nodes
1151                const select_none =
1152                    self.form.querySelectorAll(".mls-select-none");
1153
1154                select_none.forEach((selector) => {
1155                    selector.addEventListener("click", function (e) {
1156                        const filter_id = selector.getAttribute("data-filter");
1157
1158                        selector
1159                            .closest(".mls-group-box")
1160                            .querySelectorAll(".filter-node")
1161                            .forEach((a) => {
1162                                a.checked = false;
1163                            });
1164
1165                        if (filter_id) {
1166                            // Deselect type
1167                            self.form.querySelector(
1168                                '.mls-type[data-id="' + filter_id + '"]'
1169                            ).checked = false;
1170                            self.form
1171                                .querySelector(
1172                                    '.mls-type[data-id="' + filter_id + '"]'
1173                                )
1174                                .closest(".controls")
1175                                .classList.remove("mls-checked", "mls-active");
1176                        }
1177
1178                        self.countFilters();
1179                        self.submitForm();
1180                    });
1181                });
1182
1183                // Close filters dropdown
1184                const mls_fg_close =
1185                    self.form.querySelectorAll(".mls-fg-close");
1186
1187                mls_fg_close.forEach((selector) => {
1188                    selector.addEventListener("click", function (e) {
1189                        e.preventDefault();
1190
1191                        if (!self.keepFiltersOpen)
1192                            self.form
1193                                .querySelectorAll(".mls-filters-group-box")
1194                                .forEach((a) => {
1195                                    a.style.display = "none";
1196                                });
1197
1198                        self.form
1199                            .querySelectorAll(".mls-filters-type .mls-checked")
1200                            .forEach((a) => {
1201                                a.classList.remove("mls-active");
1202                            });
1203                    });
1204                });
1205
1206                // Close filters dropdown on click outside
1207                var filtersContainer =
1208                    self.form.querySelector(".mls-filters-box");
1209
1210                if (
1211                    filtersContainer &&
1212                    (!self.sidebar || !self.keepFiltersOpen)
1213                ) {
1214                    document.addEventListener(
1215                        "mouseup",
1216                        self.closeFilters.bind(self),
1217                        false
1218                    );
1219                    document.addEventListener(
1220                        "touchend",
1221                        self.closeFilters.bind(self),
1222                        false
1223                    );
1224                }
1225
1226                // 'Clear All' button
1227                var clear_maps = self.form.querySelector(".mls-clear-maps");
1228
1229                if (clear_maps) {
1230                    clear_maps.addEventListener("click", function (e) {
1231                        self.form
1232                            .querySelectorAll(".filter-node")
1233                            .forEach((a) => {
1234                                a.checked = false;
1235                            });
1236                        self.form.querySelectorAll(".mls-type").forEach((a) => {
1237                            a.checked = false;
1238                        });
1239                        self.form
1240                            .querySelectorAll(".mls-filters-type .controls")
1241                            .forEach((a) => {
1242                                a.classList.remove("mls-checked", "mls-active");
1243                            });
1244
1245                        if (!self.keepFiltersOpen)
1246                            self.form
1247                                .querySelectorAll(".mls-filters-group-box")
1248                                .forEach((a) => {
1249                                    a.style.display = "none";
1250                                });
1251
1252                        self.countFilters();
1253                        self.submitForm();
1254                    });
1255                }
1256
1257                // Select a node
1258                const filter_node = self.form.querySelectorAll(".filter-node");
1259
1260                if (
1261                    filter_node &&
1262                    self.form.querySelectorAll(".mls-type").length
1263                ) {
1264                    filter_node.forEach((node) => {
1265                        node.addEventListener("click", function (e) {
1266                            var filter_id = node.getAttribute("data-filter");
1267
1268                            // Select type only if sum of all children > 0
1269                            var checked_sum = self.form.querySelectorAll(
1270                                '.filter-node[data-filter="' +
1271                                    filter_id +
1272                                    '"]:checked'
1273                            ).length;
1274
1275                            if (
1276                                self.form.querySelector(
1277                                    '.mls-type[data-id="' + filter_id + '"]'
1278                                )
1279                            ) {
1280                                if (checked_sum > 0) {
1281                                    // Select type
1282                                    self.form.querySelector(
1283                                        '.mls-type[data-id="' + filter_id + '"]'
1284                                    ).checked = true;
1285
1286                                    self.form
1287                                        .querySelector(
1288                                            '.mls-type[data-id="' +
1289                                                filter_id +
1290                                                '"]'
1291                                        )
1292                                        .closest(".controls")
1293                                        .classList.add("mls-checked");
1294
1295                                    if (!self.sidebar || !self.keepFiltersOpen)
1296                                        self.form
1297                                            .querySelector(
1298                                                '.mls-type[data-id="' +
1299                                                    filter_id +
1300                                                    '"]'
1301                                            )
1302                                            .closest(".controls")
1303                                            .classList.add("mls-active");
1304                                } else {
1305                                    // Deselect type
1306                                    self.form.querySelector(
1307                                        '.mls-type[data-id="' + filter_id + '"]'
1308                                    ).checked = false;
1309                                    self.form
1310                                        .querySelector(
1311                                            '.mls-type[data-id="' +
1312                                                filter_id +
1313                                                '"]'
1314                                        )
1315                                        .closest(".controls")
1316                                        .classList.remove("mls-checked");
1317                                }
1318                            }
1319
1320                            self.countFilters();
1321                        });
1322                    });
1323                }
1324            }
1325        }
1326
1327        closeFilters(e) {
1328            const self = this;
1329
1330            if (!e.target.closest(".mls-filters-box")) {
1331                self.form
1332                    .querySelectorAll(".mls-filters-group-box")
1333                    .forEach((a) => {
1334                        a.style.display = "none";
1335                    });
1336                self.form.querySelectorAll(".mls-checked").forEach((a) => {
1337                    a.classList.remove("mls-active");
1338                });
1339            }
1340        }
1341
1342        // Count active filters
1343        countFilters() {
1344            const self = this;
1345
1346            if (self.sidebar) return;
1347
1348            var total_types =
1349                self.form.querySelectorAll(".mls-type:checked").length;
1350            var total_children = self.form.querySelectorAll(
1351                ".mls-filters-group-box:not(.mls-filters-hidden) .filter-node:checked"
1352            ).length;
1353            var total_orphans = self.form.querySelectorAll(
1354                ".mls-orphan-group-box:not(.mls-filters-hidden) .filter-node:checked"
1355            ).length;
1356            var total_filters = total_types + total_children + total_orphans;
1357
1358            if (self.form.querySelector(".mls-filters-count"))
1359                self.form.querySelector(".mls-filters-count").innerHTML =
1360                    total_filters;
1361        }
1362
1363        initDateFilters() {
1364            const self = this;
1365
1366            if (self.form.querySelector(".mls-dates-panel")) {
1367                // 'Clear All' button
1368                var clear_dates = self.form.querySelector(".mls-clear-dates");
1369
1370                if (clear_dates) {
1371                    clear_dates.addEventListener("click", function (e) {
1372                        self.form.querySelector(
1373                            "#filter_date1_" + self.formId
1374                        ).value = "";
1375                        self.form.querySelector(
1376                            "#filter_date2_" + self.formId
1377                        ).value = "";
1378
1379                        self.countFilters();
1380                        self.submitForm();
1381                    });
1382
1383                    const date1 = self.form.querySelector(
1384                        "#filter_date1_" + self.formId
1385                    );
1386
1387                    if (date1)
1388                        date1.addEventListener("change", function () {
1389                            self.submitForm();
1390                        });
1391
1392                    const date2 = self.form.querySelector(
1393                        "#filter_date2_" + self.formId
1394                    );
1395
1396                    if (date2)
1397                        date2.addEventListener("change", function () {
1398                            self.submitForm();
1399                        });
1400                }
1401            }
1402        }
1403
1404        dropdownLayout() {
1405            const self = this;
1406
1407            if (self.form.closest(".mls").classList.contains("mls-dropdown")) {
1408                // Close results on click outside
1409                document.addEventListener(
1410                    "mouseup",
1411                    self.closeDropdownResults.bind(self),
1412                    false
1413                );
1414                document.addEventListener(
1415                    "touchend",
1416                    self.closeDropdownResults.bind(self),
1417                    false
1418                );
1419
1420                // Open results on input
1421                document.addEventListener(
1422                    "mouseup",
1423                    self.openDropdownResults.bind(self),
1424                    false
1425                );
1426                document.addEventListener(
1427                    "touchend",
1428                    self.openDropdownResults.bind(self),
1429                    false
1430                );
1431            }
1432        }
1433
1434        closeDropdownResults(e) {
1435            const self = this;
1436
1437            if (!e.target.closest(".mls-dropdown")) {
1438                self.form.querySelector(
1439                    ".mls-dropdown .mls-results"
1440                ).style.display = "none";
1441            }
1442        }
1443
1444        openDropdownResults(e) {
1445            const self = this;
1446
1447            if (
1448                e.target.closest(".mls-dropdown") &&
1449                e.target.classList.contains("mls-input")
1450            ) {
1451                self.form.querySelector(
1452                    ".mls-dropdown .mls-results"
1453                ).style.display = "block";
1454            }
1455        }
1456
1457        // Click events inside .mls-results
1458        clickEvents() {
1459            const self = this;
1460
1461            self.form
1462                .querySelector(".mls-results")
1463                .addEventListener("click", function (e) {
1464                    // 'Did you mean' link
1465                    if (e.target.classList.contains("suggested-search")) {
1466                        var this_suggestion =
1467                            e.target.getAttribute("data-suggested");
1468                        self.form.querySelector(".mls-input").value =
1469                            this_suggestion;
1470
1471                        if (self.mls_suggest_panel) {
1472                            self.mls_suggest_panel.style.display = "none";
1473
1474                            if (self.mls_popular)
1475                                self.mls_popular.classList.remove("visible");
1476                            if (self.mls_suggestions)
1477                                self.mls_suggestions.classList.remove(
1478                                    "visible"
1479                                );
1480
1481                            self.mls_suggest_panel
1482                                .querySelectorAll("ul li")
1483                                .forEach((a) => {
1484                                    a.classList.remove("selected");
1485                                });
1486                        }
1487
1488                        self.submitForm();
1489                    }
1490
1491                    // Remove search terms
1492                    if (
1493                        e.target &&
1494                        (e.target.classList.contains("mls-remove-term") ||
1495                            e.target.closest(".mls-remove-term"))
1496                    ) {
1497                        if (e.target.classList.contains("mls-remove-term"))
1498                            var _this = e.target;
1499                        else var _this = e.target.parentNode;
1500
1501                        const q = self.form.querySelector(".mls-input");
1502                        var this_term = _this
1503                            .closest(".mls-query-item")
1504                            .querySelector(".mls-term-inner").innerText;
1505
1506                        var orRegex = new RegExp(
1507                            "(?:^|\\s)" +
1508                                self.orOperator +
1509                                '\\s["]?' +
1510                                this_term +
1511                                '["]?($|\\s)',
1512                            "gi"
1513                        );
1514                        var andRegex = new RegExp(
1515                            "(?:^|\\s)" +
1516                                self.andOperator +
1517                                '\\s["]?' +
1518                                this_term +
1519                                '["]?($|\\s)',
1520                            "gi"
1521                        );
1522                        var notRegex = new RegExp(
1523                            "(?:^|\\s)" +
1524                                self.notOperator +
1525                                '\\s["]?' +
1526                                this_term +
1527                                '["]?($|\\s)',
1528                            "gi"
1529                        );
1530                        var simpleRegex = new RegExp(
1531                            '(?:^|\\s)["]?' + this_term + '["]?($|\\s)',
1532                            "gi"
1533                        );
1534
1535                        // Remove term
1536                        _this.closest(".mls-query-item").remove();
1537                        q.value = q.value.replace(orRegex, " ");
1538                        q.value = q.value.replace(andRegex, " ");
1539                        q.value = q.value.replace(notRegex, " ");
1540                        q.value = q.value.replace(simpleRegex, " ");
1541
1542                        if (self.mls_suggestions) {
1543                            self.mls_suggestions.classList.remove("visible");
1544                            self.mls_suggest_panel
1545                                .querySelectorAll("ul li")
1546                                .forEach((a) => {
1547                                    a.classList.remove("selected");
1548                                });
1549                        }
1550
1551                        // Trim trailing operators
1552                        var q_value = q.value;
1553                        q_value = q_value.trim();
1554                        var splitQ = q_value.split(" ");
1555                        var firstElement = splitQ[0];
1556
1557                        if (
1558                            firstElement === self.orOperator ||
1559                            firstElement === self.andOperator ||
1560                            firstElement === self.notOperator
1561                        )
1562                            q_value = q_value.substring(
1563                                q_value.indexOf(" ") + 1
1564                            );
1565
1566                        q.value = q_value;
1567
1568                        if (typeof self.mls_ajax_request !== "undefined")
1569                            self.mls_ajax_request.abort();
1570
1571                        if (q_value) self.submitForm();
1572                        else self.clearInput();
1573                    }
1574
1575                    // Remove date filters
1576                    if (
1577                        e.target.classList.contains("mls-remove-date1") ||
1578                        e.target.closest(".mls-remove-date1")
1579                    ) {
1580                        e.preventDefault();
1581                        self.form.querySelector(
1582                            "#filter_date1_" + self.formId
1583                        ).value = "";
1584                        self.submitForm();
1585                    }
1586
1587                    if (
1588                        e.target.classList.contains("mls-remove-date2") ||
1589                        e.target.closest(".mls-remove-date2")
1590                    ) {
1591                        e.preventDefault();
1592                        self.form.querySelector(
1593                            "#filter_date2_" + self.formId
1594                        ).value = "";
1595                        self.submitForm();
1596                    }
1597
1598                    // Remove map filters
1599                    if (
1600                        e.target.classList.contains("mls-remove-map") ||
1601                        e.target.closest(".mls-remove-map")
1602                    ) {
1603                        e.preventDefault();
1604
1605                        if (e.target.classList.contains("mls-remove-map"))
1606                            var _this = e.target;
1607                        else var _this = e.target.parentNode;
1608
1609                        var filter_id = _this.getAttribute("data-filter");
1610                        var node_id = _this.getAttribute("data-node");
1611
1612                        // It's a child item
1613                        if (node_id) {
1614                            var checked_sum = self.form.querySelectorAll(
1615                                '.filter-node[data-filter="filter-' +
1616                                    filter_id +
1617                                    '"]:checked'
1618                            ).length;
1619
1620                            // Remove parent only if sum of children == 1
1621                            if (
1622                                checked_sum === 1 &&
1623                                self.form.querySelectorAll(".mls-type").length
1624                            ) {
1625                                // Deselect parent
1626                                self.form.querySelector(
1627                                    '.mls-type[data-id="filter-' +
1628                                        filter_id +
1629                                        '"]'
1630                                ).checked = false;
1631                                self.form
1632                                    .querySelector(
1633                                        '.mls-type[data-id="filter-' +
1634                                            filter_id +
1635                                            '"]'
1636                                    )
1637                                    .closest(".controls")
1638                                    .classList.remove(
1639                                        "mls-checked",
1640                                        "mls-active"
1641                                    );
1642
1643                                if (!self.keepFiltersOpen)
1644                                    self.form
1645                                        .querySelectorAll(
1646                                            ".mls-filters-group-box"
1647                                        )
1648                                        .forEach((a) => {
1649                                            a.style.display = "none";
1650                                        });
1651                            }
1652
1653                            // Deselect this node
1654                            self.form.querySelector(
1655                                '.filter-node[value="' +
1656                                    node_id +
1657                                    '"][data-filter="filter-' +
1658                                    filter_id +
1659                                    '"]'
1660                            ).checked = false;
1661                        }
1662                        // It's a parent item
1663                        else {
1664                            // Remove all children
1665                            self.form
1666                                .querySelectorAll(
1667                                    '.mls-query-item[data-filter="filter-' +
1668                                        filter_id +
1669                                        '"]'
1670                                )
1671                                .forEach((a) => {
1672                                    a.remove();
1673                                });
1674
1675                            // Deselect children nodes
1676                            self.form
1677                                .querySelectorAll(
1678                                    '.filter-node[data-filter="filter-' +
1679                                        filter_id +
1680                                        '"]'
1681                                )
1682                                .forEach((a) => {
1683                                    a.checked = false;
1684                                });
1685
1686                            if (!self.keepFiltersOpen)
1687                                self.form
1688                                    .querySelectorAll(".mls-filters-group-box")
1689                                    .forEach((a) => {
1690                                        a.style.display = "none";
1691                                    });
1692
1693                            // Deselect parent
1694                            self.form.querySelector(
1695                                '.mls-type[data-id="filter-' + filter_id + '"]'
1696                            ).checked = false;
1697
1698                            self.form
1699                                .querySelector(
1700                                    '.mls-type[data-id="filter-' +
1701                                        filter_id +
1702                                        '"]'
1703                                )
1704                                .closest(".controls")
1705                                .classList.remove("mls-checked", "mls-active");
1706
1707                            if (!self.keepFiltersOpen)
1708                                self.form
1709                                    .querySelectorAll(".mls-filters-group-box")
1710                                    .forEach((a) => {
1711                                        a.style.display = "none";
1712                                    });
1713                        }
1714
1715                        _this.closest(".mls-query-item").remove();
1716                        self.countFilters();
1717                        self.submitForm();
1718                    }
1719
1720                    // Pagination links
1721                    if (
1722                        e.target.classList.contains("mls-page-link") ||
1723                        e.target.closest(".mls-page-link")
1724                    ) {
1725                        e.preventDefault();
1726
1727                        if (e.target.classList.contains("mls-page-link"))
1728                            var _this = e.target;
1729                        else var _this = e.target.closest("li");
1730
1731                        if (_this.classList.contains("disabled")) return;
1732
1733                        var link_href = _this
1734                            .querySelector("a")
1735                            .getAttribute("href");
1736                        self.submitPage(link_href);
1737                    }
1738                });
1739        }
1740    }
1741
1742    window.MinitekLiveSearch = {
1743        initialise: (params, formId, searchUrl, autosuggestUrl) =>
1744            new MinitekLiveSearch(params, formId, searchUrl, autosuggestUrl),
1745    };
1746})(document, Joomla);

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