{"id":811,"date":"2026-05-16T15:55:41","date_gmt":"2026-05-16T15:55:41","guid":{"rendered":"https:\/\/bigfamilyportal.com\/?page_id=811"},"modified":"2026-05-16T15:55:42","modified_gmt":"2026-05-16T15:55:42","slug":"tree-clean-test","status":"publish","type":"page","link":"https:\/\/bigfamilyportal.com\/index.php\/tree-clean-test\/","title":{"rendered":"Tree Clean Test"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><style>\n#bfp70_irWxqe0RPN {\n    display:   block    !important;\n    position:  fixed    !important;\n    top:       0px !important;\n    left:      0        !important;\n    right:     0        !important;\n    width:     100vw    !important;\n    height:    calc(100vh - 0px) !important;\n    min-height:500px    !important;\n    overflow:  hidden   !important;\n    z-index:   9990     !important;\n    margin:    0        !important;\n    padding:   0        !important;\n    box-sizing:border-box !important;\n}\n#bfp-spacer-bfp70_irWxqe0RPN {\n    display:block;\n    height:calc(100vh - 0px);\n    min-height:500px;\n}\n<\/style>\n<div id=\"bfp-spacer-bfp70_irWxqe0RPN\"><\/div>\n<div class=\"bfp70-host\" id=\"bfp70_irWxqe0RPN\" data-tree-id=\"1\"><\/div>\n<script>\n(function(){\n    window.BFPFTSuite = window.BFPFTSuite || {};\n    window.BFPFTSuite.ajaxAction   = \"bfp_ft_tree_data_v2\";\n    window.BFPFTSuite.ajaxFallback = \"bfp_ft_tree_data\";\n\n    window.bfpInjectToolbar = function(host) {\n        \/\/ host passed from tree.js after renderTree() completes\n        if (!host) host = document.getElementById(\"bfp70_irWxqe0RPN\");\n        if (!host) return;\n        \/\/ Remove any existing toolbar first\n        var existing = host.querySelector('.bfp-share-toolbar');\n        if (existing) existing.parentNode.removeChild(existing);\n        \/\/ Create and inject fresh toolbar\n        var wrapper = document.createElement(\"div\");\n        wrapper.innerHTML = \"<div style=\\\"position:absolute;top:10px;right:12px;display:flex;gap:8px;flex-wrap:wrap;z-index:200;\\\"><button onclick=\\\"bfpExportPDF(event)\\\" style=\\\"padding:7px 14px;background:#6366f1;color:#fff;border:none;border-radius:8px;font-weight:700;cursor:pointer;font-size:12px;\\\">Export PDF<\\\/button><a href=\\\"https:\\\/\\\/www.facebook.com\\\/sharer\\\/sharer.php?u=https%3A%2F%2Fbigfamilyportal.com%2Findex.php%2Ftree-clean-test%2F\\\" target=\\\"_blank\\\" style=\\\"padding:7px 14px;background:#1877f2;color:#fff;border-radius:8px;font-weight:700;text-decoration:none;font-size:12px;\\\">Facebook<\\\/a><a href=\\\"https:\\\/\\\/twitter.com\\\/intent\\\/tweet?url=https%3A%2F%2Fbigfamilyportal.com%2Findex.php%2Ftree-clean-test%2F&amp;text=Tree%20Clean%20Test\\\" target=\\\"_blank\\\" style=\\\"padding:7px 14px;background:#1da1f2;color:#fff;border-radius:8px;font-weight:700;text-decoration:none;font-size:12px;\\\">Twitter<\\\/a><a href=\\\"https:\\\/\\\/wa.me\\\/?text=https%3A%2F%2Fbigfamilyportal.com%2Findex.php%2Ftree-clean-test%2F\\\" target=\\\"_blank\\\" style=\\\"padding:7px 14px;background:#25d366;color:#fff;border-radius:8px;font-weight:700;text-decoration:none;font-size:12px;\\\">WhatsApp<\\\/a><\\\/div>\";\n        var tb = wrapper.firstChild;\n        if (tb) {\n            tb.className = (tb.className || '') + ' bfp-share-toolbar';\n            host.appendChild(tb);\n        }\n    };\n\n    window.bfpExportPDF = function(e) {\n        var host = document.getElementById(\"bfp70_irWxqe0RPN\");\n        if (!host) { alert(\"Tree not found.\"); return; }\n        var btn = e.target;\n        btn.textContent = \"Generating...\"; btn.disabled = true;\n        var layout = host._bfpLayout;\n        if (!layout) {\n            alert(\"Tree data not ready. Please wait for the tree to finish loading.\");\n            btn.textContent = \"Export PDF\"; btn.disabled = false; return;\n        }\n        if (typeof window.jspdf === \"undefined\") {\n            alert(\"PDF library not loaded. Please try again.\");\n            btn.textContent = \"Export PDF\"; btn.disabled = false; return;\n        }\n        \/\/ Defer to next tick so button text updates first\n        setTimeout(function() {\n            try { bfpDraw(layout, btn); }\n            catch(err) {\n                alert(\"PDF export failed: \" + err.message);\n                btn.textContent = \"Export PDF\"; btn.disabled = false;\n            }\n        }, 50);\n    };\n\n    window.bfpDraw = function(L, btn) {\n        var pad=40, CW=L.CW, CH=L.CH, NW=L.NW, NH=L.NH;\n        var hidden=new Set();\n        L.collapsed.forEach(function(id){\n            (function walk(pid){\n                (L.childrenOf.get(pid)||[]).forEach(function(c){if(!hidden.has(c)){hidden.add(c);walk(c);}});\n            })(id);\n        });\n        var cvs=document.createElement('canvas');\n        cvs.width=CW+pad*2; cvs.height=CH+pad*2;\n        var ctx=cvs.getContext('2d');\n        \/\/ Plain fast background\n        ctx.fillStyle='#f0f4f8'; ctx.fillRect(0,0,cvs.width,cvs.height);\n        ctx.save(); ctx.translate(pad,pad);\n        ctx.lineCap='round'; ctx.lineJoin='round';\n        \/\/ Spouse lines\n        var ds=new Set();\n        L.spouseOf.forEach(function(set,a){\n            set.forEach(function(b){\n                var k=a<b?a+'-'+b:b+'-'+a; if(ds.has(k))return; ds.add(k);\n                if(!L.byId.has(a)||!L.byId.has(b))return;\n                if(hidden.has(a)||hidden.has(b))return;\n                var yL=Math.min(L.yR.get(a)||0,L.yR.get(b)||0)+NH-12;\n                var ax=(L.xR.get(a)||0)+NW\/2, bx=(L.xR.get(b)||0)+NW\/2;\n                var pm=L.partnerMeta.get(Math.min(a,b)+'-'+Math.max(a,b));\n                var ex=pm&&pm.type==='ex_partner';\n                ctx.strokeStyle=ex?'rgba(239,68,68,.7)':'rgba(139,92,246,.6)';\n                ctx.lineWidth=2; ctx.setLineDash(ex?[5,4]:[6,4]);\n                ctx.beginPath(); ctx.moveTo(ax,yL); ctx.lineTo(bx,yL); ctx.stroke();\n                ctx.setLineDash([]);\n                ctx.fillStyle=ex?'rgba(239,68,68,.8)':'rgba(139,92,246,.8)';\n                ctx.beginPath(); ctx.arc((ax+bx)\/2,yL,4,0,Math.PI*2); ctx.fill();\n                if(pm&&(pm.label||pm.marriage_date)){\n                    ctx.fillStyle='#64748b'; ctx.font='10px sans-serif';\n                    ctx.textAlign='center';\n                    ctx.fillText(pm.label||pm.marriage_date.slice(0,4),(ax+bx)\/2,yL-7);\n                }\n            });\n        });\n        \/\/ Parent->child\n        L.coupleKids.forEach(function(kids,key){\n            var p=key.split('-'),f=+p[0],m=+p[1];\n            var vk=kids.filter(function(c){return L.byId.has(c)&&!hidden.has(c);});\n            if(!vk.length)return;\n            var fH=hidden.has(f),mH=hidden.has(m),ux,uy;\n            if(f&&m&&L.byId.has(f)&&L.byId.has(m)&&!fH&&!mH){\n                uy=Math.min(L.yR.get(f)||0,L.yR.get(m)||0)+NH-12;\n                ux=((L.xR.get(f)||0)+(L.xR.get(m)||0))\/2+NW\/2;\n                ctx.fillStyle='rgba(139,92,246,.7)';\n                ctx.beginPath(); ctx.arc(ux,uy,4,0,Math.PI*2); ctx.fill();\n            } else if(f&&L.byId.has(f)&&!fH){ux=(L.xR.get(f)||0)+NW\/2;uy=(L.yR.get(f)||0)+NH;}\n            else if(m&&L.byId.has(m)&&!mH){ux=(L.xR.get(m)||0)+NW\/2;uy=(L.yR.get(m)||0)+NH;}\n            else return;\n            var tops=vk.map(function(c){return{x:(L.xR.get(c)||0)+NW\/2,y:L.yR.get(c)||0};});\n            var busY=uy+(Math.min.apply(null,tops.map(function(t){return t.y;}))-uy)*0.55;\n            ctx.strokeStyle='rgba(100,116,139,.5)'; ctx.lineWidth=1.5;\n            ctx.beginPath(); ctx.moveTo(ux,uy); ctx.bezierCurveTo(ux,uy+25,ux,busY-15,ux,busY); ctx.stroke();\n            var mn=Math.min.apply(null,tops.map(function(t){return t.x;}));\n            var mx=Math.max.apply(null,tops.map(function(t){return t.x;}));\n            if(mn<mx){ctx.beginPath();ctx.moveTo(mn,busY);ctx.lineTo(mx,busY);ctx.stroke();}\n            tops.forEach(function(tp){\n                ctx.beginPath();ctx.moveTo(tp.x,busY);ctx.lineTo(tp.x,tp.y);ctx.stroke();\n                ctx.fillStyle='rgba(100,116,139,.5)';\n                ctx.beginPath();ctx.arc(tp.x,tp.y,2.5,0,Math.PI*2);ctx.fill();\n            });\n        });\n        \/\/ Person cards\n        L.byId.forEach(function(p,id){\n            if(hidden.has(id))return;\n            var nx=L.xR.get(id)||0, ny=L.yR.get(id)||0;\n            var sex=(p.sex||'').toUpperCase();\n            var bg,br,avA,avB;\n            if(sex==='M'){bg='#eff6ff';br='#93c5fd';avA='#bfdbfe';avB='#3b82f6';}\n            else if(sex==='F'){bg='#fdf2f8';br='#f0abfc';avA='#fce7f3';avB='#ec4899';}\n            else{bg='#f8fafc';br='#cbd5e1';avA='#e2e8f0';avB='#94a3b8';}\n            \/\/ Shadow\n            ctx.shadowColor='rgba(0,0,0,.09)'; ctx.shadowBlur=8; ctx.shadowOffsetY=3;\n            \/\/ Card\n            bfpRR(ctx,nx,ny,NW,NH,12);\n            ctx.fillStyle=bg; ctx.fill();\n            ctx.shadowColor='transparent'; ctx.shadowBlur=0; ctx.shadowOffsetY=0;\n            ctx.strokeStyle=br; ctx.lineWidth=1.5; ctx.stroke();\n            \/\/ Avatar\n            var avX=nx+36,avY=ny+NH\/2;\n            var g=ctx.createRadialGradient(avX-5,avY-5,2,avX,avY,20);\n            g.addColorStop(0,avA); g.addColorStop(1,avB);\n            ctx.beginPath(); ctx.arc(avX,avY,20,0,Math.PI*2);\n            ctx.fillStyle=g; ctx.fill();\n            var nm=((p.first_name||'')+' '+(p.last_name||'')).trim();\n            var pts=nm.split(\/\\s+\/).filter(Boolean);\n            var ini=((pts[0]?pts[0][0]:'')+(pts.length>1?pts[pts.length-1][0]:'')).toUpperCase()||'?';\n            ctx.fillStyle='#fff'; ctx.font='bold 12px sans-serif';\n            ctx.textAlign='center'; ctx.textBaseline='middle';\n            ctx.fillText(ini,avX,avY);\n            \/\/ Name\n            var tx=nx+62, mw=NW-66;\n            ctx.fillStyle='#0f172a'; ctx.font='bold 12px sans-serif';\n            ctx.textAlign='left'; ctx.textBaseline='middle';\n            var dn=nm+(+p.is_deceased?' +':'');\n            while(ctx.measureText(dn).width>mw&&dn.length>3) dn=dn.slice(0,-2)+'...';\n            ctx.fillText(dn,tx,ny+NH\/2-8);\n            var by=p.birth_year||(p.birth_date?p.birth_date.slice(0,4):'');\n            var dy=p.death_year||(p.death_date?p.death_date.slice(0,4):'');\n            if(by||dy){\n                ctx.fillStyle='#64748b'; ctx.font='10px sans-serif';\n                ctx.fillText((by||'')+(dy?'-'+dy:''),tx,ny+NH\/2+8);\n            }\n        });\n        ctx.restore();\n        var img=cvs.toDataURL('image\/jpeg',0.9);\n        var pdf=new window.jspdf.jsPDF({\n            orientation:CW>CH?'landscape':'portrait',unit:'mm',format:'a4'\n        });\n        var pW=pdf.internal.pageSize.getWidth(),pH=pdf.internal.pageSize.getHeight();\n        var mg=10,pm=0.2646;\n        var iW=cvs.width*pm,iH=cvs.height*pm;\n        var r=Math.min((pW-mg*2)\/iW,(pH-mg*2)\/iH);\n        pdf.addImage(img,'JPEG',(pW-iW*r)\/2,(pH-iH*r)\/2,iW*r,iH*r);\n        pdf.save('family-tree.pdf');\n        btn.textContent=\"Export PDF\"; btn.disabled=false;\n    };\n\n    function bfpRR(ctx,x,y,w,h,r){\n        if(w<2*r)r=w\/2; if(h<2*r)r=h\/2;\n        ctx.beginPath();\n        ctx.moveTo(x+r,y); ctx.arcTo(x+w,y,x+w,y+h,r);\n        ctx.arcTo(x+w,y+h,x,y+h,r); ctx.arcTo(x,y+h,x,y,r);\n        ctx.arcTo(x,y,x+w,y,r); ctx.closePath();\n    }\n\n\n    \/\/ Toolbar is injected by tree.js AFTER renderTree() completes\n    \/\/ Do NOT inject here - renderTree() wipes host.innerHTML first\n})();\n<\/script>\n        <\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-811","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/pages\/811","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/comments?post=811"}],"version-history":[{"count":1,"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/pages\/811\/revisions"}],"predecessor-version":[{"id":813,"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/pages\/811\/revisions\/813"}],"wp:attachment":[{"href":"https:\/\/bigfamilyportal.com\/index.php\/wp-json\/wp\/v2\/media?parent=811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}