1let mapsLoader=null;function loadGoogleMaps(apiKey){return mapsLoader||(mapsLoader=new Promise((resolve,reject)=>{if(window.google&&window.google.maps&&window.google.maps.importLibrary){resolve(window.google);return}(g=>{let h;const c="google",l="importLibrary",q="__ib__",m=document;let b=window;b=b[c]||(b[c]={});const d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise((res,rej)=>{const a=m.createElement("script");e.set("libraries",[...r]+"");for(const k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q),a.src=`https://maps.${c}apis.com/maps/api/js?`+e,d[q]=res,a.onerror=()=>h=rej(new Error("Google Maps could not load.")),a.nonce=m.querySelector("script[nonce]")?.nonce||"",m.head.append(a)}));d[l]?console.warn("Google Maps JS API only loads once."):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({key:apiKey,v:"weekly"});const start=performance.now(),tick=()=>{window.google?.maps?.importLibrary?resolve(window.google):performance.now()-start>1e4?reject(new Error("Google Maps load timed out.")):requestAnimationFrame(tick)};tick()}),mapsLoader)}function starRow(rating){const row=document.createElement("span");row.className="ccc-greviews__stars",row.setAttribute("aria-label",`${rating} out of 5 stars`);const rounded=Math.round(rating||0);return row.textContent="\u2605\u2605\u2605\u2605\u2605\u2606\u2606\u2606\u2606\u2606".slice(5-rounded,10-rounded),row}function reviewText(review){const t=review.text;return t?typeof t=="string"?t:t.text||"":""}function reviewTime(review){if(!review.publishTime)return 0;const t=new Date(review.publishTime).getTime();return Number.isNaN(t)?0:t}class CCCGoogleReviews extends HTMLElement{connectedCallback(){if(this.dataset.ready)return;this.dataset.ready="1";const key=this.dataset.apiKey,placeId=this.dataset.placeId;if(!(!key||!placeId))if("IntersectionObserver"in window){const io=new IntersectionObserver(entries=>{entries.some(e=>e.isIntersecting)&&(io.disconnect(),this.#render(key,placeId))},{rootMargin:"400px"});io.observe(this)}else this.#render(key,placeId)}async#render(key,placeId){try{await loadGoogleMaps(key);const{Place}=await window.google.maps.importLibrary("places"),place=new Place({id:placeId});await place.fetchFields({fields:["reviews","rating","userRatingCount","googleMapsURI","displayName"]});const reviews=(place.reviews||[]).filter(r=>reviewText(r).trim());if(!reviews.length)return;reviews.sort((a,b)=>reviewTime(b)-reviewTime(a));const max=Math.max(1,Math.min(5,parseInt(this.dataset.max,10)||5)),listingUrl=this.dataset.listingUrl||place.googleMapsURI||"";this.#paintSummary(place),this.#paintReviews(reviews.slice(0,max),place.googleMapsURI),this.#paintAll(listingUrl),this.hidden=!1,this.#wireNav()}catch(err){console.warn("CCC Google reviews: unable to load",err)}}#paintSummary(place){const el=this.querySelector("[data-greviews-summary]");if(!el||place.rating==null)return;const score=document.createElement("span");if(score.className="ccc-greviews__summary-score",score.textContent=Number(place.rating).toFixed(1),el.append(score),el.append(starRow(place.rating)),place.userRatingCount){const count=document.createElement("span");count.textContent=`(${place.userRatingCount.toLocaleString()} Google reviews)`,el.append(count)}el.hidden=!1}#paintReviews(reviews,placeUri){const track=this.querySelector("[data-greviews-track]");if(!track)return;const frag=document.createDocumentFragment();reviews.forEach(review=>{const author=review.authorAttribution||{},href=author.uri||placeUri||"",card=document.createElement(href?"a":"div");card.className="ccc-greviews__card",card.setAttribute("role","listitem"),href&&(card.href=href,card.target="_blank",card.rel="noopener noreferrer nofollow"),card.append(starRow(review.rating));const text=document.createElement("p");text.className="ccc-greviews__text",text.textContent=reviewText(review),card.append(text);const meta=document.createElement("div");if(meta.className="ccc-greviews__meta",author.photoURI){const img=document.createElement("img");img.className="ccc-greviews__avatar",img.src=author.photoURI,img.alt="",img.loading="lazy",img.width=22,img.he
1ight=22,meta.append(img)}const name=document.createElement("span");if(name.className="ccc-greviews__author",name.textContent=author.displayName||"Google user",meta.append(name),review.relativePublishTimeDescription){const when=document.createElement("span");when.textContent=review.relativePublishTimeDescription,meta.append(when)}card.append(meta),frag.append(card)}),track.replaceChildren(frag)}#paintAll(url){const link=this.querySelector("[data-greviews-all]");!link||!url||(link.href=url,link.hidden=!1)}#wireNav(){const track=this.querySelector("[data-greviews-track]"),prev=this.querySelector("[data-greviews-prev]"),next=this.querySelector("[data-greviews-next]");if(!track||!prev||!next)return;const page=()=>Math.max(track.clientWidth*.9,240);prev.addEventListener("click",()=>track.scrollBy({left:-page(),behavior:"smooth"})),next.addEventListener("click",()=>track.scrollBy({left:page(),behavior:"smooth"}));const update=()=>{const maxScroll=track.scrollWidth-track.clientWidth,canScroll=maxScroll>1;prev.hidden=next.hidden=!canScroll,prev.disabled=track.scrollLeft<=1,next.disabled=track.scrollLeft>=maxScroll-1};track.addEventListener("scroll",update,{passive:!0}),window.addEventListener("resize",update),update()}}customElements.get("ccc-google-reviews")||customElements.define("ccc-google-reviews",CCCGoogleReviews); 2//# sourceMappingURL=/cdn/shop/t/40/assets/ccc-google-reviews.js.map?v=8525714151770129751784505920
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.