PageSourceSearch

https://www.mypremierproperty.com/myportal/collections

html mypremierproperty.com collected 2026-09-28 15:04:17 UTC 145,169 bytes, 2,423 lines download raw bytes

1<!DOCTYPE html> <html lang="en"> <head><meta name="description" content=""> <meta charset="utf-8"> <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="msvalidate.01" content="52D8CD5F9EA2B1031F2D2472023A5D34"> <title>MyPortal | Collections</title> 
1<script type="application/ld+json">{"@context":"https:\/\/schema.org","@type":"LocalBusiness","name":"Premier Property Solutions | Charlotte, NC","url":"https:\/\/www.mypremierproperty.com","image":"https:\/\/cdn1.brivityidx.com\/assets\/images\/agent-photos\/1\/3\/8\/13850089\/place-logo.png","telephone":"+17042860506","address":{"@type":"PostalAddress","streetAddress":"14045 Ballantyne Corporate Place Suite 500","addressLocality":"Charlotte","addressRegion":"NC","postalCode":"28277","addressCountry":"US"},"sameAs":["https:\/\/www.facebook.com\/MyPremierProperty\/","https:\/\/www.instagram.com\/premierproperty_solutions\/"]}</script>
1 <link rel="preconnect" href="https://www.google.com"> <link rel="preconnect" href="https://www.gstatic.com" crossorigin> <link rel="dns-prefetch" href="https://cdn1.brivityidx.com"> 
1<script>
2            var head = document.getElementsByTagName('head')[0]
3            var insertBefore = head.insertBefore;
4            head.insertBefore = function (newElement, referenceElement) {
5                // intercept style elements for IEs
6                if (newElement.tagName.toLowerCase() === 'style'
7                    && newElement.styleSheet
8                    && newElement.styleSheet.cssText
9                    && newElement.styleSheet.cssText.replace('\r\n', '').indexOf('.gm-style') === 0) {
10                    return;
11                }
12                // intercept style elements for other browsers
13                if (newElement.tagName.toLowerCase() === 'style'
14                    && newElement.innerHTML
15                    && newElement.innerHTML.replace('\r\n', '').indexOf('.gm-style') === 0) {
16                    return;
17                }
18                insertBefore.call(head, newElement, referenceElement);
19            }; 
20        </script>
20 <link rel="shortcut icon" href="https://cdn1.brivityidx.com/assets/images/uploads/10784/favicon-new.ico" type="image/x-icon"> <link href="https://cdn1.brivityidx.com/assets/css/build-site.min.css?ck=" rel="stylesheet"> <link href="https://cdn1.brivityidx.com/assets/css/build-chatbot-v1.min.css?ck=" rel="stylesheet" media="print" onload="this.media='all'"><noscript><link href="https://cdn1.brivityidx.com/assets/css/build-chatbot-v1.min.css?ck=" rel="stylesheet"></noscript> <link rel="canonical" href="https://www.mypremierproperty.com/myportal/collections"> 
20<script>
21            function deferScriptOnLoad(url, sleep = 0) {
22                window.addEventListener('load', function () {
23                    deferScript(url, sleep);
24                });
25            }
26            function deferScript(url, sleep = 0) {
27                if (sleep > 0) {
28                    setTimeout(() => {
29                        deferScript(url);
30                    }, sleep);
31                    return;
32                }
33                let s = document.createElement('script');
34                s.type = 'text/javascript';
35                s.async = true;
36                s.src = url;
37                let x = document.getElementsByTagName('head')[0];
38                x.appendChild(s);
39            }
40
41            /* PLACE_COMPONENTS_LOADER_START */
42            window.sitebuilderPlaceComponents = (function () {
43                var DEFAULT_URL = 'https://mobile-component-services-library-dev.brivity.com/web-components.min.js?ck=1';
44                var BUNDLE_URLS = { default: DEFAULT_URL };
45                var loadPromises = {};
46                var LOAD_TIMEOUT_MS = 10000;
47
48                function urlForTag(tagName) {
49                    return BUNDLE_URLS[tagName] || BUNDLE_URLS.default;
50                }
51
52                function ensureLoaded(tagName) {
53                    var url = urlForTag(tagName);
54                    if (loadPromises[url]) {
55                        return loadPromises[url];
56                    }
57                    loadPromises[url] = new Promise(function (resolve, reject) {
58                        var settled = false;
59                        var timer = setTimeout(function () {
60                            if (settled) return;
61                            settled = true;
62                            reject(new Error('web-components load timeout'));
63                        }, LOAD_TIMEOUT_MS);
64                        var s = document.createElement('script');
65                        s.type = 'text/javascript';
66                        s.async = true;
67                        s.src = url;
68                        s.onerror = function () {
69                            if (settled) return;
70                            settled = true;
71                            clearTimeout(timer);
72                            reject(new Error('web-components script onerror'));
73                        };
74                        document.getElementsByTagName('head')[0].appendChild(s);
75                        if (window.customElements && customElements.whenDefined) {
76                            customElements.whenDefined(tagName).then(function () {
77                                if (settled) return;
78                                settled = true;
79                                clearTimeout(timer);
80                                resolve();
81                            });
82                        }
83                    });
84                    return loadPromises[url];
85                }
86
87                var EAGER_SELECTOR = 'place-propertycard, place-searchpagefilter, place-bedbathfiltermodal, ' +
88                                     'place-listingstatusmodal, place-propertytypemodal, place-savesearchmodal, ' +
89                                     'place-basicmodal, place-details, place-agentbio, place-agentmessaging, ' +
90                                     'place-contactyouragent, place-menu, place-collectionpopup, ' +
91                                     'place-copycollectionmodal, place-removecollectionpopup, place-vs-accumulate';
92
93                function warmIfEagerTagsPresent() {
94                    if (document.querySelector(EAGER_SELECTOR)) {
95                        ensureLoaded('place-propertycard').catch(function () {});
96                    }
97                }
98                if (document.readyState === 'loading') {
99                    document.addEventListener('DOMContentLoaded', warmIfEagerTagsPresent);
100                } else {
101                    warmIfEagerTagsPresent();
102                }
103
104                var INTERACTION_SELECTOR = 'place-getyourhomecta, place-generictoast, ' + EAGER_SELECTOR +
105                                           ', [data-needs-place-components]';
106                function onInteract(e) {
107                    var t = e.target;
108                    if (t && t.closest && t.closest(INTERACTION_SELECTOR)) {
109                        ensureLoaded('place-generictoast').catch(function () {});
110                    }
111                }
112                document.addEventListener('pointerdown', onInteract, true);
113                document.addEventListener('focusin', onInteract, true);
114
115                function idleWarm() {
116                    ensureLoaded('place-generictoast').catch(function () {});
117                }
118                if ('requestIdleCallback' in window) {
119                    requestIdleCallback(idleWarm, { timeout: 5000 });
120                } else {
121                    setTimeout(idleWarm, 3000);
122                }
123
124                return { ensureLoaded: ensureLoaded };
125            })();
126            /* PLACE_COMPONENTS_LOADER_END */
127
128            const googleApiKey = 'AIzaSyAjpuNg6WGCMV5rzoJcIP2QmMTVto6hYmc'
129
130            /* Lazy loader for Google Maps API + turf.js.
131             * The TURF_INLINE / MAPS_API_INLINE placeholders below are emitted by
132             * Sitemodel.php only on pages whose blocks actually consume Maps/turf.
133             * On other pages those tags are stripped, and consumers call
134             * sitebuilderMapsApi.ensureLoaded() to inject them on demand.
135             *
136             * Safari fix vs. the prior reverted attempt (commit 0cef3135e): uses
137             * Google's official &callback= parameter, not setTimeout, to detect
138             * Maps readiness.
139             */
140            window.sitebuilderMapsApi = (function () {
141                var TURF_URL = 'https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js';
142                var MAPS_URL = 'https://maps.googleapis.com/maps/api/js?libraries=geocoding,places,marker,drawing&key=' +
143                               googleApiKey + '&map_ids=85c127b7bf0255d9&callback=__sitebuilderMapsReady';
144                var LOAD_TIMEOUT_MS = 15000;
145                var loadPromise = null;
146
147                function injectScript(url) {
148                    var s = document.createElement('script');
149                    s.type = 'text/javascript';
150                    s.async = true;
151                    s.src = url;
152                    document.getElementsByTagName('head')[0].appendChild(s);
153                    return s;
154                }
155
156                function loadTurf() {
157                    return new Promise(function (resolve, reject) {
158                        if (window.turf) { resolve(); return; }
159                        var s = injectScript(TURF_URL);
160                        s.onload = function () { resolve(); };
161                        s.onerror = function () { reject(new Error('turf load failed')); };
162                    });
163                }
164
165                function loadMaps() {
166                    return new Promise(function (resolve, reject) {
167                        if (window.google && window.google.maps) { resolve(); return; }
168                        window.__sitebuilderMapsReady = function () { resolve(); };
169                        var s = injectScript(MAPS_URL);
170                        s.onerror = function () { reject(new Error('maps load failed')); };
171                    });
172                }
173
174                function ensureLoaded() {
175                    if (loadPromise) return loadPromise;
176                    if (window.google && window.google.maps && window.turf) {
177                        loadPromise = Promise.resolve();
178                        return loadPromise;
179                    }
180                    loadPromise = new Promise(function (resolve, reject) {
181                        var settled = false;
182                        var timer = setTimeout(function () {
183                            if (settled) return;
184                            settled = true;
185                            reject(new Error('maps/turf load timeout'));
186                        }, LOAD_TIMEOUT_MS);
187                        Promise.all([loadTurf(), loadMaps()]).then(function () {
188                            if (settled) return;
189                            settled = true;
190                            clearTimeout(timer);
191                            resolve();
192                        }, function (err) {
193                            if (settled) return;
194                            settled = true;
195                            clearTimeout(timer);
196                            reject(err);
197                        });
198                    });
199                    return loadPromise;
200                }
201
202                return { ensureLoaded: ensureLoaded };
203            })();
204        </script>
204 <link href="https://cdn1.brivityidx.com/assets/css/style-headers.min.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-premium.min.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/assets/css/style-footers.css" rel="stylesheet"><link href="https://cdn1.brivityidx.com/idx-sites/1/3/5/13574/site_custom.css?v=1789579409" rel="stylesheet">
204<script type="text/javascript" src="https://cdn1.brivityidx.com/idx-sites/1/3/5/13574/global_js_variables.js?v=1789579409"></script>
204<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Oswald:wght@200;500;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://use.typekit.net/psh7aoo.css"> 
204<script type="application/ld+json">
205{"@context":"https://schema.org","@type":"RealEstateAgent","name":"Premier Property Solutions","description":"Full-service residential real estate team serving the greater Charlotte metro in NC and SC — buying and selling, from Mooresville to Clover. Premier Property Solutions has closed more than $500 million in sales volume across more than 1,300 transaction sides, per Canopy MLS agent production reports run in August 2026.","url":"https://www.mypremierproperty.com","telephone":"(704) 286-0506","email":"[email protected]","address":{"@type":"PostalAddress","streetAddress":"14045 Ballantyne Corporate Place Suite 500","addressLocality":"Charlotte","addressRegion":"NC","postalCode":"28277","addressCountry":"US"},"areaServed":["Charlotte NC","Ballantyne","SouthPark","Matthews NC","Mint Hill NC","Huntersville NC","Cornelius NC","Davidson NC","Mooresville NC","Lake Norman","Concord NC","Kannapolis NC","Gastonia NC","Belmont NC","Waxhaw NC","Weddington NC","Monroe NC","Indian Trail NC","Fort Mill SC","Tega Cay SC","Rock Hill SC","Lake Wylie SC","Clover SC","Indian Land SC"],"foundingDate":"2015", "award": "RealTrends Verified 2026 — ranked #4 among large teams in Charlotte, NC by sales volume, based on 2025 production","founder":{"@type":"Person","name":"Nicole McAlister","jobTitle":"Founder & Team Leader","url":"https://www.mypremierproperty.com/agent-profile/nicole-mcalister-13853499","description":"Founder and team leader of Premier Property Solutions, a real estate team affiliated with Ballantyne Area Market Center LLC (Keller Williams Realty; each office is independently owned and operated). Premier Property Solutions is a registered trade name of McAlisters Homes LLC, NCREC firm licence C26713. NC broker licence 279893.","identifier":[{"@type":"PropertyValue","propertyID":"NC Real Estate License","value":"279893"},{"@type":"PropertyValue","propertyID":"SC Real Estate License","value":"89383"}],"sameAs":["https://www.zillow.com/profile/NMcAlister","https://www.linkedin.com/in/nicolemcalisterrealtor/","https://www.instagram.com/nicolethecarolinasrealtor/","https://kw.com/agent/nicole-mcalister/356894"]},"sameAs":["https://www.facebook.com/MyPremierProperty/","https://www.instagram.com/premierproperty_solutions/","https://www.zillow.com/profile/MyPremierProperty/","https://www.homes.com/real-estate-agents/nicole-mcalister/jq109p5/"]}
206</script>
vendor: 64 bytes, line 206
206 <script async src="https://www.googletagmanager.com/gtag/js?id=
206G-6CDT83D19B
vendor: 12 bytes, line 206
206"></script> 
206<script>
207  
vendor: 134 bytes, lines 207-211
207window.dataLayer = window.dataLayer || [];
208  function gtag(){dataLayer.push(arguments);}
209  gtag('js', new Date());
210
211  gtag('config', '
211G-6CDT83D19B
vendor: 4 bytes, line 211
211');
212</script>
212 
212<script>
213var propDetailsPixelOnReady = function(){
214  let propDetFpst = new FbRealEstatePixelTracker({"eventType": "ViewContent", "content_ids": [""]});
215  propDetFpst.fireEvent();
216};
217if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) {
218  propDetailsPixelOnReady();
219} else {
220  document.addEventListener("DOMContentLoaded", propDetailsPixelOnReady);
221}
222
223</script>
223 
223<script>
vendor: 327 bytes, lines 223-227
223(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
224new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
225j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
226'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
227})(window,document,'script','dataLayer','
227GTM-WDHHMSP
vendor: 3 bytes, line 227
227');
227</script>
227 <meta name="google-site-verification" content="xsYLKtmmfSVuInIjmlwFAx5xCQmyB7tNOHBcE26by3Y" /> <meta property="og:url" content="https://www.mypremierproperty.com/myportal/collections"> <meta property="og:image" content="http://images.brivityidx.com/assets/images/uploads/10784/dreamstead-og-new.png"> <meta property="og:image:secure_url" content="https://images.brivityidx.com/assets/images/uploads/10784/dreamstead-og-new.png"> <meta property="og:description" content=""> <meta property="og:title" content="MyPortal | Collections"> </head> <body>
vendor: 68 bytes, line 227
227 <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
227GTM-WDHHMSP
vendor: 83 bytes, line 227
227" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> 
227<script>
228                  window.fbAsyncInit = function() {
229                    FB.init({
230                      appId      : '1',
231                      cookie     : true,
232                      xfbml      : true,
233                      version    : 'v17.0'
234                    });
235                    FB.AppEvents.logPageView();
236                  };
237
238                  setTimeout(() => {(function(d, s, id){
239                     var js, fjs = d.getElementsByTagName(s)[0];
240                     if (d.getElementById(id)) {return;}
241                     js = d.createElement(s); js.id = id;
242                     js.defer = true;
243                     js.xfbml = false;
244                     js.src = "//connect.facebook.net/en_US/sdk.js";
245                     fjs.parentNode.insertBefore(js, fjs);
246                   }(document, 'script', 'facebook-jssdk'))}, 5000);
247                </script>
247<meta property="fb:app_id" content="1"><meta name="google-signin-client_id" content="1"><meta name="apple-signin-flag" content="1"><meta name="main_sitebuilder_domain" content="https://sitebuilder.brivity.com"> <div id="site-registration-bar" class="collapse"> <input type="hidden" id="huser_id" value=""> <div class="row" style="width: 100%; margin: 0;"> <div class="col-md-12" style="display: none;" id="logged-in"> <div class="topBar flex aiCenter jcBetween"> <div class="topBarLeft flex aiCenter"> <span><topbar_show_agent_name/></span> </div> <div class="topBarRight flex aiCenter"> <a class="topLink flex aiCenter thin favoritesTop" href="/myportal/collections"> <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_16761_179132)"> <path d="M14.2659 3.57333C13.9254 3.23267 13.5211 2.96243 13.0761 2.77806C12.6312 2.59368 12.1542 2.49878 11.6726 2.49878C11.1909 2.49878 10.714 2.59368 10.269 2.77806C9.82401 2.96243 9.41973 3.23267 9.07922 3.57333L8.37256 4.28L7.66589 3.57333C6.97809 2.88554 6.04524 2.49914 5.07256 2.49914C4.09987 2.49914 3.16702 2.88554 2.47922 3.57333C1.79143 4.26113 1.40503 5.19398 1.40503 6.16667C1.40503 7.13936 1.79143 8.07221 2.47922 8.76L3.18589 9.46667L8.37256 14.6533L13.5592 9.46667L14.2659 8.76C14.6066 8.4195 14.8768 8.01521 15.0612 7.57024C15.2455 7.12526 15.3404 6.64832 15.3404 6.16667C15.3404 5.68501 15.2455 5.20807 15.0612 4.7631C14.8768 4.31812 14.6066 3.91384 14.2659 3.57333V3.57333Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> <defs> <clipPath id="clip0_16761_179132"> <rect width="16" height="16" fill="white" transform="translate(0.372559 0.5)"/> </clipPath> </defs> </svg> <span class="ml6 topLabel">Collections&nbsp;</span> </a> <a class="topLink flex aiCenter thin saveSearchTop" href="/myportal/searches"> <svg width="16" height="16" viewBox="0 4 20 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M19 21L12 16L5 21V5C5 4.46957 5.21071 3.96086 5.58579 3.58579C5.96086 3.21071 6.46957 3 7 3H17C17.5304 3 18.0391 3.21071 18.4142 3.58579C18.7893 3.96086 19 4.46957 19 5V21Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" /> </svg> <span class="ml6 topLabel">Saved Searches&nbsp;</span> </a> <a class="topLink flex aiCenter thin market-report-top" style="display:none" href="/myportal/reports"> <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M7.70589 13.1667C10.6514 13.1667 13.0392 10.7789 13.0392 7.83333C13.0392 4.88781 10.6514 2.5 7.70589 2.5C4.76037 2.5 2.37256 4.88781 2.37256 7.83333C2.37256 10.7789 4.76037 13.1667 7.70589 13.1667Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M14.3725 14.5L11.4725 11.6" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> <span class="ml6 topLabel">My Reports&nbsp;</span> </a> <a class="aiCenter flex topBarProfile thin" href="/myportal/profile"> <span class="profileName"></span> </a> <a style="padding-right: 0px" class="aiCenter flex thin" id="topBarLogout" href="javascript:void()"> <svg width="23" height="23" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_16761_179186)"> <path d="M16.4003 16.214C19.0038 13.6106 19.0038 9.38945 16.4003 6.78595C13.7968 4.18246 9.57572 4.18246 6.97222 6.78595C4.36873 9.38945 4.36873 13.6105 6.97222 16.214C9.57572 18.8175 13.7968 18.8175 16.4003 16.214Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9.80066 9.61438L13.5719 13.3856" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9.80066 13.3856L13.5719 9.61438" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </g> <defs> <clipPath id="clip0_16761_179186"> <rect width="16" height="16" fill="white" transform="translate(0.372559 11.5) rotate(-45)"/> </clipPath> </defs> </svg> <span class="ml6">Log Out</span> </a> </div> </div> </div> <div id="not-logged-in"> <topbar_agent_info_not_logged_in/> <ul class="list-unstyled list-inline no-margin"> <li class="topBarSignin"><a href="#" onclick="showGoogleOneTap(true);"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle mr10"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line>
247<line x1="8" y1="12" x2="16" y2="12"></line></svg> Sign In</a></li> </ul> </div> </div> </div> <input type="hidden" id="huser_email" value=""> <input type="hidden" id="huser_first_name" value=""> <input type="hidden" id="huser_last_name" value=""> <input type="hidden" id="huser_phone" value=""> <input type="hidden" id="huser_uuid" value=""> <div id="page" class="page"><header id="premium-navigation" class="vertical-nav" style=" outline: none; cursor: inherit;" data-selector="#premium-navigation"> <div class="main-nav"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse" style="outline: none; cursor: inherit;" data-selector="a.btn, button.btn, button"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/" style="outline: none; cursor: inherit;"> <img class="img-responsive site_custom_logo_dynamic" src="https://cdn1.brivityidx.com/assets/images/agent-photos/1/3/8/13850089/place-logo.png" alt="Premier Property Solutions logo" style="outline: none; cursor: inherit;" data-selector="img"> </a> </div> <div class="collapse navbar-collapse render-menu"><ul class="nav navbar-nav navbar-right"><li class="nav-item"><a class="sec-nav-link-color" href="/index">Home</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/search">Search</a></li><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Buying<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/buying">Searching With Us</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/the_home_buying_process">Home Buying Process</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/prepare_an_offer_in_nc">Prepare An Offer In NC</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/prepare_an_offer_in_sc">Prepare An Offer In SC</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/financing">Financing</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Selling<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/selling">Selling A Home</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/the_house_selling_process">House Selling Process</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/staging_guide">Staging Guide</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/receiving_offers">Receiving Offers</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/inspection">Inspection</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Top Areas<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?ulti_search=Charlotte,%20NC&amp;multi_cat=CityState&amp;propertyType=Condo/Townhome|Multi-Family|Residential&amp;status=1|3&amp;mlsId=102|352&amp;price=100000:&amp;multi_search=Charlotte,%20NC&amp;q_sort=createdAt-&amp;q_offset=0">Center City</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=28277&amp;multi_cat=Zip&amp;propertyType=Condo/Townhome|Multi-Family|Residential&amp;status=1|3&amp;mlsId=102|352&amp;price=100000:&amp;q_sort=createdAt-&amp;q_offset=0">Ballantyne</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=29715&amp;multi_cat=Zip&amp;propertyType=Condo/Townhome|Multi-Family|Residential&amp;status=1|3&amp;mlsId=102|352&amp;price=100000:&amp;q_sort=createdAt-&amp;q_offset=0">Fort Mill</a></li><li class="sec-nav-drop-color">
247<a class="sec-nav-drop-link-color" href="/search?multi_search=Huntersville,%20NC&amp;multi_cat=CityState&amp;propertyType=Condo/Townhome|Multi-Family|Residential&amp;status=1|3&amp;mlsId=102|352&amp;price=100000:&amp;q_sort=createdAt-&amp;q_offset=0">Huntersville</a></li><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/search?multi_search=Matthews,%20NC&amp;multi_cat=CityState&amp;propertyType=Condo/Townhome|Multi-Family|Residential&amp;status=1|3&amp;mlsId=102|352&amp;price=100000:&amp;q_sort=createdAt-&amp;q_offset=0">Matthews</a></li></ul><li class="nav-item dropdown"><a class="dropdown-toggle sec-nav-link-color" data-toggle="dropdown" data-hover="dropdown" data-delay="0" data-close-others="false">Resources<i class="fa fa-angle-down"></i></a><ul class="dropdown-menu"><li class="sec-nav-drop-color"><a class="sec-nav-drop-link-color" href="/home_maintenance_tips">Home Maintenance Tips</a></li></ul><li class="nav-item"><a class="sec-nav-link-color" href="/careers">Careers</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/realestateagent/search">Who We Are</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/blog">Blog</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/connect">Connect</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/the-real-estate-momentum">The Real Estate Momentum</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/homevalue">HomeValue</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/referring-agents">Referring Agents</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/relocating-to-charlotte">Relocating to Charlotte</a></li><li class="nav-item"><a class="sec-nav-link-color" href="/realtrends-verified">RealTrends Verified</a></li></ul></div> </div> </div> </header> <style> 
248       
249    .center-modal {
250        display:flex;
251        justify-content: center;
252        align-items:center;
253        position:fixed;
254        background-color:rgba(0,0,0,0.4);
255        left:0;
256        top:0;
257        right:0; 
258        bottom:0;
259        z-index: 300;
260    }
261
262    .page-width-parent{
263        max-width: 1280px;
264        margin: 0 auto;
265    }
266
267
268    .property-list-map-view {
269        display:flex;
270        flex-wrap:wrap;
271        gap:16px;
272    }
273    .property-list-map-view-parent {
274        background-color: #F9F9F9;
275        padding:16px;
276        height:710px;
277        overflow:scroll;
278    }
279
280    .property-list-list-view {
281        display:flex;
282        flex-wrap:wrap;
283        gap:24px
284    }
285
286    .property-container {
287        
288        gap:24px;
289    }
290
291    .property-map-container {
292        flex:1;
293        height:710px;
294    }
295
296    .property-pagination {
297        margin-top: 26px;
298    }
299
300    .collection-saved-listings {
301        margin-bottom: 26px;
302        font-size:16px;
303        color:black;
304    }
305
306    .collection-description {
307        padding: 20px 0 18px 8px;
308    }
309
310    .my-feed-parent {
311        margin-top:32px;
312        padding-top:32px; 
313        border-top: solid 1px #C4C4C4;
314    }
315
316    .collection-description-text {
317        font-size:16px;
318        margin:0;
319        color:black;
320    }
321
322    #collections {
323        display:flex;
324        flex-wrap:wrap;
325        gap:40px 24px;
326    }
327
328    #collection-pagination{
329        margin-top: 55px
330    }
331
332    #add-listing-btn{
333        margin-bottom: 20px
334    }
335
336    @media only screen and (min-width: 1280px) {
337        .collection-page {
338            padding:48px 48px 48px 120px;
339        }
340        .my-feed-parent {
341            width:90vw;
342            max-width: 100%;
343            overflow: hidden;
344        }
345        .property-list-map-view-parent {
346            width:500px;
347        }
348        .property-container {
349                display:flex;
350        }
351    }
352
353    @media only screen and (max-width:1280px) {
354        .collection-page {
355            padding:60px 16px 16px 16px;
356        }
357        .my-feed-parent {
358            width: unset;
359        }
360        .property-container {
361                display:flex;
362                flex-direction: column-reverse;
363        }
364        .property-list-map-view {
365            flex-wrap:nowrap;
366            overflow:scroll;
367            height:280px;
368        }
369        .property-list-map-view-parent {
370            height:unset;
371            padding:0px;
372            background-color: #FFFFFF
373        }
374        .property-map-container {
375            flex:none;
376            height:446px;
377        }
378    }
379
380    @media only screen and (max-width:768px) {
381        #collections {
382            justify-content: center;
383        }
384        .property-map-container {
385            width: calc(100% + 32px);
386            margin-left: -16px;
387        }
388        .property-list-map-view {
389            height:250px;
390        }
391    }
392
393</style> 
393<script>
394    window.addEventListener("load", () => {
395    const key = localStorage.getItem('authorization');
396     
397        if( !key) {
398            $("#sign-up-modal").modal('show');
399
400            $("#sign-up-modal").on("hidden.bs.modal", function () {
401                location.reload();
402            });
403        }
404        else{
405
406            let myPortalPage = document.getElementById('myportal-page');
407            myPortalPage.style.display = "block";
408
409            window.location.hash = ""
410
411            function isGuid(value) {    
412                var regex = /[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}/i;
413                var match = regex.exec(value);
414                return match != null;
415            }
416
417            let lastUrlItem = window.location.href.substring(window.location.href.lastIndexOf('/') + 1)
418            let showCollectionByUUID = false
419
420            if (isGuid(lastUrlItem)) {
421              showCollectionByUUID = true
422            } 
423
424          
425            class logger extends Collections.BaseLogger {
426                log(e) {
427                    console.log(e);
428                }
429            }
430
431
432            class Pubsub {
433                static events = {};
434                constructor() {
435                    //this.events = {};
436                }
437
438                static subscription (eventName, func) {
439                    return {
440                        subscribe: () => {
441                            if (this.events[eventName]) {
442                                this.events[eventName].push(func);
443                            } else {
444                                this.events[eventName] = [func];
445                            }
446                        },
447                        unsubscribe: () => {
448                            if(this.events[eventName]){
449                                this.events[eventName] = this.events[eventName].filter((subscriber) => subscriber !== func);
450                            }
451                        }
452                    }
453                } 
454
455                static publish(eventName, ...args) {
456                    const funcs = this.events[eventName];
457                    if (Array.isArray(funcs)) {
458                        funcs.forEach((func) => {
459                            func.apply(null, args);
460                        });
461                    }
462                }
463            }
464
465            class CollectionCard  {
466                constructor(collection, count){
467                    
468                    this.element = document.createElement(`place-collectioncard`);
469                    this.collection = collection
470                    let _this = this;
471                    let menuOpen = false;
472                    var images = [];
473                
474                    for (let i = 0; i < collection?.propertiesImages?.length; i++) {
475                        images.push(collection.propertiesImages[i].mainPhoto);
476                    }
477                
478                    this.element.setAttribute("appearance", "regular");
479                    this.element.setAttribute("image", images);
480                    this.element.setAttribute("num_properties", collection?.totalListings ?? 0)
481                    this.element.setAttribute("title", collection.collectionName);
482                    this.element.setAttribute("description", collection.collectionDescription ? collection.collectionDescription : collection.description ? collection.description : "");
483                    this.element.setAttribute("creator", "");
484                    this.element.setAttribute("disable_dropdown", "false");
485                    this.element.setAttribute("style", "height: 254px");
486                    this.element.setAttribute('z_index', count);
487                    this.element.setAttribute("show_menu", "false");
488                    this.element.setAttribute("id", collection.collectionUUID);
489                    this.element.setAttribute("container_styles", "w-[300px]");
490
491                    const collectionUUID = collection.collectionUUID;
492
493                    this.element.addEventListener(`on_menu_item_pressed`, (e) => {
494                        let menuItem = e.detail
495                        Pubsub.publish('collection_card_menu_item_pressed', {collection,menuItem});
496                    });
497
498                    this.element.addEventListener('on_search_pressed', (e) => {
499                        if (e.target.tagName != "svg" && e.target.tagName != "path") {
500                            window.open('../../search.php', '_blank');
501                            e.stopPropagation();
502                        }
503                    });
504                    
505                    this.element.addEventListener(`click`, (e) => {
506                        if (e.target.tagName != "svg" && e.target.tagName != "path" && !menuOpen) {
507                             Pubsub.publish('collection_card_pressed', {collection:_this.collection,e});
508                            e.stopPropagation();
509                        }
510                    });
511
512                    this.element.addEventListener(`on_menu_open`, (e) => {  
513                        if (this.element.getAttribute("title") === "Favorites") {
514                            this.element.setAttribute("disable_menu", "true");
515                        }
516
517                        menuOpen = e.detail;
518                        this.element.setAttribute("show_menu", menuOpen);
519                    });
520                }
521            }
522
523            class CollectionSection  {
524
525              
526                collectionSection = document.getElementById('collection-section')
527                collections = document.getElementById('collections')
528
529                addCollectionCard = (collection, count) => {
530                    const collectionCard = new CollectionCard(collection, count);
531
532
533                   
534                
535                   this.collections.append(collectionCard.element);
536                
537                } 
538
539                show = () => {
540                    this.collectionSection.style.display = 'block'
541                }
542
543                hide = () => {
544                    this.collectionSection.style.display = 'none'
545                }
546            }
547
548            class PropertyCard {
549                constructor(collectionUUID,property){
550                    
551                    let _this = this;
552                    this.element = document.createElement(`place-propertycard`);
553                    let menuOpen = false;
554                    this.property = property;
555 
556                    this.element.setAttribute("id", property.blossorId)
557                    this.element.setAttribute("display_menu", "true");
558                    this.element.setAttribute("show_menu", "false");
559                    this.element.setAttribute("items", '[{"icon":"share-2","text":"Share Property"},{"icon":"layers","text":"Copy to Collection"},{"icon":"trash","text":"Remove from Collection"}]');
560                    
561                    this.element.setAttribute('appearance','small')
562                    this.element.setAttribute('layout_width', '300')
563                    this.element.setAttribute('display_tag', 'true')
564                    this.element.setAttribute('display_favorite', 'true')
565                    this.element.setAttribute('mls',`{
566                        "status":"${property.statusText}", 
567                        "favorite":"true", 
568                        "image":[{"uri":"${property?.photos[0]?.url}"}], 
569                        "price":"${property?.price}",
570                        "address":"${property?.address?.street}",
571                        "state":"${property?.address?.state}", 
572                        "city":"${property?.address?.city}", 
573                        "postalCode":"${property?.address?.zip}", 
574                        "beds":"${property?.bedrooms}", 
575                        "baths":"${property?.totalBaths}",
576                        "sqft":"${property?.sqFeet}"
577                    }`)
578                    this.element.setAttribute('on_hover', 'true')
579
580                    this.element.addEventListener('mouseenter', (e) => {
581                        Pubsub.publish('property_card_mouseenter', property);
582                    })
583
584                    this.element.addEventListener('mouseleave', (e) => {
585                        Pubsub.publish('property_card_mouseleave', property);
586                    })
587
588                    this.element.addEventListener(`on_menu_item_pressed`, (e) => {
589                        let menuItem = e.detail
590                        let propertyCollectionUUID = property.propertyCollectionUUID
591                        let url = this.getPropertyUrl(this.property);
592                        property.searchUrl = url;
593                        Pubsub.publish('property_card_menu_item_pressed', {property,collectionUUID,propertyCollectionUUID,menuItem, url});
594                    });
595
596                    this.element.addEventListener(`on_menu_open`, (e) => {    
597                        menuOpen = e.detail;
598                       this.element.setAttribute("show_menu", menuOpen);
599                    });
600
601                    this.element.addEventListener('click', (e) => {
602                        if (e.target.tagName != "svg" && e.target.tagName != "path" && !menuOpen) {
603                            let state = _this.property.address.state;
604                            let city = _this.slugify(_this.property.address.city);
605                            let zip = _this.property.address.zip
606                            let address = _this.slugify(_this.property.address.street);
607                            let blossorId = _this.property.blossorId;
608                            let url = this.getPropertyUrl(property);
609                            window.open(`../../${url}`, '_blank');
610                        }        
611                    });
612
613                    this.element.addEventListener('on_favorite_press', (e) => {
614                        let propertyCollectionUUID = property.propertyCollectionUUID;
615                        Pubsub.publish('delete_property_modal_pressed', {collectionUUID, propertyCollectionUUID});
616                    });
617
618                }
619
620                getPropertyUrl = (property) => {
621                    let state = property.address.state;
622                    let city = this.slugify(property.address.city);
623                    let zip = property.address.zip
624                    let address = this.slugify(property.address.street);
625                    let blossorId = property.blossorId;
626                    return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`;
627                }
628
629                slugify(text) {
630                     // replace non letter or digits by -
631                    text = text.replace(/[^\pL\d]+~u/g, '_');
632                    // transliterate
633                    text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'')
634                    // remove unwanted characters
635                    text = text.replace(/[^_\w]+/g, '_');
636                    // trim
637                    text = text.trim();
638                    // remove duplicate -
639                    text = text.replace(/_+/g, '-');
640                    // lowercase
641                    text = text.toLowerCase();
642                    if (!text) {
643                        return 'n-a';
644                    }
645                    return text
646                }
647            }
648
649            let dateNow = new Date();
650            dateNow.setDate(dateNow.getDate()-7);
651            dateNow.setHours(dateNow.getHours());
652            dateNow.setMinutes(dateNow.getMinutes());
653            dateNow.setSeconds(dateNow.getSeconds());
654            const sevenDaysAgo = dateNow.getTime();
655
656            class PropertySection   {
657                propertySection = document.getElementById('property-section')
658                listIcon = document.getElementById('property-list-icon')
659                mapIcon = document.getElementById('property-map-icon')
660                propertyHeader = document.getElementById('property-header')
661                propertyList = document.getElementById("property-list")
662                propertyListParent = document.getElementById("property-list-parent")
663                propertyMap = document.getElementById('property-map')
664                selectedView = 'map'
665
666                collectionProperties = []
667
668                properties = []
669            
670
671                constructor() {
672                    this.listIcon.addEventListener('click', () => {
673                        this.setView('list')
674                    })
675
676                    this.mapIcon.addEventListener('click', () => {
677                        this.setView('map')
678                    })
679                }
680
681                show = (collectionUUID, collectionProperties) => {
682                    this.propertySection.style.display = 'block'
683                    this.collectionProperties = collectionProperties
684                    this.collectionUUID = collectionUUID
685                    
686                    this.propertyList.innerHTML = ''
687                    count = 100;
688                     
689                    this.collectionProperties?.data?.properties?.forEach((property) => {
690                         count--
691                        this.addPropertyCard(property,collectionUUID, count)
692                    });
693                }
694
695                hide = () => {
696                    this.propertySection.style.display = 'none'
697                }
698
699                setPropertyCardWidth = () => {
700                    let width;
701                    let imageHeight;
702                    let windowWidth = window.innerWidth
703                    if(this.selectedView == 'map') {
704                        if(windowWidth > 1279) {
705                            width = `220`;
706                            imageHeight = `154`;
707                        } else if(windowWidth > 768) {
708                            width = `325`;
709                            imageHeight = `184`;
710                        } else{
711                            width = `244`;
712                            imageHeight = `154`;                            
713                        }
714                    } 
715                    else {
716                        if(windowWidth > 1440 ){
717                            width = `300`;
718                            imageHeight = `184`;
719                        }
720                        else if(windowWidth > 1279) {
721                            width = `260`;
722                            imageHeight = `152`;
723                        } else if(windowWidth > 768) {
724                            width = `218`;
725                            imageHeight = `152`;
726                        } else{
727                            width = `288`;
728                            imageHeight = `184`;
729                        }
730                    }
731
732                    let propertyCards = document.querySelectorAll('place-propertycard')
733                    propertyCards.forEach((propertyCard) => {
734                        propertyCard.setAttribute('layout_width', width)
735                        propertyCard.setAttribute('image_height', imageHeight)                    
736                    })
737                }
738
739                setView = (view) => {
740                    this.selectedView = view
741                    if (view == 'list') {
742                        this.listIcon.setAttribute('stroke', 'black')
743                        this.mapIcon.setAttribute('stroke', 'gray')
744
745                        this.propertyMap.style.display = 'none'
746                        this.propertyList.classList.add('property-list-list-view')
747                        this.propertyList.classList.remove('property-list-map-view')
748                        this.propertyListParent.classList.remove('property-list-map-view-parent')
749
750                        Pubsub.publish('property_section_show_list_view', this.collectionProperties?.data?.properties);
751                    } else {
752                        this.listIcon.setAttribute('stroke', 'gray')
753                        this.mapIcon.setAttribute('stroke', 'black')
754
755                        this.propertyMap.style.display = 'block'
756                        this.propertyList.classList.remove('property-list-list-view')
757                        this.propertyList.classList.add('property-list-map-view')
758                        this.propertyListParent.classList.add('property-list-map-view-parent')
759
760                        Pubsub.publish('property_section_show_map_view', this.collectionProperties?.data?.properties);
761                    }
762
763                    this.setPropertyCardWidth();
764                }
765
766                scrollIntoView = (id) => {
767                    let propertyCard = document.getElementById(id);
768                    propertyCard.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' })
769                }
770
771                addPropertyCard = (property, collectionUUID, count) => {
772                    
773                    var propertyCardWrapperElement = document.createElement(`div`)
774                    propertyCardWrapperElement.setAttribute('style', `z-index:${count}`)
775                     propertyCardWrapperElement.setAttribute('class', 'property-card-wrapper')
776                     propertyCardWrapperElement.setAttribute("id", property.propertyCollectionUUID);
777                     
778                    const propertyCard = new PropertyCard(collectionUUID,property);
779                    var propertyCardElement = propertyCard.element;
780                
781                    propertyCardWrapperElement.append(propertyCardElement)
782                    
783                    this.propertyList.append(propertyCardWrapperElement)
784                
785                }
786                
787            }
788
789
790            class PageSubHeader{
791                constructor() {
792                    
793                    this.element = document.querySelector('place-pagesubheader')
794
795                    this.element.addEventListener('button_on_press', (e) => {
796                        Pubsub.publish('create_new_collection_pressed', e)
797                    })
798
799                    this.element.addEventListener('top_header_on_press', (e) => {
800                        Pubsub.publish('top_header_back_pressed', e)
801                    })
802
803                     this.element.addEventListener('on_menu_item_pressed', (e) => {
804                        Pubsub.publish('top_header_menu_item_pressed', e.detail)
805                    })
806
807                    this.element.addEventListener('secondary_button_on_press', (e) => {
808                        window.open('../../search.php', '_blank')
809                    })
810                }
811
812                setTitle(title) {
813                    this.element.setAttribute('title', title)
814                }
815
816                setTopHeaderTitle(title){
817                    this.element.setAttribute('top_header_title', title)
818                }
819
820                showTopHeader(){
821                    this.element.setAttribute('show_top_header', true)
822                }
823
824                hideTopHeader(){
825                    this.element.setAttribute('show_top_header', false)
826                }
827
828                showPrimaryButton() {
829                    this.element.setAttribute('show_button', true)
830                }
831
832                hidePrimaryButton() {
833                    this.element.setAttribute('show_button', false)
834                }
835
836                showSecondaryButton(){
837                    this.element.setAttribute('show_secondary_button', true)
838                }
839
840                hideSecondaryButton(){
841                    this.element.setAttribute('show_secondary_button', false)
842                }
843
844                showMenuButton() {
845                    this.element.setAttribute('show_menu_button', true)
846                }
847
848                hideMenuButton() {
849                    this.element.setAttribute('show_menu_button', false)
850                }
851            }
852
853            class CollectionModal  {
854                
855                constructor() {
856                    
857                    let _this = this;
858                    this.element = document.querySelector('place-collectionpopup');
859                    this.collectionUUID = 0;
860
861                    this.element.addEventListener("on_close_press", (e) => {
862                        _this.hide();
863                    });
864
865                    this.element.addEventListener("on_save_press", (e) => {
866                        this.showError(false);
867                        e.detail.collectionUUID = this.collectionUUID
868                         e.detail.type = this.isEditingCollection ? 'edit' : 'save'
869                        Pubsub.publish('on_new_collection_saved', e.detail);
870                    });
871                    
872                }
873
874                setName(name) {
875                    this.element.setAttribute('name_value', name)
876                }
877
878                setDescription(description) {
879                    this.element.setAttribute('description_value', description ? description : "")
880                }
881
882                showError(error) {
883                    this.element.setAttribute('show_error', error)
884                }
885
886                 show(collectionUUID, isEditingCollection) {
887                    this.isEditingCollection = isEditingCollection;
888                    if(collectionUUID){
889                        this.collectionUUID = collectionUUID;
890                    }
891                    this.element.setAttribute('style', 'display:flex')
892                }
893
894                hide() {
895                    this.element.setAttribute('style', 'display:none');
896
897                    this.showError(false)
898
899                    // terrible hack.. only way i could get it to respond to prop changes
900                    // to clear the input fields after closing the modal
901                    this.setName('none')
902                    this.setDescription('none')
903                    setTimeout(() => {
904                        this.setName('')
905                        this.setDescription('')
906                    }, 100);
907                }
908            }
909
910            class CollectionCreatedModal  {
911                constructor() {
912                    
913                   
914                    this.collection = ""
915                    this.element = document.getElementById('collection-created-modal');
916                    let _this = this;
917
918                    this.element.addEventListener("on_primary_press", (e) => {
919                        this.hide();
920                        window.location.href = '../../search.php'
921                    });
922
923                    this.element.addEventListener("on_tertiary_press", (e) => {
924                        _this.hide();
925                        Pubsub.publish('collection_created_modal_view_collection_pressed', _this.collection);
926                    });
927
928                    this.element.addEventListener("on_close_press", (e) => {
929                        _this.hide();
930                    });
931
932                    this.element.setAttribute("stacked_buttons", true)
933                    this.element.setAttribute("primary_button_text", "Search Listings")
934                    this.element.setAttribute("tertiary_button_text", "View Collection")
935                }
936
937                show(collection) {
938                    if(collection){
939                        this.collection = collection;
940                    }
941                    this.element.setAttribute('style', 'display:flex')
942                }
943
944                hide() {
945                    this.element.setAttribute('style', 'display:none');
946                }
947            }
948
949            class EditCollectionModal  {
950                constructor() {
951                    
952                   
953                    this.collection = ""
954                    this.element = document.getElementById('edit-collection-modal');
955                    let _this = this;
956
957                    this.element.addEventListener("on_primary_press", (e) => {
958                        _this.hide();
959                        
960                    });
961
962                    
963
964                    this.element.addEventListener("on_close_press", (e) => {
965                        _this.hide();
966                    });
967                }
968
969                show() {
970                    
971                    this.element.setAttribute('style', 'display:flex')
972                }
973
974                hide() {
975                    this.element.setAttribute('style', 'display:none');
976                }
977            }
978
979            class DeleteCollectionModal {
980                constructor() {
981                   
982                   
983                    this.collection = ""
984                    this.element = document.getElementById('delete-collection-modal');
985                    let _this = this;
986
987                    this.element.addEventListener("on_primary_press", (e) => {
988                        _this.hide();
989                        Pubsub.publish('delete_collection_modal_delete_pressed', _this.collection);
990                    });
991
992                    this.element.addEventListener("on_tertiary_press", (e) => {
993                        this.hide();
994                    });
995
996                    this.element.addEventListener("on_close_press", (e) => {
997                        _this.hide();
998                    });
999                }
1000
1001                show(collection) {
1002                    if(collection){
1003                        this.collection = collection;
1004                    }
1005                    this.element.setAttribute('style', 'display:flex')
1006                }
1007
1008                hide() {
1009                    this.element.setAttribute('style', 'display:none');
1010                }
1011            }
1012
1013             class ShareSavedPropertyModal {
1014                constructor() {
1015                    let _this = this;
1016                    this.savedProperty = {}
1017                    this.element = document.getElementById('share-saved-property-modal');
1018
1019                    this.element.addEventListener("on_primary_press", (e) => {
1020
1021                       
1022
1023                        navigator.clipboard.writeText(this.link)
1024                        _this.hide();
1025                         Pubsub.publish('share_saved_property_modal_share_pressed');
1026                        
1027                    });
1028
1029                    this.element.addEventListener("on_close_press", (e) => {
1030                        _this.hide();
1031                    });
1032                }
1033
1034                show = (savedProperty) => {
1035                
1036                    
1037                    this.savedProperty = savedProperty;
1038                    
1039                    this.link = document.location.origin + "/" +  this.savedProperty.searchUrl
1040                    this.element.setAttribute('share_link_text', this.link)
1041                    this.element.setAttribute('style', 'display:flex')
1042                }
1043
1044                hide = () => {
1045                    this.element.setAttribute('style', 'display:none');
1046                }
1047            }
1048
1049            class DeletePropertyModal  {
1050                constructor() {
1051                    
1052                   
1053                    this.collectionUUID = ""
1054                    this.propertyCollectionUUID = ""
1055                    this.element = document.getElementById('delete-property-modal');
1056                    let _this = this;
1057
1058                    this.element.addEventListener("on_primary_press", (e) => {
1059                        _this.hide();
1060                        Pubsub.publish('delete_property_modal_delete_pressed', {"collectionUUID":_this.collectionUUID, "propertyCollectionUUID":_this.propertyCollectionUUID});
1061                    });
1062
1063                    this.element.addEventListener("on_tertiary_press", (e) => {
1064                        this.hide();
1065                    });
1066
1067                    this.element.addEventListener("on_close_press", (e) => {
1068                        _this.hide();
1069                    });
1070                }
1071
1072                show(collectionUUID, propertyCollectionUUID) {
1073                    if(collectionUUID){
1074                        this.collectionUUID = collectionUUID;
1075                    }
1076                    if(propertyCollectionUUID){
1077                        this.propertyCollectionUUID = propertyCollectionUUID;
1078                    }
1079                    this.element.setAttribute('style', 'display:flex')
1080                }
1081
1082                hide() {
1083                    this.element.setAttribute('style', 'display:none');
1084                }
1085            }
1086
1087            class CopyPropertyToCollectionModal {
1088                constructor(){
1089                     
1090                    this.element = document.querySelector('place-copycollectionmodal');
1091                    this.collections = [];
1092                    this.property = {}
1093                    this.isVisible = false;
1094
1095                   
1096
1097                    this.element.addEventListener('close_button', (e) => {
1098                        this.hide();
1099                    });
1100
1101                    this.element.addEventListener('cancel_button', (e) => {
1102                        this.hide();
1103                    });
1104
1105                    this.element.addEventListener('on_save', (e) => {
1106                        Pubsub.publish('copy_property_to_collection_modal_save_pressed', {'collectionUUID':e.detail, 'property':this.property});
1107                    });
1108
1109                    this.element.addEventListener('set_selected_collection', (e) => {
1110                        console.log('set_selected_collection', e)
1111                    });
1112
1113                    this.element.addEventListener('on_link_press', (e) => {
1114                        Pubsub.publish('show_new_collection_modal');
1115                    });
1116
1117                }
1118
1119                getCollectionData(){
1120                    return JSON.parse(this.element.getAttribute("collections"));
1121                }
1122
1123                setCollectionData(collections){
1124                    this.element.setAttribute('collections', JSON.stringify(collections))
1125                }
1126
1127                getCollectionList(collections, currentCollectionName) {
1128                    let collectionList = [];
1129                    collections.forEach(collection => {
1130                        if (currentCollectionName && (collection.collectionName == currentCollectionName)) return;
1131                        collectionList.push({
1132                            collection_title: collection.collectionName,
1133                            id: collection.collectionUUID,
1134                            propertiesImages: collection?.propertiesImages?.length > 0 ? collection?.propertiesImages : [],
1135                        })
1136                    });
1137                    this.setCollectionData(collectionList);
1138
1139                }
1140
1141                setIsAddingToCollection(isAddingToCollection){
1142                    this.element.setAttribute('is_add_to_collection', isAddingToCollection);
1143                }
1144
1145                show(property) {
1146                          
1147                    if(property){
1148                        this.property = property;
1149                    }
1150
1151                    this.isVisible = true;
1152
1153                    let mls = {
1154                        status: property?.status || property?.standardStatus || "",
1155                        image: this.getPropertyImageUrl(property),
1156                        price: property?.price || "0",
1157                        address: ( typeof property?.address === "string") ? property?.address : (property?.address?.street || property?.streetAddress || ""),
1158                        state: property?.state || property?.address?.state || "",
1159                        city: property?.city || property?.address?.city || "",
1160                        postal_code: property?.postal_code || property?.address?.zip || "",
1161                        beds: property?.beds || property?.bedrooms || 0,
1162                        baths: property?.baths || property?.fullBaths || property?.bathsTotalDecimal || 0,
1163                        sqft: property?.sqft || property?.squareFeet || property?.sqFeet || 0,
1164                        creator: property?.creator || "",
1165                    }
1166
1167                    this.element.setAttribute('mls', JSON.stringify(mls))
1168                    this.element.setAttribute('image_url',mls?.image || "")
1169                    this.element.setAttribute('style', 'display:flex')
1170                }
1171
1172                getPropertyImageUrl(property){
1173                   // property?.image[0]?.uri || property?.photos[0]?.url || "",
1174
1175                    if(property.image && property.image.length > 0){
1176                       return property.image[0].uri
1177                    } else if (property.photos && property.photos.length > 0){
1178                       return property.photos[0].url
1179                    } else {
1180                        return ""
1181                    }
1182                }
1183
1184                hide() {
1185                    this.isVisible = false;
1186                    this.element.setAttribute('style', 'display:none');
1187                }
1188            }
1189
1190            class CollectionPaging {
1191                constructor(collectionsPerPage){
1192                   
1193                    
1194                    this.element = document.getElementById('collection-pagination');
1195                    this.collectionsPerPage = collectionsPerPage;
1196
1197                    this.element.addEventListener('page_changed', (e) => {
1198                       Pubsub.publish('collection_page_changed', e.detail);
1199                    });
1200                }
1201
1202                setPageCount(pageCount){
1203                    this.element.setAttribute('page_count', pageCount);
1204                }
1205
1206                show() {
1207                    this.element.setAttribute('style', 'display:flex')
1208                }
1209
1210                hide() {
1211                    this.element.setAttribute('style', 'display:none')
1212                }
1213            }
1214
1215            class PropertyPaging  {
1216                constructor(propertiesPerPage){
1217                    
1218                    
1219                    this.element = document.getElementById('property-pagination');
1220                    this.propertiesPerPage = propertiesPerPage;
1221
1222                    this.element.addEventListener('page_changed', (e) => {
1223                        Pubsub.publish('property_page_changed', e.detail);
1224                    });
1225                }
1226
1227                setPageCount(pageCount){
1228                    this.element.setAttribute('page_count', pageCount);
1229                }
1230
1231                setCurrentPage(currentPage){
1232                    this.element.setAttribute('current_page', currentPage);
1233                }
1234
1235                show() {
1236                    this.element.setAttribute('style', 'display:flex')
1237                }
1238
1239                hide() {
1240                    this.element.setAttribute('style', 'display:none')
1241                }
1242            }
1243
1244            class NewCollectionBlock {
1245                constructor(){
1246                    
1247                    this.element = document.getElementById('new-collection-block');
1248
1249                    this.element.addEventListener('on_main_press', (e) => {
1250                        Pubsub.publish('new_collection_block_create_collection_pressed', e.detail);
1251                    });
1252                }
1253                show(collectionUUID, propertyCollectionUUID) {
1254                    this.element.setAttribute('style', 'display:flex')
1255                }
1256
1257                hide() {
1258                    this.element.setAttribute('style', 'display:none');
1259                }
1260            }
1261
1262            class AddListingsBlock {
1263                constructor() {
1264                   
1265                    this.element = document.getElementById('add-listings-block');
1266
1267                    this.element.addEventListener('on_main_press', (e) => {
1268                        window.open('../../search.php', '_blank')
1269                    });
1270
1271                   this.element.addEventListener("on_tertiary_press", (e) => {
1272                         
1273                    });
1274                }
1275
1276                show() {
1277                    this.element.setAttribute('style', 'display:flex')
1278                }
1279
1280                hide() {
1281                    this.element.setAttribute('style', 'display:none');
1282                }
1283            }
1284
1285            class MyFeed {
1286                constructor(blueroofMiddlewareApi, collectionsService) {
1287                    this.blueroofMiddlewareApi = blueroofMiddlewareApi;
1288                    this.collectionsService = collectionsService;
1289                    this.element = document.querySelector('place-myfeedblock');
1290
1291                    this.element.addEventListener('on_menu_open', (e) => {
1292                        this.element.setAttribute('show_menu', e.detail.e);
1293                        this.element.setAttribute('show_menu_index', e.detail.index);
1294                    });
1295
1296                    this.element.addEventListener('on_view_all_pressed', (e) => {
1297                        window.open('../../search.php', '_blank');
1298                    });
1299
1300                    this.element.addEventListener('on_add_collection', (e) => {
1301                        
1302                        let property = e.detail;
1303                        Pubsub.publish('my_feed_add_collection_pressed', {property});
1304
1305                    });
1306
1307                    this.element.addEventListener('on_share_pressed', (e) => {
1308                    
1309                        let property = e.detail
1310                    
1311                        let url = this.getPropertyUrl(property);
1312                        property.searchUrl = url;
1313                        
1314                        Pubsub.publish('my_feed_share_pressed', {property});
1315                    });
1316
1317                    this.element.addEventListener('on_favorite_pressed', (e) => {
1318                        let property = e.detail.property;
1319                        let isAddingFavorite = e.detail.isAddingFavorite;
1320
1321                        if(isAddingFavorite){
1322                            Pubsub.publish('my_feed_on_favorite_pressed', {property});
1323                        }
1324                        else{
1325                            Pubsub.publish('my_feed_on_unfavorite_pressed', {property});
1326                        }
1327                    });
1328
1329                    this.element.addEventListener('on_property_pressed', (e) => {
1330                        let property = e.detail
1331                    
1332                        let url = this.getPropertyUrl(property);
1333                        property.searchUrl = url;
1334                        window.open('../../' + url, '_blank');
1335                    });
1336                
1337
1338                    this.blueroofMiddlewareApi.getMyFeed().then((data) => {
1339
1340                        let myFeedBlossorIds = data.map(property => property.blossorId);
1341                        
1342
1343                        this.collectionsService.checkIfInCollection(myFeedBlossorIds).then((propertiesInCollections) => {
1344
1345                            let feed = []
1346                            data.forEach((item) => {
1347                            feed.push({
1348                                image: [
1349                                    {
1350                                        title: "",
1351                                        id: 0,
1352                                        uri: item?.photos[0].url,
1353                                    },
1354                                    ],
1355                                    price: item?.price,
1356                                    favorite: propertiesInCollections?.data[item?.blossorId] != null || false,
1357                                    address: item?.streetAddress,
1358                                    city: item?.city,
1359                                    state: item?.state,
1360                                    postal_code: item?.postalCode,
1361                                    beds: item?.bedrooms,
1362                                    status: item?.standardStatus,
1363                                    baths: item?.bathsTotalDecimal,
1364                                    sqft: item?.squareFeet,
1365                                    creator: "",
1366                                    mls_price_history: item?.history[item.history.length-1]?.price,
1367                                    blossorId: item?.blossorId,
1368                                    open_house : item?.openhouses?.length > 0 ? true : false,
1369                                    open_house_date : item?.openhouses[0]?.startDate,
1370                                    open_house_end_time : item?.openhouses[0]?.endDate,
1371                                    property_created_at : item?.listDate,
1372                                    lastStatusChangeDate : item?.lastStatusChangeDate,
1373                                })
1374                            })
1375
1376                            if(feed && feed?.length > 0){
1377                                this.show();
1378                                this.element.setAttribute('mls_data', JSON.stringify(feed));
1379                            }
1380                        });
1381                    });
1382                    
1383                }
1384
1385                getPropertyUrl = (property) => {
1386                    let state = property.state;
1387                    let city = this.slugify(property.city);
1388                    let zip = property.postal_code
1389                    let address = this.slugify(property.address);
1390                    let blossorId = property.blossorId;
1391                    return `homes-for-sale/${state}/${city}/${zip}/${address}/bid-${blossorId}`;
1392                }
1393
1394                slugify(text) {
1395                    // replace non letter or digits by -
1396                    text = text.replace(/[^\pL\d]+~u/g, '_');
1397                    // transliterate
1398                    text = text.normalize('NFKD').replace(/[\u0300-\u036F]/g,'')
1399                    // remove unwanted characters
1400                    text = text.replace(/[^_\w]+/g, '_');
1401                    // trim
1402                    text = text.trim();
1403                    // remove duplicate -
1404                    text = text.replace(/_+/g, '-');
1405                    // lowercase
1406                    text = text.toLowerCase();
1407                    if (!text) {
1408                        return 'n-a';
1409                    }
1410                    return text
1411                }
1412
1413                getMlsData = () => {
1414                    return JSON.parse(this.element.getAttribute('mls_data'));
1415                }
1416
1417                setMlsData = (data) => {
1418                    this.element.setAttribute('mls_data', JSON.stringify(data));
1419                }
1420
1421                show() {
1422                    this.element.setAttribute('style', 'display:flex')
1423                }
1424
1425                hide() {
1426                    this.element.setAttribute('style', 'display:none')
1427                }
1428            }
1429
1430            class BlueroofMiddlewareApi {
1431                constructor() {
1432                    this.baseUrl = "https://brivity-home-middleware.production.brivity.com";
1433                    this.apiKey = localStorage.getItem('authorization');
1434                }
1435
1436                getMyFeed = async () => {
1437                     const response = await fetch(`${this.baseUrl}/listings/voltron`, {
1438                        method: 'POST',
1439                        headers: {
1440                            'Content-Type': 'application/json',
1441                            'Authorization': `${this.apiKey}`
1442                        },
1443                        body: JSON.stringify([])
1444                    });
1445
1446                    const data = await response.json();
1447                    return data;
1448                }
1449                
1450                getLeadBasicInfo = async () => {
1451                    const response = await fetch(`${this.baseUrl}/blueroofleads/basicinfo`, {
1452                        method: 'GET',
1453                        headers: {
1454                            'Content-Type': 'application/json',
1455                            'Authorization': `${this.apiKey}`
1456                        },
1457                       
1458                    });
1459
1460                    const data = await response.json();
1461                    return data;
1462                }
1463
1464                getAgentProfile = async (brivityUserId) => {
1465                    const response = await fetch(`${this.baseUrl}/blueroofagents/profile`, {
1466                        method: 'POST',
1467                        headers: {
1468                            'Content-Type': 'application/json',
1469                            'Authorization': `${this.apiKey}`
1470                        },
1471                        body: `{"brivityUserId": ${brivityUserId}}`
1472                       
1473                    });
1474
1475                    const data = await response.json();
1476                    return data;
1477                }
1478
1479            }
1480
1481            class Map {
1482                constructor(){
1483                    this.element = document.querySelector('place-map');
1484                    this.properties = [];
1485
1486                    this.element.addEventListener('on_marker_clicked', (e) => {
1487                        Pubsub.publish('map_marker_clicked', e.detail.id)
1488                    });
1489                }
1490
1491                setMarkers = (properties) => {
1492                    let markers = [];
1493                    let color = 'black'
1494
1495                    let dateNow = new Date();
1496                    dateNow.setDate(dateNow.getDate()-7);
1497                    dateNow.setHours(dateNow.getHours());
1498                    dateNow.setMinutes(dateNow.getMinutes());
1499                    dateNow.setSeconds(dateNow.getSeconds());
1500                    const sevenDaysAgo = dateNow.getTime();
1501
1502                    this.properties = properties;
1503                    properties?.forEach(property => {
1504
1505                        if(property.statusText == 'Active'){
1506                            color = '#1FA6E8'
1507                        }else if(property.statusText == 'Pending'){
1508                            color = '#FFC82C'
1509                        }else if(property.statusText == 'Sold'){
1510                            color = '#FF7343'
1511                        }
1512
1513                        let listDate = new Date(property.listDate);
1514
1515
1516                        if(listDate.getTime() > sevenDaysAgo){
1517                            color = '#24D0BC'
1518                        }
1519
1520                        markers.push({
1521                            id: `${property.blossorId}`,
1522                            location: property.location,
1523                            price: property.price,
1524                            color : color
1525                        })
1526                    });
1527
1528                    this.element.setAttribute('markers', JSON.stringify(markers));
1529                }
1530
1531                setSelectedMarker = (property) => {
1532                    let markerIndex = this.properties.findIndex((p) => p.blossorId == property.blossorId)
1533                    if(markerIndex > -1){
1534                        this.element.setAttribute('selected_property_index', markerIndex);
1535                    }
1536                }
1537
1538                clearSelectedMarker = () => {
1539                    this.element.setAttribute('selected_property_index', -1);
1540                }
1541
1542            }
1543
1544            class SavedListings {
1545                constructor(){
1546                    this.element = document.getElementById('collection-saved-listings');
1547                }
1548
1549                setCount(count) {
1550                    this.element.innerText = `Saved Listings (${count})`;
1551                }
1552
1553                hide() {
1554                    this.element.style.display = `none`;
1555                }
1556                show() {
1557                    this.element.style.display = `block`;
1558                }
1559            }
1560        
1561            class AddListingBtn {
1562                constructor(){
1563                    this.element = document.getElementById('add-listing-btn');
1564                    this.element.setAttribute('button_style', JSON.stringify({paddingLeft: '0px'}));
1565                    this.element.addEventListener('on_press', (e) => {
1566                        window.open('../../search.php', '_blank')
1567                    })
1568                }
1569
1570                hide() {
1571                    this.element.style.display = `none`;
1572                }
1573                show() {
1574                    this.element.style.display = `block`;
1575                }
1576            }
1577
1578            class Page {
1579                constructor(blueroofMiddlewareApi) {
1580                    this.selectedCollection = {};
1581                    this.inPropertyView = false;
1582                    this.lead = {}
1583                    this.agent = {}
1584                    this.isInMapView = false;
1585                    this.isInListView = true;
1586
1587                    this.authorizationData = JSON.parse(atob(blueroofMiddlewareApi.apiKey.split('.')[1]));
1588                    this.is_blueroof_person = this.authorizationData?.is_blueroof_person;
1589
1590                   
1591                }
1592
1593                setSelectedCollection(collection) {
1594                    this.selectedCollection = collection;
1595                }
1596
1597                setInPropertyView(inPropertyView) {
1598                    this.inPropertyView = inPropertyView;
1599                }
1600            }
1601
1602
1603            class messagingEmitter extends Messaging.BaseEmitter {
1604                
1605                newMessage(message) {
1606                   Pubsub.publish('messaging_emitter_new_message', message);
1607                }
1608            }
1609
1610            
1611
1612            (async () => {
1613
1614                const blueroofMiddlewareApi = new BlueroofMiddlewareApi();
1615                const page = new Page(blueroofMiddlewareApi);
1616
1617                let url = 'https://messaging.brivity.com'
1618                const messaging = new Messaging.Service(url, blueroofMiddlewareApi.apiKey, new messagingEmitter());
1619
1620                let lead =  await blueroofMiddlewareApi.getLeadBasicInfo();
1621                let agent = await blueroofMiddlewareApi.getAgentProfile(lead.data?.brivity_agent_id);
1622
1623                page.lead = lead.data;
1624                page.agent = agent.data;
1625
1626                const collectionsService = new Collections.Service(window?.globalSiteVariables?.options?.apis?.collections?.url ?? '',blueroofMiddlewareApi.apiKey, "sitebuilder", new logger());
1627
1628
1629                const menu = new Menu(page?.is_blueroof_person || false, page?.agent, blueroofMiddlewareApi.baseUrl, blueroofMiddlewareApi.apiKey);
1630                const collectionSection = new CollectionSection()
1631                const propertySection = new PropertySection()
1632                const collectionModal = new CollectionModal();
1633                const collectionCreatedModal = new CollectionCreatedModal();
1634                const deleteCollectionModal = new DeleteCollectionModal();
1635                const editCollectionModal = new EditCollectionModal();
1636                const shareSavedPropertyModal = new ShareSavedPropertyModal();
1637                const deletePropertyModal = new DeletePropertyModal();
1638                const copyPropertyToCollectionModal = new CopyPropertyToCollectionModal();
1639                const pageSubHeader = new PageSubHeader();
1640                const collectionPaging = new CollectionPaging(8)
1641                const propertyPaging = new PropertyPaging(8)
1642                const newCollectionBlock = new NewCollectionBlock();
1643                const addListingsBlock = new AddListingsBlock();
1644                const myFeed = new MyFeed(blueroofMiddlewareApi, collectionsService);
1645                const map = new Map();
1646                const savedListings = new SavedListings();
1647                const addListingBtn = new AddListingBtn();
1648
1649                collectionPaging.hide();
1650                propertySection.hide();
1651
1652                let collections = [];
1653                let extraCollections = 0;
1654                let createCopyCollection = false;
1655              
1656                if(!showCollectionByUUID){
1657                    const collectionDescription = document.getElementById("collectionDescription");
1658
1659                    collectionsService.getCollections(0, collectionPaging.collectionsPerPage).then((e) => {
1660
1661                        extraCollections = e?.data?.totalCollections
1662
1663                        if(e.data.TotalPages > 1) {
1664                            collectionPaging.show()
1665                            collectionPaging.setPageCount(e.data.TotalPages);
1666                        } else {
1667                            collectionPaging.setPageCount(1);
1668                        }
1669                        
1670
1671                        if(e?.data?.Items){
1672                            collections = e.data.Items;
1673                            count = 100;
1674                            e.data.Items.forEach((collection) => {
1675                            count--
1676                            
1677                                collectionSection.addCollectionCard(collection, count)
1678                            });
1679                        }
1680
1681                        copyPropertyToCollectionModal.getCollectionList(collections)
1682                        
1683                        if(collections.length == 0){
1684                            newCollectionBlock.show();
1685                        }
1686
1687                    }).catch((e) => {
1688                        if(collections.length == 0){
1689                            newCollectionBlock.show();
1690                        }
1691                    });
1692                }
1693                else{
1694                    collectionsService.getCollections(0, collectionPaging.collectionsPerPage).then((e) => {
1695                        
1696                        if(e?.data?.Items){
1697                            collections = e.data.Items;
1698                        }
1699                         
1700                    });
1701                }    
1702
1703                Pubsub.subscription('property_card_mouseenter', (property) => {
1704
1705                    document.querySelectorAll('place-propertycard').forEach((propertyCard) => {
1706                        propertyCard.setAttribute('show_border', false);
1707                    })
1708                    
1709                    if(page.isInMapView){
1710                        map.setSelectedMarker(property)
1711                    }
1712                }).subscribe();
1713
1714                Pubsub.subscription('property_card_mouseleave', () => {
1715                    if(page.isInMapView){
1716                        map.clearSelectedMarker()
1717                    }
1718                }).subscribe();
1719
1720                Pubsub.subscription('messaging_emitter_new_message', (message) => {
1721                    toast.show('New message from ' + message.createdByAlias)
1722                }).subscribe();
1723
1724                Pubsub.subscription('property_section_show_map_view', (properties) => {
1725                    map.setMarkers(properties);
1726                    page.isInMapView = true;
1727                    page.isInListView = false;
1728
1729                    document.querySelectorAll('place-propertycard').forEach((propertyCard) => {
1730                        propertyCard.setAttribute('show_border_on_hover', true);
1731                    })
1732                }).subscribe();
1733
1734                Pubsub.subscription('property_section_show_list_view', (properties) => {
1735                    page.isInMapView = false;
1736                    page.isInListView = true;
1737
1738                    document.querySelectorAll('place-propertycard').forEach((propertyCard) => {
1739                        propertyCard.setAttribute('show_border_on_hover', false);
1740                    })
1741                    
1742                }).subscribe();
1743
1744                Pubsub.subscription('property_page_changed', (page) => {
1745                    collectionsService.getCollectionProperties(propertySection.collectionUUID, page, propertyPaging.propertiesPerPage).then((collectionProperties) => {
1746                        map.setMarkers(collectionProperties?.data?.properties);
1747                        savedListings.setCount(collectionProperties?.data?.totalListings || 0);
1748                        propertySection.show(propertySection.collectionUUID,collectionProperties)
1749                        propertySection.setPropertyCardWidth();
1750                        propertyPaging.setCurrentPage(page);
1751                    });
1752                }).subscribe();
1753
1754                Pubsub.subscription("top_header_menu_item_pressed", (menuItemPressed) => {
1755                            
1756                    if(menuItemPressed == 'Edit Collection'){
1757                        collectionModal.setName(page.selectedCollection.collectionName);
1758                        collectionModal.setDescription(page.selectedCollection.collectionDescription);
1759                        collectionModal.show(page.selectedCollection.collectionUUID, true);
1760                    }
1761                    else if(menuItemPressed == 'Delete Collection'){
1762                        deleteCollectionModal.show(page.selectedCollection);
1763                    }
1764                }).subscribe();
1765
1766                Pubsub.subscription('new_collection_block_create_collection_pressed', (e) => {
1767                    collectionModal.show(0, false);
1768                }).subscribe();
1769
1770                Pubsub.subscription('collection_card_pressed', (e) => {
1771                
1772                    window.location.hash = e.collection.collectionUUID;
1773
1774                    page.setSelectedCollection(e.collection);
1775
1776                    collectionsService.getCollectionProperties(e.collection.collectionUUID,1, propertyPaging.propertiesPerPage).then((collectionProperties) => {
1777
1778                    
1779                        savedListings.setCount(collectionProperties?.data?.totalListings || 0);
1780                        propertyPaging.setPageCount(collectionProperties.data.totalPages);
1781                        
1782                    
1783                        if(collectionProperties?.data?.properties == null){
1784                            addListingsBlock.show();
1785                        }
1786                        propertySection.show(e.collection.collectionUUID,collectionProperties)
1787                        propertySection.setPropertyCardWidth();
1788
1789                        if(collectionProperties.data.totalPages > 1){
1790                            propertyPaging.show();
1791                        }
1792                        
1793                    });
1794                    
1795                
1796                    collectionSection.hide();
1797                 
1798                    let collectionList = [];
1799
1800                    collections.forEach(collection => {
1801                        if (collection.collectionName == e.collection.collectionName) return;
1802
1803                        collectionList.push({
1804                            collection_title: collection.collectionName,
1805                            id: collection.collectionUUID,
1806                            propertiesImages: collection?.propertiesImages?.length > 0 ? collection?.propertiesImages : [],
1807                        })
1808                    });
1809
1810                    copyPropertyToCollectionModal.getCollectionList(collections, e.collection.collectionName);
1811
1812                    pageSubHeader.showTopHeader();
1813                    pageSubHeader.setTopHeaderTitle("Collections");
1814                    pageSubHeader.setTitle(e.collection.collectionName);
1815                    pageSubHeader.hidePrimaryButton();
1816                    pageSubHeader.showMenuButton();
1817
1818                    if(window.innerWidth > 768 ){
1819                        pageSubHeader.showSecondaryButton();
1820                    } 
1821
1822                    page.setInPropertyView(true)
1823
1824                    propertyPaging.setCurrentPage(1);
1825                    propertySection.setView('list')
1826                    
1827
1828                    const collectionDescription = document.getElementById('collection-description')
1829                    collectionDescription.style.display="flex"
1830                    collectionDescription.children[0].innerText = e?.collection.collectionDescription || ""
1831                }).subscribe();
1832
1833                Pubsub.subscription('collection_card_menu_item_pressed', (e) => {
1834                    if (e.menuItem == "Delete Collection") {
1835
1836                        deleteCollectionModal.show(e.collection);
1837                        
1838                    } else {
1839
1840
1841                        collectionModal.setName(e.collection.collectionName);
1842                        collectionModal.setDescription(e.collection.collectionDescription);
1843                        collectionModal.show(e.collection.collectionUUID, true);
1844                    }
1845                }).subscribe();
1846
1847                Pubsub.subscription('property_card_menu_item_pressed', (e) => {
1848                    if(e.menuItem == 'Remove from Collection') {
1849                        deletePropertyModal.show(e.collectionUUID, e.propertyCollectionUUID);
1850                    }
1851                    else if(e.menuItem == 'Copy to Collection') {
1852                        copyPropertyToCollectionModal.show(e.property);
1853                    }
1854                    else if(e.menuItem == 'Share Property') {
1855                        
1856                        shareSavedPropertyModal.show(e.property);
1857                    }
1858                }).subscribe();
1859
1860                Pubsub.subscription('delete_property_modal_pressed', (e) => {
1861                    deletePropertyModal.show(e.collectionUUID, e.propertyCollectionUUID);
1862                }).subscribe();
1863
1864                Pubsub.subscription('show_new_collection_modal', (e) => {
1865                    collectionModal.show();
1866                    copyPropertyToCollectionModal.hide();
1867                    createCopyCollection = true;
1868                }).subscribe();
1869
1870                Pubsub.subscription('top_header_back_pressed', () => {
1871                    window.location.hash = '';
1872                    pageSubHeader.hideTopHeader();
1873                    page.selectedCollection = {};
1874                    pageSubHeader.setTitle("COLLECTIONS");
1875                    pageSubHeader.showPrimaryButton();
1876                    pageSubHeader.hideSecondaryButton();
1877                    pageSubHeader.hideMenuButton();
1878
1879                    page.setInPropertyView(false)
1880
1881                    collectionSection.show();
1882                    propertySection.hide()
1883
1884                    propertyPaging.setCurrentPage(1);
1885
1886                    copyPropertyToCollectionModal.getCollectionList(collections)
1887                
1888                    const collectionDescription = document.getElementById('collection-description')
1889                    collectionDescription.style.display="none"
1890                    collectionDescription.children[0].innerText = "";
1891                    addListingsBlock.hide();
1892                }).subscribe()
1893
1894                Pubsub.subscription('create_new_collection_pressed', (e) => {
1895                    collectionModal.show(0, false);
1896                }).subscribe();
1897
1898                Pubsub.subscription('on_new_collection_saved', (e) => {         
1899                    if(e.type == 'save'){
1900                         
1901                        let people = [{ personUUID: page.lead.brivity_uuid, role: "lead" }];
1902                        let properties = [""];
1903                        collectionsService.createCollection(e.name, e.description,  page.lead.brivity_uuid, people, properties).then((e) => {
1904                            
1905                            collections.unshift(e.data);
1906
1907                            extraCollections++
1908                             if(collections.length > 8) {
1909                                 collections.pop();
1910                                 collectionPaging.show()
1911                                 collectionPaging.setPageCount(Math.ceil(extraCollections / 8));
1912                            }
1913
1914                            count = 100;
1915                            collectionSection.collections.innerHTML = "";
1916                            collections.forEach((collection) => {
1917                                count--
1918                                collectionSection.addCollectionCard(collection, count)
1919                            });
1920
1921                            let collectionsList =  copyPropertyToCollectionModal.getCollectionData();
1922                            let newCollection = {
1923                                collection_title: e.data.collectionName,
1924                                id: e.data.collectionUUID,
1925                                propertiesImages: [],
1926                            }
1927                            collectionsList.unshift(newCollection);
1928                            copyPropertyToCollectionModal.setCollectionData(collectionsList);
1929
1930                           if(!copyPropertyToCollectionModal.isVisible){
1931                            if (createCopyCollection) {
1932                                copyPropertyToCollectionModal.isVisible = true;
1933                                copyPropertyToCollectionModal.element.setAttribute('style', 'display:flex');
1934                                createCopyCollection = false;
1935                            } else {
1936                                collectionCreatedModal.show(e.data);
1937                            }
1938                           }
1939
1940                            collectionModal.hide();
1941                            
1942                            newCollectionBlock.hide();
1943                        }).catch((e) => {
1944                            collectionModal.showError(true)
1945                        });
1946                    }
1947                    else{
1948                        collectionsService.updateCollection(e.collectionUUID, e.name, e.description).then((collection) => {
1949                            let element = document.getElementById(e.collectionUUID);
1950                            element.setAttribute('title', e.name);
1951                            element.setAttribute('description', e.description);
1952                            if(Object.keys(page.selectedCollection).length !== 0){
1953                                pageSubHeader.setTitle(e.name);
1954                            }
1955                            const collectionDescription = document.getElementById('collection-description')
1956                            collectionDescription.children[0].innerText = e.description;
1957                            let updatedCollection = collections.findIndex((c) => c.collectionUUID == e.collectionUUID)
1958                            if(updatedCollection != -1){
1959                                collections[updatedCollection].collectionName = e.name;
1960                                collections[updatedCollection].collectionDescription = e.description;
1961                            }
1962                            collectionModal.hide();
1963                            editCollectionModal.show();
1964                        });
1965                    }
1966                }).subscribe();
1967
1968                Pubsub.subscription('collection_created_modal_view_collection_pressed', (collection) => {
1969                    Pubsub.publish('collection_card_pressed', {"collection": collection})
1970                }).subscribe();
1971
1972                Pubsub.subscription('delete_collection_modal_delete_pressed', (collection) => {
1973                    collectionsService.deleteCollection(collection.collectionUUID).then((e) => {
1974                        document.getElementById(collection.collectionUUID).remove();
1975                        toast.show('Collection was Deleted')
1976
1977                        extraCollections--
1978                        
1979                        if(extraCollections.length < 9) {
1980                            collectionPaging.hide()
1981                        }else{
1982                            collectionPaging.setPageCount(Math.ceil(extraCollections / 8));
1983                        }
1984
1985                        if(page.inPropertyView){
1986                            Pubsub.publish('top_header_back_pressed');
1987                        }
1988                    });
1989                }).subscribe();
1990
1991                Pubsub.subscription('delete_property_modal_delete_pressed', (e) => {
1992                    const currentPage = $("#property-pagination").find("#info-parent").filter(
1993                        function() {
1994                            return $(this).css("color") === "rgb(196, 196, 196)"
1995                        }
1996                    ).text();
1997
1998                    const propertiesPerPage = 8;
1999                    const numOfProperties = $("#property-list .property-card-wrapper").length;
2000                    const setPage = numOfProperties === 1 ? currentPage - 1 : currentPage; 
2001
2002                    collectionsService.removePropertyFromCollection(e.collectionUUID, e.propertyCollectionUUID)
2003                        .then(() => {
2004                            toast.show('Property removed from collection');
2005                            
2006                            return collectionsService.getCollectionProperties(e.collectionUUID, setPage, propertiesPerPage);
2007                        })
2008                        .then((collectionProperties) => {
2009                            const totalListingsCount = collectionProperties?.data?.totalListings;
2010                            const properties = collectionProperties?.data?.properties;
2011                            const totalPages = collectionProperties?.data?.totalPages;
2012                            const currentCollection = $(`#${e.collectionUUID}`);
2013
2014                            currentCollection.attr("num_properties", totalListingsCount);
2015                            
2016                            map.setMarkers(properties);
2017                            savedListings.setCount(totalListingsCount || 0);
2018                            propertySection.show(propertySection.collectionUUID, collectionProperties);
2019                            propertySection.setPropertyCardWidth();
2020
2021                            propertyPaging.setCurrentPage(setPage);
2022                            propertyPaging.setPageCount(totalPages);
2023
2024                            if (totalListingsCount <= 8) {
2025                                propertyPaging.hide();
2026                            }
2027                        })
2028                        .catch(error => {
2029                            console.error("Error in collection operations:", error);
2030                        });
2031                }).subscribe();
2032
2033                Pubsub.subscription('copy_property_to_collection_modal_save_pressed', (e) => {
2034
2035                    let collectionUUID = e.collectionUUID;
2036                    let blossorId = e.property.blossorId;
2037                    collectionsService.addPropertyToCollection(collectionUUID, [blossorId]).then(() => {
2038
2039                      
2040                        let data =  copyPropertyToCollectionModal.getCollectionData();
2041                        let myFeedData = myFeed.getMlsData();
2042                         
2043                        collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => {
2044                        
2045                              // update photos in add property to collection modal
2046                            let collectionIndex =  data.findIndex((x) => x.id == collectionUUID);
2047                            let collection = data[collectionIndex];
2048                            let photo = e?.data?.properties[0]?.photos[0]?.url;
2049                        
2050                            collection.propertiesImages = [];
2051                            if(e?.data?.properties?.length > 0){
2052                                collection.propertiesImages.push({mainPhoto: photo});
2053                            }
2054                            
2055                            data[collectionIndex] = collection;
2056                            
2057                            copyPropertyToCollectionModal.setCollectionData(data);
2058
2059
2060                            // update collection card if in collection view
2061                            pageCollectionIndex = collections.findIndex((x) => x.collectionUUID == collectionUUID)
2062
2063                            if(pageCollectionIndex > -1){
2064                                
2065                                let collectionCard = document.getElementById(collectionUUID);
2066                                let numProperties = parseInt(collectionCard.getAttribute('num_properties'));
2067                                numProperties++;
2068                                collectionCard.setAttribute('num_properties', numProperties);
2069
2070                                let images = collectionCard.getAttribute('image');
2071                                if(images){
2072                                    images += "," + photo;
2073                                }
2074                                else{
2075                                    images = photo;
2076                                }
2077                               
2078                                collectionCard.setAttribute('image', images);
2079                            }
2080
2081                            //update my feed to set property heart as favorited
2082                            let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId);
2083                            if(myFeedPropertyIndex > -1){
2084                                myFeedData[myFeedPropertyIndex].favorite = true;
2085                                myFeed.setMlsData(myFeedData);
2086                            }
2087
2088                        })
2089
2090                        copyPropertyToCollectionModal.hide();
2091                        toast.show('Property added to collection')
2092                        
2093                    }).catch((e) => {
2094                        toast.show('Error adding property to collection', true)
2095                    });
2096                }).subscribe();
2097
2098                Pubsub.subscription('collection_page_changed', (e) => {
2099                    collectionsService.getCollections(e, collectionPaging.collectionsPerPage).then((e) => {
2100                        if(e?.data?.Items){
2101                            collections = e.data.Items;
2102
2103                            collectionSection.collections.innerHTML = "";
2104                            count = 100;
2105                            e.data.Items.forEach((collection) => {
2106                            count--
2107                            
2108                                collectionSection.addCollectionCard(collection, count)
2109                            });
2110                        }
2111                    });
2112                }).subscribe();
2113
2114                Pubsub.subscription('share_saved_property_modal_share_pressed', (e) => {
2115                    toast.show('Link Copied!')
2116                }).subscribe();
2117
2118                Pubsub.subscription('my_feed_share_pressed', (e) => {
2119                    shareSavedPropertyModal.show(e.property);
2120                }).subscribe();
2121
2122                Pubsub.subscription('my_feed_add_collection_pressed', (e) => {
2123                    copyPropertyToCollectionModal.setIsAddingToCollection(true);
2124                    copyPropertyToCollectionModal.show(e.property);
2125                }).subscribe();
2126
2127                Pubsub.subscription('map_marker_clicked', (id) => {
2128                    propertySection.scrollIntoView(id);
2129
2130                    document.querySelectorAll('place-propertycard').forEach((propertyCard) => {
2131                        if(propertyCard.id == id) {
2132                            propertyCard.setAttribute('show_border', true)
2133                        }
2134                        else {
2135                            propertyCard.setAttribute('show_border', false)
2136                        } 
2137                    })
2138                }).subscribe();
2139
2140                Pubsub.subscription('my_feed_on_favorite_pressed', (e) => {
2141                    copyPropertyToCollectionModal.setIsAddingToCollection(true);
2142                    copyPropertyToCollectionModal.show(e.property);
2143                }).subscribe();
2144
2145                Pubsub.subscription('my_feed_on_unfavorite_pressed', (e) => {
2146                    let blossorId = e.property.blossorId;
2147                    let myFeedData = myFeed.getMlsData();
2148                    collectionsService.checkIfInCollection([blossorId]).then((propertiesInCollections) => {
2149                        if(propertiesInCollections.data[blossorId]){
2150                            propertiesInCollections.data[blossorId].forEac
2150h((collection) => {
2151                                collectionsService.removePropertyFromCollection(collection.collectionUUID, collection.propertyUUID).then(() => {
2152                                    
2153                                    let data =  copyPropertyToCollectionModal.getCollectionData();
2154                                    let collectionUUID = collection.collectionUUID;
2155                                    collectionsService.getCollectionProperties(collectionUUID,1,1).then((e) => {
2156                                    
2157                                         // update photos in add property to collection modal
2158                                        let collectionIndex =  data.findIndex((x) => x.id == collectionUUID);
2159                                        let collection = data[collectionIndex];
2160                                        let photo = e?.data?.properties?.length > 0 ? e?.data?.properties[0]?.photos[0]?.url : '';
2161                                    
2162                                        collection.propertiesImages = [];
2163                                        if(e?.data?.properties?.length > 0){
2164                                            collection.propertiesImages.push({mainPhoto: photo});
2165                                        }
2166                                        
2167                                        data[collectionIndex] = collection;
2168                                        
2169                                        copyPropertyToCollectionModal.setCollectionData(data);
2170
2171
2172                                         // update collection card if in collection view
2173                                        pageCollectionIndex = collections.findIndex((x) => x.collectionUUID == collectionUUID)
2174
2175                                        if(pageCollectionIndex > -1){
2176                                            
2177                                            let collectionCard = document.getElementById(collectionUUID);
2178                                            let numProperties = parseInt(collectionCard.getAttribute('num_properties'));
2179                                            numProperties--;
2180                                            collectionCard.setAttribute('num_properties', numProperties);
2181
2182                                            let images = collectionCard.getAttribute('image');
2183                                            let newImages = images.split(',').filter((x) => x == photo).join(',');
2184                                            collectionCard.setAttribute('image', newImages);
2185                                        }
2186
2187                                        //update my feed to set property heart as not favorited
2188                                        let myFeedPropertyIndex = myFeedData.findIndex((x) => x.blossorId == blossorId);
2189                                        if(myFeedPropertyIndex > -1){
2190                                            myFeedData[myFeedPropertyIndex].favorite = false;
2191                                            myFeed.setMlsData(myFeedData);
2192                                        }
2193                                    })
2194                                    toast.show('Property removed from collection');
2195                                }).catch((e) => {
2196                                    toast.show('Error removing from collection', true);
2197                                });
2198                            });
2199                        }
2200                    });
2201                }).subscribe();
2202
2203                let modalBackdrop = document.getElementsByClassName('center-modal');
2204                for(let i = 0; i < modalBackdrop.length; i++){
2205                    modalBackdrop[i].addEventListener('click', (e) => {
2206                        if(e.target == modalBackdrop[i]){
2207                            modalBackdrop[i].style.display = 'none';
2208                        }
2209                    });
2210                }
2211
2212                window.addEventListener( "hashchange", function( event ) {
2213                    if(window.location.hash == ''){
2214                        Pubsub.publish("top_header_back_pressed");
2215                    }
2216                });
2217
2218
2219                document.addEventListener("click", (e) => {
2220
2221                    const elements = document.querySelectorAll("[show_menu]");
2222                    elements.forEach((el) => {
2223                        el.setAttribute("show_menu", "false");
2224                    });
2225
2226                    document.getElementById("c2dfac72-6233-4e8d-b0d2-f44e4240ebb4")?.setAttribute("show_menu", "false");
2227                });
2228                if(window.innerWidth < 768 ){
2229                     savedListings.hide();
2230                     pageSubHeader.hideSecondaryButton();
2231                } else{
2232                    addListingBtn.hide();
2233                }
2234            })();
2235        }
2236    })
2237
2238</script>
2238 <div id="myportal-page" style="display:none"> <div style="position:relative; width:100%;"> <div style="position:absolute;z-index:110; top:0; bottom:0; "> <place-menu></place-menu> </div> <div class="collection-page" style="flex:1;"> <div class="page-width-parent"> <place-pagesubheader title="COLLECTIONS" show_top_header="false" button_title="Create New" button_icon="plus" secondary_button_icon="plus" secondary_button_title="Add Listings" show_secondary_button="false" show_menu="false" menu_items='[{ "icon": "edit-2", "text": "Edit Collection" },{ "icon": "trash", "text": "Delete Collection" }]' ></place-pagesubheader> <div id="collection-description" class="collection-description" style="display:none;"> <p class="collection-description-text" style="" ></p> </div> <div id="collection-section" style="margin-top:24px;"> <div id="collections" style="display:flex; flex-wrap:wrap"> <place-actioncard id="new-collection-block" style="display:none;" title="Create A Collection" sub_title="You can create a collection to save and keep track of your favorite properties." button_text="Create New" button_icon="plus" button_icon_fill="white" card_width="300" /> </div> <place-pagination id="collection-pagination" style="display:none"></place-pagination> <div class="my-feed-parent"> <place-myfeedblock style="display:none" display_menu="false"></place-myfeedblock> </div> </div> <div id="property-section"> <div id="property-header" style="display:flex; justify-content: space-between"> <p id="collection-saved-listings" class="collection-saved-listings"></p> <place-button icon="plus" ghost="true" btn_text_styles="text-[#5386E4]" icon_stroke="#5386E4" id="add-listing-btn" title="Add Listing"></place-button> <div style="padding: 0 5px; display:flex"> <place-icon id="property-list-icon" style="margin-right:10px" name="list" size="24" fill="none" stroke="black"></place-icon> <place-icon id="property-map-icon" name="map" size="24" fill="none" stroke="gray"></place-icon> </div> </div> <div class="property-container" style=""> <div id="property-list-parent"> <div id="property-list" class="property-list-list-view"> </div> <div> <place-actioncard id="add-listings-block" style="display:none;" title="Add Listings" sub_title="You can search and add properties to a collection to keep track of your favorite homes using the heart icon." button_text="Search Listings" button_icon="search" button_icon_fill="white" card_width="300" /> </div> </div> <div id="property-map" class="property-map-container" style="display:none" > <place-map map_type_control="true" zoom_control="true"> </place-map> </div> </div> <place-pagination id="property-pagination" class="property-pagination" style="display:none"></place-pagination> </div> </div> </div> </div> <place-basicmodal id="collection-created-modal" class="center-modal" style="display:none" title="Collection Created" sub_title="Would you like to add listings to your new collection? You can search for new listings or copy them from an existing collection." title_icon="heart" primary_button_text="View Collection" tertiary_button_text="Search" stacked_buttons="true" ></place-basicmodal> <place-basicmodal id="delete-collection-modal" class="center-modal" style="display:none" title="Delete Collection" sub_title="Deleting a collection will permanently remove it from your account. Your saved properties will only be visible in your Favorites collection." description="Are you sure you would like to delete this collection?" title_icon="trash" primary_button_text="Delete" tertiary_button_text="Cancel" no_stack_buttons="true" ></place-basicmodal> <place-basicmodal id="edit-collection-modal" class="center-modal" style="display:none" title="Changes Saved" sub_title="The changes to your collection have been saved." title_icon="check" primary_button_text="Close" ></place-basicmodal> <place-basicmodal id="delete-property-modal" class="center-modal" style="display:none" title="Remove Property" sub_title="Deleting this property will remove it from the current collection. Are you sure you would like to delete this property from your collection?" title_icon="trash" primary_button_text="Delete" tertiary_button_text="Cancel" no_stack_buttons="true" ></place-basicmodal> <place-basicmodal id="share-saved-property-modal" class="center-modal" style="display:none" title="Share Property" sub_title="Copy link to share property." title_icon="share" primary_button_text="Copy Link" ></place-basicmodal> <place-copycollectionmodal class="center-modal" style="display:none" collections='[]' ></place-copycollectionmodal> <place-collectionpopup class="center-modal" style="display:none"></place-collectionpopup> </div> <footer id="footer-9n" data-selector="footer" style="outline: none; cursor: inherit;"> <div class="container"> <div class="row"> <div class="col-md-2"> <div class="render-menu hot-nav"> <ul class="" style="outline: none; cursor: inherit;"><li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/index" style="outline: none; cursor: inherit;">Home</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/search" style="outline: none; cursor: inherit;">Listings</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/buying" style="outline: none; cursor: inherit;">Buying</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a class="white" href="/selling" style="outline: none; cursor: inherit;">Selling</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/financing" style="outline: none; cursor: inherit;">Financing</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/homevalue" style="outline: none; cursor: inherit;">Home Value</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/realestateagent/search" style="outline: none; cursor: inherit;">Who We Are</a> </li> <li class="nav-item" data-selector="li" style="outline: none; cursor: inherit;"> <a href="/connect" style="outline: none; cursor: inherit;">Connect</a> </li> </ul></div> </div>
2238 <div class="col-md-7 col-md-offset-1"> <form id="form-contact1" action="" class="form-contact"> <div class="row margin-bottom-0"> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_fname" id="contact1_fname" placeholder="First Name" class="form-control contact_fname" type="text" required="" style='background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAfBJREFUWAntVk1OwkAUZkoDKza4Utm61iP0AqyIDXahN2BjwiHYGU+gizap4QDuegWN7lyCbMSlCQjU7yO0TOlAi6GwgJc0fT/fzPfmzet0crmD7HsFBAvQbrcrw+Gw5fu+AfOYvgylJ4TwCoVCs1ardYTruqfj8fgV5OUMSVVT93VdP9dAzpVvm5wJHZFbg2LQ2pEYOlZ/oiDvwNcsFoseY4PBwMCrhaeCJyKWZU37KOJcYdi27QdhcuuBIb073BvTNL8ln4NeeR6NRi/wxZKQcGurQs5oNhqLshzVTMBewW/LMU3TTNlO0ieTiStjYhUIyi6DAp0xbEdgTt+LE0aCKQw24U4llsCs4ZRJrYopB6RwqnpA1YQ5NGFZ1YQ41Z5S8IQQdP5laEBRJcD4Vj5DEsW2gE6s6g3d/YP/g+BDnT7GNi2qCjTwGd6riBzHaaCEd3Js01vwCPIbmWBRx1nwAN/1ov+/drgFWIlfKpVukyYihtgkXNp4mABK+1GtVr+SBhJDbBIubVw+Cd/TDgKO2DPiN3YUo6y/nDCNEIsqTKH1en2tcwA9FKEItyDi3aIh8Gl1sRrVnSDzNFDJT1bAy5xpOYGn5fP5JuL95ZjMIn1ya7j5dPGfv0A5eAnpZUY3n5jXcoec5J67D9q+VuAPM47D3XaSeL4AAAAASUVORK5CYII="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%;'></div> </div> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_lname" id="contact1_lname" placeholder="Last Name" class="form-control contact_lname" type="text" required=""></div> </div> </div> <div class="row margin-bottom-0"> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_email" id="contact1_email" placeholder="Email Address" class="form-control contact_email" type="email" required=""></div> </div> <div class="col-sm-6" style="margin-bottom: 20px;"> <div class="form-group"> <input name="contact1_phone" id="contact1_phone" placeholder="Phone Number" class="form-control contact_phone" type="tel" required=""></div> </div> </div> <div class="row margin-bottom-0"> <div class="col-sm-12" style="margin-bottom: 20px;"> <i class="fa fa-caret-down" style="position: absolute; top: 13px; right: 30px; font-size: 14px; outline: none; cursor: inherit;" data-selector=".fa"></i> <select name="lead_type" style="width: 100%; height: 40px; padding-left: 12px; font-size: 14px; border-radius: 0; -webkit-appearance: none; -webkit-border-radius: 0px;"><option value="buyer">I'm interested in buying a home</option><option value="seller">I'm interested in selling a home</option><option value="seller/buyer">I'm interested in buying and selling</option><option value="tenant">I'm interested in finding a home to rent</option><option value="recruit">I'm interested in a real estate career</option><option value="n/a">Other reason to contact an agent</option></select></div> </div> <div class="row margin-bottom-0"> <div class="col-sm-12" style="margin-bottom: 20px;"> <textarea name="contact1_message" id="contact1_message" class="form-control contact_message" rows="3" placeholder="Your Message"></textarea></div> </div> <div class="text-right"> <input type="text" id="contact1_robot_field" name="contact1_robot_field" style="display: none;"><button type="submit" class="btn btn-primary squared" data-selector="a.btn, button.btn, button" style="outline: none; cursor: inherit;">Send Us A Message</button> </div> <div id="honeypot-div"> <input name="age_required" id="age_required" value="" type="text" style="display: none;"></div></form> </div> <div class="col-md-2 col-md-offset-1"> <img class="ftr-logo" src="https://images.brivityidx.com/assets/images/uploads/10784/footer-place-logo.png" alt="Buy and Sell Homes Real Estate" data-selector="img" style="border-style: none !important; outline: none; cursor: inherit;"><h3 class="text-left margin-top-40" data-selector="h1, h2, h3, h4, h5, h6" style="outline: none; cursor: inherit;">Reach Out</h3> <div class="text-left" style="outline: medium none; cursor: inherit;"> <ul style="list-style-type: none; outline: none; cursor: inherit;"> <li data-selector="li" style="outline: none; cursor: inherit;"> <span class="agent_address">14045 Ballantyne Corporate Place Suite 500</span> <span class="agent_city">Charlotte</span>, <span class="agent_state">North Carolina</span> <span class="agent_zip">28277</span> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="agent_phone_dynamic dynamic_loading dynamic_loading dynamic_loading dynamic_loading" href="tel:9807040299" src="tel:" style="outline: none; cursor: inherit;"></a> </li> </ul></div> </div> </div> <div class="row ftr-anchor"> <div class="col-sm-6 anchor-col no-padding editContent" style="outline: none; cursor: inherit;" data-selector=".editContent"> <p class="no-margin" style="outline: none; cursor: inherit;" data-selector="p"><span class="get_this_year">2022</span> © <b>Premier Property Solutions | <a href="https://www.place.com/" target="_blank">PLACE</a></b></p> <p style="margin: 10px 0px; outline: none; cursor: inherit;" data-selector="p"> <img src="https://images.brivityidx.com/assets/images/uploads/1428/Equal-Housing-Realtor_gray50.png" alt="Equal Housing | Realtor" style="width: 50px; outline: none; cursor: inherit;" data-selector="img">   Each office is independently owned and operated. </p> </div> <div class="col-sm-6 anchor-col no-padding"> <ul class="list-inline social" style="outline: none; cursor: inherit;"><li data-selector="li" style="outline: none; cursor: inherit;"> <a class="" href="https://www.facebook.com/MyPremierProperty/" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg></a> </li> <li data-selector="li" style="outline: none; cursor: inherit;"> <a class="" href="https://www.instagram.com/premierproperty_solutions/" target="_blank" style="outline: none; cursor: inherit;"> <svg viewbox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.5" y2="6.5"></line></svg></a> </li> </ul></div> </div> </div> </footer> </div> <section id="seo-anchor"> <div class="container"> <ul class="powered-by"> <li>Powered by <a class="pb-vendor" href="https://www.brivity.com/"> Brivity</a></li> <li class="pb-admin-login"><a href="https://login.brivityidx.com/login"><span class='pb-admin-login-text'>Admin Log In</span></a></li> </ul> <ul class="seo-anchor-links"> <li><a href="/privacy_policy">Privacy Policy</a></li> <li><a href="/tos">DMCA &amp; Terms of Service</a></li> <li><a id='sitemapUrl' href='/sitemap' style='display: inline;'>Sitemap</a></li> </ul> </div> </section> <input type="hidden" id="hchatbot_settings" data-chatbot-version="1" value="{&quot;chat_position&quot;:&quot;right&quot;,&quot;call_to_action_text&quot;:&quot;Hi there! Please let us know if you have any questions and an agent will reach out to you as soon as possible.&quot;,&quot;initial_message&quot;:&quot;Enter your question below and an agent will be in touch with you.&quot;,&quot;tags&quot;:&quot;IDX Chat&quot;,&quot;version&quot;:&quot;1&quot;}">
2239<!-- chatbot v1 -->
2240<!-- Chatbot drawer container -->
2241<div class="chatbot-drawer-container loading">
2242    <div class="chatbot-content-wrapper">
2243        <div class="chatbot-outside-content">
2244            <div class="chatbot-bubble-message-container cb-hide">
2245                <img src="https://cdn.brivity.com/images/people/28863551/2b37c1e1cc67758023a8060b11ff9814e79e4cf8-original.png?1756463957" class="chatbot-agent-img" alt="Agent profile image in chat bubble"/>
2246                <div id="call-to-action" class="bubble-message"></div>
2247                <button type="button" class="chatbox-bubble-close" data-dismiss="modal" aria-label="Close">
2248                    <span aria-hidden="true">&times;</span>
2249                </button>
2250            </div>
2251            <button id="chatbot-open-btn" class="chatbot-open-btn bg-prmry" aria-label="Chatbot Open Button">
2252                <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
2253                    <path d="M20.8 6.35501V16C20.8 17.765 19.365 19.195 17.6 19.195L11.2 19.2L5.755 22.28C5.645 22.365 5.52 22.4 5.4 22.4C5.09 22.4 4.8 22.155 4.8 21.8V19.2H3.2C1.4375 19.2 0 17.765 0 16V6.35501C0 4.63751 1.4375 3.20001 3.2 3.20001H17.6C19.365 3.20001 20.8 4.63751 20.8 6.35501ZM7.2 18.705L10.57 16.8H17.6C18.035 16.8 18.4 16.44 18.4 16V6.40001C18.4 5.96251 18.035 5.60001 17.6 5.60001H3.2C2.7625 5.60001 2.4 5.96251 2.4 6.40001V16C2.4 16.44 2.7625 16.8 3.2 16.8H7.2V18.705ZM12.8 22.4V20.8H15.2V22.4C15.2 22.835 15.56 23.2 16 23.2H21.43L24.8 25.105V23.2H28.8C29.235 23.2 29.6 22.835 29.6 22.4V12.8C29.6 12.365 29.235 12 28.8 12H22.4V9.60001H28.8C30.565 9.60001 32 11.035 32 12.755V22.4C32 24.165 30.565 25.6 28.8 25.6H27.2V28.2C27.2 28.555 26.91 28.8 26.6 28.8C26.48 28.8 26.355 28.765 26.245 28.68L20.8 25.6L16 25.595C14.24 25.595 12.8 24.165 12.8 22.4Z" fill="white"/>
2254                </svg>
2255            </button>
2256        </div>
2257        <div class="chatbot-drawer">
2258            <div class="chatbot-header bg-prmry">
2259                <div class="chatbot-agent-info">
2260                    <img src="https://cdn.brivity.com/images/people/28863551/2b37c1e1cc67758023a8060b11ff9814e79e4cf8-original.png?1756463957" class="chatbot-agent-img" alt="Agent profile image in chat header"/>
2261                    <div class="chatbot-agent">
2262                        <h3 class="chatbot-agent-name">Premier Property Solutions Team</h3>
2263                        <h4><span class="chatbot-agent-title"></span> | <span class="chatbot-agent-company">Premier Property Solutions | Charlotte, NC</span></h4>
2264                    </div>
2265                    <a id="chatbot-agent-phone" style="display: none;">(704) 286-0506</a>
2266                </div>
2267                <button id="close-chatbot-drawer" type="button" class="chatbox-modal-close" data-dismiss="modal" aria-label="Close">
2268                    <span aria-hidden="true">&times;</span>
2269                </button>
2270            </div>
2271            <div class="chatbot-body">
2272                <div class="chatbot-message-container">
2273                    <img src="https://cdn.brivity.com/images/people/28863551/2b37c1e1cc67758023a8060b11ff9814e79e4cf8-original.png?1756463957" class="chatbot-agent-img" alt="Agent profile image in message"/>
2274                    <h4 id="initial_message" class="chatbot-chat-messages not-loaded"></h4>
2275                    <div class="chatbot-chat-messages loading">
2276                        <span class="typing-indicator">
2277                            <span></span>
2278                            <span></span>
2279                            <span></span>
2280                        </span>
2281                    </div>
2282                </div>
2283                <form id="chatbotForm" class="chatbot-form">
2284                    <input type="name" id="chatbot_fullname" class="chatbox-form-control no-native-focus" placeholder="Full Name"
2285                        pattern="^[A-Za-z'\- ]+ [A-Za-z'\- ]+$"
2286                        required />
2287                    <input type="tel" id="chatbot_phone" class="chatbox-form-control no-native-focus" placeholder="Phone" required />
2288                    <input type="email" id="chatbot_email" class="chatbox-form-control no-native-focus" placeholder="Email"
2289                        pattern="^[^@\s]+@[^@\s]+\.[^@\s]+$"
2290                        required />
2291                    <textarea id="chatbot_message" class="chatbox-form-control chatbot-message" rows="5" name="notes" placeholder="Any Comments or Questions"></textarea>
2292                    <div class="chatbot-consent-container">
2293                        <div class="chatbot-toggle">
2294                                                            By proceeding and clicking the sign up button, you consent to receive calls and texts (SMS/MMS) including marketing and promotional communications, from <span class="agent_name_dynamic"></span>, its affiliates, and agents or vendors acting on their behalf. These 
2294communications may be delivered using an automatic telephone dialing system or by using an artificial or prerecorded voice. Message and data rates may apply. To opt out of text messages, reply STOP. Your consent is not required as a condition of any purchase. By continuing, you also agree to our <a class="opt-out-href" href="/tos">Terms of Use</a> and <a class="opt-out-href" href="/privacy_policy">Privacy Policy</a>.
2295                            </div>
2296                    </div>
2297                    <input type="hidden" id="chatbot_tags">
2298                                    </form>
2299            </div>
2300            <div class="chatbot-footer">
2301                <button type="submit" form="chatbotForm" class="chatbot-send bg-prmry chatbot-btn-disabled" data-dismiss="modal" aria-label="Close" disabled>
2302                    Send 
2303                    <span aria-hidden="true"> 
2304                        <svg class="chatbot-btn-icon" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2305                            <g clip-path="url(#clip0_2435_997)">
2306                                <path d="M14.6667 1.33331L7.33337 8.66665" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
2307                                <path d="M14.6667 1.33331L10 14.6666L7.33337 8.66665L1.33337 5.99998L14.6667 1.33331Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
2308                            </g>
2309                            <defs>
2310                                <clipPath id="clip0_2435_997">
2311                                    <rect width="16" height="16" fill="white"/>
2312                                </clipPath>
2313                            </defs>
2314                        </svg>
2315                    </span>
2316                </button>
2317            </div>
2318        </div>
2319    </div>
2320</div> <style>
2321                                .signup-consent-checkbox-section {
2322                                    display: none;
2323                                    flex-direction:column;
2324                                    align-items:flex-start;
2325                                    padding: 6px 0;
2326                                }
2327
2328                                .signup-consent-checkbox-section .checkbox {
2329                                    display:flex; 
2330                                    align-items:flex-start; 
2331                                    justify-content:center; 
2332                                    gap:8px; 
2333                                    padding:0 !important;
2334                                }
2335
2336                                .signup-consent-checkbox-section .checkbox input {
2337                                    position:unset;
2338                                    margin:2px 0 0 0 !important;
2339                                }
2340
2341                                .signup-consent-checkbox-section .checkbox span {
2342                                    color: #666666;
2343                                    font-size: 14px;
2344                                    font-weight: 400;
2345                                    line-height:16px;
2346                                }
2347
2348                                .signup-verbage {
2349                                    text-align:center;
2350                                    font-size:10px;
2351                                    line-height:16px;
2352                                }
2353
2354                                .signup-verbage span {
2355                                   color: #8C8C8C; 
2356                                   font-weight:600; 
2357                                }
2358
2359                                .signup-verbage a {
2360                                    color:#5386E4 !important;
2361                                    font-weight:400;
2362                                }
2363
2364                                .signup-verbage .twilio-enabled-verbage {
2365                                    display:none;
2366                                }
2367
2368                                
2369                                
2370                            </style> <div id="modal-mount" data-modal-bundle="https://cdn1.brivityidx.com/assets/modals/v1/all.html?ck=1789512948"></div>
2370 <div id="credential_picker_container_centered"> <div id="credential_picker_header_bar"> <p><button class="signOrLogBtn" onclick="showSignupModal();">Sign up</button> or <button class="signOrLogBtn" onclick="showLoginModal();">Login</button> another way</p> </div> <div id="credential_picker_header_bar_separator"></div> </div> <place-getyourhomecta id="contact_modal" style="display:none; justify-content: center; align-items: center; position:fixed; background-color:rgba(0,0,0,0.4); left:0; top:0; right:0; bottom:0; z-index: 100;" interest_items='[{"text":"Looking to sell ASAP"},{"text":"Looking to sell (1-3 months)"},{"text":"Looking to sell (3-6 months)"}, {"text":"Looking to sell (6-12 months)"},{"text":"Looking to sell (12+ months)"}, {"text":"Just curious"}]' > </place-getyourhomecta> <place-generictoast appear_from_both="true" container_style="right-1/2 z-200"></place-generictoast> 
2370<script>
2371            document.addEventListener("DOMContentLoaded", () => {
2372                class Toast {
2373                    constructor() {
2374                        this.element = document.querySelector('place-generictoast');
2375                    }
2376
2377                    show(message, error = false, link) {
2378                        var dispatch = function () {
2379                            window.dispatchEvent(
2380                                new CustomEvent("ShowToast", {
2381                                    detail: {
2382                                        text: message,
2383                                        error: error,
2384                                        link: link,
2385                                    },
2386                                })
2387                            );
2388                        };
2389                        if (window.sitebuilderPlaceComponents && window.sitebuilderPlaceComponents.ensureLoaded) {
2390                            window.sitebuilderPlaceComponents
2391                                .ensureLoaded('place-generictoast')
2392                                .then(dispatch)
2393                                .catch(function (err) {
2394                                    console.warn('toast.show fallback (web-components unavailable):', message, err);
2395                                });
2396                        } else {
2397                            dispatch();
2398                        }
2399                    }
2400                }
2401
2402                window.toast = new Toast();
2403            });
2404        </script>
2404 
2404<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>
2404 
2404<script src="https://maps.googleapis.com/maps/api/js?libraries=geocoding,places,marker,drawing&key=AIzaSyAjpuNg6WGCMV5rzoJcIP2QmMTVto6hYmc&map_ids=85c127b7bf0255d9"></script>
2404 
2404<script src="https://cdn1.brivityidx.com/assets/js/build.min.js?ck="></script>
2404 
2404<script src="https://cdn1.brivityidx.com/assets/js/top_bar_v2.min.js?ck="></script>
2404 
2404<script src="https://cdn1.brivityidx.com/assets/js/global_js.min.js?ck=1789512947"></script>
2404 
2404<script>deferScript("https://cdn1.brivityidx.com/assets/js/global_js_defer.min.js?ck=1789512947", 5000);</script>
2404 
2404<script>
2405            function shouldLoadChatbotImmediately() {
2406                const settingsEl = document.getElementById('hchatbot_settings');
2407                if (!settingsEl) return false;
2408
2409                const version = Number(settingsEl.dataset.chatbotVersion);
2410                let isInitialized = false;
2411
2412                try {
2413                    const session = JSON.parse(sessionStorage.getItem('cbSession') || '{}');
2414                    isInitialized = session.chatbotInitialized === true;
2415                } catch (e) {}
2416
2417                return version > 1 && isInitialized;
2418            }
2419        </script>
2419 
2419<script>document.getElementById('hchatbot_settings') && Number(document.getElementById('hchatbot_settings').dataset.chatbotVersion) > 1 && deferScript("https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/9.0.6/signalr.min.js", 0);</script>
2419 
2419<script>document.getElementById('hchatbot_settings') && deferScript(Number(document.getElementById('hchatbot_settings').dataset.chatbotVersion) > 1 ? "https://cdn1.brivityidx.com/assets/js/chatbot_v2.min.js?ck=1789512945" : "https://cdn1.brivityidx.com/assets/js/chatbot.min.js?ck=1789512945", shouldLoadChatbotImmediately() ? 50 : 5000);</script>
2419 
2419<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/jquery.geocomplete.min.js"></script>
2419<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.bootstrapvalidator/0.5.3/js/bootstrapValidator.min.js"></script>
2419<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/member_area_components.js"></script>
2419<script type="text/javascript" src="https://cdn1.brivityidx.com/assets/js/update_agent_info.js"></script>
2419 
2419<script src="https://mobile-component-services-library.s3.amazonaws.com/collections_service.min.js?ck=1"></script>
2419 
2419<script src="https://mobile-component-services-library.s3.amazonaws.com/messaging_service.min.js?ck=1"></script>
2419 
2419<script>$(document).ready(function(){$("#sitemap-listings > div.container > div > div.col-xs-12.col-md-12.col-lg-4.col-lg-push-8.seo-intro > a").attr("href","/search")});$(document).ready(function(){$("#sitemap-listings > div.container > div > div.col-xs-12.col-md-12.col-lg-4.col-lg-push-8.seo-intro > a").attr("href","/search")});$(document).ready(function(){$("ul.seo-anchor-links li:nth-of-type(4) a").attr("href","/search")})</script>
2419 
2419<script>(function($){$.fn.countTo=function(options){options=options||{};return $(this).each(function(){var settings=$.extend({},$.fn.countTo.defaults,{from:$(this).data('from'),to:$(this).data('to'),speed:$(this).data('speed'),refreshInterval:$(this).data('refresh-interval'),decimals:$(this).data('decimals')},options);var loops=Math.ceil(settings.speed/settings.refreshInterval),increment=(settings.to-settings.from)/loops;var self=this,$self=$(this),loopCount=0,value=settings.from,data=$self.data('countTo')||{};$self.data('countTo',data);if(data.interval){clearInterval(data.interval)}
2420data.interval=setInterval(updateTimer,settings.refreshInterval);render(value);function updateTimer(){value+=increment;loopCount++;render(value);if(typeof(settings.onUpdate)=='function'){settings.onUpdate.call(self,value)}
2421if(loopCount>=loops){$self.removeData('countTo');clearInterval(data.interval);value=settings.to;if(typeof(settings.onComplete)=='function'){settings.onComplete.call(self,value)}}}
2422function render(value){var formattedValue=settings.formatter.call(self,value,settings);$self.html(formattedValue)}})};$.fn.countTo.defaults={from:0,to:0,speed:1000,refreshInterval:100,decimals:0,formatter:formatter,onUpdate:null,onComplete:null};function formatter(value,settings){return value.toFixed(settings.decimals)}}(jQuery));jQuery(function($){$('.count-number').data('countToOptions',{formatter:function(value,options){return value.toFixed(options.decimals).replace(/\B(?=(?:\d{3})+(?!\d))/g,',')}});$('.timer').each(count);function count(options){var $this=$(this);options=$.extend({},options||{},$this.data('countToOptions')||{});$this.countTo(options)}})</script>
2422 
2422<script>$(document).ready(function(){const navIcons={"Home":`<svg class="nav-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.61 24"><path d="M21.09,8.28L11.76.35c-.55-.47-1.36-.47-1.91,0L.52,8.27c-.33.28-.52.69-.52,1.13v13.12c0,.82.66,1.48,1.48,1.48h18.65c.82,0,1.48-.66,1.48-1.48v-13.12c0-.43-.19-.85-.52-1.13ZM17.73,12.58l-3.1,3.05c-.07.07-.1.16-.08.26l.73,4.3c.04.24-.21.42-.42.31l-3.89-2.02c-.08-.04-.18-.04-.27,0l-3.88,2c-.21.11-.46-.07-.42-.31l.7-4.31c.02-.09-.02-.19-.08-.26l-3.13-3.07c-.17-.17-.08-.46.16-.5l4.32-.64c.09-.01.18-.07.22-.16l1.94-3.89c.11-.22.42-.22.52,0l1.97,3.91c.04.08.12.14.22.16l4.33.67c.24.04.33.33.16.5Z"></path></svg>`,"Search":`<i class="nav-icon fa fa-search"></i>`,"Buying":`<i class="nav-icon fa fa-key"></i>`,"Selling":`<i class="nav-icon fa fa-truck"></i>`,"Top Areas":`<i class="nav-icon fa fa-map-marker"></i>`,"Resources":`<i class="nav-icon fa fa-pencil"></i>`,"Neighborhood Heighlights":`<i class="nav-icon fa fa-sun-o"></i>`,"Careers":`<i class="nav-icon fa fa-briefcase"></i>`,"Financing":`<i class="nav-icon fa fa-usd"></i>`,"Who We Are":`<i class="nav-icon fa fa-user"></i>`,"Reviews":`<i class="nav-icon fa fa-star"></i>`,"Blog":`<i class="nav-icon fa fa-newspaper-o"></i>`,"Connect":`<i class="nav-icon fa fa-comment"></i>`,"Google Verification":`<i class="nav-icon fa fa-google"></i>`,};const defaultIcon=`<i class="nav-icon fa fa-circle"></i>`;$('#premium-navigation .main-nav .render-menu ul li a.sec-nav-link-color, #premium-navigation .main-nav .render-menu ul li a.dropdown-toggle').each(function(){const $link=$(this);if($link.find('svg, i.fa').not('.fa-angle-down').length===0){const linkText=$link.clone().children().remove().end().text().trim();const icon=navIcons[linkText]||defaultIcon;$link.prepend(icon)}});$('#premium-navigation.vertical-nav .navbar-nav > li > a').css('opacity','1')})</script>
2422 
2422<script>$('a[class$="propClone"]').attr('target','_blank')</script>
2422 
2422<script>var acc=document.getElementsByClassName("accordion");var i;for(i=0;i<acc.length;i++){acc[i].addEventListener("click",function(){this.classList.toggle("active");var panel=this.nextElementSibling;if(panel.style.display==="block"){panel.style.display="none"}else{panel.style.display="block"}})}
2423var acc=document.getElementsByClassName("accordion");var i;for(i=0;i<acc.length;i++){acc[i].addEventListener("click",function(){this.classList.toggle("active");var panel=this.nextElementSibling;if(panel.style.maxHeight){panel.style.maxHeight=null}else{panel.style.maxHeight=panel.scrollHeight+"px"}})}</script>
2423 
2423<script>function moveleftOne(){var element=document.getElementById("leftOne");element.classList.toggle("moveleftOne")}</script>
2423 
2423<script>function moveleftTwo(){var element=document.getElementById("leftTwo");element.classList.toggle("moveleftOne")}</script>
2423 
2423<script>function moveleftThree(){var element=document.getElementById("leftThree");element.classList.toggle("moveleftTwo")}</script>
2423 
2423<script>function moveleftFour(){var element=document.getElementById("leftFour");element.classList.toggle("moveleftOne")}</script>
2423 
2423<script>function moveleftFive(){var element=document.getElementById("leftFive");element.classList.toggle("moveleftOne")}</script>
2423 
2423<script>function moveleftSix(){var element=document.getElementById("leftSix");element.classList.toggle("moveleftTwo")}</script>
2423 </body> </html> 

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.