@grunwaldlab/heat-tree 0.3.0 → 0.3.1

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.
@@ -5,5 +5,5 @@
5
5
  *
6
6
  * Copyright 2017-2024 Andreas Borgen (https://github.com/Sphinxxxx), Adam Brooks (https://github.com/dissimulate)
7
7
  * Released under the ISC license.
8
- */var gi=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},mi=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),yi=function(){return function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return function(t,e){var n=[],i=!0,a=!1,o=void 0;try{for(var s,r=t[Symbol.iterator]();!(i=(s=r.next()).done)&&(n.push(s.value),!e||n.length!==e);i=!0);}catch(l){a=!0,o=l}finally{try{!i&&r.return&&r.return()}finally{if(a)throw o}}return n}(t,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();String.prototype.startsWith=String.prototype.startsWith||function(t){return 0===this.indexOf(t)},String.prototype.padStart=String.prototype.padStart||function(t,e){for(var n=this;n.length<t;)n=e+n;return n};var bi={cb:"0f8ff",tqw:"aebd7",q:"-ffff",qmrn:"7fffd4",zr:"0ffff",bg:"5f5dc",bsq:"e4c4",bck:"---",nch:"ebcd",b:"--ff",bvt:"8a2be2",brwn:"a52a2a",brw:"deb887",ctb:"5f9ea0",hrt:"7fff-",chcT:"d2691e",cr:"7f50",rnw:"6495ed",crns:"8dc",crms:"dc143c",cn:"-ffff",Db:"--8b",Dcn:"-8b8b",Dgnr:"b8860b",Dgr:"a9a9a9",Dgrn:"-64-",Dkhk:"bdb76b",Dmgn:"8b-8b",Dvgr:"556b2f",Drng:"8c-",Drch:"9932cc",Dr:"8b--",Dsmn:"e9967a",Dsgr:"8fbc8f",DsTb:"483d8b",DsTg:"2f4f4f",Dtrq:"-ced1",Dvt:"94-d3",ppnk:"1493",pskb:"-bfff",mgr:"696969",grb:"1e90ff",rbrc:"b22222",rwht:"af0",stg:"228b22",chs:"-ff",gnsb:"dcdcdc",st:"8f8ff",g:"d7-",gnr:"daa520",gr:"808080",grn:"-8-0",grnw:"adff2f",hnw:"0fff0",htpn:"69b4",nnr:"cd5c5c",ng:"4b-82",vr:"0",khk:"0e68c",vnr:"e6e6fa",nrb:"0f5",wngr:"7cfc-",mnch:"acd",Lb:"add8e6",Lcr:"08080",Lcn:"e0ffff",Lgnr:"afad2",Lgr:"d3d3d3",Lgrn:"90ee90",Lpnk:"b6c1",Lsmn:"a07a",Lsgr:"20b2aa",Lskb:"87cefa",LsTg:"778899",Lstb:"b0c4de",Lw:"e0",m:"-ff-",mgrn:"32cd32",nn:"af0e6",mgnt:"-ff",mrn:"8--0",mqm:"66cdaa",mmb:"--cd",mmrc:"ba55d3",mmpr:"9370db",msg:"3cb371",mmsT:"7b68ee","":"-fa9a",mtr:"48d1cc",mmvt:"c71585",mnLb:"191970",ntc:"5fffa",mstr:"e4e1",mccs:"e4b5",vjw:"dead",nv:"--80",c:"df5e6",v:"808-0",vrb:"6b8e23",rng:"a5-",rngr:"45-",rch:"da70d6",pgnr:"eee8aa",pgrn:"98fb98",ptrq:"afeeee",pvtr:"db7093",ppwh:"efd5",pchp:"dab9",pr:"cd853f",pnk:"c0cb",pm:"dda0dd",pwrb:"b0e0e6",prp:"8-080",cc:"663399",r:"--",sbr:"bc8f8f",rb:"4169e1",sbrw:"8b4513",smn:"a8072",nbr:"4a460",sgrn:"2e8b57",ssh:"5ee",snn:"a0522d",svr:"c0c0c0",skb:"87ceeb",sTb:"6a5acd",sTgr:"708090",snw:"afa",n:"-ff7f",stb:"4682b4",tn:"d2b48c",t:"-8080",thst:"d8bfd8",tmT:"6347",trqs:"40e0d0",vt:"ee82ee",whT:"5deb3",wht:"",hts:"5f5f5",w:"-",wgrn:"9acd32"};function xi(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return(e>0?t.toFixed(e).replace(/0+$/,"").replace(/\.$/,""):t.toString())||"0"}var vi=function(){function t(e,n,i,a){gi(this,t);var o=this;if(void 0===e);else if(Array.isArray(e))this.rgba=e;else if(void 0===i){var s=e&&""+e;s&&function(e){if(e.startsWith("hsl")){var n=e.match(/([\-\d\.e]+)/g).map(Number),i=yi(n,4),a=i[0],s=i[1],r=i[2],l=i[3];void 0===l&&(l=1),a/=360,s/=100,r/=100,o.hsla=[a,s,r,l]}else if(e.startsWith("rgb")){var h=e.match(/([\-\d\.e]+)/g).map(Number),c=yi(h,4),u=c[0],d=c[1],p=c[2],f=c[3];void 0===f&&(f=1),o.rgba=[u,d,p,f]}else e.startsWith("#")?o.rgba=t.hexToRgb(e):o.rgba=t.nameToRgb(e)||t.hexToRgb(e)}(s.toLowerCase())}else this.rgba=[e,n,i,void 0===a?1:a]}return mi(t,[{key:"printRGB",value:function(t){var e=(t?this.rgba:this.rgba.slice(0,3)).map(function(t,e){return xi(t,3===e?3:0)});return t?"rgba("+e+")":"rgb("+e+")"}},{key:"printHSL",value:function(t){var e=[360,100,100,1],n=["","%","%",""],i=(t?this.hsla:this.hsla.slice(0,3)).map(function(t,i){return xi(t*e[i],3===i?3:1)+n[i]});return t?"hsla("+i+")":"hsl("+i+")"}},{key:"printHex",value:function(t){var e=this.hex;return t?e:e.substring(0,7)}},{key:"rgba",get:function(){if(this._rgba)return this._rgba;if(!this._hsla)throw new Error("No color is set");return this._rgba=t.hslToRgb(this._hsla)},set:function(t){3===t.length&&(t[3]=1),this._rgba=t,this._hsla=null}},{key:"rgbString",get:function(){return this.printRGB()}},{key:"rgbaString",get:function(){return this.printRGB(!0)}},{key:"hsla",get:function(){if(this._hsla)return this._hsla;if(!this._rgba)throw new Error("No color is set");return this._hsla=t.rgbToHsl(this._rgba)},set:function(t){3===t.length&&(t[3]=1),this._hsla=t,this._rgba=null}},{key:"hslString",get:function(){return this.printHSL()}},{key:"hslaString",get:function(){return this.printHSL(!0)}},{key:"hex",get:function(){return"#"+this.rgba.map(function(t,e){return e<3?t.toString(16):Math.round(255*t).toString(16)}).map(function(t){return t.padStart(2,"0")}).join("")},set:function(e){this.rgba=t.hexToRgb(e)}}],[{key:"hexToRgb",value:function(t){var e=(t.startsWith("#")?t.slice(1):t).replace(/^(\w{3})$/,"$1F").replace(/^(\w)(\w)(\w)(\w)$/,"$1$1$2$2$3$3$4$4").replace(/^(\w{6})$/,"$1FF");if(!e.match(/^([0-9a-fA-F]{8})$/))throw new Error("Unknown hex color; "+t);var n=e.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function(t){return parseInt(t,16)});return n[3]=n[3]/255,n}},{key:"nameToRgb",value:function(e){var n=e.toLowerCase().replace("at","T").replace(/[aeiouyldf]/g,"").replace("ght","L").replace("rk","D").slice(-5,4),i=bi[n];return void 0===i?i:t.hexToRgb(i.replace(/\-/g,"00").padStart(6,"f"))}},{key:"rgbToHsl",value:function(t){var e=yi(t,4),n=e[0],i=e[1],a=e[2],o=e[3];n/=255,i/=255,a/=255;var s=Math.max(n,i,a),r=Math.min(n,i,a),l=void 0,h=void 0,c=(s+r)/2;if(s===r)l=h=0;else{var u=s-r;switch(h=c>.5?u/(2-s-r):u/(s+r),s){case n:l=(i-a)/u+(i<a?6:0);break;case i:l=(a-n)/u+2;break;case a:l=(n-i)/u+4}l/=6}return[l,h,c,o]}},{key:"hslToRgb",value:function(t){var e=yi(t,4),n=e[0],i=e[1],a=e[2],o=e[3],s=void 0,r=void 0,l=void 0;if(0===i)s=r=l=a;else{var h=function(t,e,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?t+6*(e-t)*n:n<.5?e:n<2/3?t+(e-t)*(2/3-n)*6:t},c=a<.5?a*(1+i):a+i-a*i,u=2*a-c;s=h(u,c,n+1/3),r=h(u,c,n),l=h(u,c,n-1/3)}var d=[255*s,255*r,255*l].map(Math.round);return d[3]=o,d}}]),t}(),wi=function(){function t(){gi(this,t),this._events=[]}return mi(t,[{key:"add",value:function(t,e,n){t.addEventListener(e,n,!1),this._events.push({target:t,type:e,handler:n})}},{key:"remove",value:function(e,n,i){this._events=this._events.filter(function(a){var o=!0;return e&&e!==a.target&&(o=!1),n&&n!==a.type&&(o=!1),i&&i!==a.handler&&(o=!1),o&&t._doRemove(a.target,a.type,a.handler),!o})}},{key:"destroy",value:function(){this._events.forEach(function(e){return t._doRemove(e.target,e.type,e.handler)}),this._events=[]}}],[{key:"_doRemove",value:function(t,e,n){t.removeEventListener(e,n,!1)}}]),t}();function _i(t,e,n){var i=!1;function a(t,e,n){return Math.max(e,Math.min(t,n))}function o(t,o,s){if(s&&(i=!0),i){t.preventDefault();var r=e.getBoundingClientRect(),l=r.width,h=r.height,c=o.clientX,u=o.clientY,d=a(c-r.left,0,l),p=a(u-r.top,0,h);n(d/l,p/h)}}function s(t,e){1===(void 0===t.buttons?t.which:t.buttons)?o(t,t,e):i=!1}function r(t,e){1===t.touches.length?o(t,t.touches[0],e):i=!1}t.add(e,"mousedown",function(t){s(t,!0)}),t.add(e,"touchstart",function(t){r(t,!0)}),t.add(window,"mousemove",s),t.add(e,"touchmove",r),t.add(window,"mouseup",function(t){i=!1}),t.add(e,"touchend",function(t){i=!1}),t.add(e,"touchcancel",function(t){i=!1})}var Ci="keydown",ki="mousedown",Si="focusin";function Li(t,e){return(e||document).querySelector(t)}function Ti(t,e,n,i,a){t.add(e,Ci,function(t){n.indexOf(t.key)>=0&&i(t)})}var Mi=function(){function t(e){gi(this,t),this.settings={popup:"right",layout:"default",alpha:!0,editor:!0,editorFormat:"hex",cancelButton:!1,defaultColor:"#0cf"},this._events=new wi,this.onChange=null,this.onDone=null,this.onOpen=null,this.onClose=null,this.setOptions(e)}return mi(t,[{key:"setOptions",value:function(t){var e=this;if(t){var n=this.settings;if(t instanceof HTMLElement)n.parent=t;else{n.parent&&t.parent&&n.parent!==t.parent&&(this._events.remove(n.parent),this._popupInited=!1),function(t,e){for(var n in t)e[n]=t[n]}(t,n),t.onChange&&(this.onChange=t.onChange),t.onDone&&(this.onDone=t.onDone),t.onOpen&&(this.onOpen=t.onOpen),t.onClose&&(this.onClose=t.onClose);var i=t.color||t.colour;i&&this._setColor(i)}var a=n.parent;if(a&&n.popup&&!this._popupInited){var o=function(t){return e.openHandler(t)};this._events.add(a,"click",o),Ti(this._events,a,[" ","Spacebar","Enter"],o),this._popupInited=!0}else t.parent&&!n.popup&&this.show()}}},{key:"openHandler",value:function(t){if(this.show()){t&&t.preventDefault(),this.settings.parent.style.pointerEvents="none";var e=t&&t.type===Ci?this._domEdit:this.domElement;setTimeout(function(){return e.focus()},100),this.onOpen&&this.onOpen(this.colour)}}},{key:"closeHandler",value:function(t){var e=t&&t.type,n=!1;if(t)if(e===ki||e===Si){var i=(this.__containedEvent||0)+100;t.timeStamp>i&&(n=!0)}else!function(t){t.preventDefault(),t.stopPropagation()}(t),n=!0;else n=!0;n&&this.hide()&&(this.settings.parent.style.pointerEvents="",e!==ki&&this.settings.parent.focus(),this.onClose&&this.onClose(this.colour))}},{key:"movePopup",value:function(t,e){this.closeHandler(),this.setOptions(t),e&&this.openHandler()}},{key:"setColor",value:function(t,e){this._setColor(t,{silent:e})}},{key:"_setColor",value:function(t,e){if("string"==typeof t&&(t=t.trim()),t){e=e||{};var n=void 0;try{n=new vi(t)}catch(a){if(e.failSilently)return;throw a}if(!this.settings.alpha){var i=n.hsla;i[3]=1,n.hsla=i}this.colour=this.color=n,this._setHSLA(null,null,null,null,e)}}},{key:"setColour",value:function(t,e){this.setColor(t,e)}},{key:"show",value:function(){if(!this.settings.parent)return!1;if(this.domElement){var t=this._toggleDOM(!0);return this._setPosition(),t}var e,n,i=this.settings.template||'<div class="picker_wrapper" tabindex="-1"><div class="picker_arrow"></div><div class="picker_hue picker_slider"><div class="picker_selector"></div></div><div class="picker_sl"><div class="picker_selector"></div></div><div class="picker_alpha picker_slider"><div class="picker_selector"></div></div><div class="picker_editor"><input aria-label="Type a color name or hex value"/></div><div class="picker_sample"></div><div class="picker_done"><button>Ok</button></div><div class="picker_cancel"><button>Cancel</button></div></div>',a=(e=i,(n=document.createElement("div")).innerHTML=e,n.firstElementChild);return this.domElement=a,this._domH=Li(".picker_hue",a),this._domSL=Li(".picker_sl",a),this._domA=Li(".picker_alpha",a),this._domEdit=Li(".picker_editor input",a),this._domSample=Li(".picker_sample",a),this._domOkay=Li(".picker_done button",a),this._domCancel=Li(".picker_cancel button",a),a.classList.add("layout_"+this.settings.layout),this.settings.alpha||a.classList.add("no_alpha"),this.settings.editor||a.classList.add("no_editor"),this.settings.cancelButton||a.classList.add("no_cancel"),this._ifPopup(function(){return a.classList.add("popup")}),this._setPosition(),this.colour?this._updateUI():this._setColor(this.settings.defaultColor),this._bindEvents(),!0}},{key:"hide",value:function(){return this._toggleDOM(!1)}},{key:"destroy",value:function(){this._events.destroy(),this.domElement&&this.settings.parent.removeChild(this.domElement)}},{key:"_bindEvents",value:function(){var t=this,e=this,n=this.domElement,i=this._events;function a(t,e,n){i.add(t,e,n)}a(n,"click",function(t){return t.preventDefault()}),_i(i,this._domH,function(t,n){return e._setHSLA(t)}),_i(i,this._domSL,function(t,n){return e._setHSLA(null,t,1-n)}),this.settings.alpha&&_i(i,this._domA,function(t,n){return e._setHSLA(null,null,null,1-n)});var o=this._domEdit;a(o,"input",function(t){e._setColor(this.value,{fromEditor:!0,failSilently:!0})}),a(o,"focus",function(t){var e=this;e.selectionStart===e.selectionEnd&&e.select()}),this._ifPopup(function(){var e=function(e){return t.closeHandler(e)};a(window,ki,e),a(window,Si,e),Ti(i,n,["Esc","Escape"],e);var o=function(e){t.__containedEvent=e.timeStamp};a(n,ki,o),a(n,Si,o),a(t._domCancel,"click",e)});var s=function(e){t._ifPopup(function(){return t.closeHandler(e)}),t.onDone&&t.onDone(t.colour)};a(this._domOkay,"click",s),Ti(i,n,["Enter"],s)}},{key:"_setPosition",value:function(){var t=this.settings.parent,e=this.domElement;t!==e.parentNode&&t.appendChild(e),this._ifPopup(function(n){"static"===getComputedStyle(t).position&&(t.style.position="relative");var i=!0===n?"popup_right":"popup_"+n;["popup_top","popup_bottom","popup_left","popup_right"].forEach(function(t){t===i?e.classList.add(t):e.classList.remove(t)}),e.classList.add(i)})}},{key:"_setHSLA",value:function(t,e,n,i,a){a=a||{};var o=this.colour,s=o.hsla;[t,e,n,i].forEach(function(t,e){(t||0===t)&&(s[e]=t)}),o.hsla=s,this._updateUI(a),this.onChange&&!a.silent&&this.onChange(o)}},{key:"_updateUI",value:function(t){if(this.domElement){t=t||{};var e=this.colour,n=e.hsla,i="hsl("+360*n[0]+", 100%, 50%)",a=e.hslString,o=e.hslaString,s=this._domH,r=this._domSL,l=this._domA,h=Li(".picker_selector",s),c=Li(".picker_selector",r),u=Li(".picker_selector",l);b(0,h,n[0]),this._domSL.style.backgroundColor=this._domH.style.color=i,b(0,c,n[1]),x(0,c,1-n[2]),r.style.color=a,x(0,u,1-n[3]);var d=a,p=d.replace("hsl","hsla").replace(")",", 0)"),f="linear-gradient("+[d,p]+")";if(this._domA.style.background=f+", linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\n linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em",!t.fromEditor){var g=this.settings.editorFormat,m=this.settings.alpha,y=void 0;switch(g){case"rgb":y=e.printRGB(m);break;case"hsl":y=e.printHSL(m);break;default:y=e.printHex(m)}this._domEdit.value=y}this._domSample.style.color=o}function b(t,e,n){e.style.left=100*n+"%"}function x(t,e,n){e.style.top=100*n+"%"}}},{key:"_ifPopup",value:function(t,e){this.settings.parent&&this.settings.popup?t&&t(this.settings.popup):e&&e()}},{key:"_toggleDOM",value:function(t){var e=this.domElement;if(!e)return!1;var n=t?"":"none",i=e.style.display!==n;return i&&(e.style.display=n),i}}]),t}(),Pi=document.createElement("style");function Ei(){const t=document.createElement("div");return t.className="ht-control-group",t}function $i(t,e){const n=document.createElement("label");return n.className="ht-control-label",n.textContent=t,n.style.height=`${e}px`,n}function zi(t,e="",n){const i=document.createElement("button");return i.className="ht-button",i.textContent=t,i.title=e,i.style.height=`${n}px`,i}function Ni(t,e,n,i,a){const o=document.createElement("input");return o.type="range",o.className="ht-slider",o.min=t,o.max=e,o.value=n,o.step=i,o.style.height=`${a}px`,o}function Ai(t,e){const n=Math.min(24,e-4),i=n-4,a=document.createElement("div");a.className=t?"ht-toggle active":"ht-toggle",a.style.height=`${n}px`;const o=document.createElement("div");return o.className="ht-toggle-knob",o.style.width=`${i}px`,o.style.height=`${i}px`,a.appendChild(o),a}function Ri(t,e,n,i,a){const o=document.createElement("input");return o.type="number",o.className="ht-number-input",o.value=t,o.min=e,o.max=n,o.step=i,o.style.height=`${a}px`,o}Pi.textContent='.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper::before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl::before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg, gainsboro, transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg, transparent, gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg, red, yellow, lime, cyan, blue, magenta, red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg, white, rgba(255, 255, 255, 0) 50%),linear-gradient(0deg, black, rgba(0, 0, 0, 0) 50%),linear-gradient(90deg, #808080, rgba(128, 128, 128, 0))}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample::before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{background:#f2f2f2;box-shadow:0 0 10px 1px rgba(0,0,0,.4)}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow::before,.picker_wrapper.popup .picker_arrow::after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow::before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow::after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1, -1);transform:rotate(90deg) scale(1, -1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1, 1);transform:scale(-1, 1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}',document.documentElement.firstElementChild.appendChild(Pi),Mi.StyleElement=Pi;class Hi extends ai{state;scale;values;defaultPalette=["#440154","#365C8D","#1FA187","#9FDA3A"];treeState;constructor(t,e={}){if(super(),!e.scaleType)throw new Error("scaleType is required");if(void 0===e.default)throw new Error("default is required");this.values=t,this.treeState=e.treeState||null,this.state={scaleType:void 0,default:void 0,isCategorical:void 0,outputValues:null,outputRegex:null,colorPalette:this.defaultPalette,colorPositions:this.defaultPalette.map((t,e)=>e/(this.defaultPalette.length-1)),outputRange:null,inputUnits:null,title:null,maxCategories:7,otherCategory:"#888888",otherLabel:"Other",transformMin:0,transformMax:1,transformFn:null,nullValue:"#808080",showNullInLegend:!0,...e},this.updateScale(!1)}getValue(t){return this.scale.getValue(t)}updateScale(t=!0){const e=this.values,{scaleType:n,isCategorical:i}=this.state;let a,o=!0;if(i&&(this.state.outputValues||this.state.outputRegex)){if(this.state.outputValues)for(let t=0;t<e.length;t++)if(e[t]&&!this.state.outputValues.includes(e[t])){o=!1;break}if(this.state.outputRegex)for(let t=0;t<e.length;t++)if(e[t]&&!this.state.outputRegex.test(e[t])){o=!1;break}}else o=!1;if("null"===n)a=new hi(this.state),this.scale=a;else if("identity"===n||o)a=new ci(this.state),this.scale=a;else if("text"===n){if(!i)throw new Error("Text scales can only be used with categorical data");a=new ui(e,this.state),this.scale=a}else if("size"===n){if(i)throw new Error("Size scales can only be used with continuous data");const t=e.map(t=>Number(t)).filter(t=>!isNaN(t));if(0===t.length)console.warn("No numeric values found for size scale, using NullScale"),a=new hi(this.state);else{const e=Math.min(...t),n=Math.max(...t);a=new di(e,n,this.state)}this.scale=a}else{if("color"!==n)throw new Error(`Unknown scale type: ${n}`);if(i)a=new fi(e,this.state);else{const t=e.map(t=>Number(t)).filter(t=>!isNaN(t));if(0===t.length)console.warn("No numeric values found for color scale, using NullScale"),a=new hi(this.state);else{const e=Math.min(...t),n=Math.max(...t);a=new pi(e,n,this.state)}}this.scale=a}t&&this.notify("aestheticChange",this)}updateState(t){Object.assign(this.state,t),this.updateScale(this.values)}createSettingsWidget(t={}){const{controlHeight:e=20,columnId:n=null}=t;if(!n){const t=document.createElement("div");return t.textContent="Select a metadata column to edit its settings",t.style.padding="10px",t.style.color="#666",t}const i=document.createElement("div");if(i.className="ht-aesthetic-settings-content","color"===this.state.scaleType){const t=this.createColorPaletteEditor(e);if(t&&i.appendChild(t),this.state.isCategorical){const t=Ei(),a=$i("Max colors:",e);t.appendChild(a);const o=Ri(this.state.maxCategories||7,2,100,1,e);o.addEventListener("input",t=>{const e=parseInt(t.target.value);isNaN(e)||e<1||(this.updateState({maxCategories:e}),this.updateScale(this.values),this.treeState&&(this.treeState.state.treeData.tree.each(t=>{const e=t[n];null!=e&&(t.tipLabelColor=this.getValue(e))}),this.treeState.updateCoordinates(),this.treeState.notify("legendsChange")))}),t.appendChild(o),i.appendChild(t)}const a=Ei(),o=$i("Legend title:",e);a.appendChild(o);const s=document.createElement("input");if(s.type="text",s.className="ht-text-input",s.style.height=`${e}px`,s.style.flex="1",s.value=this.state.title||"",s.placeholder="Enter legend title",s.addEventListener("input",t=>{this.updateState({title:t.target.value}),this.treeState&&this.treeState.notify("legendsChange")}),a.appendChild(s),i.appendChild(a),!this.state.isCategorical){const t=Ei(),n=$i("Units label:",e);t.appendChild(n);const a=document.createElement("input");a.type="text",a.className="ht-text-input",a.style.height=`${e}px`,a.style.flex="1",a.value=this.state.inputUnits||"",a.placeholder="Enter units (e.g., °C, km)",a.addEventListener("input",t=>{this.updateState({inputUnits:t.target.value}),this.treeState&&this.treeState.notify("legendsChange")}),t.appendChild(a),i.appendChild(t)}}if(0===i.children.length){const t=document.createElement("div");t.textContent="No settings available for this aesthetic",t.style.padding="10px",t.style.color="#666",i.appendChild(t)}return i}createColorPaletteEditor(t){if(!this.scale)return null;const e=document.createElement("div");e.className="ht-color-palette-editor";const n=document.createElement("div");n.className="ht-gradient-container";const i=document.createElement("div");i.className="ht-gradient-column";const a=document.createElement("div");a.className="ht-color-squares-container";const o=document.createElement("div");o.className="ht-gradient-box";const s=()=>{const t=this.state.colorPalette.map((t,e)=>`${t} ${100*this.state.colorPositions[e]}%`).join(", ");o.style.background=`linear-gradient(to right, ${t})`};s();let r=null;const l=document.createElement("div");l.style.position="fixed",l.style.zIndex="999999",l.style.pointerEvents="auto",document.body.appendChild(l);const h=document.createElement("div");h.style.position="fixed",h.style.zIndex="999999",h.style.pointerEvents="auto",document.body.appendChild(h);const c=()=>{l.style.display="none",r=null},u=()=>{h.style.display="none"},d=document.createElement("div");d.className="ht-null-color-column";const p=document.createElement("div");p.className="ht-null-color-square-container";const f=document.createElement("div");f.style.display="flex",f.style.flexDirection="column",f.style.alignItems="center";const g=document.createElement("div");g.className="ht-null-color-square",g.style.backgroundColor=this.state.nullValue,g.title="Click to edit missing data color";const m=document.createElement("div");m.className="ht-null-color-square-tick",f.appendChild(g),f.appendChild(m),p.appendChild(f);const y=document.createElement("div");y.className="ht-null-color-box",y.style.backgroundColor=this.state.nullValue;const b=new Mi({parent:l,popup:!1,alpha:!1,editor:!0,color:this.state.colorPalette[0],onChange:t=>{if(!r)return;const e=parseInt(r.getAttribute("data-color-index")),n=t.hex.substring(0,7);this.state.colorPalette[e]=n,r.style.backgroundColor=n,s();const i=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMin);k.style.backgroundColor=i;const a=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMax);T.style.backgroundColor=a,this.updateScale()},onDone:()=>{c()}});l.style.display="none";const x=t=>{l.contains(t.target)||t.target.closest(".ht-color-square")||c()};document.addEventListener("click",x);const v=new Mi({parent:h,popup:!1,alpha:!1,editor:!0,color:this.state.nullValue,onChange:t=>{const e=t.hex.substring(0,7);this.state.nullValue=e,g.style.backgroundColor=e,y.style.backgroundColor=e,this.updateScale()},onDone:()=>{u()}});h.style.display="none";const w=t=>{h.contains(t.target)||t.target===g||u()};document.addEventListener("click",w),e.dataset.pickerCleanup="cleanup",e.cleanupFunction=()=>{document.removeEventListener("click",x),document.removeEventListener("click",w),l.parentElement&&l.parentElement.removeChild(l),h.parentElement&&h.parentElement.removeChild(h)};const _=()=>{a.innerHTML="",this.state.colorPalette.forEach((t,e)=>{const n=function(t,e,n,i){const a=document.createElement("div");a.className="ht-color-square-wrapper";const o=document.createElement("div");o.className="ht-color-square",o.style.backgroundColor=e,o.title="Click to edit color",o.setAttribute("data-color-index",n),o.addEventListener("click",i);const s=document.createElement("div");return s.className="ht-color-square-tick",a.appendChild(o),a.appendChild(s),t.appendChild(a),a}(a,t,e,t=>{t.preventDefault(),t.stopPropagation();const e=t.currentTarget,n=parseInt(e.getAttribute("data-color-index"));u(),r=e;const i=e.getBoundingClientRect();b.setColor(this.state.colorPalette[n],!0),l.style.left=`${i.left}px`,l.style.top=`${i.bottom+5}px`,l.style.display="block"});n.style.left=100*this.state.colorPositions[e]+"%"})};_();const C=document.createElement("div");C.className="ht-range-slider-container";const k=document.createElement("div");k.className="ht-range-handle",k.style.left=100*this.state.transformMin+"%",k.title="Drag to adjust minimum";let S=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMin);k.style.backgroundColor=S;const L=document.createElement("div");L.className="ht-range-handle-indicator",k.appendChild(L);const T=document.createElement("div");T.className="ht-range-handle",T.style.left=100*this.state.transformMax+"%",T.title="Drag to adjust maximum";let M=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMax);T.style.backgroundColor=M;const P=document.createElement("div");P.className="ht-range-handle-indicator",T.appendChild(P);let E=!1;k.addEventListener("mousedown",t=>{E=!0,t.preventDefault()});let $=!1;T.addEventListener("mousedown",t=>{$=!0,t.preventDefault()});document.addEventListener("mousemove",t=>{if(!E&&!$)return;const e=C.getBoundingClientRect(),n=t.clientX-e.left,i=e.width;let a=Math.max(0,Math.min(1,n/i));E?(a=Math.min(a,this.state.transformMax-.01),this.state.transformMin=a,k.style.left=100*a+"%",S=Bi(this.state.colorPalette,this.state.colorPositions,a),k.style.backgroundColor=S,this.updateScale()):$&&(a=Math.max(a,this.state.transformMin+.01),this.state.transformMax=a,T.style.left=100*a+"%",M=Bi(this.state.colorPalette,this.state.colorPositions,a),T.style.backgroundColor=M,this.updateScale())}),document.addEventListener("mouseup",()=>{E=!1,$=!1}),C.appendChild(k),C.appendChild(T),i.appendChild(a),i.appendChild(o),i.appendChild(C),g.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),c();const e=g.getBoundingClientRect();v.setColor(this.state.nullValue,!0),h.style.left=`${e.left}px`,h.style.top=`${e.bottom+5}px`,h.style.display="block"});const z=document.createElement("div");z.className="missing-data-x-container";const N=document.createElement("div");N.className="missing-data-x-container-triangle";const A=document.createElement("div");A.className="missing-data-x",A.textContent="✕",z.appendChild(N),z.appendChild(A),d.appendChild(p),d.appendChild(y),d.appendChild(z),n.appendChild(i),n.appendChild(d);const R=document.createElement("div");R.className="ht-palette-buttons-container";const H=Di("+","Add color to left");H.addEventListener("click",()=>{const t=this.state.colorPalette[0];this.state.colorPalette.unshift(t),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),s(),_(),S=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),k.style.backgroundColor=S,M=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),T.style.backgroundColor=M,this.updateScale()});const D=Di("-","Remove color from left");D.addEventListener("click",()=>{this.state.colorPalette.length<=2?console.warn("Cannot remove color: minimum 2 colors required"):(this.state.colorPalette.shift(),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),s(),_(),S=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),k.style.backgroundColor=S,M=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),T.style.backgroundColor=M,this.updateScale())}),R.appendChild(H),R.appendChild(D);const B=document.createElement("div");B.className="ht-palette-buttons-container";const I=Di("+","Add color to right");I.addEventListener("click",()=>{const t=this.state.colorPalette[this.state.colorPalette.length-1];this.state.colorPalette.push(t),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),s(),_(),S=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),k.style.backgroundColor=S,M=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),T.style.backgroundColor=M,this.updateScale()});const F=Di("-","Remove color from right");return F.addEventListener("click",()=>{this.state.colorPalette.length<=2?console.warn("Cannot remove color: minimum 2 colors required"):(this.state.colorPalette.pop(),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),s(),_(),S=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),k.style.backgroundColor=S,M=Bi(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),T.style.backgroundColor=M,this.updateScale())}),B.appendChild(I),B.appendChild(F),e.appendChild(R),e.appendChild(n),e.appendChild(B),e}}function Di(t,e){const n=document.createElement("button");return n.className="ht-palette-button",n.textContent=t,n.title=e,n}function Bi(t,e,n){if(n=Math.max(0,Math.min(1,n)),1===t.length)return t[0];let i=0;for(;i<e.length-1&&n>e[i+1];)i++;if(n===e[i])return t[i];if(i===e.length-1)return t[i];const a=e[i],o=(n-a)/(e[i+1]-a),s=Ii(t[i]),r=Ii(t[i+1]);return function(t,e,n){return"#"+[t,e,n].map(t=>{const e=t.toString(16);return 1===e.length?"0"+e:e}).join("")}(Math.round(s.r+(r.r-s.r)*o),Math.round(s.g+(r.g-s.g)*o),Math.round(s.b+(r.b-s.b)*o))}function Ii(t){const e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:{r:0,g:0,b:0}}class Fi extends ai{tree;metadata=new Map;metadataTableNames=new Map;columnType=new Map;columnName=new Map;columnDisplayName=new Map;columnAesthetic=new Map;nodeIdColumn=new Map;validIdColumns=new Map;#t=0;constructor(t,e=[],n=[]){super(),this.tree=this.createHierarchy(t),Array.isArray(e)&&e.forEach((t,e)=>{this.addTable(t,n[e])})}static fromTreeString(t,e=[],n=[]){const i=Fi.parseTrees(t,"Tree");if(1!==i.length)throw new Error(`Expected exactly one tree, but found ${i.length}. Use TreeData.parseTrees() for multiple trees.`);return new Fi(i[0].treeData,e,n)}static parseTrees(t,e="Tree"){let n;if(function(t){const e=t.trim().split(/\r?\n/)[0].trim();return/^#NEXUS$/i.test(e)}(t))n=function(t){const e=[],n=/begin\s+trees\s*;([^]*?)end\s*;/gi;let i;for(;null!==(i=n.exec(t));){const t=ri(i[1]);e.push(...t)}return e}(t);else{n=[{treeName:null,treeData:li(t)}]}const i=n.length>1;return n.map((t,n)=>{let a;return a=t.treeName?i?`${e} ${t.treeName}`:`${e} - ${t.treeName}`:i?`${e} ${n+1}`:e,{name:a,treeData:t.treeData}})}createHierarchy(t){const e=Ln(t,t=>t.children).sum(t=>t.children?0:1).each(function(t){t.leafCount=t.value,delete t.value,delete t.data.children}).sort((t,e)=>t.leafCount-e.leafCount||function(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}(t.data.length,e.data.length));let n=0;return e.each(t=>{t.id=++n}),e}setTree(t){this.tree=this.createHierarchy(t),this.metadata.keys().forEach(t=>this.#e(t)),this.notify("treeUpdated",this)}getMetadataTableNames(){return Array.from(this.metadataTableNames.values())}getTreeNodeNames(){const t=new Set;return this.tree.each(e=>{e.data.name&&t.add(e.data.name)}),t}#n(t){const e=this.metadata.get(t),n=this.nodeIdColumn.get(t);if(!e||!n)return new Map;const i=new Map;for(const a of e){const t=a[n];t&&i.set(t,a)}return i}addTable(t,e=null,n="\t"){let{metadataMap:i,columnTypes:a,idColumns:o}=function(t,e,n="\t"){let i=new Map,a=new Map,o=[],s=[];const r=t.trim().split("\n");if(0==r.length)console.error("Empty metadata table");else{const t=r[0].split(n),l=new Map;t.forEach(t=>l.set(t,[]));for(let e=1;e<r.length;e++){const a=r[e].split(n),o={};for(let e=0;e<t.length;e++){const n=t[e],i=""===a[e]?void 0:a[e];o[n]=i,l.get(n).push(i)}i.set(e-1,o)}t.forEach(t=>{const n=l.get(t),i=n.map(t=>parseFloat(t)).filter(t=>!isNaN(t)),s=i.length>0&&i.length===n.filter(t=>void 0!==t).length;a.set(t,s?"continuous":"categorical");let r=0;for(const a of n)a&&e.has(a)&&r++;r>0&&o.push({col:t,matchCount:r})}),o=o.sort((t,e)=>e.matchCount-t.matchCount),s=o.map(t=>t.col)}return{metadataMap:i,columnTypes:a,idColumns:s}}(t,this.getTreeNodeNames(),n);const s="table_"+this.#t++;e||(e=`Metadata ${this.#t}`),this.metadataTableNames.set(s,e);const r=new Map;for(const[c,u]of a){const t=`${s}_${c}`;r.set(c,t),this.columnType.set(t,u),this.columnName.set(t,c),this.columnDisplayName.set(t,ei(c))}o=o.map(t=>r.get(t));let l=null;o.length>0?l=o[0]:console.warn(`No valid node ID column found in table ${e}`);const h=[];for(const c of i.values()){const t={};for(const[e,n]of Object.entries(c)){const i=r.get(e);i&&(t[i]=n)}h.push(t)}return this.validIdColumns.set(s,o),this.nodeIdColumn.set(s,l),this.metadata.set(s,h),this.#e(s),this.notify("metadataAdded",{tableId:s,columnIds:Array.from(r.values())}),s}getValidIdColumns(t){return this.validIdColumns.get(t)||[]}getNodeIdColumn(t){return this.nodeIdColumn.get(t)}getTableColumnIds(t){const e=this.metadata.get(t);return e&&0!==e.length?Object.keys(e[0]):[]}setNodeIdColumn(t,e){if(!this.metadata.get(t))return void console.warn(`Table ${t} does not exist`);if(!this.validIdColumns.get(t).includes(e))return void console.warn(`Column ${e} is not a valid ID column for table ${t}`);const n=this.nodeIdColumn.get(t);if(n===e)return;const i=this.getTableColumnIds(t);for(const a of i)this.columnAesthetic.delete(a);this.#i(t),this.nodeIdColumn.set(t,e),this.#e(t),this.notify("metadataChanged",{tableId:t,oldIdColumn:n,newIdColumn:e,columnIds:i,requiresAestheticRefresh:!0})}deleteTable(t){const e=this.metadata.get(t);if(!e)return void console.warn(`Table ${t} does not exist`);const n=e.length>0?Object.keys(e[0]):[];for(const i of n)this.columnType.delete(i),this.columnName.delete(i),this.columnDisplayName.delete(i),this.columnAesthetic.delete(i);this.#i(t),this.metadata.delete(t),this.metadataTableNames.delete(t),this.nodeIdColumn.delete(t),this.validIdColumns.delete(t),this.notify("metadataChanged",{tableId:t,columnIds:n})}getAesthetic(t,e,n={}){this.columnAesthetic.has(t)||this.columnAesthetic.set(t,new Map);const i=this.columnAesthetic.get(t);if(i.has(e))return i.get(e);const a=this.#a(t,n);return i.set(e,a),a}setAesthetic(t,e,n){this.columnAesthetic.has(t)||this.columnAesthetic.set(t,new Map),this.columnAesthetic.get(t).set(e,n)}#a(t,e={}){const n=this.columnType.get(t),i="categorical"===n;n||console.error(`Column ${t} not found`);let a=[];this.tree.each(n=>{"tips"==e.subset&&n.children||(n.metadata?a.push(n.metadata[t]):a.push(void 0))}),0===a.length&&console.error(`No values found for column ${t}`);const o=this.columnDisplayName.get(t)||t;let s=e.scaleType;s||(s="color");return new Hi(a,{scaleType:s,default:void 0!==e.default?e.default:i?null:0,isCategorical:i,inputUnits:o,...e})}#e(t){const e=this.#n(t);this.tree.each(t=>{const n=t.data.name;if(n&&e.has(n)){const i=e.get(n);t.metadata={...t.metadata,...i}}})}#i(t){const e=this.metadata.get(t);if(!e||0===e.length)return;const n=Object.keys(e[0]);this.tree.each(t=>{t.metadata&&n.forEach(e=>{delete t.metadata[e]})})}}function Vi(t,e){const n=t.leaves().map((t,n)=>({radius:t.radius,angle:t.angle,cos:t.cos,sin:t.sin,width:(t.tipLabelBounds.width+e.nodeLabelOffset)*t.tipLabelSize,height:t.tipLabelBounds.height*t.tipLabelSize,labelScale:t.tipLabelSize}));let i=0,a=1/0,o=0,s=1/0;function r(t){t>i&&(i=t>a?a:t)}function l(t){t<s&&(s=t<o?o:t)}function h(t){t>o&&(o=t>s?s:t)}const c=Math.min(...n.map(t=>t.labelScale)),u=Math.max(...n.map(t=>t.radius)),d=n.reduce((t,e)=>t+e.radius,0)/n.length,p=t.descendants().filter(t=>t.data.length>0&&t.children),f=p.length>0?Math.min(...p.map(t=>t.data.length)):1/0;h(e.minFontPx/c),i!==a&&r(Math.max(...n.map(t=>t.width*o/(u/e.minBranchLenProp-t.radius))));const g=n.reduce((t,e)=>t+e.height,0);function m(){const t=Math.min(...n.filter(t=>t.cos>0).map(t=>(e.viewWidth/2-t.width*t.cos*o)/(t.radius*t.cos))),s=Math.min(...n.filter(t=>t.cos<0).map(t=>(e.viewWidth/2-t.width*-t.cos*o)/(t.radius*-t.cos))),r=Math.min(...n.filter(t=>t.sin>0).map(t=>(e.viewHeight/2-t.width*t.sin*o)/(t.radius*t.sin))),l=Math.min(...n.filter(t=>t.sin<0).map(t=>(e.viewHeight/2-t.width*-t.sin*o)/(t.radius*-t.sin)));var h;(h=Math.min((t+s)/2,(l+r)/2))<a&&(a=h<i?i:h)}function y(){const t=Math.min(...n.filter(t=>t.cos>0).map(t=>(e.viewWidth/2-t.radius*t.cos*i)/(t.width*t.cos))),a=Math.min(...n.filter(t=>t.cos<0).map(t=>(e.viewWidth/2-t.radius*-t.cos*i)/(t.width*-t.cos))),o=Math.min(...n.filter(t=>t.sin>0).map(t=>(e.viewHeight/2-t.radius*t.sin*i)/(t.width*t.sin))),s=Math.min(...n.filter(t=>t.sin<0).map(t=>(e.viewHeight/2-t.radius*-t.sin*i)/(t.width*-t.sin)));l(Math.min((t+a)/2,(s+o)/2))}return g>0&&d>0&&(i!==a&&r(g*o/(2*d*Math.PI)),o!==s&&l(u*a*2*Math.PI/g)),m(),y(),o!==s&&h(e.idealFontPx/c),i!==a&&m(),isFinite(f)&&f>0&&i!==a&&r(e.minBranchThicknessPx/f),o!==s&&y(),o!==s&&l(e.maxFontPx/c),{branchLenToPxFactor_min:i,branchLenToPxFactor_max:a,labelSizeToPxFactor_min:o,labelSizeToPxFactor_max:s}}class qi{constructor(){this.metricsCache=new Map,this.setupHiddenEnvironment()}setupHiddenEnvironment(){this.hiddenContainer=document.createElement("div"),this.hiddenContainer.style.cssText="\n position: absolute;\n top: -9999px;\n left: -9999px;\n visibility: hidden;\n width: 5000px;\n height: 5000px;\n overflow: hidden;\n ",this.hiddenSVG=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.hiddenSVG.setAttribute("width","5000"),this.hiddenSVG.setAttribute("height","5000"),this.hiddenSVG.setAttribute("viewBox","0 0 5000 5000"),this.hiddenContainer.appendChild(this.hiddenSVG),document.body.appendChild(this.hiddenContainer),this.hiddenD3SVG=bt(this.hiddenSVG),this.textGroup=this.hiddenD3SVG.append("g").attr("id","text-measurement-group")}getRelativeTextSize(t,e={}){const n=`${t}-${JSON.stringify(e)}`;if(this.metricsCache.has(n))return this.metricsCache.get(n);const i=this.textGroup.append("text").attr("x",1e3).attr("y",2500).text(t);Object.keys(e).forEach(t=>{i.style(t,e[t])}),this.hiddenSVG.getBoundingClientRect();const a=i.node().getBBox(),o=window.getComputedStyle(i.node()),s=parseFloat(o.fontSize);i.remove();const r={width:a.width/s,height:a.height/s};return this.metricsCache.set(n,r),r}getTextSize(t,e,n={}){const i=this.getRelativeTextSize(t,n);return{width:i.width,height:i.height,widthPx:i.width*e,heightPx:i.height*e}}clearCache(){this.metricsCache.clear()}destroy(){this.hiddenContainer&&this.hiddenContainer.parentNode&&this.hiddenContainer.parentNode.removeChild(this.hiddenContainer),this.metricsCache.clear()}}class Xi extends ai{#o={tipLabelText:{title:"Tip label text",scaleType:"identity",default:"",nullValue:"",downstream:["updateTipLabelText","updateCoordinates"],hasLegend:!1,subset:"tips"},tipLabelColor:{title:"Tip label color",scaleType:"color",default:"#000000",nullValue:"#808080",otherCategory:"#555555",downstream:[],hasLegend:!0,subset:"tips"},tipLabelSize:{title:"Tip label size",scaleType:"size",default:1,nullValue:1,isCategorical:!1,outputRange:[.5,2],downstream:["updateCoordinates"],hasLegend:!0,subset:"tips"},tipLabelFont:{title:"Tip label font",scaleType:"identity",default:"sans-serif",nullValue:"sans-serif",downstream:["updateCoordinates"],hasLegend:!1,subset:"tips"},tipLabelStyle:{title:"Tip label font style",scaleType:"text",outputValues:["normal","bold","italic","bold italic"],default:"normal",nullValue:"normal",otherCategory:"italic",downstream:["updateCoordinates"],hasLegend:!1,subset:"tips"},nodeLabelText:{title:"Node label text",scaleType:"identity",default:"",nullValue:"",downstream:["updateNodeLabelText"],hasLegend:!1,subset:"all"},nodeLabelSize:{title:"Node label size",scaleType:"size",default:1,nullValue:1,isCategorical:!1,outputRange:[.5,2],downstream:["updateCoordinates"],hasLegend:!1,subset:"all"}};state={treeData:null,layout:"rectangular",aesthetics:Object.fromEntries(Object.keys(this.#o).map(t=>[t,void 0])),viewWidth:800,viewHeight:600,labelSpacing:.1,nodeLabelSizeScale:.67,nodeLabelOffset:.3,maxLabelWidthProportion:.03,branchThicknessProp:.15,minFontPx:12,idealFontPx:18,maxFontPx:32,minBranchThicknessPx:1,minBranchLenProp:.5,collapsedRootLineProp:.05,branchLengthScale:1,treeHeightScale:1};textSizeEstimator;displayedRoot;occupiedWidth;occupiedHeight;branchLenToPxFactor;labelSizeToPxFactor;aestheticsScales={};legends=[];constructor(t={},e=new qi){super(),t.treeData&&t.treeData.tree?e?(t.aesthetics={...this.state.aesthetics,...t.aesthetics},this.state={...this.state,...t},this.textSizeEstimator=e,this.#s(),this.state.treeData.subscribe("treeUpdate",()=>{this.#s()}),this.state.treeData.subscribe("metadataChanged",t=>{if(t.columnIds&&Array.isArray(t.columnIds))if(t.requiresAestheticRefresh){const e={};for(const[n,i]of Object.entries(this.state.aesthetics))i&&t.columnIds.includes(i)&&(e[n]=i);Object.keys(e).length>0&&this.setAesthetics(e,!0)}else this.setAesthetics(Object.fromEntries(t.columnIds.map(t=>[t,void 0])))})):console.error("TreeState initialized without textSizeEstimator"):console.error("TreeState initialized without valid tree data")}#s(){this.displayedRoot=this.state.treeData.tree,this.updateLayout(),this.setAesthetics(this.state.aesthetics,!0)}setLayout(t,e=!1){["circular","rectangular"].includes(t)?(e||this.state.layout!==t)&&(this.state.layout=t,this.update(),this.notify("layoutChange",{layout:t})):console.warn(`Invalid layout type: ${t}`)}setBranchLengthScale(t){t<.01||t>100?console.warn(`Branch length scale out of range: ${t}`):(this.state.branchLengthScale=t,this.updateCoordinates(),this.notify("branchLengthScaleChange",{scale:t}))}setTreeHeightScale(t){t<.1||t>10?console.warn(`Tree height scale out of range: ${t}`):(this.state.treeHeightScale=t,this.updateCoordinates(),this.notify("treeHeightScaleChange",{scale:t}))}setAesthetics(t,e=!1){const n=new Set;let i=!1;for(const[a,o]of Object.entries(t)){const t=this.#o[a];if(t){if(e||o!==this.state.aesthetics[a]){this.state.aesthetics[a]=o,o?(this.aestheticsScales[a]=this.state.treeData.getAesthetic(o,a,t),this.aestheticsScales[a].subscribe("aestheticChange",()=>{this.#r(a,o),this.#l(),this.notify(`${a}Change`)})):this.aestheticsScales[a]=new hi({default:t.default}),this.#r(a,o);for(const e of t.downstream)n.add(e);t.hasLegend&&(i=!0)}this.notify(`${a}Change`)}else console.warn(`Unknown aesthetic: ${a}`)}i&&this.#l();for(const a of n)this[a]()}#r(t,e){const n=this.#o[t];this.state.treeData.tree.each(i=>{e&&null!=e?i.metadata?i[t]=this.aestheticsScales[t].getValue(i.metadata[e]):i[t]=n.default:i[t]=this.aestheticsScales[t].getValue()})}#l(){this.legends=[];for(const[t,e]of Object.entries(this.state.aesthetics)){const n=this.#o[t];if(!n.hasLegend||!e)continue;const i=this.aestheticsScales[t];i&&this.legends.push({aestheticId:t,aesthetic:i,type:n.scaleType})}this.notify("legendsChange")}setTargetTreeDimensions(t,e){this.state.viewWidth=t,this.state.viewHeight=e,this.updateCoordinates()}collapseSubtree(t){t?t.children?(t.collapsedChildren=t.children,delete t.children,this.update()):console.warn("Tried to collapse node with no children"):console.warn("Tried to collapse non-existant node")}expandSubtree(t){t&&t.collapsedChildren&&(t.children=t.collapsedChildren,delete t.collapsedChildren,this.update())}rotateSubtree(t){if(!t)return void console.warn("Tried to rotate non-existent node");if(!t.children||t.children.length<2)return void console.warn("Tried to rotate node with fewer than 2 children");const e=t.children.shift();t.children.push(e),this.update()}hideSubtree(t){if(!t)return void console.warn("Tried to hide non-existent node");if(!t.parent)return void console.warn("Cannot hide the root node");t.hidden=!0;const e=t.parent;e.children&&(e.hiddenChildren=e.hiddenChildren||[],e.hiddenChildren.push(t),e.children=e.children.filter(e=>e!==t),0===e.children.length&&(delete e.children,this.hideSubtree(e))),this.update()}showSubtree(t){if(!t||!t.hidden)return;const e=t.parent;e&&e.hiddenChildren&&(e.hiddenChildren=e.hiddenChildren.filter(e=>e!==t),0===e.hiddenChildren.length&&delete e.hiddenChildren,e.children||(e.children=[]),e.children.push(t),e.children.sort((t,n)=>(e.data.children?e.data.children.indexOf(t.data):0)-(e.data.children?e.data.children.indexOf(n.data):0)),delete t.hidden,this.update())}showAllHidden(){const t=[];this.state.treeData.tree.each(e=>{e.hiddenChildren&&t.push(...e.hiddenChildren)});for(const e of t)this.showSubtree(e)}collapseRoot(t){t&&t!==this.displayedRoot&&(this.displayedRoot=t,this.displayedRoot.collapsedParent=this.displayedRoot.parent,delete this.displayedRoot.parent,this.update())}expandRoot(){if(!this.displayedRoot||!this.displayedRoot.collapsedParent)return;this.displayedRoot.parent=this.displayedRoot.collapsedParent,delete this.displayedRoot.collapsedParent;let t=this.displayedRoot;for(;t.parent&&!t.collapsedParent;)t=t.parent;this.displayedRoot=t,this.update()}updateTipLabelText(){this.state.treeData.tree.each(t=>{null===this.state.aesthetics.tipLabelText?t.tipLabelText="":!t.children&&!t.collapsedChildren||void 0!==this.state.aesthetics.tipLabelText&&t.tipLabelText?t.tipLabelText||(t.tipLabelText=t.data.name||""):t.tipLabelText=`Clade with ${t.leafCount} tips`})}updateNodeLabelText(){this.state.treeData.tree.each(t=>{t.children||t.collapsedChildren?t.nodeLabelText=t.data.name||"":t.nodeLabelText||(t.tipLabel=t.data.name||"")})}update(){this.updateLayout(),this.updateCoordinates()}updateLayout(){kn().separation((t,e)=>1)(this.displayedRoot),this.displayedRoot.each(t=>{t.parent?(t.branchLen=t.data.length?t.data.length:0,t.y=t.parent.y+t.branchLen):t.y=0}),this.displayedRoot.each(t=>{const e=t.x,n=t.y;t.x=n,t.y=e,t.angle=t.y*Math.PI*2+Math.PI,t.cos=Math.cos(t.angle),t.sin=Math.sin(t.angle),t.radius=t.x}),this.displayedRoot.eachAfter(t=>{t.x=t.x-this.displayedRoot.x,t.y=t.y-this.displayedRoot.y})}getCollapsedTriangleHeight(t){return t.tipLabelSizePx+1.1}getCollapsedTriangleOffset(t){return.52*this.getCollapsedTriangleHeight(t)}updateCoordinates(){let t;this.displayedRoot.each(t=>{t.tipLabelBounds=this.textSizeEstimator.getRelativeTextSize(t.tipLabelText,{"font-family":t.tipLabelFont,"font-style":t.tipLabelStyle}),t.nodeLabelBounds=this.textSizeEstimator.getRelativeTextSize(t.nodeLabelText,{"font-family":t.nodeLabelFont,"font-style":t.nodeLabelStyle})}),t="circular"===this.state.layout?Vi(this.displayedRoot,this.state):function(t,e){const n=t.leaves().map(t=>({x:t.x,width:(t.tipLabelBounds.width+e.nodeLabelOffset)*t.tipLabelSize,height:t.tipLabelBounds.height*t.tipLabelSize,labelScale:t.tipLabelSize}));let i=0,a=1/0,o=0,s=1/0;function r(t){t<a&&(a=t<i?i:t)}function l(t){t>i&&(i=t>a?a:t)}function h(t){t<s&&(s=t<o?o:t)}function c(t){t>o&&(o=t>s?s:t)}const u=Math.min(...n.map(t=>t.labelScale)),d=Math.max(...n.map(t=>t.x)),p=t.descendants().filter(t=>t.data.length>0&&t.children),f=p.length>0?Math.min(...p.map(t=>t.data.length)):1/0;return c(e.minFontPx/u),l(Math.max(...n.map(t=>t.width*o/(d/e.minBranchLenProp-t.x)))),r(Math.min(...n.map(t=>(e.viewWidth-t.width*o)/t.x))),h(Math.min(...n.map(t=>(e.viewWidth-t.x*i)/t.width))),o!=s&&h(e.viewHeight/n.reduce((t,e)=>t+e.height,0)),o!=s&&c(e.idealFontPx/u),i!=a&&r(Math.min(...n.map(t=>(e.viewWidth-t.width*o)/t.x))),isFinite(f)&&(i!=a&&l(e.minBranchThicknessPx/f),o!=s&&h(Math.min(...n.map(t=>(e.viewWidth-t.x*i)/t.width)))),o!=s&&h(e.maxFontPx/u),{branchLenToPxFactor_min:i,branchLenToPxFactor_max:a,labelSizeToPxFactor_min:o,labelSizeToPxFactor_max:s}}(this.displayedRoot,this.state),this.branchLenToPxFactor=t.branchLenToPxFactor_max*this.state.branchLengthScale,this.labelSizeToPxFactor=t.labelSizeToPxFactor_min,this.displayedRoot.each(t=>{t.branchLenPx=t.branchLen*this.branchLenToPxFactor,t.tipLabelSizePx=t.tipLabelSize*this.labelSizeToPxFactor,t.nodeLabelSizePx=t.nodeLabelSize*this.labelSizeToPxFactor*this.state.nodeLabelSizeScale;let e=t.tipLabelSizePx*this.state.nodeLabelOffset;t.collapsedChildren&&(e+=1.3*this.getCollapsedTriangleOffset(t)),t.tipLabelXOffsetPx=e,t.nodeLabelXOffsetPx=t.nodeLabelSizePx*this.state.nodeLabelOffset,t.tipLabelYOffsetPx=t.tipLabelSizePx*t.tipLabelBounds.height/2,t.nodeLabelYOffsetPx=t.nodeLabelSizePx*t.nodeLabelBounds.height/2,t.tipLabelBounds.widthPx=t.tipLabelBounds.width*t.tipLabelSizePx,t.tipLabelBounds.heightPx=t.tipLabelBounds.height*t.tipLabelSizePx}),"circular"===this.state.layout?this.displayedRoot.each(t=>{t.radiusPx=t.radius*this.branchLenToPxFactor,t.xPx=t.radiusPx*t.cos,t.yPx=t.radiusPx*t.sin}):this.displayedRoot.each(t=>{t.xPx=t.x*this.branchLenToPxFactor,t.yPx=t.y*this.displayedRoot.leaves().length*this.labelSizeToPxFactor*(1+this.state.labelSpacing)*this.state.treeHeightScale}),"circular"===this.state.layout?this.state.treeData.tree.eachAfter(t=>{if(t.children)t.bounds={minRadius:t.radiusPx,maxRadius:Math.max(...t.children.map(t=>t.bounds.maxRadius)),minAngle:Math.min(...t.children.map(t=>t.bounds.minAngle)),maxAngle:Math.max(...t.children.map(t=>t.bounds.maxAngle)),minX:Math.min(...t.children.map(t=>t.bounds.minX)),maxX:Math.max(...t.children.map(t=>t.bounds.maxX)),minY:Math.min(...t.children.map(t=>t.bounds.minY)),maxY:Math.max(...t.children.map(t=>t.bounds.maxY))};else{const e=t.radiusPx,n=e+t.tipLabelXOffsetPx+t.tipLabelBounds.widthPx,i=Math.atan(t.tipLabelYOffsetPx/t.radiusPx),a=t.angle-i,o=t.angle+i,s=[e*Math.cos(a),e*Math.cos(o),n*Math.cos(o),n*Math.cos(a)],r=[e*Math.sin(a),e*Math.sin(o),n*Math.sin(o),n*Math.sin(a)];t.bounds={minRadius:e,maxRadius:n,minAngle:a,maxAngle:o,minX:Math.min(...s),maxX:Math.max(...s),minY:Math.min(...r),maxY:Math.max(...r)}}}):this.state.treeData.tree.eachAfter(t=>{t.children?t.bounds={minX:t.xPx,maxX:Math.max(...t.children.map(t=>t.bounds.maxX)),minY:Math.min(...t.children.map(t=>t.bounds.minY)),maxY:Math.max(...t.children.map(t=>t.bounds.maxY))}:t.bounds={minX:t.xPx,maxX:t.xPx+t.tipLabelXOffsetPx+t.tipLabelBounds.widthPx,minY:t.yPx-t.tipLabelYOffsetPx,maxY:t.yPx+t.tipLabelYOffsetPx}}),this.notify("coordinateChange")}}const Oi={refresh:["m 16,7 h 5 V 2","M 22,12 A 10,10 0 0 1 13.58,21.9 10,10 0 0 1 2.5,15.2 10,10 0 0 1 7.4,3.14 10,10 0 0 1 20,6"],outwardArrows:["m 9,19 3,3 3,-3","M 12,22 V 15","m 9,5 3,-3 3,3","M 12,2 V 9","m 5,9 -3,3 3,3","M 2,12 H 9","M 19,15 22,12 19,9","M 22,12 H 15"],compress:["M 5,12 H 19","m 9,18 3,-3 3,3","m 12,15 v 7","m 9,6 3,3 3,-3","M 12,9 V 2"],expand:["M 5,2 H 19","M 5,22 H 19","m 9,8 3,-3 3,3","m 9,16 3,3 3,-3","M 12,5 V 19"],circle:["M 12,2 A 10,10 0 1 1 12,22 A 10,10 0 1 1 12,2"],trash:["M 3,6 H 21","M 19,6 V 20 A 2,2 0 0 1 17,22 H 7 A 2,2 0 0 1 5,20 V 6","M 8,6 V 4 A 2,2 0 0 1 10,2 H 14 A 2,2 0 0 1 16,4 V 6","M 10,11 V 17","M 14,11 V 17"],rotate:["M 3,12 H 8","M 13,6 H 8 v 12 h 5","m 17,4 c 0,0 9,8 0,16","M 17,8 V 4 h 4","M 21,20 H 17 V 16"],edit:["m 12,8 -8,8 -1,5 5,-1 8,-8 z","M 21,7 18,10 14,6 17,3 Z"]};class Yi{constructor(t={}){this.state={aesthetic:null,x:0,y:0,origin:"top left",maxX:1/0,maxY:1/0,titleFontSize:16,labelFontSize:14,...t},this.coordinates={},this.group=null,this.textSizeEstimator=this.state.treeState.textSizeEstimator}render(t){this.group=t.append("g").attr("class","ht-legend"),this.updateCoordinates(),this.updatePosition()}updateCoordinates(){throw new Error("updateCoordinates must be implemented by subclass")}updatePosition(){if(!this.group)return;let t=this.state.x,e=this.state.y;const{width:n,height:i}=this.coordinates;this.state.origin.includes("right")&&(t-=n),this.state.origin.includes("bottom")&&(e-=i),this.group.attr("transform",`translate(${t}, ${e})`)}renderTitle(t){return this.group.append("text").attr("class","legend-title").attr("x",0).attr("y",0).attr("text-anchor","start").style("font-size",`${this.state.titleFontSize}px`).style("text-decoration","underline").text(t)}}class ji extends Yi{constructor(t={}){super(t),this.scaleBarEdgeHeight=6,this.titleSpacing=10,this.unitLabelSpacing=2,this.minBarLength=80,this.maxBarLength=160,this.lineThickness=2,this.showTitle=!1,this.title="Branch length"}updateCoordinates(){let t=Jn(1),e=t*this.state.treeState.branchLenToPxFactor;for((e<this.minBarLength||e>this.maxBarLength)&&(t=Jn(this.minBarLength/this.state.treeState.branchLenToPxFactor),e=t*this.state.treeState.branchLenToPxFactor);e<this.minBarLength;)t*=2,e=t*this.state.treeState.branchLenToPxFactor;for(;e>this.maxBarLength;)t/=2,e=t*this.state.treeState.branchLenToPxFactor;t=t.toPrecision(3);const n=this.textSizeEstimator.getTextSize(t,this.state.labelFontSize);this.textSizeEstimator.getTextSize(this.title,this.state.titleFontSize);let i=0;this.showTitle&&(i=this.state.titleFontSize+this.titleSpacing);const a=i+this.unitLabelSpacing+n.heightPx+10;this.coordinates={width:e+this.lineThickness,height:a+this.scaleBarEdgeHeight,title:{x:0,y:this.state.titleFontSize,text:"Branch Length"},bar:{x1:0,y1:a,x2:e,y2:a},leftTick:{x1:0,y1:a-this.scaleBarEdgeHeight,x2:0,y2:a+this.scaleBarEdgeHeight},rightTick:{x1:e,y1:a-this.scaleBarEdgeHeight,x2:e,y2:a+this.scaleBarEdgeHeight},label:{x:e/2,y:a-this.unitLabelSpacing,text:t}}}render(t){super.render(t),this.showTitle&&this.renderTitle(this.coordinates.title.text).attr("x",this.coordinates.title.x).attr("y",this.coordinates.title.y),this.group.append("line").attr("class","bar").attr("x1",this.coordinates.bar.x1).attr("y1",this.coordinates.bar.y1).attr("x2",this.coordinates.bar.x2).attr("y2",this.coordinates.bar.y2).attr("stroke","#000").attr("stroke-width",this.lineThickness),this.group.append("line").attr("class","left-tick").attr("x1",this.coordinates.leftTick.x1).attr("y1",this.coordinates.leftTick.y1).attr("x2",this.coordinates.leftTick.x2).attr("y2",this.coordinates.leftTick.y2).attr("stroke","#000").attr("stroke-width",this.lineThickness),this.group.append("line").attr("class","right-tick").attr("x1",this.coordinates.rightTick.x1).attr("y1",this.coordinates.rightTick.y1).attr("x2",this.coordinates.rightTick.x2).attr("y2",this.coordinates.rightTick.y2).attr("stroke","#000").attr("stroke-width",this.lineThickness),this.group.append("text").attr("class","label").attr("x",this.coordinates.label.x).attr("y",this.coordinates.label.y).attr("text-anchor","middle").attr("dominant-baseline","ideographic").style("font-size",`${this.state.labelFontSize}px`).text(this.coordinates.label.text)}}class Gi extends Yi{constructor(t={}){super(t),this.padding=10,this.exampleLetter="A",this.tickHeight=5,this.verticalSpacing=5,this.showTitle=!0}updateCoordinates(){const t=this.state.aesthetic.scale.dataMin,e=this.state.aesthetic.scale.dataMax,n=this.state.aesthetic.state.outputRange[0],i=this.state.aesthetic.state.outputRange[1],a=ni(t,e,5),o=i*this.state.treeState.labelSizeToPxFactor*.7,s=n*this.state.treeState.labelSizeToPxFactor*.7;this.textSizeEstimator.getTextSize(this.state.aesthetic.state.title,this.state.titleFontSize);const r=Math.max(30*a.length,100),l=a.map(t=>{const e=ii(t,a);return this.textSizeEstimator.getTextSize(e,this.state.labelFontSize)}),h=l[0].widthPx/2,c=l[l.length-1].widthPx/2,u=r+h+c;let d=0;this.showTitle&&(d=this.state.titleFontSize+this.verticalSpacing);const p=d+o,f=this.textSizeEstimator.getTextSize(this.state.aesthetic.state.inputUnits||"",this.state.labelFontSize),g=p+this.tickHeight+this.state.labelFontSize+f.heightPx;if(this.coordinates={width:u,height:g,leftOverhang:h,title:{x:h,y:this.state.titleFontSize,text:this.state.aesthetic.state.title},polygon:[],ticks:[],labels:[],units:{x:u/2,y:g,text:this.state.aesthetic.state.inputUnits||""}},t===e){const e=h+r/2;this.coordinates.ticks.push({x1:e,y1:p,x2:e,y2:p+this.tickHeight}),this.coordinates.labels.push({x:e,y:p+this.tickHeight,text:ii(t,a)});const n=(s+o)/2;this.coordinates.polygon=[{x:h,y:p},{x:h,y:p-n},{x:h+r,y:p-n},{x:h+r,y:p}]}else a.forEach((t,e)=>{const n=h+e/(a.length-1)*r;this.coordinates.ticks.push({x1:n,y1:p,x2:n,y2:p+this.tickHeight}),this.coordinates.labels.push({x:n,y:p+this.tickHeight,text:ii(t,a)})}),this.coordinates.polygon=[{x:h,y:p},{x:h,y:p-s},{x:h+r,y:p-o},{x:h+r,y:p}]}render(t){super.render(t),this.showTitle&&this.renderTitle(this.coordinates.title.text).attr("x",this.coordinates.title.x).attr("y",this.coordinates.title.y);const e=this.coordinates.polygon.map(t=>`${t.x},${t.y}`).join(" ");this.group.append("polygon").attr("points",e).attr("fill","#f0f0f0").attr("stroke","#ccc").attr("stroke-width",1),this.coordinates.ticks.forEach(t=>{this.group.append("line").attr("x1",t.x1).attr("y1",t.y1).attr("x2",t.x2).attr("y2",t.y2).attr("stroke","#000").attr("stroke-width",1)}),this.coordinates.labels.forEach(t=>{this.group.append("text").attr("x",t.x).attr("y",t.y).attr("text-anchor","middle").attr("dominant-baseline","hanging").style("font-size",`${this.state.labelFontSize}px`).text(t.text)}),this.coordinates.units.text&&this.group.append("text").attr("x",this.coordinates.units.x).attr("y",this.coordinates.units.y).attr("text-anchor","middle").attr("dominant-baseline","ideographic").style("font-size",`${this.state.labelFontSize}px`).style("font-style","italic").text(this.coordinates.units.text)}}class Ui extends Yi{constructor(t={}){super(t),this.exampleLetter="A",this.verticalSpacing=5,this.horizontalSpacing=10,this.showTitle=!0,this.squareSize=12,this.itemLabelGap=5,this.itemGap=15,this.maxCategoriesPerRow=5,this.gradientHeight=20,this.tickHeight=5,this.numGradientStops=20}updateCoordinates(){const t=this.state.aesthetic,e=t.state.isCategorical,n=this.textSizeEstimator.getTextSize(t.state.title,this.state.titleFontSize);let i=0;this.showTitle&&(i=this.state.titleFontSize+this.verticalSpacing),e?this.#h(i,n):this.#c(i,n)}#h(t,e){const n=this.state.aesthetic,i=n.scale.categories,a=this.state.maxX-this.state.x;this.coordinates={width:0,height:t,title:{x:0,y:this.state.titleFontSize,text:n.state.title},items:[],isCategorical:!0};let o=0,s=t+this.verticalSpacing+this.squareSize/2,r=this.squareSize;i.slice(0,n.state.maxCategories).forEach((t,e)=>{const l=n.scale.getValue(t),h=""===t?"No data":t,c=this.textSizeEstimator.getTextSize(h,this.state.labelFontSize),u=this.squareSize+this.itemLabelGap+c.widthPx;o>0&&o+u>a&&(o=0,s+=r+this.verticalSpacing,r=this.squareSize),this.coordinates.items.push({x:o,y:s,color:l,label:e<n.state.maxCategories-1||e==i.length-1?h:n.state.otherLabel,squareX:o,squareY:s-this.squareSize/2,labelX:o+this.squareSize+this.itemLabelGap,labelY:s}),o+=u+this.itemGap,this.coordinates.width=Math.max(this.coordinates.width,o-this.itemGap)});const l=n.values.some(t=>null==t);if(n.state.showNullInLegend&&l){const t=n.state.nullValue,e="No Data",i=this.textSizeEstimator.getTextSize(e,this.state.labelFontSize),l=this.squareSize+this.itemLabelGap+i.widthPx;o>0&&o+l>a&&(o=0,s+=r+this.verticalSpacing,r=this.squareSize),this.coordinates.items.push({x:o,y:s,color:t,label:e,squareX:o,squareY:s-this.squareSize/2,labelX:o+this.squareSize+this.itemLabelGap,labelY:s}),o+=l+this.itemGap,this.coordinates.width=Math.max(this.coordinates.width,o-this.itemGap)}this.coordinates.height=s+this.squareSize/2}#c(t,e){const n=this.state.aesthetic,i=n.scale.dataMin,a=n.scale.dataMax,o=ni(i,a,5),s=Math.max(30*o.length,120),r=o.map(t=>{const e=ii(t,o);return this.textSizeEstimator.getTextSize(e,this.state.labelFontSize)}),l=r[0].widthPx/2,h=r[r.length-1].widthPx/2,c=s+l+h,u=t+this.verticalSpacing,d=u+this.gradientHeight,p=d+this.tickHeight,f=this.textSizeEstimator.getTextSize(n.state.inputUnits||"",this.state.labelFontSize);let g=p+this.state.labelFontSize+f.heightPx;if(this.coordinates={width:c,height:g,leftOverhang:l,isCategorical:!1,title:{x:l,y:this.state.titleFontSize,text:n.state.title},gradient:{x:l,y:u,width:s,height:this.gradientHeight},ticks:[],labels:[],units:{x:c/2,y:g,text:n.state.inputUnits||""},nullItem:null},i===a){const t=l+s/2;this.coordinates.ticks.push({x1:t,y1:d,x2:t,y2:d+this.tickHeight}),this.coordinates.labels.push({x:t,y:p,text:ii(i,o)})}else o.forEach((t,e)=>{const n=l+e/(o.length-1)*s;this.coordinates.ticks.push({x1:n,y1:d,x2:n,y2:d+this.tickHeight}),this.coordinates.labels.push({x:n,y:p,text:ii(t,o)})});if(n.state.showNullInLegend){const t=n.state.nullValue,e="No Data";this.textSizeEstimator.getTextSize(e,this.state.labelFontSize);const i=g+this.verticalSpacing;this.coordinates.nullItem={x:l,y:i+this.squareSize/2,color:t,label:e,squareX:l,squareY:i,labelX:l+this.squareSize+this.itemLabelGap,labelY:i+this.squareSize/2},this.coordinates.height=i+this.squareSize}}render(t){super.render(t),this.showTitle&&this.renderTitle(this.coordinates.title.text).attr("x",this.coordinates.title.x).attr("y",this.coordinates.title.y),this.coordinates.isCategorical?this.#u():this.#d()}#u(){this.coordinates.items.forEach(t=>{this.group.append("rect").attr("x",t.squareX).attr("y",t.squareY).attr("width",this.squareSize).attr("height",this.squareSize).attr("fill",t.color).attr("stroke","#000").attr("stroke-width",1),this.group.append("text").attr("x",t.labelX).attr("y",t.labelY).attr("text-anchor","start").attr("dominant-baseline","central").style("font-size",`${this.state.labelFontSize}px`).text(t.label)})}#d(){const t=this.state.aesthetic,e=t.scale.dataMin,n=t.scale.dataMax,i=`color-gradient-${Math.random().toString(36).substr(2,9)}`,a=this.group.append("defs").append("linearGradient").attr("id",i).attr("x1","0%").attr("x2","100%").attr("y1","0%").attr("y2","0%");if(e===n){const n=t.scale.getValue(e);a.append("stop").attr("offset","0%").attr("stop-color",n),a.append("stop").attr("offset","100%").attr("stop-color",n)}else for(let o=0;o<=this.numGradientStops;o++){const i=o/this.numGradientStops,s=e+i*(n-e),r=t.scale.getValue(s);a.append("stop").attr("offset",100*i+"%").attr("stop-color",r)}this.group.append("rect").attr("x",this.coordinates.gradient.x).attr("y",this.coordinates.gradient.y).attr("width",this.coordinates.gradient.width).attr("height",this.coordinates.gradient.height).style("fill",`url(#${i})`).style("stroke","#000").style("stroke-width",1),this.coordinates.ticks.forEach(t=>{this.group.append("line").attr("x1",t.x1).attr("y1",t.y1).attr("x2",t.x2).attr("y2",t.y2).attr("stroke","#000").attr("stroke-width",1)}),this.coordinates.labels.forEach(t=>{this.group.append("text").attr("x",t.x).attr("y",t.y).attr("text-anchor","middle").attr("dominant-baseline","hanging").style("font-size",`${this.state.labelFontSize}px`).text(t.text)}),this.coordinates.units.text&&this.group.append("text").attr("x",this.coordinates.units.x).attr("y",this.coordinates.units.y).attr("text-anchor","middle").attr("dominant-baseline","ideographic").style("font-size",`${this.state.labelFontSize}px`).style("font-style","italic").text(this.coordinates.units.text)}}class Zi{constructor(t,e,n={}){if(!t)throw new Error("TreeView requires a TreeState instance");if(!e)throw new Error("TreeView requires an SVG container element");this.treeState=t,this.svg=bt(e),this.options={buttonSize:25,controlsMargin:3,buttonPadding:2,manualZoomAndPanEnabled:!0,autoZoom:"Default",autoPan:"Default",transitionDuration:500,legendSpacing:10,legendPadding:10,...n},this.layers={},this.selections={},this.legendInstances=[],this.currentTransform={x:0,y:0,k:1},this.isTransitioning=!1,this.isExpanding=!1,this.activeTransitions=new Set,this.selectedNode=null,this.selectionButtons=[{id:"collapse-subtree",icon:"compress",isVisible:t=>t&&t!==this.treeState.displayedRoot&&(t.children||t.collapsedChildren),onClick:t=>{t&&t!==this.treeState.displayedRoot&&t.children&&(this.treeState.collapseSubtree(t),this.#p())}},{id:"collapse-root",icon:"expand",isVisible:t=>t&&t!==this.treeState.displayedRoot&&(t.children||t.collapsedChildren),onClick:t=>{t&&t!==this.treeState.displayedRoot&&t.children&&(this.treeState.collapseRoot(t),this.#p())}},{id:"hide",icon:"trash",isVisible:t=>t&&t!==this.treeState.displayedRoot,onClick:t=>{t&&t!==this.treeState.displayedRoot&&(this.treeState.hideSubtree(t),this.#p())}},{id:"rotate-subtree",icon:"rotate",isVisible:t=>{if(!t||!t.children)return!1;return t.children.filter(t=>!t.hidden).length>1},onClick:t=>{if(t&&t.children){t.children.filter(t=>!t.hidden).length>1&&this.treeState.rotateSubtree(t)}}}],this.#f(),this.initializeZoom(),this.#g(),this.#m()}destroy(){this.svg.selectAll("*").remove(),this.layers={},this.selections={},this.selectedNode=null,this.legendInstances=[]}reattach(t){this.svg=bt(t),this.#f(),this.initializeZoom(),this.#y(!1),this.#b(!1),this.#x(!1),this.#l(!1),this.fitToView({transition:!1,forcePanToTop:!0})}#f(){const t=this.svg.append("g").attr("class","tree-elements");this.layers.branchLayer=t.append("g").attr("class","branch-layer"),this.layers.nodeLayer=t.append("g").attr("class","node-layer"),this.layers.hitLayer=t.append("g").attr("class","hit-layer"),this.layers.legendLayer=t.append("g").attr("class","legend-layer"),this.layers.treeGroup=t,this.layers.selectionRect=t.append("path").attr("class","selection-rect").attr("fill","none").attr("stroke","grey").attr("stroke-width",2).attr("stroke-dasharray","5,5").attr("pointer-events","none").style("display","none"),this.layers.selectionBtns=this.svg.append("g").attr("class","selection-btns").style("display","none"),this.#v()}#p(){this.selectedNode=null,this.layers.selectionRect.style("display","none"),this.layers.selectionBtns.style("display","none")}#v(){const t=this.layers.selectionBtns;this.selectionButtons.forEach(e=>{const n=t.append("g").attr("class",`btn-${e.id}`).style("cursor","pointer").on("click",()=>{e.onClick(this.selectedNode)});!function(t,e,n,i=2){const a=Oi[e],o=(n-2*i)/24,s=t.append("rect").attr("width",n).attr("height",n).attr("rx","5px").attr("ry","5px").attr("fill","#CCC"),r=t.append("g").attr("transform",`translate(${i}, ${i}) scale(${o})`).attr("stroke","#555").attr("fill","none").attr("stroke-linecap","round").attr("stroke-linejoin","round").attr("stroke-width",2);a.forEach(t=>{r.append("path").attr("d",t)})}(n,e.icon,this.options.buttonSize),e.element=n})}initializeZoom(){this.treeZoom=Qn().filter(t=>!!this.options.manualZoomAndPanEnabled&&"dblclick"!==t.type).on("zoom",t=>{this.currentTransform=t.transform,this.layers.treeGroup.attr("transform",t.transform),this.#w(null===t.sourceEvent)}),this.svg.call(this.treeZoom)}#g(){this.treeState.subscribe("coordinateChange",()=>{this.#_()}),this.treeState.subscribe("layoutChange",()=>{this.#_()}),this.treeState.subscribe("legendsChange",()=>{this.#l(!0)}),this.treeState.subscribe("tipLabelTextChange",()=>{this.#C()}),this.treeState.subscribe("tipLabelColorChange",()=>{this.#k()}),this.treeState.subscribe("tipLabelSizeChange",()=>{this.#S(),this.#l(!0)}),this.treeState.subscribe("tipLabelFontChange",()=>{this.#L()}),this.treeState.subscribe("tipLabelStyleChange",()=>{this.#T()}),this.treeState.subscribe("nodeLabelTextChange",()=>{this.#M()})}#m(){this.#y(!1),this.#b(!1),this.#x(!1),this.#l(!1),this.fitToView({transition:!1,forcePanToTop:!0})}#_(){const t=this.#y(!0),e=this.#b(!0);this.#x(!0),this.#l(!0),this.selectedNode&&this.#P(!0),this.isExpanding&&t&&e?setTimeout(()=>{t.transition("branch group fade in").duration(150).attr("opacity",1),e.transition("node group fade in").duration(150).attr("opacity",1),this.layers.selectionBtns.attr("opacity",0).transition("fade in selection buttons").duration(150).attr("opacity",1),setTimeout(()=>{this.isExpanding=!1},150)},this.options.transitionDuration):this.selectedNode&&setTimeout(()=>{this.#w(!1)},this.options.transitionDuration),this.fitToView()}#C(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").text(t=>t.tipLabelText||"")}#k(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("fill",t=>t.tipLabelColor||"#000")}#S(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("font-size",t=>`${t.tipLabelSizePx||12}px`)}#L(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("font-family",t=>t.tipLabelFont||"sans-serif")}#T(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("font-style",t=>t.tipLabelStyle.includes("italic")?"italic":"normal").style("font-weight",t=>t.tipLabelStyle.includes("bold")?"bold":"normal")}#M(){this.selections.nodes&&this.selections.nodes.selectAll(".node-label").text(t=>t.nodeLabelText||"")}#l(t=!0){this.layers.legendLayer.selectAll("*").remove(),this.legendInstances=[];const e=this.#E();if(!e)return;e.maxX,e.minX;let n=e.minX,i=e.maxY+this.options.legendSpacing;const a=new ji({treeState:this.treeState,x:n,y:i,origin:"top left",maxX:e.maxX,maxY:1/0});a.render(this.layers.legendLayer),this.legendInstances.push(a),n+=a.coordinates.width+this.options.legendSpacing;for(const o of this.treeState.legends){let t;"size"===o.type?t=new Gi({treeState:this.treeState,aesthetic:o.aesthetic,x:n,y:i,origin:"top left",maxX:e.maxX,maxY:1/0}):"color"===o.type&&(t=new Ui({treeState:this.treeState,aesthetic:o.aesthetic,x:n,y:i,origin:"top left",maxX:e.maxX,maxY:1/0})),n+t.coordinates.width+this.options.legendSpacing>e.maxX&&(n=e.minX,i+=Math.max(...this.legendInstances.map(t=>t.coordinates.height))),t&&(t.render(this.layers.legendLayer),this.legendInstances.push(t),n+=t.coordinates.width+this.options.legendSpacing)}this.fitToView({transition:t})}fitToView(t){if(!((t={transition:!0,padding:5,autoZoom:this.options.autoZoom,autoPan:this.options.autoPan,forcePanToTop:!1,...t}).autoZoom&&"None"!=t.autoZoom||t.autoPan&&"None"!=t.autoPan))return;const{width:e,height:n}=this.svg.node().getBoundingClientRect(),i=this.getCurrentBoundsWithLegends();if(!i)return;i.minX-=t.padding,i.maxX+=t.padding,i.minY-=t.padding,i.maxY+=t.padding;const a=i.maxX-i.minX,o=i.maxY-i.minY,s=e-0,r=n;let l=this.currentTransform.k,h=this.currentTransform.x,c=this.currentTransform.y;const u=s/a,d=r/o;if("Default"==t.autoZoom&&("circular"!=this.treeState.state.layout&&this.options.manualZoomAndPanEnabled?t.autoZoom="X":t.autoZoom="Both"),t.autoZoom&&"None"!=t.autoZoom&&("X"==t.autoZoom?l=Math.min(1,u):"Y"==t.autoZoom?l=Math.min(1,d):"Both"==t.autoZoom?l=Math.min(u,d):console.error(`Value of ${t.autoZoom} is invalid for input.autoZoom.`)),"Default"==t.autoPan&&(t.autoPan="Both"),t.autoPan&&"None"!=t.autoPan){if("Both"==t.autoPan||"X"==t.autoPan){const t=a*l;if(t<=s)h=0+(s-t)/2-i.minX*l;else{const t=-i.minX*l-0,n=e-i.maxX*l;h=t>0?0-i.minX*l:n>0?e-i.maxX*l:0+s/2-(i.minX+i.maxX)/2*l}}if("Both"==t.autoPan||"Y"==t.autoPan){const e=o*l;if(e<=r)c=(r-e)/2-i.minY*l;else{const e=-i.minY*l,a=n-i.maxY*l;c>e||t.forcePanToTop?c=e:c<a&&(c=a)}}}const p=Xn.translate(h,c).scale(l);t.transition?this.svg.transition("zoom").duration(this.options.transitionDuration).call(this.treeZoom.transform,p):this.svg.call(this.treeZoom.transform,p)}#E(){const t=this.treeState.displayedRoot;return{minX:t.bounds.minX,maxX:t.bounds.maxX,minY:t.bounds.minY,maxY:t.bounds.maxY}}getCurrentBoundsWithLegends(){const t=this.#E();if(!t)return null;let e=t.maxY,n=t.minX;for(const i of this.legendInstances)i.coordinates&&(e=Math.max(e,i.state.y+i.coordinates.height));return"circular"!==this.treeState.state.layout&&this.treeState.displayedRoot.collapsedParent&&(n-=this.#$()),{minX:n,maxX:t.maxX,minY:t.minY,maxY:e}}#z(t){this.selectedNode===t?this.#p():(this.selectedNode=t,this.layers.selectionRect.attr("d",this.#N(t)).style("display","block"),this.#w(!1))}#P(t=!1){this.selectedNode&&(t?this.layers.selectionRect.transition("update selection rect").duration(this.options.transitionDuration).attr("d",this.#N(this.selectedNode)):this.layers.selectionRect.attr("d",this.#N(this.selectedNode)))}#N(t){if(!t)return"";let e,n,i,a,o,s;if("circular"===this.treeState.state.layout)e={x:t.bounds.minRadius*Math.cos(t.bounds.minAngle),y:t.bounds.minRadius*Math.sin(t.bounds.minAngle)},i={x:t.bounds.maxRadius*Math.cos(t.bounds.maxAngle),y:t.bounds.maxRadius*Math.sin(t.bounds.maxAngle)},s=this.#A(i.x,i.y,t.bounds.maxRadius,t.bounds.maxAngle,t.bounds.minAngle,!1),o=this.#A(e.x,e.y,t.bounds.minRadius,t.bounds.minAngle,t.bounds.maxAngle,!0);else{e={x:t.bounds.minX,y:t.bounds.minY},n={x:t.bounds.minX,y:t.bounds.maxY},i={x:t.bounds.maxX,y:t.bounds.maxY},a={x:t.bounds.maxX,y:t.bounds.minY};const r=this.treeState.displayedRoot,l=r.bounds.maxY-r.bounds.minY,h=Math.abs(n.y-e.y)/l,c=Math.max(1,Math.ceil(h/.25));o=this.#R(e,n,c),s=this.#R(i,a,c)}return`M${e.x},${e.y} ${o} L${i.x},${i.y} ${s} Z`}#R(t,e,n=1){let i="";for(let a=0;a<n;a++){const o=a/n,s=(a+1)/n,r=t.x+(e.x-t.x)*o,l=t.y+(e.y-t.y)*o,h=t.x+(e.x-t.x)*s,c=t.y+(e.y-t.y)*s;i+=`C${r},${l+(c-l)/3} ${h},${c-(c-l)/3} ${h},${c}`,a<n-1&&(i+=" ")}return i}#w(t=!0,e=1.1){if(!this.selectedNode)return void this.layers.selectionBtns.style("display","none");let n,i;if("circular"===this.treeState.state.layout){const t=this.selectedNode.bounds.minAngle,e=this.selectedNode.bounds.maxAngle,a=this.selectedNode.bounds.minRadius,o=this.selectedNode.bounds.maxRadius,s=20;let r=1/0,l=0;for(let n=0;n<=s;n++){const i=t+(e-t)*n/s,h=a*Math.cos(i),c=a*Math.sin(i),u=o*Math.cos(i),d=o*Math.sin(i);h<r&&(r=h,l=c),u<r&&(r=u,l=d)}n=r,i=l}else n=this.selectedNode.bounds.minX,i=this.selectedNode.bounds.minY;let a=0;this.selectionButtons.forEach(t=>{if(t.isVisible(this.selectedNode)){const n=a*(this.options.buttonSize*e);t.element.style("display","block").attr("transform",`translate(0, ${n})`),a++}else t.element.style("display","none")});const o=a*this.options.buttonSize+(a-1)*this.options.buttonSize*(e-1);let s=n*this.currentTransform.k+this.currentTransform.x-this.options.buttonSize*e,r=i*this.currentTransform.k+this.currentTransform.y-this.options.buttonSize*(e-1);const{width:l,height:h}=this.svg.node().getBoundingClientRect();s=Math.max(s,0),s=Math.min(s,l-this.options.buttonSize),r=Math.max(r,0),r=Math.min(r,h-o),t?this.layers.selectionBtns.attr("opacity",0).attr("transform",`translate(${s},${r})`):this.layers.selectionBtns.attr("transform",`translate(${s},${r})`).attr("opacity",1).style("display","block")}#x(){const t=this.treeState.displayedRoot;if(!t)return;const e="circular"===this.treeState.state.layout,n=this.treeState.labelSizeToPxFactor*this.treeState.state.branchThicknessProp,i=this.#$(),a=this.layers.hitLayer.selectAll(".hit").data(t.descendants().filter(t=>{if(!t.children)return!1;return t.children.filter(t=>!t.hidden).length>1}),t=>t.id);a.exit().remove();a.enter().append("path").attr("class","hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{this.#z(e),t.stopPropagation()}).merge(a).attr("d",t=>this.#N(t)),this.layers.hitLayer.selectAll(".hit").sort((t,e)=>t.depth-e.depth);const o=this.layers.hitLayer.selectAll(".tip-hit").data(t.descendants().filter(t=>!t.children&&!t.collapsedChildren),t=>t.id);o.exit().remove();o.enter().append("path").attr("class","tip-hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{this.#z(e),t.stopPropagation()}).merge(o).attr("d",t=>this.#N(t));const s=this.layers.hitLayer.selectAll(".collapsed-hit").data(t.descendants().filter(t=>t.collapsedChildren),t=>t.id);s.exit().remove();s.enter().append("rect").attr("class","collapsed-hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{e.collapsedChildren&&(this.isExpanding=!0,this.treeState.expandSubtree(e)),t.stopPropagation()}).merge(s).attr("transform",t=>`translate(${t.xPx}, ${t.yPx}) rotate(${this.#H(t)})`).attr("y",t=>-t.tipLabelSizePx/2.5).attr("width",t=>this.treeState.getCollapsedTriangleHeight(t)+t.tipLabelBounds.width*this.treeState.labelSizeToPxFactor).attr("height",t=>Math.max(t.tipLabelSizePx,this.treeState.getCollapsedTriangleHeight(t)));const r=this.layers.hitLayer.selectAll(".collapsed-root-hit").data(t.collapsedParent?[t]:[],t=>t.id);r.exit().remove();r.enter().append("rect").attr("class","collapsed-root-hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{e.collapsedParent&&(this.isExpanding=!0,this.treeState.expandRoot()),t.stopPropagation()}).merge(r).attr("transform",t=>{if(!t.collapsedParent)return`translate(${t.xPx}, ${t.yPx})`;let n=0;if(e){const e=t.children||[];if(e.length>0){n=e.reduce((t,e)=>t+e.angle,0)/e.length*(180/Math.PI)}}return`translate(${t.xPx}, ${t.yPx}) rotate(${n})`}).attr("x",-i).attr("y",5*-n).attr("width",i).attr("height",10*n)}#y(t=!0){const e=this.treeState.displayedRoot;if(!e)return;const n=e.links(),i=this.treeState.labelSizeToPxFactor*this.treeState.state.branchThicknessProp,a=this.layers.branchLayer.selectAll(".branch-group").data(n,t=>t.target.id);t?a.exit().attr("opacity",0).remove():a.exit().remove();const o=a.enter().append("g").attr("class","branch-group");this.#D(o),this.isExpanding&&t&&o.attr("opacity",0);const s=o.merge(a);return this.#B(s,t,i),this.selections.branches=s,o}#D(t){t.append("path").attr("class","offset").attr("fill","none").attr("stroke","#000").attr("stroke-opacity",1).attr("stroke-linecap","round"),t.append("path").attr("class","extension").attr("fill","none").attr("stroke","#000").attr("stroke-opacity",1).attr("stroke-linecap","round")}#B(t,e,n){this.treeState.state.layout;const i=t.select(".offset"),a=t.select(".extension");e?(i.transition().duration(this.options.transitionDuration).attr("stroke-width",n).attr("d",t=>this.#I(t,"offset")),a.transition().duration(this.options.transitionDuration).attr("stroke-width",n).attr("d",t=>this.#I(t,"extension"))):(i.attr("stroke-width",n).attr("d",t=>this.#I(t,"offset")),a.attr("stroke-width",n).attr("d",t=>this.#I(t,"extension")))}#A(t,e,n,i,a,o){let s=a-i;o&&s<0?s+=2*Math.PI:!o&&s>0&&(s-=2*Math.PI);const r=Math.abs(s),l=Math.max(1,Math.ceil(r/(Math.PI/2))),h=s/l,c=4/3*Math.tan(h/4);let u="",d=i,p=t,f=e;for(let g=0;g<l;g++){const t=d+h,e=n*Math.cos(t),i=n*Math.sin(t);u+=` C${p-c*n*Math.sin(d)},${f+c*n*Math.cos(d)} ${e+c*n*Math.sin(t)},${i-c*n*Math.cos(t)} ${e},${i}`,d=t,p=e,f=i}return u}#I(t,e){const n="circular"===this.treeState.state.layout;if("offset"===e){if(n){t.source.radiusPx,t.target.cos,t.source.radiusPx,t.target.sin;const e=t.target.angle>t.source.angle,n=this.#A(t.source.xPx,t.source.yPx,t.source.radiusPx,t.source.angle,t.target.angle,e);return`M${t.source.xPx},${t.source.yPx}${n}`}{const e=t.source.xPx,n=t.source.yPx,i=t.source.xPx,a=t.target.yPx;return`M${e},${n} C${e},${n+(a-n)/3} ${i},${a-(a-n)/3} ${i},${a}`}}if(n){const e={x:t.source.radiusPx*t.target.cos,y:t.source.radiusPx*t.target.sin};return`M${e.x},${e.y} L${t.target.xPx},${t.target.yPx}`}return`M${t.source.xPx},${t.target.yPx} L${t.target.xPx},${t.target.yPx}`}#F(t){const e=.4330127*(n=this.treeState.getCollapsedTriangleHeight(t))*n;var n;return In().type(Bn).size(e)()}#b(t=!0){const e=this.treeState.displayedRoot;if(!e)return;this.treeState.state.layout;const n=e.descendants().filter(t=>!t.hidden),i=this.treeState.labelSizeToPxFactor*this.treeState.state.branchThicknessProp,a=this.#$(),o=this.layers.nodeLayer.selectAll(".node").data(n,t=>t.id);t?o.exit().attr("opacity",0).remove():o.exit().remove();const s=o.enter().append("g").attr("class","node").attr("transform",t=>`translate(${t.xPx}, ${t.yPx})`);this.#V(s,i),this.isExpanding&&t&&s.attr("opacity",0);const r=s.merge(o);return this.#q(r,t),this.#X(r,t),this.#O(r,t),this.#Y(r,t,i,a),this.selections.nodes=r,s}#V(t,e){t.append("path").attr("class","node-shape").attr("d",t=>t.collapsedChildren?this.#F(t):null).attr("fill","#000").style("display",t=>t.collapsedChildren?null:"none"),t.append("line").attr("class","collapsed-root-line").attr("stroke","#000").attr("stroke-width",e).style("display",t=>t.collapsedParent?null:"none"),t.filter(t=>t.tipLabelText&&""!==t.tipLabelText.trim()).append("text").attr("class","tip-label").style("text-anchor",t=>this.#j(t)).style("font-size",t=>`${t.tipLabelSizePx}px`).style("font-family",t=>t.tipLabelFont||"sans-serif").style("font-style",t=>t.tipLabelStyle||"normal").style("font-weight",t=>"bold"===t.tipLabelStyle?"bold":"normal").style("fill",t=>t.tipLabelColor||"#000").style("display",t=>t.children?"none":null).text(t=>t.tipLabelText||""),t.filter(t=>{if(!t.nodeLabelText||""===t.nodeLabelText.trim())return!1;if(!t.children)return!1;return t.children.filter(t=>!t.hidden).length>1}).append("text").attr("class","node-label").style("text-anchor",t=>this.#G(t)).style("font-size",t=>`${t.nodeLabelSizePx}px`).style("fill","#000").style("display",t=>t.children||t.collapsedChildren?null:"none").text(t=>t.nodeLabelText||"")}#q(t,e){e?t.transition("update node positions").duration(this.options.transitionDuration).attr("transform",t=>`translate(${t.xPx}, ${t.yPx}) rotate(${this.#H(t)})`):t.attr("transform",t=>`translate(${t.xPx}, ${t.yPx}) rotate(${this.#H(t)})`)}#X(t,e){const n="circular"===this.treeState.state.layout,i=t.selectAll(".tip-label");i.attr("x",t=>this.#U(t)&&n?-t.tipLabelXOffsetPx:t.tipLabelXOffsetPx).style("text-anchor",t=>this.#j(t)).attr("transform",t=>`rotate(${this.#U(t)&&n?180:0})`).text(t=>t.tipLabelText||"").style("fill",t=>t.tipLabelColor||"#000").style("font-family",t=>t.tipLabelFont||"sans-serif").style("font-style",t=>t.tipLabelStyle||"normal").style("display",t=>t.children?"none":null),e?i.transition("update tip labels").duration(this.options.transitionDuration).attr("dy",t=>t.tipLabelSizePx/2.5).style("font-size",t=>`${t.tipLabelSizePx}px`):i.attr("dy",t=>t.tipLabelSizePx/2.5).style("font-size",t=>`${t.tipLabelSizePx}px`);const a=t.selectAll(".node-label");a.attr("x",t=>this.#U(t)&&n?t.nodeLabelXOffsetPx:-t.nodeLabelXOffsetPx).attr("transform",t=>`rotate(${this.#U(t)&&n?180:0})`).style("text-anchor",t=>this.#G(t)).text(t=>t.nodeLabelText||"").style("display",t=>{if(!t.children&&!t.collapsedChildren)return"none";if(t.children){if(t.children.filter(t=>!t.hidden).length<=1)return"none"}return null}),e?a.transition("update node labels").duration(this.options.transitionDuration).attr("dy",t=>this.#Z(t)).style("font-size",t=>`${t.nodeLabelSizePx}px`):a.attr("dy",t=>this.#Z(t)).style("font-size",t=>`${t.nodeLabelSizePx}px`)}#O(t,e){const n=t.selectAll(".node-shape");n.attr("transform",t=>`rotate(-90) translate(0, ${this.treeState.getCollapsedTriangleOffset(t)})`).style("display",t=>t.collapsedChildren?null:"none"),e?n.transition().duration(this.options.transitionDuration).attr("d",t=>t.collapsedChildren?this.#F(t):null):n.attr("d",t=>t.collapsedChildren?this.#F(t):null)}#Y(t,e,n,i){const a=t.selectAll(".collapsed-root-line");e?a.transition().duration(this.options.transitionDuration).attr("x2",-i).attr("y2",0).attr("stroke-width",n).attr("stroke-dasharray",t=>t.collapsedParent?ti(i,n,4):null):a.attr("x2",-i).attr("y2",0).attr("stroke-width",n).attr("stroke-dasharray",t=>t.collapsedParent?ti(i,n,4):null),a.attr("x1",0).attr("y1",0).style("display",t=>t.collapsedParent?null:"none")}#H(t){if(!("circular"===this.treeState.state.layout))return 0;return t.angle*(180/Math.PI)}#j(t){return"circular"===this.treeState.state.layout&&this.#U(t)?t.children?"start":"end":t.children?"end":"start"}#G(t){return"circular"===this.treeState.state.layout&&this.#U(t)?t.children||t.collapsedChildren?"start":"end":t.children||t.collapsedChildren?"end":"start"}#Z(t){const e=t.parent&&t.parent.yPx>t.yPx,n=t.nodeLabelSizePx;return e?.3*-n:1*n}#U(t){return t.angle<1.5*Math.PI||t.angle>2.5*Math.PI}#$(){const t=this.treeState.displayedRoot;if(!t)return 0;if("circular"===this.treeState.state.layout){return Math.max(...t.leaves().map(t=>t.radiusPx))*this.treeState.state.collapsedRootLineProp*2}return Math.max(...t.leaves().map(t=>t.xPx))*this.treeState.state.collapsedRootLineProp}}function Wi(t,e,n){const i=t.getCurrentBoundsWithLegends(),a=i.maxX-i.minX,o=i.maxY-i.minY,s=e.width/a,r=e.height/o,l=Math.min(s,r),h=e.width+2*e.margin,c=e.height+2*e.margin,u=e.margin-i.minX*l,d=e.margin-i.minY*l,p=document.createElementNS("http://www.w3.org/2000/svg","svg");p.setAttribute("width",h),p.setAttribute("height",c),p.setAttribute("xmlns","http://www.w3.org/2000/svg");const f=document.createElementNS("http://www.w3.org/2000/svg","g");f.setAttribute("transform",`translate(${u}, ${d}) scale(${l})`);const g=t.layers.treeGroup.node().cloneNode(!0);g.removeAttribute("transform");const m=g.querySelector(".selection-rect");m&&m.remove(),f.appendChild(g),p.appendChild(f);const y=(new XMLSerializer).serializeToString(p);"svg"===e.format?function(t,e,n){const i=new Blob([t],{type:n}),a=URL.createObjectURL(i),o=document.createElement("a");o.href=a,o.download=e,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(a)}(y,n,"image/svg+xml"):"png"===e.format&&function(t,e,n,i){const a=document.createElement("canvas");a.width=e,a.height=n;const o=a.getContext("2d"),s=new Image,r=new Blob([t],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(r);s.onload=()=>{o.fillStyle="white",o.fillRect(0,0,e,n),o.drawImage(s,0,0),a.toBlob(t=>{const e=URL.createObjectURL(t),n=document.createElement("a");n.href=e,n.download=i,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(e),URL.revokeObjectURL(l)})},s.src=l}(y,h,c,n)}function Ki(t,e,n,i,a,o,s){const r=20;let l=null,h=null,c=null,u=null,d=null,p=null,f=null,g=!0;const m=document.createElement("div");m.className="ht-toggle-container";const y=document.createElement("button");y.className="ht-control-panel-toggle",y.innerHTML='\n <svg width="16" height="16" viewBox="0 0 16 16" class="ht-toggle-arrow">\n <path d="M8 4 L12 8 L8 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="rotate(-90 8 8)"/>\n </svg>\n <svg width="16" height="16" viewBox="0 0 16 16" class="ht-hamburger-icon">\n <line x1="2" y1="4" x2="14" y2="4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n <line x1="2" y1="8" x2="14" y2="8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n <line x1="2" y1="12" x2="14" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n ',y.title="Toggle control panel",m.appendChild(y);const b=document.createElement("div");b.className="ht-collapsible-panel";const x=document.createElement("div");x.className="ht-tabs";const v=document.createElement("div");v.className="ht-controls hidden";const w=document.createElement("div");w.className="ht-aesthetic-settings hidden";const _=[{id:"data",label:"Data",requiresTree:!1},{id:"controls",label:"Controls",requiresTree:!0},{id:"tree-manipulation",label:"Tree",requiresTree:!0},{id:"tip-label-settings",label:"Tip Labels",requiresTree:!0},{id:"export",label:"Export",requiresTree:!0}],C={};function k(){const t=null!==n();if(_.forEach(e=>{const n=C[e.id];e.requiresTree&&!t?n.classList.add("disabled"):n.classList.remove("disabled")}),l){const e=_.find(t=>t.id===l);e&&e.requiresTree&&!t&&A("data")}}function S(){const t=n();return t&&t.state.treeData?t.state.treeData.getMetadataTableNames():[]}function L(){return h}function T(t){S().includes(t)?h=t:console.warn(`Metadata table not found: ${t}`)}function M(){const t=S();h=t.length>0?t[0]:null}function P(){const t=n();if(t){if(u){let e=!1;t.displayedRoot.each(n=>{n!==t.displayedRoot&&n.collapsedChildren&&(e=!0)}),u.disabled=!e}if(d&&(d.disabled=!t.displayedRoot.collapsedParent),p){let e=!1;t.state.treeData.tree.each(t=>{t.hiddenChildren&&t.hiddenChildren.length>0&&(e=!0)}),p.disabled=!e}}}function E(){const t=n();if(!t)return"tree";for(const[n,i]of e.entries())if(i===t.state.treeData)return n;return"tree"}function $(t,e){c!==t?(z(),c=t,e.classList.add("ht-aesthetic-editing"),w.classList.remove("hidden"),N(t)):z()}function z(){if(!c)return;w.querySelectorAll(".ht-color-palette-editor").forEach(t=>{t.cleanupFunction&&"function"==typeof t.cleanupFunction&&t.cleanupFunction()});v.querySelectorAll(".ht-control-group").forEach(t=>t.classList.remove("ht-aesthetic-editing")),w.classList.add("hidden"),w.innerHTML="",c=null}function N(t){w.innerHTML="";const e=n();if(!e)return;const i=e.state.aesthetics[t],a=e.aestheticsScales[t];if(!a){const t=document.createElement("div");return t.textContent="Error: Could not find aesthetic",t.style.padding="10px",t.style.color="#d00",void w.appendChild(t)}const o=a.createSettingsWidget({controlHeight:r,columnId:i});o&&w.appendChild(o)}function A(t){const e=_.find(e=>e.id===t);e&&e.requiresTree&&!n()||(l=t,Object.keys(C).forEach(e=>{e===t?C[e].classList.add("active"):C[e].classList.remove("active")}),v.classList.remove("hidden"),R(t))}function R(t){switch(v.innerHTML="",z(),t){case"data":!function(t,e,n,i,a,o,s,r,l,h,c,u){t.innerHTML="";const d=Ei(),p=$i("Tree:",u);d.appendChild(p);const f=document.createElement("select");f.className="ht-select",f.style.height=`${u}px`;const g=Array.from(e.keys()),m=n(),y=m?Array.from(e.entries()).find(([t,e])=>e===m.state.treeData)?.[0]:null;if(0===g.length){const t=document.createElement("option");t.textContent="No trees loaded",t.value="",f.appendChild(t),f.disabled=!0}else g.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===y&&(e.selected=!0),f.appendChild(e)}),f.addEventListener("change",t=>{i(t.target.value)});d.appendChild(f),t.appendChild(d);const b=document.createElement("input");b.type="file",b.style.display="none",b.addEventListener("change",async t=>{const e=t.target.files[0];if(e)try{const t=await e.text();let n=e.name.replace(/\.[^/.]+$/,"");const o=a(n,t);b.value="",h(),o.length>0&&i(o[0])}catch(n){console.error("Error loading tree file:",n),alert(`Error loading tree file: ${n.message}`)}}),t.appendChild(b);const x=zi("+","Add tree from Newick file",u);if(x.addEventListener("click",()=>{b.click()}),t.appendChild(x),!m)return;const v=Ei(),w=$i("Metadata:",u);v.appendChild(w);const _=document.createElement("select");_.className="ht-select",_.style.height=`${u}px`;const C=o(),k=s();if(0===C.length){const t=document.createElement("option");t.textContent="No metadata",t.value="",_.appendChild(t),_.disabled=!0}else C.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===k&&(e.selected=!0),_.appendChild(e)}),_.addEventListener("change",t=>{r(t.target.value),h()});v.appendChild(_),t.appendChild(v);const S=document.createElement("input");S.type="file",S.accept=".tsv,.csv,.txt",S.style.display="none",S.addEventListener("change",async t=>{const e=t.target.files[0];if(!e)return;const i=n();if(!i||!i.state.treeData)return alert("No tree selected. Please select a tree first."),void(S.value="");try{const t=await e.text();let n=e.name.replace(/\.(tsv|csv|txt)$/i,""),a="\t";e.name.toLowerCase().endsWith(".csv")&&(a=",");const o=i.state.treeData.addTable(t,n,a),s=i.state.treeData.metadataTableNames.get(o);S.value="",r(s),h()}catch(a){console.error("Error loading metadata file:",a),alert(`Error loading metadata file: ${a.message}`),S.value=""}}),t.appendChild(S);const L=zi("+","Add metadata table",u);if(L.addEventListener("click",()=>{const t=n();t&&t.state.treeData?S.click():alert("No tree selected. Please select a tree first.")}),t.appendChild(L),k){const e=m.state.treeData;let n=null;for(const[t,i]of e.metadataTableNames.entries())if(i===k){n=t;break}if(n){const i=e.getValidIdColumns(n),a=e.getNodeIdColumn(n),o=Ei(),s=$i("ID Column:",u);o.appendChild(s);const r=document.createElement("select");if(r.className="ht-select",r.style.height=`${u}px`,0===i.length){const t=document.createElement("option");t.textContent="No ID column found",t.value="",r.appendChild(t),r.disabled=!0}else i.forEach(t=>{const n=document.createElement("option");n.value=t,n.textContent=e.columnName.get(t),t===a&&(n.selected=!0),r.appendChild(n)}),r.addEventListener("change",t=>{const i=t.target.value;e.setNodeIdColumn(n,i),m.updateCoordinates(),h()});o.appendChild(r),t.appendChild(o)}}}(v,e,n,a,o,S,L,T,0,H,0,r);break;case"controls":!function(t,e,n,i,a){t.innerHTML="";const o=e(),s=n();if(!o||!s)return void(t.textContent="No tree selected");const r=zi("Fit to view","Fit the tree to the current view window",a);r.addEventListener("click",()=>{s.fitToView({transition:!0,autoPan:"Both",autoZoom:"Both"})}),t.appendChild(r);const l=Ei(),h=$i("Manual zoom/pan:",a);l.appendChild(h);const c=Ai(s.options.manualZoomAndPanEnabled,a);c.addEventListener("click",()=>{s.options.manualZoomAndPanEnabled=!s.options.manualZoomAndPanEnabled,s.options.manualZoomAndPanEnabled?c.classList.add("active"):(c.classList.remove("active"),s.fitToView()),s.initializeZoom()}),l.appendChild(c),t.appendChild(l);const u=Ei(),d=$i("Auto-zoom:",a);u.appendChild(d);const p=document.createElement("select");p.className="ht-select",p.style.height=`${a}px`;["Default","Both","X","Y","None"].forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===s.options.autoZoom&&(e.selected=!0),p.appendChild(e)}),p.addEventListener("change",t=>{s.options.autoZoom=t.target.value}),u.appendChild(p),t.appendChild(u);const f=Ei(),g=$i("Auto-pan:",a);f.appendChild(g);const m=document.createElement("select");m.className="ht-select",m.style.height=`${a}px`;["Default","Both","X","Y","None"].forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===s.options.autoPan&&(e.selected=!0),m.appendChild(e)}),m.addEventListener("change",t=>{s.options.autoPan=t.target.value}),f.appendChild(m),t.appendChild(f)}(v,n,i,0,r);break;case"tree-manipulation":!function(t,e,n,i,a,o,s,r,l){t.innerHTML="";const h=e();if(!h)return void(t.textContent="No tree selected");const c=zi("Expand subtrees","Expand all collapsed subtrees",o),u=()=>{let t=!1;return h.displayedRoot.each(e=>{e!==h.displayedRoot&&e.collapsedChildren&&(t=!0)}),t};c.disabled=!u(),c.addEventListener("click",()=>{const t=[];h.displayedRoot.each(e=>{if(e!==h.displayedRoot&&e.collapsedChildren){let n=!0,i=e.parent;for(;i&&i!==h.displayedRoot;){if(i.collapsedChildren){n=!1;break}i=i.parent}n&&t.push(e)}}),t.forEach(t=>{h.expandSubtree(t)}),i()}),s(c),t.appendChild(c);const d=zi("Expand root","Expand the collapsed root",o);d.disabled=!h.displayedRoot.collapsedParent,d.addEventListener("click",()=>{h.displayedRoot.collapsedParent&&(h.expandRoot(),i())}),r(d),t.appendChild(d);const p=zi("Show hidden","Show all hidden nodes",o),f=()=>{let t=!1;return h.state.treeData.tree.each(e=>{e.hiddenChildren&&e.hiddenChildren.length>0&&(t=!0)}),t};p.disabled=!f(),p.addEventListener("click",()=>{h.showAllHidden(),i()}),l(p),t.appendChild(p);const g=Ei(),m=$i("Branch length:",o);g.appendChild(m);const y=(t,e=10)=>{const n=Math.log10(1/e),i=Math.log10(e);return(Math.log10(t)-n)/(i-n)*100},b=(t,e=10)=>{const n=Math.log10(1/e),i=n+t/100*(Math.log10(e)-n);return Math.pow(10,i)},x=Ni(0,100,y(h.state.branchLengthScale),.1,o);x.addEventListener("input",t=>{const e=parseFloat(t.target.value),n=b(e);h.setBranchLengthScale(n)}),g.appendChild(x),t.appendChild(g);const v=Ei(),w=$i("Tree height:",o);v.appendChild(w);const _=Ni(0,100,y(h.state.treeHeightScale),.1,o);_.addEventListener("input",t=>{const e=parseFloat(t.target.value),n=b(e);h.setTreeHeightScale(n)}),v.appendChild(_),t.appendChild(v);const C=Ei(),k=$i("Radial layout:",o);C.appendChild(k);const S=Ai("circular"===h.state.layout,o),L=()=>{"circular"===h.state.layout?S.classList.add("active"):S.classList.remove("active")};h.subscribe("layoutChange",L),S.addEventListener("click",()=>{const t=h.state.layout;h.setLayout("circular"===t?"rectangular":"circular")}),C.appendChild(S),t.appendChild(C)}(v,n,0,P,0,r,t=>{u=t},t=>{d=t},t=>{p=t});break;case"tip-label-settings":!function(t,e,n,i,a,o,s,r){t.innerHTML="";const l=e();if(!l)return void(t.textContent="No tree selected");const h='\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M11.5 1.5L14.5 4.5L5 14H2V11L11.5 1.5Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 3L13 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',c=Ei(),u=$i("Text:",i);c.appendChild(u);const d=Qi(l,"tipLabelText","Default",i,!0,null,r,s);c.appendChild(d),t.appendChild(c);const p=Ei(),f=$i("Color:",i);p.appendChild(f);const g=function(t,e="",n){const i=document.createElement("button");return i.className="ht-icon-button",i.innerHTML=t,i.title=e,i.style.height=`${n}px`,i.style.width=`${n}px`,i}(h,"Edit color settings",i);g.addEventListener("click",t=>{t.stopPropagation(),a("tipLabelColor",p)}),p.appendChild(g);const m=Qi(l,"tipLabelColor","Default",i,!1,null,r,s);p.appendChild(m),t.appendChild(p);const y=Ei(),b=$i("Size:",i);y.appendChild(b);const x=Qi(l,"tipLabelSize","Default",i,!1,!0,r,s);y.appendChild(x),t.appendChild(y);const v=Ei(),w=$i("Style:",i);v.appendChild(w);const _=Qi(l,"tipLabelStyle","Default",i,!1,!1,r,s);v.appendChild(_),t.appendChild(v);const C=Ei(),k=$i("Font:",i);C.appendChild(k);const S=document.createElement("select");S.className="ht-select",S.style.height=`${i}px`;const L=["sans-serif","serif","monospace"],T=void 0!==l.state.aesthetics.tipLabelFont?l.aestheticsScales.tipLabelFont.getValue():"sans-serif";L.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===T&&(e.selected=!0),S.appendChild(e)}),S.addEventListener("change",t=>{const e=t.target.value;l.setAesthetics({tipLabelFont:void 0}),l.state.treeData.tree.each(t=>{t.tipLabelFont=e}),l.updateCoordinates()}),C.appendChild(S),t.appendChild(C)}(v,n,0,r,$,0,N,()=>c);break;case"export":!function(t,e,n,i,a,o){t.innerHTML="";const s=e(),r=n();if(!s||!r)return void(t.textContent="No tree selected");const l=r.getCurrentBoundsWithLegends(),h=l.maxX-l.minX,c=l.maxY-l.minY,u={format:"svg",width:h,height:c,margin:18},d=h/c,p=300,f=2.54,g=t=>t/p*f,m=t=>t/f*p,y=(t,e)=>"png"===e?Math.round(t):Math.round(100*g(t))/100,b=(t,e)=>"png"===e?t:m(t),x=()=>{const t=r.getCurrentBoundsWithLegends(),e=t.maxX-t.minX,n=t.maxY-t.minY;u.width=e,u.height=n,M.value=y(e,u.format),$.value=y(n,u.format)},v=s.subscribe("coordinateChange",x),w=s.subscribe("legendsChange",x);t.dataset.cleanup=()=>{v(),w()};const _=zi("Export","Export the tree to a file",o);_.classList.add("primary"),_.addEventListener("click",()=>{const t=i().replace(/[^a-z0-9_-]/gi,"_"),e="svg"===u.format?"svg":"png";Wi(r,u,`${t}.${e}`)}),t.appendChild(_);const C=Ei(),k=$i("Output format:",o);C.appendChild(k);const S=document.createElement("select");S.className="ht-select",S.style.height=`${o}px`,["SVG","PNG"].forEach(t=>{const e=document.createElement("option");e.value=t.toLowerCase(),e.textContent=t,t.toLowerCase()===u.format&&(e.selected=!0),S.appendChild(e)}),S.addEventListener("change",t=>{u.format=t.target.value,M.value=y(u.width,u.format),$.value=y(u.height,u.format),A.value=y(u.margin,u.format);const e="png"===u.format?"px":"cm";T.textContent=`Width (${e}):`,E.textContent=`Height (${e}):`,N.textContent=`Margin (${e}):`}),C.appendChild(S),t.appendChild(C);const L=Ei(),T=$i(`Width (${"png"===u.format?"px":"cm"}):`,o);L.appendChild(T);const M=Ri(y(u.width,u.format),.1,1e4,.1,o);M.addEventListener("input",t=>{const e=parseFloat(t.target.value);isNaN(e)||e<=0||(u.width=b(e,u.format),u.height=u.width/d,$.value=y(u.height,u.format))}),L.appendChild(M),t.appendChild(L);const P=Ei(),E=$i(`Height (${"png"===u.format?"px":"cm"}):`,o);P.appendChild(E);const $=Ri(y(u.height,u.format),.1,1e4,.1,o);$.addEventListener("input",t=>{const e=parseFloat(t.target.value);isNaN(e)||e<=0||(u.height=b(e,u.format),u.width=u.height*d,M.value=y(u.width,u.format))}),P.appendChild($),t.appendChild(P);const z=Ei(),N=$i(`Margin (${"png"===u.format?"px":"cm"}):`,o);z.appendChild(N);const A=Ri(y(u.margin,u.format),0,100,.1,o);A.addEventListener("input",t=>{const e=parseFloat(t.target.value);isNaN(e)||e<0||(u.margin=b(e,u.format))}),z.appendChild(A),t.appendChild(z)}(v,n,i,E,0,r)}}function H(){M(),f&&(f(),f=null),u=null,d=null,p=null;const t=n();t&&(f=t.subscribe("coordinateChange",P)),k(),l&&R(l)}return _.forEach(t=>{const e=document.createElement("div");e.className="ht-tab",e.textContent=t.label,e.addEventListener("click",()=>{e.classList.contains("disabled")||(z(),l===t.id?(l=null,Object.keys(C).forEach(t=>{C[t].classList.remove("active")}),v.classList.add("hidden"),v.innerHTML="",z()):A(t.id))}),C[t.id]=e,x.appendChild(e)}),v.addEventListener("click",t=>{const e=t.target.closest(".ht-icon-button"),n=t.target.closest(".ht-control-group.ht-aesthetic-editing");e||n||z()}),y.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),g=!g,g?(b.classList.remove("ht-panel-collapsed"),y.classList.remove("collapsed")):(z(),b.classList.add("ht-panel-collapsed"),y.classList.add("collapsed"))}),b.appendChild(x),b.appendChild(v),b.appendChild(w),t.appendChild(m),t.appendChild(b),k(),M(),H}function Qi(t,e,n,i,a=!1,o=null,s=null,r=null){const l=document.createElement("select");if(l.className="ht-select",l.style.height=`${i}px`,l.style.flex="1",a){const t=document.createElement("option");t.value="none",t.textContent="None",l.appendChild(t)}const h=document.createElement("option");h.value="",h.textContent=n,l.appendChild(h);const c=t.state.treeData,u=Array.from(c.columnDisplayName.keys());let d=u;null!==o&&(d=o?u.filter(t=>"continuous"===c.columnType.get(t)):u.filter(t=>"categorical"===c.columnType.get(t))),d.forEach(n=>{const i=document.createElement("option");i.value=n,i.textContent=c.columnDisplayName.get(n),t.state.aesthetics[e]===n&&(i.selected=!0),l.appendChild(i)});const p=t.state.aesthetics[e];return l.value=null===p?"none":void 0===p||""===p?"":p,l.addEventListener("change",n=>{let i;i="none"===n.target.value?null:""===n.target.value?void 0:n.target.value;const a={};if(a[e]=i,t.setAesthetics(a),s&&r){s()===e&&r(e)}}),l}t.heatTree=function(t,e=[],n={}){e&&!Array.isArray(e)&&(e=[e]),null==e&&(e=[]),function(){const t="heat-tree-styles";if(!document.getElementById(t)){const e=document.createElement("style");e.id=t,e.textContent=".ht-widget{color-scheme:light!important;--color-background: #ffffff;--color-text: #333333;--color-border: #dddddd;--color-muted: #666666;--color-accent: #007bff;background-color:var(--color-background);color:var(--color-text);display:flex;flex-direction:column;width:100%;height:100%}.ht-toolbar{flex:0 0 auto;margin-bottom:4px;display:flex;flex-direction:column;position:relative}.ht-toggle-container{position:absolute;top:0;right:0;padding:4px 8px;z-index:10}.ht-control-panel-toggle{background-color:transparent;border:none;cursor:pointer;padding:0 4px;display:flex;align-items:center;gap:4px;transition:opacity .2s}.ht-control-panel-toggle:hover{opacity:.7}.ht-control-panel-toggle .ht-toggle-arrow{transition:transform .3s}.ht-control-panel-toggle.collapsed .ht-toggle-arrow{transform:rotate(180deg)}.ht-control-panel-toggle .ht-hamburger-icon{color:#333}.ht-collapsible-panel{max-height:1000px;overflow:hidden;transition:max-height .3s ease-in-out}.ht-collapsible-panel.ht-panel-collapsed{max-height:0}.ht-widget .ht-tabs{display:flex;gap:20px;padding:4px 8px;background-color:#f5f5f5;border-bottom:2px solid #ddd;-webkit-user-select:none;user-select:none}.ht-widget .ht-tab{cursor:pointer;padding:0 4px;font-family:sans-serif;font-size:12px;color:#333;border-bottom:2px solid transparent;transition:all .2s}.ht-widget .ht-tab:hover{color:#666}.ht-widget .ht-tab.active{color:#000;font-weight:700;border-bottom-color:#007bff}.ht-widget .ht-tab.active:hover{color:#000}.ht-widget .ht-tab.disabled{color:#999;cursor:not-allowed;opacity:.5}.ht-widget .ht-tab.disabled:hover{color:#999}.ht-widget .ht-controls{padding:2px 8px;background-color:#fafafa;border-bottom:1px solid #ddd;display:flex;flex-wrap:wrap;column-gap:8px;row-gap:2px;align-items:center;min-height:22px}.ht-controls.hidden{display:none}.ht-control-group{display:flex;align-items:center;gap:4px;white-space:nowrap;padding:2px 0;border-bottom:2px solid transparent;transition:border-bottom-color .2s}.ht-control-group.ht-aesthetic-editing{border-bottom-color:#007bff}.ht-widget .ht-control-label{font-family:sans-serif;font-size:12px;color:#333;white-space:nowrap;display:flex;align-items:center}.ht-button{font-size:12px;font-family:sans-serif;background-color:#e0e0e0;border:1px solid #ccc;border-radius:4px;cursor:pointer;transition:background-color .2s;white-space:nowrap}.ht-button:hover{background-color:#d0d0d0}.ht-button:disabled{background-color:#f0f0f0;color:#999;cursor:not-allowed}.ht-button.primary{background-color:#007bff;color:#fff;font-weight:700}.ht-button.primary:hover{background-color:#0056b3}.ht-icon-button{font-size:12px;font-family:sans-serif;background-color:#e0e0e0;border:1px solid #ccc;border-radius:4px;cursor:pointer;transition:background-color .2s;display:flex;align-items:center;justify-content:center;padding:2px}.ht-icon-button:hover{background-color:#d0d0d0}.ht-icon-button svg{display:block}.ht-select{padding:1px 2px;font-size:12px;border:1px solid #ccc;border-radius:4px}.ht-slider{cursor:pointer;width:150px}.ht-toggle{width:50px;background-color:#ccc;border-radius:12px;position:relative;cursor:pointer;transition:background-color .3s;flex-shrink:0}.ht-toggle.active{background-color:#007bff}.ht-toggle-knob{background-color:#fff;border-radius:50%;position:absolute;top:2px;left:2px;transition:left .3s}.ht-toggle.active .ht-toggle-knob{left:calc(100% - 2px);transform:translate(-100%)}.ht-number-input{font-size:12px;border:1px solid #ccc;border-radius:4px;width:80px}.ht-text-input{font-size:12px;border:1px solid #ccc;border-radius:4px;padding:2px 4px;width:100px}.ht-widget .ht-aesthetic-settings-content{padding:2px 8px;background-color:#f0f0f0;border-bottom:1px solid #ddd;display:flex;flex-wrap:wrap;column-gap:8px;row-gap:2px;align-items:center;max-height:1000px;overflow:hidden;transition:max-height .3s ease-in-out,padding .3s ease-in-out}.ht-aesthetic-settings.hidden{max-height:0;padding-top:0;padding-bottom:0;border-bottom:none}.ht-color-palette-editor{display:flex;gap:8px;align-items:center}.ht-palette-buttons-container{display:flex;flex-direction:column;gap:2px}.ht-palette-button{width:20px;height:20px;font-size:12px;font-weight:700;background-color:#e0e0e0;border:1px solid #ccc;border-radius:4px;cursor:pointer;transition:background-color .2s}.ht-palette-button:hover{background-color:#d0d0d0}.ht-gradient-container{display:flex;gap:8px}.ht-gradient-column{display:flex;flex-direction:column;gap:4px}.ht-color-squares-container{display:flex;position:relative;height:16px;width:200px}.ht-color-square-wrapper{position:absolute;display:flex;flex-direction:column;align-items:center;transform:translate(-50%)}.ht-color-square{width:12px;height:12px;border:2px solid #333;border-radius:4px;cursor:pointer}.ht-color-square-tick{width:2px;height:8px;background-color:#333}.ht-gradient-box{width:200px;height:20px;border:1px solid #ccc;border-radius:4px;position:relative}.ht-widget .ht-range-slider-container{width:200px;height:12px;position:relative;border:1px solid #ccc;border-radius:4px;background:#f0f0f0;display:flex;align-items:center}.ht-range-handle{position:absolute;width:12px;height:12px;border:2px solid #333;border-radius:4px;cursor:ew-resize;transform:translate(-50%)}.ht-range-handle-indicator{position:absolute;bottom:90%;left:50%;transform:translate(-50%) rotate(180deg);width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #333;border-radius:2px;margin-bottom:2px}.ht-null-color-column{display:flex;flex-direction:column;gap:4px}.ht-null-color-square-container{display:flex;position:relative;height:16px;justify-content:center}.ht-null-color-square{width:12px;height:12px;border:2px solid #333;border-radius:4px;cursor:pointer}.ht-null-color-square-tick{width:2px;height:6px;background-color:#333;position:absolute;bottom:-6px;left:50%;transform:translate(-50%)}.ht-null-color-box{width:16px;height:20px;border:1px solid #ccc;border-radius:4px;position:relative}.missing-data-x-container{position:relative;display:flex;align-items:center;justify-content:center}.missing-data-x-container-triangle{position:absolute;bottom:85%;left:50%;transform:translate(-50%) rotate(180deg);width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #333;border-radius:2px;margin-bottom:2px}.missing-data-x{font-size:16px;color:#d00;font-weight:700;line-height:1;-webkit-user-select:none;user-select:none;cursor:pointer}.ht-tree{flex:1 1 auto;min-height:0;position:relative}.ht-tree svg{display:block}.picker_wrapper,.picker_wrapper.popup{z-index:999999!important;position:fixed!important}.picker_wrapper *,.picker_selector,.picker_slider,.picker_editor,.picker_sample,.picker_done,.picker_cancel{pointer-events:auto!important}",document.head.appendChild(e)}}(),n={buttonSize:25,transitionDuration:500,manualZoomAndPanEnabled:!0,autoZoom:"Default",autoPan:"Default",...n};const i=new qi,a=new Map,o=new Map;e.forEach((t,e)=>{if(!t.tree)throw new Error(`Tree at index ${e} is missing tree string`);const n=t.name||`Tree ${e+1}`;let i=[],s=[];if(t.metadata){(Array.isArray(t.metadata)?t.metadata:[t.metadata]).forEach((t,e)=>{t.name&&t.data?(i.push(t.data),s.push(t.name)):(i.push(t),s.push(`Metadata ${e+1}`))})}Fi.parseTrees(t.tree,n).forEach(({name:e,treeData:n},r)=>{let l=e,h=1;for(;a.has(l);)l=`${e} (${h})`,h++;const c=new Fi(n,i,s);let u;u=t.aesthetics?Object.fromEntries(Object.entries(t.aesthetics).map(([t,e])=>{for(const[n,i]of c.columnName.entries())if(i===e)return[t,n]}).filter(t=>void 0!==t)):void 0,a.set(l,c),o.set(l,u)})});const s=new Map,r=new Map,l=document.querySelector(t);if(!l)throw new Error(`Container element not found: ${t}`);const h=document.createElement("div");h.className="ht-widget";const c=document.createElement("div");c.className="ht-toolbar";const u=document.createElement("div");u.className="ht-tree";const d=document.createElementNS("http://www.w3.org/2000/svg","svg");d.setAttribute("width","100%"),d.setAttribute("height","100%"),u.appendChild(d),h.appendChild(c),h.appendChild(u),l.appendChild(h);let p=null,f=null,g=null,m=null;function y(t,e,n=[],i=[]){const o=Fi.parseTrees(e,t),s=[];return o.forEach(({name:t,treeData:e})=>{let o=t,r=1;for(;a.has(o);)o=`${t} (${r})`,r++;const l=new Fi(e,n,i);a.set(o,l),s.push(o)}),s}function b(t){if(a.has(t)){if(p!==t||!g){for(;d.firstChild;)d.removeChild(d.firstChild);if(!s.has(t)){const e=new Xi({treeData:a.get(t),aesthetics:o.get(t),...n},i);s.set(t,e)}if(r.has(t)){r.get(t).reattach(d)}else{const e=s.get(t),i=new Zi(e,d,n);r.set(t,i)}p=t,f=s.get(t),g=r.get(t),m&&m()}}else console.error(`Tree not found: ${t}`)}if(new oi(u,t=>{g&&g.fitToView()},{debounce:100,immediate:!0}),m=Ki(c,a,()=>f,()=>g,b,y),a.size>0){b(Array.from(a.keys())[0])}return{treeDataInstances:a,treeStateCache:s,treeViewCache:r,getCurrentTreeState:()=>f,getCurrentTreeView:()=>g,getCurrentTreeName:()=>p,switchToTree:b,addNewTree:y,container:h}},Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
8
+ */var gi=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},mi=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),yi=function(){return function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return function(t,e){var n=[],i=!0,a=!1,o=void 0;try{for(var s,r=t[Symbol.iterator]();!(i=(s=r.next()).done)&&(n.push(s.value),!e||n.length!==e);i=!0);}catch(l){a=!0,o=l}finally{try{!i&&r.return&&r.return()}finally{if(a)throw o}}return n}(t,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();String.prototype.startsWith=String.prototype.startsWith||function(t){return 0===this.indexOf(t)},String.prototype.padStart=String.prototype.padStart||function(t,e){for(var n=this;n.length<t;)n=e+n;return n};var bi={cb:"0f8ff",tqw:"aebd7",q:"-ffff",qmrn:"7fffd4",zr:"0ffff",bg:"5f5dc",bsq:"e4c4",bck:"---",nch:"ebcd",b:"--ff",bvt:"8a2be2",brwn:"a52a2a",brw:"deb887",ctb:"5f9ea0",hrt:"7fff-",chcT:"d2691e",cr:"7f50",rnw:"6495ed",crns:"8dc",crms:"dc143c",cn:"-ffff",Db:"--8b",Dcn:"-8b8b",Dgnr:"b8860b",Dgr:"a9a9a9",Dgrn:"-64-",Dkhk:"bdb76b",Dmgn:"8b-8b",Dvgr:"556b2f",Drng:"8c-",Drch:"9932cc",Dr:"8b--",Dsmn:"e9967a",Dsgr:"8fbc8f",DsTb:"483d8b",DsTg:"2f4f4f",Dtrq:"-ced1",Dvt:"94-d3",ppnk:"1493",pskb:"-bfff",mgr:"696969",grb:"1e90ff",rbrc:"b22222",rwht:"af0",stg:"228b22",chs:"-ff",gnsb:"dcdcdc",st:"8f8ff",g:"d7-",gnr:"daa520",gr:"808080",grn:"-8-0",grnw:"adff2f",hnw:"0fff0",htpn:"69b4",nnr:"cd5c5c",ng:"4b-82",vr:"0",khk:"0e68c",vnr:"e6e6fa",nrb:"0f5",wngr:"7cfc-",mnch:"acd",Lb:"add8e6",Lcr:"08080",Lcn:"e0ffff",Lgnr:"afad2",Lgr:"d3d3d3",Lgrn:"90ee90",Lpnk:"b6c1",Lsmn:"a07a",Lsgr:"20b2aa",Lskb:"87cefa",LsTg:"778899",Lstb:"b0c4de",Lw:"e0",m:"-ff-",mgrn:"32cd32",nn:"af0e6",mgnt:"-ff",mrn:"8--0",mqm:"66cdaa",mmb:"--cd",mmrc:"ba55d3",mmpr:"9370db",msg:"3cb371",mmsT:"7b68ee","":"-fa9a",mtr:"48d1cc",mmvt:"c71585",mnLb:"191970",ntc:"5fffa",mstr:"e4e1",mccs:"e4b5",vjw:"dead",nv:"--80",c:"df5e6",v:"808-0",vrb:"6b8e23",rng:"a5-",rngr:"45-",rch:"da70d6",pgnr:"eee8aa",pgrn:"98fb98",ptrq:"afeeee",pvtr:"db7093",ppwh:"efd5",pchp:"dab9",pr:"cd853f",pnk:"c0cb",pm:"dda0dd",pwrb:"b0e0e6",prp:"8-080",cc:"663399",r:"--",sbr:"bc8f8f",rb:"4169e1",sbrw:"8b4513",smn:"a8072",nbr:"4a460",sgrn:"2e8b57",ssh:"5ee",snn:"a0522d",svr:"c0c0c0",skb:"87ceeb",sTb:"6a5acd",sTgr:"708090",snw:"afa",n:"-ff7f",stb:"4682b4",tn:"d2b48c",t:"-8080",thst:"d8bfd8",tmT:"6347",trqs:"40e0d0",vt:"ee82ee",whT:"5deb3",wht:"",hts:"5f5f5",w:"-",wgrn:"9acd32"};function xi(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return(e>0?t.toFixed(e).replace(/0+$/,"").replace(/\.$/,""):t.toString())||"0"}var vi=function(){function t(e,n,i,a){gi(this,t);var o=this;if(void 0===e);else if(Array.isArray(e))this.rgba=e;else if(void 0===i){var s=e&&""+e;s&&function(e){if(e.startsWith("hsl")){var n=e.match(/([\-\d\.e]+)/g).map(Number),i=yi(n,4),a=i[0],s=i[1],r=i[2],l=i[3];void 0===l&&(l=1),a/=360,s/=100,r/=100,o.hsla=[a,s,r,l]}else if(e.startsWith("rgb")){var h=e.match(/([\-\d\.e]+)/g).map(Number),c=yi(h,4),u=c[0],d=c[1],p=c[2],f=c[3];void 0===f&&(f=1),o.rgba=[u,d,p,f]}else e.startsWith("#")?o.rgba=t.hexToRgb(e):o.rgba=t.nameToRgb(e)||t.hexToRgb(e)}(s.toLowerCase())}else this.rgba=[e,n,i,void 0===a?1:a]}return mi(t,[{key:"printRGB",value:function(t){var e=(t?this.rgba:this.rgba.slice(0,3)).map(function(t,e){return xi(t,3===e?3:0)});return t?"rgba("+e+")":"rgb("+e+")"}},{key:"printHSL",value:function(t){var e=[360,100,100,1],n=["","%","%",""],i=(t?this.hsla:this.hsla.slice(0,3)).map(function(t,i){return xi(t*e[i],3===i?3:1)+n[i]});return t?"hsla("+i+")":"hsl("+i+")"}},{key:"printHex",value:function(t){var e=this.hex;return t?e:e.substring(0,7)}},{key:"rgba",get:function(){if(this._rgba)return this._rgba;if(!this._hsla)throw new Error("No color is set");return this._rgba=t.hslToRgb(this._hsla)},set:function(t){3===t.length&&(t[3]=1),this._rgba=t,this._hsla=null}},{key:"rgbString",get:function(){return this.printRGB()}},{key:"rgbaString",get:function(){return this.printRGB(!0)}},{key:"hsla",get:function(){if(this._hsla)return this._hsla;if(!this._rgba)throw new Error("No color is set");return this._hsla=t.rgbToHsl(this._rgba)},set:function(t){3===t.length&&(t[3]=1),this._hsla=t,this._rgba=null}},{key:"hslString",get:function(){return this.printHSL()}},{key:"hslaString",get:function(){return this.printHSL(!0)}},{key:"hex",get:function(){return"#"+this.rgba.map(function(t,e){return e<3?t.toString(16):Math.round(255*t).toString(16)}).map(function(t){return t.padStart(2,"0")}).join("")},set:function(e){this.rgba=t.hexToRgb(e)}}],[{key:"hexToRgb",value:function(t){var e=(t.startsWith("#")?t.slice(1):t).replace(/^(\w{3})$/,"$1F").replace(/^(\w)(\w)(\w)(\w)$/,"$1$1$2$2$3$3$4$4").replace(/^(\w{6})$/,"$1FF");if(!e.match(/^([0-9a-fA-F]{8})$/))throw new Error("Unknown hex color; "+t);var n=e.match(/^(\w\w)(\w\w)(\w\w)(\w\w)$/).slice(1).map(function(t){return parseInt(t,16)});return n[3]=n[3]/255,n}},{key:"nameToRgb",value:function(e){var n=e.toLowerCase().replace("at","T").replace(/[aeiouyldf]/g,"").replace("ght","L").replace("rk","D").slice(-5,4),i=bi[n];return void 0===i?i:t.hexToRgb(i.replace(/\-/g,"00").padStart(6,"f"))}},{key:"rgbToHsl",value:function(t){var e=yi(t,4),n=e[0],i=e[1],a=e[2],o=e[3];n/=255,i/=255,a/=255;var s=Math.max(n,i,a),r=Math.min(n,i,a),l=void 0,h=void 0,c=(s+r)/2;if(s===r)l=h=0;else{var u=s-r;switch(h=c>.5?u/(2-s-r):u/(s+r),s){case n:l=(i-a)/u+(i<a?6:0);break;case i:l=(a-n)/u+2;break;case a:l=(n-i)/u+4}l/=6}return[l,h,c,o]}},{key:"hslToRgb",value:function(t){var e=yi(t,4),n=e[0],i=e[1],a=e[2],o=e[3],s=void 0,r=void 0,l=void 0;if(0===i)s=r=l=a;else{var h=function(t,e,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?t+6*(e-t)*n:n<.5?e:n<2/3?t+(e-t)*(2/3-n)*6:t},c=a<.5?a*(1+i):a+i-a*i,u=2*a-c;s=h(u,c,n+1/3),r=h(u,c,n),l=h(u,c,n-1/3)}var d=[255*s,255*r,255*l].map(Math.round);return d[3]=o,d}}]),t}(),wi=function(){function t(){gi(this,t),this._events=[]}return mi(t,[{key:"add",value:function(t,e,n){t.addEventListener(e,n,!1),this._events.push({target:t,type:e,handler:n})}},{key:"remove",value:function(e,n,i){this._events=this._events.filter(function(a){var o=!0;return e&&e!==a.target&&(o=!1),n&&n!==a.type&&(o=!1),i&&i!==a.handler&&(o=!1),o&&t._doRemove(a.target,a.type,a.handler),!o})}},{key:"destroy",value:function(){this._events.forEach(function(e){return t._doRemove(e.target,e.type,e.handler)}),this._events=[]}}],[{key:"_doRemove",value:function(t,e,n){t.removeEventListener(e,n,!1)}}]),t}();function _i(t,e,n){var i=!1;function a(t,e,n){return Math.max(e,Math.min(t,n))}function o(t,o,s){if(s&&(i=!0),i){t.preventDefault();var r=e.getBoundingClientRect(),l=r.width,h=r.height,c=o.clientX,u=o.clientY,d=a(c-r.left,0,l),p=a(u-r.top,0,h);n(d/l,p/h)}}function s(t,e){1===(void 0===t.buttons?t.which:t.buttons)?o(t,t,e):i=!1}function r(t,e){1===t.touches.length?o(t,t.touches[0],e):i=!1}t.add(e,"mousedown",function(t){s(t,!0)}),t.add(e,"touchstart",function(t){r(t,!0)}),t.add(window,"mousemove",s),t.add(e,"touchmove",r),t.add(window,"mouseup",function(t){i=!1}),t.add(e,"touchend",function(t){i=!1}),t.add(e,"touchcancel",function(t){i=!1})}var Ci="keydown",ki="mousedown",Si="focusin";function Li(t,e){return(e||document).querySelector(t)}function Ti(t,e,n,i,a){t.add(e,Ci,function(t){n.indexOf(t.key)>=0&&i(t)})}var Mi=function(){function t(e){gi(this,t),this.settings={popup:"right",layout:"default",alpha:!0,editor:!0,editorFormat:"hex",cancelButton:!1,defaultColor:"#0cf"},this._events=new wi,this.onChange=null,this.onDone=null,this.onOpen=null,this.onClose=null,this.setOptions(e)}return mi(t,[{key:"setOptions",value:function(t){var e=this;if(t){var n=this.settings;if(t instanceof HTMLElement)n.parent=t;else{n.parent&&t.parent&&n.parent!==t.parent&&(this._events.remove(n.parent),this._popupInited=!1),function(t,e){for(var n in t)e[n]=t[n]}(t,n),t.onChange&&(this.onChange=t.onChange),t.onDone&&(this.onDone=t.onDone),t.onOpen&&(this.onOpen=t.onOpen),t.onClose&&(this.onClose=t.onClose);var i=t.color||t.colour;i&&this._setColor(i)}var a=n.parent;if(a&&n.popup&&!this._popupInited){var o=function(t){return e.openHandler(t)};this._events.add(a,"click",o),Ti(this._events,a,[" ","Spacebar","Enter"],o),this._popupInited=!0}else t.parent&&!n.popup&&this.show()}}},{key:"openHandler",value:function(t){if(this.show()){t&&t.preventDefault(),this.settings.parent.style.pointerEvents="none";var e=t&&t.type===Ci?this._domEdit:this.domElement;setTimeout(function(){return e.focus()},100),this.onOpen&&this.onOpen(this.colour)}}},{key:"closeHandler",value:function(t){var e=t&&t.type,n=!1;if(t)if(e===ki||e===Si){var i=(this.__containedEvent||0)+100;t.timeStamp>i&&(n=!0)}else!function(t){t.preventDefault(),t.stopPropagation()}(t),n=!0;else n=!0;n&&this.hide()&&(this.settings.parent.style.pointerEvents="",e!==ki&&this.settings.parent.focus(),this.onClose&&this.onClose(this.colour))}},{key:"movePopup",value:function(t,e){this.closeHandler(),this.setOptions(t),e&&this.openHandler()}},{key:"setColor",value:function(t,e){this._setColor(t,{silent:e})}},{key:"_setColor",value:function(t,e){if("string"==typeof t&&(t=t.trim()),t){e=e||{};var n=void 0;try{n=new vi(t)}catch(a){if(e.failSilently)return;throw a}if(!this.settings.alpha){var i=n.hsla;i[3]=1,n.hsla=i}this.colour=this.color=n,this._setHSLA(null,null,null,null,e)}}},{key:"setColour",value:function(t,e){this.setColor(t,e)}},{key:"show",value:function(){if(!this.settings.parent)return!1;if(this.domElement){var t=this._toggleDOM(!0);return this._setPosition(),t}var e,n,i=this.settings.template||'<div class="picker_wrapper" tabindex="-1"><div class="picker_arrow"></div><div class="picker_hue picker_slider"><div class="picker_selector"></div></div><div class="picker_sl"><div class="picker_selector"></div></div><div class="picker_alpha picker_slider"><div class="picker_selector"></div></div><div class="picker_editor"><input aria-label="Type a color name or hex value"/></div><div class="picker_sample"></div><div class="picker_done"><button>Ok</button></div><div class="picker_cancel"><button>Cancel</button></div></div>',a=(e=i,(n=document.createElement("div")).innerHTML=e,n.firstElementChild);return this.domElement=a,this._domH=Li(".picker_hue",a),this._domSL=Li(".picker_sl",a),this._domA=Li(".picker_alpha",a),this._domEdit=Li(".picker_editor input",a),this._domSample=Li(".picker_sample",a),this._domOkay=Li(".picker_done button",a),this._domCancel=Li(".picker_cancel button",a),a.classList.add("layout_"+this.settings.layout),this.settings.alpha||a.classList.add("no_alpha"),this.settings.editor||a.classList.add("no_editor"),this.settings.cancelButton||a.classList.add("no_cancel"),this._ifPopup(function(){return a.classList.add("popup")}),this._setPosition(),this.colour?this._updateUI():this._setColor(this.settings.defaultColor),this._bindEvents(),!0}},{key:"hide",value:function(){return this._toggleDOM(!1)}},{key:"destroy",value:function(){this._events.destroy(),this.domElement&&this.settings.parent.removeChild(this.domElement)}},{key:"_bindEvents",value:function(){var t=this,e=this,n=this.domElement,i=this._events;function a(t,e,n){i.add(t,e,n)}a(n,"click",function(t){return t.preventDefault()}),_i(i,this._domH,function(t,n){return e._setHSLA(t)}),_i(i,this._domSL,function(t,n){return e._setHSLA(null,t,1-n)}),this.settings.alpha&&_i(i,this._domA,function(t,n){return e._setHSLA(null,null,null,1-n)});var o=this._domEdit;a(o,"input",function(t){e._setColor(this.value,{fromEditor:!0,failSilently:!0})}),a(o,"focus",function(t){var e=this;e.selectionStart===e.selectionEnd&&e.select()}),this._ifPopup(function(){var e=function(e){return t.closeHandler(e)};a(window,ki,e),a(window,Si,e),Ti(i,n,["Esc","Escape"],e);var o=function(e){t.__containedEvent=e.timeStamp};a(n,ki,o),a(n,Si,o),a(t._domCancel,"click",e)});var s=function(e){t._ifPopup(function(){return t.closeHandler(e)}),t.onDone&&t.onDone(t.colour)};a(this._domOkay,"click",s),Ti(i,n,["Enter"],s)}},{key:"_setPosition",value:function(){var t=this.settings.parent,e=this.domElement;t!==e.parentNode&&t.appendChild(e),this._ifPopup(function(n){"static"===getComputedStyle(t).position&&(t.style.position="relative");var i=!0===n?"popup_right":"popup_"+n;["popup_top","popup_bottom","popup_left","popup_right"].forEach(function(t){t===i?e.classList.add(t):e.classList.remove(t)}),e.classList.add(i)})}},{key:"_setHSLA",value:function(t,e,n,i,a){a=a||{};var o=this.colour,s=o.hsla;[t,e,n,i].forEach(function(t,e){(t||0===t)&&(s[e]=t)}),o.hsla=s,this._updateUI(a),this.onChange&&!a.silent&&this.onChange(o)}},{key:"_updateUI",value:function(t){if(this.domElement){t=t||{};var e=this.colour,n=e.hsla,i="hsl("+360*n[0]+", 100%, 50%)",a=e.hslString,o=e.hslaString,s=this._domH,r=this._domSL,l=this._domA,h=Li(".picker_selector",s),c=Li(".picker_selector",r),u=Li(".picker_selector",l);b(0,h,n[0]),this._domSL.style.backgroundColor=this._domH.style.color=i,b(0,c,n[1]),x(0,c,1-n[2]),r.style.color=a,x(0,u,1-n[3]);var d=a,p=d.replace("hsl","hsla").replace(")",", 0)"),f="linear-gradient("+[d,p]+")";if(this._domA.style.background=f+", linear-gradient(45deg, lightgrey 25%, transparent 25%, transparent 75%, lightgrey 75%) 0 0 / 2em 2em,\n linear-gradient(45deg, lightgrey 25%, white 25%, white 75%, lightgrey 75%) 1em 1em / 2em 2em",!t.fromEditor){var g=this.settings.editorFormat,m=this.settings.alpha,y=void 0;switch(g){case"rgb":y=e.printRGB(m);break;case"hsl":y=e.printHSL(m);break;default:y=e.printHex(m)}this._domEdit.value=y}this._domSample.style.color=o}function b(t,e,n){e.style.left=100*n+"%"}function x(t,e,n){e.style.top=100*n+"%"}}},{key:"_ifPopup",value:function(t,e){this.settings.parent&&this.settings.popup?t&&t(this.settings.popup):e&&e()}},{key:"_toggleDOM",value:function(t){var e=this.domElement;if(!e)return!1;var n=t?"":"none",i=e.style.display!==n;return i&&(e.style.display=n),i}}]),t}();function Pi(){const t=document.createElement("div");return t.className="ht-control-group",t}function Ei(t,e){const n=document.createElement("label");return n.className="ht-control-label",n.textContent=t,n.style.height=`${e}px`,n}function $i(t,e="",n){const i=document.createElement("button");return i.className="ht-button",i.textContent=t,i.title=e,i.style.height=`${n}px`,i}function zi(t,e,n,i,a){const o=document.createElement("input");return o.type="range",o.className="ht-slider",o.min=t,o.max=e,o.value=n,o.step=i,o.style.height=`${a}px`,o}function Ni(t,e){const n=Math.min(24,e-4),i=n-4,a=document.createElement("div");a.className=t?"ht-toggle active":"ht-toggle",a.style.height=`${n}px`;const o=document.createElement("div");return o.className="ht-toggle-knob",o.style.width=`${i}px`,o.style.height=`${i}px`,a.appendChild(o),a}function Ai(t,e,n,i,a){const o=document.createElement("input");return o.type="number",o.className="ht-number-input",o.value=t,o.min=e,o.max=n,o.step=i,o.style.height=`${a}px`,o}class Ri extends ai{state;scale;values;defaultPalette=["#440154","#365C8D","#1FA187","#9FDA3A"];treeState;constructor(t,e={}){if(super(),!e.scaleType)throw new Error("scaleType is required");if(void 0===e.default)throw new Error("default is required");this.values=t,this.treeState=e.treeState||null,this.state={scaleType:void 0,default:void 0,isCategorical:void 0,outputValues:null,outputRegex:null,colorPalette:this.defaultPalette,colorPositions:this.defaultPalette.map((t,e)=>e/(this.defaultPalette.length-1)),outputRange:null,inputUnits:null,title:null,maxCategories:7,otherCategory:"#888888",otherLabel:"Other",transformMin:0,transformMax:1,transformFn:null,nullValue:"#808080",showNullInLegend:!0,...e},this.updateScale(!1)}getValue(t){return this.scale.getValue(t)}updateScale(t=!0){const e=this.values,{scaleType:n,isCategorical:i}=this.state;let a,o=!0;if(i&&(this.state.outputValues||this.state.outputRegex)){if(this.state.outputValues)for(let t=0;t<e.length;t++)if(e[t]&&!this.state.outputValues.includes(e[t])){o=!1;break}if(this.state.outputRegex)for(let t=0;t<e.length;t++)if(e[t]&&!this.state.outputRegex.test(e[t])){o=!1;break}}else o=!1;if("null"===n)a=new hi(this.state),this.scale=a;else if("identity"===n||o)a=new ci(this.state),this.scale=a;else if("text"===n){if(!i)throw new Error("Text scales can only be used with categorical data");a=new ui(e,this.state),this.scale=a}else if("size"===n){if(i)throw new Error("Size scales can only be used with continuous data");const t=e.map(t=>Number(t)).filter(t=>!isNaN(t));if(0===t.length)console.warn("No numeric values found for size scale, using NullScale"),a=new hi(this.state);else{const e=Math.min(...t),n=Math.max(...t);a=new di(e,n,this.state)}this.scale=a}else{if("color"!==n)throw new Error(`Unknown scale type: ${n}`);if(i)a=new fi(e,this.state);else{const t=e.map(t=>Number(t)).filter(t=>!isNaN(t));if(0===t.length)console.warn("No numeric values found for color scale, using NullScale"),a=new hi(this.state);else{const e=Math.min(...t),n=Math.max(...t);a=new pi(e,n,this.state)}}this.scale=a}t&&this.notify("aestheticChange",this)}updateState(t){Object.assign(this.state,t),this.updateScale(this.values)}createSettingsWidget(t={}){const{controlHeight:e=20,columnId:n=null,root:i=document}=t;if(!n){const t=document.createElement("div");return t.textContent="Select a metadata column to edit its settings",t.style.padding="10px",t.style.color="#666",t}const a=document.createElement("div");if(a.className="ht-aesthetic-settings-content","color"===this.state.scaleType){const t=this.createColorPaletteEditor(e,i);if(t&&a.appendChild(t),this.state.isCategorical){const t=Pi(),i=Ei("Max colors:",e);t.appendChild(i);const o=Ai(this.state.maxCategories||7,2,100,1,e);o.addEventListener("input",t=>{const e=parseInt(t.target.value);isNaN(e)||e<1||(this.updateState({maxCategories:e}),this.updateScale(this.values),this.treeState&&(this.treeState.state.treeData.tree.each(t=>{const e=t[n];null!=e&&(t.tipLabelColor=this.getValue(e))}),this.treeState.updateCoordinates(),this.treeState.notify("legendsChange")))}),t.appendChild(o),a.appendChild(t)}const o=Pi(),s=Ei("Legend title:",e);o.appendChild(s);const r=document.createElement("input");if(r.type="text",r.className="ht-text-input",r.style.height=`${e}px`,r.style.flex="1",r.value=this.state.title||"",r.placeholder="Enter legend title",r.addEventListener("input",t=>{this.updateState({title:t.target.value}),this.treeState&&this.treeState.notify("legendsChange")}),o.appendChild(r),a.appendChild(o),!this.state.isCategorical){const t=Pi(),n=Ei("Units label:",e);t.appendChild(n);const i=document.createElement("input");i.type="text",i.className="ht-text-input",i.style.height=`${e}px`,i.style.flex="1",i.value=this.state.inputUnits||"",i.placeholder="Enter units (e.g., °C, km)",i.addEventListener("input",t=>{this.updateState({inputUnits:t.target.value}),this.treeState&&this.treeState.notify("legendsChange")}),t.appendChild(i),a.appendChild(t)}}if(0===a.children.length){const t=document.createElement("div");t.textContent="No settings available for this aesthetic",t.style.padding="10px",t.style.color="#666",a.appendChild(t)}return a}createColorPaletteEditor(t,e=document){if(!this.scale)return null;const n=document.createElement("div");n.className="ht-color-palette-editor";const i=document.createElement("div");i.className="ht-gradient-container";const a=document.createElement("div");a.className="ht-gradient-column";const o=document.createElement("div");o.className="ht-color-squares-container";const s=document.createElement("div");s.className="ht-gradient-box";const r=()=>{const t=this.state.colorPalette.map((t,e)=>`${t} ${100*this.state.colorPositions[e]}%`).join(", ");s.style.background=`linear-gradient(to right, ${t})`};r();let l=null;const h=e!==document&&e.appendChild?e:document.body,c=document.createElement("div");c.style.position="fixed",c.style.zIndex="999999",c.style.pointerEvents="auto",h.appendChild(c);const u=document.createElement("div");u.style.position="fixed",u.style.zIndex="999999",u.style.pointerEvents="auto",h.appendChild(u);const d=()=>{c.style.display="none",l=null},p=()=>{u.style.display="none"},f=document.createElement("div");f.className="ht-null-color-column";const g=document.createElement("div");g.className="ht-null-color-square-container";const m=document.createElement("div");m.style.display="flex",m.style.flexDirection="column",m.style.alignItems="center";const y=document.createElement("div");y.className="ht-null-color-square",y.style.backgroundColor=this.state.nullValue,y.title="Click to edit missing data color";const b=document.createElement("div");b.className="ht-null-color-square-tick",m.appendChild(y),m.appendChild(b),g.appendChild(m);const x=document.createElement("div");x.className="ht-null-color-box",x.style.backgroundColor=this.state.nullValue;const v=new Mi({parent:c,popup:!1,alpha:!1,editor:!0,color:this.state.colorPalette[0],onChange:t=>{if(!l)return;const e=parseInt(l.getAttribute("data-color-index")),n=t.hex.substring(0,7);this.state.colorPalette[e]=n,l.style.backgroundColor=n,r();const i=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMin);T.style.backgroundColor=i;const a=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMax);E.style.backgroundColor=a,this.updateScale()},onDone:()=>{d()}});c.style.display="none";const w=e!==document&&e.addEventListener?e:document,_=t=>{c.contains(t.target)||t.target.closest(".ht-color-square")||d()};w.addEventListener("click",_);const C=new Mi({parent:u,popup:!1,alpha:!1,editor:!0,color:this.state.nullValue,onChange:t=>{const e=t.hex.substring(0,7);this.state.nullValue=e,y.style.backgroundColor=e,x.style.backgroundColor=e,this.updateScale()},onDone:()=>{p()}});u.style.display="none";const k=t=>{u.contains(t.target)||t.target===y||p()};w.addEventListener("click",k),n.dataset.pickerCleanup="cleanup",n.cleanupFunction=()=>{w.removeEventListener("click",_),w.removeEventListener("click",k),c.parentElement&&c.parentElement.removeChild(c),u.parentElement&&u.parentElement.removeChild(u)};const S=()=>{o.innerHTML="",this.state.colorPalette.forEach((t,e)=>{const n=function(t,e,n,i){const a=document.createElement("div");a.className="ht-color-square-wrapper";const o=document.createElement("div");o.className="ht-color-square",o.style.backgroundColor=e,o.title="Click to edit color",o.setAttribute("data-color-index",n),o.addEventListener("click",i);const s=document.createElement("div");return s.className="ht-color-square-tick",a.appendChild(o),a.appendChild(s),t.appendChild(a),a}(o,t,e,t=>{t.preventDefault(),t.stopPropagation();const e=t.currentTarget,n=parseInt(e.getAttribute("data-color-index"));p(),l=e;const i=e.getBoundingClientRect();v.setColor(this.state.colorPalette[n],!0),c.style.left=`${i.left}px`,c.style.top=`${i.bottom+5}px`,c.style.display="block"});n.style.left=100*this.state.colorPositions[e]+"%"})};S();const L=document.createElement("div");L.className="ht-range-slider-container";const T=document.createElement("div");T.className="ht-range-handle",T.style.left=100*this.state.transformMin+"%",T.title="Drag to adjust minimum";let M=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMin);T.style.backgroundColor=M;const P=document.createElement("div");P.className="ht-range-handle-indicator",T.appendChild(P);const E=document.createElement("div");E.className="ht-range-handle",E.style.left=100*this.state.transformMax+"%",E.title="Drag to adjust maximum";let $=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMax);E.style.backgroundColor=$;const z=document.createElement("div");z.className="ht-range-handle-indicator",E.appendChild(z);let N=!1;T.addEventListener("mousedown",t=>{N=!0,t.preventDefault()});let A=!1;E.addEventListener("mousedown",t=>{A=!0,t.preventDefault()});document.addEventListener("mousemove",t=>{if(!N&&!A)return;const e=L.getBoundingClientRect(),n=t.clientX-e.left,i=e.width;let a=Math.max(0,Math.min(1,n/i));N?(a=Math.min(a,this.state.transformMax-.01),this.state.transformMin=a,T.style.left=100*a+"%",M=Di(this.state.colorPalette,this.state.colorPositions,a),T.style.backgroundColor=M,this.updateScale()):A&&(a=Math.max(a,this.state.transformMin+.01),this.state.transformMax=a,E.style.left=100*a+"%",$=Di(this.state.colorPalette,this.state.colorPositions,a),E.style.backgroundColor=$,this.updateScale())}),document.addEventListener("mouseup",()=>{N=!1,A=!1}),L.appendChild(T),L.appendChild(E),a.appendChild(o),a.appendChild(s),a.appendChild(L),y.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),d();const e=y.getBoundingClientRect();C.setColor(this.state.nullValue,!0),u.style.left=`${e.left}px`,u.style.top=`${e.bottom+5}px`,u.style.display="block"});const R=document.createElement("div");R.className="missing-data-x-container";const H=document.createElement("div");H.className="missing-data-x-container-triangle";const D=document.createElement("div");D.className="missing-data-x",D.textContent="✕",R.appendChild(H),R.appendChild(D),f.appendChild(g),f.appendChild(x),f.appendChild(R),i.appendChild(a),i.appendChild(f);const B=document.createElement("div");B.className="ht-palette-buttons-container";const I=Hi("+","Add color to left");I.addEventListener("click",()=>{const t=this.state.colorPalette[0];this.state.colorPalette.unshift(t),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),r(),S(),M=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),T.style.backgroundColor=M,$=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),E.style.backgroundColor=$,this.updateScale()});const F=Hi("-","Remove color from left");F.addEventListener("click",()=>{this.state.colorPalette.length<=2?console.warn("Cannot remove color: minimum 2 colors required"):(this.state.colorPalette.shift(),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),r(),S(),M=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),T.style.backgroundColor=M,$=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),E.style.backgroundColor=$,this.updateScale())}),B.appendChild(I),B.appendChild(F);const V=document.createElement("div");V.className="ht-palette-buttons-container";const q=Hi("+","Add color to right");q.addEventListener("click",()=>{const t=this.state.colorPalette[this.state.colorPalette.length-1];this.state.colorPalette.push(t),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),r(),S(),M=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),T.style.backgroundColor=M,$=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),E.style.backgroundColor=$,this.updateScale()});const X=Hi("-","Remove color from right");return X.addEventListener("click",()=>{this.state.colorPalette.length<=2?console.warn("Cannot remove color: minimum 2 colors required"):(this.state.colorPalette.pop(),this.state.colorPositions=this.state.colorPalette.map((t,e)=>e/(this.state.colorPalette.length-1)),r(),S(),M=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMin),T.style.backgroundColor=M,$=Di(this.state.colorPalette,this.state.colorPositions,this.state.transformMax),E.style.backgroundColor=$,this.updateScale())}),V.appendChild(q),V.appendChild(X),n.appendChild(B),n.appendChild(i),n.appendChild(V),n}}function Hi(t,e){const n=document.createElement("button");return n.className="ht-palette-button",n.textContent=t,n.title=e,n}function Di(t,e,n){if(n=Math.max(0,Math.min(1,n)),1===t.length)return t[0];let i=0;for(;i<e.length-1&&n>e[i+1];)i++;if(n===e[i])return t[i];if(i===e.length-1)return t[i];const a=e[i],o=(n-a)/(e[i+1]-a),s=Bi(t[i]),r=Bi(t[i+1]);return function(t,e,n){return"#"+[t,e,n].map(t=>{const e=t.toString(16);return 1===e.length?"0"+e:e}).join("")}(Math.round(s.r+(r.r-s.r)*o),Math.round(s.g+(r.g-s.g)*o),Math.round(s.b+(r.b-s.b)*o))}function Bi(t){const e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:{r:0,g:0,b:0}}class Ii extends ai{tree;metadata=new Map;metadataTableNames=new Map;columnType=new Map;columnName=new Map;columnDisplayName=new Map;columnAesthetic=new Map;nodeIdColumn=new Map;validIdColumns=new Map;#t=0;constructor(t,e=[],n=[]){super(),this.tree=this.createHierarchy(t),Array.isArray(e)&&e.forEach((t,e)=>{this.addTable(t,n[e])})}static fromTreeString(t,e=[],n=[]){const i=Ii.parseTrees(t,"Tree");if(1!==i.length)throw new Error(`Expected exactly one tree, but found ${i.length}. Use TreeData.parseTrees() for multiple trees.`);return new Ii(i[0].treeData,e,n)}static parseTrees(t,e="Tree"){let n;if(function(t){const e=t.trim().split(/\r?\n/)[0].trim();return/^#NEXUS$/i.test(e)}(t))n=function(t){const e=[],n=/begin\s+trees\s*;([^]*?)end\s*;/gi;let i;for(;null!==(i=n.exec(t));){const t=ri(i[1]);e.push(...t)}return e}(t);else{n=[{treeName:null,treeData:li(t)}]}const i=n.length>1;return n.map((t,n)=>{let a;return a=t.treeName?i?`${e} ${t.treeName}`:`${e} - ${t.treeName}`:i?`${e} ${n+1}`:e,{name:a,treeData:t.treeData}})}createHierarchy(t){const e=Ln(t,t=>t.children).sum(t=>t.children?0:1).each(function(t){t.leafCount=t.value,delete t.value,delete t.data.children}).sort((t,e)=>t.leafCount-e.leafCount||function(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}(t.data.length,e.data.length));let n=0;return e.each(t=>{t.id=++n}),e}setTree(t){this.tree=this.createHierarchy(t),this.metadata.keys().forEach(t=>this.#e(t)),this.notify("treeUpdated",this)}getMetadataTableNames(){return Array.from(this.metadataTableNames.values())}getTreeNodeNames(){const t=new Set;return this.tree.each(e=>{e.data.name&&t.add(e.data.name)}),t}#n(t){const e=this.metadata.get(t),n=this.nodeIdColumn.get(t);if(!e||!n)return new Map;const i=new Map;for(const a of e){const t=a[n];t&&i.set(t,a)}return i}addTable(t,e=null,n="\t"){let{metadataMap:i,columnTypes:a,idColumns:o}=function(t,e,n="\t"){let i=new Map,a=new Map,o=[],s=[];const r=t.trim().split("\n");if(0==r.length)console.error("Empty metadata table");else{const t=r[0].split(n),l=new Map;t.forEach(t=>l.set(t,[]));for(let e=1;e<r.length;e++){const a=r[e].split(n),o={};for(let e=0;e<t.length;e++){const n=t[e],i=""===a[e]?void 0:a[e];o[n]=i,l.get(n).push(i)}i.set(e-1,o)}t.forEach(t=>{const n=l.get(t),i=n.map(t=>parseFloat(t)).filter(t=>!isNaN(t)),s=i.length>0&&i.length===n.filter(t=>void 0!==t).length;a.set(t,s?"continuous":"categorical");let r=0;for(const a of n)a&&e.has(a)&&r++;r>0&&o.push({col:t,matchCount:r})}),o=o.sort((t,e)=>e.matchCount-t.matchCount),s=o.map(t=>t.col)}return{metadataMap:i,columnTypes:a,idColumns:s}}(t,this.getTreeNodeNames(),n);const s="table_"+this.#t++;e||(e=`Metadata ${this.#t}`),this.metadataTableNames.set(s,e);const r=new Map;for(const[c,u]of a){const t=`${s}_${c}`;r.set(c,t),this.columnType.set(t,u),this.columnName.set(t,c),this.columnDisplayName.set(t,ei(c))}o=o.map(t=>r.get(t));let l=null;o.length>0?l=o[0]:console.warn(`No valid node ID column found in table ${e}`);const h=[];for(const c of i.values()){const t={};for(const[e,n]of Object.entries(c)){const i=r.get(e);i&&(t[i]=n)}h.push(t)}return this.validIdColumns.set(s,o),this.nodeIdColumn.set(s,l),this.metadata.set(s,h),this.#e(s),this.notify("metadataAdded",{tableId:s,columnIds:Array.from(r.values())}),s}getValidIdColumns(t){return this.validIdColumns.get(t)||[]}getNodeIdColumn(t){return this.nodeIdColumn.get(t)}getTableColumnIds(t){const e=this.metadata.get(t);return e&&0!==e.length?Object.keys(e[0]):[]}setNodeIdColumn(t,e){if(!this.metadata.get(t))return void console.warn(`Table ${t} does not exist`);if(!this.validIdColumns.get(t).includes(e))return void console.warn(`Column ${e} is not a valid ID column for table ${t}`);const n=this.nodeIdColumn.get(t);if(n===e)return;const i=this.getTableColumnIds(t);for(const a of i)this.columnAesthetic.delete(a);this.#i(t),this.nodeIdColumn.set(t,e),this.#e(t),this.notify("metadataChanged",{tableId:t,oldIdColumn:n,newIdColumn:e,columnIds:i,requiresAestheticRefresh:!0})}deleteTable(t){const e=this.metadata.get(t);if(!e)return void console.warn(`Table ${t} does not exist`);const n=e.length>0?Object.keys(e[0]):[];for(const i of n)this.columnType.delete(i),this.columnName.delete(i),this.columnDisplayName.delete(i),this.columnAesthetic.delete(i);this.#i(t),this.metadata.delete(t),this.metadataTableNames.delete(t),this.nodeIdColumn.delete(t),this.validIdColumns.delete(t),this.notify("metadataChanged",{tableId:t,columnIds:n})}getAesthetic(t,e,n={}){this.columnAesthetic.has(t)||this.columnAesthetic.set(t,new Map);const i=this.columnAesthetic.get(t);if(i.has(e))return i.get(e);const a=this.#a(t,n);return i.set(e,a),a}setAesthetic(t,e,n){this.columnAesthetic.has(t)||this.columnAesthetic.set(t,new Map),this.columnAesthetic.get(t).set(e,n)}#a(t,e={}){const n=this.columnType.get(t),i="categorical"===n;n||console.error(`Column ${t} not found`);let a=[];this.tree.each(n=>{"tips"==e.subset&&n.children||(n.metadata?a.push(n.metadata[t]):a.push(void 0))}),0===a.length&&console.error(`No values found for column ${t}`);const o=this.columnDisplayName.get(t)||t;let s=e.scaleType;s||(s="color");return new Ri(a,{scaleType:s,default:void 0!==e.default?e.default:i?null:0,isCategorical:i,inputUnits:o,...e})}#e(t){const e=this.#n(t);this.tree.each(t=>{const n=t.data.name;if(n&&e.has(n)){const i=e.get(n);t.metadata={...t.metadata,...i}}})}#i(t){const e=this.metadata.get(t);if(!e||0===e.length)return;const n=Object.keys(e[0]);this.tree.each(t=>{t.metadata&&n.forEach(e=>{delete t.metadata[e]})})}}function Fi(t,e){const n=t.leaves().map((t,n)=>({radius:t.radius,angle:t.angle,cos:t.cos,sin:t.sin,width:(t.tipLabelBounds.width+e.nodeLabelOffset)*t.tipLabelSize,height:t.tipLabelBounds.height*t.tipLabelSize,labelScale:t.tipLabelSize}));let i=0,a=1/0,o=0,s=1/0;function r(t){t>i&&(i=t>a?a:t)}function l(t){t<s&&(s=t<o?o:t)}function h(t){t>o&&(o=t>s?s:t)}const c=Math.min(...n.map(t=>t.labelScale)),u=Math.max(...n.map(t=>t.radius)),d=n.reduce((t,e)=>t+e.radius,0)/n.length,p=t.descendants().filter(t=>t.data.length>0&&t.children),f=p.length>0?Math.min(...p.map(t=>t.data.length)):1/0;h(e.minFontPx/c),i!==a&&r(Math.max(...n.map(t=>t.width*o/(u/e.minBranchLenProp-t.radius))));const g=n.reduce((t,e)=>t+e.height,0);function m(){const t=Math.min(...n.filter(t=>t.cos>0).map(t=>(e.viewWidth/2-t.width*t.cos*o)/(t.radius*t.cos))),s=Math.min(...n.filter(t=>t.cos<0).map(t=>(e.viewWidth/2-t.width*-t.cos*o)/(t.radius*-t.cos))),r=Math.min(...n.filter(t=>t.sin>0).map(t=>(e.viewHeight/2-t.width*t.sin*o)/(t.radius*t.sin))),l=Math.min(...n.filter(t=>t.sin<0).map(t=>(e.viewHeight/2-t.width*-t.sin*o)/(t.radius*-t.sin)));var h;(h=Math.min((t+s)/2,(l+r)/2))<a&&(a=h<i?i:h)}function y(){const t=Math.min(...n.filter(t=>t.cos>0).map(t=>(e.viewWidth/2-t.radius*t.cos*i)/(t.width*t.cos))),a=Math.min(...n.filter(t=>t.cos<0).map(t=>(e.viewWidth/2-t.radius*-t.cos*i)/(t.width*-t.cos))),o=Math.min(...n.filter(t=>t.sin>0).map(t=>(e.viewHeight/2-t.radius*t.sin*i)/(t.width*t.sin))),s=Math.min(...n.filter(t=>t.sin<0).map(t=>(e.viewHeight/2-t.radius*-t.sin*i)/(t.width*-t.sin)));l(Math.min((t+a)/2,(s+o)/2))}return g>0&&d>0&&(i!==a&&r(g*o/(2*d*Math.PI)),o!==s&&l(u*a*2*Math.PI/g)),m(),y(),o!==s&&h(e.idealFontPx/c),i!==a&&m(),isFinite(f)&&f>0&&i!==a&&r(e.minBranchThicknessPx/f),o!==s&&y(),o!==s&&l(e.maxFontPx/c),{branchLenToPxFactor_min:i,branchLenToPxFactor_max:a,labelSizeToPxFactor_min:o,labelSizeToPxFactor_max:s}}class Vi{constructor(){this.metricsCache=new Map,this.setupHiddenEnvironment()}setupHiddenEnvironment(){this.hiddenContainer=document.createElement("div"),this.hiddenContainer.style.cssText="\n position: absolute;\n top: -9999px;\n left: -9999px;\n visibility: hidden;\n width: 5000px;\n height: 5000px;\n overflow: hidden;\n ",this.hiddenSVG=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.hiddenSVG.setAttribute("width","5000"),this.hiddenSVG.setAttribute("height","5000"),this.hiddenSVG.setAttribute("viewBox","0 0 5000 5000"),this.hiddenContainer.appendChild(this.hiddenSVG),document.body.appendChild(this.hiddenContainer),this.hiddenD3SVG=bt(this.hiddenSVG),this.textGroup=this.hiddenD3SVG.append("g").attr("id","text-measurement-group")}getRelativeTextSize(t,e={}){const n=`${t}-${JSON.stringify(e)}`;if(this.metricsCache.has(n))return this.metricsCache.get(n);const i=this.textGroup.append("text").attr("x",1e3).attr("y",2500).text(t);Object.keys(e).forEach(t=>{i.style(t,e[t])}),this.hiddenSVG.getBoundingClientRect();const a=i.node().getBBox(),o=window.getComputedStyle(i.node()),s=parseFloat(o.fontSize);i.remove();const r={width:a.width/s,height:a.height/s};return this.metricsCache.set(n,r),r}getTextSize(t,e,n={}){const i=this.getRelativeTextSize(t,n);return{width:i.width,height:i.height,widthPx:i.width*e,heightPx:i.height*e}}clearCache(){this.metricsCache.clear()}destroy(){this.hiddenContainer&&this.hiddenContainer.parentNode&&this.hiddenContainer.parentNode.removeChild(this.hiddenContainer),this.metricsCache.clear()}}class qi extends ai{#o={tipLabelText:{title:"Tip label text",scaleType:"identity",default:"",nullValue:"",downstream:["updateTipLabelText","updateCoordinates"],hasLegend:!1,subset:"tips"},tipLabelColor:{title:"Tip label color",scaleType:"color",default:"#000000",nullValue:"#808080",otherCategory:"#555555",downstream:[],hasLegend:!0,subset:"tips"},tipLabelSize:{title:"Tip label size",scaleType:"size",default:1,nullValue:1,isCategorical:!1,outputRange:[.5,2],downstream:["updateCoordinates"],hasLegend:!0,subset:"tips"},tipLabelFont:{title:"Tip label font",scaleType:"identity",default:"sans-serif",nullValue:"sans-serif",downstream:["updateCoordinates"],hasLegend:!1,subset:"tips"},tipLabelStyle:{title:"Tip label font style",scaleType:"text",outputValues:["normal","bold","italic","bold italic"],default:"normal",nullValue:"normal",otherCategory:"italic",downstream:["updateCoordinates"],hasLegend:!1,subset:"tips"},nodeLabelText:{title:"Node label text",scaleType:"identity",default:"",nullValue:"",downstream:["updateNodeLabelText"],hasLegend:!1,subset:"all"},nodeLabelSize:{title:"Node label size",scaleType:"size",default:1,nullValue:1,isCategorical:!1,outputRange:[.5,2],downstream:["updateCoordinates"],hasLegend:!1,subset:"all"}};state={treeData:null,layout:"rectangular",aesthetics:Object.fromEntries(Object.keys(this.#o).map(t=>[t,void 0])),viewWidth:800,viewHeight:600,labelSpacing:.1,nodeLabelSizeScale:.67,nodeLabelOffset:.3,maxLabelWidthProportion:.03,branchThicknessProp:.15,minFontPx:12,idealFontPx:18,maxFontPx:32,minBranchThicknessPx:1,minBranchLenProp:.5,collapsedRootLineProp:.05,branchLengthScale:1,treeHeightScale:1};textSizeEstimator;displayedRoot;occupiedWidth;occupiedHeight;branchLenToPxFactor;labelSizeToPxFactor;aestheticsScales={};legends=[];constructor(t={},e=new Vi){super(),t.treeData&&t.treeData.tree?e?(t.aesthetics={...this.state.aesthetics,...t.aesthetics},this.state={...this.state,...t},this.textSizeEstimator=e,this.#s(),this.state.treeData.subscribe("treeUpdate",()=>{this.#s()}),this.state.treeData.subscribe("metadataChanged",t=>{if(t.columnIds&&Array.isArray(t.columnIds))if(t.requiresAestheticRefresh){const e={};for(const[n,i]of Object.entries(this.state.aesthetics))i&&t.columnIds.includes(i)&&(e[n]=i);Object.keys(e).length>0&&this.setAesthetics(e,!0)}else this.setAesthetics(Object.fromEntries(t.columnIds.map(t=>[t,void 0])))})):console.error("TreeState initialized without textSizeEstimator"):console.error("TreeState initialized without valid tree data")}#s(){this.displayedRoot=this.state.treeData.tree,this.updateLayout(),this.setAesthetics(this.state.aesthetics,!0)}setLayout(t,e=!1){["circular","rectangular"].includes(t)?(e||this.state.layout!==t)&&(this.state.layout=t,this.update(),this.notify("layoutChange",{layout:t})):console.warn(`Invalid layout type: ${t}`)}setBranchLengthScale(t){t<.01||t>100?console.warn(`Branch length scale out of range: ${t}`):(this.state.branchLengthScale=t,this.updateCoordinates(),this.notify("branchLengthScaleChange",{scale:t}))}setTreeHeightScale(t){t<.1||t>10?console.warn(`Tree height scale out of range: ${t}`):(this.state.treeHeightScale=t,this.updateCoordinates(),this.notify("treeHeightScaleChange",{scale:t}))}setAesthetics(t,e=!1){const n=new Set;let i=!1;for(const[a,o]of Object.entries(t)){const t=this.#o[a];if(t){if(e||o!==this.state.aesthetics[a]){this.state.aesthetics[a]=o,o?(this.aestheticsScales[a]=this.state.treeData.getAesthetic(o,a,t),this.aestheticsScales[a].subscribe("aestheticChange",()=>{this.#r(a,o),this.#l(),this.notify(`${a}Change`)})):this.aestheticsScales[a]=new hi({default:t.default}),this.#r(a,o);for(const e of t.downstream)n.add(e);t.hasLegend&&(i=!0)}this.notify(`${a}Change`)}else console.warn(`Unknown aesthetic: ${a}`)}i&&this.#l();for(const a of n)this[a]()}#r(t,e){const n=this.#o[t];this.state.treeData.tree.each(i=>{e&&null!=e?i.metadata?i[t]=this.aestheticsScales[t].getValue(i.metadata[e]):i[t]=n.default:i[t]=this.aestheticsScales[t].getValue()})}#l(){this.legends=[];for(const[t,e]of Object.entries(this.state.aesthetics)){const n=this.#o[t];if(!n.hasLegend||!e)continue;const i=this.aestheticsScales[t];i&&this.legends.push({aestheticId:t,aesthetic:i,type:n.scaleType})}this.notify("legendsChange")}setTargetTreeDimensions(t,e){this.state.viewWidth=t,this.state.viewHeight=e,this.updateCoordinates()}collapseSubtree(t){t?t.children?(t.collapsedChildren=t.children,delete t.children,this.update()):console.warn("Tried to collapse node with no children"):console.warn("Tried to collapse non-existant node")}expandSubtree(t){t&&t.collapsedChildren&&(t.children=t.collapsedChildren,delete t.collapsedChildren,this.update())}rotateSubtree(t){if(!t)return void console.warn("Tried to rotate non-existent node");if(!t.children||t.children.length<2)return void console.warn("Tried to rotate node with fewer than 2 children");const e=t.children.shift();t.children.push(e),this.update()}hideSubtree(t){if(!t)return void console.warn("Tried to hide non-existent node");if(!t.parent)return void console.warn("Cannot hide the root node");t.hidden=!0;const e=t.parent;e.children&&(e.hiddenChildren=e.hiddenChildren||[],e.hiddenChildren.push(t),e.children=e.children.filter(e=>e!==t),0===e.children.length&&(delete e.children,this.hideSubtree(e))),this.update()}showSubtree(t){if(!t||!t.hidden)return;const e=t.parent;e&&e.hiddenChildren&&(e.hiddenChildren=e.hiddenChildren.filter(e=>e!==t),0===e.hiddenChildren.length&&delete e.hiddenChildren,e.children||(e.children=[]),e.children.push(t),e.children.sort((t,n)=>(e.data.children?e.data.children.indexOf(t.data):0)-(e.data.children?e.data.children.indexOf(n.data):0)),delete t.hidden,this.update())}showAllHidden(){const t=[];this.state.treeData.tree.each(e=>{e.hiddenChildren&&t.push(...e.hiddenChildren)});for(const e of t)this.showSubtree(e)}collapseRoot(t){t&&t!==this.displayedRoot&&(this.displayedRoot=t,this.displayedRoot.collapsedParent=this.displayedRoot.parent,delete this.displayedRoot.parent,this.update())}expandRoot(){if(!this.displayedRoot||!this.displayedRoot.collapsedParent)return;this.displayedRoot.parent=this.displayedRoot.collapsedParent,delete this.displayedRoot.collapsedParent;let t=this.displayedRoot;for(;t.parent&&!t.collapsedParent;)t=t.parent;this.displayedRoot=t,this.update()}updateTipLabelText(){this.state.treeData.tree.each(t=>{null===this.state.aesthetics.tipLabelText?t.tipLabelText="":!t.children&&!t.collapsedChildren||void 0!==this.state.aesthetics.tipLabelText&&t.tipLabelText?t.tipLabelText||(t.tipLabelText=t.data.name||""):t.tipLabelText=`Clade with ${t.leafCount} tips`})}updateNodeLabelText(){this.state.treeData.tree.each(t=>{t.children||t.collapsedChildren?t.nodeLabelText=t.data.name||"":t.nodeLabelText||(t.tipLabel=t.data.name||"")})}update(){this.updateLayout(),this.updateCoordinates()}updateLayout(){kn().separation((t,e)=>1)(this.displayedRoot),this.displayedRoot.each(t=>{t.parent?(t.branchLen=t.data.length?t.data.length:0,t.y=t.parent.y+t.branchLen):t.y=0}),this.displayedRoot.each(t=>{const e=t.x,n=t.y;t.x=n,t.y=e,t.angle=t.y*Math.PI*2+Math.PI,t.cos=Math.cos(t.angle),t.sin=Math.sin(t.angle),t.radius=t.x}),this.displayedRoot.eachAfter(t=>{t.x=t.x-this.displayedRoot.x,t.y=t.y-this.displayedRoot.y})}getCollapsedTriangleHeight(t){return t.tipLabelSizePx+1.1}getCollapsedTriangleOffset(t){return.52*this.getCollapsedTriangleHeight(t)}updateCoordinates(){let t;this.displayedRoot.each(t=>{t.tipLabelBounds=this.textSizeEstimator.getRelativeTextSize(t.tipLabelText,{"font-family":t.tipLabelFont,"font-style":t.tipLabelStyle}),t.nodeLabelBounds=this.textSizeEstimator.getRelativeTextSize(t.nodeLabelText,{"font-family":t.nodeLabelFont,"font-style":t.nodeLabelStyle})}),t="circular"===this.state.layout?Fi(this.displayedRoot,this.state):function(t,e){const n=t.leaves().map(t=>({x:t.x,width:(t.tipLabelBounds.width+e.nodeLabelOffset)*t.tipLabelSize,height:t.tipLabelBounds.height*t.tipLabelSize,labelScale:t.tipLabelSize}));let i=0,a=1/0,o=0,s=1/0;function r(t){t<a&&(a=t<i?i:t)}function l(t){t>i&&(i=t>a?a:t)}function h(t){t<s&&(s=t<o?o:t)}function c(t){t>o&&(o=t>s?s:t)}const u=Math.min(...n.map(t=>t.labelScale)),d=Math.max(...n.map(t=>t.x)),p=t.descendants().filter(t=>t.data.length>0&&t.children),f=p.length>0?Math.min(...p.map(t=>t.data.length)):1/0;return c(e.minFontPx/u),l(Math.max(...n.map(t=>t.width*o/(d/e.minBranchLenProp-t.x)))),r(Math.min(...n.map(t=>(e.viewWidth-t.width*o)/t.x))),h(Math.min(...n.map(t=>(e.viewWidth-t.x*i)/t.width))),o!=s&&h(e.viewHeight/n.reduce((t,e)=>t+e.height,0)),o!=s&&c(e.idealFontPx/u),i!=a&&r(Math.min(...n.map(t=>(e.viewWidth-t.width*o)/t.x))),isFinite(f)&&(i!=a&&l(e.minBranchThicknessPx/f),o!=s&&h(Math.min(...n.map(t=>(e.viewWidth-t.x*i)/t.width)))),o!=s&&h(e.maxFontPx/u),{branchLenToPxFactor_min:i,branchLenToPxFactor_max:a,labelSizeToPxFactor_min:o,labelSizeToPxFactor_max:s}}(this.displayedRoot,this.state),this.branchLenToPxFactor=t.branchLenToPxFactor_max*this.state.branchLengthScale,this.labelSizeToPxFactor=t.labelSizeToPxFactor_min,this.displayedRoot.each(t=>{t.branchLenPx=t.branchLen*this.branchLenToPxFactor,t.tipLabelSizePx=t.tipLabelSize*this.labelSizeToPxFactor,t.nodeLabelSizePx=t.nodeLabelSize*this.labelSizeToPxFactor*this.state.nodeLabelSizeScale;let e=t.tipLabelSizePx*this.state.nodeLabelOffset;t.collapsedChildren&&(e+=1.3*this.getCollapsedTriangleOffset(t)),t.tipLabelXOffsetPx=e,t.nodeLabelXOffsetPx=t.nodeLabelSizePx*this.state.nodeLabelOffset,t.tipLabelYOffsetPx=t.tipLabelSizePx*t.tipLabelBounds.height/2,t.nodeLabelYOffsetPx=t.nodeLabelSizePx*t.nodeLabelBounds.height/2,t.tipLabelBounds.widthPx=t.tipLabelBounds.width*t.tipLabelSizePx,t.tipLabelBounds.heightPx=t.tipLabelBounds.height*t.tipLabelSizePx}),"circular"===this.state.layout?this.displayedRoot.each(t=>{t.radiusPx=t.radius*this.branchLenToPxFactor,t.xPx=t.radiusPx*t.cos,t.yPx=t.radiusPx*t.sin}):this.displayedRoot.each(t=>{t.xPx=t.x*this.branchLenToPxFactor,t.yPx=t.y*this.displayedRoot.leaves().length*this.labelSizeToPxFactor*(1+this.state.labelSpacing)*this.state.treeHeightScale}),"circular"===this.state.layout?this.state.treeData.tree.eachAfter(t=>{if(t.children)t.bounds={minRadius:t.radiusPx,maxRadius:Math.max(...t.children.map(t=>t.bounds.maxRadius)),minAngle:Math.min(...t.children.map(t=>t.bounds.minAngle)),maxAngle:Math.max(...t.children.map(t=>t.bounds.maxAngle)),minX:Math.min(...t.children.map(t=>t.bounds.minX)),maxX:Math.max(...t.children.map(t=>t.bounds.maxX)),minY:Math.min(...t.children.map(t=>t.bounds.minY)),maxY:Math.max(...t.children.map(t=>t.bounds.maxY))};else{const e=t.radiusPx,n=e+t.tipLabelXOffsetPx+t.tipLabelBounds.widthPx,i=Math.atan(t.tipLabelYOffsetPx/t.radiusPx),a=t.angle-i,o=t.angle+i,s=[e*Math.cos(a),e*Math.cos(o),n*Math.cos(o),n*Math.cos(a)],r=[e*Math.sin(a),e*Math.sin(o),n*Math.sin(o),n*Math.sin(a)];t.bounds={minRadius:e,maxRadius:n,minAngle:a,maxAngle:o,minX:Math.min(...s),maxX:Math.max(...s),minY:Math.min(...r),maxY:Math.max(...r)}}}):this.state.treeData.tree.eachAfter(t=>{t.children?t.bounds={minX:t.xPx,maxX:Math.max(...t.children.map(t=>t.bounds.maxX)),minY:Math.min(...t.children.map(t=>t.bounds.minY)),maxY:Math.max(...t.children.map(t=>t.bounds.maxY))}:t.bounds={minX:t.xPx,maxX:t.xPx+t.tipLabelXOffsetPx+t.tipLabelBounds.widthPx,minY:t.yPx-t.tipLabelYOffsetPx,maxY:t.yPx+t.tipLabelYOffsetPx}}),this.notify("coordinateChange")}}const Xi={refresh:["m 16,7 h 5 V 2","M 22,12 A 10,10 0 0 1 13.58,21.9 10,10 0 0 1 2.5,15.2 10,10 0 0 1 7.4,3.14 10,10 0 0 1 20,6"],outwardArrows:["m 9,19 3,3 3,-3","M 12,22 V 15","m 9,5 3,-3 3,3","M 12,2 V 9","m 5,9 -3,3 3,3","M 2,12 H 9","M 19,15 22,12 19,9","M 22,12 H 15"],compress:["M 5,12 H 19","m 9,18 3,-3 3,3","m 12,15 v 7","m 9,6 3,3 3,-3","M 12,9 V 2"],expand:["M 5,2 H 19","M 5,22 H 19","m 9,8 3,-3 3,3","m 9,16 3,3 3,-3","M 12,5 V 19"],circle:["M 12,2 A 10,10 0 1 1 12,22 A 10,10 0 1 1 12,2"],trash:["M 3,6 H 21","M 19,6 V 20 A 2,2 0 0 1 17,22 H 7 A 2,2 0 0 1 5,20 V 6","M 8,6 V 4 A 2,2 0 0 1 10,2 H 14 A 2,2 0 0 1 16,4 V 6","M 10,11 V 17","M 14,11 V 17"],rotate:["M 3,12 H 8","M 13,6 H 8 v 12 h 5","m 17,4 c 0,0 9,8 0,16","M 17,8 V 4 h 4","M 21,20 H 17 V 16"],edit:["m 12,8 -8,8 -1,5 5,-1 8,-8 z","M 21,7 18,10 14,6 17,3 Z"]};class Oi{constructor(t={}){this.state={aesthetic:null,x:0,y:0,origin:"top left",maxX:1/0,maxY:1/0,titleFontSize:16,labelFontSize:14,...t},this.coordinates={},this.group=null,this.textSizeEstimator=this.state.treeState.textSizeEstimator}render(t){this.group=t.append("g").attr("class","ht-legend"),this.updateCoordinates(),this.updatePosition()}updateCoordinates(){throw new Error("updateCoordinates must be implemented by subclass")}updatePosition(){if(!this.group)return;let t=this.state.x,e=this.state.y;const{width:n,height:i}=this.coordinates;this.state.origin.includes("right")&&(t-=n),this.state.origin.includes("bottom")&&(e-=i),this.group.attr("transform",`translate(${t}, ${e})`)}renderTitle(t){return this.group.append("text").attr("class","legend-title").attr("x",0).attr("y",0).attr("text-anchor","start").style("font-size",`${this.state.titleFontSize}px`).style("text-decoration","underline").text(t)}}class Yi extends Oi{constructor(t={}){super(t),this.scaleBarEdgeHeight=6,this.titleSpacing=10,this.unitLabelSpacing=2,this.minBarLength=80,this.maxBarLength=160,this.lineThickness=2,this.showTitle=!1,this.title="Branch length"}updateCoordinates(){let t=Jn(1),e=t*this.state.treeState.branchLenToPxFactor;for((e<this.minBarLength||e>this.maxBarLength)&&(t=Jn(this.minBarLength/this.state.treeState.branchLenToPxFactor),e=t*this.state.treeState.branchLenToPxFactor);e<this.minBarLength;)t*=2,e=t*this.state.treeState.branchLenToPxFactor;for(;e>this.maxBarLength;)t/=2,e=t*this.state.treeState.branchLenToPxFactor;t=t.toPrecision(3);const n=this.textSizeEstimator.getTextSize(t,this.state.labelFontSize);this.textSizeEstimator.getTextSize(this.title,this.state.titleFontSize);let i=0;this.showTitle&&(i=this.state.titleFontSize+this.titleSpacing);const a=i+this.unitLabelSpacing+n.heightPx+10;this.coordinates={width:e+this.lineThickness,height:a+this.scaleBarEdgeHeight,title:{x:0,y:this.state.titleFontSize,text:"Branch Length"},bar:{x1:0,y1:a,x2:e,y2:a},leftTick:{x1:0,y1:a-this.scaleBarEdgeHeight,x2:0,y2:a+this.scaleBarEdgeHeight},rightTick:{x1:e,y1:a-this.scaleBarEdgeHeight,x2:e,y2:a+this.scaleBarEdgeHeight},label:{x:e/2,y:a-this.unitLabelSpacing,text:t}}}render(t){super.render(t),this.showTitle&&this.renderTitle(this.coordinates.title.text).attr("x",this.coordinates.title.x).attr("y",this.coordinates.title.y),this.group.append("line").attr("class","bar").attr("x1",this.coordinates.bar.x1).attr("y1",this.coordinates.bar.y1).attr("x2",this.coordinates.bar.x2).attr("y2",this.coordinates.bar.y2).attr("stroke","#000").attr("stroke-width",this.lineThickness),this.group.append("line").attr("class","left-tick").attr("x1",this.coordinates.leftTick.x1).attr("y1",this.coordinates.leftTick.y1).attr("x2",this.coordinates.leftTick.x2).attr("y2",this.coordinates.leftTick.y2).attr("stroke","#000").attr("stroke-width",this.lineThickness),this.group.append("line").attr("class","right-tick").attr("x1",this.coordinates.rightTick.x1).attr("y1",this.coordinates.rightTick.y1).attr("x2",this.coordinates.rightTick.x2).attr("y2",this.coordinates.rightTick.y2).attr("stroke","#000").attr("stroke-width",this.lineThickness),this.group.append("text").attr("class","label").attr("x",this.coordinates.label.x).attr("y",this.coordinates.label.y).attr("text-anchor","middle").attr("dominant-baseline","ideographic").style("font-size",`${this.state.labelFontSize}px`).text(this.coordinates.label.text)}}class ji extends Oi{constructor(t={}){super(t),this.padding=10,this.exampleLetter="A",this.tickHeight=5,this.verticalSpacing=5,this.showTitle=!0}updateCoordinates(){const t=this.state.aesthetic.scale.dataMin,e=this.state.aesthetic.scale.dataMax,n=this.state.aesthetic.state.outputRange[0],i=this.state.aesthetic.state.outputRange[1],a=ni(t,e,5),o=i*this.state.treeState.labelSizeToPxFactor*.7,s=n*this.state.treeState.labelSizeToPxFactor*.7;this.textSizeEstimator.getTextSize(this.state.aesthetic.state.title,this.state.titleFontSize);const r=Math.max(30*a.length,100),l=a.map(t=>{const e=ii(t,a);return this.textSizeEstimator.getTextSize(e,this.state.labelFontSize)}),h=l[0].widthPx/2,c=l[l.length-1].widthPx/2,u=r+h+c;let d=0;this.showTitle&&(d=this.state.titleFontSize+this.verticalSpacing);const p=d+o,f=this.textSizeEstimator.getTextSize(this.state.aesthetic.state.inputUnits||"",this.state.labelFontSize),g=p+this.tickHeight+this.state.labelFontSize+f.heightPx;if(this.coordinates={width:u,height:g,leftOverhang:h,title:{x:h,y:this.state.titleFontSize,text:this.state.aesthetic.state.title},polygon:[],ticks:[],labels:[],units:{x:u/2,y:g,text:this.state.aesthetic.state.inputUnits||""}},t===e){const e=h+r/2;this.coordinates.ticks.push({x1:e,y1:p,x2:e,y2:p+this.tickHeight}),this.coordinates.labels.push({x:e,y:p+this.tickHeight,text:ii(t,a)});const n=(s+o)/2;this.coordinates.polygon=[{x:h,y:p},{x:h,y:p-n},{x:h+r,y:p-n},{x:h+r,y:p}]}else a.forEach((t,e)=>{const n=h+e/(a.length-1)*r;this.coordinates.ticks.push({x1:n,y1:p,x2:n,y2:p+this.tickHeight}),this.coordinates.labels.push({x:n,y:p+this.tickHeight,text:ii(t,a)})}),this.coordinates.polygon=[{x:h,y:p},{x:h,y:p-s},{x:h+r,y:p-o},{x:h+r,y:p}]}render(t){super.render(t),this.showTitle&&this.renderTitle(this.coordinates.title.text).attr("x",this.coordinates.title.x).attr("y",this.coordinates.title.y);const e=this.coordinates.polygon.map(t=>`${t.x},${t.y}`).join(" ");this.group.append("polygon").attr("points",e).attr("fill","#f0f0f0").attr("stroke","#ccc").attr("stroke-width",1),this.coordinates.ticks.forEach(t=>{this.group.append("line").attr("x1",t.x1).attr("y1",t.y1).attr("x2",t.x2).attr("y2",t.y2).attr("stroke","#000").attr("stroke-width",1)}),this.coordinates.labels.forEach(t=>{this.group.append("text").attr("x",t.x).attr("y",t.y).attr("text-anchor","middle").attr("dominant-baseline","hanging").style("font-size",`${this.state.labelFontSize}px`).text(t.text)}),this.coordinates.units.text&&this.group.append("text").attr("x",this.coordinates.units.x).attr("y",this.coordinates.units.y).attr("text-anchor","middle").attr("dominant-baseline","ideographic").style("font-size",`${this.state.labelFontSize}px`).style("font-style","italic").text(this.coordinates.units.text)}}class Gi extends Oi{constructor(t={}){super(t),this.exampleLetter="A",this.verticalSpacing=5,this.horizontalSpacing=10,this.showTitle=!0,this.squareSize=12,this.itemLabelGap=5,this.itemGap=15,this.maxCategoriesPerRow=5,this.gradientHeight=20,this.tickHeight=5,this.numGradientStops=20}updateCoordinates(){const t=this.state.aesthetic,e=t.state.isCategorical,n=this.textSizeEstimator.getTextSize(t.state.title,this.state.titleFontSize);let i=0;this.showTitle&&(i=this.state.titleFontSize+this.verticalSpacing),e?this.#h(i,n):this.#c(i,n)}#h(t,e){const n=this.state.aesthetic,i=n.scale.categories,a=this.state.maxX-this.state.x;this.coordinates={width:0,height:t,title:{x:0,y:this.state.titleFontSize,text:n.state.title},items:[],isCategorical:!0};let o=0,s=t+this.verticalSpacing+this.squareSize/2,r=this.squareSize;i.slice(0,n.state.maxCategories).forEach((t,e)=>{const l=n.scale.getValue(t),h=""===t?"No data":t,c=this.textSizeEstimator.getTextSize(h,this.state.labelFontSize),u=this.squareSize+this.itemLabelGap+c.widthPx;o>0&&o+u>a&&(o=0,s+=r+this.verticalSpacing,r=this.squareSize),this.coordinates.items.push({x:o,y:s,color:l,label:e<n.state.maxCategories-1||e==i.length-1?h:n.state.otherLabel,squareX:o,squareY:s-this.squareSize/2,labelX:o+this.squareSize+this.itemLabelGap,labelY:s}),o+=u+this.itemGap,this.coordinates.width=Math.max(this.coordinates.width,o-this.itemGap)});const l=n.values.some(t=>null==t);if(n.state.showNullInLegend&&l){const t=n.state.nullValue,e="No Data",i=this.textSizeEstimator.getTextSize(e,this.state.labelFontSize),l=this.squareSize+this.itemLabelGap+i.widthPx;o>0&&o+l>a&&(o=0,s+=r+this.verticalSpacing,r=this.squareSize),this.coordinates.items.push({x:o,y:s,color:t,label:e,squareX:o,squareY:s-this.squareSize/2,labelX:o+this.squareSize+this.itemLabelGap,labelY:s}),o+=l+this.itemGap,this.coordinates.width=Math.max(this.coordinates.width,o-this.itemGap)}this.coordinates.height=s+this.squareSize/2}#c(t,e){const n=this.state.aesthetic,i=n.scale.dataMin,a=n.scale.dataMax,o=ni(i,a,5),s=Math.max(30*o.length,120),r=o.map(t=>{const e=ii(t,o);return this.textSizeEstimator.getTextSize(e,this.state.labelFontSize)}),l=r[0].widthPx/2,h=r[r.length-1].widthPx/2,c=s+l+h,u=t+this.verticalSpacing,d=u+this.gradientHeight,p=d+this.tickHeight,f=this.textSizeEstimator.getTextSize(n.state.inputUnits||"",this.state.labelFontSize);let g=p+this.state.labelFontSize+f.heightPx;if(this.coordinates={width:c,height:g,leftOverhang:l,isCategorical:!1,title:{x:l,y:this.state.titleFontSize,text:n.state.title},gradient:{x:l,y:u,width:s,height:this.gradientHeight},ticks:[],labels:[],units:{x:c/2,y:g,text:n.state.inputUnits||""},nullItem:null},i===a){const t=l+s/2;this.coordinates.ticks.push({x1:t,y1:d,x2:t,y2:d+this.tickHeight}),this.coordinates.labels.push({x:t,y:p,text:ii(i,o)})}else o.forEach((t,e)=>{const n=l+e/(o.length-1)*s;this.coordinates.ticks.push({x1:n,y1:d,x2:n,y2:d+this.tickHeight}),this.coordinates.labels.push({x:n,y:p,text:ii(t,o)})});if(n.state.showNullInLegend){const t=n.state.nullValue,e="No Data";this.textSizeEstimator.getTextSize(e,this.state.labelFontSize);const i=g+this.verticalSpacing;this.coordinates.nullItem={x:l,y:i+this.squareSize/2,color:t,label:e,squareX:l,squareY:i,labelX:l+this.squareSize+this.itemLabelGap,labelY:i+this.squareSize/2},this.coordinates.height=i+this.squareSize}}render(t){super.render(t),this.showTitle&&this.renderTitle(this.coordinates.title.text).attr("x",this.coordinates.title.x).attr("y",this.coordinates.title.y),this.coordinates.isCategorical?this.#u():this.#d()}#u(){this.coordinates.items.forEach(t=>{this.group.append("rect").attr("x",t.squareX).attr("y",t.squareY).attr("width",this.squareSize).attr("height",this.squareSize).attr("fill",t.color).attr("stroke","#000").attr("stroke-width",1),this.group.append("text").attr("x",t.labelX).attr("y",t.labelY).attr("text-anchor","start").attr("dominant-baseline","central").style("font-size",`${this.state.labelFontSize}px`).text(t.label)})}#d(){const t=this.state.aesthetic,e=t.scale.dataMin,n=t.scale.dataMax,i=`color-gradient-${Math.random().toString(36).substr(2,9)}`,a=this.group.append("defs").append("linearGradient").attr("id",i).attr("x1","0%").attr("x2","100%").attr("y1","0%").attr("y2","0%");if(e===n){const n=t.scale.getValue(e);a.append("stop").attr("offset","0%").attr("stop-color",n),a.append("stop").attr("offset","100%").attr("stop-color",n)}else for(let o=0;o<=this.numGradientStops;o++){const i=o/this.numGradientStops,s=e+i*(n-e),r=t.scale.getValue(s);a.append("stop").attr("offset",100*i+"%").attr("stop-color",r)}this.group.append("rect").attr("x",this.coordinates.gradient.x).attr("y",this.coordinates.gradient.y).attr("width",this.coordinates.gradient.width).attr("height",this.coordinates.gradient.height).style("fill",`url(#${i})`).style("stroke","#000").style("stroke-width",1),this.coordinates.ticks.forEach(t=>{this.group.append("line").attr("x1",t.x1).attr("y1",t.y1).attr("x2",t.x2).attr("y2",t.y2).attr("stroke","#000").attr("stroke-width",1)}),this.coordinates.labels.forEach(t=>{this.group.append("text").attr("x",t.x).attr("y",t.y).attr("text-anchor","middle").attr("dominant-baseline","hanging").style("font-size",`${this.state.labelFontSize}px`).text(t.text)}),this.coordinates.units.text&&this.group.append("text").attr("x",this.coordinates.units.x).attr("y",this.coordinates.units.y).attr("text-anchor","middle").attr("dominant-baseline","ideographic").style("font-size",`${this.state.labelFontSize}px`).style("font-style","italic").text(this.coordinates.units.text)}}class Ui{constructor(t,e,n={}){if(!t)throw new Error("TreeView requires a TreeState instance");if(!e)throw new Error("TreeView requires an SVG container element");this.treeState=t,this.svg=bt(e),this.options={buttonSize:25,controlsMargin:3,buttonPadding:2,manualZoomAndPanEnabled:!0,autoZoom:"Default",autoPan:"Default",transitionDuration:500,legendSpacing:10,legendPadding:10,...n},this.layers={},this.selections={},this.legendInstances=[],this.currentTransform={x:0,y:0,k:1},this.isTransitioning=!1,this.isExpanding=!1,this.activeTransitions=new Set,this.selectedNode=null,this.selectionButtons=[{id:"collapse-subtree",icon:"compress",isVisible:t=>t&&t!==this.treeState.displayedRoot&&(t.children||t.collapsedChildren),onClick:t=>{t&&t!==this.treeState.displayedRoot&&t.children&&(this.treeState.collapseSubtree(t),this.#p())}},{id:"collapse-root",icon:"expand",isVisible:t=>t&&t!==this.treeState.displayedRoot&&(t.children||t.collapsedChildren),onClick:t=>{t&&t!==this.treeState.displayedRoot&&t.children&&(this.treeState.collapseRoot(t),this.#p())}},{id:"hide",icon:"trash",isVisible:t=>t&&t!==this.treeState.displayedRoot,onClick:t=>{t&&t!==this.treeState.displayedRoot&&(this.treeState.hideSubtree(t),this.#p())}},{id:"rotate-subtree",icon:"rotate",isVisible:t=>{if(!t||!t.children)return!1;return t.children.filter(t=>!t.hidden).length>1},onClick:t=>{if(t&&t.children){t.children.filter(t=>!t.hidden).length>1&&this.treeState.rotateSubtree(t)}}}],this.#f(),this.initializeZoom(),this.#g(),this.#m()}destroy(){this.svg.selectAll("*").remove(),this.layers={},this.selections={},this.selectedNode=null,this.legendInstances=[]}reattach(t){this.svg=bt(t),this.#f(),this.initializeZoom(),this.#y(!1),this.#b(!1),this.#x(!1),this.#l(!1),this.fitToView({transition:!1,forcePanToTop:!0})}#f(){const t=this.svg.append("g").attr("class","tree-elements");this.layers.branchLayer=t.append("g").attr("class","branch-layer"),this.layers.nodeLayer=t.append("g").attr("class","node-layer"),this.layers.hitLayer=t.append("g").attr("class","hit-layer"),this.layers.legendLayer=t.append("g").attr("class","legend-layer"),this.layers.treeGroup=t,this.layers.selectionRect=t.append("path").attr("class","selection-rect").attr("fill","none").attr("stroke","grey").attr("stroke-width",2).attr("stroke-dasharray","5,5").attr("pointer-events","none").style("display","none"),this.layers.selectionBtns=this.svg.append("g").attr("class","selection-btns").style("display","none"),this.#v()}#p(){this.selectedNode=null,this.layers.selectionRect.style("display","none"),this.layers.selectionBtns.style("display","none")}#v(){const t=this.layers.selectionBtns;this.selectionButtons.forEach(e=>{const n=t.append("g").attr("class",`btn-${e.id}`).style("cursor","pointer").on("click",()=>{e.onClick(this.selectedNode)});!function(t,e,n,i=2){const a=Xi[e],o=(n-2*i)/24,s=t.append("rect").attr("width",n).attr("height",n).attr("rx","5px").attr("ry","5px").attr("fill","#CCC"),r=t.append("g").attr("transform",`translate(${i}, ${i}) scale(${o})`).attr("stroke","#555").attr("fill","none").attr("stroke-linecap","round").attr("stroke-linejoin","round").attr("stroke-width",2);a.forEach(t=>{r.append("path").attr("d",t)})}(n,e.icon,this.options.buttonSize),e.element=n})}initializeZoom(){this.treeZoom=Qn().filter(t=>!!this.options.manualZoomAndPanEnabled&&"dblclick"!==t.type).on("zoom",t=>{this.currentTransform=t.transform,this.layers.treeGroup.attr("transform",t.transform),this.#w(null===t.sourceEvent)}),this.svg.call(this.treeZoom)}#g(){this.treeState.subscribe("coordinateChange",()=>{this.#_()}),this.treeState.subscribe("layoutChange",()=>{this.#_()}),this.treeState.subscribe("legendsChange",()=>{this.#l(!0)}),this.treeState.subscribe("tipLabelTextChange",()=>{this.#C()}),this.treeState.subscribe("tipLabelColorChange",()=>{this.#k()}),this.treeState.subscribe("tipLabelSizeChange",()=>{this.#S(),this.#l(!0)}),this.treeState.subscribe("tipLabelFontChange",()=>{this.#L()}),this.treeState.subscribe("tipLabelStyleChange",()=>{this.#T()}),this.treeState.subscribe("nodeLabelTextChange",()=>{this.#M()})}#m(){this.#y(!1),this.#b(!1),this.#x(!1),this.#l(!1),this.fitToView({transition:!1,forcePanToTop:!0})}#_(){const t=this.#y(!0),e=this.#b(!0);this.#x(!0),this.#l(!0),this.selectedNode&&this.#P(!0),this.isExpanding&&t&&e?setTimeout(()=>{t.transition("branch group fade in").duration(150).attr("opacity",1),e.transition("node group fade in").duration(150).attr("opacity",1),this.layers.selectionBtns.attr("opacity",0).transition("fade in selection buttons").duration(150).attr("opacity",1),setTimeout(()=>{this.isExpanding=!1},150)},this.options.transitionDuration):this.selectedNode&&setTimeout(()=>{this.#w(!1)},this.options.transitionDuration),this.fitToView()}#C(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").text(t=>t.tipLabelText||"")}#k(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("fill",t=>t.tipLabelColor||"#000")}#S(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("font-size",t=>`${t.tipLabelSizePx||12}px`)}#L(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("font-family",t=>t.tipLabelFont||"sans-serif")}#T(){this.selections.nodes&&this.selections.nodes.selectAll(".tip-label").style("font-style",t=>t.tipLabelStyle.includes("italic")?"italic":"normal").style("font-weight",t=>t.tipLabelStyle.includes("bold")?"bold":"normal")}#M(){this.selections.nodes&&this.selections.nodes.selectAll(".node-label").text(t=>t.nodeLabelText||"")}#l(t=!0){this.layers.legendLayer.selectAll("*").remove(),this.legendInstances=[];const e=this.#E();if(!e)return;e.maxX,e.minX;let n=e.minX,i=e.maxY+this.options.legendSpacing;const a=new Yi({treeState:this.treeState,x:n,y:i,origin:"top left",maxX:e.maxX,maxY:1/0});a.render(this.layers.legendLayer),this.legendInstances.push(a),n+=a.coordinates.width+this.options.legendSpacing;for(const o of this.treeState.legends){let t;"size"===o.type?t=new ji({treeState:this.treeState,aesthetic:o.aesthetic,x:n,y:i,origin:"top left",maxX:e.maxX,maxY:1/0}):"color"===o.type&&(t=new Gi({treeState:this.treeState,aesthetic:o.aesthetic,x:n,y:i,origin:"top left",maxX:e.maxX,maxY:1/0})),n+t.coordinates.width+this.options.legendSpacing>e.maxX&&(n=e.minX,i+=Math.max(...this.legendInstances.map(t=>t.coordinates.height))),t&&(t.render(this.layers.legendLayer),this.legendInstances.push(t),n+=t.coordinates.width+this.options.legendSpacing)}this.fitToView({transition:t})}fitToView(t){if(!((t={transition:!0,padding:5,autoZoom:this.options.autoZoom,autoPan:this.options.autoPan,forcePanToTop:!1,...t}).autoZoom&&"None"!=t.autoZoom||t.autoPan&&"None"!=t.autoPan))return;const{width:e,height:n}=this.svg.node().getBoundingClientRect(),i=this.getCurrentBoundsWithLegends();if(!i)return;i.minX-=t.padding,i.maxX+=t.padding,i.minY-=t.padding,i.maxY+=t.padding;const a=i.maxX-i.minX,o=i.maxY-i.minY,s=e-0,r=n;let l=this.currentTransform.k,h=this.currentTransform.x,c=this.currentTransform.y;const u=s/a,d=r/o;if("Default"==t.autoZoom&&("circular"!=this.treeState.state.layout&&this.options.manualZoomAndPanEnabled?t.autoZoom="X":t.autoZoom="Both"),t.autoZoom&&"None"!=t.autoZoom&&("X"==t.autoZoom?l=Math.min(1,u):"Y"==t.autoZoom?l=Math.min(1,d):"Both"==t.autoZoom?l=Math.min(u,d):console.error(`Value of ${t.autoZoom} is invalid for input.autoZoom.`)),"Default"==t.autoPan&&(t.autoPan="Both"),t.autoPan&&"None"!=t.autoPan){if("Both"==t.autoPan||"X"==t.autoPan){const t=a*l;if(t<=s)h=0+(s-t)/2-i.minX*l;else{const t=-i.minX*l-0,n=e-i.maxX*l;h=t>0?0-i.minX*l:n>0?e-i.maxX*l:0+s/2-(i.minX+i.maxX)/2*l}}if("Both"==t.autoPan||"Y"==t.autoPan){const e=o*l;if(e<=r)c=(r-e)/2-i.minY*l;else{const e=-i.minY*l,a=n-i.maxY*l;c>e||t.forcePanToTop?c=e:c<a&&(c=a)}}}const p=Xn.translate(h,c).scale(l);t.transition?this.svg.transition("zoom").duration(this.options.transitionDuration).call(this.treeZoom.transform,p):this.svg.call(this.treeZoom.transform,p)}#E(){const t=this.treeState.displayedRoot;return{minX:t.bounds.minX,maxX:t.bounds.maxX,minY:t.bounds.minY,maxY:t.bounds.maxY}}getCurrentBoundsWithLegends(){const t=this.#E();if(!t)return null;let e=t.maxY,n=t.minX;for(const i of this.legendInstances)i.coordinates&&(e=Math.max(e,i.state.y+i.coordinates.height));return"circular"!==this.treeState.state.layout&&this.treeState.displayedRoot.collapsedParent&&(n-=this.#$()),{minX:n,maxX:t.maxX,minY:t.minY,maxY:e}}#z(t){this.selectedNode===t?this.#p():(this.selectedNode=t,this.layers.selectionRect.attr("d",this.#N(t)).style("display","block"),this.#w(!1))}#P(t=!1){this.selectedNode&&(t?this.layers.selectionRect.transition("update selection rect").duration(this.options.transitionDuration).attr("d",this.#N(this.selectedNode)):this.layers.selectionRect.attr("d",this.#N(this.selectedNode)))}#N(t){if(!t)return"";let e,n,i,a,o,s;if("circular"===this.treeState.state.layout)e={x:t.bounds.minRadius*Math.cos(t.bounds.minAngle),y:t.bounds.minRadius*Math.sin(t.bounds.minAngle)},i={x:t.bounds.maxRadius*Math.cos(t.bounds.maxAngle),y:t.bounds.maxRadius*Math.sin(t.bounds.maxAngle)},s=this.#A(i.x,i.y,t.bounds.maxRadius,t.bounds.maxAngle,t.bounds.minAngle,!1),o=this.#A(e.x,e.y,t.bounds.minRadius,t.bounds.minAngle,t.bounds.maxAngle,!0);else{e={x:t.bounds.minX,y:t.bounds.minY},n={x:t.bounds.minX,y:t.bounds.maxY},i={x:t.bounds.maxX,y:t.bounds.maxY},a={x:t.bounds.maxX,y:t.bounds.minY};const r=this.treeState.displayedRoot,l=r.bounds.maxY-r.bounds.minY,h=Math.abs(n.y-e.y)/l,c=Math.max(1,Math.ceil(h/.25));o=this.#R(e,n,c),s=this.#R(i,a,c)}return`M${e.x},${e.y} ${o} L${i.x},${i.y} ${s} Z`}#R(t,e,n=1){let i="";for(let a=0;a<n;a++){const o=a/n,s=(a+1)/n,r=t.x+(e.x-t.x)*o,l=t.y+(e.y-t.y)*o,h=t.x+(e.x-t.x)*s,c=t.y+(e.y-t.y)*s;i+=`C${r},${l+(c-l)/3} ${h},${c-(c-l)/3} ${h},${c}`,a<n-1&&(i+=" ")}return i}#w(t=!0,e=1.1){if(!this.selectedNode)return void this.layers.selectionBtns.style("display","none");let n,i;if("circular"===this.treeState.state.layout){const t=this.selectedNode.bounds.minAngle,e=this.selectedNode.bounds.maxAngle,a=this.selectedNode.bounds.minRadius,o=this.selectedNode.bounds.maxRadius,s=20;let r=1/0,l=0;for(let n=0;n<=s;n++){const i=t+(e-t)*n/s,h=a*Math.cos(i),c=a*Math.sin(i),u=o*Math.cos(i),d=o*Math.sin(i);h<r&&(r=h,l=c),u<r&&(r=u,l=d)}n=r,i=l}else n=this.selectedNode.bounds.minX,i=this.selectedNode.bounds.minY;let a=0;this.selectionButtons.forEach(t=>{if(t.isVisible(this.selectedNode)){const n=a*(this.options.buttonSize*e);t.element.style("display","block").attr("transform",`translate(0, ${n})`),a++}else t.element.style("display","none")});const o=a*this.options.buttonSize+(a-1)*this.options.buttonSize*(e-1);let s=n*this.currentTransform.k+this.currentTransform.x-this.options.buttonSize*e,r=i*this.currentTransform.k+this.currentTransform.y-this.options.buttonSize*(e-1);const{width:l,height:h}=this.svg.node().getBoundingClientRect();s=Math.max(s,0),s=Math.min(s,l-this.options.buttonSize),r=Math.max(r,0),r=Math.min(r,h-o),t?this.layers.selectionBtns.attr("opacity",0).attr("transform",`translate(${s},${r})`):this.layers.selectionBtns.attr("transform",`translate(${s},${r})`).attr("opacity",1).style("display","block")}#x(){const t=this.treeState.displayedRoot;if(!t)return;const e="circular"===this.treeState.state.layout,n=this.treeState.labelSizeToPxFactor*this.treeState.state.branchThicknessProp,i=this.#$(),a=this.layers.hitLayer.selectAll(".hit").data(t.descendants().filter(t=>{if(!t.children)return!1;return t.children.filter(t=>!t.hidden).length>1}),t=>t.id);a.exit().remove();a.enter().append("path").attr("class","hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{this.#z(e),t.stopPropagation()}).merge(a).attr("d",t=>this.#N(t)),this.layers.hitLayer.selectAll(".hit").sort((t,e)=>t.depth-e.depth);const o=this.layers.hitLayer.selectAll(".tip-hit").data(t.descendants().filter(t=>!t.children&&!t.collapsedChildren),t=>t.id);o.exit().remove();o.enter().append("path").attr("class","tip-hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{this.#z(e),t.stopPropagation()}).merge(o).attr("d",t=>this.#N(t));const s=this.layers.hitLayer.selectAll(".collapsed-hit").data(t.descendants().filter(t=>t.collapsedChildren),t=>t.id);s.exit().remove();s.enter().append("rect").attr("class","collapsed-hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{e.collapsedChildren&&(this.isExpanding=!0,this.treeState.expandSubtree(e)),t.stopPropagation()}).merge(s).attr("transform",t=>`translate(${t.xPx}, ${t.yPx}) rotate(${this.#H(t)})`).attr("y",t=>-t.tipLabelSizePx/2.5).attr("width",t=>this.treeState.getCollapsedTriangleHeight(t)+t.tipLabelBounds.width*this.treeState.labelSizeToPxFactor).attr("height",t=>Math.max(t.tipLabelSizePx,this.treeState.getCollapsedTriangleHeight(t)));const r=this.layers.hitLayer.selectAll(".collapsed-root-hit").data(t.collapsedParent?[t]:[],t=>t.id);r.exit().remove();r.enter().append("rect").attr("class","collapsed-root-hit").attr("fill","transparent").style("cursor","pointer").on("click",(t,e)=>{e.collapsedParent&&(this.isExpanding=!0,this.treeState.expandRoot()),t.stopPropagation()}).merge(r).attr("transform",t=>{if(!t.collapsedParent)return`translate(${t.xPx}, ${t.yPx})`;let n=0;if(e){const e=t.children||[];if(e.length>0){n=e.reduce((t,e)=>t+e.angle,0)/e.length*(180/Math.PI)}}return`translate(${t.xPx}, ${t.yPx}) rotate(${n})`}).attr("x",-i).attr("y",5*-n).attr("width",i).attr("height",10*n)}#y(t=!0){const e=this.treeState.displayedRoot;if(!e)return;const n=e.links(),i=this.treeState.labelSizeToPxFactor*this.treeState.state.branchThicknessProp,a=this.layers.branchLayer.selectAll(".branch-group").data(n,t=>t.target.id);t?a.exit().attr("opacity",0).remove():a.exit().remove();const o=a.enter().append("g").attr("class","branch-group");this.#D(o),this.isExpanding&&t&&o.attr("opacity",0);const s=o.merge(a);return this.#B(s,t,i),this.selections.branches=s,o}#D(t){t.append("path").attr("class","offset").attr("fill","none").attr("stroke","#000").attr("stroke-opacity",1).attr("stroke-linecap","round"),t.append("path").attr("class","extension").attr("fill","none").attr("stroke","#000").attr("stroke-opacity",1).attr("stroke-linecap","round")}#B(t,e,n){this.treeState.state.layout;const i=t.select(".offset"),a=t.select(".extension");e?(i.transition().duration(this.options.transitionDuration).attr("stroke-width",n).attr("d",t=>this.#I(t,"offset")),a.transition().duration(this.options.transitionDuration).attr("stroke-width",n).attr("d",t=>this.#I(t,"extension"))):(i.attr("stroke-width",n).attr("d",t=>this.#I(t,"offset")),a.attr("stroke-width",n).attr("d",t=>this.#I(t,"extension")))}#A(t,e,n,i,a,o){let s=a-i;o&&s<0?s+=2*Math.PI:!o&&s>0&&(s-=2*Math.PI);const r=Math.abs(s),l=Math.max(1,Math.ceil(r/(Math.PI/2))),h=s/l,c=4/3*Math.tan(h/4);let u="",d=i,p=t,f=e;for(let g=0;g<l;g++){const t=d+h,e=n*Math.cos(t),i=n*Math.sin(t);u+=` C${p-c*n*Math.sin(d)},${f+c*n*Math.cos(d)} ${e+c*n*Math.sin(t)},${i-c*n*Math.cos(t)} ${e},${i}`,d=t,p=e,f=i}return u}#I(t,e){const n="circular"===this.treeState.state.layout;if("offset"===e){if(n){t.source.radiusPx,t.target.cos,t.source.radiusPx,t.target.sin;const e=t.target.angle>t.source.angle,n=this.#A(t.source.xPx,t.source.yPx,t.source.radiusPx,t.source.angle,t.target.angle,e);return`M${t.source.xPx},${t.source.yPx}${n}`}{const e=t.source.xPx,n=t.source.yPx,i=t.source.xPx,a=t.target.yPx;return`M${e},${n} C${e},${n+(a-n)/3} ${i},${a-(a-n)/3} ${i},${a}`}}if(n){const e={x:t.source.radiusPx*t.target.cos,y:t.source.radiusPx*t.target.sin};return`M${e.x},${e.y} L${t.target.xPx},${t.target.yPx}`}return`M${t.source.xPx},${t.target.yPx} L${t.target.xPx},${t.target.yPx}`}#F(t){const e=.4330127*(n=this.treeState.getCollapsedTriangleHeight(t))*n;var n;return In().type(Bn).size(e)()}#b(t=!0){const e=this.treeState.displayedRoot;if(!e)return;this.treeState.state.layout;const n=e.descendants().filter(t=>!t.hidden),i=this.treeState.labelSizeToPxFactor*this.treeState.state.branchThicknessProp,a=this.#$(),o=this.layers.nodeLayer.selectAll(".node").data(n,t=>t.id);t?o.exit().attr("opacity",0).remove():o.exit().remove();const s=o.enter().append("g").attr("class","node").attr("transform",t=>`translate(${t.xPx}, ${t.yPx})`);this.#V(s,i),this.isExpanding&&t&&s.attr("opacity",0);const r=s.merge(o);return this.#q(r,t),this.#X(r,t),this.#O(r,t),this.#Y(r,t,i,a),this.selections.nodes=r,s}#V(t,e){t.append("path").attr("class","node-shape").attr("d",t=>t.collapsedChildren?this.#F(t):null).attr("fill","#000").style("display",t=>t.collapsedChildren?null:"none"),t.append("line").attr("class","collapsed-root-line").attr("stroke","#000").attr("stroke-width",e).style("display",t=>t.collapsedParent?null:"none"),t.filter(t=>t.tipLabelText&&""!==t.tipLabelText.trim()).append("text").attr("class","tip-label").style("text-anchor",t=>this.#j(t)).style("font-size",t=>`${t.tipLabelSizePx}px`).style("font-family",t=>t.tipLabelFont||"sans-serif").style("font-style",t=>t.tipLabelStyle||"normal").style("font-weight",t=>"bold"===t.tipLabelStyle?"bold":"normal").style("fill",t=>t.tipLabelColor||"#000").style("display",t=>t.children?"none":null).text(t=>t.tipLabelText||""),t.filter(t=>{if(!t.nodeLabelText||""===t.nodeLabelText.trim())return!1;if(!t.children)return!1;return t.children.filter(t=>!t.hidden).length>1}).append("text").attr("class","node-label").style("text-anchor",t=>this.#G(t)).style("font-size",t=>`${t.nodeLabelSizePx}px`).style("fill","#000").style("display",t=>t.children||t.collapsedChildren?null:"none").text(t=>t.nodeLabelText||"")}#q(t,e){e?t.transition("update node positions").duration(this.options.transitionDuration).attr("transform",t=>`translate(${t.xPx}, ${t.yPx}) rotate(${this.#H(t)})`):t.attr("transform",t=>`translate(${t.xPx}, ${t.yPx}) rotate(${this.#H(t)})`)}#X(t,e){const n="circular"===this.treeState.state.layout,i=t.selectAll(".tip-label");i.attr("x",t=>this.#U(t)&&n?-t.tipLabelXOffsetPx:t.tipLabelXOffsetPx).style("text-anchor",t=>this.#j(t)).attr("transform",t=>`rotate(${this.#U(t)&&n?180:0})`).text(t=>t.tipLabelText||"").style("fill",t=>t.tipLabelColor||"#000").style("font-family",t=>t.tipLabelFont||"sans-serif").style("font-style",t=>t.tipLabelStyle||"normal").style("display",t=>t.children?"none":null),e?i.transition("update tip labels").duration(this.options.transitionDuration).attr("dy",t=>t.tipLabelSizePx/2.5).style("font-size",t=>`${t.tipLabelSizePx}px`):i.attr("dy",t=>t.tipLabelSizePx/2.5).style("font-size",t=>`${t.tipLabelSizePx}px`);const a=t.selectAll(".node-label");a.attr("x",t=>this.#U(t)&&n?t.nodeLabelXOffsetPx:-t.nodeLabelXOffsetPx).attr("transform",t=>`rotate(${this.#U(t)&&n?180:0})`).style("text-anchor",t=>this.#G(t)).text(t=>t.nodeLabelText||"").style("display",t=>{if(!t.children&&!t.collapsedChildren)return"none";if(t.children){if(t.children.filter(t=>!t.hidden).length<=1)return"none"}return null}),e?a.transition("update node labels").duration(this.options.transitionDuration).attr("dy",t=>this.#Z(t)).style("font-size",t=>`${t.nodeLabelSizePx}px`):a.attr("dy",t=>this.#Z(t)).style("font-size",t=>`${t.nodeLabelSizePx}px`)}#O(t,e){const n=t.selectAll(".node-shape");n.attr("transform",t=>`rotate(-90) translate(0, ${this.treeState.getCollapsedTriangleOffset(t)})`).style("display",t=>t.collapsedChildren?null:"none"),e?n.transition().duration(this.options.transitionDuration).attr("d",t=>t.collapsedChildren?this.#F(t):null):n.attr("d",t=>t.collapsedChildren?this.#F(t):null)}#Y(t,e,n,i){const a=t.selectAll(".collapsed-root-line");e?a.transition().duration(this.options.transitionDuration).attr("x2",-i).attr("y2",0).attr("stroke-width",n).attr("stroke-dasharray",t=>t.collapsedParent?ti(i,n,4):null):a.attr("x2",-i).attr("y2",0).attr("stroke-width",n).attr("stroke-dasharray",t=>t.collapsedParent?ti(i,n,4):null),a.attr("x1",0).attr("y1",0).style("display",t=>t.collapsedParent?null:"none")}#H(t){if(!("circular"===this.treeState.state.layout))return 0;return t.angle*(180/Math.PI)}#j(t){return"circular"===this.treeState.state.layout&&this.#U(t)?t.children?"start":"end":t.children?"end":"start"}#G(t){return"circular"===this.treeState.state.layout&&this.#U(t)?t.children||t.collapsedChildren?"start":"end":t.children||t.collapsedChildren?"end":"start"}#Z(t){const e=t.parent&&t.parent.yPx>t.yPx,n=t.nodeLabelSizePx;return e?.3*-n:1*n}#U(t){return t.angle<1.5*Math.PI||t.angle>2.5*Math.PI}#$(){const t=this.treeState.displayedRoot;if(!t)return 0;if("circular"===this.treeState.state.layout){return Math.max(...t.leaves().map(t=>t.radiusPx))*this.treeState.state.collapsedRootLineProp*2}return Math.max(...t.leaves().map(t=>t.xPx))*this.treeState.state.collapsedRootLineProp}}function Zi(t,e,n,i=document){const a=t.getCurrentBoundsWithLegends(),o=a.maxX-a.minX,s=a.maxY-a.minY,r=e.width/o,l=e.height/s,h=Math.min(r,l),c=e.width+2*e.margin,u=e.height+2*e.margin,d=e.margin-a.minX*h,p=e.margin-a.minY*h,f=document.createElementNS("http://www.w3.org/2000/svg","svg");f.setAttribute("width",c),f.setAttribute("height",u),f.setAttribute("xmlns","http://www.w3.org/2000/svg");const g=document.createElementNS("http://www.w3.org/2000/svg","g");g.setAttribute("transform",`translate(${d}, ${p}) scale(${h})`);const m=t.layers.treeGroup.node().cloneNode(!0);m.removeAttribute("transform");const y=m.querySelector(".selection-rect");y&&y.remove(),g.appendChild(m),f.appendChild(g);const b=(new XMLSerializer).serializeToString(f);"svg"===e.format?function(t,e,n){const i=new Blob([t],{type:n}),a=URL.createObjectURL(i),o=document.createElement("a");o.href=a,o.download=e,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(a)}(b,n,"image/svg+xml"):"png"===e.format&&function(t,e,n,i){const a=document.createElement("canvas");a.width=e,a.height=n;const o=a.getContext("2d"),s=new Image,r=new Blob([t],{type:"image/svg+xml;charset=utf-8"}),l=URL.createObjectURL(r);s.onload=()=>{o.fillStyle="white",o.fillRect(0,0,e,n),o.drawImage(s,0,0),a.toBlob(t=>{const e=URL.createObjectURL(t),n=document.createElement("a");n.href=e,n.download=i,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(e),URL.revokeObjectURL(l)})},s.src=l}(b,c,u,n)}function Wi(t,e,n,i,a,o,s,r=document){const l=20;let h=null,c=null,u=null,d=null,p=null,f=null,g=null,m=!0;const y=document.createElement("div");y.className="ht-toggle-container";const b=document.createElement("button");b.className="ht-control-panel-toggle",b.innerHTML='\n <svg width="16" height="16" viewBox="0 0 16 16" class="ht-toggle-arrow">\n <path d="M8 4 L12 8 L8 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="rotate(-90 8 8)"/>\n </svg>\n <svg width="16" height="16" viewBox="0 0 16 16" class="ht-hamburger-icon">\n <line x1="2" y1="4" x2="14" y2="4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n <line x1="2" y1="8" x2="14" y2="8" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n <line x1="2" y1="12" x2="14" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>\n </svg>\n ',b.title="Toggle control panel",y.appendChild(b);const x=document.createElement("div");x.className="ht-collapsible-panel";const v=document.createElement("div");v.className="ht-tabs";const w=document.createElement("div");w.className="ht-controls hidden";const _=document.createElement("div");_.className="ht-aesthetic-settings hidden";const C=[{id:"data",label:"Data",requiresTree:!1},{id:"controls",label:"Controls",requiresTree:!0},{id:"tree-manipulation",label:"Tree",requiresTree:!0},{id:"tip-label-settings",label:"Tip Labels",requiresTree:!0},{id:"export",label:"Export",requiresTree:!0}],k={};function S(){const t=null!==n();if(C.forEach(e=>{const n=k[e.id];e.requiresTree&&!t?n.classList.add("disabled"):n.classList.remove("disabled")}),h){const e=C.find(t=>t.id===h);e&&e.requiresTree&&!t&&R("data")}}function L(){const t=n();return t&&t.state.treeData?t.state.treeData.getMetadataTableNames():[]}function T(){return c}function M(t){L().includes(t)?c=t:console.warn(`Metadata table not found: ${t}`)}function P(){const t=L();c=t.length>0?t[0]:null}function E(){const t=n();if(t){if(d){let e=!1;t.displayedRoot.each(n=>{n!==t.displayedRoot&&n.collapsedChildren&&(e=!0)}),d.disabled=!e}if(p&&(p.disabled=!t.displayedRoot.collapsedParent),f){let e=!1;t.state.treeData.tree.each(t=>{t.hiddenChildren&&t.hiddenChildren.length>0&&(e=!0)}),f.disabled=!e}}}function $(){const t=n();if(!t)return"tree";for(const[n,i]of e.entries())if(i===t.state.treeData)return n;return"tree"}function z(t,e){u!==t?(N(),u=t,e.classList.add("ht-aesthetic-editing"),_.classList.remove("hidden"),A(t)):N()}function N(){if(!u)return;_.querySelectorAll(".ht-color-palette-editor").forEach(t=>{t.cleanupFunction&&"function"==typeof t.cleanupFunction&&t.cleanupFunction()});w.querySelectorAll(".ht-control-group").forEach(t=>t.classList.remove("ht-aesthetic-editing")),_.classList.add("hidden"),_.innerHTML="",u=null}function A(t){_.innerHTML="";const e=n();if(!e)return;const i=e.state.aesthetics[t],a=e.aestheticsScales[t];if(!a){const t=document.createElement("div");return t.textContent="Error: Could not find aesthetic",t.style.padding="10px",t.style.color="#d00",void _.appendChild(t)}const o=a.createSettingsWidget({controlHeight:l,columnId:i,root:r});o&&_.appendChild(o)}function R(t){const e=C.find(e=>e.id===t);e&&e.requiresTree&&!n()||(h=t,Object.keys(k).forEach(e=>{e===t?k[e].classList.add("active"):k[e].classList.remove("active")}),w.classList.remove("hidden"),H(t))}function H(t){switch(w.innerHTML="",N(),t){case"data":!function(t,e,n,i,a,o,s,r,l,h,c,u){t.innerHTML="";const d=Pi(),p=Ei("Tree:",u);d.appendChild(p);const f=document.createElement("select");f.className="ht-select",f.style.height=`${u}px`;const g=Array.from(e.keys()),m=n(),y=m?Array.from(e.entries()).find(([t,e])=>e===m.state.treeData)?.[0]:null;if(0===g.length){const t=document.createElement("option");t.textContent="No trees loaded",t.value="",f.appendChild(t),f.disabled=!0}else g.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===y&&(e.selected=!0),f.appendChild(e)}),f.addEventListener("change",t=>{i(t.target.value)});d.appendChild(f),t.appendChild(d);const b=document.createElement("input");b.type="file",b.style.display="none",b.addEventListener("change",async t=>{const e=t.target.files[0];if(e)try{const t=await e.text();let n=e.name.replace(/\.[^/.]+$/,"");const o=a(n,t);b.value="",h(),o.length>0&&i(o[0])}catch(n){console.error("Error loading tree file:",n),alert(`Error loading tree file: ${n.message}`)}}),t.appendChild(b);const x=$i("+","Add tree from Newick file",u);if(x.addEventListener("click",()=>{b.click()}),t.appendChild(x),!m)return;const v=Pi(),w=Ei("Metadata:",u);v.appendChild(w);const _=document.createElement("select");_.className="ht-select",_.style.height=`${u}px`;const C=o(),k=s();if(0===C.length){const t=document.createElement("option");t.textContent="No metadata",t.value="",_.appendChild(t),_.disabled=!0}else C.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===k&&(e.selected=!0),_.appendChild(e)}),_.addEventListener("change",t=>{r(t.target.value),h()});v.appendChild(_),t.appendChild(v);const S=document.createElement("input");S.type="file",S.accept=".tsv,.csv,.txt",S.style.display="none",S.addEventListener("change",async t=>{const e=t.target.files[0];if(!e)return;const i=n();if(!i||!i.state.treeData)return alert("No tree selected. Please select a tree first."),void(S.value="");try{const t=await e.text();let n=e.name.replace(/\.(tsv|csv|txt)$/i,""),a="\t";e.name.toLowerCase().endsWith(".csv")&&(a=",");const o=i.state.treeData.addTable(t,n,a),s=i.state.treeData.metadataTableNames.get(o);S.value="",r(s),h()}catch(a){console.error("Error loading metadata file:",a),alert(`Error loading metadata file: ${a.message}`),S.value=""}}),t.appendChild(S);const L=$i("+","Add metadata table",u);if(L.addEventListener("click",()=>{const t=n();t&&t.state.treeData?S.click():alert("No tree selected. Please select a tree first.")}),t.appendChild(L),k){const e=m.state.treeData;let n=null;for(const[t,i]of e.metadataTableNames.entries())if(i===k){n=t;break}if(n){const i=e.getValidIdColumns(n),a=e.getNodeIdColumn(n),o=Pi(),s=Ei("ID Column:",u);o.appendChild(s);const r=document.createElement("select");if(r.className="ht-select",r.style.height=`${u}px`,0===i.length){const t=document.createElement("option");t.textContent="No ID column found",t.value="",r.appendChild(t),r.disabled=!0}else i.forEach(t=>{const n=document.createElement("option");n.value=t,n.textContent=e.columnName.get(t),t===a&&(n.selected=!0),r.appendChild(n)}),r.addEventListener("change",t=>{const i=t.target.value;e.setNodeIdColumn(n,i),m.updateCoordinates(),h()});o.appendChild(r),t.appendChild(o)}}}(w,e,n,a,o,L,T,M,0,D,0,l);break;case"controls":!function(t,e,n,i,a){t.innerHTML="";const o=e(),s=n();if(!o||!s)return void(t.textContent="No tree selected");const r=$i("Fit to view","Fit the tree to the current view window",a);r.addEventListener("click",()=>{s.fitToView({transition:!0,autoPan:"Both",autoZoom:"Both"})}),t.appendChild(r);const l=Pi(),h=Ei("Manual zoom/pan:",a);l.appendChild(h);const c=Ni(s.options.manualZoomAndPanEnabled,a);c.addEventListener("click",()=>{s.options.manualZoomAndPanEnabled=!s.options.manualZoomAndPanEnabled,s.options.manualZoomAndPanEnabled?c.classList.add("active"):(c.classList.remove("active"),s.fitToView()),s.initializeZoom()}),l.appendChild(c),t.appendChild(l);const u=Pi(),d=Ei("Auto-zoom:",a);u.appendChild(d);const p=document.createElement("select");p.className="ht-select",p.style.height=`${a}px`;["Default","Both","X","Y","None"].forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===s.options.autoZoom&&(e.selected=!0),p.appendChild(e)}),p.addEventListener("change",t=>{s.options.autoZoom=t.target.value}),u.appendChild(p),t.appendChild(u);const f=Pi(),g=Ei("Auto-pan:",a);f.appendChild(g);const m=document.createElement("select");m.className="ht-select",m.style.height=`${a}px`;["Default","Both","X","Y","None"].forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===s.options.autoPan&&(e.selected=!0),m.appendChild(e)}),m.addEventListener("change",t=>{s.options.autoPan=t.target.value}),f.appendChild(m),t.appendChild(f)}(w,n,i,0,l);break;case"tree-manipulation":!function(t,e,n,i,a,o,s,r,l){t.innerHTML="";const h=e();if(!h)return void(t.textContent="No tree selected");const c=$i("Expand subtrees","Expand all collapsed subtrees",o),u=()=>{let t=!1;return h.displayedRoot.each(e=>{e!==h.displayedRoot&&e.collapsedChildren&&(t=!0)}),t};c.disabled=!u(),c.addEventListener("click",()=>{const t=[];h.displayedRoot.each(e=>{if(e!==h.displayedRoot&&e.collapsedChildren){let n=!0,i=e.parent;for(;i&&i!==h.displayedRoot;){if(i.collapsedChildren){n=!1;break}i=i.parent}n&&t.push(e)}}),t.forEach(t=>{h.expandSubtree(t)}),i()}),s(c),t.appendChild(c);const d=$i("Expand root","Expand the collapsed root",o);d.disabled=!h.displayedRoot.collapsedParent,d.addEventListener("click",()=>{h.displayedRoot.collapsedParent&&(h.expandRoot(),i())}),r(d),t.appendChild(d);const p=$i("Show hidden","Show all hidden nodes",o),f=()=>{let t=!1;return h.state.treeData.tree.each(e=>{e.hiddenChildren&&e.hiddenChildren.length>0&&(t=!0)}),t};p.disabled=!f(),p.addEventListener("click",()=>{h.showAllHidden(),i()}),l(p),t.appendChild(p);const g=Pi(),m=Ei("Width",o);g.appendChild(m);const y=(t,e=10)=>{const n=Math.log10(1/e),i=Math.log10(e);return(Math.log10(t)-n)/(i-n)*100},b=(t,e=10)=>{const n=Math.log10(1/e),i=n+t/100*(Math.log10(e)-n);return Math.pow(10,i)},x=zi(0,100,y(h.state.branchLengthScale),.1,o);x.addEventListener("input",t=>{const e=parseFloat(t.target.value),n=b(e);h.setBranchLengthScale(n)}),g.appendChild(x),t.appendChild(g);const v=Pi(),w=Ei("Height",o);v.appendChild(w);const _=zi(0,100,y(h.state.treeHeightScale),.1,o);_.addEventListener("input",t=>{const e=parseFloat(t.target.value),n=b(e);h.setTreeHeightScale(n)}),v.appendChild(_),t.appendChild(v);const C=Pi(),k=Ei("Radial:",o);C.appendChild(k);const S=Ni("circular"===h.state.layout,o),L=()=>{"circular"===h.state.layout?S.classList.add("active"):S.classList.remove("active")};h.subscribe("layoutChange",L),S.addEventListener("click",()=>{const t=h.state.layout;h.setLayout("circular"===t?"rectangular":"circular")}),C.appendChild(S),t.appendChild(C)}(w,n,0,E,0,l,t=>{d=t},t=>{p=t},t=>{f=t});break;case"tip-label-settings":!function(t,e,n,i,a,o,s,r){t.innerHTML="";const l=e();if(!l)return void(t.textContent="No tree selected");const h='\n <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path d="M11.5 1.5L14.5 4.5L5 14H2V11L11.5 1.5Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n <path d="M10 3L13 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>\n </svg>\n ',c=Pi(),u=Ei("Text:",i);c.appendChild(u);const d=Ki(l,"tipLabelText","Default",i,!0,null,r,s);c.appendChild(d),t.appendChild(c);const p=Pi(),f=Ei("Color:",i);p.appendChild(f);const g=function(t,e="",n){const i=document.createElement("button");return i.className="ht-icon-button",i.innerHTML=t,i.title=e,i.style.height=`${n}px`,i.style.width=`${n}px`,i}(h,"Edit color settings",i);g.addEventListener("click",t=>{t.stopPropagation(),a("tipLabelColor",p)}),p.appendChild(g);const m=Ki(l,"tipLabelColor","Default",i,!1,null,r,s);p.appendChild(m),t.appendChild(p);const y=Pi(),b=Ei("Size:",i);y.appendChild(b);const x=Ki(l,"tipLabelSize","Default",i,!1,!0,r,s);y.appendChild(x),t.appendChild(y);const v=Pi(),w=Ei("Style:",i);v.appendChild(w);const _=Ki(l,"tipLabelStyle","Default",i,!1,!1,r,s);v.appendChild(_),t.appendChild(v);const C=Pi(),k=Ei("Font:",i);C.appendChild(k);const S=document.createElement("select");S.className="ht-select",S.style.height=`${i}px`;const L=["sans-serif","serif","monospace"],T=void 0!==l.state.aesthetics.tipLabelFont?l.aestheticsScales.tipLabelFont.getValue():"sans-serif";L.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,t===T&&(e.selected=!0),S.appendChild(e)}),S.addEventListener("change",t=>{const e=t.target.value;l.setAesthetics({tipLabelFont:void 0}),l.state.treeData.tree.each(t=>{t.tipLabelFont=e}),l.updateCoordinates()}),C.appendChild(S),t.appendChild(C)}(w,n,0,l,z,0,A,()=>u);break;case"export":!function(t,e,n,i,a,o,s=document){t.innerHTML="";const r=e(),l=n();if(!r||!l)return void(t.textContent="No tree selected");const h=l.getCurrentBoundsWithLegends(),c=h.maxX-h.minX,u=h.maxY-h.minY,d={format:"svg",width:c,height:u,margin:18},p=c/u,f=300,g=2.54,m=t=>t/f*g,y=t=>t/g*f,b=(t,e)=>"png"===e?Math.round(t):Math.round(100*m(t))/100,x=(t,e)=>"png"===e?t:y(t),v=()=>{const t=l.getCurrentBoundsWithLegends(),e=t.maxX-t.minX,n=t.maxY-t.minY;d.width=e,d.height=n,P.value=b(e,d.format),z.value=b(n,d.format)},w=r.subscribe("coordinateChange",v),_=r.subscribe("legendsChange",v);t.dataset.cleanup=()=>{w(),_()};const C=$i("Export","Export the tree to a file",o);C.classList.add("primary"),C.addEventListener("click",()=>{const t=i().replace(/[^a-z0-9_-]/gi,"_"),e="svg"===d.format?"svg":"png";Zi(l,d,`${t}.${e}`,s)}),t.appendChild(C);const k=Pi(),S=Ei("Format:",o);k.appendChild(S);const L=document.createElement("select");L.className="ht-select",L.style.height=`${o}px`,["SVG","PNG"].forEach(t=>{const e=document.createElement("option");e.value=t.toLowerCase(),e.textContent=t,t.toLowerCase()===d.format&&(e.selected=!0),L.appendChild(e)}),L.addEventListener("change",t=>{d.format=t.target.value,P.value=b(d.width,d.format),z.value=b(d.height,d.format),R.value=b(d.margin,d.format);const e="png"===d.format?"px":"cm";M.textContent=`Width (${e}):`,$.textContent=`Height (${e}):`,A.textContent=`Margin (${e}):`}),k.appendChild(L),t.appendChild(k);const T=Pi(),M=Ei(`Width (${"png"===d.format?"px":"cm"}):`,o);T.appendChild(M);const P=Ai(b(d.width,d.format),.1,1e4,.1,o);P.addEventListener("input",t=>{const e=parseFloat(t.target.value);isNaN(e)||e<=0||(d.width=x(e,d.format),d.height=d.width/p,z.value=b(d.height,d.format))}),T.appendChild(P),t.appendChild(T);const E=Pi(),$=Ei(`Height (${"png"===d.format?"px":"cm"}):`,o);E.appendChild($);const z=Ai(b(d.height,d.format),.1,1e4,.1,o);z.addEventListener("input",t=>{const e=parseFloat(t.target.value);isNaN(e)||e<=0||(d.height=x(e,d.format),d.width=d.height*p,P.value=b(d.width,d.format))}),E.appendChild(z),t.appendChild(E);const N=Pi(),A=Ei(`Margin (${"png"===d.format?"px":"cm"}):`,o);N.appendChild(A);const R=Ai(b(d.margin,d.format),0,100,.1,o);R.addEventListener("input",t=>{const e=parseFloat(t.target.value);isNaN(e)||e<0||(d.margin=x(e,d.format))}),N.appendChild(R),t.appendChild(N)}(w,n,i,$,0,l,r)}}function D(){P(),g&&(g(),g=null),d=null,p=null,f=null;const t=n();t&&(g=t.subscribe("coordinateChange",E)),S(),h&&H(h)}return C.forEach(t=>{const e=document.createElement("div");e.className="ht-tab",e.textContent=t.label,e.addEventListener("click",()=>{e.classList.contains("disabled")||(N(),h===t.id?(h=null,Object.keys(k).forEach(t=>{k[t].classList.remove("active")}),w.classList.add("hidden"),w.innerHTML="",N()):R(t.id))}),k[t.id]=e,v.appendChild(e)}),w.addEventListener("click",t=>{const e=t.target.closest(".ht-icon-button"),n=t.target.closest(".ht-control-group.ht-aesthetic-editing");e||n||N()}),b.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),m=!m,m?(x.classList.remove("ht-panel-collapsed"),b.classList.remove("collapsed")):(N(),x.classList.add("ht-panel-collapsed"),b.classList.add("collapsed"))}),x.appendChild(v),x.appendChild(w),x.appendChild(_),t.appendChild(y),t.appendChild(x),S(),P(),D}function Ki(t,e,n,i,a=!1,o=null,s=null,r=null){const l=document.createElement("select");if(l.className="ht-select",l.style.height=`${i}px`,l.style.flex="1",a){const t=document.createElement("option");t.value="none",t.textContent="None",l.appendChild(t)}const h=document.createElement("option");h.value="",h.textContent=n,l.appendChild(h);const c=t.state.treeData,u=Array.from(c.columnDisplayName.keys());let d=u;null!==o&&(d=o?u.filter(t=>"continuous"===c.columnType.get(t)):u.filter(t=>"categorical"===c.columnType.get(t))),d.forEach(n=>{const i=document.createElement("option");i.value=n,i.textContent=c.columnDisplayName.get(n),t.state.aesthetics[e]===n&&(i.selected=!0),l.appendChild(i)});const p=t.state.aesthetics[e];return l.value=null===p?"none":void 0===p||""===p?"":p,l.addEventListener("change",n=>{let i;i="none"===n.target.value?null:""===n.target.value?void 0:n.target.value;const a={};if(a[e]=i,t.setAesthetics(a),s&&r){s()===e&&r(e)}}),l}t.heatTree=function(t,e=[],n={}){e&&!Array.isArray(e)&&(e=[e]),null==e&&(e=[]);const i=(n={buttonSize:25,transitionDuration:500,manualZoomAndPanEnabled:!0,autoZoom:"Default",autoPan:"Default",isolation:"shadow",...n}).isolation;let a;const o=new Vi,s=new Map,r=new Map;e.forEach((t,e)=>{if(!t.tree)throw new Error(`Tree at index ${e} is missing tree string`);const n=t.name||`Tree ${e+1}`;let i=[],a=[];if(t.metadata){(Array.isArray(t.metadata)?t.metadata:[t.metadata]).forEach((t,e)=>{t.name&&t.data?(i.push(t.data),a.push(t.name)):(i.push(t),a.push(`Metadata ${e+1}`))})}Ii.parseTrees(t.tree,n).forEach(({name:e,treeData:n},o)=>{let l=e,h=1;for(;s.has(l);)l=`${e} (${h})`,h++;const c=new Ii(n,i,a);let u;u=t.aesthetics?Object.fromEntries(Object.entries(t.aesthetics).map(([t,e])=>{for(const[n,i]of c.columnName.entries())if(i===e)return[t,n]}).filter(t=>void 0!==t)):void 0,s.set(l,c),r.set(l,u)})});const l=new Map,h=new Map;let c;if("string"==typeof t){if(c=document.querySelector(t),!c)throw new Error(`Container element not found: ${t}`)}else{if(!(t instanceof HTMLElement))throw new Error("First argument must be a CSS selector string or an HTMLElement");c=t}let u=null;"shadow"===i?(u=c.attachShadow({mode:"open"}),a=u):a=document,function(t=document){const e="heat-tree-styles";if(!(t.querySelector?t.querySelector(`#${e}`):document.getElementById(e))){const n=document.createElement("style");n.id=e,n.textContent='.ht-widget{color-scheme:light!important;--color-background: #ffffff;--color-text: #333333;--color-border: #dddddd;--color-muted: #666666;--color-accent: #007bff;background-color:var(--color-background);color:var(--color-text);outline:2px solid #ddd;border-radius:5px;overflow:hidden;display:flex;flex-direction:column;width:100%;height:100%}.ht-toolbar{flex:0 0 auto;margin-bottom:4px;display:flex;flex-direction:column;position:relative}.ht-toggle-container{position:absolute;top:0;right:0;padding:4px 8px;z-index:10}.ht-control-panel-toggle{background-color:transparent;border:none;cursor:pointer;display:flex;align-items:center;gap:4px;transition:opacity .2s}.ht-control-panel-toggle:hover{opacity:.7}.ht-control-panel-toggle .ht-toggle-arrow{transition:transform .3s}.ht-control-panel-toggle.collapsed .ht-toggle-arrow{transform:rotate(180deg)}.ht-control-panel-toggle .ht-hamburger-icon{color:#333}.ht-collapsible-panel{max-height:1000px;overflow:hidden;transition:max-height .3s ease-in-out}.ht-collapsible-panel.ht-panel-collapsed{max-height:0}.ht-widget .ht-tabs{display:flex;gap:20px;padding:4px 8px;background-color:#f5f5f5;border-bottom:2px solid #ddd;-webkit-user-select:none;user-select:none}.ht-widget .ht-tab{cursor:pointer;padding:0 4px;font-family:sans-serif;font-size:12px;color:#333;border-bottom:2px solid transparent;transition:all .2s}.ht-widget .ht-tab:hover{color:#666}.ht-widget .ht-tab.active{color:#000;font-weight:700;border-bottom-color:#007bff}.ht-widget .ht-tab.active:hover{color:#000}.ht-widget .ht-tab.disabled{color:#999;cursor:not-allowed;opacity:.5}.ht-widget .ht-tab.disabled:hover{color:#999}.ht-widget .ht-controls{padding:2px 8px;background-color:#fafafa;border-bottom:1px solid #ddd;display:flex;flex-wrap:wrap;column-gap:8px;row-gap:2px;align-items:center;min-height:22px}.ht-controls.hidden{display:none}.ht-control-group{display:flex;align-items:center;gap:4px;white-space:nowrap;padding:2px 0;border-bottom:2px solid transparent;transition:border-bottom-color .2s}.ht-control-group.ht-aesthetic-editing{border-bottom-color:#007bff}.ht-widget .ht-control-label{font-family:sans-serif;font-size:12px;color:#333;white-space:nowrap;display:flex;align-items:center}.ht-button{font-size:12px;font-family:sans-serif;background-color:#e0e0e0;border:1px solid #ccc;border-radius:4px;cursor:pointer;transition:background-color .2s;white-space:nowrap}.ht-button:hover{background-color:#d0d0d0}.ht-button:disabled{background-color:#f0f0f0;color:#999;cursor:not-allowed}.ht-button.primary{background-color:#007bff;color:#fff;font-weight:700}.ht-button.primary:hover{background-color:#0056b3}.ht-icon-button{font-size:12px;font-family:sans-serif;background-color:#e0e0e0;border:1px solid #ccc;border-radius:4px;cursor:pointer;transition:background-color .2s;display:flex;align-items:center;justify-content:center;padding:2px}.ht-icon-button:hover{background-color:#d0d0d0}.ht-icon-button svg{display:block}.ht-select{padding:1px 2px;font-size:12px;border:1px solid #ccc;border-radius:4px}.ht-slider{cursor:pointer;width:100px}.ht-toggle{width:30px;background-color:#ccc;border-radius:12px;position:relative;cursor:pointer;transition:background-color .3s;flex-shrink:0}.ht-toggle.active{background-color:#007bff}.ht-toggle-knob{background-color:#fff;border-radius:50%;position:absolute;top:2px;left:2px;transition:left .3s}.ht-toggle.active .ht-toggle-knob{left:calc(100% - 2px);transform:translate(-100%)}.ht-number-input{font-size:12px;border:1px solid #ccc;border-radius:4px;width:60px}.ht-text-input{font-size:12px;border:1px solid #ccc;border-radius:4px;padding:2px 4px;width:100px}.ht-widget .ht-aesthetic-settings-content{padding:2px 8px;background-color:#f0f0f0;border-bottom:1px solid #ddd;display:flex;flex-wrap:wrap;column-gap:8px;row-gap:2px;align-items:center;max-height:1000px;overflow:hidden;transition:max-height .3s ease-in-out,padding .3s ease-in-out}.ht-aesthetic-settings.hidden{max-height:0;padding-top:0;padding-bottom:0;border-bottom:none}.ht-color-palette-editor{display:flex;gap:8px;align-items:center}.ht-palette-buttons-container{display:flex;flex-direction:column;gap:2px}.ht-palette-button{width:20px;height:20px;font-size:12px;font-weight:700;background-color:#e0e0e0;border:1px solid #ccc;border-radius:4px;cursor:pointer;transition:background-color .2s}.ht-palette-button:hover{background-color:#d0d0d0}.ht-gradient-container{display:flex;gap:8px}.ht-gradient-column{display:flex;flex-direction:column;gap:4px}.ht-color-squares-container{display:flex;position:relative;height:16px;width:200px}.ht-color-square-wrapper{position:absolute;display:flex;flex-direction:column;align-items:center;transform:translate(-50%)}.ht-color-square{width:12px;height:12px;border:2px solid #333;border-radius:4px;cursor:pointer}.ht-color-square-tick{width:2px;height:8px;background-color:#333}.ht-gradient-box{width:200px;height:20px;border:1px solid #ccc;border-radius:4px;position:relative}.ht-widget .ht-range-slider-container{width:200px;height:12px;position:relative;border:1px solid #ccc;border-radius:4px;background:#f0f0f0;display:flex;align-items:center}.ht-range-handle{position:absolute;width:12px;height:12px;border:2px solid #333;border-radius:4px;cursor:ew-resize;transform:translate(-50%)}.ht-range-handle-indicator{position:absolute;bottom:90%;left:50%;transform:translate(-50%) rotate(180deg);width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #333;border-radius:2px;margin-bottom:2px}.ht-null-color-column{display:flex;flex-direction:column;gap:4px}.ht-null-color-square-container{display:flex;position:relative;height:16px;justify-content:center}.ht-null-color-square{width:12px;height:12px;border:2px solid #333;border-radius:4px;cursor:pointer}.ht-null-color-square-tick{width:2px;height:6px;background-color:#333;position:absolute;bottom:-6px;left:50%;transform:translate(-50%)}.ht-null-color-box{width:16px;height:20px;border:1px solid #ccc;border-radius:4px;position:relative}.missing-data-x-container{position:relative;display:flex;align-items:center;justify-content:center}.missing-data-x-container-triangle{position:absolute;bottom:85%;left:50%;transform:translate(-50%) rotate(180deg);width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #333;border-radius:2px;margin-bottom:2px}.missing-data-x{font-size:16px;color:#d00;font-weight:700;line-height:1;-webkit-user-select:none;user-select:none;cursor:pointer}.ht-tree{flex:1 1 auto;min-height:0;position:relative}.ht-tree svg{display:block;height:100%;width:100%}.picker_wrapper,.picker_wrapper.popup{z-index:999999!important;position:fixed!important}.picker_wrapper *,.picker_selector,.picker_slider,.picker_editor,.picker_sample,.picker_done,.picker_cancel{pointer-events:auto!important}\n.picker_wrapper.no_alpha .picker_alpha{display:none}.picker_wrapper.no_editor .picker_editor{position:absolute;z-index:-1;opacity:0}.picker_wrapper.no_cancel .picker_cancel{display:none}.layout_default.picker_wrapper{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:stretch;font-size:10px;width:25em;padding:.5em}.layout_default.picker_wrapper input,.layout_default.picker_wrapper button{font-size:1rem}.layout_default.picker_wrapper>*{margin:.5em}.layout_default.picker_wrapper:before{content:"";display:block;width:100%;height:0;order:1}.layout_default .picker_slider,.layout_default .picker_selector{padding:1em}.layout_default .picker_hue{width:100%}.layout_default .picker_sl{flex:1 1 auto}.layout_default .picker_sl:before{content:"";display:block;padding-bottom:100%}.layout_default .picker_editor{order:1;width:6.5rem}.layout_default .picker_editor input{width:100%;height:100%}.layout_default .picker_sample{order:1;flex:1 1 auto}.layout_default .picker_done,.layout_default .picker_cancel{order:1}.picker_wrapper{box-sizing:border-box;background:#f2f2f2;box-shadow:0 0 0 1px silver;cursor:default;font-family:sans-serif;color:#444;pointer-events:auto}.picker_wrapper:focus{outline:none}.picker_wrapper button,.picker_wrapper input{box-sizing:border-box;border:none;box-shadow:0 0 0 1px silver;outline:none}.picker_wrapper button:focus,.picker_wrapper button:active,.picker_wrapper input:focus,.picker_wrapper input:active{box-shadow:0 0 2px 1px #1e90ff}.picker_wrapper button{padding:.4em .6em;cursor:pointer;background-color:#f5f5f5;background-image:linear-gradient(0deg,gainsboro,transparent)}.picker_wrapper button:active{background-image:linear-gradient(0deg,transparent,gainsboro)}.picker_wrapper button:hover{background-color:#fff}.picker_selector{position:absolute;z-index:1;display:block;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);border:2px solid #fff;border-radius:100%;box-shadow:0 0 3px 1px #67b9ff;background:currentColor;cursor:pointer}.picker_slider .picker_selector{border-radius:2px}.picker_hue{position:relative;background-image:linear-gradient(90deg,red,#ff0,#0f0,#0ff,#00f,#f0f,red);box-shadow:0 0 0 1px silver}.picker_sl{position:relative;box-shadow:0 0 0 1px silver;background-image:linear-gradient(180deg,#fff,#fff0 50%),linear-gradient(0deg,#000,#0000 50%),linear-gradient(90deg,gray,#80808000)}.picker_alpha,.picker_sample{position:relative;background:linear-gradient(45deg,lightgrey 25%,transparent 25%,transparent 75%,lightgrey 75%) 0 0/2em 2em,linear-gradient(45deg,#d3d3d3 25%,#fff 25% 75%,#d3d3d3 75%) 1em 1em/2em 2em;box-shadow:0 0 0 1px silver}.picker_alpha .picker_selector,.picker_sample .picker_selector{background:none}.picker_editor input{font-family:monospace;padding:.2em .4em}.picker_sample:before{content:"";position:absolute;display:block;width:100%;height:100%;background:currentColor}.picker_arrow{position:absolute;z-index:-1}.picker_wrapper.popup{position:absolute;z-index:2;margin:1.5em}.picker_wrapper.popup,.picker_wrapper.popup .picker_arrow:before,.picker_wrapper.popup .picker_arrow:after{background:#f2f2f2;box-shadow:0 0 10px 1px #0006}.picker_wrapper.popup .picker_arrow{width:3em;height:3em;margin:0}.picker_wrapper.popup .picker_arrow:before,.picker_wrapper.popup .picker_arrow:after{content:"";display:block;position:absolute;top:0;left:0;z-index:-99}.picker_wrapper.popup .picker_arrow:before{width:100%;height:100%;-webkit-transform:skew(45deg);transform:skew(45deg);-webkit-transform-origin:0 100%;transform-origin:0 100%}.picker_wrapper.popup .picker_arrow:after{width:150%;height:150%;box-shadow:none}.popup.popup_top{bottom:100%;left:0}.popup.popup_top .picker_arrow{bottom:0;left:0;-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.popup.popup_bottom{top:100%;left:0}.popup.popup_bottom .picker_arrow{top:0;left:0;-webkit-transform:rotate(90deg) scale(1,-1);transform:rotate(90deg) scaleY(-1)}.popup.popup_left{top:0;right:100%}.popup.popup_left .picker_arrow{top:0;right:0;-webkit-transform:scale(-1,1);transform:scaleX(-1)}.popup.popup_right{top:0;left:100%}.popup.popup_right .picker_arrow{top:0;left:0}',t===document?document.head.appendChild(n):t.prepend(n)}}(a);const d=document.createElement("div");d.className="ht-widget";const p=document.createElement("div");p.className="ht-toolbar";const f=document.createElement("div");f.className="ht-tree";const g=document.createElementNS("http://www.w3.org/2000/svg","svg");f.appendChild(g),d.appendChild(p),d.appendChild(f),u?u.appendChild(d):c.appendChild(d);let m=null,y=null,b=null,x=null;function v(t,e,n=[],i=[]){const a=Ii.parseTrees(e,t),o=[];return a.forEach(({name:t,treeData:e})=>{let a=t,r=1;for(;s.has(a);)a=`${t} (${r})`,r++;const l=new Ii(e,n,i);s.set(a,l),o.push(a)}),o}function w(t){if(s.has(t)){if(m!==t||!b){for(;g.firstChild;)g.removeChild(g.firstChild);if(!l.has(t)){const e=new qi({treeData:s.get(t),aesthetics:r.get(t),...n},o);l.set(t,e)}if(h.has(t)){h.get(t).reattach(g)}else{const e=l.get(t),i=new Ui(e,g,n);h.set(t,i)}m=t,y=l.get(t),b=h.get(t),x&&x()}}else console.error(`Tree not found: ${t}`)}if(new oi(f,t=>{b&&b.fitToView()},{debounce:100,immediate:!0}),x=Wi(p,s,()=>y,()=>b,w,v,0,a),s.size>0){w(Array.from(s.keys())[0])}return{treeDataInstances:s,treeStateCache:l,treeViewCache:h,getCurrentTreeState:()=>y,getCurrentTreeView:()=>b,getCurrentTreeName:()=>m,switchToTree:w,addNewTree:v,container:d,shadowRoot:u}},Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
9
9
  //# sourceMappingURL=heat-tree.umd.min.js.map