PageSourceSearch

https://sdrproperties.com/Widgets/PropertySearch/PropertySearch.js…FX8ylIFuUjT04g4ebgAsGFAWmbRp0Kj3nNmf53A7tx0

js sdrproperties.com collected 2026-09-29 21:46:56 UTC 25,913 bytes, 608 lines download raw bytes

1Widgets.PropertySearch = function (txtSearch, btnSearch, options = null) {
2    this.className = "defaultPropertySearchContainer";
3
4    Widgets.BaseWidget.call(this, "/Widgets/PropertySearch/PropertySearch", this.className);
5
6    //custom overriding options
7    BaseHelper.MergeIntoObject(this, options);
8
9    this._setup = function () {
10        this.requestQueue = BaseHelper.createRequestQueue();
11        this.changeID = 0;
12        this.txtSearch = txtSearch;
13        this.btnSearch = btnSearch;
14        this.searchView = null;
15        let loadingStyle = "width:100px;";
16
17        this.loadingListing = {
18            img: BaseHelper.getLoadingImg(loadingStyle),
19            data: false
20        };
21        this.loadingCityStateZip = {
22            img: BaseHelper.getLoadingImg(loadingStyle),
23            data: false
24        };
25
26        txtSearch.addEventListener("input", (e) => { this.onReady(this.onChange) });
27        btnSearch.addEventListener("click", (e) => { this.onReady(this.onSearch) });
28        Widgets.BaseWidget.prototype._setup.call(this);
29    };
30
31
32    this.getLoadData = async function () {
33        let result = Widgets.BaseWidget.prototype.getLoadData.call(this);
34        return result;
35    };
36
37    this.onPropertySearchItemClickCallback = async (filterArr, searchText) => {
38        let filter = {
39            searchText: searchText
40            //,SortResult: "newest"
41        }
42        filterArr.forEach((f) => {
43            filter[f.name] = f.value
44        });
45        if (this.searchView != null) {
46            filter["SearchView"] = this.searchView;
47        }
48        let encodedFilter = BaseHelper.EncodeObjectToHtmlData(filter);
49        //BaseHelper.MakeAJAXPostJSONRequest("/api/Listing/PreloadListings", filter);
50        window.location = "/search-results?" + encodedFilter;
51    };
52
53    this.onPropertySearchItemArrClickCallback = async (filterObjArr, searchText) => {
54        if (filterObjArr.length == 1) {
55            this.onPropertySearchItemClickCallback(filterObjArr[0], searchText);
56            return;
57        }
58        let filter = {
59            searchText: searchText
60            //,SortResult: "newest"
61        };
62        let filters = [];
63        filterObjArr.forEach((filterArr) => {
64            let subFilter = {};
65            filterArr.forEach((f) => {
66                subFilter[f.name] = f.value
67            });
68            filters.push(subFilter)
69        });
70
71        if (filterObjArr.length > 1) {
72            let filterObj = filterObjArr[0];
73            filterObj.forEach((f) => {
74                if (f.name == "City") {
75                    filter.City = f.value;
76                }
77                else if (f.name == "State") {
78                    filter.State = f.value;
79                }
80            });
81        }
82        filter.filters = JSON.stringify(filters);
83        if (this.searchView != null) {
84            filter["SearchView"] = this.searchView;
85        }
86        let encodedFilter = BaseHelper.EncodeObjectToHtmlData(filter);
87        BaseHelper.MakeAJAXPostJSONRequest("/api/Listing/PreloadListings", filter);
88        window.location = "/search-results?" + encodedFilter;
89    };
90
91
92    this.onSearch = async (e) => {
93        //if search button is clicked act as if the user clicked on the first row.
94        //if theres no events that should happen if rows are clicked, then the search should also not know wtf to do.
95        if (this.onPropertySearchItemClickCallback == null || this.currentData == null) {
96            return;
97        }
98        let data = this.currentData;
99        let dtAddress = data.dtAddress;
100        let dtZip = data.dtZip;
101        let dtCity = data.dtCity;
102        let dtState = data.dtState;
103
104        //address is always above zip
105        if (dtAddress != null && dtAddress.length > 0) {
106            this.GotoAddress(dtAddress[0]);
107            return;
108        }
109        if (dtZip != null && dtZip.length > 0) {
110            this.onPropertySearchItemClickCallback(this.getAddressFilter(dtZip[0]), dtZip[0].ZipCityState);
111            return;
112        }
113        //city is always above state
114        if (dtCity != null && dtCity.length > 0) {
115            this.onPropertySearchItemClickCallback(this.getAddressFilter(dtCity[0]), dtZip[0].CityState);
116            return;
117        }
118        if (dtState != null && dtState.length > 0) {
119            this.onPropertySearchItemClickCallback(this.getAddressFilter(dtState[0]), dtZip.State);
120            return;
121        }
122    };
123
124    this.createPsDisplayItem = function (type, index, value) {
125        let psItem = document.createElement("div");
126        psItem.classList.add("PropertySearchItem");
127        psItem.setAttribute("data-type", type);
128        psItem.setAttribute("data-index", index);
129        psItem.innerText = value;
130        return psItem;
131    };
132
133
134    this.onChange = async (e) => {
135        let currentChangeID = ++this.changeID;
136        window.setTimeout(async () => {
137            if (currentChangeID == this.changeID) {
138                //console.log("finished typing");
139                await this.refresh(currentChangeID);
140            }
141            else {
142                //console.log("typing..");
143            }
144        }, 250);
145    };
146
147    this.retrieveAndPopulateListingData = async (cID, searchValue) => {
148        if (searchValue == null || searchValue.trim().length == 0) {
149            return;
150        }
151
152        this.toggleDataLoad(true, this.psAddressContainer, this.psAddressItemContainer, this.loadingListing);
153        if (cID == this.changeID) {
154            this.psAddressContainer.style.display = "block";
155        }
156        let trimmedSearch = searchValue.trim();
157        if (isNaN(trimmedSearch[0])) {
158            if (cID == this.changeID) {
159                this.psAddressContainer.style.display = "none";
160                this.toggleDataLoad(false, this.psAddressContainer, this.psAddressItemContainer, this.loadingListing)                
161            }
162        }
163        else {
164            let json_listingData = await BaseHelper.MakeAJAXGetRequest
164("/api/Listing/searchListing", { searchValue: searchValue });
165            if (cID == this.changeID) {
166                let listingData = JSON.parse(json_listingData);
167                if (listingData == null || listingData.Listing == null || listingData.Listing.length == 0) {
168                    this.psAddressContainer.style.display = "none";
169                }
170                this.populateListingFields(listingData);
171                this.toggleDataLoad(false, this.psAddressContainer, this.psAddressItemContainer, this.loadingListing)                
172            }
173        }
174    };
175
176    this.toggleDataLoad = (toggle, container, itemContainer, loading) => {
177        if (loading.data == true) {
178            if (toggle) {
179                return;
180            }
181            else {
182                itemContainer.style.display = "block";
183                container.removeChild(loading.img);
184            }
185        }
186        else {
187            if (toggle) {
188                container.appendChild(loading.img);
189                itemContainer.style.display = "none";
190            }
191            else {
192                return;
193            }
194        }
195        loading.data = toggle;
196    }
197
198    this.retrieveAndPopulateCityStateZipCountySubdivisionData = async (cID, searchValue) => {
199        if (searchValue == null || searchValue.trim().length == 0) {
200            return;
201        }
202
203        this.toggleDataLoad(true, this.psCityStateZipCountySubdivisionContainer, this.psCityStateZipCountySubdivisionItemContainer, this.loadingCityStateZip);
204
205        let json_cityStateZipData = await BaseHelper.MakeAJAXGetRequest("/api/Listing/searchCityStateZipCountySubdivision", { searchValue: searchValue });
206        if (cID == this.changeID) {
207            let listingData = JSON.parse(json_cityStateZipData);
208            this.populateCityStateZipCountySubdivisionFields(listingData);
209            this.toggleDataLoad(false, this.psCityStateZipCountySubdivisionContainer, this.psCityStateZipCountySubdivisionItemContainer, this.loadingCityStateZip);
210        }
211    };
212
213    this.refresh = async (cID) => {
214        let searchValue = this.txtSearch.value;
215        if (searchValue.length < 2) {
216            return;
217        }
218        //this.ToggleLoading(true);
219        let listingDataTask = this.retrieveAndPopulateListingData(cID, searchValue);
220        let cityStateZipTask = this.retrieveAndPopulateCityStateZipCountySubdivisionData(cID, searchValue);
221        await listingDataTask;
222        await cityStateZipTask;
223        //this.ToggleLoading(false);
224    };
225
226    this.populateFields = function (data) {
227        this.clearFields();
228        this.currentData = data;
229        if (data == null) {
230            return;
231        }
232        for (let i = 0; data.dtAddress != null && i < data.dtAddress.length; i++) {
233            let itemData = data.dtAddress[i];
234            let psItem = this.createPsDisplayItem("Address", i, itemData.AddressLine);
235            this.psAddressItemContainer.appendChild(psItem);
236            psItem.addEventListener("click", (e) => {
237                this.onPropertySearchItemClick(psItem);
238            })
239        }
240        for (let i = 0; data.dtCity != null && i < data.dtCity.length; i++) {
241            let itemData = data.dtCity[i];
242            let psItem = this.createPsDisplayItem("City", i, itemData.CityState);
243            this.psCityItemContainer.appendChild(psItem);
244            psItem.addEventListener("click", (e) => {
245                this.onPropertySearchItemClick(psItem);
246            })
247        }
248        for (let i = 0; data.dtState != null && i < data.dtState.length; i++) {
249            let itemData = data.dtState[i];
250            let psItem = this.createPsDisplayItem("State", i, itemData.State);
251            this.psStateItemContainer.appendChild(psItem);
252            psItem.addEventListener("click", (e) => {
253                this.onPropertySearchItemClick(psItem);
254            })
255        }
256        for (let i = 0; data.dtZip != null && i < data.dtZip.length; i++) {
257            let itemData = data.dtZip[i];
258            let psItem = this.createPsDisplayItem("Zip", i, itemData.ZipCityState);
259            this.psZipItemContainer.appendChild(psItem);
260            psItem.addEventListener("click", (e) => {
261                this.onPropertySearchItemClick(psItem);
262            })
263        }
264        this.setSectionDisplay(this.currentData);
265    };
266
267    this.generateAddressLine = (obj) => {
268        // Initialize an empty address line
269        let addressLine = '';
270        if (obj.FilterStreetNumber == null && obj.FilterStreetName == null && obj.AddressLine != null) {
271            let result = "";
272            let al = obj["AddressLine"];
273            let parts = al.split(',');
274            result = BaseHelper.toTitleCase(parts[0]);
275            addressLine = `${result}, `;
276        }
277        else {
278            // Append each field to the address line if present, applying transformations as 
278necessary
279            if (obj.FilterStreetNumber) addressLine += `${obj.FilterStreetNumber} `;
280            if (obj.StreetDirPrefix) addressLine += `${obj.StreetDirPrefix} `;
281            if (obj.FilterStreetName) {
282                // Convert to title case first to check suffix presence accurately
283                let streetNameTitleCase = BaseHelper.toTitleCase(obj.FilterStreetName);
284                addressLine += `${streetNameTitleCase} `;
285
286                if (obj.FilterStreetSuffix) {
287                    // Convert to title case for a proper comparison
288                    let streetSuffixTitleCase = BaseHelper.toTitleCase(obj.FilterStreetSuffix);
289                    // Check if the street name ends with the street suffix, append suffix if not
290                    if (!streetNameTitleCase.endsWith(streetSuffixTitleCase)) {
291                        addressLine += `${streetSuffixTitleCase} `;
292                    }
293                }
294            } else if (obj.FilterStreetSuffix) { // If there's no street name but a suffix, append the suffix
295                addressLine += `${BaseHelper.toTitleCase(obj.FilterStreetSuffix)} `;
296            }
297
298            if (obj.FilterStreetDirSuffix) addressLine += `${BaseHelper.toTitleCase(obj.FilterStreetDirSuffix)} `;
299            addressLine = addressLine.trim() + ", "
300            if (obj.FilterUnitNumber) addressLine += `${BaseHelper.toTitleCase(obj.FilterUnitNumber)}, `;
301        }
302        if (obj.FilterCity) addressLine += `${BaseHelper.toTitleCase(obj.FilterCity)}, `;
303        if (obj.FilterState) addressLine += `${obj.FilterState.toUpperCase()}, `; // State kept in uppercase, no title case
304        if (obj.FilterZip) addressLine += `${obj.FilterZip}`;
305
306        // Clean up double spaces or leading/trailing spaces if any field was missing
307        return addressLine.replace(/  +/g, ' ').trim();
308    };
309
310    this.populateListingFields = (data) => {
311        this.psAddressItemContainer.innerHTML = "";
312        for (let i = 0; data.Listing != null && i < data.Listing.length; i++) {
313            let itemData = data.Listing[i];
314            let psItem = this.createPsDisplayItem("Address", i, this.generateAddressLine(itemData));
315            this.psAddressItemContainer.appendChild(psItem);
316            psItem.addEventListener("click", (e) => {
317                this.onPropertySearchAddressClick(itemData);
318            })
319        }
320        //console.log(data);
321    };
322
323    this.populateCityStateZipCountySubdivisionFields = (data) => {
324        this.psCityContainer.style.display = "none";
325        this.psStateContainer.style.display = "none";
326        this.psZipContainer.style.display = "none";
327        this.psCountyContainer.style.display = "none";
328        this.psSubdivisionContainer.style.display = "none";
329
330        if (data.city != null && data.city.length > 0) {
331            this.psCityItemContainer.innerHTML = "";
332            this.psCityContainer.style.display = "block";
333            for (let i = 0; i < data.city.length; i++) {
334                let city = data.city[i];
335                let itemData = data.city[i].data;
336                let psItem = this.createPsDisplayItem("City", i, city.searchText);
337                this.psCityItemContainer.appendChild(psItem);
338                psItem.addEventListener("click", (e) => {
339                    this.onPropertySearchCityClick(itemData, city.searchText);
340                });
341            }
342        }
343        if (data.county != null && data.county.length > 0) {
344            this.psCountyItemContainer.innerHTML = "";
345            this.psCountyContainer.style.display = "block";
346            for (let i = 0; data.county != null && i < data.county.length; i++) {
347                let county = data.county[i];
348                let itemData = data.county[i].data;
349                let psItem = this.createPsDisplayItem("County", i, county.searchText);
350                this.psCountyItemContainer.appendChild(psItem);
351                psItem.addEventListener("click", (e) => {
352                    this.onPropertySearchCountyClick(itemData, county.searchText);
353                })
354            }
355        }
356        if (data.subdivision != null && data.subdivision.length > 0) {
357            this.psSubdivisionItemContainer.innerHTML = "";
358            this.psSubdivisionContainer.style.display = "block";
359            for (let i = 0; data.subdivision != null && i < data.subdivision.length; i++) {
360                let subdivision = data.subdivision[i];
361                let itemData = data.subdivision[i].data;
362                let psItem = this.createPsDisplayItem("Subdivision", i, subdivision.searchText);
363                this.psSubdivisionItemContainer.appendChild(psItem);
364                psItem.addEventListener("click", (e) => {
365                    this.onPropertySearchSubdivisionClick(itemData, subdivision.searchText);
366                })
367            }
368        }
369
370        if (data.state != null && data.state.length > 0) {
371            this.psStateItemContainer.innerHTML = "";
372            this.psStateContainer.style.display = "block";
373            for (let i = 0; data.state != null && i < data.state.length; i++) {
374                let itemData = data.state[i];
375                let psItem = this.createPsDisplayItem("State", i, BaseHelper.toTitleCase(itemData.stateName));
376                this.psStateItemContainer.appendChild(psItem);
377                psItem.addEventListener("click", (e) => {
378                    this.onPropertySearchStateClick(itemData);
379                })
380            }
381        }
382        if (data.zip != null && data.zip.length > 0) {
383            this.psZipItemContainer.innerHTML = "";
384            this.psZipContainer.style.display = "block";
385            for (let i = 0; data.zip != null && i < data.zip.length; i++) {
386                let itemData = data.zip[i];
387                let psItem = this.createPsDisplayItem("Zip", i, BaseHelper.toTitleCase(itemData.zip) + ", " + itemData.state);
388                this.psZipItemContainer.appendChild(psItem);
389                psItem.addEventListener("click", (e) => {
390                    this.onPropertySearchZipClick(itemData);
391                })
392            }
393        }
394        //console.log(data);
395    };
396
397    this.GotoAddress = (record) => {
398        let addressLine = "";
399        if (record!=null && record.AddressLine != null) {
400            addressLine = record.AddressLine;
401        }
402        if (BaseHelper.displayAddress(record)) {
403            window.location = "/prop-details/" + record.ListingID + "/" + addressLine.replace(/[^a-zA-Z0-9 ]/g, "").replaceAll(' ', '_');
404        }
405        else {
406            window.location = "/prop-details/" + record.ListingID + "/";
407        }
408        
409    }
410
411    this.onPropertySearchAddressClick = (record) => {
412        this.GotoAddress(record);
413    };
414
415    this.onPropertySearchCityClick = (recordArr, searchText) => {
416        let sdFilterArr = [];
417        recordArr.forEach((record) => {
418            sdFilterArr.push(this.getCityFilter(record));
419        });
420        if (this.onPropertySearchItemClickCallback != null) {
421            this.onPropertySearchItemArrClickCallback(sdFilterArr, searchText);
422        }
423    };
424
425    this.onPropertySearchStateClick = (record) => {
426        filter = this.getStateFilter(record);
427        let searchText = BaseHelper.capitalizeFirstLetter(record.stateName.toLowerCase());
428        if (this.onPropertySearchItemClickCallback != null) {
429            this.onPropertySearchItemClickCallback(filter, searchText);
430        }
431    };
432
433    this.onPropertySearchZipClick = (record) => {
434        filter = this.getZipFilter(record);
435        let searchText = record.zipCityState;
436        if (this.onPropertySearchItemClickCallback != null) {
437            this.onPropertySearchItemClickCallback(filter, searchText);
438        }
439    };
440
441    this.onPropertySearchCountyClick = (recordArr, searchText) => {
442        let sdFilterArr = [];
443        recordArr.forEach((record) => {
444            sdFilterArr.push(this.getCountyFilter(record));
445        });
446        if (this.onPropertySearchItemClickCallback != null) {
447            this.onPropertySearchItemArrClickCallback(sdFilterArr, searchText);
448        }
449    };
450
451    this.onPropertySearchSubdivisionClick = (recordArr, searchText) => {
452        let sdFilterArr = [];
453        recordArr.forEach((record) => {
454            sdFilterArr.push(this.getSubdivisionFilter(record));
455        });
456        if (this.onPropertySearchItemClickCallback != null) {
457            this.onPropertySearchItemArrClickCallback(sdFilterArr, searchText);
458        }
459    };
460
461    this.onPropertySearchItemClick = async (psItem) => {
462        let type = psItem.getAttribute("data-type");
463        let index = psItem.getAttribute("data-index");
464        let filter = null;
465        let searchText = null;
466        if (type == "Address") {
467            let record = this.currentData.dtAddress[index];
468            this.GotoAddress(record);
469        }
470        else if (type == "City") {
471            let record = this.currentData.dtCity[index];
472            filter = this.getCityFilter(record);
473            searchText = record.CityState;
474        }
475        else if (type == "State") {
476            let record = this.currentData.dtState[index];
477            filter = this.getStateFilter(record);
478            searchText = record.State;
479        }
480        else if (type == "Zip") {
481            let record = this.currentData.dtZip[index];
482            filter = this.getZipFilter(record);
483            searchText = record.ZipCityState;
484        }
485        if (this.onPropertySearchItemClickCallback != null) {
486            this.onPropertySearchItemClickCallback(filter, searchText);
487        }
488    };
489
490    this.createFilter = (name, value) => {
491        return {
492            name: name,
493            value: value
494        }
495    };
496
497    this.getAddressFilter = (record) => {
498        let filterArr = [];
499        filterArr.push(this.createFilter("City", record.FilterCity));
500        filterArr.push(this.createFilter("State", record.FilterState));
501        filterArr.push(this.createFilter("StreetName", record.FilterStreetName));
502        filterArr.push(this.createFilter("StreetNumber", record.FilterStreetNumber));
503        filterArr.push(this.createFilter("Zip", record.FilterZip));
504        return filterArr;
505    };
506
507    this.getCityFilter = (record) => {
508        let filterArr = [];
509        filterArr.push(this.createFilter("City", record.city));
510        filterArr.push(this.createFilter("State", record.state));
511        return filterArr;
512    };
513    this.getStateFilter = (record) => {
514        let filterArr = [];
515        filterArr.push(this.createFilter("State", record.state));
516        return filterArr;
517    };
518    this.getZipFilter = (record) => {
519        let filterArr = [];
520        filterArr.push(this.createFilter("Zip", record.zip));
521        filterArr.push(this.createFilter("State", record.state));
522        return filterArr;
523    };
524
525    this.getCountyFilter = (record) => {
526        let filterArr = [];
527        filterArr.push(this.createFilter("CountyID", record.countyId));
528        return filterArr;
529    };
530
531    this.getSubdivisionFilter = (record) => {
532        let filterArr = [];
533        filterArr.push(this.createFilter("SubdivisionID", record.subdivisionId));
534        filterArr.push(this.createFilter("City", record.city));
535        filterArr.push(this.createFilter("State", record.state));
536        return filterArr;
537    };
538
539    this.clearFields = function () {
540        this.psAddressItemContainer.innerHTML = "";
541        this.psZipItemContainer.innerHTML = "";
542        this.psCityItemContainer.innerHTML = "";
543        this.psStateItemContainer.innerHTML = "";
544        this.psCountyItemContainer.innerHTML = "";
545
546    };
547
548    this.setSectionDisplay = function (data) {
549        this.psAddressContainer.style.display = "none";
550        this.psZipContainer.style.display = "none";
551        this.psCityContainer.style.display = "none";
552        this.psStateContainer.style.display = "none";
553        this.psCountyContainer.style.display = "none";
554        this.psSubdivisionContainer.style.display = "none";
555        if (data == null) {
556            return;
557        }
558        if (data.dtAddress != null && data.dtAddress.length > 0) {
559            this.psAddressContainer.style.display = "block";
560        }
561        if (data.dtCity != null && data.dtCity.length > 0) {
562            this.psCityContainer.style.display = "block";
563        }
564        if (data.dtState != null && data.dtState.length > 0) {
565            this.psStateContainer.style.display = "block";
566        }
567        if (data.dtZip != null && data.dtZip.length > 0) {
568            this.psZipContainer.style.display = "block";
569        }
570        if (data.dtCounty != null && data.dtCounty.length > 0) {
571            this.psSubdivisionContainer.style.display = "block";
572        }
573        if (data.dtSubdivision != null && data.dtCounty.length > 0) {
574            this.psSubdivisionContainer.style.display = "block";
575        }
576    };
577
578    this.onTemplateLoad = function () {
579        this.psAddressContainer = this.element.querySelector(".psAddressContainer");
580        this.psZipContainer = this.element.querySelector(".psZipContainer");
581        this.psCityContainer = this.element.querySelector(".psCityContainer");
582        this.psStateContainer = this.element.querySelector(".psStateContainer");
583        this.psCountyContainer = this.element.querySelector(".psCountyContainer");
584        this.psSubdivisionContainer = this.element.querySelector(".psSubdivisionContainer");
585        this.psCityStateZipCountySubdivisionContainer = this.element.querySelector(".psCityStateZipCountySubdivisionContainer");
586
587        this.psAddressSectionName = this.psAddressContainer.querySelector(".SectionName");
588        this.psZipSectionName = this.psZipContainer.querySelector(".SectionName");
589        this.psCitySectionName = this.psCityContainer.querySelector(".SectionName");
590        this.psStateSectionName = this.psStateContainer.querySelector(".SectionName");
591        this.psCountySectionName = this.psCountyContainer.querySelector(".SectionName");
592        this.psSubdivisionSectionName = this.psSubdivisionContainer.querySelector(".SectionName");
593
594        this.psAddressItemContainer = this.psAddressContainer.querySelector(".ItemContainer");
595        this.psZipItemContainer = this.psZipContainer.querySelector(".ItemContainer");
596        this.psCityItemContainer = this.psCityContainer.querySelector(".ItemContainer");
597        this.psStateItemContainer = this.psStateContainer.querySelector(".ItemContainer");
598        this.psCountyItemContainer = this.psCountyContainer.querySelector(".ItemContainer");
599        this.psSubdivisionItemContainer = this.psSubdivisionContainer.querySelector(".ItemContainer");
600
601        this.psCityStateZipCountySubdivisionItemContainer = this.element.querySelector(".psCityStateZipCountySubdivisionItemContainer");
602
603        this.psAddressContainer.style.display = "none";
604        this.psCityStateZipCountySubdivisionItemContainer.style.display = "none";
605        //this.setSectionDisplay(null);
606    };
607}
608Widgets.PropertySearch.prototype = new Widgets.PropertySearch();

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.