PageSourceSearch

https://replaylistings.com/assets/js/mapgridsecond.js

js replaylistings.com collected 2026-10-02 10:16:45 UTC 53,406 bytes, 1,406 lines download raw bytes

1var visibleLocations = new Map();
2var totalListings = new Map();
3var listingMarker = new Map();
4var markerCluster;
5var markers = [];
6var initialMarker = [];
7
8var googleMapView;
9
10var f_bed = new Set();
11var f_bath = new Set();
12var f_amenities = new Set();
13var f_minPrice = 0;
14var f_maxPrice = 9999999999999;
15var f_priceCategory = "";
16// Get the modal
17var modal;
18
19var isMapView = true;
20
21var isScrolling;
22var listingKeys;
23var visibleListingCount = 0;
24var lastVisibleListingIndex = 0;
25var initialLoading = 5;
26
27
28var timer = null;
29var lastScroll = 0;
30
31var isMobile = false;
32
33var isSales = false;
34
35var priceIconGMSize = 60;
36
37var fistIdle = false;
38
39
40// $(window).on('load', function () {
41//     setTimeout(
42//         function () {
43
44//         }, 2000);
45// })
46
47
48
49
50window.addEventListener('load', function () {
51    console.log("loaded ")
52    const queryString = window.location.search;
53    const urlParams = new URLSearchParams(queryString);
54    var rentalSale = "rentals";
55    if (urlParams.has('type')) {
56        rentalSale = urlParams.get('type');
57    }
58
59
60    switch (rentalSale) {
61        case "sales":
62            priceIconGMSize = 80;
63            var element = document.getElementById("saleSelecttion");
64            var isPreviouslySelected = element.classList.contains("sSelected")
65            if (!isPreviouslySelected) {
66                element.classList.toggle("sSelected");
67            }
68            element.previousElementSibling.classList.remove("rSelected");
69            isSales = true;
70            updatePriceDropdown()
71            break;
72        default:
73            var element = document.getElementById("rentalSelection");
74            var isPreviouslySelected = element.classList.contains("rSelected")
75            if (!isPreviouslySelected) {
76                element.classList.toggle("rSelected");
77            }
78
79            element.nextElementSibling.classList.remove("sSelected");
80            break;
81    }
82
83    loadListings(rentalSale);
84
85
86    setModal();
87    var listingHeight = document.getElementById('listingCollection');
88
89
90    window.addEventListener('scroll', function (e) {
91
92        clearTimeout($.data(this, 'scrollTimer'));
93        $.data(this, 'scrollTimer', setTimeout(function () {
94            var scrolled = this.window.scrollY;
95            addNewListingUi(12);
96            autoPlayVideo();
97        }, 100));
98    });
99
100    $(".listings").on('scroll', function () {
101
102        clearTimeout($.data(this, 'scrollTimer'));
103        $.data(this, 'scrollTimer', setTimeout(function () {
104            var totalHeight = listingHeight.scrollHeight;
105            var scrolled = listingHeight.scrollTop;
106            var diff = (scrolled - lastScroll);
107
108            if (totalHeight - scrolled < 2000 && diff > 800) {
109                lastScroll = scrolled;
110                addNewListingUi();
111            }
112            autoPlayVideo();
113        }, 100));
114    });
115
116});
117
118async function loadListings(type) {
119    var count = 1000;
120    if (/Android|webOS|iPhone|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {
121        isMobile = true;
122        count = 500;
123    }
124    var listingUrl = 'https://replaylistings-95421.firebaseio.com/all_listings/approved_listings.json?orderBy="$key"&limitToLast=' + count;
125    if (type == "sales") {
126        listingUrl = 'https://replaylistings-95421.firebaseio.com/sales_listings.json?orderBy="$key"&limitToLast=' + count;
127    }
128
129    fetch(listingUrl, { mode: 'cors' })
130        .then(function (response) {
131            return response.json();
132        })
133        .then(function (text) {
134            if (isMobile) {
135                return gotDataMobile(text)
136                    .then(applyUrlFilters());
137            } else {
138                return gotData(text)
139                    .then(applyUrlFilters());       
140            }
141        })
142        .catch(function (error) {
143        });
144}
145
146
147function updatePriceDropdown() {
148    var priceA = document.getElementById("classA");
149    priceA.innerText = "Under 1M"
150
151    var priceB = document.getElementById("classB");
152    priceB.innerText = "1M - 3M"
153
154    var priceC = document.getElementById("classC");
155    priceC.innerText = "3M - 5M"
156
157    var priceD = document.getElementById("classD");
158    priceD.innerText = "5M +"
159
160}
161
162
163function applyUrlFilters() {
164    const queryString = window.location.search;
165    const urlParams = new URLSearchParams(queryString);
166
167    if (urlParams.has('bed')) {
168        const bedSize = urlParams.get('bed');
169        bedSize.split(",").forEach(val => {
170            f_bed.add(val)
171            switch (val) {
172                case "0":
173                    document.getElementById('studioBedLbl').MaterialCheckbox.check();
174                    break;
175                case "1":
176                    document.getElementById('oneBedLbl').MaterialCheckbox.check();
177                    break;
178                case "2":
179                    document.getElementById('twoBedLbl').MaterialCheckbox.check();
180                    break;
181                case "3":
182                    document.getElementById('threeBedLbl').MaterialCheckbox.check();
183                    break;
184            }
185        });
186        updateBedSelectedUi();
187        // choose
188    }
189
190
191    if (urlParams.has('bath')) {
192        var bathFiltersParm = urlParams.get('bath');
193        bathFiltersParm.split(",").forEach(val => {
194            f_bath.add(val);
195            switch (val) {
196                case "1":
197                    document.getElementById('oneBathLbl').MaterialCheckbox.check();
198                    break;
199                case "2":
200                    document.getElementById('twoBathLbl').MaterialCheckbox.check();
201                    break;
202                case "3":
203                    document.getElementById('threeBathLbl').MaterialCheckbox.check();
204                    break;
205            }
206        });
207        updateBathSelectedUi();
208    }
209
210    if (urlParams.has('price')) {
211        var minPrice = urlParams.get('price');
212        var prange = priceRentalRange(minPrice);
213        f_priceCategory = "price" + prange[0];
214        document.getElementById(f_priceCategory + "lbl").MaterialRadio.check();
215
216        var txtElement = document.getElementById('txtPrice');
217        // txtElement.innerHTML = "Price: " + document.getElementById("class" + prange).innerText;
218        // if (!txtElement.parentElement.classList.contains('pbpink')) {
219        //     txtElement.parentElement.classList.add('pbpink');
220        // }
221
222        onPriceSelectedTrigger(prange[1], document.getElementById("class" + prange[0]).innerText, false)
223    }
224
225    if (urlParams.has('amenities')) {
226        var amenities = urlParams.get('amenities');
227        amenities.split(",").forEach(amenity => {
228            f_amenities.add(amenity);
229            document.getElementById(amenity + 'lbl').MaterialCheckbox.check();
230        });
231
232        var txtElement = document.getElementById('txtAmenities');
233        var amen = Array.from(f_amenities).join(',');
234        txtElement.innerHTML = "Amenities: " + amen;
235        if (!txtElement.parentElement.classList.contains('pbpink')) {
236            txtElement.parentElement.classList.add('pbpink');
237        }
238    }
239
240    // applyFilterNew();
241}
242
243function autoPlayVideo() {
244
245    var videos = document.getElementsByTagName("video");
246
247
248    for (var i = 0; i < videos.length; i++) {
249        try {
250            var video = videos[i];
251            if (isInViewport(video)) {
252                video.play();
253            } else {
254                video.pause();
255            }
256        } catch (Ex) {
257
258        }
259    }
260}
261
262function isInViewport(element) {
263    var rect = element.getBoundingClientRect();
264    // console.log(" rect.top >= 0" + rect.top)
265    // console.log(" rect.left >= 0" + rect.left)
266    // console.log(" rect.bottom <= 0" + rect.bottom)
267    // console.log("window.innerHeight and client height" + window.innerHeight + " " + document.documentElement.clientHeight)
268    // console.log(" rect.right <= 0" + rect.right)
269    // console.log("window.innerWidth and clientWidth" + window.innerWidth + " " + document.documentElement.clientWidth)
270
271
272    return (
273        rect.top >= 0 &&
274        rect.left >= 0 &&
275        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
276        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
277    );
278}
279
280
281var regionsAndNeighborhood = {
282    "Manhattan": {
283        "Upper Manhattan": ["Fort George", "Hamilton Heights", "Marcus Garvey", "Inwood", "Washington Heights", "Morningside Heights", "West Harlem", "East Harlem", "South Harlem", "Central Harlem", "Harlem"],
284        "Upper East Side": ["Upper East Side", "Carnegie Hill", "Lenox Hill", "Upper Carnegie Hill", "Yorkville"],
285        "Upper West Side": ["Upper West Side", "Lincoln Square", "Manhattan Valley"],
286        "Midtown West": ["Midtown West", "Chelsea", "Hell's Kitchen", "Hudson Yards", "Koreatown", "Clinton", "Theater District - Times Square"],
287        "Flatiron": ["Flatiron District", "Midtown Center", "Midtown South Central"],
288        "Midtown East": ["Midtown East", "Tudor City", "Sutton Place", "Murray Hill", "Roosevelt Island", "Gramercy Park", "Kips Bay", "Stuyvesant Town - Peter Cooper Village"],
289        "East Village Lower": ["East Village", "Union Square", "Bowery", "Lower East Side", "Chinatown", "Little Italy", "Civic Center", "Two Bridges"],
290        "West Village": ["West Village", "Greenwich Village", "Tribeca", "NoHo", "NoLita", "Nolita", "Meatpacking District"],
291        "Soho": ["SoHo"],
292        "Financial District": ["Battery Park City", "Financial District"]
293    },
294    "Queens": {
295        "Northwestern Queens": ["Astoria", "Corona", "East Elmhurst", "Elmhurst", "Forest Hills", "Glendale", "Jackson Heights", "Long Island City", "Maspeth", "Middle Village", "Rego Park", "Ridgewood", "Sunnyside", "Woodside"],
296        "Northeastern Queens": ["Auburndale", "Bayside", "College Point", "Flushing", "Flushing Meadows-Corona Park", "Fresh Meadows", "Glen Oaks", "Kew Gardens", "Kew Gardens Hills", "Whitestone"],
297        "Southeastern Queens": ["Briarwood", "Hollis", "Holliswood", "Jamaica", "Jamaica Estates", "Jamaica Hills", "South Jamaica", "St. Albans"],
298        "Southwestern Queens": ["Forest Park", "Howard Beach", "Ozone Park", "Richmond Hill", "South Ozone Park", "Woodhaven"],
299        "Rockaway Peninsula": ["Far Rockaway", "Rockaway Beach"]
300    },
301
302    "Brooklyn": {
303        "Northern Brooklyn": ["Bedford-Stuyvesant", "Bushwick", "Greenpoint", "Williamsburg"],
304        "South Brooklyn": ["Boerum Hill", "Carroll Gardens", "Cobble Hill", "Gowanus", "Greenwood Heights", "Park Slope", "Prospect Park", "Red Hook", "Sunset Park", "Windsor Terrace"],
305        "Central Brooklyn": ["Crown Heights", "East Flatbush", "Flatbush", "Flatbush - Ditmas Park", "Kensington", "Midwood", "Ocean Hill"],
306        "Northwestern Brooklyn": ["Brooklyn Heights", "Brooklyn Navy Yard", "Clinton Hill", "DUMBO", "Downtown Brooklyn", "Fort Greene", "Prospect Heights", "Vinegar Hill"],
307        "Southwestern Brooklyn": ["Bath Beach", "Bay Ridge", "Bensonhurst", "Borough Park", "Dyker Heights", "Mapleton"],
308        "Southern Brooklyn": ["Brighton Beach", "Coney Island", "Gravesend", "Sheepshead Bay"],
309        "Eastern Brooklyn": ["Brownsville", "Canarsie", "Cypress Hills", "East New York"],
310        "Southeastern Brooklyn": ["Bergen Beach", "Flatlands", "Floyd Bennett Airfield", "Marine Park", "Mill Basin"]
311    }
312
313};
314
315
316// constants start
317var paidCompaniesLogos = {
318    "Bond New York Properties Llc": "assets/brokerages_logo/BOND.svg",
319    "Caliber Associates Inc": "assets/brokerages_logo/Caliber.svg",
320    "Gzb Realty Llc": "assets/brokerages_logo/GZB Realty.svg",
321    "GZ Brokers": "assets/brokerages_logo/GZB Realty.svg",
322    "Manhattan Realty Group": "assets/brokerages_logo/Manhattan Realty Group.svg",
323    "Mdrn Group Llc": "assets/brokerages_logo/Mdrn Residential.svg",
324    "Mdrn Residential": "assets/brokerages_logo/Mdrn Residential.svg",
325
326    "Platinum Properties": "assets/brokerages_logo/Platinum Properties.svg",
327    "Highline Residential  Queens": "assets/brokerages_logo/Highline Residential.svg",
328    "Highline Residential Llc": "assets/brokerages_logo/Highline Residential.svg",
329    "Citi Habitats": "assets/brokerages_logo/Citi Habitats.svg",
330    "Anchor Associates Group Inc": "assets/brokerages_logo/Anchor Associates.svg"
331};
332
333var allAmenitiesMapping = {};
334allAmenitiesMapping['roofDeck'] = "Roof Deck";
335allAmenitiesMapping['convertible'] = "Convertible";
336allAmenitiesMapping['elevator'] = "Elevator";
337allAmenitiesMapping['gym'] = "Gym";
338allAmenitiesMapping['petFriendly'] = "Pet Friendly";
339allAmenitiesMapping['dishwasher'] = "Dishwasher";
340allAmenitiesMapping['laundry'] = "Laundry";
341allAmenitiesMapping['balcony'] = "Balcony";
342allAmenitiesMapping['doorman'] = "Door Man";
343
344var locationOffset = "";
345// constants end
346
347
348async function gotDataMobile(snapshot) {
349    isMapView = false;
350    visibleLocations = new Map();
351    totalListings = new Map();
352    listingKeys = Object.keys(snapshot);
353    var fetchedListingCount = listingKeys.length;
354    for (var i = fetchedListingCount - 1; i >= 0; i--) {
355
356        var lst = snapshot[listingKeys[i]]
357        totalListings.set(lst.listingKey, lst);
358        var latlng = {};
359        latlng["lat"] = lst.address.latitude;
360        latlng["lng"] = lst.address.longitude;
361
362        var markerId = totalListings.size - 1;
363        var marker = new google.maps.Marker({
364            position: latlng,
365            label: lst.rentAmount + "",
366            listingId: lst.listingKey,
367            markerId: markerId,
368        });
369        markers.push(marker);
370        listingMarker.set(lst.listingKey, markerId);
371        totalListings.set(lst.listingKey, lst);
372    }
373
374    addNewListingUi(9);
375}
376
377
378var infowindow;
379async function gotData(snapshot) {
380    console.log("got data" + new Date())
381    initMap();
382    infowindow = new google.maps.InfoWindow({
383        maxWidth: 400
384    });
385    visibleLocations = new Map();
386    totalListings = new Map();
387
388    var iconUrl = isSales ? "assets/images/markericonblack.png" : "assets/images/markericon.png";
389
390    var icon = {
391        url: iconUrl, // url
392        scaledSize: new google.maps.Size(priceIconGMSize, 20), // scaled size
393        origin: new google.maps.Point(0, 0), // origin
394        anchor: new google.maps.Point(0, 0), // anchor
395    };
396
397
398    listingKeys = Object.keys(snapshot);
399    var fetchedListingCount = listingKeys.length;
400
401    for (var i = fetchedListingCount - 1; i >= 0; i--) {
402
403        var lst = snapshot[listingKeys[i]]
404        var key = lst.listingKey;
405        var latlng = {};
406        latlng["lat"] = lst.address.latitude;
407        latlng["lng"] = lst.address.longitude;
408        var str = lst.address.latitude + "," + lst.address.longitude;
409
410        var completeAddress = lst.address.street.trim();
411        var address = completeAddress.trim();
412        if (!lst.showAddress) {
413            var pos = completeAddress.indexOf(" ");
414            address = completeAddress.substring(pos + 1);
415        }
416
417        var unitOrApartmentNumber = lst.address.unitOrApartmentNumber;
418        var listingAddressUnit = address + ", #" + unitOrApartmentNumber;
419
420        var bed = lst.bedroom.trim();
421        var bath = lst.bathroom.trim();
422        var bedBath = (bed == 0 ? "Studio" : (bed + ' Bed')) + ' | ' + bath + ' Bath';
423
424        var saleRental = isSales ? "sales" : "listing"
425
426        var listingSinglePageUrl = "https://replaylistings.com/" + saleRental + "?id=" + key;
427
428        var markerId = totalListings.size;
429        var marker = new google.maps.Marker({
430            position: latlng,
431            label: { text: "$" + lst.rentAmount + "", color: "white" },
432            listingId: key,
433            markerId: markerId,
434            icon: icon,
435            title: listingAddressUnit,
436            url: listingSinglePageUrl,
437            bedbath: bedBath,
438        });
439
440        marker.addListener('click', function (e) {
441            mixpanel.track("map_pills_clicked", { "source": "web", "page": "map view" });
442            window.open(this.url, '_blank');
443        });
444
445        marker.addListener('mouseover', function () {
446            mixpanel.track("map_pills_hovered", { "source": "web", "page": "map view" });
447            infowindow.setContent('<div class="listingInfo">' + this.bedbath + '</div>');
448            infowindow.open(map, this);
449        });
450
451        // assuming you also want to hide the infowindow when user mouses-out
452        marker.addListener('mouseout', function () {
453            infowindow.close();
454        });
455
456        if (!visibleLocations.has(getLatLngString(marker.position))) {
457            markers.push(marker);
458            visibleLocations.set(str, false);
459            listingMarker.set(key, markerId);
460            totalListings.set(key, lst);
461        }
462
463    }
464}
465
466
467function getLatLngString(position) {
468    return "" + position.lat() + "," + position.lng();
469}
470
471function addListingOnHoverEventListener() {
472
473    $('.listings .listing').hover(
474        // mouse in
475        function () {
476            // first we need to know which <div class="marker"></div> we hovered
477            var index = this.dataset.markerid;
478            markers[index].setIcon(highlightedIcon());
479        },
480        // mouse out
481        function () {
482            // first we need to know which <div class="marker"></div> we hovered
483            var index = this.dataset.markerid;
484            markers[index].setIcon(normalIcon());
485        }
486
487    );
488}
489
490async function createListing(listing, isMapListingPopUp, index) {
491    if (isSales) {
492        return createSalesListing(listing, isMapListingPopUp, index);
493    } else {
494        return createRentalListing(listing, isMapListingPopUp, index);
495    }
496
497}
498
499async function createSalesListing(listing, isMapListingPopUp, index) {
500    var listingKey = listing.listingKey;
501    var completeAddress = listing.address.street.trim();
502    var address = completeAddress.trim();
503    if (!listing.showAddress) {
504        var pos = completeAddress.indexOf(" ");
505        address = completeAddress.substring(pos + 1);
506    }
507    var neighborhood = listing.address.neighborhood.trim();
508    var price = listing.rentAmount;
509    var bed = listing.bedroom.trim();
510    var bath = listing.bathroom.trim();
511    var amenities = listing.amenities;
512    var videoThumbnail = listing.thumbnailURL;
513    var subNeighborhood = listing.address.subNeighborhood.trim();
514    var propertyType = listing.property_type;
515    if (!videoThumbnail)
516        videoThumbnail = 'https://s3.amazonaws.com/replaylistings-hosting-mobilehub-1004267050/1C85D002-C6D1-4BA0-A864-4D637BC6833A.jpeg';
517    var videoUrl = listing.m4v_url;
518
519    var agentName = listing.agent.first.trim();
520    var agentId = listing.authorKey.trim();
521    var agentProfilePic = listing.agent.profilePhoto;
522    if (!agentProfilePic) {
523        agentProfilePic = "./images/profile-image.png";
524    }
525    var listingIdAndAgentId = listingKey + "," + agentId;
526    var agentUrl = "https://replaylistings.com/Agents/" + agentId;
527    var listingSinglePageUrl = "https://replaylistings.com/sales?id=" + listingKey;
528
529    var completeNeighborhood = subNeighborhood + ", " + neighborhood;
530    var unitOrApartmentNumber = listing.address.unitOrApartmentNumber;
531    var listingAddressUnit = address + ", #" + unitOrApartmentNumber;
532
533    var agentCompany = listing.agent.company.trim();
534    var companyLogo = "";
535    if (paidCompaniesLogos.hasOwnProperty(agentCompany)) {
536        companyLogo = locationOffset + paidCompaniesLogos[agentCompany];
537    } else {
538        companyLogo = "";
539    }
540
541    var region = listing.query_boroughs;
542    var regionNeighborhood = listing.query_region;
543    var regionNeighBorhoodSub = listing.query_neighborhood;
544
545    var timePosted = listing.timePosted;
546
547
548    var propertyTypeDiv = '<div class="nofee_chip ovalchip medium-bold-font single-line">' + propertyType + '</div>';
549
550    var companyLogoDiv = "";
551    if (companyLogo) {
552        companyLogoDiv = '<img class="companylogo" src="' + companyLogo + '" alt="Person" width="96" height="96" />';
553    }
554
555    var bedBath = (bed == 0 ? "Studio" : (bed + ' Bed')) + ' | ' + bath + ' Bath';
556
557    var classForListing = "listing ";
558    if (isMapListingPopUp) {
559        classForListing = classForListing + " " + "listing-popup ";
560    }
561
562    var bedFilter = (bed >= 3 ? 3 : bed) + "-Bed ";
563    var bathFilter = (bath >= 3 ? 3 : bath) + "-Bath ";
564    var priceFilter = "";
565    if (price <= 1000000) {
566        priceFilter = "priceA ";
567    } else if (price > 1000000 && price <= 3000000) {
568        priceFilter = "priceB ";
569    } else if (price > 3000000 && price <= 5000000) {
570        priceFilter = "priceC ";
571    } else if (price > 5000000) {
572        priceFilter = "priceD ";
573    }
574
575    var subNeighborhoodSearch = 'https://replaylistings.com/search/?subNeighborhoods=' + neighborhood;
576
577    var media;
578
579    if (isMapListingPopUp) {
580        media = '<a href="' + listingSinglePageUrl + '" target="_blank"><img src="' + videoThumbnail + '" style="height: 100%; width: 100%"></a>';
581    } else {
582        media = '<a href="' + listingSinglePageUrl + '" target="_blank"><video onplay="onVideoPlayed(this)"  onclick="videoClicked(this)" preload="none" class="rcorners-image-left" poster="' + videoThumbnail + '"disablePictureInPicture muted controlslist="nodownload" playsinline><source src="' + videoUrl + '" type="video/mp4">Your browser does not support the video tag.</video></a>';
583    }
584
585    var priceDisplay = "$ " + numberWithCommas(price);
586
587
588    // var listingDom = '<div onmouseenter="onDivMouseOver(this)" class="' + classForListing + '' + bedFilter + '' + bathFilter + '' + priceFilter + '" id="' + listingKey + '" data-markerId="' + index + '"><div class="chip"><a><img class="agentlogo"src="' + agentProfilePic + '" alt="Person" /></a><a class="agent single-line" onclick="agentPageViewed(this)" href="' + agentUrl + '" target="_blank">' + agentName + '</a><a href="#">
588' + companyLogoDiv + '</a></div><div class="details">' + media + propertyTypeDiv + '<div class="address_chip ovalchip single-line"><a onclick="onNeighborhoodQuickSearch(this)" target="_blank" href="' + subNeighborhoodSearch + '">' + neighborhood + '</a></div> <div class="openHouse_chip ovalchip single-line"><a onclick="onNeighborhoodQuickSearch(this)" target="_blank" href="' + subNeighborhoodSearch + '">' + "Open House" + '</a></div> <div class="price_chip ovalchip single-line">$ ' + price + ' </div> <div class="heart_chip"><i data-toggle="modal" data-target="#heartClicked" class="fa fa-3x fa-heart-o"></i></div></div> <div class="footer"><a onclick="singleListingClicked(this)" href="' + listingSinglePageUrl + '" class="address single-line">' + listingAddressUnit + '</a><div></div><div class="bed-bath">' + bedBath + '</div><div class="gap"></div><a class="btn pbblue check-availability" role="button" href="' + listingSinglePageUrl + '" target="_blank"><span class="mdc-button__ripple"></span>Check Availability</a></div></div>';
589
590    // var listingDom = '<div onmouseenter="onDivMouseOver(this)" class="' + classForListing + '' + bedFilter + '' + bathFilter + '' + priceFilter + '" id="' + listingKey + '" data-markerId="' + index + '"><div class="details">' + media + '</div><div class="footer"><div class="price" id="price">' + priceDisplay + '</div><div class="bedbath">' + bedBath + '</div><div></div><div class="address">' + listingAddressUnit + '</div><div class="subneighborhood">' + neighborhood + '</div><a class="btn pbblue check-availability" role="button" href="' + listingSinglePageUrl + '"></span>More Info</a> </div></div>';
591
592
593    var listingDom = `
594    <div  onmouseleave=onDivMouseOver(this) onmouseenter="onDivMouseOver(this)" class="${classForListing} ${bedFilter} ${bathFilter} ${priceFilter} " id="${listingKey}" data-markerid="${index}">
595    <div class="details"> ${media} </div>
596    <a class="footer"  href="${listingSinglePageUrl}" target="_blank"  onclick="videoClicked(this)">
597        <div class="price" id="price">${priceDisplay}</div>
598        <div class="bedbath">${bedBath}</div>
599        <div></div>
600        <div class="address">${listingAddressUnit}</div>
601        <div class="subneighborhood">${neighborhood}</div>
602        <button class="btn pbblue check-availability" role="button">More Info</button>
603    </a>
604</div>
605
606`;
607
608    return listingDom;
609}
610
611async function createRentalListing(listing, isMapListingPopUp, index) {
612    var listingKey = listing.listingKey;
613    var completeAddress = listing.address.street.trim();
614    var address = completeAddress.trim();
615    if (!listing.showAddress) {
616        var pos = completeAddress.indexOf(" ");
617        address = completeAddress.substring(pos + 1);
618    }
619    var neighborhood = listing.address.neighborhood.trim();
620    var price = listing.rentAmount;
621    var bed = listing.bedroom.trim();
622    var bath = listing.bathroom.trim();
623    var amenities = listing.amenities;
624    var videoThumbnail = listing.thumbnailURL;
625    var subNeighborhood = listing.address.subNeighborhood.trim();
626    if (!videoThumbnail)
627        videoThumbnail = 'https://s3.amazonaws.com/replaylistings-hosting-mobilehub-1004267050/1C85D002-C6D1-4BA0-A864-4D637BC6833A.jpeg';
628    var videoUrl = listing.videoURL;
629    if (videoUrl.endsWith("m3u8")) {
630        var urlSplits = videoUrl.split("/");
631        if (videoUrl.startsWith("https://testbucket2-replaylistings.s3.amazonaws.com")) {
632            videoUrl = urlSplits[0] + "/" + urlSplits[1] + "/" + urlSplits[2] + "/" + urlSplits[4] + ".m4v"
633        } else {
634            videoUrl = urlSplits[0] + "/" + urlSplits[1] + "/" + urlSplits[2] + "/" + urlSplits[3] + "/" + urlSplits[5] + ".m4v"
635        }
636    }
637
638    var agentName = listing.agent.first.trim();
639    var agentId = listing.authorKey.trim();
640    var agentProfilePic = listing.agent.profilePhoto;
641    if (!agentProfilePic) {
642        agentProfilePic = "./images/profile-image.png";
643    }
644    var listingIdAndAgentId = listingKey + "," + agentId;
645    var agentUrl = "https://replaylistings.com/Agents/" + agentId;
646    var listingSinglePageUrl = "https://replaylistings.com/listing/" + listingKey;
647
648    var completeNeighborhood = subNeighborhood + ", " + neighborhood;
649    var unitOrApartmentNumber = listing.address.unitOrApartmentNumber;
650    var listingAddressUnit = address + ", #" + unitOrApartmentNumber;
651
652    var agentCompany = listing.agent.company.trim();
653    var companyLogo = "";
654    if (paidCompaniesLogos.hasOwnProperty(agentCompany)) {
655        companyLogo = locationOffset + paidCompaniesLogos[agentCompany];
656    } else {
657        companyLogo = "";
658    }
659
660    var region = listing.query_boroughs;
661    var regionNeighborhood = listing.query_region;
662    var regionNeighBorhoodSub = listing.query_neighborhood;
663
664    var timePosted = listing.timePosted;
665
666    var isNoFee = false;
667    if (listing.amenities) {
668        isNoFee = listing.amenities.includes('noFee');
669    }
670    var noFeeDiv = "";
671    if (isNoFee) {
672        noFeeDiv = '<div class="nofee_chip ovalchip medium-bold-font single-line">No Fee </div>';
673    }
674
675    var companyLogoDiv = "";
676    if (companyLogo) {
677        companyLogoDiv = '<img class="companylogo" src="' + companyLogo + '" alt="Person" width="96" height="96" />';
678    }
679
680    var bedBath = (bed == 0 ? "Studio" : (bed + ' Bed')) + ' | ' + bath + ' Bath';
681
682    var classForListing = "listing ";
683    if (isMapListingPopUp) {
684        classForListing = classForListing + " " + "listing-popup ";
685    }
686
687    var bedFilter = (bed >= 3 ? 3 : bed) + "-Bed ";
688    var bathFilter = (bath >= 3 ? 3 : bath) + "-Bath ";
689    var priceFilter = "";
690    if (price <= 3000) {
691        priceFilter = "priceA ";
692    } else if (price > 3000 && price <= 4000) {
693        priceFilter = "priceB ";
694    } else if (price > 4000 && price <= 5000) {
695        priceFilter = "priceC ";
696    } else if (price > 5000) {
697        priceFilter = "priceD ";
698    }
699
700    var subNeighborhoodSearch = 'https://replaylistings.com/search/?subNeighborhoods=' + subNeighborhood;
701
702    var media;
703
704    if (isMapListingPopUp) {
705        media = '<a href="' + listingSinglePageUrl + '" target="_blank"><img src="' + videoThumbnail + '" style="height: 100%; width: 100%;"></a>';
706    } else {
707        media = '<a href="' + listingSinglePageUrl + '" target="_blank"><video onplay="onVideoPlayed(this)"  onclick="videoClicked(this)" preload="none" class="rcorners-image-left" poster="' + videoThumbnail + '"disablePictureInPicture muted controlslist="nodownload" playsinline><source src="' + videoUrl + '" type="video/mp4">Your browser does not support the video tag.</video></a>';
708    }
709
710    var priceDisplay = "$ " + numberWithCommas(price);
711
712    var listingDom = `
713    <div onmouseenter=" onmouseleave=onDivMouseOver(this) onDivMouseOver(this)" class="${classForListing} ${bedFilter} ${bathFilter} ${priceFilter} " id="${listingKey}" data-markerid="${index}">
714    <div class="details"> ${media} </div>
715    <a class="footer"  href="${listingSinglePageUrl}" target="_blank"  onclick="videoClicked(this)">
716        <div class="price" id="price">${priceDisplay}</div>
717        <div class="bedbath">${bedBath}</div>
718        <div></div>
719        <div class="address">${listingAddressUnit}</div>
720        <div class="subneighborhood">${neighborhood}</div>
721        <button class="btn pbblue check-availability" role="button">More Info</button>
722    </a>
723</div>
724
725`;
726
727
728    return listingDom;
729}
730
731function initMap() {
732    // console.log("init map")
733    markers = [];
734    setMapOnAll(null);
735
736    googleMapView = new google.maps.Map(document.getElementById('map'), {
737        zoom: isSales ? 10 : 14,
738        center: { lat: 40.777263, lng: -73.9540303 },
739        minZoom: 5,
740        maxZoom: 20,
741        styles: [
742            {
743                "featureType": "poi.business",
744                "stylers": [
745                    {
746                        "visibility": "off"
747                    }
748                ]
749            },
750            {
751                "featureType": "poi.park",
752                "elementType": "labels.text",
753                "stylers": [
754                    {
755                        "visibility": "off"
756                    }
757                ]
758            }
759        ]
760    });
761
762    google.maps.event.addListener(googleMapView, 'idle', function () {
763        // console.log("idle")
764        onLoadAndOnBoundChange();
765    });
766}
767
768function setMapOnAll(map) {
769    for (var i = 0; i < markers.length; i++) {
770        markers[i].setMap(map);
771    }
772}
773
774async function onLoadAndOnBoundChange() {
775    // console.log("on bound change");
776    await loadListingsWithInBound(9);
777    autoPlayVideo()
778}
779
780async function loadListingsWithInBound(limit) {
781    // console.log('loadListingsWithInBound called')
782    if (isMapView && googleMapView) {
783        var lat = googleMapView.center.lat();
784        var lng = googleMapView.center.lng();
785        var zoom = googleMapView.zoom;
786        mixpanel.track("map_bound_change", { "lat": lat, "lng": lng, "zoom": zoom, "source": "web" });
787    }
788    var count = 0;
789    var listingsToShow = '';
790    var markerMatched = [];
791    var listingWithInBound = 0;
792    for (var i = 0; i < markers.length; i++) {
793        var key = markers[i].listingId;
794        var markerId = listingMarker.get(key);
795        if (!markers[markerId]) {
796            var a = 123;
797            continue;
798        }
799        // markers[markerId].setMap(null);
800        if ((googleMapView && googleMapView.getBounds().contains(markers[i].getPosition())) || !isMapView || isMobile) {
801            var c_listing = totalListings.get(key);
802
803            if (listingMatchedFilter(c_listing)) {
804                listingWithInBound++;
805                var isCountReached = count >= limit;
806                if (!isMapView || isMobile) {
807                    if (isCountReached) {
808                        break;
809                    } else {
810                        listingsToShow += await createListing(c_listing, false, i);
811                        // console.log("created listing")
812                        lastVisibleListingIndex = i;
813                    }
814                } else {
815                    var latlngStr = getLatLngString(markers[i].getPosition());
816                    var hasListing = visibleLocations.has(latlngStr);
817                    if (hasListing) {
818                        if (visibleLocations.get(latlngStr)) {
819
820                        } else {
821                            markers[markerId].setMap(googleMapView);
822                            visibleLocations.set(latlngStr, true);
823                        }
824                    }
825
826                    if (!isCountReached) {
827                        // console.log("created listing 2s " + key)
828
829                        listingsToShow += await createListing(c_listing, false, i);
830                        lastVisibleListingIndex = i;
831                    }
832                }
833                count++;
834            } else {
835                if (isMapView) {
836                    var latlngStr = getLatLngString(markers[i].getPosition());
837                    var hasListing = visibleLocations.has(latlngStr);
838                    if (hasListing) {
839                        if (visibleLocations.get(latlngStr)) {
840                            markers[markerId].setMap(null);
841                            visibleLocations.set(latlngStr, false);
842                        }
843                    }
844                }
845            }
846        }
847    }
848
849    if (listingWithInBound < 1 && googleMapView) {
850        if (googleMapView.getZoom() > 10) {
851            googleMapView.setZoom(10);
852            googleMapView.setCenter({ lat: 40.757263, lng: -73.9500303 })
853        }
854
855    }
856
857    if (isMapView) {
858        // if (markerCluster) {
859        //     markerCluster.clearMarkers();
860        // }
861
862        // var mcOptions = { 
863        //     styles: [{
864        //         height: 2,
865        //         url: "cluster_images/m1.png",
866        //         width: 53
867        //       }
868        //     ]
869        //   }
870        // markerCluster = new MarkerClusterer(googleMapView, markerMatched,
871        //     mcOptions);
872    }
873    clearListingUiAndAddNewListings(listingsToShow);
874}
875
876function videoClicked(element) {
877    mixpanel.track("more_info_clicked", { "listing": element.href, "source": "web" });
878}
879
880function FShandler(element) {
881    var currentObjectFitState = element.srcElement.style.objectFit;
882    if (currentObjectFitState === "" || currentObjectFitState === "contain") {
883        element.srcElement.style.objectFit = "cover";
884    } else {
885        element.srcElement.style.objectFit = "contain";
886    }
887}
888
889function checkAvailabilityClicked(element) {
890
891    // Get the <span> element that closes the modal
892    var span = document.getElementsByClassName("close")[0];
893
894    modal.style.display = "block";
895
896    // When the user clicks on <span> (x), close the modal
897    span.onclick = function () {
898        modal.style.display = "none";
899    }
900
901    // When the user clicks anywhere outside of the modal, close it
902    window.onclick = function (event) {
903        if (event.target == modal) {
904            modal.style.display = "none";
905        }
906    }
907}
908
909function sendEmailToAgent(element) {
910    var pop = element.parentElement.parentElement;
911    var listingId = document.getElementById("contactModal").getAttribute("data-listingid")
912    // var agentEmail = totalListings.get(listingId).agent.email;
913    var agentName = totalListings.get(listingId).agent.first.trim();
914    var inputs = pop.getElementsByTagName('input');
915    var messageSender = inputs[0].value;
916    var messengerEmail = inputs[1].value;
917    var messengerPhone = inputs[2].value;
918    var messageToAgent = pop.getElementsByTagName('textarea')[0].value;
919    var apartmentViewed = "https://replaylistings.com/listing/" + listingId;
920    var messageUrl = window.location.href;
921
922    if (messageToAgent === "" || messengerEmail === "") {
923        // todo analytics
924    } else {
925        $.ajax({
926            url: "https://us-central1-replaylistings-95421.cloudfunctions.net/sendEmail",
927            contentType: 'text/plain',
928            type: 'POST',
929            data: JSON.stringify({ "messageSender": messageSender, "messageSent": messageToAgent, "apartmentViewed": apartmentViewed, "agentName": agentName, "messageUrl": messageUrl, "messengerPhone": messengerPhone, "messengerEmail": messengerEmail, "agentEmail": agentEmail }),
930            success: function () {
931                // mixpanel.track("email_by_renter", { "Agent Email": agentEmail, "Sent By": messageSender, "ApartmentViewed": apartmentViewed, "source": "web" })
932                logAgentMessageSentEvent(agentEmail, messageSender, apartmentViewed, messengerEmail, messengerPhone);
933            },
934            error: function (error) {
935                // todo log message in mixpanel
936            }
937        });
938        $('#contactModal').modal('hide')
939    }
940}
941
942async function onBedSelected(event) {
943    var choosenFilter = event.getAttribute('id');
944    var isChecked = event.checked;
945    var mappingBed;
946    switch (choosenFilter) {
947        case "studio":
948            mappingBed = "0";
949            break;
950        case "oneBed":
951            mappingBed = "1";
952            break;
953        case "twoBed":
954            mappingBed = "2";
955            break;
956        default:
957            mappingBed = "3";
958            break;
959    }
960
961    if (isChecked) {
962        f_bed.add(mappingBed);
963    } else {
964        f_bed.delete(mappingBed);
965    }
966
967    mixpanel.track("quick_search_bed", { "bed count": choosenFilter, "checked": isChecked, "source": "web" });
968
969    updateBedSelectedUi();
970    applyFilterNew();
971}
972
973function updateBedSelectedUi() {
974    var txtElement = document.getElementById('txtBedSize');
975    if (f_bed.size == 0) {
976        txtElement.innerHTML = "Bedroom Size";
977        if (txtElement.parentElement.classList.contains('pbpink')) {
978            txtElement.parentElement.classList.remove('pbpink');
979        }
980    } else {
981        var beds = Array.from(f_bed).join(',');
982        txtElement.innerHTML = "Bedroom Size: " + beds;
983        if (!txtElement.parentElement.classList.contains('pbpink')) {
984            txtElement.parentElement.classList.add('pbpink');
985        }
986    }
987}
988
989function onBathSelected(event) {
990    var choosenFilter = event.getAttribute('id');
991    var isChecked = event.checked;
992    var mappingBath;
993    switch (choosenFilter) {
994        case "oneBath":
995            mappingBath = "1";
996            break;
997        case "twoBath":
998            mappingBath = "2";
999            break;
1000        default:
1001            mappingBath = "3";
1002            break;
1003    }
1004    if (isChecked) {
1005        f_bath.add(mappingBath);
1006    } else {
1007        f_bath.delete(mappingBath);
1008    }
1009
1010    mixpanel.track("quick_search_bath", { "bath count": mappingBath, "checked": isChecked, "source": "web" });
1011
1012    updateBathSelectedUi();
1013    applyFilterNew();
1014}
1015
1016function updateBathSelectedUi() {
1017    var txtElement = document.getElementById('txtBathSize');
1018    if (f_bath.size == 0) {
1019        txtElement.innerHTML = "Bathrooms";
1020        if (txtElement.parentElement.classList.contains('pbpink')) {
1021            txtElement.parentElement.classList.remove('pbpink');
1022        }
1023    } else {
1024        var beds = Array.from(f_bath).join(',');
1025        txtElement.innerHTML = "Bathrooms: " + beds;
1026        if (!txtElement.parentElement.classList.contains('pbpink')) {
1027            txtElement.parentElement.classList.add('pbpink');
1028        }
1029    }
1030}
1031
1032function onPriceSelected(event) {
1033    var choosenFilter = event.getAttribute('value');
1034    var isAnyPrice = false;
1035    var mappingPrice = "";
1036    var text = event.nextElementSibling.innerText;
1037    onPriceSelectedTrigger(choosenFilter, text, isAnyPrice);
1038}
1039
1040function onPriceSelectedTrigger(choosenFilter, text, isAnyPrice) {
1041    switch (choosenFilter) {
1042        case "1":
1043            isAnyPrice = true;
1044            f_maxPrice = 9999999999999;
1045            f_minPrice = 1000;
1046            f_priceCategory = "";
1047            break;
1048        case "2":
1049            f_maxPrice = isSales ? 1000000 : 3000;
1050            f_minPrice = 0;
1051            // mappingPrice = "Below $3,000";
1052            f_priceCategory = "priceA"
1053            break;
1054        case "3":
1055            f_maxPrice = isSales ? 3000000 : 4000;
1056            f_minPrice = isSales ? 1000000 : 3000;
1057            // mappingPrice = "$3,000 - $4000";
1058            f_priceCategory = "priceB"
1059            break;
1060        case "4":
1061            f_maxPrice = isSales ? 5000000 : 5000;
1062            f_minPrice = isSales ? 3000000 : 4000;
1063            // mappingPrice = "$4,000 - $5,000";
1064            f_priceCategory = "priceC"
1065            break;
1066        case "5":
1067            f_maxPrice = 9999999999999;
1068            f_minPrice = isSales ? 5000000 : 5000;
1069            // mappingPrice = "Above $5,000";
1070            f_priceCategory = "priceD"
1071            break;
1072    }
1073
1074    mappingPrice = text;
1075
1076    var txtElement = document.getElementById('txtPrice');
1077    if (isAnyPrice) {
1078        txtElement.innerHTML = "Price";
1079        if (txtElement.parentElement.classList.contains('pbpink')) {
1080            txtElement.parentElement.classList.remove('pbpink');
1081        }
1082    } else {
1083        txtElement.innerHTML = "Price: " + mappingPrice;
1084        if (!txtElement.parentElement.classList.contains('pbpink')) {
1085            txtElement.parentElement.classList.add('pbpink');
1086        }
1087    }
1088
1089    mixpanel.track("quick_search_price", { "minprice": f_minPrice, "maxprice": f_maxPrice, "source": "web" });
1090
1091    applyFilterNew();
1092}
1093
1094function onAmenitiesSelected(event) {
1095    var choosenFilter = event.getAttribute('id');
1096    var isChecked = event.checked;
1097    var mappingAmenity = choosenFilter;
1098
1099    if (isChecked) {
1100        f_amenities.add(mappingAmenity);
1101    } else {
1102        f_amenities.delete(mappingAmenity);
1103    }
1104
1105    mixpanel.track("quick_search_amenity", { "amenity": mappingAmenity, "checked": isChecked, "source": "web" });
1106
1107    var txtElement = document.getElementById('txtAmenities');
1108    if (f_amenities.size == 0) {
1109        txtElement.innerHTML = "Amenities";
1110        if (txtElement.parentElement.classList.contains('pbpink')) {
1111            txtElement.parentElement.classList.remove('pbpink');
1112        }
1113    } else {
1114        var amenities = Array.from(f_amenities).join(',');
1115        txtElement.innerHTML = "Amenities: " + amenities.toLowerCase();
1116        if (!txtElement.parentElement.classList.contains('pbpink')) {
1117            txtElement.parentElement.classList.add('pbpink');
1118        }
1119    }
1120    applyFilterNew();
1121}
1122
1123
1124
1125function applyFilterNew() {
1126    console.log("apply new filter");
1127    loadListingsWithInBound(initialLoading);
1128}
1129
1130function listingMatchedFilter(listing) {
1131    var price = listing.rentAmount;
1132    var bed = listing.bedroom.trim();
1133    if (bed > 3)
1134        bed = 3;
1135    var bath = listing.bathroom.trim();
1136    if (bath > 3)
1137        bath = 3;
1138
1139    var matchedBed = true;
1140    var matchedBath = true;
1141    var matchedPrice = true;
1142    var matchedAmenities = true;
1143
1144    if (f_bed.size > 0) {
1145        matchedBed = f_bed.has(bed);
1146    }
1147
1148    if (f_bath.size > 0) {
1149        matchedBath = f_bath.has(bath);
1150    }
1151
1152    if (f_priceCategory !== "") {
1153        matchedPrice = price >= f_minPrice && price <= f_maxPrice;
1154    }
1155
1156    var listingAmenities = listing.amenities;
1157
1158    if (f_amenities.size > 0) {
1159        if (!listingAmenities) {
1160            matchedAmenities = false;
1161        } else {
1162            matchedAmenities = Array.from(f_amenities).every(val => listingAmenities.includes(val));
1163        }
1164    }
1165
1166    if (matchedBed && matchedBath && matchedPrice && matchedAmenities) {
1167        return true;
1168    } else {
1169        return false;
1170    }
1171}
1172
1173function resetFilter() {
1174    window.location.reload();
1175    mixpanel.track("Reset Filter.", { "source": "web" });
1176}
1177
1178function clearListingUiAndAddNewListings(listingsToShow) {
1179    document.getElementById('listingCollection').innerHTML = '';
1180    if (listingsToShow == '') {
1181        listingsToShow = `<div onmouseenter="onDivMouseOver(this)" class="listing 1.0-Bed 1-Bath priceB " id="-MSFVEVDWKjD2KMipNTT" data-markerid="0" style="height:100px;"><div class="chip"><a><img class="agentlogo" src="assets/images/Replay_Listings_Favicon.png" alt="Person"></a><a class="agent single-line" target="_blank">Replay Listings</a></div> <div class="footer" style="
1182       padding-top: 10px;
1183   "><a onclick="singleListingClicked(this)" href="https://replaylistings.com/sales?id=-MSFVEVDWKjD2KMipNTT" class="address single-line">No matching listings found.</a><div></div><div class="bed-bath">Try other filter.</div><div class="gap"></div><a class="btn pbblue check-availability" role="button" onClick="resetFilter()"><span class="mdc-button__ripple"></span>Clear Filter</a></div></div>`;
1184    }
1185
1186    $(".listings").append(listingsToShow);
1187}
1188
1189function onMapToggled(event) {
1190    lastScroll = 0;
1191    if (event.checked) {
1192        isMapView = true;
1193        document.getElementById("body-div").classList.remove('body-grid');
1194        mixpanel.track("show map view", { "source": "web" });
1195    } else {
1196        document.getElementById("body-div").classList.add('body-grid');
1197        mixpanel.track("show grid view", { "source": "web" });
1198        isMapView = false;
1199    }
1200}
1201
1202function setModal() {
1203    $('#contactModal').on('show.bs.modal', function (e) {
1204        modal = document.getElementById("contactModal");
1205
1206        $("#id_validationError").hide();
1207        var listingAndAgentId = e.relatedTarget.parentElement.parentElement.id.split(",");
1208        if (listingAndAgentId[0]) {
1209            var listId = listingAndAgentId[0];
1210            document.getElementById("contactModal").setAttribute("data-listingid", listId)
1211            var agentInfo = totalListings.get(listId).agent;
1212            if (agentInfo.profilePhoto != "")
1213                document.getElementById("id_agentImageMdl").src = agentInfo.profilePhoto;
1214            document.getElementById("id_agentNameMdl").innerText = agentInfo.first;
1215
1216            logCheckAvailabiltyClicked(listId, agentInfo.first);
1217        } else {
1218            document.getElementById("id_agentImageMdl").src = "assets/images/Replay_Listings_Favicon.png";
1219            document.getElementById("id_agentNameMdl").innerText = "Replay Listings";
1220        }
1221    })
1222}
1223
1224async function addNewListingUi(limit = 3) {
1225    console.log("add new litigs")
1226    mixpanel.track("listing_scrolled", { "source": "web" });
1227    var count = 0;
1228    var listingsToShow = '';
1229    for (var i = lastVisibleListingIndex + 1; i < markers.length; i++) {
1230
1231        if (count >= limit)
1232            break;
1233
1234        var key = markers[i].listingId;
1235
1236        var c_listing = totalListings.get(key);
1237        var markerId = listingMarker.get(key);
1238        if ((googleMapView && googleMapView.getBounds().contains(markers[i].getPosition())) || isMobile || !isMapView) {
1239
1240            if (listingMatchedFilter(c_listing)) {
1241                count++;
1242                listingsToShow += await createListing(c_listing, false, i);
1243                count++
1244                lastVisibleListingIndex = i;
1245            }
1246        }
1247    }
1248
1249    $(".listings").append(listingsToShow);
1250}
1251
1252
1253// START: tracking logs mixpanel and google tags
1254function singleListingClicked(element) {
1255    // todo log in mixpanel
1256    mixpanel.track("listing_detail_viewed", { "Listing URL": element.href, "source": "web" });
1257}
1258
1259function agentPageViewed(element) {
1260    // todo log in mixpanel
1261    mixpanel.track("agent_profile_viewed", { "Agent URL": element.href, "source": "web" });
1262}
1263
1264function onNeighborhoodQuickSearch(element) {
1265    mixpanel.track("quick_search_subneighborhood", { "subneighborhood": element.value, "source": "web" });
1266}
1267
1268function viewOldPageClicked(element) {
1269    mixpanel.track("view_old_page", { "url": element.href, "source": "web" });
1270}
1271
1272function itunesLinkPressed() {
1273    mixpanel.track("download_from_itunes_clicked", { "source": "web" });
1274}
1275
1276function navCicked(element) {
1277    mixpanel.track("top_navigation_clicked", { "Clicked Nav": element.innerText, "Link": element.href, "source": "web" });
1278}
1279
1280function socialMediaCicked(element) {
1281    mixpanel.track("social_media_clicked", { "Clicked Nav": element.innerText, "Link": element.href, "source": "web" });
1282}
1283
1284function onVideoPlayed(element) {
1285    var videoListing = totalListings.get(element.parentElement.parentElement.parentElement.id);
1286    mixpanel.track("play_video_by_renters", { "listingId": element.parentElement.parentElement.id, "source": "web", "neighborhood": videoListing.address.subNeighborhood, "company": videoListing.agent.company, "borough": videoListing.address.neighborhood, "agent": videoListing.agent, "amenities": videoListing.amenities, "bed": videoListing.bedroom, "bath": videoListing.bathroom, "rent": videoListing.rentAmount, "agent_name": videoListing.agent.firstName });
1287}
1288
1289function infowindowOpnedEvent(listingId, agentName) {
1290    mixpanel.track("info_window_opned", { "listing_id": listingId, "agentName": agentName, "source": "web" });
1291}
1292
1293function playStoreLinkPressed() {
1294    gtag('event', 'conversion', {
1295        'send_to': 'AW-458725521/_zSmCIvJqu4BEJGx3toB',
1296        'type': "download from android play store",
1297        'source': 'web',
1298        "page": "map view"
1299    });
1300    mixpanel.track("download_from_play_store_clicked", { "source": "web", "page": "map view" });
1301}
1302
1303function itunesLinkPressed() {
1304    gtag('event', 'conversion', {
1305        'send_to': 'AW-458725521/S78hCN2xiu4BEJGx3toB',
1306        'type': "download from apple store",
1307        'source': 'web',
1308        "page": "map view"
1309    });
1310    mixpanel.track("download_from_apple_store_clicked", { "source": "web", "page": "map view" });
1311}
1312
1313function logCheckAvailabiltyClicked(listingId, agentName) {
1314    gtag('event', 'conversion', {
1315        'send_to': 'AW-458725521/XX3WCPGMqe4BEJGx3toB',
1316        'listingId': listingId,
1317        'agentName': agentName,
1318        'source': 'web',
1319        "page": "map view"
1320    });
1321
1322    mixpanel.track("check_availability_clicked", { "listing_id": listingId, "agent_name": agentName, "source": "web", "page": "map view" });
1323}
1324
1325function logAgentMessageSentEvent(agentEmail, messageSender, apartmentViewed, messengerEmail, messengerPhone) {
1326    gtag('event', 'conversion', {
1327        'send_to': 'AW-458725521/FhcNCKKDtvMBEJGx3toB',
1328        'eventname': "Contacted Agent",
1329        'agentEmail': agentEmail,
1330        'messengerEmail': messengerEmail,
1331        'messengerPhone': messengerPhone,
1332        'source': 'web',
1333        "page": "map view"
1334    });
1335    mixpanel.track("email_by_renter", {
1336        "Agent Email": agentEmail, "Sent By": messageSender, "ApartmentViewed": apartmentViewed,
1337        "messengerEmail": messengerEmail, "messengerPhone": messengerPhone, "source": "web", "page": "map view"
1338    })
1339
1340}
1341
1342// END: tracking logs mixpanel and google tags
1343
1344
1345function reloadPage(type) {
1346    var baseUrl = window.location.pathname;
1347    baseUrl = baseUrl + "?type=" + type;
1348    location.href = baseUrl;
1349    mixpanel.track("web_page_load", { "source": "web", "page": "sales main page" });
1350}
1351
1352
1353function onDivMouseOver(src) {
1354
1355    var videoTag = src.querySelector('video');
1356    try {
1357        if (videoTag.paused) {
1358            videoTag.play();
1359        } else {
1360            videoTag.pause();
1361        }
1362    } catch (err) {
1363
1364    }
1365}
1366
1367
1368function appendParameters(key, value) {
1369
1370}
1371
1372function numberWithCommas(x) {
1373    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1374}
1375
1376function priceSaleRange(price) {
1377    var priceFilter = "priceA";
1378    if (price <= 1000000) {
1379        priceFilter = "priceA";
1380    } else if (price > 1000000 && price <= 3000000) {
1381        priceFilter = "priceB";
1382    } else if (price > 3000000 && price <= 5000000) {
1383        priceFilter = "priceC";
1384    } else if (price > 5000000) {
1385        priceFilter = "priceD";
1386    }
1387    return priceFilter;
1388}
1389
1390function priceRentalRange(price) {
1391    var priceFilter = "A";
1392    var index = "2";
1393    if (price <= 3000) {
1394        priceFilter = "A";
1395    } else if (price > 3000 && price <= 4000) {
1396        priceFilter = "B";
1397        index = "3";
1398    } else if (price > 4000 && price <= 5000) {
1399        priceFilter = "C";
1400        index = "4";
1401    } else if (price > 5000) {
1402        priceFilter = "D";
1403        index = "5";
1404    }
1405    return [priceFilter, index];
1406}

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.