(function (w, d) {
w.tsUpdateMetaDescription = function () {
var existingTitle = document.querySelector('title').innerText;
document.querySelector('title').innerText = "***** Rating: 5.0 - 36 Reviews - " + existingTitle;
var existingDesc = document.querySelector('meta[name="description"]').getAttribute("content");
document.querySelector('meta[name="description"]').setAttribute("content", "***** Rating: 5.0 - 36 Reviews - " + existingDesc);
};
var timestamp = document.createElement("meta");
timestamp.setAttribute("name", "ts-timestamp");
timestamp.setAttribute("content", new Date().toLocaleString());
document.head.appendChild(timestamp);
var businessKey = "3ez07dcs";
var locationKey = "";
var tenantKey = "";
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var accessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbnRpdHlJZCI6IjNlejA3ZGNzIiwiZXhwIjoxNzYyMjUxNzg2LCJpc3MiOiJUcnVzdGlzdCIsImF1ZCI6IldpZGdldHMifQ.Ai6i_-z8ViszfaY0DextRigfQz63WPHRK0IEcdUJcQQ";
function start(f) { /in/.test(document.readyState) ? setTimeout(start, 5, f) : f(); }
tsAddCssTag("https://fonts.googleapis.com/css2?family=Poppins&display=swap");;
tsAddCssTag("https://widgetassets.trustist.com/css/cleanslate.css");
tsAddCssTag("https://widgetassets.trustist.com/css/sidebar.css?v=1.0.0");
w.trustist ??= {};
w.trustist.sidebar = {
draw: function () {
if (d.getElementById("ts-json") === null) {
var filter = Array.prototype.filter;
var els = d.querySelectorAll('h1,title,h2');
var productName = "Brooke and Associates";
var field = filter.call(els, function (node) {
return node.innerText != "";
})[0];
if (typeof field !== "undefined") {
productName = field.innerText;
}
var json = "[{\"@type\":\"Product\",\"@id\":\"{{url}}#trustist\",\"description\":null,\"logo\":\"https://content.trustist.com/brandlogos/f03f841c-2931-4122-8784-51e2b9851719.png\",\"image\":[\"https://content.trustist.com/brandlogos/f03f841c-2931-4122-8784-51e2b9851719.png\"],\"name\":\"{{productName}}\",\"alternateName\":null,\"hasMap\":null,\"geo\":null,\"telephone\":null,\"url\":\"{{url}}\",\"address\":null,\"branchOf\":null,\"openingHoursSpecification\":null,\"sameAs\":[\"https://www.trustist.com/local-reviews/Website-Review-brooke-and-associates-reviews-4435.html\"],\"@context\":\"http://schema.org\",\"brand\":{\"@type\":\"Organization\",\"@id\":null,\"description\":null,\"logo\":\"https://content.trustist.com/brandlogos/f03f841c-2931-4122-8784-51e2b9851719.png\",\"image\":[\"https://content.trustist.com/brandlogos/f03f841c-2931-4122-8784-51e2b9851719.png\"],\"name\":\"Brooke and Associates\",\"alternateName\":null,\"hasMap\":null,\"geo\":null,\"telephone\":null,\"url\":null,\"address\":null,\"branchOf\":null,\"openingHoursSpecification\":null,\"sameAs\":null},\"aggregateRating\":{\"@type\":\"AggregateRating\",\"ratingValue\":5,\"bestRating\":5,\"worstRating\":1,\"reviewCount\":36},\"review\":{\"@type\":\"Review\",\"url\":\"https://www.trustist.com/local-reviews/Website-Review-brooke-and-associates-reviews-4435.html\",\"author\":{\"@type\":\"Person\",\"name\":\"Steve Grace\",\"address\":null},\"datePublished\":\"2025-06-27T09:55:42.000Z\",\"headline\":\"\",\"isBasedOn\":null,\"reviewBody\":\"Our project is the demolition of an existing lightweight conservatory and replacement with a heated single room extension with an octagonal roof lantern. \\r\\n\\r\\nBrooke and Associates acted as Post Design Contract Administrator for this project. \\r\\n\\r\\nPre Build, they prepared a very comprehensive Tender Package based on our initial specification to thus obtain detailed Contractors’ pricing and delivery proposals . Additionally, they provided expert advice in the type of Contract to use, given that we had a nominated sub-contractor for the Roof Lantern. \\r\\n\\r\\nDuring the build, they visited site every week to check progress, support interim valuations, administrate the Contact including many Extensions of Time’ requests from the Contractor , provide valuable advice on some ‘technical’ issues and managed the Client/Contractor interface, \\r\\n\\r\\nAt the time of writing this review, we have recently reached Practical Completion and based on Brooke and Associates performance to date we certainly recommend them for such a role.\",\"reviewRating\":{\"@type\":\"Rating\",\"ratingValue\":5,\"bestRating\":5,\"worstRating\":1},\"publisher\":{\"@type\":\"Organization\",\"name\":\"Trustist\",\"sameAs\":\"https://www.trustist.com\"},\"reply\":null,\"replyDate\":null,\"subject\":null},\"mpn\":\"{{url}}\",\"sku\":\"{{url}}\"}]";
var a = d;
var c = a.createElement("script");
c.type = 'application/ld+json';
c.id = 'ts-json';
c.innerText = json
.replace(new RegExp("{{url}}", 'g'), w.location.href)
.replace("{{productName}}", productName)
.replace("\"{{productDesc}}\"", JSON.stringify((d.body.innerText || d.body.textContent).replace(/[^ -~]+/g, "").substring(0, 200) + "..."));
a = a.getElementsByTagName("head")[0];
a.appendChild(c);
}
// iterate over all widgets on the page and render
var div = document.querySelector("[ts-sidebarWidget],div.ts-sidebarWidget");
if (!div) {
div = d.createElement('div');
div.setAttribute('ts-sidebarWidget', '');
d.body.appendChild(div);
}
if (div) {
tsDisplayWidget(div, businessKey, locationKey, tenantKey);
}
else {
}
}
};
start(w.trustist.sidebar.draw);
function tsDisplayWidget(target) {
// get options before cleanslate
var options = tsReadAttributes(target);
// draw the main template
var template = '
';
var theme = options.theme;
if (theme !== "white" && theme !== "blue" && theme !== "orange") theme = "white";
var buttonLogo = options.theme === "white" ? "TrustedBy-01.svg" : "TrustedBy-White-01.svg";
target.innerHTML = template
.replace(new RegExp("{{side}}", "g"), options.side)
.replace(new RegExp("{{theme}}", "g"), theme)
.replace(new RegExp("{{buttonLogo}}", "g"), buttonLogo)
.replace(new RegExp("{{buttonBottom}}", "g"), options.widgetBottom)
.replace(new RegExp("{{url}}", "g"), options.reviewPageUrl || "https://www.trustist.com/local-reviews/Website-Review-brooke-and-associates-reviews-4435.html");
// draw the reviews
var xhr = new XMLHttpRequest();
var url = tsBuildUrl(options);
xhr.open("GET", url);
xhr.onload = function () {
if (xhr.status === 200 && xhr.responseText !== "") {
var reviews = JSON.parse(xhr.responseText);
tsDrawReviews(target, reviews, options);
tsWireUp(options);
} else {
}
};
xhr.send();
}
function tsBuildUrl(options) {
var url = "https://widget.trustist.com/reviewlistdata?v=1&accessToken=" + accessToken + "&pageNum=1&pageSize=" + options.pageSize;
if (typeof tenantKey !== "undefined" && tenantKey !== "") url += "&tenantKey=" + tenantKey;
if (typeof businessKey !== "undefined" && businessKey !== "") url += "&businessKey=" + businessKey;
if (typeof locationKey !== "undefined" && locationKey !== "") url += "&locationKey=" + locationKey;
if (options.ratingsAbove > 0) url += "&ratingFrom=" + options.ratingsAbove;
if (options.exclude > '') url += "&exclude=" + options.exclude;
return url;
}
function tsDrawReviews(target, reviews, options) {
var reviewContent = '';
var template = '
';
var replyTemplate = '';
reviews.forEach(function (review) {
var d = new Date(review.datePublished);
var reviewDate = d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear();
var thisReview = template
.replace('{{reviewSourceLogo}}', review.image)
.replace('', review.author.name)
.replace('', reviewDate)
.replace('{{rating}}', (review.reviewRating.ratingValue / 2).toFixed(1))
.replace('{{reviewStarsWidth}}', ((130 * review.reviewRating.ratingValue / review.reviewRating.bestRating).toFixed(0)))
.replace('', review.reviewBody);
if (review.reply > '') {
var replyDate = new Date(review.replyDate);
var replyDateString = replyDate.getDate() + " " + months[replyDate.getMonth()] + " " + replyDate.getFullYear();
thisReview = thisReview.replace(
'',
replyTemplate
.replace('', review.reply)
.replace('', replyDateString));
}
reviewContent += thisReview;
});
target.innerHTML = target.innerHTML.replace('', reviewContent).replace('', reviews.length);
}
function tsReadAttributes(target) {
return {
pageSize: target.getAttribute("ts-page-size") || 20,
side: target.getAttribute("ts-side") === "left" ? "left" : "right",
ratingsAbove: parseInt(target.getAttribute("ts-ratings-above")) || 0,
exclude: target.getAttribute("ts-exclude") || "",
theme: target.getAttribute("ts-theme") || "white",
reviewPageUrl: target.getAttribute("ts-reviews-url"),
widgetBottom: target.getAttribute("ts-widget-bottom") || 13.0625,
};
}
function tsAddCssTag(url) {
var includedAlready = tsCheckIfIncluded(url);
var head = d.getElementsByTagName("head")[0];
if (!includedAlready) {
var tag = d.createElement("link");
tag.rel = "stylesheet";
tag.type = "text/css";
tag.href = url;
head.appendChild(tag);
}
}
function tsCheckIfIncluded(file) {
var links = d.getElementsByTagName("link");
for (var i = 0; i < links.length; i++) {
if (links[i].href?.substr(-file.length) === file)
return true;
}
var scripts = d.getElementsByTagName("script");
for (var j = 0; j < scripts.length; j++) {
if (scripts[j].src?.substr(-file.length) === file)
return true;
}
return false;
}
function addClass(element, className) {
if (element.classList) {
element.classList.add(className); // Modern Browsers
} else {
var currentClassName = element.className;
if (currentClassName.indexOf(className) === -1) {
element.className += ' ' + className; // Older Browsers
}
}
}
function removeClass(element, className) {
if (element.classList) {
element.classList.remove(className); // Modern Browsers
} else {
var currentClassName = ' ' + element.className + ' ';
var classToRemove = ' ' + className + ' ';
if (currentClassName.indexOf(classToRemove) !== -1) {
element.className = currentClassName.replace(classToRemove, ' ').trim(); // Older Browsers
}
}
}
function isTouchDevice() {
return 'ontouchstart' in window || navigator.maxTouchPoints;
}
function closeOverlayHover(e) {
if (isTouchDevice()) return; // Skip hover-close on touch devices
var overlay = d.getElementById('ts-sidebar-overlay');
var overlayInner = d.getElementById('ts-sidebar-overlay-inner');
var overlayPopoverLink = d.getElementById('ts-sidebar-read-more-reviews-btn');
removeClass(overlayInner, 'ts-sidebar-overlay-inner-visible');
removeClass(overlayPopoverLink, 'ts-sidebar-read-more-reviews-btn-visible');
overlayInner.addEventListener(
'transitionend',
function () {
removeClass(overlay, 'ts-sidebar-overlay-visible');
},
{ once: true }
);
}
function closeOverlayClick(e) {
var overlay = d.getElementById('ts-sidebar-overlay');
var overlayInner = d.getElementById('ts-sidebar-overlay-inner');
var overlayPopoverLink = d.getElementById('ts-sidebar-read-more-reviews-btn');
if (e.target === overlay || e.target.closest('.ts-sidebar-overlay-close-btn')) {
removeClass(overlayInner, 'ts-sidebar-overlay-inner-visible');
removeClass(overlayPopoverLink, 'ts-sidebar-read-more-reviews-btn-visible');
overlayInner.addEventListener(
'transitionend',
function () {
removeClass(overlay, 'ts-sidebar-overlay-visible');
},
{ once: true }
);
}
}
function openOverlay() {
var overlay = d.getElementById('ts-sidebar-overlay');
var overlayInner = d.getElementById('ts-sidebar-overlay-inner');
addClass(overlay, 'ts-sidebar-overlay-visible');
addClass(overlayInner, 'ts-sidebar-overlay-inner-visible');
}
function handleShowOverlayPopover() {
var overlayPopoverLink = d.getElementById('ts-sidebar-read-more-reviews-btn');
overlayPopoverLink.classList.add('ts-sidebar-read-more-reviews-btn-visible');
}
function tsWireUp(options) {
var button = d.getElementById('ts-sidebar-button');
var overlayInner = d.getElementById('ts-sidebar-overlay-inner');
var overlayCloseBtn = d.getElementById('ts-sidebar-overlay-close-btn');
if (isTouchDevice()) {
button.addEventListener('click', openOverlay);
} else {
button.addEventListener('mouseover', openOverlay);
overlayInner.addEventListener('mouseleave', closeOverlayHover);
}
overlayCloseBtn.addEventListener('click', closeOverlayClick);
overlayInner.addEventListener('scroll', handleShowOverlayPopover);
}
})(window, document);