UNPKG

famtree-charted

Version:
2 lines 65.9 kB
// undefined v0.5.2 Copyright 2025 donatso edited by bagusandre !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).f3=e()}(this,(function(){"use strict";var t="object"==typeof window&&window.d3?window.d3:_d3;function e(t,e,n){return n.find((n=>n.id!==e.id&&(n.id===t.rels.mother||n.id===t.rels.father)))}function n(t,e,n){if(t.exiting=n,e)0!==t.depth||t.spouse?t.spouse?(t._x=t.spouse.x,t._y=t.spouse.y):t.is_ancestry?(t._x=t.parent.x,t._y=t.parent.y):(t._x=t.psx,t._y=t.psy):(t._x=t.x,t._y=t.y);else if(n){const e=t.x>0?1:-1,n=t.y>0?1:-1;t._x=t.x+400*e,t._y=t.y+400*n}}function r(t,e){const n=e?"rels":"_rels",r=e?"_rels":"rels";function i(e){t.data[n]&&t.data[n][e]&&(t.data[r]||(t.data[r]={}),t.data[r][e]=t.data[n][e],delete t.data[n][e])}t.is_ancestry||t.data.main?(i("father"),i("mother")):function(){if(!t.data[n]||!t.data[n].children)return;const e=t.data[n].children.slice(0),i=t.spouse?[t.spouse]:t.spouses||[];[t,...i].forEach((t=>e.forEach((e=>{t.data[n].children.includes(e)&&(t.data[r]||(t.data[r]={}),t.data[r].children||(t.data[r].children=[]),t.data[r].children.push(e),t.data[n].children.splice(t.data[n].children.indexOf(e),1))}))))}()}function i(t,e){const n=t.rels,r=[n.father,n.mother,...n.spouses||[],...n.children||[]].filter((t=>!!t)),i=[];for(let n=0;n<r.length;n++){if(!a(e.find((t=>t.id===r[n])),[t])){i.push(r[n]);break}}return 0===i.length;function a(t,n){let r;return s(t)&&(r=[t]),function t(i,a){if(r)return;a=[...a,i],o((function(t){s(t)&&(r=a)})),r||o(d);function o(t){const e=i.rels;[e.father,e.mother,...e.spouses||[],...e.children||[]].filter((t=>t&&![...n,...a].find((e=>e.id===t)))).forEach((e=>t(e)))}function d(n){const r=e.find((t=>t.id===n));t(r,a)}}(t,[t]),r}function s(t){return"object"==typeof t?t.id===e[0].id:t===e[0].id}}function a(t,e){return delete t.to_add,t}function s(t,e){return o(t,e),!1}function o(t,e){return i(t,e)?(e.forEach((e=>{for(let n in e.rels)e.rels.hasOwnProperty(n)&&(e.rels[n]===t.id?delete e.rels[n]:Array.isArray(e.rels[n])&&e.rels[n].includes(t.id)&&e.rels[n].splice(e.rels[n].findIndex((e=>e===t.id)),1))})),e.splice(e.findIndex((e=>e.id===t.id)),1),e.forEach((t=>{t.to_add&&o(t,e)})),0===e.length&&e.push(f({}).data[0]),{success:!0}):{success:!1,error:"checkIfRelativesConnectedWithoutPerson"}}function d(t){let e=JSON.parse(t);return e.forEach((t=>t.to_add?s(t,e):t)),e.forEach((t=>delete t.main)),e.forEach((t=>delete t.hide_rels)),JSON.stringify(e,null,2)}function l({datum:t,data_stash:e,rel_type:n,rel_datum:r}){function i(t){!function(){if(!r.rels.spouses)return;r.rels.spouses.forEach((t=>{const n=e.find((e=>e.id===t));n.to_add&&s(n,e)}))}(),r.rels.spouses||(r.rels.spouses=[]),r.rels.spouses.push(t.id),t.rels.spouses=[r.id]}"daughter"===n||"son"===n?function(t){t.data.other_parent&&(!function(n){"_new"===n&&(n=s().id);const a=e.find((t=>t.id===n));t.rels["M"===a.data.gender?"father":"mother"]=a.id,a.rels.hasOwnProperty("children")||(a.rels.children=[]);function s(){const t=u({rel_type:"spouse",rel_datum:r});return i(t),p({data_stash:e,datum:t}),t}a.rels.children.push(t.id)}(t.data.other_parent),delete t.data.other_parent);t.rels["M"===r.data.gender?"father":"mother"]=r.id,r.rels.children||(r.rels.children=[]);r.rels.children.push(t.id)}(t):"father"===n||"mother"===n?function(t){const n="M"===t.data.gender,i=r.rels[n?"father":"mother"];i&&s(e.find((t=>t.id===i)),e);r.rels[n?"father":"mother"]=t.id,function(){const i=r.rels[n?"mother":"father"];if(!i)return;const a=e.find((t=>t.id===i));t.rels.spouses=[i],a.rels.spouses||(a.rels.spouses=[]),a.rels.spouses.push(t.id)}(),t.rels.children=[r.id]}(t):"spouse"===n&&i(t)}function c({datum:t,new_rel_datum:e,data_stash:n}){const r=e._new_rel_data.rel_type;if(delete e._new_rel_data,e=JSON.parse(JSON.stringify(e)),"son"===r||"daughter"===r){let t=n.find((t=>t.id===e.rels.mother)),r=n.find((t=>t.id===e.rels.father));e.rels={},r&&(r.rels.children||(r.rels.children=[]),r.rels.children.push(e.id),e.rels.father=r.id),t&&(t.rels.children||(t.rels.children=[]),t.rels.children.push(e.id),e.rels.mother=t.id)}else if("spouse"===r)t.rels.spouses||(t.rels.spouses=[]),t.rels.spouses.includes(e.id)||t.rels.spouses.push(e.id),e.rels.children=e.rels.children.filter((r=>{const i=n.find((t=>t.id===r));return!!i&&(i.rels.mother!==t.id&&(n.find((t=>t.id===i.rels.mother))&&n.splice(n.findIndex((t=>t.id===i.rels.mother)),1),i.rels.mother=e.id),i.rels.father!==t.id&&(n.find((t=>t.id===i.rels.father))&&n.splice(n.findIndex((t=>t.id===i.rels.father)),1),i.rels.father=e.id),!0)})),e.rels={spouses:[t.id],children:e.rels.children};else if("father"===r){if(t.rels.father=e.id,e.rels={children:[t.id]},t.rels.mother){e.rels.spouses=[t.rels.mother];const r=n.find((e=>e.id===t.rels.mother));r.rels.spouses||(r.rels.spouses=[]),r.rels.spouses.push(e.id)}}else if("mother"===r&&(t.rels.mother=e.id,e.rels={children:[t.id]},t.rels.father)){e.rels.spouses=[t.rels.father];const r=n.find((e=>e.id===t.rels.father));r.rels.spouses||(r.rels.spouses=[]),r.rels.spouses.push(e.id)}n.push(e)}function h({data:t,rels:e}){return{id:(n=(new Date).getTime(),r=performance&&performance.now&&1e3*performance.now()||0,"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random();return n>0?(e=(n+e)%16|0,n=Math.floor(n/16)):(e=(r+e)%16|0,r=Math.floor(r/16)),("x"===t?e:3&e|8).toString(16)}))),data:t||{},rels:e||{}};var n,r}function u({data:t,rel_type:e,rel_datum:n}){const r=function(t,e){return["daughter","mother"].includes(e)||"spouse"===e&&"M"===t.data.gender?"F":"M"}(n,e);return h({data:t=Object.assign(t||{},{gender:r})})}function p({data_stash:t,datum:e}){t.push(e)}function f({data:t,version:e}){return{data:[h({data:t})],version:e}}function _(t,e){const n=t.data.rels;return[n.father,n.mother,...n.spouses||[],...n.children||[]].filter((t=>t)).every((t=>e.some((e=>e.data.id===t))))}function m({data:n,main_id:r=null,node_separation:i=250,level_separation:a=150,single_parent_empty_card:s=!0,is_horizontal:o=!1}){if(!n||!n.length)return{data:[],data_stash:[],dim:{width:0,height:0},main_id:null};o&&([i,a]=[a,i]);const d=s?function(t){const e=[];for(let e=0;e<t.length;e++){const r=t[e];if(r.rels.children&&r.rels.children.length>0){r.rels.spouses||(r.rels.spouses=[]);const e="M"===r.data.gender;let i;r.rels.children.forEach((a=>{const s=t.find((t=>t.id===a));s.rels[e?"father":"mother"]===r.id&&(s.rels[e?"mother":"father"]||(i||(i=n(r),r.rels.spouses.push(i.id)),i.rels.children.push(s.id),s.rels[e?"mother":"father"]=i.id))}))}}return e.forEach((e=>t.push(e))),t;function n(t){const n=h({data:{gender:"M"===t.data.gender?"F":"M"},rels:{spouses:[t.id],children:[]}});return n.to_add=!0,e.push(n),n}}(n):n;!function(t){t.forEach((n=>{if(!n.rels.children)return;const r=n.rels.spouses||[];n.rels.children.sort(((i,a)=>{const s=t.find((t=>t.id===i)),o=t.find((t=>t.id===a)),d=e(s,n,t)||{},l=e(o,n,t)||{},c=r.indexOf(d.id),h=r.indexOf(l.id);return"M"===n.data.gender?c-h:h-c}))}))}(d);const l=null!==r&&d.find((t=>t.id===r))||d[0],c=g(l,"children",!1),u=g(l,"parents",!0);d.forEach((t=>t.main=t===l)),function(t,e){const n=(t[0].x-e[0].x)/2;t.forEach((t=>t.x-=n)),e.forEach((t=>t.x+=n))}(u,c);const p=(m=c,(f=u).forEach((t=>{t.is_ancestry=!0})),f.forEach((t=>1===t.depth?t.parent=m[0]:null)),[...m,...f.slice(1)]);var f,m;!function({tree:t}){t.forEach((e=>{delete e.children,t.forEach((t=>{t.parent===e&&(t.is_ancestry?(e.parents||(e.parents=[]),e.parents.push(t)):(e.children||(e.children=[]),e.children.push(t)))}))}))}({tree:p}),function({tree:t,node_separation:e}){for(let n=t.length;n--;){const r=t[n];if(!r.is_ancestry&&r.data.rels.spouses&&r.data.rels.spouses.length>0){const n="M"===r.data.data.gender?-1:1;r.x+=r.data.rels.spouses.length/2*e*n,r.data.rels.spouses.forEach(((i,a)=>{const s={data:d.find((t=>t.id===i)),added:!0};s.x=r.x-e*(a+1)*n,s.y=r.y,s.sx=a>0?s.x:s.x+e/2*n,s.sy=a>0?s.y:s.y+e/2*n,s.depth=r.depth,s.spouse=r,r.spouses||(r.spouses=[]),r.spouses.push(s),t.push(s)}))}if(r.parents&&2===r.parents.length){const t=r.parents[0],n=r.parents[1],i=t.x-(t.x-n.x)/2,a=(t,n)=>i+e/2*(t.x<n.x?1:-1);n.x=a(t,n),t.x=a(n,t)}}}({tree:p,node_separation:i}),function({tree:t}){function e(e){return e?t.find((t=>t.data.id===e)):null}t.forEach((t=>{if(t.is_ancestry)return;if(0===t.depth)return;if(t.added)return;const n=e(t.data.rels.mother),r=e(t.data.rels.father);if(n&&r){n.added||r.added||console.error("no added spouse",n,r);i(t,n.added?n:r)}else if(n||r){const e=n||r;e.sx=e.x,e.sy=e.y,i(t,e)}function i(t,e){t.psx=o?e.y:e.sx,t.psy=o?e.sx:e.y}}))}({tree:p}),function({tree:t}){t.forEach((t=>{if(t.y*=t.is_ancestry?-1:1,o){const e=t.x;t.x=t.y,t.y=e}}))}({tree:p}),p.forEach((t=>t.all_rels_displayed=_(t,p)));const y=function(e,n,r){o&&([n,r]=[r,n]);const i=t.extent(e,(t=>t.x)),a=t.extent(e,(t=>t.y));return{width:i[1]-i[0]+n,height:a[1]-a[0]+r,x_off:-i[0]+n/2,y_off:-a[0]+r/2}}(p,i,a);return{data:p,data_stash:d,dim:y,main_id:l.id,is_horizontal:o};function g(e,n,r){const s="children"===n?function(t){return[...t.rels.children||[]].map((t=>d.find((e=>e.id===t))))}:function(t){return[t.rels.father,t.rels.mother].filter((t=>t)).map((t=>d.find((e=>e.id===t))))},o=t.tree().nodeSize([i,a]).separation((function(t,e){let n=1;r||(c(t,e)||(n+=.25),function(t,e){return h(t)||h(e)}(t,e)&&(n+=function(t,e){return.5*((t.data.rels.spouses||[]).length+(e.data.rels.spouses||[]).length)}(t,e)),c(t,e)&&!function(t,e){return t.data.rels.father===e.data.rels.father&&t.data.rels.mother===e.data.rels.mother}(t,e)&&(n+=.125));return n})),l=t.hierarchy(e,s);return o(l),l.descendants();function c(t,e){return t.parent==e.parent}function h(t){return t.data.rels.spouses&&t.data.rels.spouses.length>0}}}function y({t:e,svg:n,transition_time:r=2e3}){const i=n.__zoomObj?n:n.parentNode,a=i.__zoomObj;t.select(i).transition().duration(r||0).delay(r?100:0).call(a.transform,t.zoomIdentity.scale(e.k).translate(e.x,e.y))}function g({svg:t,svg_dim:e,tree_dim:n,with_transition:r,transition_time:i}){y({t:v(e,n),svg:t,with_transition:r,transition_time:i})}function v(t,e){let n=Math.min(t.width/e.width,t.height/e.height);n>1&&(n=1);return{k:n,x:e.x_off+(t.width-e.width*n)/n/2,y:e.y_off+(t.height-e.height*n)/n/2}}function x({datum:t,svg:e,svg_dim:n,scale:r,transition_time:i}){const a=r||1;y({t:{k:a,x:(n.width/2-t.x*a)/a,y:(n.height/2-t.y)/a},svg:e,with_transition:!0,transition_time:i})}function b({d:t,tree:e,is_horizontal:n=!1}){const r=[];return t.data.rels.spouses&&t.data.rels.spouses.length>0&&function({d:t}){t.data.rels.spouses.forEach((n=>{const i=d(t,e,(t=>t.data.id===n));i&&!t.spouse&&r.push({d:[[t.x,t.y],[i.x,i.y]],_d:()=>[t.is_ancestry?[a(t,"x")-1e-4,a(t,"y")]:[t.x,t.y],t.is_ancestry?[a(i,"x"),a(i,"y")]:[t.x-1e-4,t.y]],curve:!1,id:o(t,i),depth:t.depth,spouse:!0,is_ancestry:i.is_ancestry,source:t,target:i})}))}({d:t}),function({d:t}){if(!t.parents)return;const e=t.parents[0],n=t.parents[1]||e,a={x:i(e,n,"x"),y:i(e,n,"y")};r.push({d:s(t,a),_d:()=>s({x:t.x,y:t.y},{x:t.x,y:t.y}),curve:!0,id:o(t,e,n),depth:t.depth+1,is_ancestry:!0,source:t,target:[e,n]})}({d:t}),function({d:t}){if(!t.children||0===t.children.length)return;t.children.forEach(((i,l)=>{const c=function(t,e,n){return d(e,n,(n=>n.data.id!==e.data.id&&(n.data.id===t.data.rels.mother||n.data.id===t.data.rels.father)))}(i,t,e)||t,h=c.sx,u=n?{x:t.x,y:h}:{x:h,y:t.y};r.push({d:s(i,u),_d:()=>s(u,{x:a(u,"x"),y:a(u,"y")}),curve:!0,id:o(i,t,c),depth:t.depth+1,is_ancestry:!1,source:[t,c],target:i})}))}({d:t}),r;function i(t,e,n,r){return r?a(t,n)-(a(t,n)-a(e,n))/2:t[n]-(t[n]-e[n])/2}function a(t,e){return t.hasOwnProperty("_"+e)?t["_"+e]:t[e]}function s(t,e){return n?function(t,e){const n=t.x+(e.x-t.x)/2;return[[t.x,t.y],[n,t.y],[n,t.y],[n,e.y],[n,e.y],[e.x,e.y]]}(t,e):function(t,e){const n=t.y+(e.y-t.y)/2;return[[t.x,t.y],[t.x,n],[t.x,n],[e.x,n],[e.x,n],[e.x,e.y]]}(t,e)}function o(...t){return t.map((t=>t.data.id)).sort().join(", ")}function d(t,e,n){const r=e.filter(n),i=(t,e)=>Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));return r.length>1?r.sort(((e,n)=>i(e,t)-i(n,t)))[0]:r[0]}}function C(e,n){const r=t.line().curve(t.curveMonotoneY),i=t.line().curve(t.curveBasis),a=n?e._d():e.d;return e.curve?!0===e.curve?i(a):void 0:r(a)}function w(e,n){const r=t.select(e).selectAll("div.card_cont_2fake").data(n,(t=>t.data.id)),i=r.exit(),a=r.enter().append("div").attr("class","card_cont_2fake").style("display","none").attr("data-id",(()=>Math.random())),s=a.merge(r);i.each((function(e){e.unique_id=t.select(this).attr("data-id"),t.select(this).remove()})),a.each((function(e){e.unique_id=t.select(this).attr("data-id")})),s.each((function(e){e.unique_id=t.select(this).attr("data-id")}))}function $(e){t.select(e()).append("div").attr("class","cards_view_fake").style("display","none")}function M(e){return t.select(e()).select("div.cards_view_fake").node()}var k=Object.freeze({__proto__:null,assignUniqueIdToTreeData:w,setupHtmlSvg:$,getCardsViewFake:M,onZoomSetup:function(e,n){return function(r){const i=r.transform;t.select(e()).style("transform",`translate(${i.x}px, ${i.y}px) scale(${i.k}) `),t.select(n()).style("transform",`translate(${i.x}px, ${i.y}px) scale(${i.k}) `)}},setupReactiveTreeData:function(t){let e=[];return function(n){const r=function(t,e){return e.length>0?e.filter((e=>!t.find((t=>t.data.id===e.data.id)))):[]}(n,e);return e=[...n,...r],w(M(t),e),e}},createHtmlSvg:function(e){const n=t.select(e).select("#f3Canvas").append("div").attr("id","htmlSvg").attr("style","position: absolute; width: 100%; height: 100%; z-index: 2; top: 0; left: 0");return n.append("div").attr("class","cards_view").style("transform-origin","0 0"),$((()=>n.node())),n.node()},getUniqueId:function(t){return t.unique_id}});function S(t,e,n){const r=.4*n,i=Math.max(...t.data.map((t=>t.is_ancestry?t.depth:0)));let a=e.depth*r;return 0===e.depth&&!e.spouse||e.is_ancestry||(a+=i*r,e.spouse&&(a+=r),a+=e.depth*r),a}function L(t,{d:e}){var n,i;return n=t.getTree().data,i=!1,n.forEach((t=>{t.data.hide_rels=i,r(t,i)})),t.updateMainId(e.data.id),t.updateTree({tree_position:t.state.tree_fit_on_change}),!0}function I(t,{d:e,cardEditForm:n}){const r=e.data;n({datum:r,postSubmit:e=>{r.to_add&&a(r,t.getData()),e&&e.delete&&(r.main&&t.updateMainId(null),o(r,t.getData())),t.updateTree()},store:t})}function A(t,{d:e}){e.data.hide_rels=!e.data.hide_rels,r(e,e.data.hide_rels),t.updateTree({tree_position:t.state.tree_fit_on_change})}function H(){return`\n <g data-icon="user">\n ${X()}\n <path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z" />\n </g>\n `}function D(){return`\n <g data-icon="user-edit">\n ${X()}\n <path d="M21.7,13.35L20.7,14.35L18.65,12.3L19.65,11.3C19.86,11.09 20.21,11.09 20.42,11.3L21.7,12.58C21.91,\n 12.79 21.91,13.14 21.7,13.35M12,18.94L18.06,12.88L20.11,14.93L14.06,21H12V18.94M12,14C7.58,14 4,15.79 4,\n 18V20H10V18.11L14,14.11C13.34,14.03 12.67,14 12,14M12,4A4,4 0 0,0 8,8A4,4 0 0,0 12,12A4,4 0 0,0 16,8A4,4 0 0,0 12,4Z" />\n </g>\n `}function T(){return`\n <g data-icon="user-plus">\n ${X()}\n <path d="M15,14C12.33,14 7,15.33 7,18V20H23V18C23,15.33 17.67,14 15,14M6,10V7H4V10H1V12H4V15H6V12H9V10M15,12A4,4 0 0,0 19,8A4,4 0 0,0 15,4A4,4 0 0,0 11,8A4,4 0 0,0 15,12Z" />\n </g>\n `}function E(){return`\n <g data-icon="user-plus-close">\n ${X()}\n <path d="M15,14C12.33,14 7,15.33 7,18V20H23V18C23,15.33 17.67,14 15,14M6,10V7H4V10H1V12H4V15H6V12H9V10M15,12A4,4 0 0,0 19,8A4,4 0 0,0 15,4A4,4 0 0,0 11,8A4,4 0 0,0 15,12Z" />\n <line x1="3" y1="3" x2="24" y2="24" stroke="currentColor" stroke-width="2" />\n </g>\n `}function R(){return`\n <g data-icon="plus">\n ${X()}\n <path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />\n </g>\n `}function F(){return`\n <g data-icon="pencil">\n ${X()}\n <path d="M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z" />\n </g>\n `}function z(){return`\n <g data-icon="pencil-off">\n ${X()}\n <path d="M18.66,2C18.4,2 18.16,2.09 17.97,2.28L16.13,4.13L19.88,7.88L21.72,6.03C22.11,5.64 22.11,5 21.72,4.63L19.38,2.28C19.18,2.09 18.91,2 18.66,2M3.28,4L2,5.28L8.5,11.75L4,16.25V20H7.75L12.25,15.5L18.72,22L20,20.72L13.5,14.25L9.75,10.5L3.28,4M15.06,5.19L11.03,9.22L14.78,12.97L18.81,8.94L15.06,5.19Z" />\n </g>\n `}function O(){return`\n <g data-icon="trash">\n ${X()}\n <path d="M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19M8,9H16V19H8V9M15.5,4L14.5,3H9.5L8.5,4H5V6H19V4H15.5Z" />\n </g>\n `}function V(){return`\n <g data-icon="history-back">\n ${X()}\n <path d="M20 13.5C20 17.09 17.09 20 13.5 20H6V18H13.5C16 18 18 16 18 13.5S16 9 13.5 9H7.83L10.91 12.09L9.5 13.5L4 8L9.5 2.5L10.92 3.91L7.83 7H13.5C17.09 7 20 9.91 20 13.5Z" />\n </g>\n `}function P(){return`\n <g data-icon="history-forward">\n ${X()}\n <path d="M10.5 18H18V20H10.5C6.91 20 4 17.09 4 13.5S6.91 7 10.5 7H16.17L13.08 3.91L14.5 2.5L20 8L14.5 13.5L13.09 12.09L16.17 9H10.5C8 9 6 11 6 13.5S8 18 10.5 18Z" />\n </g>\n `}function U(){return'\n <g data-icon="person">\n <path d="M256 288c79.5 0 144-64.5 144-144S335.5 0 256 0 112 \n 64.5 112 144s64.5 144 144 144zm128 32h-55.1c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16H128C57.3 320 0 377.3 \n 0 448v16c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-16c0-70.7-57.3-128-128-128z" />\n </g>\n '}function q(){return'\n <g transform="translate(31,25)" data-icon="mini-tree">\n <rect x="-31" y="-25" width="72" height="15" fill="rgba(0,0,0,0)"></rect>\n <g>\n <rect x="-31" y="-25" width="72" height="15" fill="rgba(0,0,0,0)"></rect>\n <line y2="-17.5" stroke="#fff" />\n <line x1="-20" x2="20" y1="-17.5" y2="-17.5" stroke="#fff" />\n <rect x="-31" y="-25" width="25" height="15" rx="5" ry="5" class="card-male" />\n <rect x="6" y="-25" width="25" height="15" rx="5" ry="5" class="card-female" />\n </g>\n </g>\n '}function j(){return K(T())}function N(){return K(E())}function B(){return K(R())}function J(){return K(F())}function Z(){return K(z())}function W(){return K(V())}function G(){return K(P())}function Q(){return K('\n <g data-icon="person">\n <path d="M256 288c79.5 0 144-64.5 144-144S335.5 0 256 0 112 \n 64.5 112 144s64.5 144 144 144zm128 32h-55.1c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16H128C57.3 320 0 377.3 \n 0 448v16c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-16c0-70.7-57.3-128-128-128z" />\n </g>\n ',"0 0 512 512")}function Y(){return K('\n <g transform="translate(31,25)" data-icon="mini-tree">\n <rect x="-31" y="-25" width="72" height="15" fill="rgba(0,0,0,0)"></rect>\n <g>\n <rect x="-31" y="-25" width="72" height="15" fill="rgba(0,0,0,0)"></rect>\n <line y2="-17.5" stroke="#fff" />\n <line x1="-20" x2="20" y1="-17.5" y2="-17.5" stroke="#fff" />\n <rect x="-31" y="-25" width="25" height="15" rx="5" ry="5" class="card-male" />\n <rect x="6" y="-25" width="25" height="15" rx="5" ry="5" class="card-female" />\n </g>\n </g>\n ',"0 0 72 25")}function K(t,e="0 0 24 24"){const n=t.match(/data-icon="([^"]+)"/);return`\n <svg xmlns="http://www.w3.org/2000/svg" viewBox="${e}" style="fill: currentColor" ${n?`data-icon="${n[1]}"`:""}>\n ${t}\n </svg>\n `}function X(){return'\n <circle r="12" cx="12" cy="12" style="fill: rgba(0,0,0,0)" />\n '}var tt=Object.freeze({__proto__:null,userIcon:H,userEditIcon:D,userPlusIcon:T,userPlusCloseIcon:E,plusIcon:R,pencilIcon:F,pencilOffIcon:z,trashIcon:O,historyBackIcon:V,historyForwardIcon:P,personIcon:U,miniTreeIcon:q,userSvgIcon:function(){return K(H())},userEditSvgIcon:function(){return K(D())},userPlusSvgIcon:j,userPlusCloseSvgIcon:N,plusSvgIcon:B,pencilSvgIcon:J,pencilOffSvgIcon:Z,trashSvgIcon:function(){return K(O())},historyBackSvgIcon:W,historyForwardSvgIcon:G,personSvgIcon:Q,miniTreeSvgIcon:Y});var et=Object.freeze({__proto__:null,manualZoom:function({amount:e,svg:n,transition_time:r=500}){const i=n.__zoomObj;t.select(n).transition().duration(r||0).delay(r?100:0).call(i.scaleBy,e)},isAllRelativeDisplayed:_,cardChangeMain:L,cardEdit:I,cardShowHideRels:A,handleRelsOfNewDatum:l,handleNewRel:c,createNewPerson:h,createNewPersonWithGenderFromRel:u,addNewPerson:p,createTreeDataWithMainNode:f,addNewPersonAndHandleRels:function({datum:t,data_stash:e,rel_type:n,rel_datum:r}){p({data_stash:e,datum:t}),l({datum:t,data_stash:e,rel_type:n,rel_datum:r})},checkIfRelativesConnectedWithoutPerson:i,createForm:function({datum:t,store:e,fields:n,postSubmit:r,addRelative:a,deletePerson:s,onCancel:o,editFirst:d}){const l={fields:[],onSubmit:function(e){e.preventDefault();new FormData(e.target).forEach(((e,n)=>t.data[n]=e)),t.to_add&&delete t.to_add;r()}};return t._new_rel_data||(l.onDelete=function(){s(),r({delete:!0})},l.addRelative=()=>a.activate(t),l.addRelativeCancel=()=>a.onCancel(),l.addRelativeActive=a.is_active,l.editable=!1),t._new_rel_data&&(l.title=t._new_rel_data.label,l.new_rel=!0,l.editable=!0,l.onCancel=o),l.onDelete&&(l.can_delete=i(t,e.getData())),d&&(l.editable=!0),l.gender_field={id:"gender",type:"switch",label:"Gender",initial_value:t.data.gender,options:[{value:"M",label:"Male"},{value:"F",label:"Female"}]},n.forEach((e=>{const n={id:e.id,type:e.type,label:e.label,initial_value:t.data[e.id]};l.fields.push(n)})),l},moveToAddToAdded:a,removeToAdd:s,deletePerson:o,cleanupDataJson:d,removeToAddFromData:function(t){return t.forEach((e=>e.to_add?s(e,t):e)),t},formInfoSetup:function(t,e){const n=document.createElement("div");return r(),n;function r(){const i=function(t){return` \n <form id="familyForm" class="f3-form ${t.editable?"":"non-editable"}">\n ${o()}\n ${t.title?`<h3 class="f3-form-title">${t.title}</h3>`:""}\n <div style="text-align: right; display: ${t.new_rel?"none":"block"}">\n ${t.addRelative&&!t.no_edit?n():""}\n ${t.no_edit?d():r()}\n </div>\n ${i()}\n\n ${a()}\n\n ${t.other_parent_field?s():""}\n\n ${t.onDelete?e():""}\n \n <div class="f3-form-buttons">\n <button type="button" class="f3-cancel-btn">Cancel</button>\n <button type="submit">Submit</button>\n </div>\n </form>\n `;function e(){return`\n <div>\n <button type="button" class="f3-delete-btn" ${t.can_delete?"":"disabled"}>\n Delete\n </button>\n </div>\n `}function n(){return`\n <span class="f3-add-relative-btn">\n ${t.addRelativeActive?N():j()}\n </span>\n `}function r(){return`\n <span class="f3-edit-btn">\n ${t.editable?Z():J()}\n </span>\n `}function i(){return t.editable?`\n <div class="f3-radio-group">\n ${t.gender_field.options.map((e=>`\n <label>\n <input type="radio" name="${t.gender_field.id}" \n value="${e.value}" \n ${e.value===t.gender_field.initial_value?"checked":""}\n >\n ${e.label}\n </label>\n `)).join("")}\n </div>\n `:""}function a(){return t.editable?t.fields.map((t=>`\n ${"text"===t.type?`\n <div class="f3-form-field">\n <label>${t.label}</label>\n <input type="${t.type}" \n name="${t.id}" \n value="${t.initial_value||""}"\n placeholder="${t.label}">\n </div>\n `:"textarea"===t.type?`\n <div class="f3-form-field">\n <label>${t.label}</label>\n <textarea name="${t.id}" \n placeholder="${t.label}">${t.initial_value||""}</textarea>\n </div>\n `:""}\n `)).join(""):e();function e(){return t.fields.map((t=>`\n <div class="f3-info-field">\n <span class="f3-info-field-label">${t.label}</span>\n <span class="f3-info-field-value">${t.initial_value||""}</span>\n </div>\n `)).join("")}}function s(){return`\n <div class="f3-form-field">\n <label>${t.other_parent_field.label}</label>\n <select name="${t.other_parent_field.id}">\n ${t.other_parent_field.options.map((e=>`\n <option value="${e.value}" \n ${e.value===t.other_parent_field.initial_value?"selected":""}>\n ${e.label}\n </option>\n `)).join("")}\n </select>\n </div>\n `}function o(){return'\n <span class="f3-close-btn">\n ×\n </span>\n '}function d(){return'<div style="height: 24px;"></div>'}}(t);return n.innerHTML=i,function(){const i=n.querySelector("form");i.addEventListener("submit",t.onSubmit);const a=i.querySelector(".f3-cancel-btn");a.addEventListener("click",l);const s=i.querySelector(".f3-edit-btn");s&&s.addEventListener("click",c);const o=i.querySelector(".f3-delete-btn");o&&t.onDelete&&o.addEventListener("click",t.onDelete);const d=i.querySelector(".f3-add-relative-btn");d&&t.addRelative&&d.addEventListener("click",(()=>{t.addRelativeActive?t.addRelativeCancel():t.addRelative(),t.addRelativeActive=!t.addRelativeActive,r()}));i.querySelector(".f3-close-btn").addEventListener("click",e),t.other_parent_field&&(a.style.display="none");function l(){t.editable=!1,t.onCancel&&t.onCancel(),r()}function c(){t.editable=!t.editable,r()}}(),n}},createHistory:function(t,e,n){let r=[],i=-1;return{changed:function(){i<r.length-1&&(r=r.slice(0,i));const n=JSON.parse(d(JSON.stringify(e())));n.main_id=t.getMainId(),r.push(n),i++},back:function(){if(!s())return;i--,o(r[i])},forward:function(){if(!a())return;i++,o(r[i])},canForward:a,canBack:s};function a(){return i<r.length-1}function s(){return i>0}function o(e){t.updateMainId(e.main_id),t.updateData(e),n()}},createHistoryControls:function(e,n,r=(()=>{})){const i=t.select(e).append("div").attr("class","f3-history-controls"),a=i.append("button").attr("class","f3-back-button").on("click",(()=>{n.back(),o(),r()})),s=i.append("button").attr("class","f3-forward-button").on("click",(()=>{n.forward(),o(),r()}));return a.html(W()),s.html(G()),{back_btn:a.node(),forward_btn:s.node(),updateButtons:o,destroy:function(){n=null,t.select(e).select(".f3-history-controls").remove()}};function o(){a.classed("disabled",!n.canBack()),s.classed("disabled",!n.canForward()),i.style("display",n.canBack()||n.canForward()?null:"none")}},treeFit:g,calculateTreeFit:v,cardToMiddle:x});function nt({d:t,card_dim:e,card_display:n}){return{template:`\n <g>\n <g class="card-text" clip-path="url(#card_text_clip)">\n <g transform="translate(${e.text_x}, ${e.text_y})">\n <text>\n ${Array.isArray(n)?n.map((e=>`<tspan x="0" dy="14">${e(t.data)}</tspan>`)).join("\n"):n(t.data)}\n </text>\n </g>\n </g>\n <rect width="${e.w-10}" height="${e.h}" style="mask: url(#fade)" class="text-overflow-mask" /> \n </g>\n `}}function rt({x:t,y:e,rt:n,closed:r}){return{template:`\n <g style="\n transform: translate(-12.2px, -.5px);\n cursor: pointer;\n " \n fill="currentColor" class="card_break_link${r?" closed":""}"\n >\n <g style="transform: translate(${t}px,${e}px)scale(.02)rotate(${n+"deg"})">\n <rect width="1000" height="700" y="150" style="opacity: 0" />\n <g class="link_upper">\n <g>\n <path d="M616.3,426.4c19,4.5,38.1-7.4,42.6-26.4c4.4-19-7.4-38-26.5-42.5L522.5,332c-18,11.1-53.9,33.4-53.9,33.4l80.4,18.6c-7.8,4.9-19.5,12.1-31.3,19.4L616.3,426.4L616.3,426.4z"/>\n <path d="M727.4,244.2c-50.2-11.6-100.3,3.3-135.7,35.4c28.6,22.6,64.5,30.2,116.4,51.3l141,32.6c23.9,5.6,56.6,47.2,51.1,71l-4.1,17c-5.6,23.7-47.3,56.4-71.2,51l-143.4-33.2c-66.8-8.6-104.1-16.6-132.9-7.5c17.4,44.9,55.9,80.8,106.5,92.4L800.9,588c81.3,18.8,162.3-31.5,181.2-112.4l4-17c18.8-81.1-31.7-161.8-112.9-180.6L727.4,244.2z"/>\n </g>\n </g>\n <g class="link_lower">\n <path d="M421.2,384.9l-128,127.6c-13.9,13.8-13.9,36.2,0,50s36.3,13.8,50.2,0.1l136.2-135.8v-36.7l-58.4,58.1V384.9L421.2,384.9z"/>\n <path d="M204.6,742.8c-17.4,17.3-63.3,17.2-80.6,0.1l-12.3-12.3c-17.3-17.3,0.6-81.2,17.9-98.5l100.2-99.9c12.5-14.9,45.8-40.8,66.1-103.7c-47.7-9.4-98.9,4.2-135.8,40.9L54.2,575c-58.9,58.8-58.9,154,0,212.8L66.6,800c58.9,58.8,154.5,58.8,213.4,0l105.8-105.6c38.4-38.3,51.3-91.9,39.7-141c-44,22.7-89,62.3-116,84.8L204.6,742.8z"/>\n </g>\n <g class="link_particles">\n <path d="M351.9,248.4l-26.5,63.4l80.6,30.1L351.9,248.4z"/>\n <path d="M529.3,208l-43,26.6l35.4,52.3L529.3,208z"/>\n <path d="M426.6,158.8l-44-2.9l61.7,134.6L426.6,158.8z"/>\n </g>\n </g>\n </g>\n `}}const it={miniTree:function(e,n){if(e.data.to_add)return;const r=n.card_dim;if(e.all_rels_displayed)return;const i=t.create("svg:g").html(function({d:t,card_dim:e}){return{template:`\n <g class="card_family_tree" style="cursor: pointer">\n <rect x="-31" y="-25" width="72" height="15" fill="rgba(0,0,0,0)"></rect>\n <g transform="translate(${.8*e.w},6)scale(.9)">\n <rect x="-31" y="-25" width="72" height="15" fill="rgba(0,0,0,0)"></rect>\n <line y2="-17.5" stroke="#fff" />\n <line x1="-20" x2="20" y1="-17.5" y2="-17.5" stroke="#fff" />\n <rect x="-31" y="-25" width="25" height="15" rx="5" ry="5" class="card-male" />\n <rect x="6" y="-25" width="25" height="15" rx="5" ry="5" class="card-female" />\n </g>\n </g>\n `}}({d:e,card_dim:r}).template);return i.on("click",(function(t){t.stopPropagation(),n.onMiniTreeClick?n.onMiniTreeClick.call(this,t,e):L(n.store,{d:e})})),i.node()},lineBreak:function(e,n){if(e.data.to_add)return;const r=n.card_dim,i=t.create("svg:g").html(function({d:t,card_dim:e}){let n="",r=t.data.rels,i=t.data._rels||{},a=t.data.hide_rels,s=t=>t.father||t.mother,o=t=>t.children&&t.children.length>0;if((t.is_ancestry||t.data.main)&&(s(r)||s(i))&&(n+=rt({x:e.w/2,y:0,rt:-45,closed:a}).template),!t.is_ancestry&&t.added){const s=t.spouse,d=s.data.rels,l=s.data._rels||{};(o(r)||o(i))&&(o(d)||o(l))&&(n+=rt({x:t.sx-t.x+e.w/2+24.4,y:(t.x!==t.sx?e.h/2:e.h)+1,rt:135,closed:a}).template)}return{template:n}}({d:e,card_dim:r}).template);return i.on("click",(t=>{t.stopPropagation(),A(n.store,{d:e})})),i.node()},cardBody:function(e,n){const r=n.cardEditForm?"ADD":"UNKNOWN",i=n.card_dim;let a;e.data.to_add?(a=t.create("svg:g").html(function({d:t,card_dim:e,card_add:n,label:r}){return{template:`\n <g class="card-body ${n?"card_add":"card-unknown"}">\n <rect class="card-body-rect" width="${e.w}" height="${e.h}" fill="rgb(59, 85, 96)" />\n <text transform="translate(${e.w/2}, ${e.h/2})" text-anchor="middle" fill="#fff">\n <tspan font-size="18" dy="8">${r}</tspan>\n </text>\n </g>\n `}}({d:e,card_dim:i,card_add:n.cardEditForm,label:r}).template),a.on("click",(t=>{t.stopPropagation(),I(n.store,{d:e,cardEditForm:n.cardEditForm})}))):(a=t.create("svg:g").html(function({d:t,card_dim:e,card_display:n}){return{template:`\n <g class="card-body">\n <rect width="${e.w}" height="${e.h}" class="card-body-rect" />\n ${nt({d:t,card_dim:e,card_display:n}).template}\n </g>\n `}}({d:e,card_dim:i,card_display:n.card_display}).template),a.on("click",(function(t){t.stopPropagation(),n.onCardClick?n.onCardClick.call(this,t,e):L(n.store,{d:e})})));return a.node()},cardImage:function(e,n){if(e.data.to_add)return;const r=n.card_dim;return t.create("svg:g").html(function({d:t,image:e,card_dim:n,maleIcon:r,femaleIcon:i}){return{template:`\n <g style="transform: translate(${n.img_x}px,${n.img_y}px);" class="card_image" clip-path="url(#card_image_clip)">\n ${e?`<image href="${e}" height="${n.img_h}" width="${n.img_w}" preserveAspectRatio="xMidYMin slice" />`:"F"===t.data.data.gender&&i?i({card_dim:n}):"M"===t.data.data.gender&&r?r({card_dim:n}):`\n <g class="genderless-icon">\n <rect height="${n.img_h}" width="${n.img_w}" fill="rgb(59, 85, 96)" />\n <g transform="scale(${.001616*n.img_w})">\n <path transform="translate(50,40)" fill="lightgrey" d="M256 288c79.5 0 144-64.5 144-144S335.5 0 256 0 112 \n 64.5 112 144s64.5 144 144 144zm128 32h-55.1c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16H128C57.3 320 0 377.3 \n 0 448v16c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48v-16c0-70.7-57.3-128-128-128z" />\n </g>\n </g>\n `} \n </g>\n `}}({d:e,image:e.data.data.avatar||null,card_dim:r,maleIcon:null,femaleIcon:null}).template).node()},cardEdit:function(e,n){if(e.data.to_add)return;const r=n.card_dim,i=t.create("svg:g").html(function({d:t,card_dim:e,x:n,y:r}){return{template:`\n <g transform="translate(${n||e.w-20},${r||e.h-20})scale(.6)" style="cursor: pointer" class="card_edit pencil_icon">\n <circle fill="rgba(0,0,0,0)" r="17" cx="8.5" cy="8.5" />\n <path fill="currentColor" transform="translate(-1.5, -1.5)"\n d="M19.082,2.123L17.749,0.79c-1.052-1.052-2.766-1.054-3.819,0L1.925,12.794c-0.06,0.06-0.104,0.135-0.127,0.216\n l-1.778,6.224c-0.05,0.175-0.001,0.363,0.127,0.491c0.095,0.095,0.223,0.146,0.354,0.146c0.046,0,0.092-0.006,0.137-0.02\n l6.224-1.778c0.082-0.023,0.156-0.066,0.216-0.127L19.082,5.942C20.134,4.89,20.134,3.176,19.082,2.123z M3.076,13.057l9.428-9.428\n l3.738,3.739l-9.428,9.428L3.076,13.057z M2.566,13.961l3.345,3.344l-4.683,1.339L2.566,13.961z M18.375,5.235L16.95,6.66\n l-3.738-3.739l1.425-1.425c0.664-0.663,1.741-0.664,2.405,0l1.333,1.333C19.038,3.493,19.038,4.572,18.375,5.235z"/>\n </g>\n `}}({card_dim:r,x:r.w-46,y:r.h-20}).template);return i.on("click",(t=>{t.stopPropagation(),I(n.store,{d:e,cardEditForm:n.cardEditForm})})),i.node()},cardAdd:function(e,n){if(e.data.to_add)return;const r=n.card_dim,i=t.create("svg:g").html(function({d:t,card_dim:e,x:n,y:r}){return{template:`\n <g class="card_add_relative">\n <g transform="translate(${n||e.w/2},${r||e.h})scale(.13)">\n <circle r="80" cx="40" cy="40" fill="rgba(0,0,0,0)" />\n <g transform="translate(-10, -8)">\n <line\n x1="10" x2="90" y1="50" y2="50"\n stroke="currentColor" stroke-width="15" stroke-linecap="round"\n />\n <line\n x1="50" x2="50" y1="10" y2="90"\n stroke="currentColor" stroke-width="15" stroke-linecap="round"\n />\n </g>\n </g>\n </g>\n `}}({card_dim:r,x:r.w-26,y:r.h-20}).template);return i.on("click",(t=>{t.stopPropagation(),n.addRelative({d:e})})),i.node()}};function at(t,e,n){t&&(n?e.insertBefore(t,e.firstChild):e.appendChild(t))}function st(t,e){function n(t,e,n){const{w:r,h:i}=t,a=e,s=n||[],o=t=>s.includes(t);return`${o("lx")?"M0,0":`M0,${a} Q 0,0 5,0`} ${o("rx")?`H${r}`:`H${r-a} Q ${r},0 ${r},5`} ${o("ry")?`V${i}`:`V${i-a} Q ${r},${i} ${r-a},${i}`} ${o("ly")?"H0":`H${a} Q 0,${i} 0,${i-a}`} z`}t.querySelector("defs#f3CardDef")||t.insertAdjacentHTML("afterbegin",`\n <defs id="f3CardDef">\n <linearGradient id="fadeGrad">\n <stop offset="0.9" stop-color="white" stop-opacity="0"/>\n <stop offset=".91" stop-color="white" stop-opacity=".5"/>\n <stop offset="1" stop-color="white" stop-opacity="1"/>\n </linearGradient>\n <mask id="fade" maskContentUnits="objectBoundingBox"><rect width="1" height="1" fill="url(#fadeGrad)"/></mask>\n <clipPath id="card_clip"><path d="${n({w:e.w,h:e.h},5)}"></clipPath>\n <clipPath id="card_text_clip"><rect width="${e.w-10}" height="${e.h}"></rect></clipPath>\n <clipPath id="card_image_clip"><path d="M0,0 Q 0,0 0,0 H${e.img_w} V${e.img_h} H0 Q 0,${e.img_h} 0,${e.img_h} z"></clipPath>\n <clipPath id="card_image_clip_curved"><path d="${n({w:e.img_w,h:e.img_h},5,["rx","ry"])}"></clipPath>\n </defs>\n `)}var ot=Object.freeze({__proto__:null,appendElement:at,Card:function(e){return st((e=function(t){const e={img:!0,mini_tree:!0,link_break:!1,card_dim:{w:220,h:70,text_x:75,text_y:15,img_w:60,img_h:60,img_x:5,img_y:5}};t||(t={});for(const n in e)void 0===t[n]&&(t[n]=e[n]);return t}(e)).svg,e.card_dim),function(n){const r="M"===n.data.data.gender?"card-male":"F"===n.data.data.gender?"card-female":"card-genderless",i=e.card_dim,a=t.create("svg:g").attr("class",`card ${r}`).attr("transform",`translate(${[-i.w/2,-i.h/2]})`);a.append("g").attr("class","card-inner").attr("clip-path","url(#card_clip)"),this.innerHTML="",this.appendChild(a.node()),function(t,e,n){const r=document.createElementNS("http://www.w3.org/2000/svg","g");r.innerHTML=t,n?e.insertBefore(r,e.firstChild):e.appendChild(r)}(function({d:t,card_dim:e,is_new:n}){return{template:`\n <rect width="${e.w}" height="${e.h}" rx="4" ry="4" class="card-outline ${t.data.main&&!n?"card-main-outline":""} ${n?"card-new-outline":""}" />\n `}}({d:n,card_dim:i,is_new:n.data.to_add}).template,a.node(),!0),at(it.cardBody(n,e),this.querySelector(".card-inner")),e.img&&at(it.cardImage(n,e),this.querySelector(".card")),e.mini_tree&&at(it.miniTree(n,e),this.querySelector(".card"),!0),e.link_break&&at(it.lineBreak(n,e),this.querySelector(".card")),e.cardEditForm&&(at(it.cardEdit(n,e),this.querySelector(".card-inner")),at(it.cardAdd(n,e),this.querySelector(".card-inner"))),e.onCardUpdates&&e.onCardUpdates.map((t=>t.call(this,n))),e.onCardUpdate&&e.onCardUpdate.call(this,n)}},CardHtml:function(e){const n="default"===e.style?a:"imageCircleRect"===e.style?function(t){return t.data.data.avatar?s(t):o(t)}:"imageCircle"===e.style?s:"imageRect"===e.style?function(t){return r(t)}:"rect"===e.style?o:a;return function(r){this.innerHTML=`\n <div class="card ${function(t){const e=[];"M"===t.data.data.gender?e.push("card-male"):"F"===t.data.data.gender?e.push("card-female"):e.push("card-genderless");t.data.main&&e.push("card-main");t.data._new_rel_data&&e.push("card-new-rel");t.data.to_add&&e.push("card-to-add");return e}(r).join(" ")}" data-id="${r.data.id}" style="transform: translate(-50%, -50%); pointer-events: auto;">\n ${e.mini_tree?function(t){return e.mini_tree?t.data.to_add||t.data._new_rel_data||t.all_rels_displayed?"":`<div class="mini-tree">${Y()}</div>`:""}(r):""}\n ${n(r)}\n </div>\n `,this.querySelector(".card").addEventListener("click",(t=>e.onCardClick(t,r))),e.onCardUpdate&&e.onCardUpdate.call(this,r),e.onCardMouseenter&&t.select(this).select(".card").on("mouseenter",(t=>e.onCardMouseenter(t,r))),e.onCardMouseleave&&t.select(this).select(".card").on("mouseleave",(t=>e.onCardMouseleave(t,r)))};function r(t){return`\n <div class="card-inner card-image-rect" ${d()}>\n ${t.data.data.avatar?`<img src="${t.data.data.avatar}" ${l()}>`:c(t)}\n <div class="card-label">${i(t)}</div>\n </div>\n `}function i(t){return t.data._new_rel_data?function(t){const e=[];e.push(`data-rel-type="${t.data._new_rel_data.rel_type}"`),["son","daughter"].includes(t.data._new_rel_data.rel_type)&&e.push(`data-other-parent-id="${t.data._new_rel_data.other_parent_id}"`);return`<div ${e.join(" ")}>${t.data._new_rel_data.label}</div>`}(t):t.data.to_add?`<div>${e.empty_card_label||"ADD"}</div>`:`\n ${e.card_display.map((e=>`<div>${e(t.data)}</div>`)).join("")}\n `}function a(t){return r(t)}function s(t){return function(t){return`\n <div class="card-inner card-image-circle" ${d()}>\n ${t.data.data.avatar?`<img src="${t.data.data.avatar}" ${l()}>`:c(t)}\n <div class="card-label">${i(t)}</div>\n </div>\n `}(t)}function o(t){return function(t){return`\n <div class="card-inner card-rect" ${d()}>\n ${i(t)}\n </div>\n `}(t)}function d(){let t='style="';return e.card_dim.w||e.card_dim.h?(t+=`width: ${e.card_dim.w}px; min-height: ${e.card_dim.h}px;`,e.card_dim.height_auto?t+="height: auto;":t+=`height: ${e.card_dim.h}px;`,t+='"',t):""}function l(){let t='style="position: relative;';return e.card_dim.img_w||e.card_dim.img_h||e.card_dim.img_x||e.card_dim.img_y?(t+=`width: ${e.card_dim.img_w}px; height: ${e.card_dim.img_h}px;`,t+=`left: ${e.card_dim.img_x}px; top: ${e.card_dim.img_y}px;`,t+='"',t):""}function c(t){return t.data._new_rel_data?`<div class="person-icon" ${l()}>${B()}</div>`:`<div class="person-icon" ${l()}>${Q()}</div>`}}});function dt(t,e,n){return this.store=t,this.cancelCallback=e,this.onSubmitCallback=n,this.datum=null,this.onChange=null,this.onCancel=null,this.is_active=!1,this.store_data=null,this.addRelLabels=this.addRelLabelsDefault(),this}function lt(t,e){return this.cont=t,this.store=e,this.fields=[{type:"text",label:"first name",id:"first name"},{type:"text",label:"last name",id:"last name"},{type:"text",label:"birthday",id:"birthday"},{type:"text",label:"avatar",id:"avatar"}],this.form_cont=null,this.is_fixed=!0,this.history=null,this.no_edit=!1,this.onChange=null,this.editFirst=!1,this.init(),this}function ct(t,e){return this.cont=null,this.store=null,this.svg=null,this.getCard=null,this.node_separation=250,this.level_separation=150,this.is_horizontal=!1,this.single_parent_empty_card=!0,this.transition_time=2e3,this.is_card_html=!1,this.beforeUpdate=null,this.afterUpdate=null,this.init(t,e),this}function ht(t){const e=[];return Array.isArray(t)?t.forEach((t=>{"function"==typeof t?e.push(t):"string"==typeof t?e.push((e=>e.data[t])):Array.isArray(t)&&e.push((e=>t.map((t=>e.data[t])).join(" ")))})):"function"==typeof t?e.push(t):"string"==typeof t&&e.push((e=>e.data[t])),e}function ut(...t){return new pt(...t)}function pt(t,e){return this.cont=t,this.store=e,this.svg=null,this.getCard=null,this.card_dim={w:220,h:70,text_x:75,text_y:15,img_w:60,img_h:60,img_x:5,img_y:5},this.card_display=[t=>`${t.data["first name"]} ${t.data["last name"]}`],this.mini_tree=!0,this.link_break=!1,this.onCardClick=this.onCardClickDefault,this.onCardUpdate=null,this.onCardUpdates=null,this.init(),this}function ft(...t){return new _t(...t)}function _t(t,e){return this.cont=t,this.store=e,this.getCard=null,this.card_display=[t=>`${t.data["first name"]} ${t.data["last name"]}`],this.onCardClick=this.onCardClickDefault,this.style="default",this.mini_tree=!1,this.onCardUpdate=null,this.card_dim={},this.init(),this}dt.prototype.activate=function(t){this.is_active&&this.onCancel(),this.is_active=!0;const e=this.store;this.store_data=e.getData(),this.datum=t;const n=function(t,e,n){const r=function(t,e){const n=[t];return Object.keys(t.rels).forEach((e=>{const n=t.rels[e];Array.isArray(n)?n.forEach((t=>{r(e,t)})):r(e,n)})),n;function r(t,r){const i=function(t,e){return JSON.parse(JSON.stringify(t.find((t=>t.id===e))))}(e,r);"father"!==t&&"mother"!==t||(delete i.rels.father,delete i.rels.mother),"children"===t&&(i.rels.children=[],i.rels.spouses=[]),n.push(i)}}(t,e);if(!t.rels.father){const e=h({data:{gender:"M"},rels:{children:[t.id]}});e._new_rel_data={rel_type:"father",label:n.father},t.rels.father=e.id,r.push(e)}if(!t.rels.mother){const e=h({data:{gender:"F"},rels:{children:[t.id]}});e._new_rel_data={rel_type:"mother",label:n.mother},t.rels.mother=e.id,r.push(e)}const i=r.find((e=>e.id===t.rels.mother)),a=r.find((e=>e.id===t.rels.father));i.rels.spouses=[a.id],a.rels.spouses=[i.id],i.rels.children=[t.id],a.rels.children=[t.id],t.rels.spouses||(t.rels.spouses=[]);if(t.rels.children){let e;t.rels.children.forEach((i=>{const a=r.find((t=>t.id===i));a.rels.mother||(e||(e=h({data:{gender:"F"},rels:{spouses:[t.id],children:[]}})),e._new_rel_data={rel_type:"spouse",label:n.spouse},e.rels.children.push(a.id),t.rels.spouses.push(e.id),a.rels.mother=e.id,r.push(e)),a.rels.father||(e||(e=h({data:{gender:"M"},rels:{spouses:[t.id],children:[]}})),e._new_rel_data={rel_type:"spouse",label:n.spouse},e.rels.children.push(a.id),t.rels.spouses.push(e.id),a.rels.father=e.id,r.push(e))}))}const s=h({data:{gender:"F"},rels:{spouses:[t.id]}});s._new_rel_data={rel_type:"spouse",label:n.spouse},t.rels.spouses.push(s.id),r.push(s),t.rels.children||(t.rels.children=[]);return t.rels.spouses.forEach((e=>{const i=r.find((t=>t.id===e));i.rels.children||(i.rels.children=[]),i.rels.children=i.rels.children.filter((e=>t.rels.children.includes(e)));const a=h({data:{gender:"M"},rels:{father:t.id,mother:i.id}});a._new_rel_data={rel_type:"son",label:n.son,other_parent_id:i.id},i.rels.children.push(a.id),t.rels.children.push(a.id),r.push(a);const s=h({data:{gender:"F"},rels:{mother:i.id,father:t.id}});s._new_rel_data={rel_type:"daughter",label:n.daughter,other_parent_id:i.id},i.rels.children.push(s.id),t.rels.children.push(s.id),r.push(s)})),r}(t=JSON.parse(JSON.stringify(this.datum)),this.getStoreData(),this.addRelLabels);e.updateData(n),e.updateTree({}),this.onChange=function(t){if(t?._new_rel_data){const e=t;c({datum:this.datum,new_rel_datum:e,data_stash:this.getStoreData()}),this.onSubmitCallback(this.datum,e)}else t.id===this.datum.id?this.datum.data=t.data:console.error("Something went wrong")}.bind(this),this.onCancel=function(){if(!this.is_active)return;this.is_active=!1,e.updateData(this.getStoreData()),this.cancelCallback(this.datum),this.store_data=null,this.datum=null,this.onChange=null,this.onCancel=null}.bind(this)},dt.prototype.setAddRelLabels=function(t){if("object"==typeof t){for(let e in t)this.addRelLabels[e]=t[e];return this}console.error("add_rel_labels must be an object")},dt.prototype.addRelLabelsDefault=function(){return{father:"Add Father",mother:"Add Mother",spouse:"Add Spouse",son:"Add Son",daughter:"Add Daughter"}},dt.prototype.getStoreData=function(){return this.store_data},lt.prototype.init=function(){this.form_cont=t.select(this.cont).append("div").classed("f3-form-cont",!0).node(),this.addRelativeInstance=this.setupAddRelative(),this.createHistory()},lt.prototype.open=function(t){t.data.data&&(t=t.data),this.addRelativeInstance.is_active&&!t._new_rel_data&&(this.addRelativeInstance.onCancel(),t=this.store.getDatum(t.id)),this.cardEditForm(t)},lt.prototype.openWithoutRelCancel=function(t){t.data.data&&(t=t.data),this.cardEditForm(t)},lt.prototype.cardEditForm=function(t){const e={};t?._new_rel_data?e.onCancel=()=>this.addRelativeInstance.onCancel():(e.addRelative=this.addRelativeInstance,e.deletePerson=()=>{const e=this.store.getData();o(t,e),this.store.updateData(e),this.openFormWithId(this.store.getLastAvailableMainDatum().id),this.store.updateTree({})});const n=mt.handlers.createForm({store:this.store,datum:t,postSubmit:function(e){this.addRelativeInstance.is_active?this.addRelativeInstance.onChange(t):e?.delete||this.openFormWithId(t.id);this.is_fixed||this.closeForm();this.store.updateTree({}),this.updateHistory()}.bind(this),fields:this.fields,card_display:this.card_display,addRelative:null,onCancel:()=>{},editFirst:this.editFirst,...e});n.no_edit=this.no_edit;const r=mt.handlers.formInfoSetup(n,this.closeForm.bind(this));this.form_cont.innerHTML="",this.form_cont.appendChild(r),this.openForm()},lt.prototype.openForm=function(){t.select(this.form_cont).classed("opened",!0)},lt.prototype.closeForm=function(){t.select(this.form_cont).classed("opened",!1).html(""),this.store.updateTree({})},lt.prototype.fixed=function(){return this.is_fixed=!0,t.select(this.form_cont).style("position","relative"),this},lt.prototype.absolute=function(){return this.is_fixed=!1,t.select(this.form_cont).style("position","absolute"),this},lt.prototype.setCardClickOpen=function(t){return t.setOnCardClick(((t,e)=>{this.addRelativeInstance.is_active?this.open(e):(this.open(e),this.store.updateMainId(e.data.id),this.store.updateTree({}))})),this},lt.prototype.openFormWithId=function(t){if(t){const e=this.store.getDatum(t);this.openWithoutRelCancel({data:e})}else{const t=this.store.getMainDatum();this.openWithoutRelCancel({data:t})}},lt.prototype.createHistory=function(){return this.history=mt.handlers.createHistory(this.store,this.getStoreData.bind(this),function(){this.addRelativeInstance.is_active&&this.addRelativeInstance.onCancel();this.store.updateTree({initial:!1}),this.history.controls.updateButtons(),this.openFormWithId(this.store.getMainDatum()?.id)}.bind(this)),this.history.controls=mt.handlers.createHistoryControls(this.cont,this.history),this.history.changed(),this.history.controls.updateButtons(),this},lt.prototype.setNoEdit=function(){return this.no_edit=!0,this},lt.prototype.setEdit=function(){return this.no_edit=!1,this},lt.prototype.setFields=function(t){const e=[];if(!Array.isArray(t))return console.error("fields must be an array"),this;for(const n of t)"string"==typeof n?e.push({type:"text",label:n,id:n}):"object"==typeof n?n.id?e.push(n):console.error("fields must be an array of objects with id property"):console.error("fields must be an array of strings or objects");return this.fields=e,this},lt.prototype.setOnChange=function(t){return this.onChange=t,this},lt.prototype.addRelative=function(t){return t||(t=this.store.getMainDatum()),this.addRelativeInstance.activate(t),this},lt.prototype.setupAddRelative=function(){return((...t)=>new dt(...t))(this.store,function(t){this.store.updateMainId(t.id),this.store.updateTree({}),this.openFormWithId(t.id)}.bind(this),function(t,e){this.store.updateMainId(t.id),this.openFormWithId(t.id)}.bind(this))},lt.prototype.setEditFirst=function(t){return this.editFirst=t,this},lt.prototype.isAddingRelative=function(){return this.addRelativeInstance.is_active},lt.prototype.setAddRelLabels=function(t){return this.addRelativeInstance.setAddRelLabels(t),this},lt.prototype.getStoreData=function(){return this.addRelativeInstance.is_active?this.addRelativeInstance.getStoreData():this.store.getData()},lt.prototype.getDataJson=function(t){const e=this.getStoreData();return mt.handlers.cleanupDataJson(JSON.stringify(e))},lt.prototype.updateHistory=function(){this.history&&(this.history.changed(),this.history.controls.updateButtons()),this.onChange&&this.onChange()},lt.prototype.destroy=function(){return this.history.controls.destroy(),this.histor