diff --git a/build/assets/js/main.js b/build/assets/js/main.js
index 8b80351..6c9ed94 100644
--- a/build/assets/js/main.js
+++ b/build/assets/js/main.js
@@ -1,2 +1,2 @@
-!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},t=(new Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="3684181e-c9e4-40bd-9bb8-66e5c9a86e6c",e._sentryDebugIdIdentifier="sentry-dbid-3684181e-c9e4-40bd-9bb8-66e5c9a86e6c")}catch(e){}}();var _global="undefined"!==typeof window?window:"undefined"!==typeof global?global:"undefined"!==typeof self?self:{};_global.SENTRY_RELEASE={id:"f168b5d5b0e4fcda9b4819db908db0f06bba82c1"},(self.webpackChunklocal_services_lookup=self.webpackChunklocal_services_lookup||[]).push([[179],{2789:(e,t,a)=>{class r extends HTMLElement{static get observedAttributes(){return["form","parcelStatus","user"]}constructor(){super(),this.form=null,this.parcelStatus="Invalid",this.user=null,this.styles=document.createElement("style"),this.styles.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100;700&display=swap')\n #geocoder {width: 100%}\n input {width: calc(100% - 2em); padding: 1em; border:.1em solid #e6e6e6; font-size: 1em;}\n ";const e=this.attachShadow({mode:"open"});e.appendChild(this.styles);const t=document.createElement("article");t.id="geocoder";let a=document.createElement("form"),r=document.createElement("label");r.style.fontFamily="Montserrat, sans-serif",r.style.fontWeight="bold";let n=document.createElement("input"),i=(document.createElement("ul"),document.createElement("datalist")),s=document.createElement("i");a.addEventListener("submit",(e=>{this.submit(e,this)})),s.className="fas fa-map-marker-alt";const o=document.getElementsByTagName("my-home-info");r.innerText="Property Address:";try{o[0].getAttribute("data-geocoder-label")&&""!=o[0].getAttribute("data-geocoder-label")&&(r.innerText=o[0].getAttribute("data-geocoder-label"))}catch(l){}r.setAttribute("for","geocoder-input"),n.type="text",n.setAttribute("list","addresses-list"),n.placeholder="Enter address",n.setAttribute("id","geocoder-input"),n.setAttribute("autocomplete","off"),n.addEventListener("keyup",(e=>{this.inputChange(e,this)})),i.setAttribute("id","addresses-list"),a.appendChild(r),a.appendChild(n),a.appendChild(s),a.appendChild(i),this.form=a,t.appendChild(a),e.appendChild(t)}supplementGeocoder(e,t,a){const r=document.getElementsByTagName("my-home-info");let n=e.split(",");n=n[0],n=n.split(" ");let i="",s=n.length;n.forEach((function(e,t){i+=e,te.json())).then((function(n){if("suggestions"===a)n.candidates.forEach((e=>{let a=document.createElement("option");""===e.attributes.parcel_id?(a.value=e.address,a.setAttribute("data-parsel","no-parcel")):(a.value=`${e.address} RECOMMENDED`,a.setAttribute("data-parsel",e.attributes.parcel_id)),a.onclick=e=>{t.selectSuggestion(e,t)},t.form.childNodes[3].appendChild(a)}));else if(n.candidates.length){let a=`https://services2.arcgis.com/qvkbeam7Wirps6zC/arcgis/rest/services/City_of_Detroit_Boundary/FeatureServer/0/query?where=&objectIds=&time=&geometry=${n.candidates[0].location.x}%2C+${n.candidates[0].location.y}&geometryType=esriGeometryPoint&inSR=4326&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&returnGeodetic=false&outFields=4326&returnGeometry=true&returnCentroid=false&multipatchOption=xyFootprint&maxAllowableOffset=&geometryPrecision=&outSR=&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnDistinctValues=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=geojson&token=`;try{fetch(a).then((e=>e.json())).then((function(a){if(a.features.length){let a,i=null;n.candidates.forEach((e=>{""!==e.attributes.parcel_id&&t.checkParcelValid(e.attributes.parcel_id)&&(i=e)})),a=null==i?n.candidates[0].location:null,null===i?(t.parcelStatus="Invalid",t.needGeocode(e,t,a),t.clearSuggestions(t),r[0].setAttribute("data-parcel-id",JSON.stringify(n.candidates[0]))):(t.parcelStatus="Valid",t.needGeocode(e,t,a),t.clearSuggestions(t),r[0].setAttribute("data-parcel-id",JSON.stringify(i)))}else t.parcelStatus="Invalid",t.needGeocode(e,t,location),t.clearSuggestions(t),r[0].setAttribute("data-app-state","error")}))}catch(i){t.parcelStatus="Invalid",t.needGeocode(e,t,location),t.clearSuggestions(t),r[0].setAttribute("data-app-state","error")}}else t.parcelStatus="Invalid",t.needGeocode(e,t,location),t.clearSuggestions(t),r[0].setAttribute("data-app-state","error")}))}catch(l){t.parcelStatus="Invalid",t.needGeocode(e,t,location),t.clearSuggestions(t),r[0].setAttribute("data-app-state","error")}}selectSuggestion(e,t){let a=null;a="SPAN"===e.target.tagName?e.target.parentNode:e.target,"no-parcel"===a.attributes[0].value?(t.clearSuggestions(t),t.supplementGeocoder(a.innerText,t,"submit")):t.supplementGeocoder(a.innerText,t,"submit")}inputChange(e,t){switch(e.key){case"Enter":""!=e.target.value&&void 0!=e.target.value&&t.supplementGeocoder(e.target.value,t,"submit");break;case"ArrowDown":case"ArrowUp":case"ArrowRight":case"ArrowLeft":break;case void 0:""!=e.target.value&&void 0!=e.target.value&&t.supplementGeocoder(e.target.value,t,"submit");break;default:t.clearSuggestions(t),t.supplementGeocoder(e.target.value,t,"suggestions")}}clearSuggestions(e){for(;e.form.childNodes[3].firstChild;)e.form.childNodes[3].removeChild(e.form.childNodes[3].firstChild)}needGeocode(e,t,a){fetch("https://us-central1-local-services-loopkup.cloudfunctions.net/getToken").then((e=>e.json())).then((function(r){let n=e.split(" RECOMMENDED")[0],i=[{attributes:{valid_parcel_status:t.parcelStatus,user_input:n},geometry:{x:0,y:0}}];null!=a&&(i[0].geometry.x=a.x,i[0].geometry.y=a.y);let s=new Request(`https://services2.arcgis.com/qvkbeam7Wirps6zC/ArcGIS/rest/services/addressvalidator/FeatureServer/0/addFeatures?token=${r.access_token}&features=${encodeURIComponent(JSON.stringify(i))}&f=json`,{method:"POST",body:"",headers:new Headers,mode:"cors",cache:"default"});fetch(s).then((e=>{}))}))}checkParcelValid(e){return/\d/.test(e)}submit(e,t){e.preventDefault(),t.supplementGeocoder(e.target[0].value,t,"submit")}}class n extends HTMLElement{constructor(){super();this.attachShadow({mode:"open"});this.navToolsStyle=document.createElement("style"),this.navToolsStyle.textContent="\n #nav-tools-wrapper { display: flex; flex-direction: column;}\n button.clear { font-size: 1.25em; width: 2.5em; height: 2.5em; background-color: #FEB70D; cursor: pointer; border: none; }\n button.nav { width: 3.75em; height: 3.75em; border: none; cursor: pointer;background: #fff; }\n button.nav:hover { background-color: #e6e6e6; transition: all 500ms cubic-bezier(.64,.09,.08,1); }\n button.nav.active { background-color: #9fd5b3; }\n button.nav img { width: 100%; }\n ",this.loadNavTools(this)}clearDisplay(e){const t=e.shadowRoot;for(;t.firstChild;)t.removeChild(t.firstChild)}loadNavTools(e){const t=document.getElementsByTagName("my-home-info"),a=t[0].getAttribute("data-app-state"),r=t[0].getAttribute("data-app-mode"),n=t[0].getAttribute("data-inital-sets"),i=t[0].getAttribute("data-initial-map-available"),s=e.shadowRoot;s.appendChild(e.navToolsStyle);const o=document.createElement("section");o.id="nav-tools-wrapper",o.setAttribute("role","navigation"),o.setAttribute("aria-label","Data Navigation");const l=document.createElement("cod-button");if(l.addEventListener("click",(e=>{"my-home-info"==t[0].getAttribute("data-app-mode")?(t[0].setAttribute("data-app-state","welcome-screen"),t[0].setAttribute("data-active-sets","assessors-data,neighborhood,recycling,rental-data,rental-cert,demo-status,blight-data,permit-data,DWSDBackupProtection")):(t[0].setAttribute("data-app-state","active-screen"),t[0].setAttribute("data-active-sets",n)),"true"==i?t[0].setAttribute("data-map-available","true"):t[0].setAttribute("data-map-available","false"),t[0].setAttribute("data-parcel-id","none"),t[0].setAttribute("data-api-stored-datasets","{}"),t[0].setAttribute("data-api-active-datasets","none"),t[0].setAttribute("data-active-section","property")})),l.setAttribute("data-primary",!0),l.setAttribute("data-label","x"),l.setAttribute("data-size","lg"),l.setAttribute("data-hover",!1),l.setAttribute("data-extra-classes","fw-bold"),l.setAttribute("data-background-color","warning"),l.setAttribute("data-img",""),l.setAttribute("data-img-alt",""),l.setAttribute("data-shape","square"),l.setAttribute("data-icon",""),o.appendChild(l),"my-home-info"==r&&"error"!=a){const e=document.createElement("cod-button");e.setAttribute("data-label",""),e.setAttribute("data-size","lg"),e.setAttribute("data-img","https://detroitmi.gov/sites/detroitmi.localhost/files/2023-01/home.png"),e.setAttribute("data-img-alt","about this property"),e.setAttribute("data-shape","square"),e.setAttribute("data-nav-value","about this property"),e.setAttribute("data-icon",""),"about this property"==t[0].getAttribute("data-active-section")?(e.setAttribute("data-background-color","success"),e.setAttribute("data-primary",!0)):(e.setAttribute("data-background-color","secondary"),e.setAttribute("data-primary",!1),e.addEventListener("click",(e=>{if("none"!=t[0].getAttribute("data-api-active-datasets")){let e=JSON.parse(t[0].getAttribute("data-api-stored-datasets")),a=JSON.parse(t[0].getAttribute("data-api-active-datasets"));for(const t in a)t in e||(e[t]=a[t]);t[0].setAttribute("data-api-stored-datasets",JSON.stringify(e))}t[0].setAttribute("data-api-active-datasets","none"),t[0].setAttribute("data-active-sets","assessors-data,neighborhood,recycling,rental-data,rental-cert,demo-status,blight-data,permit-data,DWSDBackupProtection"),t[0].setAttribute("data-map-available","false"),t[0].setAttribute("data-active-section","about this property"),t[0].setAttribute("data-app-state","loading-screen")}))),o.appendChild(e);const a=document.createElement("cod-button");a.setAttribute("data-label",""),a.setAttribute("data-size","lg"),a.setAttribute("data-img","https://detroitmi.gov/sites/detroitmi.localhost/files/2023-01/government.png"),a.setAttribute("data-img-alt","government officials"),a.setAttribute("data-shape","square"),a.setAttribute("data-nav-value","government officials"),a.setAttribute("data-icon",""),"government officials"==t[0].getAttribute("data-active-section")?(a.setAttribute("data-background-color","success"),a.setAttribute("data-primary",!0)):(a.setAttribute("data-background-color","secondary"),a.setAttribute("data-primary",!1),a.addEventListener("click",(e=>{if("none"!=t[0].getAttribute("data-api-active-datasets")){let e=JSON.parse(t[0].getAttribute("data-api-stored-datasets")),a=JSON.parse(t[0].getAttribute("data-api-active-datasets"));for(const t in a)t in e||(e[t]=a[t]);t[0].setAttribute("data-api-stored-datasets",JSON.stringify(e))}t[0].setAttribute("data-api-active-datasets","none"),t[0].setAttribute("data-active-sets","council,council-members,bop-members,district-managers,business-liaison,district-inspectors,npo"),t[0].setAttribute("data-map-available","false"),t[0].setAttribute("data-active-section","government officials"),t[0].setAttribute("data-app-state","loading-screen")}))),o.appendChild(a);const r=document.createElement("cod-button");r.setAttribute("data-label",""),r.setAttribute("data-size","lg"),r.setAttribute("data-img","https://detroitmi.gov/sites/detroitmi.localhost/files/2023-01/zone.png"),r.setAttribute("data-img-alt","special areas and zones"),r.setAttribute("data-shape","square"),r.setAttribute("data-nav-value","special areas and zones"),r.setAttribute("data-icon",""),"special areas and zones"==t[0].getAttribute("data-active-section")?(r.setAttribute("data-background-color","success"),r.setAttribute("data-primary",!0)):(r.setAttribute("data-background-color","secondary"),r.setAttribute("data-primary",!1),r.addEventListener("click",(e=>{if("none"!=t[0].getAttribute("data-api-active-datasets")){let e=JSON.parse(t[0].getAttribute("data-api-stored-datasets")),a=JSON.parse(t[0].getAttribute("data-api-active-datasets"));for(const t in a)t in e||(e[t]=a[t]);t[0].setAttribute("data-api-stored-datasets",JSON.stringify(e))}t[0].setAttribute("data-api-active-datasets","none"),t[0].setAttribute("data-active-sets","nez,nrsa,historicDistrict"),t[0].setAttribute("data-map-available","false"),t[0].setAttribute("data-active-section","special areas and zones"),t[0].setAttribute("data-app-state","loading-screen")}))),o.appendChild(r);const n=document.createElement("cod-button");n.setAttribute("data-label",""),n.setAttribute("data-size","lg"),n.setAttribute("data-img","https://detroitmi.gov/sites/detroitmi.localhost/files/2023-01/nearby.png"),n.setAttribute("data-img-alt","things nearby"),n.setAttribute("data-shape","square"),n.setAttribute("data-nav-value","things nearby"),n.setAttribute("data-icon",""),"things nearby"==t[0].getAttribute("data-active-section")?(n.setAttribute("data-background-color","success"),n.setAttribute("data-primary",!0)):(n.setAttribute("data-background-color","secondary"),n.setAttribute("data-primary",!1),n.addEventListener("click",(e=>{if("none"!=t[0].getAttribute("data-api-active-datasets")){let e=JSON.parse(t[0].getAttribute("data-api-stored-datasets")),a=JSON.parse(t[0].getAttribute("data-api-active-datasets"));for(const t in a)t in e||(e[t]=a[t]);t[0].setAttribute("data-api-stored-datasets",JSON.stringify(e))}t[0].setAttribute("data-api-active-datasets","none"),t[0].setAttribute("data-active-sets","schools,demos-data,stabilization-data,improve-det"),t[0].setAttribute("data-active-section","things nearby"),t[0].setAttribute("data-map-available","true"),t[0].setAttribute("data-app-state","loading-screen")}))),o.appendChild(n);const i=document.createElement("cod-button");i.setAttribute("data-label",""),i.setAttribute("data-size","lg"),i.setAttribute("data-img","https://detroitmi.gov/sites/detroitmi.localhost/files/2023-01/print.png"),i.setAttribute("data-img-alt","print"),i.setAttribute("data-shape","square"),i.setAttribute("data-nav-value","print"),i.setAttribute("data-icon",""),"print"==t[0].getAttribute("data-active-section")?(i.setAttribute("data-background-color","success"),i.setAttribute("data-primary",!0)):(i.setAttribute("data-background-color","secondary"),i.setAttribute("data-primary",!1),i.addEventListener("click",(e=>{e.target.getAttribute("data-nav-value")&&t[0].setAttribute("data-app-state","print")}))),o.appendChild(i)}s.appendChild(o)}}customElements.define("app-geocoder",r),customElements.define("app-nav-tools",n);class i extends HTMLElement{static get observedAttributes(){return["data-display-type","data-pagination"]}constructor(){super();this.attachShadow({mode:"open"});this.neighborhoodImage=document.createElement("img"),this.neighborhoodImage.src="https://detroitmi.gov/sites/detroitmi.localhost/files/2023-01/neighborhood.png",this.neighborhoodImage.setAttribute("alt",""),this.welcomeStyle=document.createElement("style"),this.welcomeStyle.textContent="\n @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100;700&display=swap')\n #display-wrapper { display: flex; padding: 1em; flex-wrap: wrap; font-family: 'Montserrat', sans-serif;}\n #display-wrapper #welcome-img-wrapper { display: flex; }\n #display-wrapper #welcome-img-wrapper img { height: 10em; margin: auto }\n #display-wrapper p { text-align: center; font-family: 'Montserrat', sans-serif;}\n #display-wrapper button { padding: 1em 3em; background-color: #004445; color: #fff; border: none; cursor: pointer; margin: auto; width: 100%;}\n p.display-title { font-weight: bold; font-size: 1.25em; }\n app-geocoder { width: 100%}\n .btn-group { display:flex; width: 100%; }\n @media all and (min-width: 551px) {\n #display-wrapper{ display: flex; }\n #display-wrapper #welcome-img-wrapper img { width: 15em; height: auto; }\n #display-wrapper article { flex: 1; padding: 1em; }\n }\n ",this.resultsStyle=document.createElement("style"),this.resultsStyle.textContent="\n .results-container{ display: flex; }\n #data-results { background-color: #e6e6e6; padding: 1em; height: 40em; overflow-y: auto; }\n .data-title { font-weight: bold; border-left: solid .2em #FEB70D; padding: .5em; margin: 0 0 1em 0; font-family: 'Montserrat', sans-serif;}\n .result-address {background-color: #fff; border: solid 0.1em #e6e6e6; padding: 1.04em 0.6em; font-family: 'Montserrat', sans-serif;}\n .data-block-title { padding: .5em; background-color: #FEB70D; margin: 0; font-weight: bold; font-family: 'Montserrat', sans-serif; display: flex;}\n .data-block-title span { flex: 1; margin: auto; }\n .data-block-content { padding: .5em; margin-bottom: .5em; background-color: #fff; }\n .data-block-content p { margin: 0; font-family: 'Montserrat', sans-serif;}\n .data-block-content hr { border-top: 1px dotted;}\n .dataset-results {flex: 1;}\n .critical-text { color: #CF3234; }\n .error-result { padding: 1em; }\n .data-block-title button { background-color: #fff; border: none; padding: 0.25em 0.5em; box-shadow: 1px 1px 3px 0px rgb(0 0 0 / 75%);}\n .data-block-title button img { height: 1em; }\n @media all and (min-width: 551px) {\n #data-results { height: auto; }\n #data-blocks { column-count: 2; }\n #data-blocks .data-block { -webkit-column-break-inside: avoid; page-break-inside: avoid; break-inside: avoid; }\n }\n\n @media all and (min-width: 1024px) {\n #data-results { height: auto; }\n #data-blocks { column-count: 3; }\n #data-blocks .data-block { -webkit-column-break-inside: avoid; page-break-inside: avoid; break-inside: avoid; }\n }\n ",this.loadDisplay(this)}attributeChangedCallback(e,t,a){"results"==a&&this.clearDisplay(this),"data-pagination"==e&&this.clearDisplay(this),this.loadDisplay(this)}clearDisplay(e){const t=e.shadowRoot;for(;t.firstChild;)t.removeChild(t.firstChild)}formatDate(e){const t=new Date(e);return`${["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][t.getMonth()]} ${t.getDate()}, ${t.getFullYear()}`}buildCouncil(e){let t=window.location.hostname,a={title:"Council District",content:null};return a.content=`\n
District Number: ${e.data.district}
\nCouncil Member: ${e.data.name}
\nCouncil Member Phone: ${e.data.phone}
\n `,a}buildBOP(e){let t=window.location.hostname,a={title:"Police Commissioner",content:null};return a.content=`\nCommissioner: ${e.data.name}
\nCommissioner's Phone: ${e.data.phone}
\nCommissioner's Email: ${e.data.email}
\n `,a}buildDistrictManagers(e){let t={title:"District Managers",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nDistrict Manager: ${e.data.manager.name}
\nManager Phone: ${e.data.manager.phone}
\nDeputy Manager: ${e.data.deputy.name}
\nDeputy Manager Phone: ${e.data.deputy.phone}
\n `:t.content="\nNo data found
\n ",t}buildBusinessLiaison(e){let t={title:"Business Liaison",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nLiaison: ${e.data.name}
\nLiaison Phone: ${e.data.email}
\n `:t.content="\nNo data found
\n ",t}buildInspector(e){let t={title:"Enforcement Inspector",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nInspector: ${e.data.name}
\nInspector Phone: ${e.data.phone}
\n `:t.content="\nNo data found
\n ",t}buildNeighborhood(e){let t={title:"Neighborhood",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nNeighborhood name: ${e.data.attributes.neighborhood_name}
\n `:t.content="\nNo neighborhood found
\n ",t}buildDWSDBackupProtection(e){let t=["Aviation Sub","Barton-McFarland","Chadsey Condon","Cornerstone Village","East English Village","Morningside","Jefferson Chalmers","Warrendale","Victoria Park","Moross-Morang","Garden View"],a={title:"DWSD Basement Backup Protection Program",content:null};return e&&e.data.attributes.neighborhood_name&&t.includes(e.data.attributes.neighborhood_name)?a.content=`\nThis property qualifies for the DWSD Basement Backup Protection Program.
\nThis property doesn\'t qualify for the Basement Backup Protection Program. To learn more please visit our page.
\n ',a}buildHRDFlooding(e){let t=["Cornerstone Village","Morningside","Chandler Park","Fox Creek","Riverbend","Morningside","West End ","Midwest","Chadsey\u2010Condon","Claytown","North Corktown","Michigan\u2010 Martin","Aviation Sub","Garden View","Plymouth\u2010I96","Plymouth\u2010Hubell","Paveway","We Care Community","Fiskhorn","Joy-Schaefer","Warrendale","Warren Ave Community","Barton-McFarland"],a={title:"CDBG Disaster Recovery Basement Backup Protection Program",content:null};return e&&e.data.attributes.neighborhood_name&&t.includes(e.data.attributes.neighborhood_name)?a.content='\nThis property qualifies for the CDBG Disaster Recovery Basement Backup Protection Program.
\nThis property doesn\u2019t qualify for the CDBG Disaster Recovery Basement Backup Protection Program. To learn more please visit our page.
\n ',a}buildHistoricDistrict(e,t){let a={title:"NEZ Homestead Zone",content:null};return 0!=Object.keys(e.data).length&&e.data.constructor===Object&&e.data.features.length>0?a.content=`\nNAME: ${e.data.features[0].attributes.Name}
\nDESIGNATED ON: ${t.formatDate(e.data.features[0].attributes.Year_Enacted).format("MMM DD, YYYY")}
\n `:a.content="\nThis property is not in a historic district.
\n ",a}buildNEZ(e){let t={title:"NEZ Homestead Zone",content:null};return 0!=Object.keys(e.data).length&&e.data.constructor===Object&&e.data.features.length>0?t.content=`\nName: ${e.data.features[0].attributes.RNNAME}
\nID: ${e.data.features[0].attributes.RID}
\n \n `:t.content='\nThis property is not on a NEZ Homestead zone.
\n \n ',t}buildNRSA(e){let t={title:"Neighborhood Revitalization Strategy Areas (NRSA)",content:null};return 0!=Object.keys(e.data).length&&e.data.constructor===Object&&e.data.features.length>0?t.content=`\nName: ${e.data.features[0].attributes.Name}
\n `:t.content="\nThis property is not on a NRSA.
\n ",t}buildNPO(e){let t={title:"Police",content:null};return e&&e.data.features.length?t.content=`\nPRECINCT
\nNumber: ${e.data.features[0].attributes.precinct}
\nAddress: ${e.data.features[0].attributes.precinct_location}
\nNEIGHBORHOOD POLICE OFFICER (NPO)
\nName: ${e.data.features[0].attributes.officer_name}
\nPhone: ${e.data.features[0].attributes.npo_cell_phone}
\nEmail: ${e.data.features[0].attributes.npo_email}
\n `:t.content="No police info found
",t}checkRecyclingStatus(e){try{if(e.next_pickups["yard waste"]){let t=null,a=null;return e.details.forEach((e=>{"start-date"==e.type&&"yard waste"==e.service&&(t=null!=e.normalDay?e.normalDay:e.newDay),"end-date"==e.type&&"yard waste"==e.service&&(a=null!=e.normalDay?e.normalDay:e.newDay)})),!!moment(e.next_pickups["yard waste"].next_pickup).isBetween(t,a)}return!1}catch(t){return!1}}buildRecycling(e,t){let a={title:"Trash & Recycling",content:null};if(e&&0!=Object.keys(e.data).length&&e.data.constructor===Object){let r={name:null,url:null,phone:null};"GFL"===e.data.next_pickups.trash.contractor?(r.name="GFL",r.url="http://gflusa.com/residential/detroit/",r.phone="(844) 464-3587"):(r.name="WM",r.url="http://www.advanceddisposal.com/mi/detroit/detroit-residential-collection",r.phone=" (844) 233-8764"),a.content=`\nProvider: ${r.name} ${r.phone}
\nNext Trash: ${t.formatDate(e.data.next_pickups.trash.next_pickup)}
\nNext Recycling: ${t.formatDate(e.data.next_pickups.recycling.next_pickup)}
\nNext Bulk: ${t.formatDate(e.data.next_pickups.bulk.next_pickup)}
\n ${t.checkRecyclingStatus(e.data)?tempHTML+=`Next Yard: ${t.formatDate(e.data.next_pickups["yard waste"].next_pickup)}
`:""}\n `}else a.content="No data found
";return a}buildAssessors(e){let t={title:"Assessor's Data",content:null};if(e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail){let a={year:null,value:null,floor:null,buildingClass:null};t.content=`\nOwner's address: ${e.data.ownerstreetaddr}
\nOwner's city: ${e.data.ownercity}
\nOwner's state: ${e.data.ownerstate}
\nOwner's zip: ${e.data.ownerzip}
\n `,0===e.data.resb_bldgclass?(a.year=e.data.cib_yearbuilt,a.value=e.data.cib_value,a.floor=e.data.cib_yearbuilt,a.buildingClass=e.data.cib_yearbuilt):(a.year=e.data.resb_yearbuilt,a.value=e.data.resb_value,a.floor=e.data.resb_floorarea,a.buildingClass=e.data.resb_bldgclass),t.content+=`\nParcel number: ${e.data.pnum}
\nYear build: ${a.year}
\nCalculated value: $${a.value.toLocaleString()}
\nFloor area: ${a.floor.toLocaleString()} SQFT
\nBuilding class: ${a.buildingClass}
\n `}else t.content="No data found
";return t}buildRental(e,t){let a=document.getElementsByTagName("my-home-info"),r=JSON.parse(a[0].getAttribute("data-api-active-datasets")),n={title:"Rental Enforcement Status",content:null};return e&&e.data.features.length||r["rental-cert-data"]&&r["rental-cert-data"].data.features.length?n.content=`\nRegistered: ${e.data.features.length?`${t.formatDate(e.data.features[0].attributes.date_status)}`:"Not registered"}
\nCertified: ${r["rental-cert-data"].data.features.length?`${t.formatDate(r["rental-cert-data"].data.features[0].attributes.issued_date)}`:"Not certified"}
\n `:n.content="\nRegistered: Not registered
\nCertified: Not certified
\n ",n}buildFireEscrow(e){let t="";return e&&e.data.features.length?t+='\nSTATUS: Fire Escrow not found
\nTicket ID: ${e.attributes.ticket_number}
\nFine Amount: $${e.attributes.fine_amount}
\nAgency name: ${e.attributes.agency_name}
\nDisposition: ${e.attributes.disposition}
\nDescription: ${e.attributes.violation_description}
\nHearing Date: ${t.formatDate(e.attributes.hearing_date)}
\nHearing Time: ${e.attributes.hearing_time}
\n `:a.content="No blight tickets found
",a}buildSchools(e,t){let a={title:"Schools",content:null};return e&&e.data.features.length?e.data.features.forEach((function(e,t){0==t?a.content=`\nName: ${e.properties.EntityOfficialName}
\nEntityActualGrades: ${e.properties.EntityActualGrades}
\nType: ${e.properties.EntityTypeName}
\nAddress: ${e.properties.EntityPhysicalStreet}
\nName: ${e.properties.EntityOfficialName}
\nEntityActualGrades: ${e.properties.EntityActualGrades}
\nType: ${e.properties.EntityTypeName}
\nAddress: ${e.properties.EntityPhysicalStreet}
\nNo schools nearby.
",a}buildPermit(e,t){let a={title:"Building Permits",content:null};return e&&e.data.features.length?a.content=`\nPERMIT NUMBER: ${e.attributes.record_id}
\nPERMIT TYPE: ${e.attributes.permit_type}
\nPERMIT BUILDING TYPE: ${e.attributes.permit_type}
\nPERMIT STATUS: ${e.attributes.status}
\nPERMIT ISSUED: ${t.formatDate(e.attributes.issued_date)}
\nPERMIT DESCRIPTION: ${e.attributes.description_of_work}
\n `:a.content="No building permits found
",a}buildDemoStatus(e,t){let a=document.getElementsByTagName("my-home-info"),r=JSON.parse(a[0].getAttribute("data-parcel-id")).address.replace(" ","%2520");r=r.replace(",","%252C");let n={title:"Demolition Status",content:null};return e&&e.data.features.length?n.content=`\nWARNIG!
\nTHIS PROPERTY IS SCHEDULED FOR DEMOLITION
\n ${null==e.data.features[0].attributes.demolish_by_date?"Date to be determined
":`${t.formatDate(e.attributes.demolish_by_date)}
`}\nThis property is not on the demolition list
\nAddress: ${e.properties.address}
\nCommercial: ${e.properties.commercial_building}
\nPrice: $${parseInt(e.properties.price).toLocaleString()}
\nParcel: ${e.properties.parcel_id}
\nContractor: ${e.properties.contractor_name}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\n ${void 0==e.properties.demolish_by_date||null==e.properties.demolish_by_date?"Expected Date: Date to be determined
":`Expected Date:${t.formatDate(e.properties.demolish_by_date)}
`}\nAddress: ${e.properties.address}
\nCommercial: ${e.properties.commercial_building}
\nPrice: $${parseInt(e.properties.price).toLocaleString()}
\nParcel: ${e.properties.parcel_id}
\nContractor: ${e.properties.contractor_name}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\n ${void 0==e.properties.demolish_by_date||null==e.properties.demolish_by_date?"Expected Date: Date to be determined
":`Expected Date:${t.formatDate(e.properties.demolish_by_date)}
`}\nNo demolitions are happening nearby.
",a}buildStabilizationsNear(e,t){let a={title:"Stabilizations Nearby",content:null};return e&&e.data.features.length?e.data.features.forEach((function(e,t){0==t?a.content=`\nAddress: ${e.properties.address}
\nParcel: ${e.properties.parcel_id}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\nStatus: ${e.properties.rehab_status}
\nAddress: ${e.properties.address}
\nParcel: ${e.properties.parcel_id}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\nStatus: ${e.properties.rehab_status}
\nNo stabilizations are happening nearby.
",a}buildImproveDet(e,t){let a={title:"Improve Detroit Issues Nearby",content:null};return e&&e.data.features.length?e.data.features.forEach((function(e,r){0==r?a.content=`\n \nType: ${e.properties.Request_Type_Title}
\nStatus: ${e.properties.Status}
\nReported on: ${t.formatDate(e.properties.Created_At)}
\nType: ${e.properties.Request_Type_Title}
\nStatus: ${e.properties.Status}
\nReported on: ${t.formatDate(e.properties.Created_At)}
\nNo active issues nearby.
",a}selectDataBlockType(e,t){switch(t.id){case"council-members":try{return e.buildCouncil(t)}catch(a){return""}break;case"bop-members":try{return e.buildBOP(t)}catch(a){return""}break;case"district-managers":try{return e.buildDistrictManagers(t)}catch(a){return""}break;case"business-liaison":try{return e.buildBusinessLiaison(t)}catch(a){return""}break;case"district-inspectors":try{return e.buildInspector(t)}catch(a){return""}break;case"neighborhood":try{return e.buildNeighborhood(t)}catch(a){return""}break;case"nez":try{return e.buildNEZ(t)}catch(a){return""}break;case"nrsa":try{return e.buildNRSA(t)}catch(a){return""}break;case"assessors-data":try{return e.buildAssessors(t)}catch(a){return""}break;case"permit-data":try{return e.buildPermit(t,e)}catch(a){return""}break;case"rental-data":try{return e.buildRental(t,e)}catch(a){return""}break;case"blight-data":try{return e.buildBlight(t,e)}catch(a){return""}break;case"demos-data":try{return e.buildDemosNear(t,e)}catch(a){return""}break;case"stabilization-data":try{return e.buildStabilizationsNear(t,e)}catch(a){return""}break;case"demo-status":try{return e.buildDemoStatus(t)}catch(a){return""}break;case"npo":try{return e.buildNPO(t)}catch(a){return""}break;case"improve-det":try{return e.buildImproveDet(t,e)}catch(a){return""}break;case"schools":try{return e.buildSchools(t,e)}catch(a){return""}break;case"recycling":try{return e.buildRecycling(t,e)}catch(a){return""}break;case"historicDistrict":try{return e.buildHistoricDistrict(t)}catch(a){return""}break;case"fireEscrow":try{return e.buildFireEscrow(t)}catch(a){return""}break;case"DWSDBackupProtection":try{return e.buildDWSDBackupProtection(t)}catch(a){return""}break;case"HRDFlooding":try{return e.buildHRDFlooding(t)}catch(a){return""}break;default:return""}}setDatasetPagination(e,t){if(e.hasAttribute("data-pagination")){let a=JSON.parse(e.getAttribute("data-pagination"));if(a[t.id]){let e={start:a[t.id].start};return t.data.features.length<=a[t.id].end+3?(e.end=t.data.features.length,e.more=!1):(e.end=a[t.id].end+3,e.more=!0),e}{let e={start:0,end:3,more:!0};return t.data.features?t.data.features.length<=3&&(e.end=t.data.features.length,e.more=!1):(e.start=null,e.more=!1),e}}{let e={start:0,end:3,more:!0};return t.data.features?t.data.features.length<=3&&(e.end=t.data.features.length,e.more=!1):(e.start=null,e.more=!1),e}}printInfo(e){let t=e.buildDataSection(e),a=window.open("","","height=500, width=500");a.document.write(""),a.document.write(""),a.document.write(""),a.document.write(t.children[1].innerHTML),a.document.write(""),a.document.close(),a.print()}buildDataBlock(e,t){const a=document.getElementsByTagName("my-home-info"),r=a[0].getAttribute("data-map-available"),n=document.createElement("article");n.className="data-block";let i=e.setDatasetPagination(e,t),s=JSON.parse(JSON.stringify(t));null!==i.start&&(s.data.features=t.data.features.slice(i.start,i.end));let o=e.selectDataBlockType(e,s);if(void 0==o||null==o.content)return null;{const s=document.createElement("p");s.className="data-block-title";const l=document.createElement("article");if(l.className="data-block-content",l.innerHTML=o.content,"true"==r){const e=document.createElement("span");e.innerText=o.title;const r=document.createElement("cod-button");r.setAttribute("data-map-active-data",t.id),r.setAttribute("data-label","View Map"),r.setAttribute("data-size","xsmall"),r.setAttribute("data-icon",""),r.setAttribute("data-img","https://detroitmi.gov/sites/detroitmi.localhost/files/2023-02/map.png"),r.setAttribute("data-img-alt","map"),r.setAttribute("data-shape",""),r.setAttribute("data-hover",!1),r.setAttribute("data-extra-classes","fw-bold"),r.setAttribute("data-background-color","light"),r.setAttribute("data-primary",!0),r.addEventListener("click",(e=>{e.target.getAttribute("data-map-active-data")&&(a[0].setAttribute("data-map-active-data",e.target.getAttribute("data-map-active-data")),a[0].setAttribute("data-app-state","map"))})),s.appendChild(e),s.appendChild(r)}else s.innerText=o.title;if(n.appendChild(s),n.appendChild(l),i.more){let a=document.createElement("cod-button");a.setAttribute("data-pagination-id",t.id),a.setAttribute("data-pagination",JSON.stringify(i)),a.setAttribute("data-label","Load More +"),a.setAttribute("data-size","xsmall"),a.setAttribute("data-icon",""),a.setAttribute("data-img",""),a.setAttribute("data-img-alt",""),a.setAttribute("data-shape",""),a.setAttribute("data-hover",!1),a.setAttribute("data-extra-classes","fw-bold"),a.setAttribute("data-background-color","primary"),a.setAttribute("data-primary",!1),a.addEventListener("click",(t=>{if(t.target.getAttribute("data-pagination")){let a=document.createElement("cod-spinner");a.setAttribute("data-type","border"),a.setAttribute("data-background-color","primary"),a.setAttribute("data-size","sm");let r=e.getAttribute("data-pagination");r=null===r?{}:JSON.parse(r),r[`${t.target.getAttribute("data-pagination-id")}`]=JSON.parse(t.target.getAttribute("data-pagination")),e.setAttribute("data-pagination",JSON.stringify(r)),t.target.parentElement.appendChild(a),t.target.remove()}})),l.appendChild(a)}return n}}buildDataSection(e){const t=document.getElementsByTagName("my-home-info"),a=t[0].getAttribute("data-app-mode"),r=document.createElement("section");if(r.id="data-results","my-home-info"==a){const e=document.createElement("p");e.className="data-title",e.innerText=t[0].getAttribute("data-active-section").toUpperCase(),r.appendChild(e)}const n=document.createElement("div");n.id="data-blocks",r.appendChild(n);const i=JSON.parse(t[0].getAttribute("data-api-active-datasets"));for(const s in i)Object.hasOwnProperty.call(i,s)&&null!=e.buildDataBlock(e,i[s])&&n.appendChild(e.buildDataBlock(e,i[s]));return r}loadDisplay(e){const t=e.shadowRoot,a=document.createElement("section"),r=document.createElement("app-geocoder"),n=document.createElement("app-nav-tools"),i=document.getElementsByTagName("my-home-info");switch(n.printInfo=e.printInfo,a.id="display-wrapper",this.getAttribute("data-display-type")){case"welcome":t.appendChild(e.welcomeStyle);const s=document.createElement("div");s.id="welcome-img-wrapper",s.appendChild(this.neighborhoodImage),a.appendChild(s);const o=document.createElement("article");a.appendChild(o);const l=document.createElement("p");l.setAttribute("aria-label","title"),l.innerText="It\u2019s all here. All in one place.",l.className="display-title",o.appendChild(l);const d=document.createElement("p");d.innerText="Enter your home address to find out your city councilmember and neighborhood district manager, along with local information about trash/recycling, your neighborhood police officer, city issues reported in your neighborhood, and more.",o.appendChild(d),o.appendChild(r),t.appendChild(a);break;case"active":t.appendChild(e.welcomeStyle),a.appendChild(r),t.appendChild(a);break;case"loading":const c=document.createElement("cod-loader");c.setAttribute("data-color","color-3"),a.appendChild(c),t.appendChild(a);break;case"results":let u=JSON.parse(i[0].getAttribute("data-parcel-id"));t.appendChild(e.resultsStyle);let p=document.createElement("section");p.className="results-container",p.appendChild(n);let m=document.createElement("article");m.className="dataset-results";let g=document.createElement("article");g.className="result-address",g.innerText=u.address,m.appendChild(g);let b=e.buildDataSection(e);m.appendChild(b),p.appendChild(m),a.appendChild(p),t.appendChild(a);break;case"error":let h=document.createElement("section");t.appendChild(e.resultsStyle),h.className="results-container",h.appendChild(n);let f=document.createElement("article");f.className="error-result",f.innerHTML='\n \nDistrict Number: ${e.data.district}
\nCouncil Member: ${e.data.name}
\nCouncil Member Phone: ${e.data.phone}
\n `,a}buildBOP(e){let t=window.location.hostname,a={title:"Police Commissioner",content:null};return a.content=`\nCommissioner: ${e.data.name}
\nCommissioner's Phone: ${e.data.phone}
\nCommissioner's Email: ${e.data.email}
\n `,a}buildDistrictManagers(e){let t={title:"District Managers",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nDistrict Manager: ${e.data.manager.name}
\nManager Phone: ${e.data.manager.phone}
\nDeputy Manager: ${e.data.deputy.name}
\nDeputy Manager Phone: ${e.data.deputy.phone}
\n `:t.content="\nNo data found
\n ",t}buildBusinessLiaison(e){let t={title:"Business Liaison",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nLiaison: ${e.data.name}
\nLiaison Phone: ${e.data.email}
\n `:t.content="\nNo data found
\n ",t}buildInspector(e){let t={title:"Enforcement Inspector",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nInspector: ${e.data.name}
\nInspector Phone: ${e.data.phone}
\n `:t.content="\nNo data found
\n ",t}buildNeighborhood(e){let t={title:"Neighborhood",content:null};return e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail?t.content=`\nNeighborhood name: ${e.data.attributes.neighborhood_name}
\n `:t.content="\nNo neighborhood found
\n ",t}buildDWSDBackupProtection(e){let t=["Aviation Sub","Barton-McFarland","Chadsey Condon","Cornerstone Village","East English Village","Morningside","Jefferson Chalmers","Warrendale","Victoria Park","Moross-Morang","Garden View"],a={title:"DWSD Basement Backup Protection Program",content:null};return e&&e.data.attributes.neighborhood_name&&t.includes(e.data.attributes.neighborhood_name)?a.content=`\nThis property qualifies for the DWSD Basement Backup Protection Program.
\nThis property doesn\'t qualify for the Basement Backup Protection Program. To learn more please visit our page.
\n ',a}buildHRDFlooding(e){let t=["Cornerstone Village","Morningside","Chandler Park","Fox Creek","Riverbend","Morningside","West End ","Midwest","Chadsey\u2010Condon","Claytown","North Corktown","Michigan\u2010 Martin","Aviation Sub","Garden View","Plymouth\u2010I96","Plymouth\u2010Hubell","Paveway","We Care Community","Fiskhorn","Joy-Schaefer","Warrendale","Warren Ave Community","Barton-McFarland"],a={title:"CDBG-DR Private Sewer Repair Program",content:null};return e&&e.data.attributes.neighborhood_name&&t.includes(e.data.attributes.neighborhood_name)?a.content='\nThis property qualifies for the CDBG-DR Private Sewer Repair Program.
\nThis property doesn\u2019t qualify for the CDBG-DR Private Sewer Repair Program. To learn more please visit our page.
\n ',a}buildHistoricDistrict(e,t){let a={title:"NEZ Homestead Zone",content:null};return 0!=Object.keys(e.data).length&&e.data.constructor===Object&&e.data.features.length>0?a.content=`\nNAME: ${e.data.features[0].attributes.Name}
\nDESIGNATED ON: ${t.formatDate(e.data.features[0].attributes.Year_Enacted).format("MMM DD, YYYY")}
\n `:a.content="\nThis property is not in a historic district.
\n ",a}buildNEZ(e){let t={title:"NEZ Homestead Zone",content:null};return 0!=Object.keys(e.data).length&&e.data.constructor===Object&&e.data.features.length>0?t.content=`\nName: ${e.data.features[0].attributes.RNNAME}
\nID: ${e.data.features[0].attributes.RID}
\n \n `:t.content='\nThis property is not on a NEZ Homestead zone.
\n \n ',t}buildNRSA(e){let t={title:"Neighborhood Revitalization Strategy Areas (NRSA)",content:null};return 0!=Object.keys(e.data).length&&e.data.constructor===Object&&e.data.features.length>0?t.content=`\nName: ${e.data.features[0].attributes.Name}
\n `:t.content="\nThis property is not on a NRSA.
\n ",t}buildNPO(e){let t={title:"Police",content:null};return e&&e.data.features.length?t.content=`\nPRECINCT
\nNumber: ${e.data.features[0].attributes.precinct}
\nAddress: ${e.data.features[0].attributes.precinct_location}
\nNEIGHBORHOOD POLICE OFFICER (NPO)
\nName: ${e.data.features[0].attributes.officer_name}
\nPhone: ${e.data.features[0].attributes.npo_cell_phone}
\nEmail: ${e.data.features[0].attributes.npo_email}
\n `:t.content="No police info found
",t}checkRecyclingStatus(e){try{if(e.next_pickups["yard waste"]){let t=null,a=null;return e.details.forEach((e=>{"start-date"==e.type&&"yard waste"==e.service&&(t=null!=e.normalDay?e.normalDay:e.newDay),"end-date"==e.type&&"yard waste"==e.service&&(a=null!=e.normalDay?e.normalDay:e.newDay)})),!!moment(e.next_pickups["yard waste"].next_pickup).isBetween(t,a)}return!1}catch(t){return!1}}buildRecycling(e,t){let a={title:"Trash & Recycling",content:null};if(e&&0!=Object.keys(e.data).length&&e.data.constructor===Object){let r={name:null,url:null,phone:null};"GFL"===e.data.next_pickups.trash.contractor?(r.name="GFL",r.url="http://gflusa.com/residential/detroit/",r.phone="(844) 464-3587"):(r.name="WM",r.url="http://www.advanceddisposal.com/mi/detroit/detroit-residential-collection",r.phone=" (844) 233-8764"),a.content=`\nProvider: ${r.name} ${r.phone}
\nNext Trash: ${t.formatDate(e.data.next_pickups.trash.next_pickup)}
\nNext Recycling: ${t.formatDate(e.data.next_pickups.recycling.next_pickup)}
\nNext Bulk: ${t.formatDate(e.data.next_pickups.bulk.next_pickup)}
\n ${t.checkRecyclingStatus(e.data)?tempHTML+=`Next Yard: ${t.formatDate(e.data.next_pickups["yard waste"].next_pickup)}
`:""}\n `}else a.content="No data found
";return a}buildAssessors(e){let t={title:"Assessor's Data",content:null};if(e&&0!=Object.keys(e.data).length&&e.data.constructor===Object&&"Not found."!==e.data.detail){let a={year:null,value:null,floor:null,buildingClass:null};t.content=`\nOwner's address: ${e.data.ownerstreetaddr}
\nOwner's city: ${e.data.ownercity}
\nOwner's state: ${e.data.ownerstate}
\nOwner's zip: ${e.data.ownerzip}
\n `,0===e.data.resb_bldgclass?(a.year=e.data.cib_yearbuilt,a.value=e.data.cib_value,a.floor=e.data.cib_yearbuilt,a.buildingClass=e.data.cib_yearbuilt):(a.year=e.data.resb_yearbuilt,a.value=e.data.resb_value,a.floor=e.data.resb_floorarea,a.buildingClass=e.data.resb_bldgclass),t.content+=`\nParcel number: ${e.data.pnum}
\nYear build: ${a.year}
\nCalculated value: $${a.value.toLocaleString()}
\nFloor area: ${a.floor.toLocaleString()} SQFT
\nBuilding class: ${a.buildingClass}
\n `}else t.content="No data found
";return t}buildRental(e,t){let a=document.getElementsByTagName("my-home-info"),r=JSON.parse(a[0].getAttribute("data-api-active-datasets")),n={title:"Rental Enforcement Status",content:null};return e&&e.data.features.length||r["rental-cert-data"]&&r["rental-cert-data"].data.features.length?n.content=`\nRegistered: ${e.data.features.length?`${t.formatDate(e.data.features[0].attributes.date_status)}`:"Not registered"}
\nCertified: ${r["rental-cert-data"].data.features.length?`${t.formatDate(r["rental-cert-data"].data.features[0].attributes.issued_date)}`:"Not certified"}
\n `:n.content="\nRegistered: Not registered
\nCertified: Not certified
\n ",n}buildFireEscrow(e){let t="";return e&&e.data.features.length?t+='\nSTATUS: Fire Escrow not found
\nTicket ID: ${e.attributes.ticket_number}
\nFine Amount: $${e.attributes.fine_amount}
\nAgency name: ${e.attributes.agency_name}
\nDisposition: ${e.attributes.disposition}
\nDescription: ${e.attributes.violation_description}
\nHearing Date: ${t.formatDate(e.attributes.hearing_date)}
\nHearing Time: ${e.attributes.hearing_time}
\n `:a.content="No blight tickets found
",a}buildSchools(e,t){let a={title:"Schools",content:null};return e&&e.data.features.length?e.data.features.forEach((function(e,t){0==t?a.content=`\nName: ${e.properties.EntityOfficialName}
\nEntityActualGrades: ${e.properties.EntityActualGrades}
\nType: ${e.properties.EntityTypeName}
\nAddress: ${e.properties.EntityPhysicalStreet}
\nName: ${e.properties.EntityOfficialName}
\nEntityActualGrades: ${e.properties.EntityActualGrades}
\nType: ${e.properties.EntityTypeName}
\nAddress: ${e.properties.EntityPhysicalStreet}
\nNo schools nearby.
",a}buildPermit(e,t){let a={title:"Building Permits",content:null};return e&&e.data.features.length?a.content=`\nPERMIT NUMBER: ${e.attributes.record_id}
\nPERMIT TYPE: ${e.attributes.permit_type}
\nPERMIT BUILDING TYPE: ${e.attributes.permit_type}
\nPERMIT STATUS: ${e.attributes.status}
\nPERMIT ISSUED: ${t.formatDate(e.attributes.issued_date)}
\nPERMIT DESCRIPTION: ${e.attributes.description_of_work}
\n `:a.content="No building permits found
",a}buildDemoStatus(e,t){let a=document.getElementsByTagName("my-home-info"),r=JSON.parse(a[0].getAttribute("data-parcel-id")).address.replace(" ","%2520");r=r.replace(",","%252C");let n={title:"Demolition Status",content:null};return e&&e.data.features.length?n.content=`\nWARNIG!
\nTHIS PROPERTY IS SCHEDULED FOR DEMOLITION
\n ${null==e.data.features[0].attributes.demolish_by_date?"Date to be determined
":`${t.formatDate(e.attributes.demolish_by_date)}
`}\nThis property is not on the demolition list
\nAddress: ${e.properties.address}
\nCommercial: ${e.properties.commercial_building}
\nPrice: $${parseInt(e.properties.price).toLocaleString()}
\nParcel: ${e.properties.parcel_id}
\nContractor: ${e.properties.contractor_name}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\n ${void 0==e.properties.demolish_by_date||null==e.properties.demolish_by_date?"Expected Date: Date to be determined
":`Expected Date:${t.formatDate(e.properties.demolish_by_date)}
`}\nAddress: ${e.properties.address}
\nCommercial: ${e.properties.commercial_building}
\nPrice: $${parseInt(e.properties.price).toLocaleString()}
\nParcel: ${e.properties.parcel_id}
\nContractor: ${e.properties.contractor_name}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\n ${void 0==e.properties.demolish_by_date||null==e.properties.demolish_by_date?"Expected Date: Date to be determined
":`Expected Date:${t.formatDate(e.properties.demolish_by_date)}
`}\nNo demolitions are happening nearby.
",a}buildStabilizationsNear(e,t){let a={title:"Stabilizations Nearby",content:null};return e&&e.data.features.length?e.data.features.forEach((function(e,t){0==t?a.content=`\nAddress: ${e.properties.address}
\nParcel: ${e.properties.parcel_id}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\nStatus: ${e.properties.rehab_status}
\nAddress: ${e.properties.address}
\nParcel: ${e.properties.parcel_id}
\nCouncil District: ${e.properties.council_district}
\nNeighborhood: ${e.properties.neighborhood}
\nStatus: ${e.properties.rehab_status}
\nNo stabilizations are happening nearby.
",a}buildImproveDet(e,t){let a={title:"Improve Detroit Issues Nearby",content:null};return e&&e.data.features.length?e.data.features.forEach((function(e,r){0==r?a.content=`\n \nType: ${e.properties.Request_Type_Title}
\nStatus: ${e.properties.Status}
\nReported on: ${t.formatDate(e.properties.Created_At)}
\nType: ${e.properties.Request_Type_Title}
\nStatus: ${e.properties.Status}
\nReported on: ${t.formatDate(e.properties.Created_At)}
\nNo active issues nearby.
",a}selectDataBlockType(e,t){switch(t.id){case"council-members":try{return e.buildCouncil(t)}catch(a){return""}break;case"bop-members":try{return e.buildBOP(t)}catch(a){return""}break;case"district-managers":try{return e.buildDistrictManagers(t)}catch(a){return""}break;case"business-liaison":try{return e.buildBusinessLiaison(t)}catch(a){return""}break;case"district-inspectors":try{return e.buildInspector(t)}catch(a){return""}break;case"neighborhood":try{return e.buildNeighborhood(t)}catch(a){return""}break;case"nez":try{return e.buildNEZ(t)}catch(a){return""}break;case"nrsa":try{return e.buildNRSA(t)}catch(a){return""}break;case"assessors-data":try{return e.buildAssessors(t)}catch(a){return""}break;case"permit-data":try{return e.buildPermit(t,e)}catch(a){return""}break;case"rental-data":try{return e.buildRental(t,e)}catch(a){return""}break;case"blight-data":try{return e.buildBlight(t,e)}catch(a){return""}break;case"demos-data":try{return e.buildDemosNear(t,e)}catch(a){return""}break;case"stabilization-data":try{return e.buildStabilizationsNear(t,e)}catch(a){return""}break;case"demo-status":try{return e.buildDemoStatus(t)}catch(a){return""}break;case"npo":try{return e.buildNPO(t)}catch(a){return""}break;case"improve-det":try{return e.buildImproveDet(t,e)}catch(a){return""}break;case"schools":try{return e.buildSchools(t,e)}catch(a){return""}break;case"recycling":try{return e.buildRecycling(t,e)}catch(a){return""}break;case"historicDistrict":try{return e.buildHistoricDistrict(t)}catch(a){return""}break;case"fireEscrow":try{return e.buildFireEscrow(t)}catch(a){return""}break;case"DWSDBackupProtection":try{return e.buildDWSDBackupProtection(t)}catch(a){return""}break;case"HRDFlooding":try{return e.buildHRDFlooding(t)}catch(a){return""}break;default:return""}}setDatasetPagination(e,t){if(e.hasAttribute("data-pagination")){let a=JSON.parse(e.getAttribute("data-pagination"));if(a[t.id]){let e={start:a[t.id].start};return t.data.features.length<=a[t.id].end+3?(e.end=t.data.features.length,e.more=!1):(e.end=a[t.id].end+3,e.more=!0),e}{let e={start:0,end:3,more:!0};return t.data.features?t.data.features.length<=3&&(e.end=t.data.features.length,e.more=!1):(e.start=null,e.more=!1),e}}{let e={start:0,end:3,more:!0};return t.data.features?t.data.features.length<=3&&(e.end=t.data.features.length,e.more=!1):(e.start=null,e.more=!1),e}}printInfo(e){let t=e.buildDataSection(e),a=window.open("","","height=500, width=500");a.document.write(""),a.document.write(""),a.document.write(""),a.document.write(t.children[1].innerHTML),a.document.write(""),a.document.close(),a.print()}buildDataBlock(e,t){const a=document.getElementsByTagName("my-home-info"),r=a[0].getAttribute("data-map-available"),n=document.createElement("article");n.className="data-block";let i=e.setDatasetPagination(e,t),s=JSON.parse(JSON.stringify(t));null!==i.start&&(s.data.features=t.data.features.slice(i.start,i.end));let o=e.selectDataBlockType(e,s);if(void 0==o||null==o.content)return null;{const s=document.createElement("p");s.className="data-block-title";const l=document.createElement("article");if(l.className="data-block-content",l.innerHTML=o.content,"true"==r){const e=document.createElement("span");e.innerText=o.title;const r=document.createElement("cod-button");r.setAttribute("data-map-active-data",t.id),r.setAttribute("data-label","View Map"),r.setAttribute("data-size","xsmall"),r.setAttribute("data-icon",""),r.setAttribute("data-img","https://detroitmi.gov/sites/detroitmi.localhost/files/2023-02/map.png"),r.setAttribute("data-img-alt","map"),r.setAttribute("data-shape",""),r.setAttribute("data-hover",!1),r.setAttribute("data-extra-classes","fw-bold"),r.setAttribute("data-background-color","light"),r.setAttribute("data-primary",!0),r.addEventListener("click",(e=>{e.target.getAttribute("data-map-active-data")&&(a[0].setAttribute("data-map-active-data",e.target.getAttribute("data-map-active-data")),a[0].setAttribute("data-app-state","map"))})),s.appendChild(e),s.appendChild(r)}else s.innerText=o.title;if(n.appendChild(s),n.appendChild(l),i.more){let a=document.createElement("cod-button");a.setAttribute("data-pagination-id",t.id),a.setAttribute("data-pagination",JSON.stringify(i)),a.setAttribute("data-label","Load More +"),a.setAttribute("data-size","xsmall"),a.setAttribute("data-icon",""),a.setAttribute("data-img",""),a.setAttribute("data-img-alt",""),a.setAttribute("data-shape",""),a.setAttribute("data-hover",!1),a.setAttribute("data-extra-classes","fw-bold"),a.setAttribute("data-background-color","primary"),a.setAttribute("data-primary",!1),a.addEventListener("click",(t=>{if(t.target.getAttribute("data-pagination")){let a=document.createElement("cod-spinner");a.setAttribute("data-type","border"),a.setAttribute("data-background-color","primary"),a.setAttribute("data-size","sm");let r=e.getAttribute("data-pagination");r=null===r?{}:JSON.parse(r),r[`${t.target.getAttribute("data-pagination-id")}`]=JSON.parse(t.target.getAttribute("data-pagination")),e.setAttribute("data-pagination",JSON.stringify(r)),t.target.parentElement.appendChild(a),t.target.remove()}})),l.appendChild(a)}return n}}buildDataSection(e){const t=document.getElementsByTagName("my-home-info"),a=t[0].getAttribute("data-app-mode"),r=document.createElement("section");if(r.id="data-results","my-home-info"==a){const e=document.createElement("p");e.className="data-title",e.innerText=t[0].getAttribute("data-active-section").toUpperCase(),r.appendChild(e)}const n=document.createElement("div");n.id="data-blocks",r.appendChild(n);const i=JSON.parse(t[0].getAttribute("data-api-active-datasets"));for(const s in i)Object.hasOwnProperty.call(i,s)&&null!=e.buildDataBlock(e,i[s])&&n.appendChild(e.buildDataBlock(e,i[s]));return r}loadDisplay(e){const t=e.shadowRoot,a=document.createElement("section"),r=document.createElement("app-geocoder"),n=document.createElement("app-nav-tools"),i=document.getElementsByTagName("my-home-info");switch(n.printInfo=e.printInfo,a.id="display-wrapper",this.getAttribute("data-display-type")){case"welcome":t.appendChild(e.welcomeStyle);const s=document.createElement("div");s.id="welcome-img-wrapper",s.appendChild(this.neighborhoodImage),a.appendChild(s);const o=document.createElement("article");a.appendChild(o);const l=document.createElement("p");l.setAttribute("aria-label","title"),l.innerText="It\u2019s all here. All in one place.",l.className="display-title",o.appendChild(l);const d=document.createElement("p");d.innerText="Enter your home address to find out your city councilmember and neighborhood district manager, along with local information about trash/recycling, your neighborhood police officer, city issues reported in your neighborhood, and more.",o.appendChild(d),o.appendChild(r),t.appendChild(a);break;case"active":t.appendChild(e.welcomeStyle),a.appendChild(r),t.appendChild(a);break;case"loading":const c=document.createElement("cod-loader");c.setAttribute("data-color","color-3"),a.appendChild(c),t.appendChild(a);break;case"results":let u=JSON.parse(i[0].getAttribute("data-parcel-id"));t.appendChild(e.resultsStyle);let p=document.createElement("section");p.className="results-container",p.appendChild(n);let m=document.createElement("article");m.className="dataset-results";let g=document.createElement("article");g.className="result-address",g.innerText=u.address,m.appendChild(g);let b=e.buildDataSection(e);m.appendChild(b),p.appendChild(m),a.appendChild(p),t.appendChild(a);break;case"error":let h=document.createElement("section");t.appendChild(e.resultsStyle),h.className="results-container",h.appendChild(n);let f=document.createElement("article");f.className="error-result",f.innerHTML='\n \nDistrict Number: ${value.data.district}
\nCouncil Member: ${value.data.name}
\nCouncil Member Phone: ${value.data.phone}
\n `;\n return dataParsing;\n }\n\n buildBOP(value) {\n let siteURL = window.location.hostname;\n let dataParsing = { title: \"Police Commissioner\", content: null };\n dataParsing.content = `\nCommissioner: ${value.data.name}
\nCommissioner's Phone: ${value.data.phone}
\nCommissioner's Email: ${value.data.email}
\n `;\n return dataParsing;\n }\n\n buildDistrictManagers(value) {\n let dataParsing = { title: \"District Managers\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nDistrict Manager: ${value.data.manager.name}
\nManager Phone: ${value.data.manager.phone}
\nDeputy Manager: ${value.data.deputy.name}
\nDeputy Manager Phone: ${value.data.deputy.phone}
\n `;\n } else {\n dataParsing.content = `\nNo data found
\n `;\n }\n return dataParsing;\n }\n\n buildBusinessLiaison(value) {\n let dataParsing = { title: \"Business Liaison\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nLiaison: ${value.data.name}
\nLiaison Phone: ${value.data.email}
\n `;\n } else {\n dataParsing.content = `\nNo data found
\n `;\n }\n return dataParsing;\n }\n\n buildInspector(value) {\n let dataParsing = { title: \"Enforcement Inspector\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nInspector: ${value.data.name}
\nInspector Phone: ${value.data.phone}
\n `;\n } else {\n dataParsing.content = `\nNo data found
\n `;\n }\n return dataParsing;\n }\n\n buildNeighborhood(value) {\n let dataParsing = { title: \"Neighborhood\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nNeighborhood name: ${value.data.attributes.neighborhood_name}
\n `;\n } else {\n dataParsing.content = `\nNo neighborhood found
\n `;\n }\n return dataParsing;\n }\n\n buildDWSDBackupProtection(values) {\n let validNeighborhoods = ['Aviation Sub', 'Barton-McFarland', 'Chadsey Condon', 'Cornerstone Village', 'East English Village', 'Morningside', 'Jefferson Chalmers', 'Warrendale', 'Victoria Park', 'Moross-Morang', 'Garden View'];\n let dataParsing = { title: \"DWSD Basement Backup Protection Program\", content: null };\n if (values && values.data.attributes.neighborhood_name) {\n if (validNeighborhoods.includes(values.data.attributes.neighborhood_name)) {\n dataParsing.content = `\nThis property qualifies for the DWSD Basement Backup Protection Program.
\nThis property doesn't qualify for the Basement Backup Protection Program. To learn more please visit our page.
\n `;\n }\n } else {\n dataParsing.content = `\nThis property doesn't qualify for the Basement Backup Protection Program. To learn more please visit our page.
\n `;\n }\n return dataParsing;\n }\n\n buildHRDFlooding(values) {\n let validNeighborhoods = ['Cornerstone Village', 'Morningside', 'Chandler Park', 'Fox Creek', 'Riverbend', 'Morningside', 'West End ', 'Midwest', 'Chadsey‐Condon', 'Claytown', 'North Corktown', 'Michigan‐ Martin', 'Aviation Sub', 'Garden View', 'Plymouth‐I96', 'Plymouth‐Hubell', 'Paveway', 'We Care Community', 'Fiskhorn', 'Joy-Schaefer', 'Warrendale', 'Warren Ave Community', 'Barton-McFarland'];\n let dataParsing = { title: \"CDBG Disaster Recovery Basement Backup Protection Program\", content: null };\n if (values && values.data.attributes.neighborhood_name) {\n if (validNeighborhoods.includes(values.data.attributes.neighborhood_name)) {\n dataParsing.content = `\nThis property qualifies for the CDBG Disaster Recovery Basement Backup Protection Program.
\nThis property doesn’t qualify for the CDBG Disaster Recovery Basement Backup Protection Program. To learn more please visit our page.
\n `;\n }\n } else {\n dataParsing.content = `\nThis property doesn’t qualify for the CDBG Disaster Recovery Basement Backup Protection Program. To learn more please visit our page.
\n `;\n }\n return dataParsing;\n }\n\n buildHistoricDistrict(value, display) {\n let dataParsing = { title: \"NEZ Homestead Zone\", content: null };\n if (Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.features.length > 0) {\n dataParsing.content = `\nNAME: ${value.data.features[0].attributes.Name}
\nDESIGNATED ON: ${display.formatDate(value.data.features[0].attributes.Year_Enacted).format('MMM DD, YYYY')}
\n `;\n } else {\n dataParsing.content = `\nThis property is not in a historic district.
\n `;\n }\n return dataParsing;\n }\n\n buildNEZ(nez) {\n let dataParsing = { title: \"NEZ Homestead Zone\", content: null };\n if (Object.keys(nez.data).length != 0 && nez.data.constructor === Object && nez.data.features.length > 0) {\n dataParsing.content = `\nName: ${nez.data.features[0].attributes.RNNAME}
\nID: ${nez.data.features[0].attributes.RID}
\n \n `;\n } else {\n dataParsing.content = `\nThis property is not on a NEZ Homestead zone.
\n \n `;\n }\n return dataParsing;\n }\n\n buildNRSA(value) {\n let dataParsing = { title: \"Neighborhood Revitalization Strategy Areas (NRSA)\", content: null };\n if (Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.features.length > 0) {\n dataParsing.content = `\nName: ${value.data.features[0].attributes.Name}
\n `;\n } else {\n dataParsing.content = `\nThis property is not on a NRSA.
\n `;\n }\n return dataParsing;\n }\n\n buildNPO(value) {\n let dataParsing = { title: \"Police\", content: null };\n if (value && value.data.features.length) {\n dataParsing.content = `\nPRECINCT
\nNumber: ${value.data.features[0].attributes.precinct}
\nAddress: ${value.data.features[0].attributes.precinct_location}
\nNEIGHBORHOOD POLICE OFFICER (NPO)
\nName: ${value.data.features[0].attributes.officer_name}
\nPhone: ${value.data.features[0].attributes.npo_cell_phone}
\nEmail: ${value.data.features[0].attributes.npo_email}
\n `;\n } else {\n dataParsing.content = `No police info found
`;\n }\n return dataParsing;\n }\n\n checkRecyclingStatus(data) {\n try {\n if (data.next_pickups['yard waste']) {\n let yardStart = null;\n let yardEnd = null;\n data.details.forEach((item) => {\n if (item.type == 'start-date' && item.service == 'yard waste') {\n if (item.normalDay != null) {\n yardStart = item.normalDay;\n } else {\n yardStart = item.newDay;\n }\n }\n if (item.type == 'end-date' && item.service == 'yard waste') {\n if (item.normalDay != null) {\n yardEnd = item.normalDay;\n } else {\n yardEnd = item.newDay;\n }\n }\n });\n if (moment(data.next_pickups['yard waste'].next_pickup).isBetween(yardStart, yardEnd)) {\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n } catch (error) {\n return false;\n }\n }\n\n buildRecycling(value, display) {\n let dataParsing = { title: \"Trash & Recycling\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object) {\n let contractorInfo = {\n name: null,\n url: null,\n phone: null\n };\n if (value.data.next_pickups.trash.contractor === 'GFL') {\n contractorInfo.name = 'GFL';\n contractorInfo.url = 'http://gflusa.com/residential/detroit/';\n contractorInfo.phone = '(844) 464-3587';\n } else {\n contractorInfo.name = 'WM';\n contractorInfo.url = 'http://www.advanceddisposal.com/mi/detroit/detroit-residential-collection';\n contractorInfo.phone = ' (844) 233-8764';\n }\n dataParsing.content = `\nProvider: ${contractorInfo.name} ${contractorInfo.phone}
\nNext Trash: ${display.formatDate(value.data.next_pickups.trash.next_pickup)}
\nNext Recycling: ${display.formatDate(value.data.next_pickups.recycling.next_pickup)}
\nNext Bulk: ${display.formatDate(value.data.next_pickups.bulk.next_pickup)}
\n ${(display.checkRecyclingStatus(value.data)) ? tempHTML += `Next Yard: ${display.formatDate(value.data.next_pickups['yard waste'].next_pickup)}
` : ``}\n `;\n } else {\n dataParsing.content = `No data found
`;\n }\n return dataParsing;\n }\n\n buildAssessors(value) {\n let dataParsing = { title: \"Assessor's Data\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n let property = {\n year: null,\n value: null,\n floor: null,\n buildingClass: null\n }\n dataParsing.content = `\nOwner's address: ${value.data.ownerstreetaddr}
\nOwner's city: ${value.data.ownercity}
\nOwner's state: ${value.data.ownerstate}
\nOwner's zip: ${value.data.ownerzip}
\n `;\n if (value.data.resb_bldgclass === 0) {\n property.year = value.data.cib_yearbuilt;\n property.value = value.data.cib_value;\n property.floor = value.data.cib_yearbuilt;\n property.buildingClass = value.data.cib_yearbuilt;\n } else {\n property.year = value.data.resb_yearbuilt;\n property.value = value.data.resb_value;\n property.floor = value.data.resb_floorarea;\n property.buildingClass = value.data.resb_bldgclass;\n }\n dataParsing.content += `\nParcel number: ${value.data.pnum}
\nYear build: ${property.year}
\nCalculated value: $${property.value.toLocaleString()}
\nFloor area: ${property.floor.toLocaleString()} SQFT
\nBuilding class: ${property.buildingClass}
\n `;\n } else {\n dataParsing.content = `No data found
`;\n }\n return dataParsing;\n }\n\n buildRental(value, display) {\n let app = document.getElementsByTagName('my-home-info');\n let apiDataSets = JSON.parse(app[0].getAttribute('data-api-active-datasets'));\n let dataParsing = { title: \"Rental Enforcement Status\", content: null };\n if ((value && value.data.features.length) || (apiDataSets['rental-cert-data'] && apiDataSets['rental-cert-data'].data.features.length)) {\n dataParsing.content = `\nRegistered: ${value.data.features.length ? `${display.formatDate(value.data.features[0].attributes.date_status)}` : `Not registered`}
\nCertified: ${apiDataSets['rental-cert-data'].data.features.length ? `${display.formatDate(apiDataSets['rental-cert-data'].data.features[0].attributes.issued_date)}` : `Not certified`}
\n `;\n } else {\n dataParsing.content = `\nRegistered: Not registered
\nCertified: Not certified
\n `;\n }\n return dataParsing;\n }\n\n buildFireEscrow(value) {\n let tempHTML = '';\n if (value && value.data.features.length) {\n tempHTML += `\nSTATUS: Fire Escrow not found
\nTicket ID: ${value.attributes.ticket_number}
\nFine Amount: $${value.attributes.fine_amount}
\nAgency name: ${value.attributes.agency_name}
\nDisposition: ${value.attributes.disposition}
\nDescription: ${value.attributes.violation_description}
\nHearing Date: ${display.formatDate(value.attributes.hearing_date)}
\nHearing Time: ${value.attributes.hearing_time}
\n `;\n } else {\n dataParsing.content = `No blight tickets found
`;\n }\n return dataParsing;\n }\n\n buildSchools(value, display) {\n let dataParsing = { title: \"Schools\", content: null };\n if (value && value.data.features.length) {\n value.data.features.forEach(function (value, index) {\n if (index == 0) {\n dataParsing.content = `\nName: ${value.properties.EntityOfficialName}
\nEntityActualGrades: ${value.properties.EntityActualGrades}
\nType: ${value.properties.EntityTypeName}
\nAddress: ${value.properties.EntityPhysicalStreet}
\nName: ${value.properties.EntityOfficialName}
\nEntityActualGrades: ${value.properties.EntityActualGrades}
\nType: ${value.properties.EntityTypeName}
\nAddress: ${value.properties.EntityPhysicalStreet}
\nNo schools nearby.
`;\n }\n return dataParsing;\n }\n\n buildPermit(value, display) {\n let dataParsing = { title: \"Building Permits\", content: null };\n if (value && value.data.features.length) {\n dataParsing.content = `\nPERMIT NUMBER: ${value.attributes.record_id}
\nPERMIT TYPE: ${value.attributes.permit_type}
\nPERMIT BUILDING TYPE: ${value.attributes.permit_type}
\nPERMIT STATUS: ${value.attributes.status}
\nPERMIT ISSUED: ${display.formatDate(value.attributes.issued_date)}
\nPERMIT DESCRIPTION: ${value.attributes.description_of_work}
\n `;\n } else {\n dataParsing.content = `No building permits found
`;\n }\n return dataParsing;\n }\n\n buildDemoStatus(value, display) {\n let app = document.getElementsByTagName('my-home-info');\n let parcelData = JSON.parse(app[0].getAttribute('data-parcel-id'));\n let tempAddress = parcelData.address.replace(' ', '%2520');\n tempAddress = tempAddress.replace(',', '%252C');\n let dataParsing = { title: \"Demolition Status\", content: null };\n if (value && value.data.features.length) {\n dataParsing.content = `\nWARNIG!
\nTHIS PROPERTY IS SCHEDULED FOR DEMOLITION
\n ${(value.data.features[0].attributes.demolish_by_date == null) ? `Date to be determined
` : `${display.formatDate(value.attributes.demolish_by_date)}
`}\nThis property is not on the demolition list
\nAddress: ${value.properties.address}
\nCommercial: ${value.properties.commercial_building}
\nPrice: $${parseInt(value.properties.price).toLocaleString()}
\nParcel: ${value.properties.parcel_id}
\nContractor: ${value.properties.contractor_name}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\n ${(value.properties.demolish_by_date == undefined || value.properties.demolish_by_date == null) ? `Expected Date: Date to be determined
` : `Expected Date:${display.formatDate(value.properties.demolish_by_date)}
`}\nAddress: ${value.properties.address}
\nCommercial: ${value.properties.commercial_building}
\nPrice: $${parseInt(value.properties.price).toLocaleString()}
\nParcel: ${value.properties.parcel_id}
\nContractor: ${value.properties.contractor_name}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\n ${(value.properties.demolish_by_date == undefined || value.properties.demolish_by_date == null) ? `Expected Date: Date to be determined
` : `Expected Date:${display.formatDate(value.properties.demolish_by_date)}
`}\nNo demolitions are happening nearby.
`;\n }\n return dataParsing;\n }\n\n buildStabilizationsNear(value, display) {\n let dataParsing = { title: \"Stabilizations Nearby\", content: null };\n if (value && value.data.features.length) {\n value.data.features.forEach(function (value, index) {\n\n if (index == 0) {\n dataParsing.content = `\nAddress: ${value.properties.address}
\nParcel: ${value.properties.parcel_id}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\nStatus: ${value.properties.rehab_status}
\nAddress: ${value.properties.address}
\nParcel: ${value.properties.parcel_id}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\nStatus: ${value.properties.rehab_status}
\nNo stabilizations are happening nearby.
`;\n }\n return dataParsing;\n }\n\n buildImproveDet(value, display) {\n let dataParsing = { title: \"Improve Detroit Issues Nearby\", content: null };\n if (value && value.data.features.length) {\n value.data.features.forEach(function (value, index) {\n if (index == 0) {\n dataParsing.content = `\n \nType: ${value.properties.Request_Type_Title}
\nStatus: ${value.properties.Status}
\nReported on: ${display.formatDate(value.properties.Created_At)}
\nType: ${value.properties.Request_Type_Title}
\nStatus: ${value.properties.Status}
\nReported on: ${display.formatDate(value.properties.Created_At)}
\nNo active issues nearby.
`;\n }\n return dataParsing;\n }\n\n selectDataBlockType(display, value) {\n switch (value.id) {\n case 'council-members':\n try {\n return display.buildCouncil(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'bop-members':\n try {\n return display.buildBOP(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'district-managers':\n try {\n return display.buildDistrictManagers(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'business-liaison':\n try {\n return display.buildBusinessLiaison(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'district-inspectors':\n try {\n return display.buildInspector(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'neighborhood':\n try {\n return display.buildNeighborhood(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'nez':\n try {\n return display.buildNEZ(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'nrsa':\n try {\n return display.buildNRSA(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'assessors-data':\n try {\n return display.buildAssessors(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'permit-data':\n try {\n return display.buildPermit(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'rental-data':\n try {\n return display.buildRental(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'blight-data':\n try {\n return display.buildBlight(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'demos-data':\n try {\n return display.buildDemosNear(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'stabilization-data':\n try {\n return display.buildStabilizationsNear(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'demo-status':\n try {\n return display.buildDemoStatus(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'npo':\n try {\n return display.buildNPO(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'improve-det':\n try {\n return display.buildImproveDet(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'schools':\n try {\n return display.buildSchools(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'recycling':\n try {\n return display.buildRecycling(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'historicDistrict':\n try {\n return display.buildHistoricDistrict(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'fireEscrow':\n try {\n return display.buildFireEscrow(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'DWSDBackupProtection':\n try {\n return display.buildDWSDBackupProtection(value);\n } catch (error) {\n return '';\n }\n break;\n\n case 'HRDFlooding':\n try {\n return display.buildHRDFlooding(value);\n } catch (error) {\n return '';\n }\n break;\n\n default:\n return '';\n break;\n }\n }\n\n setDatasetPagination(display, dataset){\n if(display.hasAttribute('data-pagination')){\n let paginations = JSON.parse(display.getAttribute('data-pagination'));\n if(paginations[dataset.id]){\n let paginationObj = {start: paginations[dataset.id].start};\n if(dataset.data.features.length <= (paginations[dataset.id].end + 3)){\n paginationObj.end = dataset.data.features.length;\n paginationObj.more = false;\n }else{\n paginationObj.end = paginations[dataset.id].end + 3;\n paginationObj.more = true;\n }\n return paginationObj;\n }else{\n let paginationObj = {start: 0, end: 3, more: true};\n if(dataset.data.features){\n if(dataset.data.features.length <= 3){\n paginationObj.end = dataset.data.features.length;\n paginationObj.more = false;\n }\n }else{\n paginationObj.start = null;\n paginationObj.more = false;\n }\n return paginationObj;\n }\n }else{\n let paginationObj = {start: 0, end: 3, more: true};\n if(dataset.data.features){\n if(dataset.data.features.length <= 3){\n paginationObj.end = dataset.data.features.length;\n paginationObj.more = false;\n }\n }else{\n paginationObj.start = null;\n paginationObj.more = false;\n }\n return paginationObj;\n }\n }\n\n printInfo(display) {\n let divContents = display.buildDataSection(display);\n let a = window.open('', '', 'height=500, width=500');\n a.document.write('');\n a.document.write('');\n a.document.write('');\n a.document.write(divContents.children[1].innerHTML);\n a.document.write('');\n a.document.close();\n a.print();\n }\n\n buildDataBlock(display, dataSet) {\n const app = document.getElementsByTagName('my-home-info');\n const mapAvailable = app[0].getAttribute('data-map-available');\n const dataBlock = document.createElement('article');\n dataBlock.className = 'data-block';\n let pagination = display.setDatasetPagination(display, dataSet);\n let splitDataset = JSON.parse(JSON.stringify(dataSet));\n if(pagination.start !== null){\n splitDataset.data.features = dataSet.data.features.slice(pagination.start, pagination.end);\n }\n let datasetValues = display.selectDataBlockType(display, splitDataset);\n if (datasetValues == undefined || datasetValues.content == null) {\n return null;\n } else {\n const dataBlockTitle = document.createElement('p');\n dataBlockTitle.className = 'data-block-title';\n const dataBlockContent = document.createElement('article');\n dataBlockContent.className = 'data-block-content';\n dataBlockContent.innerHTML = datasetValues.content;\n if (mapAvailable == 'true') {\n const text = document.createElement('span');\n text.innerText = datasetValues.title;\n const mapButton = document.createElement('cod-button');\n mapButton.setAttribute('data-map-active-data', dataSet.id);\n mapButton.setAttribute('data-label', 'View Map');\n mapButton.setAttribute('data-size', 'xsmall');\n mapButton.setAttribute('data-icon', '');\n mapButton.setAttribute('data-img', 'https://detroitmi.gov/sites/detroitmi.localhost/files/2023-02/map.png');\n mapButton.setAttribute('data-img-alt', 'map');\n mapButton.setAttribute('data-shape', '');\n mapButton.setAttribute('data-hover', false);\n mapButton.setAttribute('data-extra-classes', 'fw-bold');\n mapButton.setAttribute('data-background-color', 'light');\n mapButton.setAttribute('data-primary', true);\n mapButton.addEventListener('click', (ev) => {\n if(ev.target.getAttribute('data-map-active-data')){\n app[0].setAttribute('data-map-active-data', ev.target.getAttribute('data-map-active-data'));\n app[0].setAttribute('data-app-state', 'map');\n }\n });\n dataBlockTitle.appendChild(text);\n dataBlockTitle.appendChild(mapButton);\n } else {\n dataBlockTitle.innerText = datasetValues.title;\n }\n dataBlock.appendChild(dataBlockTitle);\n dataBlock.appendChild(dataBlockContent);\n if(pagination.more){\n let loadMoreBtn = document.createElement('cod-button');\n loadMoreBtn.setAttribute('data-pagination-id', dataSet.id);\n loadMoreBtn.setAttribute('data-pagination', JSON.stringify(pagination));\n loadMoreBtn.setAttribute('data-label', 'Load More +');\n loadMoreBtn.setAttribute('data-size', 'xsmall');\n loadMoreBtn.setAttribute('data-icon', '');\n loadMoreBtn.setAttribute('data-img', '');\n loadMoreBtn.setAttribute('data-img-alt', '');\n loadMoreBtn.setAttribute('data-shape', '');\n loadMoreBtn.setAttribute('data-hover', false);\n loadMoreBtn.setAttribute('data-extra-classes', 'fw-bold');\n loadMoreBtn.setAttribute('data-background-color', 'primary');\n loadMoreBtn.setAttribute('data-primary', false);\n loadMoreBtn.addEventListener('click', (ev) => {\n if(ev.target.getAttribute('data-pagination')){\n let loadMoreSpinner = document.createElement('cod-spinner');\n loadMoreSpinner.setAttribute('data-type', 'border');\n loadMoreSpinner.setAttribute('data-background-color', 'primary');\n loadMoreSpinner.setAttribute('data-size', 'sm');\n let paginations = display.getAttribute('data-pagination');\n if(paginations === null){\n paginations = {};\n }else{\n paginations = JSON.parse(paginations);\n }\n paginations[`${ev.target.getAttribute('data-pagination-id')}`] = JSON.parse(ev.target.getAttribute('data-pagination'));\n display.setAttribute('data-pagination', JSON.stringify(paginations));\n ev.target.parentElement.appendChild(loadMoreSpinner);\n ev.target.remove();\n }\n });\n dataBlockContent.appendChild(loadMoreBtn);\n }\n return dataBlock;\n }\n }\n\n buildDataSection(display) {\n const app = document.getElementsByTagName('my-home-info');\n const appMode = app[0].getAttribute('data-app-mode');\n const results = document.createElement('section');\n results.id = 'data-results';\n if (appMode == 'my-home-info') {\n const sectionTitle = document.createElement('p');\n sectionTitle.className = 'data-title';\n sectionTitle.innerText = app[0].getAttribute('data-active-section').toUpperCase();\n results.appendChild(sectionTitle);\n }\n const dataBlocks = document.createElement('div');\n dataBlocks.id = 'data-blocks';\n results.appendChild(dataBlocks);\n\n const apiDataSets = JSON.parse(app[0].getAttribute('data-api-active-datasets'));\n for (const dataSet in apiDataSets) {\n if (Object.hasOwnProperty.call(apiDataSets, dataSet)) {\n if (display.buildDataBlock(display, apiDataSets[dataSet]) != null) {\n dataBlocks.appendChild(display.buildDataBlock(display, apiDataSets[dataSet]));\n }\n }\n }\n return results;\n }\n\n loadDisplay(display) {\n const shadow = display.shadowRoot;\n const displayWrapper = document.createElement('section');\n const geocoder = document.createElement('app-geocoder');\n const navTools = document.createElement('app-nav-tools');\n const app = document.getElementsByTagName('my-home-info');\n navTools.printInfo = display.printInfo;\n displayWrapper.id = 'display-wrapper';\n switch (this.getAttribute('data-display-type')) {\n case 'welcome':\n shadow.appendChild(display.welcomeStyle);\n const imageWrapper = document.createElement('div');\n imageWrapper.id = 'welcome-img-wrapper';\n imageWrapper.appendChild(this.neighborhoodImage);\n displayWrapper.appendChild(imageWrapper);\n const textWrapperWelcome = document.createElement('article');\n displayWrapper.appendChild(textWrapperWelcome);\n const titleWelcome = document.createElement('p');\n titleWelcome.setAttribute('aria-label', 'title');\n titleWelcome.innerText = 'It’s all here. All in one place.';\n titleWelcome.className = 'display-title';\n textWrapperWelcome.appendChild(titleWelcome)\n const textWelcome = document.createElement('p');\n textWelcome.innerText = 'Enter your home address to find out your city councilmember and neighborhood district manager, along with local information about trash/recycling, your neighborhood police officer, city issues reported in your neighborhood, and more.';\n textWrapperWelcome.appendChild(textWelcome);\n textWrapperWelcome.appendChild(geocoder);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'active':\n shadow.appendChild(display.welcomeStyle);\n displayWrapper.appendChild(geocoder);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'loading':\n const loader = document.createElement('cod-loader');\n loader.setAttribute('data-color', 'color-3');\n displayWrapper.appendChild(loader);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'results':\n let parcelData = JSON.parse(app[0].getAttribute('data-parcel-id'));\n shadow.appendChild(display.resultsStyle);\n let resultsContainer = document.createElement('section');\n resultsContainer.className = 'results-container';\n resultsContainer.appendChild(navTools);\n let dataSetResults = document.createElement('article');\n dataSetResults.className = 'dataset-results';\n let addressBox = document.createElement('article');\n addressBox.className = 'result-address';\n addressBox.innerText = parcelData.address;\n dataSetResults.appendChild(addressBox);\n let results = display.buildDataSection(display);\n dataSetResults.appendChild(results);\n resultsContainer.appendChild(dataSetResults);\n displayWrapper.appendChild(resultsContainer);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'error':\n let errorContainer = document.createElement('section');\n shadow.appendChild(display.resultsStyle);\n errorContainer.className = 'results-container';\n errorContainer.appendChild(navTools);\n let errorBox = document.createElement('article');\n errorBox.className = 'error-result';\n errorBox.innerHTML = `\n \nDistrict Number: ${value.data.district}
\nCouncil Member: ${value.data.name}
\nCouncil Member Phone: ${value.data.phone}
\n `;\n return dataParsing;\n }\n\n buildBOP(value) {\n let siteURL = window.location.hostname;\n let dataParsing = { title: \"Police Commissioner\", content: null };\n dataParsing.content = `\nCommissioner: ${value.data.name}
\nCommissioner's Phone: ${value.data.phone}
\nCommissioner's Email: ${value.data.email}
\n `;\n return dataParsing;\n }\n\n buildDistrictManagers(value) {\n let dataParsing = { title: \"District Managers\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nDistrict Manager: ${value.data.manager.name}
\nManager Phone: ${value.data.manager.phone}
\nDeputy Manager: ${value.data.deputy.name}
\nDeputy Manager Phone: ${value.data.deputy.phone}
\n `;\n } else {\n dataParsing.content = `\nNo data found
\n `;\n }\n return dataParsing;\n }\n\n buildBusinessLiaison(value) {\n let dataParsing = { title: \"Business Liaison\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nLiaison: ${value.data.name}
\nLiaison Phone: ${value.data.email}
\n `;\n } else {\n dataParsing.content = `\nNo data found
\n `;\n }\n return dataParsing;\n }\n\n buildInspector(value) {\n let dataParsing = { title: \"Enforcement Inspector\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nInspector: ${value.data.name}
\nInspector Phone: ${value.data.phone}
\n `;\n } else {\n dataParsing.content = `\nNo data found
\n `;\n }\n return dataParsing;\n }\n\n buildNeighborhood(value) {\n let dataParsing = { title: \"Neighborhood\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n dataParsing.content = `\nNeighborhood name: ${value.data.attributes.neighborhood_name}
\n `;\n } else {\n dataParsing.content = `\nNo neighborhood found
\n `;\n }\n return dataParsing;\n }\n\n buildDWSDBackupProtection(values) {\n let validNeighborhoods = ['Aviation Sub', 'Barton-McFarland', 'Chadsey Condon', 'Cornerstone Village', 'East English Village', 'Morningside', 'Jefferson Chalmers', 'Warrendale', 'Victoria Park', 'Moross-Morang', 'Garden View'];\n let dataParsing = { title: \"DWSD Basement Backup Protection Program\", content: null };\n if (values && values.data.attributes.neighborhood_name) {\n if (validNeighborhoods.includes(values.data.attributes.neighborhood_name)) {\n dataParsing.content = `\nThis property qualifies for the DWSD Basement Backup Protection Program.
\nThis property doesn't qualify for the Basement Backup Protection Program. To learn more please visit our page.
\n `;\n }\n } else {\n dataParsing.content = `\nThis property doesn't qualify for the Basement Backup Protection Program. To learn more please visit our page.
\n `;\n }\n return dataParsing;\n }\n\n buildHRDFlooding(values) {\n let validNeighborhoods = ['Cornerstone Village', 'Morningside', 'Chandler Park', 'Fox Creek', 'Riverbend', 'Morningside', 'West End ', 'Midwest', 'Chadsey‐Condon', 'Claytown', 'North Corktown', 'Michigan‐ Martin', 'Aviation Sub', 'Garden View', 'Plymouth‐I96', 'Plymouth‐Hubell', 'Paveway', 'We Care Community', 'Fiskhorn', 'Joy-Schaefer', 'Warrendale', 'Warren Ave Community', 'Barton-McFarland'];\n let dataParsing = { title: \"CDBG-DR Private Sewer Repair Program\", content: null };\n if (values && values.data.attributes.neighborhood_name) {\n if (validNeighborhoods.includes(values.data.attributes.neighborhood_name)) {\n dataParsing.content = `\nThis property qualifies for the CDBG-DR Private Sewer Repair Program.
\nThis property doesn’t qualify for the CDBG-DR Private Sewer Repair Program. To learn more please visit our page.
\n `;\n }\n } else {\n dataParsing.content = `\nThis property doesn’t qualify for the CDBG-DR Private Sewer Repair Program. To learn more please visit our page.
\n `;\n }\n return dataParsing;\n }\n\n buildHistoricDistrict(value, display) {\n let dataParsing = { title: \"NEZ Homestead Zone\", content: null };\n if (Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.features.length > 0) {\n dataParsing.content = `\nNAME: ${value.data.features[0].attributes.Name}
\nDESIGNATED ON: ${display.formatDate(value.data.features[0].attributes.Year_Enacted).format('MMM DD, YYYY')}
\n `;\n } else {\n dataParsing.content = `\nThis property is not in a historic district.
\n `;\n }\n return dataParsing;\n }\n\n buildNEZ(nez) {\n let dataParsing = { title: \"NEZ Homestead Zone\", content: null };\n if (Object.keys(nez.data).length != 0 && nez.data.constructor === Object && nez.data.features.length > 0) {\n dataParsing.content = `\nName: ${nez.data.features[0].attributes.RNNAME}
\nID: ${nez.data.features[0].attributes.RID}
\n \n `;\n } else {\n dataParsing.content = `\nThis property is not on a NEZ Homestead zone.
\n \n `;\n }\n return dataParsing;\n }\n\n buildNRSA(value) {\n let dataParsing = { title: \"Neighborhood Revitalization Strategy Areas (NRSA)\", content: null };\n if (Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.features.length > 0) {\n dataParsing.content = `\nName: ${value.data.features[0].attributes.Name}
\n `;\n } else {\n dataParsing.content = `\nThis property is not on a NRSA.
\n `;\n }\n return dataParsing;\n }\n\n buildNPO(value) {\n let dataParsing = { title: \"Police\", content: null };\n if (value && value.data.features.length) {\n dataParsing.content = `\nPRECINCT
\nNumber: ${value.data.features[0].attributes.precinct}
\nAddress: ${value.data.features[0].attributes.precinct_location}
\nNEIGHBORHOOD POLICE OFFICER (NPO)
\nName: ${value.data.features[0].attributes.officer_name}
\nPhone: ${value.data.features[0].attributes.npo_cell_phone}
\nEmail: ${value.data.features[0].attributes.npo_email}
\n `;\n } else {\n dataParsing.content = `No police info found
`;\n }\n return dataParsing;\n }\n\n checkRecyclingStatus(data) {\n try {\n if (data.next_pickups['yard waste']) {\n let yardStart = null;\n let yardEnd = null;\n data.details.forEach((item) => {\n if (item.type == 'start-date' && item.service == 'yard waste') {\n if (item.normalDay != null) {\n yardStart = item.normalDay;\n } else {\n yardStart = item.newDay;\n }\n }\n if (item.type == 'end-date' && item.service == 'yard waste') {\n if (item.normalDay != null) {\n yardEnd = item.normalDay;\n } else {\n yardEnd = item.newDay;\n }\n }\n });\n if (moment(data.next_pickups['yard waste'].next_pickup).isBetween(yardStart, yardEnd)) {\n return true;\n } else {\n return false;\n }\n } else {\n return false;\n }\n } catch (error) {\n return false;\n }\n }\n\n buildRecycling(value, display) {\n let dataParsing = { title: \"Trash & Recycling\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object) {\n let contractorInfo = {\n name: null,\n url: null,\n phone: null\n };\n if (value.data.next_pickups.trash.contractor === 'GFL') {\n contractorInfo.name = 'GFL';\n contractorInfo.url = 'http://gflusa.com/residential/detroit/';\n contractorInfo.phone = '(844) 464-3587';\n } else {\n contractorInfo.name = 'WM';\n contractorInfo.url = 'http://www.advanceddisposal.com/mi/detroit/detroit-residential-collection';\n contractorInfo.phone = ' (844) 233-8764';\n }\n dataParsing.content = `\nProvider: ${contractorInfo.name} ${contractorInfo.phone}
\nNext Trash: ${display.formatDate(value.data.next_pickups.trash.next_pickup)}
\nNext Recycling: ${display.formatDate(value.data.next_pickups.recycling.next_pickup)}
\nNext Bulk: ${display.formatDate(value.data.next_pickups.bulk.next_pickup)}
\n ${(display.checkRecyclingStatus(value.data)) ? tempHTML += `Next Yard: ${display.formatDate(value.data.next_pickups['yard waste'].next_pickup)}
` : ``}\n `;\n } else {\n dataParsing.content = `No data found
`;\n }\n return dataParsing;\n }\n\n buildAssessors(value) {\n let dataParsing = { title: \"Assessor's Data\", content: null };\n if (value && Object.keys(value.data).length != 0 && value.data.constructor === Object && value.data.detail !== \"Not found.\") {\n let property = {\n year: null,\n value: null,\n floor: null,\n buildingClass: null\n }\n dataParsing.content = `\nOwner's address: ${value.data.ownerstreetaddr}
\nOwner's city: ${value.data.ownercity}
\nOwner's state: ${value.data.ownerstate}
\nOwner's zip: ${value.data.ownerzip}
\n `;\n if (value.data.resb_bldgclass === 0) {\n property.year = value.data.cib_yearbuilt;\n property.value = value.data.cib_value;\n property.floor = value.data.cib_yearbuilt;\n property.buildingClass = value.data.cib_yearbuilt;\n } else {\n property.year = value.data.resb_yearbuilt;\n property.value = value.data.resb_value;\n property.floor = value.data.resb_floorarea;\n property.buildingClass = value.data.resb_bldgclass;\n }\n dataParsing.content += `\nParcel number: ${value.data.pnum}
\nYear build: ${property.year}
\nCalculated value: $${property.value.toLocaleString()}
\nFloor area: ${property.floor.toLocaleString()} SQFT
\nBuilding class: ${property.buildingClass}
\n `;\n } else {\n dataParsing.content = `No data found
`;\n }\n return dataParsing;\n }\n\n buildRental(value, display) {\n let app = document.getElementsByTagName('my-home-info');\n let apiDataSets = JSON.parse(app[0].getAttribute('data-api-active-datasets'));\n let dataParsing = { title: \"Rental Enforcement Status\", content: null };\n if ((value && value.data.features.length) || (apiDataSets['rental-cert-data'] && apiDataSets['rental-cert-data'].data.features.length)) {\n dataParsing.content = `\nRegistered: ${value.data.features.length ? `${display.formatDate(value.data.features[0].attributes.date_status)}` : `Not registered`}
\nCertified: ${apiDataSets['rental-cert-data'].data.features.length ? `${display.formatDate(apiDataSets['rental-cert-data'].data.features[0].attributes.issued_date)}` : `Not certified`}
\n `;\n } else {\n dataParsing.content = `\nRegistered: Not registered
\nCertified: Not certified
\n `;\n }\n return dataParsing;\n }\n\n buildFireEscrow(value) {\n let tempHTML = '';\n if (value && value.data.features.length) {\n tempHTML += `\nSTATUS: Fire Escrow not found
\nTicket ID: ${value.attributes.ticket_number}
\nFine Amount: $${value.attributes.fine_amount}
\nAgency name: ${value.attributes.agency_name}
\nDisposition: ${value.attributes.disposition}
\nDescription: ${value.attributes.violation_description}
\nHearing Date: ${display.formatDate(value.attributes.hearing_date)}
\nHearing Time: ${value.attributes.hearing_time}
\n `;\n } else {\n dataParsing.content = `No blight tickets found
`;\n }\n return dataParsing;\n }\n\n buildSchools(value, display) {\n let dataParsing = { title: \"Schools\", content: null };\n if (value && value.data.features.length) {\n value.data.features.forEach(function (value, index) {\n if (index == 0) {\n dataParsing.content = `\nName: ${value.properties.EntityOfficialName}
\nEntityActualGrades: ${value.properties.EntityActualGrades}
\nType: ${value.properties.EntityTypeName}
\nAddress: ${value.properties.EntityPhysicalStreet}
\nName: ${value.properties.EntityOfficialName}
\nEntityActualGrades: ${value.properties.EntityActualGrades}
\nType: ${value.properties.EntityTypeName}
\nAddress: ${value.properties.EntityPhysicalStreet}
\nNo schools nearby.
`;\n }\n return dataParsing;\n }\n\n buildPermit(value, display) {\n let dataParsing = { title: \"Building Permits\", content: null };\n if (value && value.data.features.length) {\n dataParsing.content = `\nPERMIT NUMBER: ${value.attributes.record_id}
\nPERMIT TYPE: ${value.attributes.permit_type}
\nPERMIT BUILDING TYPE: ${value.attributes.permit_type}
\nPERMIT STATUS: ${value.attributes.status}
\nPERMIT ISSUED: ${display.formatDate(value.attributes.issued_date)}
\nPERMIT DESCRIPTION: ${value.attributes.description_of_work}
\n `;\n } else {\n dataParsing.content = `No building permits found
`;\n }\n return dataParsing;\n }\n\n buildDemoStatus(value, display) {\n let app = document.getElementsByTagName('my-home-info');\n let parcelData = JSON.parse(app[0].getAttribute('data-parcel-id'));\n let tempAddress = parcelData.address.replace(' ', '%2520');\n tempAddress = tempAddress.replace(',', '%252C');\n let dataParsing = { title: \"Demolition Status\", content: null };\n if (value && value.data.features.length) {\n dataParsing.content = `\nWARNIG!
\nTHIS PROPERTY IS SCHEDULED FOR DEMOLITION
\n ${(value.data.features[0].attributes.demolish_by_date == null) ? `Date to be determined
` : `${display.formatDate(value.attributes.demolish_by_date)}
`}\nThis property is not on the demolition list
\nAddress: ${value.properties.address}
\nCommercial: ${value.properties.commercial_building}
\nPrice: $${parseInt(value.properties.price).toLocaleString()}
\nParcel: ${value.properties.parcel_id}
\nContractor: ${value.properties.contractor_name}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\n ${(value.properties.demolish_by_date == undefined || value.properties.demolish_by_date == null) ? `Expected Date: Date to be determined
` : `Expected Date:${display.formatDate(value.properties.demolish_by_date)}
`}\nAddress: ${value.properties.address}
\nCommercial: ${value.properties.commercial_building}
\nPrice: $${parseInt(value.properties.price).toLocaleString()}
\nParcel: ${value.properties.parcel_id}
\nContractor: ${value.properties.contractor_name}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\n ${(value.properties.demolish_by_date == undefined || value.properties.demolish_by_date == null) ? `Expected Date: Date to be determined
` : `Expected Date:${display.formatDate(value.properties.demolish_by_date)}
`}\nNo demolitions are happening nearby.
`;\n }\n return dataParsing;\n }\n\n buildStabilizationsNear(value, display) {\n let dataParsing = { title: \"Stabilizations Nearby\", content: null };\n if (value && value.data.features.length) {\n value.data.features.forEach(function (value, index) {\n\n if (index == 0) {\n dataParsing.content = `\nAddress: ${value.properties.address}
\nParcel: ${value.properties.parcel_id}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\nStatus: ${value.properties.rehab_status}
\nAddress: ${value.properties.address}
\nParcel: ${value.properties.parcel_id}
\nCouncil District: ${value.properties.council_district}
\nNeighborhood: ${value.properties.neighborhood}
\nStatus: ${value.properties.rehab_status}
\nNo stabilizations are happening nearby.
`;\n }\n return dataParsing;\n }\n\n buildImproveDet(value, display) {\n let dataParsing = { title: \"Improve Detroit Issues Nearby\", content: null };\n if (value && value.data.features.length) {\n value.data.features.forEach(function (value, index) {\n if (index == 0) {\n dataParsing.content = `\n \nType: ${value.properties.Request_Type_Title}
\nStatus: ${value.properties.Status}
\nReported on: ${display.formatDate(value.properties.Created_At)}
\nType: ${value.properties.Request_Type_Title}
\nStatus: ${value.properties.Status}
\nReported on: ${display.formatDate(value.properties.Created_At)}
\nNo active issues nearby.
`;\n }\n return dataParsing;\n }\n\n selectDataBlockType(display, value) {\n switch (value.id) {\n case 'council-members':\n try {\n return display.buildCouncil(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'bop-members':\n try {\n return display.buildBOP(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'district-managers':\n try {\n return display.buildDistrictManagers(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'business-liaison':\n try {\n return display.buildBusinessLiaison(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'district-inspectors':\n try {\n return display.buildInspector(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'neighborhood':\n try {\n return display.buildNeighborhood(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'nez':\n try {\n return display.buildNEZ(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'nrsa':\n try {\n return display.buildNRSA(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'assessors-data':\n try {\n return display.buildAssessors(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'permit-data':\n try {\n return display.buildPermit(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'rental-data':\n try {\n return display.buildRental(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'blight-data':\n try {\n return display.buildBlight(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'demos-data':\n try {\n return display.buildDemosNear(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'stabilization-data':\n try {\n return display.buildStabilizationsNear(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'demo-status':\n try {\n return display.buildDemoStatus(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'npo':\n try {\n return display.buildNPO(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'improve-det':\n try {\n return display.buildImproveDet(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'schools':\n try {\n return display.buildSchools(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'recycling':\n try {\n return display.buildRecycling(value, display);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'historicDistrict':\n try {\n return display.buildHistoricDistrict(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'fireEscrow':\n try {\n return display.buildFireEscrow(value);\n } catch (error) {\n // console.log(error);\n return '';\n }\n break;\n\n case 'DWSDBackupProtection':\n try {\n return display.buildDWSDBackupProtection(value);\n } catch (error) {\n return '';\n }\n break;\n\n case 'HRDFlooding':\n try {\n return display.buildHRDFlooding(value);\n } catch (error) {\n return '';\n }\n break;\n\n default:\n return '';\n break;\n }\n }\n\n setDatasetPagination(display, dataset){\n if(display.hasAttribute('data-pagination')){\n let paginations = JSON.parse(display.getAttribute('data-pagination'));\n if(paginations[dataset.id]){\n let paginationObj = {start: paginations[dataset.id].start};\n if(dataset.data.features.length <= (paginations[dataset.id].end + 3)){\n paginationObj.end = dataset.data.features.length;\n paginationObj.more = false;\n }else{\n paginationObj.end = paginations[dataset.id].end + 3;\n paginationObj.more = true;\n }\n return paginationObj;\n }else{\n let paginationObj = {start: 0, end: 3, more: true};\n if(dataset.data.features){\n if(dataset.data.features.length <= 3){\n paginationObj.end = dataset.data.features.length;\n paginationObj.more = false;\n }\n }else{\n paginationObj.start = null;\n paginationObj.more = false;\n }\n return paginationObj;\n }\n }else{\n let paginationObj = {start: 0, end: 3, more: true};\n if(dataset.data.features){\n if(dataset.data.features.length <= 3){\n paginationObj.end = dataset.data.features.length;\n paginationObj.more = false;\n }\n }else{\n paginationObj.start = null;\n paginationObj.more = false;\n }\n return paginationObj;\n }\n }\n\n printInfo(display) {\n let divContents = display.buildDataSection(display);\n let a = window.open('', '', 'height=500, width=500');\n a.document.write('');\n a.document.write('');\n a.document.write('');\n a.document.write(divContents.children[1].innerHTML);\n a.document.write('');\n a.document.close();\n a.print();\n }\n\n buildDataBlock(display, dataSet) {\n const app = document.getElementsByTagName('my-home-info');\n const mapAvailable = app[0].getAttribute('data-map-available');\n const dataBlock = document.createElement('article');\n dataBlock.className = 'data-block';\n let pagination = display.setDatasetPagination(display, dataSet);\n let splitDataset = JSON.parse(JSON.stringify(dataSet));\n if(pagination.start !== null){\n splitDataset.data.features = dataSet.data.features.slice(pagination.start, pagination.end);\n }\n let datasetValues = display.selectDataBlockType(display, splitDataset);\n if (datasetValues == undefined || datasetValues.content == null) {\n return null;\n } else {\n const dataBlockTitle = document.createElement('p');\n dataBlockTitle.className = 'data-block-title';\n const dataBlockContent = document.createElement('article');\n dataBlockContent.className = 'data-block-content';\n dataBlockContent.innerHTML = datasetValues.content;\n if (mapAvailable == 'true') {\n const text = document.createElement('span');\n text.innerText = datasetValues.title;\n const mapButton = document.createElement('cod-button');\n mapButton.setAttribute('data-map-active-data', dataSet.id);\n mapButton.setAttribute('data-label', 'View Map');\n mapButton.setAttribute('data-size', 'xsmall');\n mapButton.setAttribute('data-icon', '');\n mapButton.setAttribute('data-img', 'https://detroitmi.gov/sites/detroitmi.localhost/files/2023-02/map.png');\n mapButton.setAttribute('data-img-alt', 'map');\n mapButton.setAttribute('data-shape', '');\n mapButton.setAttribute('data-hover', false);\n mapButton.setAttribute('data-extra-classes', 'fw-bold');\n mapButton.setAttribute('data-background-color', 'light');\n mapButton.setAttribute('data-primary', true);\n mapButton.addEventListener('click', (ev) => {\n if(ev.target.getAttribute('data-map-active-data')){\n app[0].setAttribute('data-map-active-data', ev.target.getAttribute('data-map-active-data'));\n app[0].setAttribute('data-app-state', 'map');\n }\n });\n dataBlockTitle.appendChild(text);\n dataBlockTitle.appendChild(mapButton);\n } else {\n dataBlockTitle.innerText = datasetValues.title;\n }\n dataBlock.appendChild(dataBlockTitle);\n dataBlock.appendChild(dataBlockContent);\n if(pagination.more){\n let loadMoreBtn = document.createElement('cod-button');\n loadMoreBtn.setAttribute('data-pagination-id', dataSet.id);\n loadMoreBtn.setAttribute('data-pagination', JSON.stringify(pagination));\n loadMoreBtn.setAttribute('data-label', 'Load More +');\n loadMoreBtn.setAttribute('data-size', 'xsmall');\n loadMoreBtn.setAttribute('data-icon', '');\n loadMoreBtn.setAttribute('data-img', '');\n loadMoreBtn.setAttribute('data-img-alt', '');\n loadMoreBtn.setAttribute('data-shape', '');\n loadMoreBtn.setAttribute('data-hover', false);\n loadMoreBtn.setAttribute('data-extra-classes', 'fw-bold');\n loadMoreBtn.setAttribute('data-background-color', 'primary');\n loadMoreBtn.setAttribute('data-primary', false);\n loadMoreBtn.addEventListener('click', (ev) => {\n if(ev.target.getAttribute('data-pagination')){\n let loadMoreSpinner = document.createElement('cod-spinner');\n loadMoreSpinner.setAttribute('data-type', 'border');\n loadMoreSpinner.setAttribute('data-background-color', 'primary');\n loadMoreSpinner.setAttribute('data-size', 'sm');\n let paginations = display.getAttribute('data-pagination');\n if(paginations === null){\n paginations = {};\n }else{\n paginations = JSON.parse(paginations);\n }\n paginations[`${ev.target.getAttribute('data-pagination-id')}`] = JSON.parse(ev.target.getAttribute('data-pagination'));\n display.setAttribute('data-pagination', JSON.stringify(paginations));\n ev.target.parentElement.appendChild(loadMoreSpinner);\n ev.target.remove();\n }\n });\n dataBlockContent.appendChild(loadMoreBtn);\n }\n return dataBlock;\n }\n }\n\n buildDataSection(display) {\n const app = document.getElementsByTagName('my-home-info');\n const appMode = app[0].getAttribute('data-app-mode');\n const results = document.createElement('section');\n results.id = 'data-results';\n if (appMode == 'my-home-info') {\n const sectionTitle = document.createElement('p');\n sectionTitle.className = 'data-title';\n sectionTitle.innerText = app[0].getAttribute('data-active-section').toUpperCase();\n results.appendChild(sectionTitle);\n }\n const dataBlocks = document.createElement('div');\n dataBlocks.id = 'data-blocks';\n results.appendChild(dataBlocks);\n\n const apiDataSets = JSON.parse(app[0].getAttribute('data-api-active-datasets'));\n for (const dataSet in apiDataSets) {\n if (Object.hasOwnProperty.call(apiDataSets, dataSet)) {\n if (display.buildDataBlock(display, apiDataSets[dataSet]) != null) {\n dataBlocks.appendChild(display.buildDataBlock(display, apiDataSets[dataSet]));\n }\n }\n }\n return results;\n }\n\n loadDisplay(display) {\n const shadow = display.shadowRoot;\n const displayWrapper = document.createElement('section');\n const geocoder = document.createElement('app-geocoder');\n const navTools = document.createElement('app-nav-tools');\n const app = document.getElementsByTagName('my-home-info');\n navTools.printInfo = display.printInfo;\n displayWrapper.id = 'display-wrapper';\n switch (this.getAttribute('data-display-type')) {\n case 'welcome':\n shadow.appendChild(display.welcomeStyle);\n const imageWrapper = document.createElement('div');\n imageWrapper.id = 'welcome-img-wrapper';\n imageWrapper.appendChild(this.neighborhoodImage);\n displayWrapper.appendChild(imageWrapper);\n const textWrapperWelcome = document.createElement('article');\n displayWrapper.appendChild(textWrapperWelcome);\n const titleWelcome = document.createElement('p');\n titleWelcome.setAttribute('aria-label', 'title');\n titleWelcome.innerText = 'It’s all here. All in one place.';\n titleWelcome.className = 'display-title';\n textWrapperWelcome.appendChild(titleWelcome)\n const textWelcome = document.createElement('p');\n textWelcome.innerText = 'Enter your home address to find out your city councilmember and neighborhood district manager, along with local information about trash/recycling, your neighborhood police officer, city issues reported in your neighborhood, and more.';\n textWrapperWelcome.appendChild(textWelcome);\n textWrapperWelcome.appendChild(geocoder);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'active':\n shadow.appendChild(display.welcomeStyle);\n displayWrapper.appendChild(geocoder);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'loading':\n const loader = document.createElement('cod-loader');\n loader.setAttribute('data-color', 'color-3');\n displayWrapper.appendChild(loader);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'results':\n let parcelData = JSON.parse(app[0].getAttribute('data-parcel-id'));\n shadow.appendChild(display.resultsStyle);\n let resultsContainer = document.createElement('section');\n resultsContainer.className = 'results-container';\n resultsContainer.appendChild(navTools);\n let dataSetResults = document.createElement('article');\n dataSetResults.className = 'dataset-results';\n let addressBox = document.createElement('article');\n addressBox.className = 'result-address';\n addressBox.innerText = parcelData.address;\n dataSetResults.appendChild(addressBox);\n let results = display.buildDataSection(display);\n dataSetResults.appendChild(results);\n resultsContainer.appendChild(dataSetResults);\n displayWrapper.appendChild(resultsContainer);\n shadow.appendChild(displayWrapper);\n break;\n\n case 'error':\n let errorContainer = document.createElement('section');\n shadow.appendChild(display.resultsStyle);\n errorContainer.className = 'results-container';\n errorContainer.appendChild(navTools);\n let errorBox = document.createElement('article');\n errorBox.className = 'error-result';\n errorBox.innerHTML = `\n \n0;)p--}0===i(t[n],h)?ot(t,n,p):ot(t,++p,r),p<=e&&(n=p+1),e<=p&&(r=p-1)}}function ot(t,e,n){var r=t[e];t[e]=t[n],t[n]=r}function st(t,e){if(!(this instanceof st))return new st(t,e);this._maxEntries=Math.max(4,t||9),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),e&&this._initFormat(e),this.clear()}function at(t,e){ut(t,0,t.children.length,e,t)}function ut(t,e,n,r,i){i||(i=yt(null)),i.minX=1/0,i.minY=1/0,i.maxX=-1/0,i.maxY=-1/0;for(var o,s=e;s 0;)p--}0===i(t[n],h)?Be(t,n,p):Be(t,++p,r),p<=e&&(n=p+1),e<=p&&(r=p-1)}}function Be(t,e,n){var r=t[e];t[e]=t[n],t[n]=r}function ke(t,e){if(!(this instanceof ke))return new ke(t,e);this._maxEntries=Math.max(4,t||9),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),e&&this._initFormat(e),this.clear()}function ze(t,e){je(t,0,t.children.length,e,t)}function je(t,e,n,r,i){i||(i=Ze(null)),i.minX=1/0,i.minY=1/0,i.maxX=-1/0,i.maxY=-1/0;for(var o,s=e;se&&(i.push(n),r=n);return r!==n&&i.push(n),i}(t,r),function(t,e){var n=t.length-1,r=[t[0]];return ie(t,0,n,e,r),r.push(t[n]),r}(t,r)}function se(t,e,n){return oe(t.map((function(t){return{x:t[0],y:t[1],z:t[2]}})),e,n).map((function(t){return t.z?[t.x,t.y,t.z]:[t.x,t.y]}))}function ae(t,e,n){return t.map((function(t){var r=t.map((function(t){return{x:t[0],y:t[1]}}));if(r.length<4)throw new Error("invalid polygon");for(var i=oe(r,e,n).map((function(t){return[t.x,t.y]}));!function(t){return!(t.length<3||3===t.length&&t[2][0]===t[0][0]&&t[2][1]===t[0][1])}(i);)i=oe(r,e-=.01*e,n).map((function(t){return[t.x,t.y]}));return i[i.length-1][0]===i[0][0]&&i[i.length-1][1]===i[0][1]||i.push(i[0]),i}))}function ue(t,e){if(!I(e=e||{}))throw new Error("options is invalid");var n=e.resolution||1e4,r=e.sharpness||.85;if(!t)throw new Error("line is required");if(!b(n))throw new Error("resolution must be an number");if(!b(r))throw new Error("sharpness must be an number");for(var i=[],o=new bs({points:J(t).coordinates.map((function(t){return{x:t[0],y:t[1]}})),duration:n,sharpness:r}),s=0;s