@breadbutter/report-templates 0.0.0-stage → 1.0.0-t95dd9d1bd4a4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/bread-butter-01-executive-report-template.js +106 -0
- package/bread-butter-02-report-for-your-boss-template.js +106 -0
- package/bread-butter-03-attribution-leads-template.js +106 -0
- package/bread-butter-04-ads-spend-template.js +106 -0
- package/bread-butter-05-leads-found-template.js +106 -0
- package/bread-butter-05b-leads-found-notools-template.js +106 -0
- package/bread-butter-06-leads-followup-template.js +106 -0
- package/bread-butter-07-exit-destinations-template.js +106 -0
- package/bread-butter-08-ai-assistants-geo-template.js +106 -0
- package/bread-butter-09-email-campaigns-template.js +106 -0
- package/bread-butter-10-bots-ai-crawlers-template.js +106 -0
- package/bread-butter-11-scorecard-template.js +106 -0
- package/bread-butter-12-health-check-template.js +106 -0
- package/bread-butter-13-old-school-website-analytics-template.js +106 -0
- package/bread-butter-14-intelligence-brief-template.js +106 -0
- package/bread-butter-15-company-intelligence-template.js +106 -0
- package/package.json +24 -4
package/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Bread & Butter report templates
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Generated from breadbutter-backend (Mcp/Reports/Templates and Assets). Do not edit by hand.
|
|
4
|
+
Each script draws one report from the values the assistant writes in `window.BB_REPORT`; no customer data is in this package.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
(function(){var T="\u003C!doctype html\u003E\n\n\u003Chtml lang=\u0022en\u0022\u003E\u003Chead\u003E\u003Cmeta charset=\u0022utf-8\u0022\u003E\u003Cmeta name=\u0022viewport\u0022 content=\u0022width=device-width,initial-scale=1\u0022\u003E\n\u003Ctitle\u003EBread \u0026amp; Butter \u002B {{account_name}} Executive report: {{period}}\u003C/title\u003E\n\u003Clink rel=\u0022preconnect\u0022 href=\u0022https://fonts.googleapis.com\u0022\u003E\u003Clink href=\u0022https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700\u0026display=swap\u0022 rel=\u0022stylesheet\u0022\u003E\n\u003Cstyle\u003E\n:root{--navy:#1f2937;--slate:#5b6472;--gold:#ffc72c;--paper:#f5f6f8;--sand:#e4e7eb;--grey:#8b94a1;--ink:#22353f;--alert:#b4432c}\n*{box-sizing:border-box}body{margin:0;background:var(--paper);color:var(--ink);font:15px/1.55 \u0022Inter\u0022,\u0022PP Neue Montreal\u0022,system-ui,sans-serif}\n.wrap{max-width:980px;margin:0 auto;padding:0 24px 48px}\nheader{background:var(--navy);color:#fff}header .wrap{display:flex;justify-content:space-between;align-items:center;padding-top:22px;padding-bottom:22px}\nheader .meta{text-align:right;font-size:12.5px;letter-spacing:.06em;text-transform:uppercase;color:#5b6472}\n.hero{padding:44px 0 18px}.kick{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--slate);font-weight:600}\nh1{font-family:\u0022Fraunces\u0022,\u0022Roslindale\u0022,Georgia,serif;font-weight:400;font-size:44px;line-height:1.1;margin:10px 0 12px;color:var(--navy)}\n.lede{font-size:17px;color:var(--slate);max-width:760px}\nh2{font-family:\u0022Fraunces\u0022,\u0022Roslindale\u0022,Georgia,serif;font-weight:400;font-size:28px;margin:44px 0 6px}\n.sub{color:var(--grey);font-size:14px;margin-bottom:18px}\n.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:26px}\n.k{background:#fff;border-top:3px solid var(--navy);padding:16px 18px}.k .v.up:after{content:\u0022 \\2191\u0022;font-size:22px;color:var(--slate)}.k.alert{border-top-color:var(--alert);background:#fbefeb}.k.alert .v,.k.alert .l{color:var(--alert)}\n.k .l{font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--grey);font-weight:600}\n.k .v{font-family:\u0022Fraunces\u0022,Georgia,serif;font-size:36px;line-height:1.1;margin-top:6px}\n.k .d{font-size:13px;color:var(--slate);margin-top:4px}\nol.story{list-style:none;padding:0;margin:0;counter-reset:s}\nol.story li{background:#fff;padding:18px 22px 18px 64px;margin-bottom:10px;position:relative;counter-increment:s}\nol.story li:before{content:counter(s);position:absolute;left:20px;top:16px;width:30px;height:30px;border-radius:50%;background:var(--sand);color:var(--navy);font:600 14px/30px \u0022Inter\u0022;text-align:center}\n.ih{font-family:\u0022Fraunces\u0022,Georgia,serif;font-size:19px;line-height:1.3}\n.ih a,p a{color:var(--navy);text-decoration:underline;text-decoration-color:var(--gold);text-underline-offset:3px}\nol.story p{margin:6px 0 0;color:var(--slate)}\n.two{display:grid;grid-template-columns:1.1fr 1fr;gap:16px}\n.card{background:#fff;padding:20px 22px}.card h3{margin:0 0 4px;font:600 15px \u0022Inter\u0022}.card .n{font-size:13px;color:var(--grey);margin-bottom:10px}\nsvg.ch .bv{font:600 12px Inter;fill:var(--navy)}svg.ch .bl{font:12px Inter;fill:var(--grey)}\n.sr{display:grid;grid-template-columns:170px 1fr 34px;gap:10px;align-items:center;font-size:13.5px;padding:6px 0}\n.sb{background:var(--paper);height:10px}.sb i{display:block;height:10px;background:var(--slate)}.sr:first-child .sb i{background:var(--gold)}.sr b{text-align:right}\n.next{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}.next div{background:var(--navy);color:#fff;padding:18px 20px}\n.next b{display:block;font-family:\u0022Fraunces\u0022,Georgia,serif;font-weight:400;font-size:18px;margin-bottom:6px;color:var(--gold)}.next span{font-size:14px;color:#e5e7eb}.next div.att{background:#fbefeb;border-left:4px solid var(--alert)}.next div.att b{color:var(--alert)}.next div.att span{color:var(--navy)}\n.note{font-size:12.5px;color:var(--grey);margin-top:10px}\n.tbl{padding:8px 0 16px}.tbl table{width:100%;border-collapse:collapse;font-size:14px}.tbl th{text-align:right;font:600 11.5px Inter;letter-spacing:.06em;text-transform:uppercase;color:var(--grey);padding:12px 18px;border-bottom:1px solid var(--sand)}.tbl th:first-child,.tbl td:first-child{text-align:left}\n.tbl td{text-align:right;padding:11px 18px;border-bottom:1px solid var(--paper);vertical-align:top}.tbl td span{display:block;font-size:12.5px;color:var(--grey)}.tbl td em{font-style:normal;font-weight:600}\n.tbl tr.best td em{background:var(--gold);padding:2px 8px}.tbl tr.good td em{background:#fff3c4;padding:2px 8px}.tbl tr.alert td em{background:var(--alert);color:#fff;padding:2px 8px}.tbl td i{font-style:normal;color:var(--grey);font-size:12.5px}.tbl td b.dn{color:var(--alert)}.tbl .note{padding:0 18px}\n@media(max-width:720px){.tbl td,.tbl th{padding:10px 10px}}\n.cm .tbl th:not(:first-child),.cm .tbl td:not(:first-child){width:1%;white-space:nowrap;padding-left:8px;padding-right:16px}.cm .tbl th:not(:first-child){white-space:normal;line-height:1.3}\n.cm{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}.mapc .map{display:block;margin-top:4px}\n.map .ml{font:600 10.5px Inter;fill:#22353f;paint-order:stroke;stroke:#fcfcfb;stroke-width:3px}.map .mr{font-weight:500;fill:#43535c}.map .ma{font:600 11px Inter;fill:#b4432c;paint-order:stroke;stroke:#fcfcfb;stroke-width:3px}\n.lg{display:flex;flex-wrap:wrap;gap:12px;font-size:12px;color:var(--slate);margin-top:10px}.lg i{display:inline-block;width:11px;height:11px;border-radius:50%;margin-right:5px;vertical-align:-1px;border:1px solid #22353f}\n@media(max-width:720px){.cm{grid-template-columns:1fr}}\n@media(max-width:720px){.cm .tbl th,.cm .tbl td{padding:9px 5px!important;font-size:13px}.cm .tbl th:not(:first-child),.cm .tbl td:not(:first-child){white-space:normal}.cm .tbl th{font-size:10px}.tbl td span,.tbl td i{font-size:11.5px}.tbl tr td em{padding:2px 5px!important}}\nfooter{margin-top:44px;padding-top:16px;border-top:1px solid var(--sand);font-size:12.5px;color:var(--grey);display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap}\n@media(max-width:720px){.kpis{grid-template-columns:1fr 1fr}.two,.next{grid-template-columns:1fr}h1{font-size:34px}.sr{grid-template-columns:120px 1fr 30px}header .meta{display:none}}\n\nheader{background:linear-gradient(110deg,#fff6d6,#e6f4fd);color:var(--ink);border-bottom:1px solid var(--sand)}header .meta{color:var(--slate)}header .pbtn{border-color:var(--sand)}header .pbtn svg{stroke:var(--ink)}\nh1,h2,.ih,.k .v,.next b{font-family:Inter,system-ui,sans-serif!important;font-weight:700!important;letter-spacing:-.01em}.next b{color:var(--gold)}\n\n.brand{display:flex;align-items:center;gap:10px;color:#fff}.brand b{font-family:Fraunces,Georgia,serif;font-weight:600;font-size:21px;letter-spacing:.01em;line-height:1}.brand small{display:block;font:600 10px Inter;letter-spacing:.32em;color:var(--gold);margin-top:3px}\nheader .right{display:flex;align-items:center;gap:14px}\n.pbtn{width:34px;height:34px;border-radius:50%;border:1px solid rgba(255,255,255,.35);background:transparent;cursor:pointer;display:grid;place-items:center;padding:0}\n.pbtn svg{width:17px;height:17px;fill:none;stroke:#fff;stroke-width:1.8;stroke-linejoin:round}\n.k .v.dn:after{content:\u0022 \\2193\u0022;font-size:22px;color:var(--slate)}\n.k.alert .v.up:after{color:var(--alert)}\n.hero{padding:36px 0 8px}\n.cols{display:grid;grid-template-columns:1fr 1.05fr;gap:18px;align-items:start}.cols h2{margin-top:34px}\n/* Both columns share the title and subtitle rows, so the list and the table always start at the same height */\n.cols{grid-template-rows:auto auto auto;row-gap:0}.cols\u003Ediv{display:grid;grid-row:span 3;grid-template-rows:subgrid}.cols\u003Ediv\u003Eh2{align-self:end}.cols\u003Ediv\u003E.sub{align-self:start}\nol.story li{padding:15px 18px 15px 58px}ol.story li:before{left:16px;top:14px}\n.ih{font-size:17.5px}ol.story p{font-size:14px}\n.tbl td i{font-style:normal;color:var(--grey);font-size:12.5px}\n.tbl th:not(:first-child),.tbl td:not(:first-child){width:1%;white-space:nowrap;padding-left:8px;padding-right:16px}.tbl th:not(:first-child){white-space:normal;line-height:1.3}\n.next{grid-template-columns:repeat(4,1fr);gap:12px}.next div{padding:16px 18px}.next b{font-size:17px}.next span{font-size:13.5px}\n.try{margin-top:22px;display:grid;grid-template-columns:22px minmax(0,1fr);gap:4px 10px;align-items:start;background:#fff;padding:14px 16px}\n.try svg{width:18px;height:18px;fill:none;stroke:var(--gold);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;margin-top:2px}\n.try .nl{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--grey)}\n.try .np{grid-column:2;display:flex;gap:10px;align-items:center;flex-wrap:wrap}\n.try q{quotes:none;font-size:13.5px;background:var(--paper);padding:8px 12px;flex:1 1 240px;min-width:0}\n.try button,.sched .sx{font:600 12.5px Inter;color:var(--slate);background:#fff;border:1px solid var(--sand);border-radius:999px;padding:6px 12px;cursor:pointer}\n.sched{margin-top:12px;display:grid;grid-template-columns:20px minmax(0,1fr) 24px;gap:10px;align-items:start;padding:12px 14px;background:#e3ece8;font-size:13px;line-height:1.5;color:var(--slate)}\n.sched svg{width:20px;height:20px;fill:none;stroke:var(--navy);stroke-width:2;stroke-linecap:round;margin-top:1px}.sched b{color:var(--navy)}.sched a{color:var(--navy);font-weight:600}\n.sched .sx{border:0;background:none;font-size:18px;line-height:1;padding:0}\n.aibox{margin:22px 0 0;display:grid;grid-template-columns:20px minmax(0,1fr);gap:10px;align-items:start;padding:12px 14px;border:1px solid var(--sand);background:#fff;font-size:13px;line-height:1.5;color:var(--slate)}\n.aibox svg{width:20px;height:20px;fill:none;stroke:var(--slate);stroke-width:2;stroke-linejoin:round;stroke-linecap:round;margin-top:1px}.aibox b{color:var(--navy);font-weight:600}.aibox a{color:var(--navy)}\nfooter{margin-top:18px}\n@media(max-width:860px){.cols{grid-template-columns:1fr}.next{grid-template-columns:1fr 1fr}}\n@media(max-width:560px){.next{grid-template-columns:1fr}.tbl td,.tbl th{padding:9px 6px!important;font-size:13px}.tbl th{font-size:10px!important}}\n/* One page, letter or A4 */\n@page{size:auto;margin:10mm 11mm}\n@media print{\n *{-webkit-print-color-adjust:exact;print-color-adjust:exact}\n html{font-size:12px}body{background:#fff;font-size:11px;line-height:1.42}\n .wrap{max-width:none;padding:0 0 0}header .wrap{padding:10px 14px}\n .pbtn,.try,.sched{display:none!important}\n .cols{grid-template-columns:1fr 1.05fr!important}.next{grid-template-columns:repeat(4,1fr)!important}.kpis{grid-template-columns:repeat(4,1fr)!important}header .meta{display:block!important}h1{font-size:27px!important}\n .tbl td,.tbl th{padding:5px 8px!important}.tbl th{font-size:8.5px!important}.tbl td{font-size:10.5px!important}.tbl td span{font-size:9.5px!important}\n .hero{padding:12px 0 2px}.kick{font-size:9px}h1{font-size:27px;margin:4px 0 6px}.lede{font-size:12px;max-width:none}\n .kpis{gap:8px;margin-top:12px}.k{padding:8px 11px}.k .l{font-size:8.5px}.k .v{font-size:24px;margin-top:2px}.k .d{font-size:10px;margin-top:1px}.k .v.up:after,.k .v.dn:after{font-size:15px}\n h2{font-size:17px;margin:14px 0 2px!important}.sub{font-size:10px;margin-bottom:7px}\n .cols{gap:12px}ol.story li{padding:8px 11px 8px 40px;margin-bottom:6px;break-inside:avoid}ol.story li:before{left:11px;top:8px;width:20px;height:20px;font-size:10px;line-height:20px}\n .ih{font-size:12.5px}ol.story p{font-size:10.5px;margin-top:2px}\n .tbl{padding:2px 0 8px}.tbl table{font-size:10.5px}.tbl th{font-size:8.5px;padding:6px 10px}.tbl td{padding:6px 10px}.tbl td span{font-size:9.5px}.tbl .note,.note{font-size:9.5px;margin-top:5px}\n .next{gap:8px}.next div{padding:9px 11px;break-inside:avoid}.next b{font-size:12.5px;margin-bottom:3px}.next span{font-size:10px}\n .aibox{margin-top:10px;padding:7px 10px;font-size:9.5px;grid-template-columns:14px 1fr}.aibox svg{width:14px;height:14px}\n footer{margin-top:8px;padding-top:6px;font-size:9.5px}\n}\n/* bb-footer css */.bbcopy{margin:16px 0 4px;text-align:center;font-size:12px;line-height:1.4;color:var(--faint,var(--grey,#8b94a1))}.sched.infoot{margin:28px 0 0}.bbfoot{margin-top:18px;padding-top:14px;border-top:1px solid var(--line,var(--sand,#e4e7eb));display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;font-size:12.5px;color:var(--faint,var(--grey,#8b94a1))}@media print{.bbcopy{margin:3px 0 0;font-size:8.5px;line-height:1.2}footer{margin-top:5px!important;padding-top:4px!important}}\n\u003C/style\u003E\u003C/head\u003E\u003Cbody\u003E\n\u003Cheader\u003E\u003Cdiv class=\u0022wrap\u0022\u003E\u003Cimg style=\u0022height:34px;width:auto;display:block\u0022 src=\u0022data:image/svg\u002Bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTYzLjI4MSIgaGVpZ2h0PSI1MiIgdmlld0JveD0iMCAwIDE2My4yODEgNTIiPgogIDxkZWZzPgogICAgPGxpbmVhckdyYWRpZW50IGlkPSJsaW5lYXItZ3JhZGllbnQiIHgxPSIwLjUiIHgyPSIwLjUiIHkyPSIxIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCI\u002BCiAgICAgIDxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZGUwMCIvPgogICAgICA8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZjliMDAiLz4KICAgIDwvbGluZWFyR3JhZGllbnQ\u002BCiAgPC9kZWZzPgogIDxnIGlkPSJHcm91cF8yOTgyIiBkYXRhLW5hbWU9Ikdyb3VwIDI5ODIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTE4MC44MjUpIj4KICAgIDxnIGlkPSJHcm91cF8yOTc1IiBkYXRhLW5hbWU9Ikdyb3VwIDI5NzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDU0LjYwNSAxODUuMTM4KSI\u002BCiAgICAgIDxwYXRoIGlkPSJQYXRoXzI1NjgiIGRhdGEtbmFtZT0iUGF0aCAyNTY4IiBkPSJNMTE1LjA1OSwyMDkuODE1YTUuOCw1LjgsMCwwLDAsMS40NDYtMi4xMjV2My45MzJoNi4xNDh2LThsLS4wNDQtMS41MTFxLjE2Mi40NzQuMjc0LjgxNXQuMTU2LjU0OGwuNzA4LDEuODkxYTkuNjE3LDkuNjE3LDAsMCwwLDguMjI2LDYuMnYuMDYxaDE2Ljc1NGwuNS0yLjloNC4xNjNsLjQ1OSwyLjlIMTY1LjIycTQuNzg1LDAsNy4yLTIuNjM3LDIuODMtMy4xLDIuODMtOC43ODUsMC01Ljc3OC0zLjM0OC04Ljk5MmE5LjgzOCw5LjgzOCwwLDAsMC03LjEyNi0yLjQ1OWgtNS4zMzN2MTkuMTNsLTQuMDUyLTE5LjEzaC03LjU1NUwxNDMuNDUyLDIwN3YtLjg2OWgtNS4zdi0zLjVIMTQyLjl2LTUuMTdoLTQuNzU1di0zLjMzM2g1LjNWMTg4Ljc1SDEzMS45NzF2MjEuMjE4bC0zLjc5My03Ljg1NWE1Ljc1MSw1Ljc1MSwwLDAsMCwzLjU0LTUuNzMzLDcuMjEzLDcuMjEzLDAsMCwwLTIuNjM3LTUuOTg1cS0yLjA3NC0xLjY0NC02LjI1MS0xLjY0NEgxMTYuNXY2LjA4OGE2LjA0OSw2LjA0OSwwLDAsMC0xLjkzNS00LjMxMXEtMS45NDEtMS43NzctNS45Ny0xLjc3OGgtNy4xODV2MjIuODczaDguNjUyQTYuOTM0LDYuOTM0LDAsMCwwLDExNS4wNTksMjA5LjgxNVptNTAuNTYyLTE1LjM2MmguMTkzYTIuNTQ4LDIuNTQ4LDAsMCwxLDIuMjgyLDEuNiw5LjI3MSw5LjI3MSwwLDAsMSwuODQ0LDQuMzI1cTAsNS41NTYtMy4zMTgsNS43MTlabS0xNC45NCw1Ljc3Ny40MjktMi43N2MuMDEtLjA0OS4wMjktLjE5My4wNTktLjQyOXMuMDc5LS42NjIuMTQ4LTEuMjc0cS4wNi0uNDU5LjExMS0uODQ0dC4wODItLjdsLjE5MywyLjE2M3EuMDc0LjY2Ni4xMTksMS4xdC4wNzQuNjg5cS4yODEsMi4yNTIuMzExLDIuNTc4YTIuNjMzLDIuNjMzLDAsMCwwLC4wNTkuNGwuNCwyLjY2NmgtMi42MDdabS0yOC02LjM0aC4yMjJxMi42ODEsMCwyLjY4MSwyLjU2M2EzLjAzOSwzLjAzOSwwLDAsMS0uNzExLDIuMDc0LDIuMjYyLDIuMjYyLDAsMCwxLTEuNzc4LjgxNWgtLjQxNVptLTYuMTc3LDEuNnY3LjE5YTMuOTk0LDMuOTk0LDAsMCwwLS42NjgtMS4xOTMsNS43OTIsNS43OTIsMCwwLDAtMy41NjMtMS42QzExNS4wMjMsMTk5LjY2MSwxMTYuNDEyLDE5OC4xNzYsMTE2LjUsMTk1LjQ5M1ptLTguOTEyLTEuNzgxcS4yMjMtLjAxNS4zNzgtLjAyMmMuMSwwLC4xOS0uMDA3LjI2LS4wMDdxMi4xNzcsMCwyLjE3OCwxLjk4NWExLjc1OSwxLjc1OSwwLDAsMS0uNjQ0LDEuNDUyLDIuNzI0LDIuNzI0LDAsMCwxLTEuNzU2LjUxOWgtLjQxNVptLjUzMywxMi45NzdjLS4wNTksMC0uMTMzLDAtLjIyMi0uMDA3cy0uMTkzLS4wMTMtLjMxMS0uMDIydi00LjM4NWguNDg5YTIuODQ4LDIuODQ4LDAsMCwxLDEuODg5LjU3OCwxLjk3NCwxLjk3NCwwLDAsMSwuNjg4LDEuNiwyLjA2MiwyLjA2MiwwLDAsMS0uNjg4LDEuNjNBMi42ODgsMi42ODgsMCwwLDEsMTA4LjEyNiwyMDYuNjlaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTAwLjgyMyAtMTg4Ljc1KSIvPgogICAgICA8cGF0aCBpZD0iUGF0aF8yNTY5IiBkYXRhLW5hbWU9IlBhdGggMjU2OSIgZD0iTTE4NC43MDUsMjQ5Ljc0YTMuNDQsMy40NCwwLDAsMC0zLjQzNywzLjQzNywzLjQzNCwzLjQzNCwwLDAsMCwuMDkuNDcybC0zLjIyNi02LjY4MWE1Ljc1LDUuNzUsMCwwLDAsMy41NC01LjczMyw3LjIxMiw3LjIxMiwwLDAsMC0yLjYzNy01Ljk4NXEtMi4wNzQtMS42NDUtNi4yNTEtMS42NDVoLTYuMzI2djE3LjM3N2gtNi4yNDJ2LTMuNWg0Ljc1NXYtNS4xN2gtNC43NTV2LTMuMzM0aDUuM3YtNS4zNzdIMTI1LjA1M3YxNC43N2E0Ljc3LDQuNzcsMCwwLDEtLjM0MSwyLjE0OCwxLjU1MywxLjU1MywwLDAsMS0yLjQ1Mi0uMDQ0LDQuNDg1LDQuNDg1LDAsMCwxLS4zNjMtMi4xMTlWMjMzLjYwNkgxMTUuNzJ2MTUuMTQ2YTQuNTg3LDQuNTg3LDAsMCwwLS45NzItMi40MDYsNS43OTQsNS43OTQsMCwwLDAtMy41NjMtMS42cTQuMjY3LS4zNTUsNC4yNjctNC42NTFhNi4xMjUsNi4xMjUsMCwwLDAtMS45Ny00LjcxMXEtMS45NDEtMS43NzctNS45Ny0xLjc3OGgtNy4xODV2MjIuODczaDguNjUyYTYuOTM1LDYuOTM1LDAsMCwwLDQuOTkyLTEuODA4LDYuMDc3LDYuMDc3LDAsMCwwLDEuODcyLTQuMjg1LDYuODEzLDYuODEzLDAsMCwwLDIuNiw0LjkyMiw4Ljc3LDguNzcsMCwwLDAsNS4zMTgsMS41Nyw3Ljg2NSw3Ljg2NSwwLDAsMCw0Ljc1NS0xLjQyMiw2LjQsNi40LDAsMCwwLDIuMDc0LTIuMzg1LDcuMzA2LDcuMzA2LDAsMCwwLC42MzctMy4yODl2LTEwLjdoMi43djE3LjM5MkgxNDAuMVYyMzkuMDg3aDQuNjI4djE3LjM5Mmg2LjE3OFYyMzkuMDg3aDMuMTMxdjE3LjM5MmgxOC41Njd2LThsLS4wNDUtMS41MTFxLjE2Mi40NzQuMjc0LjgxNXQuMTU2LjU0OGwuNzA4LDEuODkxYTkuNjM3LDkuNjM3LDAsMCwwLDkuMDI1LDYuMjU3bC0uMzg0LS44YTMuNDU0LDMuNDU0LDAsMCwwLDIuNDI0Ljk3NCwzLjMsMy4zLDAsMCwwLDIuNDI5LS45OTMsMy4yMDYsMy4yMDYsMCwwLDAsMS4wMjItMi4zODUsMy40MDUsMy40MDUsMCwwLDAtMS4wMjItMi41QTMuMzYyLDMuMzYyLDAsMCwwLDE4NC43MDUsMjQ5Ljc0Wm0tNzguMi0xMS4xNzFjLjE0OS0uMDEuMjc0LS4wMTcuMzc4LS4wMjJzLjE5LS4wMDcuMjU5LS4wMDdxMi4xNzcsMCwyLjE3OCwxLjk4NWExLjc1OSwxLjc1OSwwLDAsMS0uNjQ0LDEuNDUyLDIuNzIyLDIuNzIyLDAsMCwxLTEuNzU1LjUxOUgxMDYuNVptMi4zNzgsMTIuMzdhMi42ODUsMi42ODUsMCwwLDEtMS44NDUuNjA3Yy0uMDU5LDAtLjEzMywwLS4yMjItLjAwN3MtLjE5My0uMDEyLS4zMTEtLjAyMnYtNC4zODVoLjQ4OWEyLjg0OSwyLjg0OSwwLDAsMSwxLjg4OS41NzgsMS45NzUsMS45NzUsMCwwLDEsLjY4OSwxLjZBMi4wNjMsMi4wNjMsMCwwLDEsMTA4Ljg4MiwyNTAuOTM4Wm02NS45NDYtNy41NTVhMi4yNjIsMi4yNjIsMCwwLDEtMS43NzguODE1aC0uNDE1di01LjQ1MWguMjIycTIuNjgyLDAsMi42ODIsMi41NjNBMy4wMzksMy4wMzksMCwwLDEsMTc0LjgyOCwyNDMuMzgzWiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwMC4zMjcgLTIwOS4xOTIpIi8\u002BCiAgICAgIDxwYXRoIGlkPSJQYXRoXzI1NzAiIGRhdGEtbmFtZT0iUGF0aCAyNTcwIiBkPSJNMjY0LjUsMjM3LjMzYTMuNDI0LDMuNDI0LDAsMCwwLDIuNDQ0LTEuMDA3LDMuMzE3LDMuMzE3LDAsMCwwLDEuMDIzLTIuNDMsMy40NjUsMy40NjUsMCwwLDAtMy40ODItMy41LDMuNDI2LDMuNDI2LDAsMCwwLTIuNDQ0LDEuMDA3LDMuMzI5LDMuMzI5LDAsMCwwLTEuMDA3LDIuNDQ1LDMuNDQ0LDMuNDQ0LDAsMCwwLDEuMDA3LDIuNDU5QTMuMzUyLDMuMzUyLDAsMCwwLDI2NC41LDIzNy4zM1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNzMuNTY2IC0yMDcuNzMpIi8\u002BCiAgICAgIDxwYXRoIGlkPSJQYXRoXzI1NzEiIGRhdGEtbmFtZT0iUGF0aCAyNTcxIiBkPSJNMjgwLjYzOSwyNDcuNjA4YTYuOTI1LDYuOTI1LDAsMCwwLTUuNTExLTIuMyw2Ljc0NSw2Ljc0NSwwLDAsMC01LjM0OCwyLjMxMSw4LjIxMiw4LjIxMiwwLDAsMC0xLjkyLDQuNTMxdi02LjVIMjYxLjl2MTYuMDE0aDUuOTU1VjI1NS4zYTguMSw4LjEsMCwwLDAsMS44NzYsNC40NTMsNi44NTQsNi44NTQsMCwwLDAsNS4zNzcsMi4yMzcsNy4xMzYsNy4xMzYsMCwwLDAsNS40ODEtMi4xOTIsOC4zLDguMywwLDAsMCwyLjA0NC01LjlBOS4yNjQsOS4yNjQsMCwwLDAsMjgwLjYzOSwyNDcuNjA4Wm0tNC4yMzcsOC44NzRxLS40NzQsMS4wNTItMS4yLDEuMDUyLS43NzEsMC0xLjIzLTEuMDY2YTYuNzI0LDYuNzI0LDAsMCwxLS40NTktMi44LDYuNiw2LjYsMCwwLDEsLjQ1OS0yLjhxLjQ2LTEuMDY2LDEuMjE1LTEuMDY3YTEuMDE1LDEuMDE1LDAsMCwxLC43LjI4MSwyLjI3NCwyLjI3NCwwLDAsMSwuNTMzLjc5Myw1LjE5NCw1LjE5NCwwLDAsMSwuMzQxLDEuMjI5LDkuOTM0LDkuOTM0LDAsMCwxLC4xMTksMS42MDdBNy4zNTUsNy4zNTUsMCwwLDEsMjc2LjQsMjU2LjQ4MloiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNzMuOTYzIC0yMTQuNTI3KSIvPgogICAgPC9nPgogICAgPHBhdGggaWQ9IlBhdGhfMjU3MiIgZGF0YS1uYW1lPSJQYXRoIDI1NzIiIGQ9Ik00OS4wNjcsMTk0LjYyMWMwLTguNzA5LTguNzMxLTEzLjYwOS0yNC42LTEzLjhDOC42OTEsMTgxLjAxMywwLDE4NS45MTMsMCwxOTQuNjIxYzAsMy41NC45LDYuMjM3LDIuNjg3LDguMDE0YTcuMTU1LDcuMTU1LDAsMCwwLC42MTMuNTQ1Qy4xNTksMjA5LjU2MiwwLDIyMy40NjQsMCwyMjYuMjQzYTYuMjU1LDYuMjU1LDAsMCwwLDYuMjM4LDYuMTg1aDM2LjU5YTYuMjY4LDYuMjY4LDAsMCwwLDYuMjM4LTYuMjA2YzAtMi43NzItLjE2Mi0xNi42NjYtMy4zLTIzLjA0MmE3LjIzOCw3LjIzOCwwLDAsMCwuNjEzLS41NDVDNDguMTYyLDIwMC44NTcsNDkuMDY3LDE5OC4xNjEsNDkuMDY3LDE5NC42MjFaIiBmaWxsPSIjZmZmIi8\u002BCiAgICA8cGF0aCBpZD0iUGF0aF8yNTczIiBkYXRhLW5hbWU9IlBhdGggMjU3MyIgZD0iTTQ2LjQ1MSwyMTYuNDU3bC0yLjgzNCwxMS4yOTVhMS44ODksMS44ODksMCwwLDEtMi40MzUsMS4xbC0xMS44LTQuMDkyYTEuODg5LDEuODg5LDAsMCwxLTEuMS0yLjQzNUwzMi40MzksMjEwLjZhMS44ODksMS44ODksMCwwLDEsMi40MzUtMS4xbDEwLjQ3OCw0LjUxOEExLjg4OSwxLjg4OSwwLDAsMSw0Ni40NTEsMjE2LjQ1N1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMi44MzQgLTEzLjAxNCkiIGZpbGw9InVybCgjbGluZWFyLWdyYWRpZW50KSIvPgogICAgPHBhdGggaWQ9IlBhdGhfMjE1Ni0yIiBkYXRhLW5hbWU9IlBhdGggMjE1Ni0yIiBkPSJNMjQuNDcyLDE4My43NmM4LjEwNi4xLDIxLjY2MSwxLjY0NiwyMS42NjEsMTAuODU3LDAsMi43MzEtLjYxMyw0LjcyOC0xLjgyNCw1LjkzNmEzLjk4OSwzLjk4OSwwLDAsMS0uMzYuMzE4LDIuOTM3LDIuOTM3LDAsMCwwLS44MTUsMy42YzIuMjE0LDQuNSwzLDE0LjUyNSwzLDIxLjcyYTMuMzI2LDMuMzI2LDAsMCwxLTMuMywzLjNINi4yNGEzLjMwNywzLjMwNywwLDAsMS0zLjMtMy4yNTJjMC03LjIzLjc4My0xNy4yNjcsMy0yMS43NjVhMi45MzYsMi45MzYsMCwwLDAtLjgxNy0zLjYsMy45LDMuOSwwLDAsMS0uMzU4LS4zMThjLTEuMjExLTEuMjA3LTEuODI1LTMuMi0xLjgyNS01LjkzNiwwLTkuMjEzLDEzLjQ3Ni0xMC43NjEsMjEuNTM3LTEwLjg1N20wLTIuOTM1QzguNjkzLDE4MS4wMTQsMCwxODUuOTEzLDAsMTk0LjYyMWMwLDMuNTQuOSw2LjIzNywyLjY4OCw4LjAxM2E2LjkyNyw2LjkyNywwLDAsMCwuNjEzLjU0NEMuMTYxLDIwOS41NiwwLDIyMy40NjksMCwyMjYuMjQxYTYuMjU1LDYuMjU1LDAsMCwwLDYuMjM3LDYuMTg0aDM2LjU5YTYuMjY4LDYuMjY4LDAsMCwwLDYuMjM4LTYuMmMwLTIuNzcyLS4xNjMtMTYuNjcyLTMuMy0yMy4wNDJhNy4xNzIsNy4xNzIsMCwwLDAsLjYxMy0uNTQ0YzEuNzgyLTEuNzgsMi42ODgtNC40NzQsMi42ODgtOC4wMTMsMC04LjcwOS04LjczMS0xMy42MDktMjQuNi0xMy44WiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuMDAxKSIvPgogIDwvZz4KPC9zdmc\u002BCg==\u0022 alt=\u0022Bread \u0026amp; Butter\u0022\u003E\u003Cdiv class=\u0022right\u0022\u003E\u003Cdiv class=\u0022meta\u0022\u003E{{account_name}}\u003Cbr\u003EExecutive report \u00B7 {{period}}\u003C/div\u003E\u003Cbutton class=\u0022pbtn\u0022 type=\u0022button\u0022 onclick=\u0022window.print()\u0022 aria-label=\u0022Print this report\u0022 title=\u0022Print this report\u0022\u003E\u003Csvg viewBox=\u00220 0 24 24\u0022\u003E\u003Cpath d=\u0022M6 9V3h12v6M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2M6 14h12v7H6z\u0022/\u003E\u003C/svg\u003E\u003C/button\u003E\u003C/div\u003E\u003C/div\u003E\u003C/header\u003E\n\u003Cdiv class=\u0022wrap\u0022\u003E\n\u003Csection class=\u0022hero\u0022\u003E\u003Cdiv class=\u0022kick\u0022\u003E{{domain}} \u00B7 {{period_dates}}\u003C/div\u003E\n\u003Ch1\u003E{{headline}}\u003C/h1\u003E\n\u003Cdiv class=\u0022lede\u0022\u003E{{lede}}\u003C/div\u003E\n\u003Cdiv class=\u0022kpis\u0022\u003E\n\u003Cdiv class=\u0022k\u0022\u003E\u003Cdiv class=\u0022l\u0022\u003EVisitors\u003C/div\u003E\u003Cdiv class=\u0022v {{visitors_trend_class}}\u0022\u003E{{visitors_change}}\u003C/div\u003E\u003Cdiv class=\u0022d\u0022\u003E{{visitors_note}}\u003C/div\u003E\u003C/div\u003E\n\u003Cdiv class=\u0022k\u0022\u003E\u003Cdiv class=\u0022l\u0022\u003EReading closely\u003C/div\u003E\u003Cdiv class=\u0022v {{focused_rate_trend_class}}\u0022\u003E{{focused_rate}}\u003C/div\u003E\u003Cdiv class=\u0022d\u0022\u003E{{focused_rate_note}}\u003C/div\u003E\u003C/div\u003E\n\u003Cdiv class=\u0022k\u0022\u003E\u003Cdiv class=\u0022l\u0022\u003ERegistration rate\u003C/div\u003E\u003Cdiv class=\u0022v {{registration_rate_trend_class}}\u0022\u003E{{registration_rate}}\u003C/div\u003E\u003Cdiv class=\u0022d\u0022\u003E{{registration_rate_note}}\u003C/div\u003E\u003C/div\u003E\n\u003Cdiv class=\u0022k {{money_tile_alert_class}}\u0022\u003E\u003Cdiv class=\u0022l\u0022\u003E{{money_tile_label}}\u003C/div\u003E\u003Cdiv class=\u0022v {{money_tile_trend_class}}\u0022\u003E{{money_tile_value}}\u003C/div\u003E\u003Cdiv class=\u0022d\u0022\u003E{{money_tile_note}}\u003C/div\u003E\u003C/div\u003E\n\u003C/div\u003E\u003C/section\u003E\n\n\u003Cdiv class=\u0022cols\u0022\u003E\n\u003Cdiv\u003E\u003Ch2\u003EThree things to know\u003C/h2\u003E\u003Cdiv class=\u0022sub\u0022\u003EWhat {{period}} says about the business.\u003C/div\u003E\u003Col class=\u0022story\u0022\u003E\u003Cli data-bb-row\u003E\u003Cdiv class=\u0022ih\u0022\u003E{{finding_headline}}\u003C/div\u003E\u003Cp\u003E{{finding_text}}\u003C/p\u003E\u003C/li\u003E\u003C/ol\u003E\u003C/div\u003E\n\u003Cdiv\u003E\u003Ch2\u003EHow the campaigns are performing\u003C/h2\u003E\u003Cdiv class=\u0022sub\u0022\u003EHow the Google Ads budget is split, and what each campaign\u2019s visitors did.\u003C/div\u003E\n\u003Cdiv class=\u0022card tbl\u0022\u003E\u003Ctable\u003E\u003Cthead\u003E\u003Ctr\u003E\u003Cth\u003ECampaign\u003C/th\u003E\u003Cth\u003EShare of\u003Cbr\u003Espend\u003C/th\u003E\u003Cth\u003ERead\u003Cbr\u003Eclosely\u003C/th\u003E\u003Cth\u003ERegistration\u003Cbr\u003Erate\u003C/th\u003E\u003C/tr\u003E\u003C/thead\u003E\u003Ctbody\u003E\u003Ctr data-bb-row class=\u0022{{campaign_row_class}}\u0022\u003E\u003Ctd\u003E\u003Cb\u003E{{campaign_name}}\u003C/b\u003E\u003Cspan\u003E{{campaign_description}}\u003C/span\u003E\u003C/td\u003E\u003Ctd\u003E{{campaign_share_of_spend}}\u003C/td\u003E\u003Ctd\u003E{{campaign_read_closely}}\u003C/td\u003E\u003Ctd\u003E\u003Cem\u003E{{campaign_registration_rate}}\u003C/em\u003E\u003C/td\u003E\u003C/tr\u003E\u003C/tbody\u003E\u003C/table\u003E\n\u003Cdiv class=\u0022note\u0022\u003E{{table_note}}\u003C/div\u003E\u003C/div\u003E\u003C/div\u003E\n\u003C/div\u003E\n\n\u003Ch2\u003EWhere to put more money\u003C/h2\u003E\u003Cdiv class=\u0022sub\u0022\u003EWhat the {{period}} results point to for {{next_period}}.\u003C/div\u003E\n\u003Cdiv class=\u0022next\u0022\u003E\n\u003Cdiv data-bb-row class=\u0022{{money_move_class}}\u0022\u003E\u003Cb\u003E{{money_move_headline}}\u003C/b\u003E\u003Cspan\u003E{{money_move_text}}\u003C/span\u003E\u003C/div\u003E\n\u003C/div\u003E\n\n\u003Cdiv class=\u0022try\u0022\u003E\u003Csvg viewBox=\u00220 0 24 24\u0022 aria-hidden=\u0022true\u0022\u003E\u003Cpath d=\u0022M9 18h6M10 21h4M12 3a6 6 0 0 0-3.5 10.9c.6.5.9 1.1.9 1.8V16h5.2v-.3c0-.7.3-1.3.9-1.8A6 6 0 0 0 12 3z\u0022/\u003E\u003C/svg\u003E\u003Cdiv class=\u0022nl\u0022\u003ETry this next in your AI assistant\u003C/div\u003E\u003Cdiv class=\u0022np\u0022\u003E\u003Cq id=\u0022tryq\u0022\u003E{{try_prompt}}\u003C/q\u003E\u003Cbutton type=\u0022button\u0022 id=\u0022trybtn\u0022 title=\u0022Copies the full prompt, with the report and account named\u0022\u003ECopy prompt\u003C/button\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cdiv class=\u0022sched\u0022 id=\u0022sched\u0022\u003E\u003Csvg viewBox=\u00220 0 24 24\u0022 aria-hidden=\u0022true\u0022\u003E\u003Ccircle cx=\u002212\u0022 cy=\u002212\u0022 r=\u00229\u0022/\u003E\u003Cpath d=\u0022M12 7v5l3 2\u0022/\u003E\u003C/svg\u003E\u003Cdiv\u003E\u003Cb\u003EGet this report whenever you need it.\u003C/b\u003E It was built by your AI assistant from Bread \u0026amp; Butter data, through the Bread \u0026amp; Butter MCP server. Ask for it any time: \u003Cq\u003ERun my Bread \u0026amp; Butter Executive report for last month\u003C/q\u003E, or ask your assistant to run it on the 1st of every month. Was this forwarded to you? Connect your own assistant to Bread \u0026amp; Butter and run it yourself: \u003Ca href=\u0022https://support.breadbutter.io/article/249-bread-butter-mcp-server\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003EBread \u0026amp; Butter MCP server connections\u003C/a\u003E. This report is also kept in your account: \u003Ca href=\u0022https://app.breadbutter.io/\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003EView in Bread \u0026amp; Butter\u003C/a\u003E.\u003C/div\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022sx\u0022 title=\u0022Hide this box. To leave it out of future reports, tell your AI assistant.\u0022 aria-label=\u0022Hide\u0022\u003E\u00D7\u003C/button\u003E\u003C/div\u003E\n\n\u003Cdiv class=\u0022aibox\u0022 role=\u0022note\u0022\u003E\u003Csvg viewBox=\u00220 0 24 24\u0022 aria-hidden=\u0022true\u0022\u003E\u003Ccircle cx=\u002212\u0022 cy=\u002212\u0022 r=\u00229\u0022/\u003E\u003Cpath d=\u0022M12 11v5M12 8h.01\u0022/\u003E\u003C/svg\u003E\u003Cp style=\u0022margin:0\u0022\u003E\u003Cb\u003EThis report was built with AI.\u003C/b\u003E Your AI assistant put it together from Bread \u0026amp; Butter data, and AI can make mistakes. Before you make a decision based on a number here, check it in Bread \u0026amp; Butter. If something seems out of place, raise your hand and we\u0027ll look into it: \u003Ca href=\u0022https://breadbutter.io/contact/\u0022 target=\u0022_blank\u0022 rel=\u0022noopener\u0022\u003EContact us\u003C/a\u003E.\u003C/p\u003E\u003C/div\u003E\n\u003Cfooter\u003E\u003Cspan\u003EPrepared for {{account_name}} \u00B7 {{domain}} \u00B7 {{period_dates}}\u003C/span\u003E\u003Cspan\u003EPowered by Bread \u0026amp; Butter\u003C/span\u003E\u003C/footer\u003E\n\u003Cp class=\u0022bbcopy\u0022\u003E\u0026copy; 2026 Bread \u0026amp; Butter IO Inc.\u003C/p\u003E\n\u003C/div\u003E\n\u003Cscript\u003E(function(){\nconst s=document.getElementById(\u0027sched\u0027);try{if(localStorage.getItem(\u0027bb-sched-hidden\u0027))s.remove();}catch(e){}\nconst x=s\u0026\u0026s.querySelector(\u0027.sx\u0027);if(x)x.addEventListener(\u0027click\u0027,()=\u003E{s.remove();try{localStorage.setItem(\u0027bb-sched-hidden\u0027,\u00271\u0027);}catch(e){}});\nconst b=document.getElementById(\u0027trybtn\u0027),q=document.getElementById(\u0027tryq\u0027);\nconst full=\u0027Using the Bread \u0026 Butter MCP server for {{account_name}} ({{domain}}): in the Bread \u0026 Butter Executive report for {{period}}, the campaign table shows this. \u0027\u002Bq.textContent\u002B\u0027 Keep the same layout and colours as that report, and render the result as a page.\u0027;\nb.addEventListener(\u0027click\u0027,()=\u003E{const done=()=\u003E{b.textContent=\u0027Copied\u0027;setTimeout(()=\u003Eb.textContent=\u0027Copy prompt\u0027,1600);};\n const fb=()=\u003E{const r=document.createRange();r.selectNodeContents(q);const g=getSelection();g.removeAllRanges();g.addRange(r);b.textContent=\u0027Selected, press copy\u0027;setTimeout(()=\u003Eb.textContent=\u0027Copy prompt\u0027,2000);};\n if(navigator.clipboard\u0026\u0026navigator.clipboard.writeText)navigator.clipboard.writeText(full).then(done,fb);else fb();});\n})();\u003C/script\u003E\n\u003C!-- bb-utm --\u003E\u003Cscript\u003E(function(){const tag=a=\u003E{try{const u=new URL(a.getAttribute(\u0027href\u0027),location.href);if(u.hostname!==\u0027app.breadbutter.io\u0027||u.searchParams.has(\u0027utm_source\u0027))return;u.searchParams.set(\u0027utm_source\u0027,\u0027bb-report\u0027);u.searchParams.set(\u0027utm_medium\u0027,\u0027report\u0027);u.searchParams.set(\u0027utm_campaign\u0027,\u0027executive-report\u0027);u.searchParams.set(\u0027utm_content\u0027,a.closest(\u0027.sched\u0027)?\u0027schedule\u0027:\u0027page\u0027);a.setAttribute(\u0027href\u0027,u.toString());}catch(e){}};document.querySelectorAll(\u0027a[href*=\u0022app.breadbutter.io\u0022]\u0027).forEach(tag);})();\u003C/script\u003E\n\u003Cscript\u003E/* bb-footer: schedule box above the AI box, copyright last */(function(){const go=()=\u003E{const s=document.querySelector(\u0022.sched\u0022),a=document.querySelector(\u0022.aibox\u0022),c=document.querySelector(\u0022.bbcopy\u0022);if(s\u0026\u0026a\u0026\u0026s.nextElementSibling!==a){s.classList.add(\u0022infoot\u0022);a.parentNode.insertBefore(s,a);}if(c\u0026\u0026c.parentNode.lastElementChild!==c)c.parentNode.appendChild(c);};go();setTimeout(go,0);})();\u003C/script\u003E\n\u003C/body\u003E\u003C/html\u003E";
|
|
2
|
+
/* API-2871: draws a Bread & Butter report from its hosted template (T) and the values the assistant wrote in window.BB_REPORT. */
|
|
3
|
+
var R = window.BB_REPORT || {}, V = R.values || {}, ROWS = R.rows || {};
|
|
4
|
+
var PH = /\{\{(\w+)\}\}/g;
|
|
5
|
+
/* The account's brand kit comes with the page, so one published script serves every account: placed as McpReportBranding.Apply places it. */
|
|
6
|
+
var B = R.brand;
|
|
7
|
+
if (B && B.css) {
|
|
8
|
+
var st = T.indexOf('</style>');
|
|
9
|
+
if (st >= 0) T = T.slice(0, st) + B.css + T.slice(st);
|
|
10
|
+
if (B.logo) T = T.replace(/(<header(?: class="head")?>\s*<div class="(?:top|wrap)">\s*)<img(?:\s+style="[^"]*")?\s+src="data:[^"]*"[^>]*>/, function (m, p) { return p + B.logo; });
|
|
11
|
+
var hd = T.indexOf('</header>');
|
|
12
|
+
if (hd >= 0 && B.footer) {
|
|
13
|
+
var sc = T.indexOf('<script', hd), end = sc < 0 ? T.length : sc, cl = T.lastIndexOf('</div>', end - 1), at = cl <= hd ? end : cl;
|
|
14
|
+
T = T.slice(0, at) + B.footer + T.slice(at);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/* API-2872 (Alex): the schedule box says to run the report at the rhythm of the dates asked for, which the server puts in the page. */
|
|
18
|
+
if (typeof R.schedule === 'string' && R.schedule)
|
|
19
|
+
T = T.replace(/const SCHEDULE="[^"]*"/, function () { return 'const SCHEDULE=' + JSON.stringify(R.schedule).replace(/</g, '\\u003c'); });
|
|
20
|
+
var doc = new DOMParser().parseFromString(T, 'text/html');
|
|
21
|
+
|
|
22
|
+
function has(o, k) { return o != null && Object.prototype.hasOwnProperty.call(o, k); }
|
|
23
|
+
function str(v) { return v == null ? '' : typeof v === 'object' ? JSON.stringify(v) : String(v); }
|
|
24
|
+
function code(el) { return el && el.closest && el.closest('script,style'); }
|
|
25
|
+
|
|
26
|
+
function fillText(s, o, rest) {
|
|
27
|
+
return s.replace(PH, function (m, k) { return has(o, k) ? str(o[k]) : rest ? (/_json$/.test(k) ? '[]' : '') : m; });
|
|
28
|
+
}
|
|
29
|
+
function html(s) { return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, '''); }
|
|
30
|
+
function jsText(s) {
|
|
31
|
+
return html(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/'/g, "\\'").replace(/`/g, '\\`')
|
|
32
|
+
.replace(/\$\{/g, '\\${').replace(/\r?\n/g, '\\n').replace(/<\/(script)/gi, '<\\/$1');
|
|
33
|
+
}
|
|
34
|
+
function fillScript(s, o, rest) {
|
|
35
|
+
return s.replace(PH, function (m, k) {
|
|
36
|
+
if (!has(o, k)) return rest ? (/_json$/.test(k) ? '[]' : '') : m;
|
|
37
|
+
var v = o[k];
|
|
38
|
+
if (/_json$/.test(k)) return typeof v === 'string' ? v : JSON.stringify(v);
|
|
39
|
+
return typeof v === 'number' || typeof v === 'boolean' ? String(v) : jsText(str(v));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function fill(root, o, rest) {
|
|
43
|
+
var w = doc.createTreeWalker(root, 1 | 4), n, all = [root];
|
|
44
|
+
while ((n = w.nextNode())) all.push(n);
|
|
45
|
+
all.forEach(function (n) {
|
|
46
|
+
if (n.nodeType === 3) {
|
|
47
|
+
if (n.nodeValue.indexOf('{{') < 0) return;
|
|
48
|
+
n.nodeValue = code(n.parentElement) && n.parentElement.tagName === 'SCRIPT' ? fillScript(n.nodeValue, o, rest) : fillText(n.nodeValue, o, rest);
|
|
49
|
+
} else if (n.attributes) {
|
|
50
|
+
for (var i = 0; i < n.attributes.length; i++) {
|
|
51
|
+
var a = n.attributes[i];
|
|
52
|
+
if (a.value.indexOf('{{') >= 0) a.value = fillText(a.value, o, rest);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function find(k) {
|
|
58
|
+
var needle = '{{' + k + '}}', w = doc.createTreeWalker(doc.documentElement, 1 | 4), n;
|
|
59
|
+
while ((n = w.nextNode())) {
|
|
60
|
+
if (n.nodeType === 3) { if (n.nodeValue.indexOf(needle) >= 0 && !code(n.parentElement)) return n.parentElement; }
|
|
61
|
+
else for (var i = 0; i < n.attributes.length; i++) if (n.attributes[i].value.indexOf(needle) >= 0 && !code(n)) return n;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
/* The row a row template repeats: a data-bb-row element when the template marks one; else, as the field guides say, the
|
|
66
|
+
row inside a container that holds only it; else the nearest list item, table row, article or SVG group. */
|
|
67
|
+
function rowOf(el) {
|
|
68
|
+
var marked = el.closest('[data-bb-row]');
|
|
69
|
+
if (marked) return marked;
|
|
70
|
+
var c = el, best = null;
|
|
71
|
+
while (c.parentElement && c.parentElement !== doc.body) {
|
|
72
|
+
if (c.parentElement.children.length === 1) best = c;
|
|
73
|
+
else if (best) break;
|
|
74
|
+
c = c.parentElement;
|
|
75
|
+
}
|
|
76
|
+
if (best) return best;
|
|
77
|
+
var item = el.closest('li,tr,article,g');
|
|
78
|
+
if (item) return item;
|
|
79
|
+
for (c = el; c.parentElement && c.parentElement !== doc.body; c = c.parentElement)
|
|
80
|
+
if (c.parentElement.id) return c;
|
|
81
|
+
return el;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Object.keys(ROWS).forEach(function (k) {
|
|
85
|
+
var el = find(k);
|
|
86
|
+
if (!el) return;
|
|
87
|
+
var row = rowOf(el), list = ROWS[k] || [];
|
|
88
|
+
list.forEach(function (o) {
|
|
89
|
+
var copy = row.cloneNode(true);
|
|
90
|
+
fill(copy, o, false);
|
|
91
|
+
row.parentNode.insertBefore(copy, row);
|
|
92
|
+
});
|
|
93
|
+
row.parentNode.removeChild(row);
|
|
94
|
+
});
|
|
95
|
+
fill(doc.documentElement, V, true);
|
|
96
|
+
|
|
97
|
+
/* Swap the page in, then run the template's scripts in order (scripts moved between documents don't run by themselves). */
|
|
98
|
+
var root = document.importNode(doc.documentElement, true);
|
|
99
|
+
document.replaceChild(root, document.documentElement);
|
|
100
|
+
Array.prototype.forEach.call(root.querySelectorAll('script'), function (old) {
|
|
101
|
+
var s = document.createElement('script');
|
|
102
|
+
for (var i = 0; i < old.attributes.length; i++) s.setAttribute(old.attributes[i].name, old.attributes[i].value);
|
|
103
|
+
s.text = old.text;
|
|
104
|
+
old.parentNode.replaceChild(s, old);
|
|
105
|
+
});
|
|
106
|
+
})();
|