1import{s as H,b_ as R,b$ as j,c2 as E,j as h}from"./index-BxMXNQIY.js";const G={express:"Express",standard:"Standard",economy:"Economy"};function $(t){return Array.isArray(t)?"["+t.map($).join(",")+"]":t&&typeof t=="object"?"{"+Object.keys(t).sort().map(s=>JSON.stringify(s)+":"+$(t[s])).join(",")+"}":JSON.stringify(t)}async function x(t){const r=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t));return Array.from(new Uint8Array(r),s=>s.toString(16).padStart(2,"0")).join("")}function C(t,r){const s=t.company_weights,e=r.filter(a=>s[a]!=null&&s[a]>0);e.sort();const n=e.reduce((a,u)=>a+s[u],0),i={};if(n<=0)return i;for(const a of e)i[a]=s[a]/n;return i}function O(t,r,s){if(!(t>=0&&t<1))throw new Error(`rollCompany: r out of [0,1): ${t}`);const e=C(r,s),n=Object.keys(e);if(n.length===0)throw new Error("no_available_companies");let i=0;for(const a of n)if(i+=e[a],t<i)return a;return n[n.length-1]}function N(t,r,s,e,n){var _,f;if(!s||s.grade_total<=0)return{};if(!n||n<=0)return{};if(!e||e<=0)return{};const i=t.grade_floor,a=G[r],u=Number(t.p10_cap??.5),d=String(t.p10_model??"multiple");let p;if(d==="population"){let c=0;for(let y=4;y<=10;y++)c+=s.per_grade[String(y)]??0;const g=Number(t.min_pop_total_for_ratio??0);if(c<=0||c<g)return{};const b=(s.per_grade[10]??0)/c,k=Number(((_=t.tier_p10_k)==null?void 0:_[a])??.667);p=Math.min(u,t.p10_tier_scaling?k*b:b)}else{const c=Number(((f=t.tier_p10_k)==null?void 0:f[a])??.667);p=Math.min(u,c*(e/n))}let l=0;for(let c=4;c<=9;c++)l+=s.per_grade[String(c)]??0;if(l<=0)return{};const m={};for(let c=4;c<=10;c++)if(!(c<i))if(c===10)m[10]=p;else{const g=s.per_grade[String(c)]??0;m[String(c)]=g/l*(1-p)}return m}function A(t,r,s,e,n,i,a){if(!(t>=0&&t<1))throw new Error(`rollGrade: r out of [0,1): ${t}`);const u=N(r,s,n,i,a),d=Object.entries(u).sort((l,m)=>Number(m[0])-Number(l[0]));if(d.length===0)throw new Error("zero_grade_weight");let p=0;for(const[l,m]of d)if(p+=m,t<p)return Number(l);return Number(d[d.length-1][0])}async function M(t){const{data:r,error:s}=await H.functions.invoke("get-grade-verification",{body:{submission_id:t.receiptRowId}});return s||!(r!=null&&r.success)?null:{tier:r.tier,recordedCompany:r.recorded_company??null,recordedGrade:r.recorded_grade!=null?Number(r.recorded_grade):null,recordedLabel:r.recorded_grade_label??null,recordedRandomCompany:r.recorded_random_company!=null?Number(r.recorded_random_company):null,recordedRandomGrade:r.recorded_random_grade!=null?Number(r.recorded_random_grade):null,cfg:r.grading_config_snapshot??null,cfgHash:r.grading_config_hash??null,pop:r.pop_summary_snapshot??null,popHash:r.pop_summary_hash??null,prices:r.graded_prices_snapshot??null,pricesHash:r.graded_prices_hash??null,rawGems:Number(r.raw_gems_snapshot??0),psa10Gems:Number(r.psa10_gems_snapshot??0),companySet:Array.isArray(r.company_set)?r.company_set:[],status:r.status}}async function T(t){var b,k,y;const{inputs:r,cursorRecorded:s,recorded:e}=t,n=[],i=(await R(r.serverSeed)).toLowerCase()===r.serverSeedHash.toLowerCase();n.push({key:"commitment",ok:i,severity:i?"pass":"fail",label:"Server seed integrity",detail:i?"SHA-256(revealed seed) matches the hash committed at submit â the seed wasn't swapped after the result.":"Revealed seed does NOT hash to the committed value. Tampered."});const a=[];if(e.cfg&&e.cfgHash){const o=await x($(e.cfg));o!==e.cfgHash&&a.push(`grading_config hash mismatch (${o.slice(0,10)}⦠vs ${e.cfgHash.slice(0,10)}â¦)`)}else a.push("missing grading_config snapshot");if((e.pop||e.popHash)&&(!e.pop||!e.popHash?a.push("pop_summary snapshot/hash mismatch"):await x($(e.pop))!==e.popHash&&a.push("pop_summary hash mismatch")),e.prices&&e.pricesHash){const o=await x($(e.prices));o!==e.pricesHash&&a.push(`graded_prices hash mismatch (${o.slice(0,10)}⦠vs ${e.pricesHash.slice(0,10)}â¦)`)}else a.push("missing graded_prices snapshot");const u=a.length===0;n.push({key:"inputs_integrity",ok:u,severity:u?"pass":"fail",label:"Input integrity",detail:u?`Snapshot content hashes all match (config ${(b=e.cfgHash)==null?void 0:b.slice(0,10)}â¦, prices ${(k=e.pricesHash)==null?void 0:k.slice(0,10)}â¦${e.popHash?`, pop ${e.popHash.slice(0,10)}â¦`:""}). raw=${e.rawGems}, psa10=${e.psa10Gems}.`:`Issues: ${a.join("; ")}`});const d=j({serverSeed:r.serverSeed,clientSeed:r.clientSeed,nonce:r.nonce,actionType:r.actionType}),p=await d.next(),l=await d.next(),m=d.cursor===s;n.push({key:"stream",ok:m,severity:m?"pass":"fail",label:"HMAC stream",detail:m?`Replay consumed ${d.cursor} draws â matches recorded cursor count.`:`Replay consumed ${d.cursor}; server recorded ${s}.`});const _=1e-12;if(e.recordedRandomCompany!=null){const o=Math.abs(p-e.recordedRandomCompany)<_;n.push({key:"random_company",ok:o,severity:o?"pass":"fail",label:"Company draw",detail
1:o?`Re-derived r=${p} matches recorded (within IEEE-754 round-trip).`:`Mismatch â replayed ${p}, recorded ${e.recordedRandomCompany}.`})}if(e.recordedRandomGrade!=null){const o=Math.abs(l-e.recordedRandomGrade)<_;n.push({key:"random_grade",ok:o,severity:o?"pass":"fail",label:"Grade draw",detail:o?`Re-derived r=${l} matches recorded (within IEEE-754 round-trip).`:`Mismatch â replayed ${l}, recorded ${e.recordedRandomGrade}.`})}let f=!1,c=!1,g="";try{if(!e.cfg)throw new Error("missing config snapshot");if(!((y=e.companySet)!=null&&y.length))throw c=!0,new Error("Verification data incomplete â this grade pre-dates the grade_v2 verifier rollout and didn't snapshot the company set. The HMAC stream and commitment still match, but outcome replay can't run.");const o=O(p,e.cfg,e.companySet),w=A(l,e.cfg,e.tier,o,e.pop,e.rawGems,e.psa10Gems);f=o===e.recordedCompany&&w===e.recordedGrade,g=f?`Re-derived ${o} ${w} matches the recorded outcome.`:`Mismatch â replayed ${o} ${w}, recorded ${e.recordedCompany} ${e.recordedGrade}.`}catch(o){g=o instanceof Error?o.message:String(o)}return n.push({key:"outcome",ok:f||c,severity:f?"pass":c?"warn":"fail",label:"Outcome",detail:g}),{checks:n,verdict:E(n),detailRender:()=>{const o=e.cfg?N(e.cfg,e.tier,e.pop,e.rawGems,e.psa10Gems):{},w=Object.entries(o).sort((v,S)=>Number(S[0])-Number(v[0]));return h.jsxs("div",{className:"text-xs space-y-1 rounded border p-2 bg-muted/30",children:[h.jsxs("div",{className:"font-medium",children:["Reconstructed grade distribution (tier: ",e.tier,")"]}),h.jsx("table",{className:"w-full",children:h.jsx("tbody",{children:w.map(([v,S])=>h.jsxs("tr",{children:[h.jsxs("td",{className:"text-muted-foreground",children:["Grade ",v]}),h.jsxs("td",{className:"text-right tabular-nums",children:[(S*100).toFixed(4),"%"]})]},v))})}),h.jsxs("div",{className:"text-muted-foreground pt-1",children:["Eligible companies: ",e.companySet.join(", ")||"â"]})]})}}}const L={actionType:"grade_v2",fetchRecorded:M,verify:T};export{L as gradeV2Adapter};
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.