PageSourceSearch

https://blisstherapy.ai/assets/admin.analytics-DGHftzvF.js

js blisstherapy.ai collected 2026-10-05 11:53:06 UTC 21,826 bytes, 1 lines download raw bytes

1import{k as B,l as q,j as s,r as U,b as _,L as V,b7 as z}from"./index-CwxMVMRT.js";import{R as W}from"./refresh-cw-CTgJAez9.js";const Y=B({method:"POST"}).handler(q("c720654e0816d4f3eb03a8cb7b6bcfbcaaff7ec410c382342536f0ab25cb5040"));function Z(t){const o=t/3,n=Math.pow(10,Math.floor(Math.log10(o||1))),i=o/n;return(i>=5?5:i>=2?2:1)*n}function K({values:t}){const r=t.filter(c=>c!=null);if(r.length<2)return null;const e=Math.min(...r),p=Math.max(...r)-e||1,f=c=>3+c*234/(t.length-1),u=c=>33-(c-e)/p*30;let j="",N=!1,k=0;t.forEach((c,b)=>{c!=null&&(j+=`${N?"L":"M"}${f(b).toFixed(1)} ${u(c).toFixed(1)}`,N=!0,k=b)});const P=t[k];return s.jsxs("svg",{viewBox:"0 0 240 36",preserveAspectRatio:"none",className:"mt-1.5 block h-9 w-full","aria-hidden":"true",children:[s.jsx("path",{d:j,fill:"none",className:"stroke-bliss-primary",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke"}),s.jsx("circle",{cx:f(k).toFixed(1),cy:u(P).toFixed(1),r:2.6,className:"fill-bliss-primary"})]})}function X({labels:t,series:o,format:n}){const e={t:14,r:52,b:24,l:50},d=560-e.l-e.r,p=172-e.t-e.b,f=o.flatMap(l=>l.values).filter(l=>l!=null);if(f.length===0)return s.jsx("div",{className:"flex h-[172px] items-center justify-center text-xs text-bliss-ink-soft",children:"No data in range"});let u=Math.min(...f);const j=Math.max(...f);u>0&&u/j>.35&&(u=0);const N=Z(j-u||1),k=Math.ceil(j/N)*N||1,P=k-u||1,c=l=>e.l+(t.length<=1?d/2:l*d/(t.length-1)),b=l=>e.t+p-(l-u)/P*p,S=[];for(let l=u;l<=k+1e-6;l+=N)S.push(l);const F=Math.max(1,Math.ceil(t.length/8));return s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("svg",{viewBox:"0 0 560 172",preserveAspectRatio:"xMidYMid meet",className:"block h-[172px] w-full min-w-[320px]",role:"img","aria-label":o.map(l=>
1l.name).join(" vs "),children:[S.map(l=>s.jsxs("g",{children:[s.jsx("line",{x1:e.l,x2:560-e.r,y1:b(l).toFixed(1),y2:b(l).toFixed(1),className:"stroke-bliss-stone",strokeWidth:1,opacity:.5}),s.jsx("text",{x:e.l-8,y:(b(l)+3).toFixed(1),textAnchor:"end",className:"fill-bliss-ink-soft text-[10px]",children:n(l)})]},`t${l}`)),o.map((l,h)=>{let g="",O=!1,w=null;if(l.values.forEach((T,E)=>{if(T==null)return;const I=c(E),L=b(T);g+=`${O?" L":"M"}${I.toFixed(1)} ${L.toFixed(1)}`,O=!0,w=E}),w==null)return null;const D=l.values[w],G=o.length===1&&!l.dashed;return s.jsxs("g",{children:[G?s.jsx("path",{d:`${g} L${c(w).toFixed(1)} ${(e.t+p).toFixed(1)} L${c(0).toFixed(1)} ${(e.t+p).toFixed(1)} Z`,className:"fill-bliss-primary",opacity:.08}):null,s.jsx("path",{d:g,fill:"none",className:l.dashed?"stroke-bliss-ink-soft":"stroke-bliss-primary",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",strokeDasharray:l.dashed?"5 3":void 0}),s.jsx("circle",{cx:c(w).toFixed(1),cy:b(D).toFixed(1),r:3.2,className:l.dashed?"fill-bliss-ink-soft":"fill-bliss-primary"}),s.jsx("text",{x:(c(w)+7).toFixed(1),y:(b(D)+3).toFixed(1),className:`${l.dashed?"fill-bliss-ink-soft":"fill-bliss-primary"} text-[10px] font-semibold`,children:n(D)})]},`s${h}`)}),t.map((l,h)=>{const g=h===t.length-1,O=h>t.length-1-Math.ceil(F/2);return g||h%F===0&&!O?s.jsx("text",{x:c(h).toFixed(1),y:165,textAnchor:"middle",className:"fill-bliss-ink-soft text-[10px]",children:l},`x${h}`):null}),t.map((l,h)=>s.jsx("rect",{x:(c(h)-d/t.length/2).toFixed(1),y:e.t,width:(d/t.length).toFixed(1),height:p,fill:"transparent",children:s.jsx("title",{children:`${l}  `+o.map(g=>`${g.name}: ${g.values[h]==null?"—":n(g.values[h])}`).join("   ")})},`h${h}`))]})})}const J=[{label:"Last 6 months",months:6},{label:"Last 12 months",months:12},{label:"Last 24 months",months:24},{label:"All time",months:36}],Q=Date.parse("2026-07-01T00:00:00.000Z");function oe(){const[t,o]=U.useState(12),n=_({queryKey:["admin-product-analytics",t],queryFn:()=>Y({data:{months:t}}),staleTime:5*6e4}),i=n.data?.points??[],r=i.at(-1);return s.jsxs("section",{className:"space-y-8",children:[s.jsxs("header",{className:"flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between",children:[s.jsxs("div",{children:[s.jsx("p",{className:"text-xs uppercase tracking-[0.18em] text-bliss-ink-soft",children:"Growth"}),s.jsx("h1",{className:"font-serif text-3xl font-semibold tracking-tight text-bliss-ink",children:"Product analytics"}),s.jsx("p",{className:"mt-1 text-sm text-bliss-ink-muted",children:"Live aggregate metrics from the Bliss production database."})]}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx("label",{className:"sr-only",htmlFor:"analytics-range",children:"Time range"}),s.jsx("select",{id:"analytics-range",value:t,onChange:e=>o(Number(e.target.value)),className:"rounded-full border border-bliss-stone/60 bg-white px-4 py-2 text-xs font-medium text-bliss-ink-muted transition hover:bg-bliss-frost-soft",children:J.map(e=>s.jsx("option",{value:e.months,children:e.label},e.months))}),s.jsxs("button",{type:"button",onClick:()=>n.refetch(),disabled:n.isFetching,className:"inline-flex items-center justify-center gap-2 rounded-full border border-bliss-stone/60 bg-white px-4 py-2 text-xs font-medium text-bliss-ink-muted transition hover:bg-bliss-frost-soft disabled:opacity-60",children:[s.jsx(W,{className:`h-3.5 w-3.5 ${n.isFetching?"animate-spin":""}`}),"Refresh"]})]})]}),n.isPending?s.jsx("div",{className:"flex h-48 items-center justify-center",children:s.jsx(V,{className:"h-6 w-6 animate-spin text-bliss-primary"})}):n.isError||!r?s.jsxs("div",{className:"flex items-start gap-3 rounded-2xl border border-rose-200 bg-rose-50 p-5 text-sm text-rose-800",children:[s.jsx(z,{className:"mt-0.5 h-4 w-4 shrink-0"}),"Product analytics could not be loaded. No source data was changed."]}):s.jsxs(s.Fragment,{children:[s.jsx(ne,{points:i}),s.jsx(ie,{points:i}),s.jsx(v,{title:"Monthly performance",description:"Canonical commercial activity. Current month values are month-to-date.",points:i,columns:[["New users",e=>a(e.acquisition.newUsers)],["New customers",e=>a(e.acquisition.newCustomers)],["New therapists",e=>a(e.acquisition.newTherapists)],["Cash payers",e=>a(e.customers.activePaying)],["New cash payers",e=>a(e.customers.newPaying)],["Cash sessions",e=>a(e.booking.paidConversions)],["Cash sessions / payer",e=>y(e.customers.averageConvertedSessionsPerCustomer)],["Commercial therapists",e=>a(e.therapists.commerciallyActive)]]}),s.jsx(v,{title:"Bookings and cash economics",description:"Converted bookings are currently confirmed or completed bookings created in the month; they are not proof of attendance. Cash metrics use canonical positive, non-refunded regular-session payments tied to active appointments.",points:i,columns:[["Bookings created",e=>a(e.booking.created)],["Converted bookings",e=>a(e.booking.convertedByCurrentStatus)],["Cash sessions",e=>a(e.booking.paidConversions)],["Sponsored sessions",e=>a(e.booking.sponsoredConversions)],["Abandoned",e=>a(e.booking.abandoned)],["Canceled",e=>a(e.booking.genuineCancellations)],["Cash session GMV",e=>A(e.value.cashGmvEurStored)],["Average cash session",e=>R(e.value.averagePaidSessionEur)],["Cash GMV / payer",e=>R(e.value.averageRevenuePerPayingCustomerEur)],["Booking conversion rate",e=>m(e.booking.conversionRate)]]}),s.jsx(v,{title:"Matching health",description:"Responses are deduplicated by session and therapist; scores are normalized to 0–100. Months before matching data existed are unavailable, not zero.",points:i,columns:[["Starts",e=>x(e,()=>a(e.matching.created))],["Results",e=>x(e,()=>a(e.matching.results))],["Errors",e=>x(e,()=>a(e.matching.errors))],["Canceled",e=>x(e,()=>a(e.matching.canceled))],["Completion rate",e=>x(e,()=>m(e.matching.completionRate))],["Unique therapist responses",e=>x(e,()=>a(e.matching.responses))],["Average score",e=>x(e,()=>y(e.matching.averageScore))],["Eligible-customer link rate",e=>x(e,()=>m(e.matchingOutcomes.userLinkRate))],["Mature matching → cash 30d",e=>x(e,()=>m(e.matchingOutcomes.bookingConversion30DayRate))],["Mature 30d sample",e=>x(e,()=>a(e.matchingOutcomes.mature30DayUsers))]]}
1),s.jsx(v,{title:"AI-matched paid sessions",description:"Average canonical paid regular sessions per user whose first AI-matching result landed in the month. Averages include users with zero paid sessions and are shown only after the full 30- or 90-day window has matured.",points:i,columns:[["AI-matched users",e=>a(e.matchingOutcomes.firstMatchCohortUsers)],["Mature 30d cohort",e=>a(e.matchingOutcomes.mature30DayUsers)],["Avg paid sessions / user 30d",e=>y(e.matchingOutcomes.averagePaidSessions30DaysAllMatched)],["Mature 90d cohort",e=>a(e.matchingOutcomes.mature90DayUsers)],["Avg paid sessions / user 90d",e=>y(e.matchingOutcomes.averagePaidSessions90DaysAllMatched)]]}),s.jsx(v,{title:"Repeat paid-session retention",description:"First-time cash payers are grouped by whether an AI-matching result existed before their first paid booking. Retention means a second canonical paid regular session within the window; samples are retained / eligible.",points:i,columns:[["AI-matched 30d",e=>C(e.matchingOutcomes.retention.aiMatched.retention30DayRate,e.matchingOutcomes.retention.aiMatched.retained30Days,e.matchingOutcomes.retention.aiMatched.eligible30Days)],["Not AI-matched 30d",e=>C(e.matchingOutcomes.retention.notAiMatched.retention30DayRate,e.matchingOutcomes.retention.notAiMatched.retained30Days,e.matchingOutcomes.retention.notAiMatched.eligible30Days)],["AI-matched 60d",e=>C(e.matchingOutcomes.retention.aiMatched.retention60DayRate,e.matchingOutcomes.retention.aiMatched.retained60Days,e.matchingOutcomes.retention.aiMatched.eligible60Days)],["Not AI-matched 60d",e=>C(e.matchingOutcomes.retention.notAiMatched.retention60DayRate,e.matchingOutcomes.retention.notAiMatched.retained60Days,e.matchingOutcomes.retention.notAiMatched.eligible60Days)],["AI-matched 90d",e=>C(e.matchingOutcomes.retention.aiMatched.retention90DayRate,e.matchingOutcomes.retention.aiMatched.retained90Days,e.matchingOutcomes.retention.aiMatched.eligible90Days)],["Not AI-matched 90d",e=>C(e.matchingOutcomes.retention.notAiMatched.retention90DayRate,e.matchingOutcomes.retention.notAiMatched.retained90Days,e.matchingOutcomes.retention.notAiMatched.eligible90Days)]]}),s.jsx(v,{title:"Therapist supply",description:"Cash sessions and qualifying company-sponsored sessions define commercial activity. Published and accepting-client counts are current-state values.",points:i,columns:[["Total therapists",e=>a(e.therapists.totalAsOfPeriodEnd)],["Commercially active",e=>a(e.therapists.commerciallyActive)],["Activated",e=>a(e.therapists.activatedAsOfPeriodEnd)],["Currently published",e=>$(e.therapists.currentlyPublished)],["Currently accepting",e=>$(e.therapists.currentlyAcceptingClients)],["Cash sessions / active therapist",e=>y(e.therapists.averageB2cSessionsPerActiveTherapist)],["Sponsored sessions / active therapist",e=>y(e.therapists.averageB2bSessionsPerActiveTherapist)]]}),s.jsx(ee,{distribution:n.data.therapistPriceDistribution}),s.jsx(H,{rows:n.data.therapistMetrics,label:r.label}),s.jsx(v,{title:"Guest → account",description:"Guest tracking began in July 2026. Earlier periods are unavailable; thirty-day conversion is shown only for cohorts old enough to mature.",points:i,columns:[["Guest identities",e=>M(e,()=>a(e.guestFunnel.identities))],["Converted bookings",e=>M(e,()=>a(e.guestFunnel.withConvertedSession))],["Cash payers",e=>M(e,()=>a(e.guestFunnel.withPayment))],["Accounts claimed",e=>M(e,()=>a(e.guestFunnel.accountsClaimed))],["Mature 30d claim rate",e=>M(e,()=>m(e.guestFunnel.mature30DayConversionRate))]]}),s.jsx(v,{title:"Cash-session progression",description:"Lifetime canonical cash-session progression as of each month-end; this is not mature-cohort retention.",points:i,columns:[["1+ sessions",e=>a(e.progressionAsOfPeriodEnd.session1Customers)],["2+ sessions",e=>a(e.progressionAsOfPeriodEnd.session2Customers)],["3+ sessions",e=>a(e.progressionAsOfPeriodEnd.session3Customers)],["4+ sessions",e=>a(e.progressionAsOfPeriodEnd.session4Customers)],["1 → 2",e=>m(e.progressionAsOfPeriodEnd.session1To2Rate)],["2 → 3",e=>m(e.progressionAsOfPeriodEnd.session2To3Rate)],["3 → 4",e=>m(e.progressionAsOfPeriodEnd.session3To4Rate)]]}),s.jsxs("p",{className:"text-xs text-bliss-ink-soft",children:["Updated ",new Date(n.data.generatedAt).toLocaleStr
1ing(),". Current month values are month-to-date. Internal/test accounts must be explicitly tagged to be excluded when they use personal email addresses."]})]})]})}function H({rows:t,label:o}){return s.jsxs("div",{className:"overflow-hidden rounded-2xl border border-bliss-stone/55 bg-white",children:[s.jsxs("div",{className:"border-b border-bliss-stone/45 px-5 py-4",children:[s.jsxs("h2",{className:"font-serif text-xl font-semibold text-bliss-ink",children:["Top 10 therapists by commercial sessions · ",o," MTD"]}),s.jsx("p",{className:"mt-1 text-xs text-bliss-ink-muted",children:"Canonical cash and qualifying sponsored volume. Cash GMV excludes sponsored value. Abandonment means unpaid bookings plus released or expired checkout holds. Customer identities are never exposed."})]}),s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"min-w-full text-sm",children:[s.jsx("thead",{className:"bg-bliss-frost-soft/60 text-left text-[11px] uppercase tracking-[0.12em] text-bliss-ink-soft",children:s.jsxs("tr",{children:[s.jsx("th",{className:"sticky left-0 z-10 bg-bliss-frost px-4 py-3 font-semibold",children:"Therapist"}),["Clients","Sessions","Bookings","Abandoned","Abandon rate","Sessions / client","Cash GMV"].map(n=>s.jsx("th",{className:"whitespace-nowrap px-4 py-3 text-right font-semibold",children:n},n))]})}),s.jsx("tbody",{className:"divide-y divide-bliss-stone/35",children:t.map(n=>s.jsxs("tr",{className:"hover:bg-bliss-frost-soft/35",children:[s.jsx("td",{className:"sticky left-0 z-[1] whitespace-nowrap bg-white px-4 py-3 font-medium text-bliss-ink shadow-[1px_0_0_var(--color-bliss-stone)]",children:n.displayName}),s.jsx("td",{className:"px-4 py-3 text-right tabular-nums",children:a(n.clients)}),s.jsx("td",{className:"px-4 py-3 text-right tabular-nums",children:a(n.convertedSessions)}),s.jsx("td",{className:"px-4 py-3 text-right tabular-nums",children:a(n.bookingsCreated)}),s.jsx("td",{className:"px-4 py-3 text-right tabular-nums",children:a(n.abandonedBookings)}),s.jsx("td",{className:"px-4 py-3 text-right tabular-nums",children:m(n.abandonmentRate)}),s.jsx("td",{className:"px-4 py-3 text-right tabular-nums",children:y(n.averageSessionsPerClient)}),s.jsx("td",{className:"px-4 py-3 text-right tabular-nums",children:A(n.cashGmvEur)})]},n.therapistId))})]})})]})}function ee({distribution:t}){const o=[["Below €30",t.below30],["€30–€50",t.from30To50],["Above €50–€80",t.over50To80],["Above €80",t.over80],["Missing or €0",t.missingOrZero]];return s.jsxs("div",{className:"overflow-hidden rounded-2xl border border-bliss-stone/55 bg-white",children:[s.jsxs("div",{className:"border-b border-bliss-stone/45 px-5 py-4",children:[s.jsx("h2",{className:"font-serif text-xl font-semibold text-bliss-ink",children:"Therapist price distribution"}),s.jsxs("p",{className:"mt-1 text-xs text-bliss-ink-muted",children:["Current profile snapshot for ",a(t.total)," activated or published therapists. Rates are not historically versioned, so these values are not projected back into previous months."]})]}),s.jsx("div",{className:"grid gap-px bg-bliss-stone/35 sm:grid-cols-5",children:o.map(([n,i])=>s.jsxs("div",{className:"bg-white px-5 py-4",children:[s.jsx("p",{className:"text-xs text-bliss-ink-muted",children:n}),s.jsx("p",{className:"mt-1 font-serif text-2xl font-semibold tabular-nums text-bliss-ink",children:a(i)})]},n))})]})}function se(t){if(t.length<2)return null;const o=t[t.length-1],n=t[t.length-2];return o==null||n==null||n===0?null:(o-n)/Math.abs(n)*100}function te({values:t,isPartial:o}){if(o)return null;const n=se(t);return n==null?null:s.jsxs("span",{className:"inline-flex items-center gap-1 whitespace-nowrap rounded-full border border-bliss-stone/60 bg-bliss-frost-soft px-2 py-0.5 text-xs font-semibold text-bliss-ink-soft",children:[n>=0?"▲":"▼"," ",Math.abs(n).toFixed(1),"%"]})}function ne({points:t}){const o=t.at(-1);if(!o)return null;const n=[{label:"Cash session GMV",value:i=>A(i.value.cashGmvEurStored),series:i=>i.value.cashGmvEurStored},{label:"New customers",value:i=>a(i.acquisition.newCustomers),series:i=>i.acquisition.newCustomers},{label:"Cash sessions",value:i=>a(i.booking.paidConversions),series:i=>i.booking.paidConversions},{label:"Average cash session",value:i=>R(i.value.averagePaidSessionEur),series:i=>i.value.averagePaidSessionEur},{label:"Cash payers",value:i=>a(i.customers.activePaying),series:i=>i.customers.activePaying},{label:"Booking conversion rate",value:i=>m(i.booking.conversionRate),series:i=>i.booking.conversionRate}];return s.jsx("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-3",children:n.map(i=>{const r=t.map(i.series);return s.jsxs("div",{className:"rounded-2xl border border-bliss-stone/55 bg-white p-5",children:[s.jsx("p",{className:"text-[11px] font-semibold uppercase tracking-[0.16em] text-bliss-ink-soft",children:i.label}),s.jsxs("div",{className:"mt-2 flex flex-wrap items-baseline gap-x-3 gap-y-1",children:[s.jsx("p",{className:"font-serif text-3xl font-semibold tabular-nums text-bliss-ink",children:i.value(o)}),s.jsx(te,{values:r,isPartial:o.isPartial})]}),s.jsxs("p",{className:"mt-1 text-xs text-bliss-ink-soft",children:[o.label,o.isPartial?" · MTD":""]}),s.jsx(K,{values:r})]},i.label)})})}function ie({points:t}){const o=t.map(r=>`${r.label}${r.isPartial?" MTD":""}`),n=r=>t.map(r),i=[{title:"Cash session GMV",description:"Monthly non-refunded cash session GMV (EUR).",format:A,series:[{name:"Cash",values:n(r=>r.value.cashGmvEurStored)}]},{title:"New customers",description:"New eligible customer accounts per month.",format:a,series:[{name:"New customers",values:n(r=>r.acquisition.newCustomers)}]},{title:"Bookings: created vs converted",description:"Converted means currently confirmed or completed, not attended.",format:a,series:[{name:"Created",values:n(r=>r.booking.created),dashed:!0},{name:"Converted",values:n(r=>r.booking.convertedByCurrentStatus)}]},{title:"Conversion rate",description:"Converted ÷ created.",format:m,series:[{name:"Conversion",values:n(r=>r.booking.conversionRate)}]},{title:"Matching: starts vs results",description:"AI matching volume and completions.",format:a,series:[{name:"Starts",values:n(r=>r.matching.available?r.matching.created:null),dashed:!0},{name:"Results",values:n(r=>r.matching.available?r.matching.results:null)}]},{title:"AI-matched → paid (30d)",description:"First-match users booking a paid session within 30 days.",format:m,series:[{name:"Matching → paid",values:n(r=>r.matchingOutcomes.bookingConversion30DayRate)}]}];return s.jsxs("div",{children:[s.jsxs("div",{className:"mb-3 flex items-center gap-3",children:[s.jsx("h2",{className:"font-serif text-xl font-semibold text-bliss-ink",children:"Trends"}),s.jsx("div",{className:"h-px flex-1 bg-bliss-stone/55"})]}),s.jsx("div",{className:"grid gap-3 lg:grid-cols-2 xl:grid-cols-3",children:i.map(r=>s.jsxs("div",{className:"rounded-2xl border border-bliss-stone/55 bg-white p-4",children:[s.jsx("h3",{className:"text-sm font-semibold text-bliss-ink",children:r.title}),s.jsx("p",{className:"mb-1 mt-0.5 text-xs text-bliss-ink-soft",children:r.description}),s.jsx(X,{labels:o,series:r.series,format:r.format}),r.series.length>1?s.jsx("div",{className:"mt-2 flex flex-wrap gap-4 text-xs text-bliss-ink-muted",children:r.series.map(e=>s.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[s.jsx("span",{className:`inline-block h-2.5 w-2.5 rounded-sm ${e.dashed?"bg-bliss-ink-soft":"bg-bliss-primary"}`}),e.name]},e.name))}):null]},r.title))})]})}function v({title:t,description:o,points:n,columns:i}){const r=n.slice(-12),e=n.length>r.length;return s.jsxs("div",{className:"overflow-hidden rounded-2xl border border-bliss-stone/55 bg-white",children:[s.jsxs("div",{className:"border-b border-bliss-stone/45 px-5 py-4",children:[s.jsx("h2",{className:"font-serif text-xl font-semibold text-bliss-ink",children:t}),s.jsxs("p",{className:"mt-1 text-xs text-bliss-ink-muted",children:[o,e?" · table shows the most recent 12 months; charts above use the full range.":""]})]}),s.jsx("div",{className:"overflow-x-auto",children:s.jsxs("table",{className:"min-w-full text-sm",children:[s.jsx("thead",{className:"bg-bliss-frost-soft/60 text-left text-[11px] uppercase tracking-[0.12em] text-bliss-ink-soft",children:s.jsxs("tr",{children:[s.jsx("th",{className:"sticky left-0 z-10 bg-bliss-frost px-4 py-3 font-semibold",children:"Month"}),i.map(([d])=>s.jsx("th",{className:"whitespace-nowrap px-4 py-3 text-right font-semibold",children:d},d))]})}),s.jsx("tbody",{className:"divide-y divide-bliss-stone/35",children:r.map(d=>s.jsxs("tr",{className:"hover:bg-bliss-frost-soft/35",children:[s.jsxs("td",{className:"sticky left-0 z-[1] whitespace-nowrap bg-white px-4 py-3 font-medium text-bliss-ink shadow-[1px_0_0_var(--color-bliss-stone)]",children:[d.label,d.isPartial?" MTD":""]}),i.map(([p,f])=>s.jsx("td",{className:"whitespace-nowrap px-4 py-3 text-right tabular-nums text-bliss-ink-muted",children:f(d)},p))]}
1,d.period.from))})]})})]})}function x(t,o){return t.matching.available?o():"—"}function M(t,o){return Date.parse(t.period.from)>=Q?o():"—"}function a(t){return t.toLocaleString()}function $(t){return t==null?"—":a(t)}function A(t){return new Intl.NumberFormat("en",{style:"currency",currency:"EUR"}).format(t)}function m(t){return t==null?"—":`${(t*100).toFixed(1)}%`}function C(t,o,n){return`${m(t)} (${a(o)} / ${a(n)})`}function y(t){return t==null?"—":t.toFixed(1)}function R(t){return t==null?"—":A(t)}export{oe as component};

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.