PageSourceSearch

https://www.premiercottages.co.uk/js/ph3/premier.js?version=26.09.23.1

js premiercottages.co.uk collected 2026-10-04 02:16:53 UTC 27,605 bytes, 709 lines download raw bytes

1//Register Spark as a namespace if has not been defined before
2if (typeof (PC) === 'undefined') {
3    PC = [];
4};
5
6//Add Search to the Spark namespace
7PC.TypeAhead = PC.TypeAhead || {};
8PC.WebService = PC.WebService || {};
9PC.Cottage = PC.Cottage || {};
10
11/**********************************
12 *   Dependencies: JQuery
13 *               : EasyAutoComplete v1.3.3 + 
14 *
15 *   Search functionality
16 *   
17 **********************************/
18PC.TypeAhead = function () {
19    var self = this;
20
21
22    /**********************
23    *   @description Initalises the search lookahead
24    *   @param {string} lookaheadID the lookaheadID 
25    *   @param {string} hidRegionID the regionID 
26    *   
27    ****************/
28    self.SetupLookahead = function (lookaheadID, hidRegionID) {
29
30
31        //get auto complete options from webservice
32        var autoCompleteOptions = {
33            url: function (query) {
34                if (query !== "") {
35                    return "/webservice/searchService.svc/lookAhead?query=" + query
36                }
37            },
38            ajaxSettings: {
39                method: "GET",
40            },
41            list: {
42                //SR: 08/02/2017 - Remove hover over on typeahead 
43                //onMouseOverEvent: function () {
44                //    //Set the mouse over destination into the text box / hidden field
45                //    var destination = $(lookaheadID).getSelectedItemData();
46                //    searchCriteria.destinationId(destination.DestinationID);
47                //    $(lookaheadID).val(destination.Destination)
48                //},
49                onChooseEvent: function () {
50                    //On choose event (enter / mouse click) set the destinationID / hidden field
51                    var destination = $(lookaheadID).getSelectedItemData();
52                    $(hidRegionID).val(destination.DestinationID);
53                    $(".ui-menu-item").hide();
54                },
55                onClickEvent: function () {
56                    //On choose event (enter / mouse click) set the destinationID / hidden field
57                    var destination = $(lookaheadID).getSelectedItemData();
58                    $(hidRegionID).val(destination.DestinationID);
59                    $(".ui-menu-item").hide();
60                }
61                , maxNumberOfElements: 10
62                , match: {
63                    enabled: false
64                }
65            },
66            getValue: "Destination",
67            requestDelay: 750,
68            theme: "square"
69        };
70
71        $(lookaheadID).easyAutocomplete(autoCompleteOptions)
72            //On blur event get the selectedItem ID and place into the search criteria       
73            .blur(function () {
74                var destination = $(lookaheadID).getSelectedItemData();
75                $(hidRegionID).val(destination.DestinationID);
76                $(".ui-menu-item").hide();
77            }
78            );
79
80        SparkBase.General.Console.Log("PC.TypeAhead.SetupLookahead()");
81    };
82
83    return {
84        SetupLookahead: self.SetupLookahead, //Configure the look ahead       
85    }
86}();
87
88
89/**
90* @description  Common interface to webservice features   
91*/
92PC.WebService = function () {
93    var self = this;
94
95    /**********************
96    *   @description Submit a newsletter subscription to Server & Liquid Mail
97    *   @param {string} email email address
98    *   @param {string} forename  comments
99    *   @param {boolean} surname is newsletter checked
100    *   @param {boolean} subscribeMarketing is other marketing checked
101    *   @param {function} callbackFunction the call back function 
102    */
103    self.SubmitNewsletter = function (email, forename, surname, subscribeMarketing, iPAddress, callbackFunction) {
104        SparkBase.General.Console.Log('PC.WebService.SubmitNewsletter()');
105        $.getJSON('/webservice/general.svc/subscribeNewsletter?emailAddress=' + email + '&forename=' + forename + '&surname=' + surname + '&subscribeMarketing=' + subscribeMarketing + '&iPAddress=' + iPAddress)
106            .success(function (data) {
107                SparkBase.General.Console.Log("Newsletter submitted");
108                callbackFunction(data);
109            }
110            );
111
112    };
113
114    /** 
115    *   @description  Submit a feedback to Server & Liquid Mail
116    *   @param {string} captureMethodID where the information has been captured from 
117    *   @param {string} email email address 
118    *   @param {string} comment  comments 
119    *   @param {boolean} chkNewsLetter is newsletter checked 
120    *   @param {boolean}
120 chkOtherMarketing is other marketing checked
121    *   @param {function} callbackFunction the call back function 
122    */
123    self.SubmitFeedback = function (captureMethodID, email, comment, chkNewsLetter, chkOtherMarketing, callbackFunction) {
124        SparkBase.General.Console.Log('PC.WebService.SubmitFeedback()');
125        //AS of 17/11/2016 - We need to include the capture method as we have extended for contact requests
126        $.getJSON('/webservice/general.svc/SubmitFeedback?captureMethodID=' + captureMethodID + '&emailAddress=' + email + '&comments=' + comment + '&newsletter=' + chkNewsLetter + '&allowMarketing=' + chkOtherMarketing)
127            .success(function (data) {
128                SparkBase.General.Console.Log("Feedback submitted");
129                callbackFunction(data);
130            }
131            );
132
133    };
134
135
136    /** 
137*   @description  Share a compare list with a friend
138*   @param {string} nameTo where the information has been captured from
139*   @param {string}  emailTo address
140*   @param {string} comment  comments 
141*   @param {function} callbackFunction the call back function 
142*/
143    self.ShareCompareList = function (nameTo, emailTo, comment, callbackFunction) {
144        SparkBase.General.Console.Log('PC.WebService.ShareCompareList()');
145        $.getJSON('/webservice/general.svc/ShareCompareList?nameTo=' + nameTo + '&emailAddress=' + emailTo + '&comments=' + comment)
146            .success(function (data) {
147                SparkBase.General.Console.Log("Compare List shared");
148                callbackFunction(data);
149            }
150            );
151
152    };
153
154    /**
155    *   @description Do a search for cottages
156    *   @param {string} searchCriteraString search string
157    *   @param {function} callBackFunction success function 
158    *   @param {function} errFunction function to handle any errors 
159    */
160    self.Search = function (searchCriteraString, callBackFunction, errFunction) {
161        SparkBase.General.Console.Log("Calling Search: " + searchCriteraString);
162        $.getJSON("/webservice/searchservice.svc/Search?" + searchCriteraString + "&cacheBuster=" + Math.random())
163            .done(function (data) {
164                SparkBase.General.Console.Log("Cottage Search: Success");
165                if (typeof callBackFunction === 'function') {
166                    callBackFunction(data);
167                }
168            })
169            .fail(function (err) {
170                SparkBase.General.Console.Log("Cottage Search: Failed");
171                if (typeof errFunction === 'function') {
172                    errFunction(err);
173                }
174            });
175    };
176
177
178    /**
179    *   @description Do a search for cottages with an extended date ranage 
180    *   @param {string} searchCriteraString search string
181    *   @param {function} callBackFunction success function 
182    *   @param {function} errFunction function to handle any errors 
183    */
184    self.GetExtendedResults = function (searchCriteraString, callBackFunction, errFunction) {
185        SparkBase.General.Console.Log("Calling GetExtendedResults: " + searchCriteraString);
186        $.getJSON("/webservice/searchservice.svc/GetExtendedResults?" + searchCriteraString + "&cacheBuster=" + Math.random())
187            .done(function (data) {
188                SparkBase.General.Console.Log("Cottage Search Extended Results: Success");
189                if (typeof callBackFunction === 'function') {
190                    callBackFunction(data);
191                }
192            })
193            .fail(function (err) {
194                SparkBase.General.Console.Log("Cottage Search: Failed");
195                if (typeof errFunction === 'function') {
196                    errFunction(err);
197                }
198            });
199    };
200
201    /**
202    *   @description  Do a search for special offers
203    *   @param {string} searchCriteraString search string
204    *   @param {number} lastMinuteOfferPeriodId the offer period id
205    *   @param {function} callBackFunction success function
206    *   @param {function} errFunction function to handle any errors
207    */
208    self.SpecialOffers = function (searchCriteraString, lastMinuteOfferPeriodId, callBackFunction, errFunction) {
209
210        SparkBase.General.Console.Log("Calling Special Offers: /webservice/searchservice.svc/SpecialOffers?" + searchCriteraString + "&lastMinuteOfferPeriodId=" + lastMinuteOfferPeriodId + "&cacheBuster=" + Math.random());
211        $.getJSON("/webservice/searchservice.svc/SpecialOffers?" + searchCriteraString + "&lastMinuteOfferPeriodId=" + lastMinuteOfferPeriodId + "&cacheBuster=" + Math.random())
212            .done(function (data) {
213                SparkBase.General.Console.Log("Cottage Search: Success");
214                if (typeof callBackFunction === 'function') {
215                    callBackFunction(data);
216                }
217            })
218            .fail(function (err) {
219                SparkBase.General.Console.Log("Cottage Search: Failed");
220                if (typeof errFunction === 'function') {
221                    errFunction(err);
222                }
223            });
224    };
225
226    /**
227    *   @description  Do a search for special offers
228    *   @param {string} searchCriteraString search string
229    *   @param {function} callBackFunction success function
230    *   @param {function} errFunction function to handle any errors
231    */
232    self.LateDeals = function (searchCriteraString, callBackFunction, errFunction) {
233
234        SparkBase.General.Console.Log("Calling Special Offers: /webservice/searchservice.svc/LateDeals?" + searchCriteraString + "&cacheBuster=" + Math.random());
235        $.getJSON("/webservice/searchservice.svc/LateDeals?" + searchCriteraString + "&cacheBuster=" + Math.random())
236            .done(function (data) {
237                SparkBase.General.Console.Log("Cottage Search: Success");
238                if (typeof callBackFunction === 'function') {
239                    callBackFunction(data);
240                }
241            })
242            .fail(function (err) {
243                SparkBase.General.Console.Log("Cottage Search: Failed");
244                if (typeof errFunction === 'function') {
245                    errFunction(err);
246                }
247            });
248    };
249
250    /**
251    *   @description toggle the cottageID favourite status in the comparelist 
252    *   @param {number} cottageID cottageid
253    *   @param {boolean} include to include to favourites
254    *   @param {function} callBackFunction - function to carry out on success 
255    *   @param {function} errFunction - function to carry out on an error 
256    */
257    self.ToggleFavourites = function (cottageID, include, callBackFunction, errFunction) {
258        var includeToString = include ? 'True' : 'False';
259        var url = '/webservice/cottageService.svc/AddToShortlist?cottageId=' + cottageID + '&include=' + includeToString;
260        $.get(url)
261            .done(function () {
262                if (typeof callBackFunction === 'function') {
263                    callBackFunction();
264                };
265            })
266            .fail(function (err) {
267                //Log error!
268                var txt;
269                include ? txt = 'Add' : txt = 'Remove';
270                SparkBase.General.Console.Log("Could not " + txt + "  Cottage from favourites,  Cottage:" + cottageID);
271
272                if (typeof errFunction === 'function') {
273                    errFunction(err);
274                }
275            });
276    };
277
278
279    self.PushFeatures = function () {
280        if (typeof PC.PageNameID !== 'undefined') {
281
282            $.getJSON("/webservice/general.svc/LastSearchQuery?PageNameID=" + PC.PageNameID + "&Features=" + escape(SparkBase.General.URL.GetHashValue("selectedFeatures", "")))
283                .done(function (data) {
284                    SparkBase.General.Console.Log("Cottage Search: Success");
285                    if (typeof callBackFunction === 'function') {
286                        callBackFunction(data);
287                    }
288                });
289        }
290    };
291
292
293    /**
294    *   @description  Do a search for special offers
295    *   @param {string} searchCriteraString search string
296    *   @param {number}
296 vipOfferId the offer period id
297    *   @param {function} callBackFunction success function
298    *   @param {function} errFunction function to handle any errors
299    */
300    self.VIPOffer = function (searchCriteraString, vipOfferId, callBackFunction, errFunction) {
301
302        SparkBase.General.Console.Log("Calling Special Offers: /webservice/searchservice.svc/VIPOffers?" + searchCriteraString + "&VIPOfferId=" + vipOfferId + "&cacheBuster=" + Math.random());
303        $.getJSON("/webservice/searchservice.svc/VIPOffers?" + searchCriteraString + "&vipOfferId=" + vipOfferId + "&cacheBuster=" + Math.random())
304            .done(function (data) {
305                SparkBase.General.Console.Log("Cottage Search: Success");
306                if (typeof callBackFunction === 'function') {
307                    callBackFunction(data);
308                }
309            })
310            .fail(function (err) {
311                SparkBase.General.Console.Log("Cottage Search: Failed");
312                if (typeof errFunction === 'function') {
313                    errFunction(err);
314                }
315            });
316    };
317
318    self.MyFavourites = function MyFavourites(queryString, callBackFunction, errFunction) {
319        SparkBase.General.Console.Log("Calling /webservice/searchService.svc/ListCompareList?queryString=" + queryString);
320
321        $.getJSON("/webservice/searchService.svc/ListCompareList?queryString=" + queryString + "&cacheBuster=" + Math.random())
322            .done(function (data) {
323                SparkBase.General.Console.Log("Cottage Search: Success");
324                if (typeof callBackFunction === 'function') {
325                    callBackFunction(data);
326                }
327            })
328            .fail(function (err) {
329                SparkBase.General.Console.Log("Cottage Search: Failed");
330                if (typeof errFunction === 'function') {
331                    errFunction(err);
332                }
333            });
334    };
335
336    return {
337        SubmitNewsletter: self.SubmitNewsletter, /* Submit the newsletter to WebService */
338        SubmitFeedback: self.SubmitFeedback,     /* Submit the newsletter to WebService */
339        ShareCompareList: self.ShareCompareList, /* Share Compare List via WebService */
340        Search: self.Search,                /* General purpose search */
341        SpecialOffers: self.SpecialOffers,
342        LateDeals: self.LateDeals,
343        ToggleFavourites: self.ToggleFavourites,  /* Toggle favourites webservice call */
344        PushFeatures: self.PushFeatures,
345        GetExtendedResults: self.GetExtendedResults, /** get extended results **/
346        VIPOffer: self.VIPOffer, /* Get the VIP Club webservice */
347        MyFavourites: self.MyFavourites /* Get the my favourites webservice */
348    };
349}();
350
351
352/**
353*   @description Class for holding site wide cottage functionality 
354*/
355PC.Cottage = PC.Cottage || {};
356PC.Cottage.Favourite = (function Favourite() {
357    var Me = this;
358    Me.listener = undefined;
359
360    /******
361    *   @description Notify Premier Cottages that a cottage has been added to favourites 
362    *   @param {object} hyperLinkElement the hyperlink
363    */
364    Me.AddCottageToFavourites = function (hyperLinkElement) {
365        var cottageID = $(hyperLinkElement).data('cottageid');
366
367        Me.SetAddedToFavourite(hyperLinkElement);
368
369        PC.WebService.ToggleFavourites(cottageID, true,
370            function Success() {
371
372                var cottageID = $(hyperLinkElement).data('cottageid');
373                var cottageGroupID = $(hyperLinkElement).data('cottagegroupid');
374                var cottagegroup = $(hyperLinkElement).data('cottagegroupname');
375
376                /* track event in google */
377                if ((typeof cottageGroupID !== 'undefined') && (typeof cottageGroupID !== 'undefined')) {
378                    SparkBase.Google.Track.CompareList(cottageGroupID, cottagegroup, cottageID);
379                };
380            },
381            function Error() {
382                Me.RemoveFromFavourite(hyperLinkElement);
383            });
384    };
385
386
387    Me.SetAddedToFavourite = function (hyperLinkElement) {
388
389        var text = "Remove from favourites";
390
391        $('[data-buttontype="favourite"]').each(function () {
392            var $element = $(this);
393
394            if ($element.hasClass('active') == false) {
395
396                $element.addClass('active'); 
397                $element.find('span').text(text);
398                $element.attr('title', text);
399            }
400        });
401
402        var $icon = $('[data-icontype="favouriteMobileIcon"]');
403        $icon.removeClass("fa-heart-o");
404        $icon.addClass("fa-heart");
405    }
406
407    Me.RemoveFromFavourite = function (hyperLinkElement) {
408
409        var text = "Add to favourites";
410
411        $('[data-buttontype="favourite"]').each(function () {
412            var $element = $(this);
413
414            if ($element.hasClass('active') == true) {
415                $element.removeClass('active'); 
416
417                $element.find('span').text(text);
418                $element.attr('title', text);
419            }
420        });
421
422
423        var $icon = $('[data-icontype="favouriteMobileIcon"]');
424        $icon.removeClass("fa-heart");
425        $icon.addClass("fa-heart-o");
426    }
427
428
429    /******
430    *   @description Notify Premier Cottages that a cottage has been removed from favourites 
431    *   @param {string} hyperLinkElement the hyperlink
432    */
433    Me.RemoveCottageFromFavourites = function (hyperLinkElement) {
434        var cottageID = $(hyperLinkElement).data('cottageid');
435
436
437        Me.RemoveFromFavourite(hyperLinkElement);
438
439        PC.WebService.ToggleFavourites(cottageID, false, function Success() {
440        }, function Error() {
441            Me.SetAddedToFavourite(hyperLinkElement);
442        });
443    }; 
444 
445
446    /******
447    *   @description Toggles the cottage to and from a fravouite 
448    *   @param {object} hyperLinkElement hyperlink 
449    */
450    Me.ToggleFavourite = function (hyperLinkElement) {
451
452        if ($(hyperLinkElement).hasClass('active')) {
453            Me.RemoveCottageFromFavourites(hyperLinkElement);
454        } else {
455            Me.AddCottageToFavourites(hyperLinkElement);
456        };
457    };
458
459    Me.ToggleFavouriteCottagePageMobile = function (hyperLinkElement) {
460
461        /* classes will be toggled */
462        Me.ToggleFavourite(hyperLinkElement);
463
464        /* mobile heart */
465    }
466
467
468
469    /******
470    *   @description called when a cottageID is added or removed from favourites
471    *   @param {function} listener function(cottageID, event)
472    */
473    Me.Addlistener = function (listener) {
474        Me.listener = listener;
475    };
476
477    return {
478        ToggleFavourite: Me.ToggleFavourite,
479        Addlistener: Me.Addlistener,
480        ToggleFavouriteCottagePageMobile: ToggleFavouriteCottagePageMobile
481    };
482})();
483
484
485/**
486*   @description Class for holding search citeria 
487*/
488PC.Search = function () {
489    var self = this;
490
491    /**
492    *   @description Search Criteria Class 
493    */
494    self.SearchCriteria = function () {
495        /***
496        *   @description find the data-searchFields and get their values & return as an url 
497        *   @param {object} searchCriteria the search criteria being passed in 
498        *   @returns {string}
498 the search criteria as a stirng
499        */
500        function GetSearchString(searchCriteria) {
501            var outStr = "";
502
503            /** If we have had the search criteria passed in then use that object else generate another **/
504            searchCriteria = searchCriteria || GetSearchCriteria();
505
506            outStr = SearchCriteriaToURL(searchCriteria);
507
508            /** return the search citeria **/
509            return outStr;
510        };
511
512        /***
513        *   @description Convert the search Criteria to a url string
514        *   @param {object}  searchCriteria  searchCriteria
515        *   @return {string}    search URL
516        */
517        function SearchCriteriaToURL(searchCriteria) {
518            var outStr = '';
519
520            if (typeof searchCriteria !== 'undefined') {
521                /** loop though the search criteria and get the values if they are declared if not leave as the default - ie blank or 0 **/
522                for (prop in searchCriteria) {
523
524                    if (prop == 'guests' || prop == 'bedrooms') {
525                        var val = searchCriteria[prop];
526                        val.replace(prop + "-", "");
527
528                        if (val.toLowerCase() == 'any') {
529                            val = '';
530                        }
531                        outStr += "&" + prop + "=" + val;
532
533                    } else if (prop == 'selectedNights') {
534                        var val = searchCriteria[prop];
535                        val = val.replace("date-nights-", "");
536                        outStr += "&" + prop + "=" + val;
537
538                    } else if (prop == 'datesFlexible') {
539                        var val = searchCriteria[prop];
540
541                        if (val.toLowerCase() == 'true') {
542                            outStr += "&" + prop + "=" + 1;
543                        } else {
544                            outStr += "&" + prop + "=" + 0;
545                        }
546                    }
547
548                    else {
549                        outStr += "&" + prop + "=" + searchCriteria[prop];
550                    }
551
552
553                };
554            };
555
556            /** remove the initial &... **/
557            outStr = outStr.substr(1, outStr.length - 1);
558
559            return outStr;
560        };
561
562        /**
563        *   @description returns a search 
564        *   @returns {string} the search criteria 
565        */
566        function GetSearchCriteria() {
567            var searchCriteria = SearchCriteria();
568
569            for (prop in searchCriteria) {
570                if (prop.toLowerCase() == 'selectedFeatures'.toLowerCase()) {
571                    searchCriteria[prop] = SparkBase.General.URL.GetHashValue('selectedFeatures', '');
572                } else {
573                    var val = $('[data-searchfield="' + prop + '"]').val();
574
575                    if (typeof val !== 'undefined') {
576
577
578                        val = val.replace(prop + "-", '');
579
580                        if (val.toLowerCase() == "any") {
581                            val = 0;
582                        }
583
584                        searchCriteria[prop] = escape(val);
585                    } else {
586                        /** if undefined and extend results then set it to be false always **/
587                        if (prop == 'extendResults') {
588                            searchCriteria[prop] = 'false';
589                        }
590                    };
591                };
592            };
593
594            return searchCriteria;
595        };
596
597
598        /**
599        *   @description get search criteria JSON object 
600        *   @returns {object} Search criteria object
601        */
602        function SearchCriteria() {
603            return {
604                destinationId: 0,
605                destination: '',
606                dateFrom: '',
607                selectedNights: 0,
608                datesFlexible: 0,
609                collectionId: 0,
610                guests: 0,
611                bedrooms: 0,
612                selectedFeatures: '',
613                extendResults: 'false'
614            };
615        };
616
617        /**
618        *   @description  set the search fields from the URL 
619        */
620        function SetFromURL() {
621            var searchCriteria = SparkBase.General.URL.GetHashAsObject();
622
623            for (var i = 0, len = searchCriteria.length; i < len; i++) {
624                if (searchCriteria[i].name.toLowerCase() == 'destination'.toLowerCase()) {
625                    var val = unescape(searchCriteria[i].value)
626                    $('[data-searchfield="' + searchCriteria[i].name + '"]').val(val);
627                } else {
628                    $('[data-searchfield="' + searchCriteria[i].name + '"]').val(searchCriteria[i].value);
629                }
630            };
631        }
632
633
634        return {
635            GetSearchCriteria: GetSearchCriteria,
636            GetSearchString: GetSearchString,
637            SearchCriteria: SearchCriteria,
638            SearchCriteriaToURL: SearchCriteriaToURL,
639            SetFromURL: SetFromURL
640        }
641    }();
642
643
644    return {
645        SearchCriteria: self.SearchCriteria
646    }
647}()
648
649
650/** 
651*   @description Publisher / Subscriber for page objects 
652*/
653PC.Events = (function () {
654    var event = {};
655    var hop = event.hasOwnProperty;
656
657    return {
658        /**
659        * @description give a list of event 
660        * @returns {object} an event
661        */
662        List: function List() {
663            return event;
664        },
665
666        /**
667        *   @description Allow object to to subscribe to an event
668        *   @param {string} topic the topic the function is listening for 
669        *   @param {function} listener the function to be called when the topic is called
670        *   @returns {object} JSON with the delete event
671        */
672        Subscribe: function Subscribe(topic, listener) {
673            /* Create the topic's object if not yet created */
674            if (!hop.call(event, topic)) {
675                event[topic] = [];
676            }
677
678            /* Add the listener to queue */
679            var index = event[topic].push(listener) - 1;
680
681            /*  Provide handle back for removal of topic */
682            return {
683                Remove: function () {
684                    delete event[topic][index];
685                }
686            };
687        },
688
689        /**
690        *   @description notifi the listeners that there has been an event
691        *   @param {string} topic the name of the event being executed
692        *   @param {object} info any informtion that is being published 
693        */
694        Publish: function Publish(topic, info) {
695            //  SparkBase.General.Console.Log("Event.Publish Called  Topic: " + topic + " :Info: " + info);
696            SparkBase.General.Console.Log("Event:" + topic);
697            /*  If the topic doesn't exist, or there's no listeners in queue, just leave */
698            if (!hop.call(event, topic)) return;
699
700            /*  Cycle through event queue, fire! */
701            event[topic].forEach(function (item) {
702                /* Only try to call it if its a function... */
703                if (typeof item === 'function') {
704                    item(info != undefined ? info : {});
705                }
706            });
707        }
708    };
709})();

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.