changeset 5:62c6402dd50d draft

"planemo upload for repository https://github.com/mesocentre-clermont-auvergne/galaxy-tools/tree/master/tools/recentrifuge commit 0bff76499478da0f47e93e02542414d6a2aa8077"
author pimarin
date Wed, 18 May 2022 09:36:38 +0000
parents 512dc05a0e5a
children ecc282b4fe01
files mylog.txt output.rcf.data.csv output.rcf.html output.rcf.stat.csv
diffstat 4 files changed, 0 insertions(+), 6637 deletions(-) [+]
line wrap: on
line diff
--- a/mylog.txt	Wed May 18 09:28:48 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-
-=-= /home/pierre/anaconda3/envs/rcf/bin/rcf =-= v1.8.1 - Mar 2022 =-= by Jose Manuel Martí =-=
-
-Loading NCBI nodes... OK! 
-Loading NCBI names... OK! 
-Building dict of parent to children taxa... OK! 
-
-Please, wait, processing files in parallel...
-
-Loading output file test-data/kraken_test/kraken.out... OK!
-  Seqs read: 99	[52.81 knt]
-  Seqs clas: 99	(0.00% unclassified)
-  Seqs pass: 99	(0.00% rejected)
-  Scores SHEL: min = 36.0, max = 347.0, avr = 99.9
-  Coverage(%): min = 0.2, max = 88.1, avr = 15.4
-  Read length: min = 198 nt, max = 602 nt, avr = 533 nt
-  TaxIds: by classifier = 13, by filter = 13
-Building from raw data with mintaxa = 2 ... 
-  Check for more seqs lost ([in/ex]clude affects)... 
-  Info: 65 additional seqs discarded (65.657% of accepted)
-
-  Warning! 9 orphan taxids (rerun with --debug for details)
-test-data/kraken_test/kraken sample OK!
-Load elapsed time: 0.00243 sec
-
-
-Building the taxonomy multiple tree... OK!
-Generating interactive plot (output.rcf.html)... OK!
-Generating csv extra output ([output.rcf.]*.csv)... OK!
-Total elapsed time: 00:00:00
--- a/output.rcf.data.csv	Wed May 18 09:28:48 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-Samples,test-data/kraken_test/kraken,test-data/kraken_test/kraken,test-data/kraken_test/kraken,Details,Details
-Stats,count,unassigned,score,Rank,Name
-Id,,,,,
-1,34,0,26.826023135133102,no_rank,root
-2,34,0,26.826023135133102,superkingdom,Bacteria
-1224,34,0,26.826023135133102,phylum,Proteobacteria
-1236,34,0,26.826023135133102,class,Gammaproteobacteria
-91347,34,0,26.826023135133102,order,Unnamed
-543,34,9,26.826023135133102,family,Enterobacteriaceae
-547,25,25,31.582057972392526,genus,Enterobacter
--- a/output.rcf.html	Wed May 18 09:28:48 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6581 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta charset="utf-8"><link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAMAEBAAAAEAIABoBAAANgAAABgYAAABACAAiAkAAJ4EAAAgIAAAAQAgAKgQAAAmDgAAKAAAABAAAAAgAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wCAgIAC////AP///wC0tKJHlZWSqI6OmuRxcXn9koaK9J2Ym8uNm5V73PPoFv///wAAAAAD////AP///wCAgIAC////AP//7xCHh4OodHSi/2xqw/9nZ9H/XVuU/9eFqv/njb7/yYiq/5GAiOifqKJV////AAAAAAL///8A////AO3t2w56eoHPdHLH/3Vz3vx4dtz7dXTb/mVimv/XhKn/8ZPG/fSVx/vvlcT/kG+E/32Himb///8AAAAAA////wB0dHageHbO/3585fl5d9r/dnTX/3V02/5mYpz80X2i/eaIuv/ukcD/wXak/I6Maf+OkXD9iIKjL////wCEhFo+c3Kv/4F+6P18etz/e3nd/3l33P57eeT/aWag/9F5oP/sib3+tmuZ/3uEXf/P1YX7zdKG/3x9dbX///8Ac3J9nYKA4f+CgOb7fnzf/3174P58et//bm2v8Vtgc7SdbIHNqWmM/4aLZP/L0YT/0dWH/tfdiP+go3P6YlyWJ3BvmduGg+n/g4Hk/oF+4/6AfuX/bm2k7pCUUUX///8Ajv/jCVBmXqPBxoH/1NmI/c7Uhf/b4Yn9wMWB/2BdcGBraqX6iYbs/4SB5P+Eguj7hYPm/2Vlcov///8AACRtB////wAAAIAWrLB29uHojv/X3on+3eSK+9PYh/9XWVN7bWum+ouI7/+Gg+f/hoTq+4iF6f9lZXKL////ACQAbQf///8AAABoFoF+Xva0snL/y818/uDmiPvZ34n/WVlTe3Jxm9uMiu//iofr/oiG6f6Jhu3/cnGo7oyQQ0X///8A/znjCXF8dKNotpL/Za2O/WuVe/+FkGv9mJ5w/2pqaGBzc3+djYrr/42K8fuKh+v/i4js/oqH6/93dbfxYmJztGaTec1yxJr/gOGu/4nptf+K6Lf+i+q8/2eXhfqDNG8ngIBKPnt6uP+Rjvf9jInr/4yJ7f+Miu3+jor0/25xoP920pz/gOGw/oHerv+H4rL/kPC9+5Ttvf98ioC1////AP///wB0dHSgioff/5SR+/mOi+7/jYvt/4+L8P5scJ78etKe/YXis/+H47P/kO+8/JLxv/92m4f9nXKNL////wD///8A7e3bDnt7hM+Ihdv/ko/4/JSS+PuUkPb+bnKg/4Lapv+Q7739kfO/+43puf9/qJH/mYeUZv///wAAAAADgICAAv///wD//+8QhoaBqIB/sf+Iht7/jYjw/2tvnf+D3Kf/ieS1/4bIpP+AkYfoqJOfVf///wAAAAAC////AP///wCAgIAC////AP///wCwsJdHlZWQqJORn+RzdHv9hZOK9Jecmcuej5l7/+jzFv///wAAAAAD////AP///wD4PwAA4A8AAMAHAACAAwAAgAEAAAABAAADgQAAA8EAAAPBAAADgQAAAAEAAIABAACAAwAAwAcAAOAPAAD4PwAAKAAAABgAAAAwAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wEAAAAB////AP///wi6urdDubmxj6ennsuQkIzvc3Nz/YSIh/WWoZzWrrezoLe6t1X///8T////AP///wCAgIAC////AP///wD///8A////AP///wD///8A////Af///wD///8Ax8fDQJeYkLV4eH39WlmM/19dpP9dX6b/WFRr/611j/+/fJ//om2I/4N3ff+Jko7Ntri2Xv///wD///8AgICAAv///wD///8A////AP///wD///8B////AP///wOfn5t9c3N29GRjn/9oZ8P/c3LU/XVy3P9rbdH/YVt8/9eIrv/5mcz/75bE/t+Mt/67epz/fnN5/4uTkKP///8W////AAAAAAL///8A////AP///wH///8A////A5iYkZJoaH3/bWvB/3h23Px4dt3+dHPX/3Rx1v9sbcv/YFp6/82ApP/rj8D/65DA//KVxv/1mcn83424/5t1iP98gX7A////F////wCAgIAC////AAAAAAL///8AkJCHdWZlf/9zcs7/fHrj/Hh32/92ddn/dXTX/3Zz2P9vcM//YFt7/8t9of/pi73/54u7/+eNvf/vk8P/7ZbE/pxsh/xLVU7/iomJqP///wD///8A////Af///wCfn5Y4ZmV07XZ0zv9+fOX8enjc/3p43P94dtv/dnXZ/3d12f9xcdD/YFp6/8h5nf/mh7r/44e3/+qMvf/ljrv/jV59/3F+V/68wH3/gYNp/4uIlWf///8AAAAAAv///wJ3d22pc3G6/4KA5/t9e9//fHre/3t53f96eNz/eHbZ/3l23P50dNb9Ylx+/ch2m/3jg7b+44W2/+CItv+NXXz/bnpW/8XIgv/Y3Yv8ur57/3Fxbtni4uIa////AHl5XTdoZ4b4f3zb/4F+5P5+fN//fXvf/3x63v96edz/ennf/nt54P9xccb/Xlxy/7Rvj//gf7P/3IKw/olZeP9te1b/xsqD/9DVh//P1IX/09iG/pWYcf9nZ3Nt////AISEb35ycLb/hYPr/YB+4f9/feH/fnzh/3173/99e+L+enjX/2dmmfhlZXiwYGBiknJkaqGVZ37pg11x/3eBXP7GyoP/0NWH/87Uhf/R1ob/2eCK+8HFff9tbXWv////BG9vdb16eMn/hYPq/4F/4/+BfuP/gH7i/4B94v59e93/Y2KO+ISEbX7y8uQT////AP///weAjo5aT1tP5L7Cf//T2Ij+ztOF/9HWhv/S14b/2d+K/s3Sgv+BgnLcg4OSI11deeaBf9r/hYPo/4OB5P+DgeX/gX/i/4OB6v10c77/cXFjmv///wL///8A////AP///wD///8AeHN9apuecP/U2Yf/0teG/tPZhv/V24f/2uCJ/tTahv+KjGj6AABINV9egfuGg+P/hoTp/4WC5v+EgeX/goDk/4WD6/1wbq//WFgAQ////wAzMzMFAAAAAVVVVQP///8AAABjEoiLZ/Df5Y7/2d+J/dfch//W3If/2d+H/9vhif6ZnW3/AAA5P19egvuHheX/iIXq/4eE6P+Gg+f/hILl/4eE7P1xb7D/WFgAQ////wAzMzMFAAAAAVVVVQP///8AAABVEnd1WvDEx37/y9GD/dnfif/g54z/4OeL/97kiv6anWz/AAA1P15eeuaFg93/ioft/4iF6f+Hhen/hoPn/4mG7/14d8L/cXFimv///wP///8A////AP///wD///8AenV3a1dyZf9QY1//bGVW/pORY/+trnD/xch7/tTZhP+Pkmn6AABINXBwdb1/fc7/jYry/4mH6v+Jhur/iIbp/4iG6/6Gg+X/Z2aT+IKEaX7y8uQT////AP///wiXgY9bXndp5HXLnv95z6P+dsif/2Wrjv9RcWv/Z3Rk/nyBYv9xcWbbfHyDI4SEa354d73/kI31/YuI6/+LiOz/iofr/4mG6v+Lh+3+hoPi/21soPhnZ3qwYGBikmNza6JhinXpcsWa/3vdq/6C4a//iOi1/4zpt/+O6Lf/kOu8+3O1l/9jVmKv////BHl5WDdraor4iofn/4+M8v6Miez/i4nt/4uI7P+LiOv/i4jt/ouJ8P9+e83/XGBt/223jv952aj/e9uq/n3aqv+D36//huKy/4rntv+Q7r3/lvTC/nupj/9zYmxt////AP///wJ3d2qpfXvF/5KP9vyNiu7/jYru/4yJ7f+Miu7/i4jr/46L8P6FgN79XmZ5/XTMm/1+3q7+f9ys/4Lgr/+G5LP/iue2/4zot/+V9cL8iNWs/3BxcNni4uIa////AP///wCfn5I4aGd17YeE3v+Ukfj8jovu/46L7/+Oi+//jYru/46M8f+FgNv/XmV3/3jMnf+D4rH/g+Cw/4fks/+K57b/jem4/5TywP6Q57n/bYh5/5KIjWf///8AAAAAAgAAAAL///8AkJCFdWtqhf+IheL/lZL5/JCN8P+PjO//j4zv/5GO8/+Hgt3/X2Z4/33Rof+I5rb/h+Sz/4nmtf+N6rn/lPPB/pHruvxxm4T/h3yDqP///wD///8A////Af///wH///8A////A5aWj5JtbIP/g4DW/5SR9vyVkvj+kY7y/5KP9P+Ig97/X2d4/4DUpf+N6rn/jeq4/5Lwvv+U88D8h9qu/3KVgv+Lgoe/////F////wCAgIAC////AP///wD///8B////AP///wOfn5l9dHR39HVzsf+Fg97/k4/x/ZiW/v+Nh+f/YWl7/4ngrv+W+MX/kuy8/onesP52uZb/dH54/5aOk6P///8W////AAAAAAL///8A////AP///wD///8A////Af///wD///8Ax8fDQJWVjbV5eX79amic/3h2vv93crf/WV9r/3W1kP95vZn/aZ2C/3eCfP+Ui5DNu7i7Xv///wD///8AgICAAv///wD///8A////AP///wD///8A////AP///wEAAAAB////AP///wi6urdDuLitj6WmmcuPj4rvc3Nz/YiEh/Whlp3Wt66zoLq3ulX///8T////AP///wD///8C////AP///wD///8A////AP8B/wD8AH8A+AAfAOAADwDgAAcAwAAHAIAAAwCAAAMAgAABAAB8AQAAfgEAAP4BAAD+AQAAfgEAAHwBAIAAAQCAAAMAgAADAMAABwDgAAcA4AAPAPgAHwD8AH8A/wH/ACgAAAAgAAAAQAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////KO3t7XXFxcWwqqqq25eXl/RwcHD9mJiY9Kurq9vHx8ew8PDwdf///yj///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A9/f3TLS0tLpvb3H/UVFR/1VVWf9bW27/WVlz/1FRUf96ZG//c2Nr/1lWV/9RUVH/d3V2/7m5ubr5+flM////AP///wD///8A////AP///wD///8A////AP///wAAAAAA////AP///wD///8A////AP///wD///8A/f39HLW1tatbW13/V1de/2FgkP9rabv/cG7S/29u0/9paL7/UVFR/9GIrv/wlcX/75bE/8+Irf+ZcYb/XVhb/2FfYP+8vLyr/v7+HP///wD///8A////AP///wD///8A////AAAAAAD///8A////AP///wD///8A////AOvr60l2dnnpVVVZ/2ZlnP9ycdL/c3LW/3Jx1f9xcNT/cG/T/2ppvv9RUVH/zoSs/+yRwf/uk8L/7pPC/++UxP/pk8D/pXaP/1hVV/9/fn/p7+/vSf///wD///8A////AP///wD///8AAAAAAP///wD///8A////AP///wDg4OBWX19h/11dcv9zccr/d3XZ/3Z02P91c9f/dHLX/3Nx1v9xcNT/a2q//1FRUf/Ngqn/6o6+/+uQwP/tksH/7pPD/++Vxf/xl8b/3I64/3Jiav9lY2T/2dnZVv///wD///8A////AP///wAAAAAA////AP///wD///8A5OTkQ1tbXf9hYIH/eHfY/3l32/94dtr/d3ba/3Z12f90c9f/c3LW/3Nx1f9tbMH/UVFR/8l/pf/mirr/6Iy8/+mOvv/qj7//7JHB/++VxP/xl8b/04qx/1RUUv9ZWVj/6+vrQ////wD///8A////AAAAAAD///8A////APX19Q9mZmjfYF98/3t53P97ed3/enjc/3l32/93dtr/dnXZ/3Z02P91c9f/dXTY/25tw/9RUVH/yHyj/+WIuf/libn/54q7/+mNvf/rj7//7JHB/9WJsf9XVlX/Z2hb/3BxX/9vb23f+fn5D////wD///8AAAAAAP///wD///8AkZCSnFpaZ/97edn/fHre/3t53v97ed3/enjc/3l33P94dtv/dnXZ/3V02P92dNj/cG7D/1FRUf/FeaH/4oW2/+OGt//liLj/54q6/+mOvv/Sha3/V1VV/2doW//FyYL/xcqC/19fWf+fn5+c////AP///wAAAAAA////ANjY2DhRUVL/dXPA/3994f9+fOD/fXvf/3x63v97ed3/enjc/3l32/94dtr/eHba/3d12f9xb8T/UVFR/8J1nf/fgLH/4IOz/+KEtf/liLn/zoCq/1dVVf9naFr/w8eA/83Shf/P1Yb/q652/1JSUf/h4eE4////AAAAAAD///8Afn6ApWNigv+BfuL/gH3h/3584P99e9//fHre/3x63v97ed3/eXjc/3l32/95d9v/d3ba/3Fwxf9RUVH/wXSc/9x9r//fgbL/4YO0/8t9pv9XVVT/Z2ha/8LHgf/N0oX/ztOF/8/Uhv/S14b/c3Vh/42Ni6X///8AAAAAAOfn5xJRUVH/eXbG/4F/4/+AfuL/f33h/3584P99e+D/fHrf/3x63v97ed3/e3ne/3p43f9ycMH/Y2OR/1FRUf+NY3j/w3Sd/9x9rv/IeaL/V1VU/2doWv/DyIH/zNGF/87Thf/Q1Yb/0daG/9TZh/+ytnj/UlJS/+/v7xIAAAAAq6urYF1cav+DgeX/goDk/4F/4/+AfuL/f33h/3994f9+fOD/fXvf/3x63v95d9X/YF99/1FRUb9sbG+AZmVmgG1qa4BRUVG/fWBv/1dVVP9naFr/xMiB/83Shv/O04b/z9WG/9HWhv/S14b/1NqH/9TZhv9fYFn/t7e3YAAAAAB6enyeaGeV/4SC5v+DgeX/goDk/4F+4/+BfuP/f33h/3584P9+fOD/fHrb/1xcbv9sbG6g39/fQP///wD///8A////ANra2kBbWlugVVVT/8LHgf/O04X/ztOF/8/Uhf/Q1Yb/0teG/9PZh//V24f/2N6I/4aIZv+IiIeeAAAAAFpaXMx0crX/hYLm/4SC5v+DgeX/goDk/4KA5P+Bf+P/gH7i/3994f9oZ5v/X19hv/Hx8SD///8A////AP///wD///8A////AOfn5yBcXFq/m55w/9DVhv/R1ob/0teG/9LXhv/T2Yb/1dqH/9jdiP/Z34j/o6Zy/2VlY8wAAAAAUVFR7Hx7zP+GhOj/hYLm/4SB5f+Egub/g4Hl/4KA5P+Bf+P/gX/j/1paZP+xsbFA////AP///wD///8A////AP///wD///8A////AKampkBqa17/0teG/9LXhv/T2Yf/1dqH/9bciP/Y3oj/2N6H/9rgiP+5vXr/UlJS7AAAAABRUVH7gX7W/4eE6P+GhOj/hYPn/4WC5v+EgeX/g4Hl/4OB5f9/fNv/UVFR/9zc3AD///8A////AP///wD///8A////AP///wD///8A0NDQAFRUU//R14b/1dqH/9Xbh//W3If/192H/9jeh//a4Ij/3OKI/8PJfv9RUVH7AAAAAFFRUfuCgNj/iIbq/4eE6P+HhOj/hoPn/4WC5v+Egub/hILm/4B+3f9RUVH/3NzcAP///wD///8A////AP///wD///8A////AP///wDLy8sAUlJR/87ThP/W3Ij/192H/9nfiP/Z34j/2uCI/9vhiP/d44j/xMh+/1FRUfsAAAAAUVFR7H99zv+Jh+v/iIXq/4iF6v+Hhen/hoTo/4aD5/+Fgub/hYLm/1taZP+xsbFA////AP///wD///8A////AP///wD///8A////AJWVlUBSUlH/UlJR/25vXf+Ul2z/ur97/9jeh//c44j/3uWJ/97lif+8wXr/UVFR7AAAAABaWlzMd3W4/4qH6/+Kh+v/iYbq/4iF6f+HhOj/iIXp/4aE6P+GhOj/a2qe/19fYr/x8fEg////AP///wD///8A////AP///wDp6ekgW1xcv2SWe/9nm4D/Wm9k/1daVv9RUVH/VlZT/3p8Yf+ipnH/ys+A/6ircv9lZmPMAAAAAHp6fJ5rapf/i4js/4uJ7f+KiOz/iYbq/4mG6v+Ihur/iIbq/4eE6P+FguP/Xl5w/2xsb6Df399A////AP///wD///8A2traQGVnZqBccGX/d9Sk/3vZqf+B367/g+Gw/33No/9qk33/W2lh/1ZXVP9RUVH/U1NR/3d3dZ4AAAAAq6urYF5ea/+Ni+//jInt/4uI7P+LiOz/iofr/4mG6v+Jhur/iIXp/4iF6f+EguD/ZGSB/1FRUb9ra2+AZWdmgGpubIBRUVG/Xn1u/3TOn/9516f/ftyr/4Herf+G47L/iOa1/4vot/+Q7bz/k+++/4PHo/9SVFP/oaGhYAAAAADn5+cSUVFR/4F/z/+Niu7/jInt/4yJ7f+LiOz/i4nt/4qI7P+LiOz/iofr/4mG6v+Jhur/fnzN/2ZljP9RUVH/YpB5/2++lf921KT/edem/3vZqf+A3q3/hOGw/4bjs/+J5rX/juu6/5Dsu/+U8cD/g8Wi/1JTUv/t7e0SAAAAAP///wB+foClZ2aG/46L8P+Oi/D/jYru/4yJ7f+Mie3/i4js/4uI7P+LiOz/iofr/4qH6/+KiOz/eXjA/1FRUf9zyJz/eden/3zaqf982qn/ftys/4Hfrv+G47L/iOW0/4rntv+N6rn/ku++/5XxwP9le2//iYqKpf///wAAAAAA////ANjY2DhRUVL/gH7L/4+M8P+Oi+//jovv/42K7v+Niu7/jIru/4yK7v+Mie3/jInt/4uI7P96eMD/UVFR/3bLoP972an/ftyr/4Herv+D4K//heOy/4jmtf+L6Lf/juu5/5DtvP+V8cD/gcGf/1NUU//l5eU4////AAAAAAD///8A////AJGRkpxdXGn/jYrp/5CN8f+PjPD/j4zw/46L7/+Oi+//jYru/42K7v+Niu7/jYru/3x5wv9RUVH/ec6i/4Herv+B367/hOGw/4bjsv+I5bT/i+i3/43quf+Q7bz/k+++/4/jtv9bY17/nZ6enP///wD///8AAAAAAP///wD///8A9vb2D2Zmad9mZYL/kI3w/5CN8f+QjfH/j4zw/4+M8P+PjPD/j4zw/46L7/+Oi+//fHrD/1FRUf9/0qb/hOGw/4Xjsv+F47L/iOa1/4vot/+O67r/kO28/5Lvvf+S7b3/ZHht/3N1dN/6+voP////AP///wAAAAAA////AP///wD///8A5OTkQ1xcXv9oZ4j/kI3v/5GN8f+RjfH/kI3x/5CN8f+QjfH/kI3x/5CN8f99e8P/UVFR/3/UqP+I5bT/iOW0/4vot/+L6Lf/juu5/4/su/+S773/kem6/2Z9cf9gYmH/6+vrQ////wD///8A////AAAAAAD///8A////AP///wD///8A4ODgVl9fYf9iYnf/iojh/5KP8/+Sj/P/kY7y/5GO8v+RjvL/kY7y/358xf9RUVH/hdmt/4vot/+O67n/juu5/5Dtu/+Q7bv/ku++/4rXrv9hcGj/aGpp/+np6Vb///8A////AP///wD///8AAAAAAP///wD///8A////AP///wD///8A7OzsSXd3eelWVlr/dXOr/5CO7v+TkPT/k5D0/5KP8/+Sj/P/f33F/1FRUf+I267/kO28/5Dsu/+Q7Lv/ku+9/5Douv9zoon/U1VU/4GDgunx8fFJ////AP///wD///8A////AP///wAAAAAA////AP///wD///8A////AP///wD///8A/f39HLW1tatbW13/WVlg/3Bunv+Gg9T/k4/y/5SR9f+Bfsf/UVFR/4vfsv+S773/kOu7/4TKpf9ul4H/VlpY/19hYP/AwMCr////HP///wD///8A////AP///wD///8A////AAAAAAD///8A////AP///wD///8A////AP///wD///8A////APf390y0tLS6cG9y/1FRUf9WVlr/Y2J2/2Fgdv9RUVH/ZYBx/2N1a/9VV1b/UVFR/3R2df+/v7+6+vr6TP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8o7e3tdcXFxbCqqqrbl5eX9HBwcP2YmJj0q6ur28fHx7Dv7+91////KP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAA//Af//+AA//+AAD//AAAf/gAAD/wAAAf4AAAD8AAAAfAAAAHgAAAA4AAAAOAAAADAAfAAQAP4AEAH/ABAB/wAQAf8AEAH/ABAA/gAQAHwAGAAAADgAAAA4AAAAPAAAAHwAAAB+AAAA/wAAAf+AAAP/wAAH/+AAD//4AD///wH/8="><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Ubuntu"><script id="notfound">window.onload=function(){document.body.innerHTML=""}</script><script language="javascript" type="text/javascript">{//----------------------------------------------------------------------------
-// 
-// PURPOSE
-// 
-// Krona is a flexible tool for exploring the relative proportions of
-// hierarchical data, such as metagenomic classifications, using a
-// radial, space-filling display. It is implemented using HTML5 and
-// JavaScript, allowing charts to be explored locally or served over the
-// Internet, requiring only a current version of any major web
-// browser. Krona charts can be created using an Excel template or from
-// common bioinformatic formats using the provided conversion scripts.
-// 
-// 
-// COPYRIGHT LICENSE
-// 
-// Copyright (c) 2011, Battelle National Biodefense Institute (BNBI);
-// all rights reserved. Authored by: Brian Ondov, Nicholas Bergman, and
-// Adam Phillippy
-// 
-// This Software was prepared for the Department of Homeland Security
-// (DHS) by the Battelle National Biodefense Institute, LLC (BNBI) as
-// part of contract HSHQDC-07-C-00020 to manage and operate the National
-// Biodefense Analysis and Countermeasures Center (NBACC), a Federally
-// Funded Research and Development Center.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-// * Redistributions of source code must retain the above copyright
-//   notice, this list of conditions and the following disclaimer.
-// 
-// * Redistributions in binary form must reproduce the above copyright
-//   notice, this list of conditions and the following disclaimer in the
-//   documentation and/or other materials provided with the distribution.
-// 
-// * Neither the name of the Battelle National Biodefense Institute nor
-//   the names of its contributors may be used to endorse or promote
-//   products derived from this software without specific prior written
-//   permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// 
-// 
-// TRADEMARK LICENSE
-// 
-// KRONA(TM) is a trademark of the Department of Homeland Security, and use
-// of the trademark is subject to the following conditions:
-// 
-// * Distribution of the unchanged, official code/software using the
-//   KRONA(TM) mark is hereby permitted by the Department of Homeland
-//   Security, provided that the software is distributed without charge
-//   and modification.
-// 
-// * Distribution of altered source code/software using the KRONA(TM) mark
-//   is not permitted unless written permission has been granted by the
-//   Department of Homeland Security.
-// 
-// 
-// FOR MORE INFORMATION VISIT
-// 
-// https://github.com/marbl/Krona/wiki/
-// 
-//----------------------------------------------------------------------------
-//
-// Copyright (C) 2017-2022 Jose Manuel Martí Martínez, for the changes in
-// this file from the Krona Javascript 2.0 release.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the above copyright notice is
-// reproduced and all the above conditions are met.
-//
-// The KRONA(TM) mark has been substituted in the generated charts by
-// another logo in compliance with the above-stated conditions.
-//
-// FOR MORE INFORMATION VISIT
-//
-// https://github.com/khyox/recentrifuge/wiki/
-//
-//----------------------------------------------------------------------------
-}
-
-///////////////
-// Variables //
-///////////////
-
-var canvas;
-var canvasButtons = [];  // Keep trace of CanvasButton objects
-var ChartEnum = Object.freeze({
-    TAXOMIC: 'taxonomic',
-    GENOMIC: 'genomic'
-})
-var chart = ChartEnum.TAXOMIC
-var context;
-var svg; // for snapshot mode
-var collapse = true;
-var collapseCheckBox;
-var collapseLast;
-var compress;
-var compressCheckBox;
-var maxAbsoluteDepthText;
-var maxAbsoluteDepthButtonDecrease;
-var maxAbsoluteDepthButtonIncrease;
-var fontSize = 12;
-var fontSizeText;
-var fontSizeButtonDecrease;
-var fontSizeButtonIncrease;
-var fontSizeLast;
-var bkgBright = "eeeeee";
-var bkgBrightButtonDecrease;
-var bkgBrightButtonIncrease;
-var radiusButtonDecrease;
-var radiusButtonIncrease;
-var shorten;
-var shortenCheckBox;
-var maxAbsoluteDepth;
-var backButton;
-var upButton;
-var forwardButton;
-var snapshotButton;
-var snapshotMode = false;
-var details;
-var detailsName;
-var search;
-var searchResults;
-var nSearchResults;
-var useHueCheckBox;
-var useHueDiv;
-var sortByScoreCheckBox;
-var datasetDropDown;
-var datasetButtonLast;
-var datasetButtonPrev;
-var datasetButtonNext;
-var rankDropDown;
-var keyControl;
-var showKeys = true;
-var linkButton;
-var linkText;
-var frame;
-
-// Node references. Note that the meanings of 'selected' and 'focused' are
-// swapped in the docs.
-//
-var head; // the root of the entire tree
-var selectedNode = 0; // the root of the current view
-var focusNode = 0; // a node chosen for more info (single-click)
-var highlightedNode = 0; // mouse hover node
-var highlightingHidden = false;
-var nodes = new Array();  // Array with all the nodes
-var nodesIndex;  // Index of nodes, points last using hue(score) buttons
-var currentNodeID = 0; // to iterate while loading
-
-var nodeHistory = new Array();
-var nodeHistoryPosition = 0;
-
-var dataEnabled = false; // true when supplemental files are present
-
-// store non-Krona GET variables so they can be passed on to links
-//
-var getVariables = new Array();
-
-// selectedNodeLast is separate from the history, since we need to check
-// properties of the last node viewed when browsing through the history
-//
-var selectedNodeLast = 0;
-var zoomOut = false;
-
-// temporary zoom-in while holding the mouse button on a wedge
-//
-var quickLook = false; // true when in quick look state
-var mouseDown = false;
-var mouseDownTime; // to detect mouse button hold
-var quickLookHoldLength = 200;
-
-var imageWidth;
-var imageHeight;
-var centerX;
-var centerY;
-var gRadius;
-var updateViewNeeded = false;
-
-// Determines the angle that the pie chart starts at.  90 degrees makes the
-// center label consistent with the children.
-//
-var rotationOffset = Math.PI / 2;
-
-var buffer;
-var bufferFactor = .1;
-
-// The maps are the small pie charts showing the current slice being viewed.
-//
-var mapBuffer = 10;
-var mapRadius = 0;
-var maxMapRadius = 25;
-var mapWidth = 150;
-var maxLabelOverhang = Math.PI * 4.18;
-
-// Keys are the labeled boxes for slices in the highest level that are too thin
-// to label.
-//
-var maxKeySizeFactor = 2; // will be multiplied by font size
-var keySize;
-var keys;
-var keyBuffer = 10;
-var currentKey;
-var keyMinTextLeft;
-var keyMinAngle;
-
-var minRingWidthFactor = 5; // will be multiplied by font size
-var maxPossibleDepth; // the theoretical max that can be displayed
-var maxDisplayDepth; // the actual depth that will be displayed
-var headerHeight = 0;//document.getElementById('options').clientHeight;
-var historySpacingFactor = 1.6; // will be multiplied by font size
-var historyAlphaDelta = .25;
-
-// appearance
-//
-var lineOpacity = 0.3;
-var saturation = 0.5;
-var lightnessBase = 0.6;
-var lightnessMax = .8;
-var thinLineWidth = .3;
-var highlightLineWidth = 1.5;
-var labelBoxBuffer = 6;
-var labelBoxRounding = 15;
-var labelWidthFudge = 1.05; // The width of unshortened labels are set slightly
-                            // longer than the name width so the animation
-                            // finishes faster.
-var fontNormal;
-var fontBold;
-var fontFamily = 'sans-serif';
-//var fontFaceBold = 'bold Arial';
-var nodeRadius;
-var angleFactor;
-var tickLength;
-var compressedRadii;
-
-// colors
-//
-var highlightFill = 'rgba(255, 255, 255, .3)';
-var colorUnclassified = 'rgb(220,220,220)';
-
-// label staggering
-//
-var labelOffsets; // will store the current offset at each depth
-//
-// This will store pointers to the last node that had a label in each offset
-// (or "track") of each depth.  These will be used to shorten neighboring
-// labels that would overlap. The [nLabelNodes] index will store the last node
-// with a radial label. labelFirstNodes is the same, but to check for going all
-// the way around and overlapping the first labels.
-//
-var labelLastNodes;
-var labelFirstNodes;
-//
-var nLabelOffsets = 3; // the number of offsets to use
-
-var mouseX = -1;
-var mouseY = -1;
-var mouseXRel = -1;
-var mouseYRel = -1;
-
-// tweening
-//
-var progress = 0; // for tweening; goes from 0 to 1.
-var progressLast = 0;
-var tweenFactor = 0; // progress converted by a curve for a smoother effect.
-var tweenLength = 850; // in ms
-var tweenCurvature = 13;
-//
-// tweenMax is used to scale the sigmoid function so its range is [0,1] for the
-// domain [0,1]
-//
-var tweenMax = 1 / (1 + Math.exp(-tweenCurvature / 2));
-//
-var tweenStartTime;
-
-// for framerate debug
-//
-var tweenFrames = 0;
-var fpsDisplay = document.getElementById('frameRate');
-
-// Arrays to translate xml attribute names into displayable attribute names
-//
-var attributes = [];
-//
-var magnitudeIndex; // the index of attribute arrays used for magnitude
-var membersAssignedIndex;
-var membersSummaryIndex;
-
-// For defining gradients
-//
-var hueDisplayName;
-var hueStopPositions;
-var hueStopHues;
-var hueStopText;
-
-// multiple datasets
-//
-const DEFAULT_RANK = 'SUMMARY';
-const NO_RANK = 'NONE';
-var currentRank = DEFAULT_RANK;
-var currentDataset = 0;
-var lastDataset = 0;
-var datasets = 1;
-var datasetNames;
-const DATASET_MAX_SIZE = 20;  // Max size in rows of the dataset selection list
-var datasetsVisible = 1; // Number of datasets not hidden
-var datasetAlpha = new Tween(0, 0);
-var datasetWidths = [];
-var datasetChanged;
-var datasetSelectWidth = 50;
-var numRawSamples;
-var stats;
-
-window.onload = load;
-
-var image;
-var hiddenPattern;
-var loadingImage;
-var logoImage;
-
-// Setup CSS-like style of tooltips for attributes
-//
-var csstring = '.CellWithTooltip{ position:relative; }\n' +
-    '.Tooltip{ display:none;position:absolute;z-index:100;border:2px;' +
-    'background-color:white;border-style:solid;border-width:2px;' +
-    'border-color:red;padding:3px;color:red;top:20px;left:0px; }' +
-    '.CellWithTooltip:hover span.Tooltip{ display:block; }';
-var style = document.createElement('style');
-if (style.styleSheet) {
-    style.styleSheet.cssText = csstring;
-} else {
-    style.appendChild(document.createTextNode(csstring));
-}
-document.getElementsByTagName('head')[0].appendChild(style);
-
-///////////////
-// Functions //
-///////////////
-
-function backingScale() {
-    if ('devicePixelRatio' in window) {
-        if (window.devicePixelRatio > 1) {
-            return window.devicePixelRatio;
-        }
-    }
-
-    return 1;
-}
-
-function resize() {
-    imageWidth = window.innerWidth;
-    imageHeight = window.innerHeight;
-
-    if (!snapshotMode) {
-        context.canvas.width = imageWidth * backingScale();
-        context.canvas.height = imageHeight * backingScale();
-        context.canvas.style.width = imageWidth + "px"
-        context.canvas.style.height = imageHeight + "px"
-        context.scale(backingScale(), backingScale());
-    }
-
-    if (datasetDropDown) {
-        var ratio =
-            (datasetDropDown.offsetTop + datasetDropDown.clientHeight) * 2 /
-            imageHeight;
-
-        if (ratio > 1) {
-            ratio = 1;
-        }
-
-        ratio = Math.sqrt(ratio);
-
-        datasetSelectWidth =
-            (datasetDropDown.offsetLeft + datasetDropDown.clientWidth) * ratio;
-    }
-    var leftMargin = datasets > 1 ? datasetSelectWidth + 30 : 0;
-    var minDimension = imageWidth - mapWidth - leftMargin > imageHeight ?
-        imageHeight :
-        imageWidth - mapWidth - leftMargin;
-
-    maxMapRadius = minDimension * .03;
-    buffer = minDimension * bufferFactor;
-    margin = minDimension * .015;
-    centerX = (imageWidth - mapWidth - leftMargin) / 2 + leftMargin;
-    centerY = imageHeight / 2;
-    gRadius = minDimension / 2 - buffer;
-    //context.font = '11px sans-serif';
-}
-
-function handleResize() {
-    updateViewNeeded = true;
-}
-
-function Attribute() {
-}
-
-function SampleStats(sample, ictrl, sread, sclas, sfilt, scmin, scavg, scmax,
-                     lnmin, lnavg, lnmax, tclas, tfilt, tfold) {
-    // Class to store the statistics of a sample
-    this.sample = sample;
-    this.is_ctrl = (ictrl === 'True');
-    this.sread = sread;
-    this.sclas = sclas;
-    this.sfilt = sfilt;
-    this.scmin = scmin;
-    this.scavg = scavg;
-    this.scmax = scmax;
-    this.lnmin = lnmin;
-    this.lnavg = lnavg;
-    this.lnmax = lnmax;
-    this.tclas = tclas;
-    this.tfilt = tfilt;
-    this.tfold = tfold;
-}
-
-function CanvasButton(name, x, y, w, h, fill) {
-    // Constructor for a button in the canvas
-    this.name = name;
-    this.x = x || 0;
-    this.y = y || 0;
-    this.w = w || 1;
-    this.h = h || 1;
-    this.fill = fill || '#000000';
-
-    // Draws the button to a given context
-    this.draw = function (ctx) {
-        var oldAlpha = ctx.globalAlpha
-        ctx.globalAlpha = 1;
-        ctx.strokeStyle = '#' + bkgBright;
-        ctx.lineWidth = 3;
-        ctx.strokeRect(this.x, this.y, this.w, this.h);
-        ctx.fillStyle = this.fill;
-        ctx.fillRect(this.x, this.y, this.w, this.h);
-        ctx.strokeStyle = '#000000';
-        ctx.lineWidth = 0.5;
-        ctx.strokeRect(this.x, this.y, this.w, this.h);
-        // Draws symbols in buttons
-        ctx.fillStyle = '#000000';
-        ctx.globalAlpha = 0.7;
-        switch (this.name) {
-            case 'mostScore':
-                ctx.beginPath();
-                ctx.moveTo(this.x + 1 * this.w / 2, this.y + this.h / 8);
-                ctx.lineTo(this.x + 1 * this.w / 6, this.y + this.h / 2);
-                ctx.lineTo(this.x + 5 * this.w / 6, this.y + this.h / 2);
-                ctx.fill();
-            case 'moreScore':
-                ctx.beginPath();
-                ctx.moveTo(this.x + 1 * this.w / 2, this.y + 1 * this.h / 4);
-                ctx.lineTo(this.x + 1 * this.w / 6, this.y + 3 * this.h / 4);
-                ctx.lineTo(this.x + 5 * this.w / 6, this.y + 3 * this.h / 4);
-                ctx.fill();
-                break;
-            case 'lestScore':
-                ctx.beginPath();
-                ctx.moveTo(this.x + 1 * this.w / 2, this.y + 7 * this.h / 8);
-                ctx.lineTo(this.x + 1 * this.w / 6, this.y + 1 * this.h / 2);
-                ctx.lineTo(this.x + 5 * this.w / 6, this.y + 1 * this.h / 2);
-                ctx.fill();
-            case 'lessScore':
-                ctx.beginPath();
-                ctx.moveTo(this.x + 1 * this.w / 2, this.y + 3 * this.h / 4);
-                ctx.lineTo(this.x + 1 * this.w / 6, this.y + 1 * this.h / 4);
-                ctx.lineTo(this.x + 5 * this.w / 6, this.y + 1 * this.h / 4);
-                ctx.fill();
-                break;
-        }
-        ctx.globalAlpha = oldAlpha
-    };
-
-    // Determine if a point is inside the button's bounds
-    this.is_inside = function (mx, my) {
-        // Check the Mouse X,Y fall in the button's area
-        return (this.x <= mx) && (this.x + this.w >= mx) &&
-            (this.y <= my) && (this.y + this.h >= my);
-    }
-}
-
-function Tween(start, end) {
-    this.start = start;
-    this.end = end;
-    this.current = this.start;
-
-    this.current = function () {
-        if (progress == 1 || this.start == this.end) {
-            return this.end;
-        }
-        else {
-            return this.start + tweenFactor * (this.end - this.start);
-        }
-    };
-
-    this.setTarget = function (target) {
-        this.start = this.current();
-        this.end = target;
-    }
-}
-
-function Node() {
-    this.id = currentNodeID;
-    currentNodeID++;
-    nodes[this.id] = this;
-
-    this.angleStart = new Tween(Math.PI, 0);
-    this.angleEnd = new Tween(Math.PI, 0);
-    this.radiusInner = new Tween(1, 1);
-    this.labelRadius = new Tween(1, 1);
-    this.labelWidth = new Tween(0, 0);
-    this.scale = new Tween(1, 1); // TEMP
-    this.radiusOuter = new Tween(1, 1);
-
-    this.r = new Tween(255, 255);
-    this.g = new Tween(255, 255);
-    this.b = new Tween(255, 255);
-
-    this.alphaLabel = new Tween(0, 1);
-    this.alphaLine = new Tween(0, 1);
-    this.alphaArc = new Tween(0, 0);
-    this.alphaWedge = new Tween(0, 1);
-    this.alphaOther = new Tween(0, 1);
-    this.alphaPattern = new Tween(0, 0);
-    this.children = Array();
-    this.parent = 0;
-
-    this.attributes = new Array(attributes.length);
-
-    this.addChild = function (child) {
-        this.children.push(child);
-    };
-
-    this.addLabelNode = function (depth, labelOffset) {
-        if (labelHeadNodes[depth][labelOffset] == 0) {
-            // this will become the head node for this list
-
-            labelHeadNodes[depth][labelOffset] = this;
-            this.labelPrev = this;
-        }
-
-        var head = labelHeadNodes[depth][labelOffset];
-
-        this.labelNext = head;
-        this.labelPrev = head.labelPrev;
-        head.labelPrev.labelNext = this;
-        head.labelPrev = this;
-    }
-
-    this.canDisplayDepth = function () {
-        // whether this node is at a depth that can be displayed, according
-        // to the max absolute depth
-
-        return this.depth <= maxAbsoluteDepth;
-    }
-
-    this.canDisplayHistory = function () {
-        var radiusInner;
-
-        if (compress) {
-            radiusInner = compressedRadii[0];
-        }
-        else {
-            radiusInner = nodeRadius;
-        }
-
-        return (
-            -this.labelRadius.end * gRadius +
-            historySpacingFactor * fontSize / 2 <
-            radiusInner * gRadius
-        );
-    }
-
-    this.canDisplayLabelCurrent = function () {
-        return (
-            (this.angleEnd.current() - this.angleStart.current()) *
-            (this.radiusInner.current() * gRadius + gRadius) >=
-            minWidth());
-    }
-
-    this.checkHighlight = function () {
-        if (this.children.length == 0 && this == focusNode) {
-            //return false;
-        }
-
-        if (this.hide) {
-            return false;
-        }
-
-        if (this.radiusInner.end == 1) {
-            // compressed to the outside; don't check
-
-            return false;
-        }
-
-        var highlighted = false;
-
-        var angleStartCurrent = this.angleStart.current() + rotationOffset;
-        var angleEndCurrent = this.angleEnd.current() + rotationOffset;
-        var radiusInner = this.radiusInner.current() * gRadius;
-
-        for (var i = 0; i < this.children.length; i++) {
-            highlighted = this.children[i].checkHighlight();
-
-            if (highlighted) {
-                return true;
-            }
-        }
-
-        if (this.radial) {
-            var angleText = (angleStartCurrent + angleEndCurrent) / 2;
-            var radiusText = (gRadius + radiusInner) / 2;
-
-            context.rotate(angleText);
-            context.beginPath();
-            context.moveTo(radiusText, -fontSize);
-            context.lineTo(radiusText, fontSize);
-            context.lineTo(radiusText + centerX, fontSize);
-            context.lineTo(radiusText + centerX, -fontSize);
-            context.closePath();
-            context.rotate(-angleText);
-
-            if (context.isPointInPath(mouseXRel, mouseYRel)) {
-                var label = String(this.getPercentage()) + '%' + '   '
-                    + this.name;
-
-                if (this.searchResultChildren()) {
-                    label += searchResultString(this.searchResultChildren());
-                }
-
-                if
-                (
-                    Math.sqrt((mouseXRel) * (mouseXRel)
-                        + (mouseYRel) * (mouseYRel)) / backingScale() <
-                    radiusText + measureText(label)
-                ) {
-                    highlighted = true;
-                }
-            }
-        }
-        else {
-            for (var i = 0; i < this.hiddenLabels.length; i++) {
-                var hiddenLabel = this.hiddenLabels[i];
-
-                context.rotate(hiddenLabel.angle);
-                context.beginPath();
-                context.moveTo(gRadius, -fontSize);
-                context.lineTo(gRadius, fontSize);
-                context.lineTo(gRadius + centerX, fontSize);
-                context.lineTo(gRadius + centerX, -fontSize);
-                context.closePath();
-                context.rotate(-hiddenLabel.angle);
-
-                if (context.isPointInPath(mouseXRel, mouseYRel)) {
-                    var label = String(hiddenLabel.value) + ' more';
-
-                    if (hiddenLabel.search) {
-                        label += searchResultString(hiddenLabel.search);
-                    }
-
-                    if
-                    (
-                        Math.sqrt((mouseXRel) * (mouseXRel)
-                            + (mouseYRel) * (mouseYRel)) / backingScale() <
-                        gRadius + fontSize + measureText(label)
-                    ) {
-                        highlighted = true;
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (!highlighted && this != selectedNode && !this.getCollapse()) {
-            context.beginPath();
-            context.arc(0, 0, radiusInner, angleStartCurrent, angleEndCurrent,
-                false);
-            context.arc(0, 0, gRadius, angleEndCurrent, angleStartCurrent,
-                true);
-            context.closePath();
-
-            if (context.isPointInPath(mouseXRel, mouseYRel)) {
-                highlighted = true;
-            }
-
-            if
-            (
-                !highlighted &&
-                (angleEndCurrent - angleStartCurrent) *
-                (radiusInner + gRadius) <
-                minWidth() &&
-                this.getDepth() == selectedNode.getDepth() + 1
-            ) {
-                if (showKeys && this.checkHighlightKey()) {
-                    highlighted = true;
-                }
-            }
-        }
-
-        if (highlighted) {
-            if (this != highlightedNode) {
-                //	document.body.style.cursor='pointer';
-            }
-
-            highlightedNode = this;
-        }
-
-        return highlighted;
-    }
-
-    this.checkHighlightCenter = function () {
-        if (!this.canDisplayHistory()) {
-            return;
-        }
-
-        var cx = centerX;
-        var cy = centerY - this.labelRadius.end * gRadius;
-        //var dim = context.measureText(this.name);
-
-        var width = this.nameWidth;
-
-        if (this.searchResultChildren()) {
-            var results = searchResultString(this.searchResultChildren());
-            var dim = context.measureText(results);
-            width += dim.width;
-        }
-
-        if
-        (
-            mouseX > cx - width / 2 &&
-            mouseX < cx + width / 2 &&
-            mouseY > cy - historySpacingFactor * fontSize / 2 &&
-            mouseY < cy + historySpacingFactor * fontSize / 2
-        ) {
-            highlightedNode = this;
-            return;
-        }
-
-        if (this.getParent()) {
-            this.getParent().checkHighlightCenter();
-        }
-    }
-
-    this.checkHighlightKey = function () {
-        var offset = keyOffset();
-
-        var xMin = imageWidth - keySize - margin - this.keyNameWidth
-            - keyBuffer;
-        var xMax = imageWidth - margin;
-        var yMin = offset;
-        var yMax = offset + keySize;
-
-        currentKey++;
-
-        return (
-            mouseX > xMin &&
-            mouseX < xMax &&
-            mouseY > yMin &&
-            mouseY < yMax);
-    }
-
-    this.checkHighlightMap = function () {
-        if (this.parent) {
-            this.parent.checkHighlightMap();
-        }
-
-        if (this.getCollapse() || this == focusNode) {
-            return;
-        }
-
-        var box = this.getMapPosition();
-
-        if
-        (
-            mouseX > box.x - mapRadius &&
-            mouseX < box.x + mapRadius &&
-            mouseY > box.y - mapRadius &&
-            mouseY < box.y + mapRadius
-        ) {
-            highlightedNode = this;
-        }
-    }
-
-    /*	this.collapse = function()
-	{
-		for (var i = 0; i < this.children.length; i++ )
-		{
-			this.children[i] = this.children[i].collapse();
-		}
-
-		if
-		(
-			this.children.length == 1 &&
-			this.children[0].magnitude == this.magnitude
-		)
-		{
-			this.children[0].parent = this.parent;
-			this.children[0].getDepth() = this.parent.getDepth() + 1;
-			return this.children[0];
-		}
-		else
-		{
-			return this;
-		}
-	}
-*/
-    this.draw = function (labelMode, selected, searchHighlighted) {
-        var depth = this.getDepth() - selectedNode.getDepth() + 1;
-//		var hidden = false;
-
-        if (selectedNode == this) {
-            selected = true;
-        }
-
-        var angleStartCurrent = this.angleStart.current() + rotationOffset;
-        var angleEndCurrent = this.angleEnd.current() + rotationOffset;
-        var radiusInner = this.radiusInner.current() * gRadius;
-        var canDisplayLabelCurrent = this.canDisplayLabelCurrent();
-        var hiddenSearchResults = false;
-
-        /*		if ( ! this.hide )
-		{
-			for ( var i = 0; i < this.children.length; i++ )
-			{
-				if ( this.children[i].hide && this.children[i].searchResults )
-				{
-					hiddenSearchResults = true;
-				}
-			}
-		}
-*/
-        var drawChildren =
-            (!this.hide || !this.hidePrev && progress < 1) &&
-            (!this.hideAlone || !this.hideAlonePrev && progress < 1);
-
-//		if ( this.alphaWedge.current() > 0 || this.alphaLabel.current() > 0 )
-        {
-            var lastChildAngleEnd = angleStartCurrent;
-
-            if (this.hasChildren())//canDisplayChildren )
-            {
-                lastChildAngleEnd =
-                    this.children[this.children.length - 1].angleEnd.current()
-                    + rotationOffset;
-            }
-
-            if (labelMode) {
-                var drawRadial =
-                    !(
-                        this.parent &&
-                        this.parent != selectedNode &&
-                        angleEndCurrent == this.parent.angleEnd.current()
-                        + rotationOffset
-                    );
-
-                //if ( angleStartCurrent != angleEndCurrent )
-                {
-                    this.drawLines(angleStartCurrent, angleEndCurrent,
-                        radiusInner, drawRadial, selected);
-                }
-
-                var alphaOtherCurrent = this.alphaOther.current();
-                var childRadiusInner;
-
-                if (this == selectedNode || alphaOtherCurrent) {
-                    childRadiusInner =
-                        this.children.length ?
-                            this.children[this.children.length
-                            - 1].radiusInner.current() * gRadius
-                            : radiusInner
-                }
-
-                if (this == selectedNode) {
-                    this.drawReferenceRings(childRadiusInner);
-                }
-
-                if
-                (
-                    selected &&
-                    !searchHighlighted &&
-                    this != selectedNode &&
-                    (
-                        this.isSearchResult ||
-                        this.hideAlone && this.searchResultChildren() ||
-                        false
-//						this.hide &&
-//						this.containsSearchResult
-                    )
-                ) {
-                    context.globalAlpha = this.alphaWedge.current();
-
-                    drawWedge
-                    (
-                        angleStartCurrent,
-                        angleEndCurrent,
-                        radiusInner,
-                        gRadius,
-                        highlightFill,
-                        0,
-                        true
-                    );
-
-                    if
-                    (
-                        this.keyed &&
-                        !showKeys &&
-                        this.searchResults &&
-                        !searchHighlighted &&
-                        this != highlightedNode &&
-                        this != focusNode
-                    ) {
-                        var angle = (angleEndCurrent + angleStartCurrent) / 2;
-                        this.drawLabel(angle, true, false, true, true);
-                    }
-
-                    //this.drawHighlight(false);
-                    searchHighlighted = true;
-                }
-
-                if
-                (
-                    this == selectedNode ||
-                    //					true
-                    //(canDisplayLabelCurrent) &&
-                    this != highlightedNode &&
-                    this != focusNode
-                ) {
-                    if (this.radial != this.radialPrev
-                        && this.alphaLabel.end == 1) {
-                        context.globalAlpha = tweenFactor;
-                    }
-                    else {
-                        context.globalAlpha = this.alphaLabel.current();
-                    }
-
-                    this.drawLabel
-                    (
-                        (angleStartCurrent + angleEndCurrent) / 2,
-                        this.hideAlone && this.searchResultChildren() ||
-                        (this.isSearchResult || hiddenSearchResults) && selected,
-                        this == selectedNode && !this.radial,
-                        selected,
-                        this.radial
-                    );
-
-                    if (this.radial != this.radialPrev
-                        && this.alphaLabel.start == 1 && progress < 1) {
-                        context.globalAlpha = 1 - tweenFactor;
-
-                        this.drawLabel
-                        (
-                            (angleStartCurrent + angleEndCurrent) / 2,
-                            (this.isSearchResult || hiddenSearchResults)
-                            && selected,
-                            this == selectedNodeLast && !this.radialPrev,
-                            selected,
-                            this.radialPrev
-                        );
-                    }
-                }
-
-                if
-                (
-                    alphaOtherCurrent &&
-                    lastChildAngleEnd != null
-                ) {
-                    if
-                    (
-                        (angleEndCurrent - lastChildAngleEnd) *
-                        (childRadiusInner + gRadius) >=
-                        minWidth()
-                    ) {
-                        //context.font = fontNormal;
-                        context.globalAlpha = this.alphaOther.current();
-
-                        drawTextPolar
-                        (
-                            this.getUnclassifiedText(),
-                            this.getUnclassifiedPercentage(),
-                            (lastChildAngleEnd + angleEndCurrent) / 2,
-                            (childRadiusInner + gRadius) / 2,
-                            true,
-                            false,
-                            false,
-                            0,
-                            0
-                        );
-                    }
-                }
-
-                if (this == selectedNode && this.keyUnclassified && showKeys) {
-                    this.drawKey
-                    (
-                        (lastChildAngleEnd + angleEndCurrent) / 2,
-                        false,
-                        false
-                    );
-                }
-            }
-            else {
-                var alphaWedgeCurrent = this.alphaWedge.current();
-
-                if (alphaWedgeCurrent || this.alphaOther.current()) {
-                    var currentR = this.r.current();
-                    var currentG = this.g.current();
-                    var currentB = this.b.current();
-
-                    var fill = rgbText(currentR, currentG, currentB);
-
-                    var radiusOuter;
-                    var lastChildAngle;
-                    var truncateWedge =
-                        (
-                            (this.hasChildren() || this == selectedNode) &&
-                            !this.keyed &&
-                            (compress || depth < maxDisplayDepth) &&
-                            drawChildren
-                        );
-
-                    if (truncateWedge) {
-                        radiusOuter = this.children.length
-                            ? this.children[0].radiusInner.current()
-                            * gRadius : radiusInner;
-                    }
-                    else {
-                        radiusOuter = gRadius;
-                    }
-                    /*
-					if ( this.hasChildren() )
-					{
-						radiusOuter = this.children[0].getUncollapsed().radiusInner.current() * gRadius + 1;
-					}
-					else
-					{ // TEMP
-						radiusOuter = radiusInner + nodeRadius * gRadius;
-
-						if ( radiusOuter > gRadius )
-						{
-							radiusOuter = gRadius;
-						}
-					}
-					*/
-                    context.globalAlpha = alphaWedgeCurrent;
-
-                    if (radiusInner != radiusOuter || truncateWedge) {
-                        drawWedge
-                        (
-                            angleStartCurrent,
-                            angleEndCurrent,
-                            radiusInner,
-                            radiusOuter,//this.radiusOuter.current() * gRadius,
-                            //'rgba(0, 200, 0, .1)',
-                            fill,
-                            this.alphaPattern.current()
-                        );
-
-                        if (truncateWedge) {
-                            // fill in the extra space if the sum of our
-                            // childrens' magnitudes is less than ours
-
-                            if (lastChildAngleEnd < angleEndCurrent)
-                            //&& false) // TEMP
-                            {
-                                if (radiusOuter > 1) {
-                                    // overlap slightly to hide the seam
-
-                                    //								radiusOuter -= 1;
-                                }
-
-                                if (alphaWedgeCurrent < 1) {
-                                    context.globalAlpha
-                                        = this.alphaOther.current();
-                                    drawWedge
-                                    (
-                                        lastChildAngleEnd,
-                                        angleEndCurrent,
-                                        radiusOuter,
-                                        gRadius,
-                                        colorUnclassified,
-                                        0
-                                    );
-                                    context.globalAlpha = alphaWedgeCurrent;
-                                }
-
-                                drawWedge
-                                (
-                                    lastChildAngleEnd,
-                                    angleEndCurrent,
-                                    radiusOuter,
-                                    gRadius,
-                                    //this.radiusOuter.current() * gRadius,
-                                    //'rgba(200, 0, 0, .1)',
-                                    fill,
-                                    this.alphaPattern.current()
-                                );
-                            }
-                        }
-
-                        if (radiusOuter < gRadius) {
-                            // patch up the seam
-                            //
-                            context.beginPath();
-                            context.arc(0, 0, radiusOuter,
-                                angleStartCurrent/*lastChildAngleEnd*/,
-                                angleEndCurrent, false);
-                            context.strokeStyle = fill;
-                            context.lineWidth = 1;
-                            context.stroke();
-                        }
-                    }
-
-                    if (this.keyed && selected && showKeys)
-                    //&& progress == 1 )
-                    {
-                        this.drawKey
-                        (
-                            (angleStartCurrent + angleEndCurrent) / 2,
-                            (
-                                this == highlightedNode ||
-                                this == focusNode ||
-                                this.searchResults
-                            ),
-                            this == highlightedNode || this == focusNode
-                        );
-                    }
-                }
-            }
-        }
-
-        this.hiddenLabels = Array();
-
-        if (drawChildren) {
-            // draw children
-            //
-            for (var i = 0; i < this.children.length; i++) {
-                if (this.drawHiddenChildren(i, selected, labelMode,
-                    searchHighlighted)) {
-                    var childHiddenEnd = this.children[i].hiddenEnd;
-                    if (childHiddenEnd > i) {  // Avoid infinite loop
-                        i = childHiddenEnd;
-                    }
-                }
-                else {
-                    this.children[i].draw(labelMode, selected,
-                        searchHighlighted);
-                }
-            }
-        }
-    };
-
-    this.drawHiddenChildren = function
-        (firstHiddenChild,
-         selected,
-         labelMode,
-         searchHighlighted) {
-        var firstChild = this.children[firstHiddenChild];
-
-        if (firstChild.hiddenEnd == null
-            || firstChild.radiusInner.current() == 1) {
-            return false;
-        }
-
-        for (var i = firstHiddenChild; i < firstChild.hiddenEnd; i++) {
-            if (!this.children[i].hide
-                || !this.children[i].hidePrev && progress < 1) {
-                return false;
-            }
-        }
-
-        var angleStart = firstChild.angleStart.current() + rotationOffset;
-        var lastChild = this.children[firstChild.hiddenEnd];
-        var angleEnd = lastChild.angleEnd.current() + rotationOffset;
-        var radiusInner = gRadius * firstChild.radiusInner.current();
-        var hiddenChildren = firstChild.hiddenEnd - firstHiddenChild + 1;
-
-        if (labelMode) {
-            var hiddenSearchResults = 0;
-
-            for (var i = firstHiddenChild; i <= firstChild.hiddenEnd; i++) {
-                hiddenSearchResults += this.children[i].searchResults;
-
-                if (this.children[i].magnitude == 0) {
-                    hiddenChildren--;
-                }
-            }
-
-            if
-            (
-                selected &&
-                (angleEnd - angleStart) *
-                (gRadius + gRadius) >=
-                minWidth() ||
-                this == highlightedNode &&
-                hiddenChildren ||
-                hiddenSearchResults
-            ) {
-                context.globalAlpha = this.alphaWedge.current();
-
-                this.drawHiddenLabel
-                (
-                    angleStart,
-                    angleEnd,
-                    hiddenChildren,
-                    hiddenSearchResults
-                );
-            }
-        }
-
-        var drawWedges = true;
-
-        for (var i = firstHiddenChild; i <= firstChild.hiddenEnd; i++) {
-            // all hidden children must be completely hidden to draw together
-
-            if (this.children[i].alphaPattern.current()
-                != this.children[i].alphaWedge.current()) {
-                drawWedges = false;
-                break;
-            }
-        }
-
-        if (labelMode) {
-            if (drawWedges) {
-                var drawRadial = (angleEnd
-                    < this.angleEnd.current() + rotationOffset);
-                this.drawLines(angleStart, angleEnd, radiusInner, drawRadial);
-            }
-
-            if (hiddenSearchResults && !searchHighlighted) {
-                drawWedge
-                (
-                    angleStart,
-                    angleEnd,
-                    radiusInner,
-                    gRadius,//this.radiusOuter.current() * gRadius,
-                    highlightFill,
-                    0,
-                    true
-                );
-            }
-        }
-        else if (drawWedges) {
-            context.globalAlpha = this.alphaWedge.current();
-
-            var fill = rgbText
-            (
-                firstChild.r.current(),
-                firstChild.g.current(),
-                firstChild.b.current()
-            );
-
-            drawWedge
-            (
-                angleStart,
-                angleEnd,
-                radiusInner,
-                gRadius,//this.radiusOuter.current() * gRadius,
-                fill,
-                context.globalAlpha,
-                false
-            );
-        }
-
-        return drawWedges;
-    }
-
-    this.drawHiddenLabel = function (angleStart, angleEnd, value,
-                                     hiddenSearchResults) {
-        var textAngle = (angleStart + angleEnd) / 2;
-        var labelRadius = gRadius + fontSize;//(radiusInner + radius) / 2;
-
-        var hiddenLabel = Array();
-
-        hiddenLabel.value = value;
-        hiddenLabel.angle = textAngle;
-        hiddenLabel.search = hiddenSearchResults;
-
-        this.hiddenLabels.push(hiddenLabel);
-
-        drawTick(gRadius - fontSize * .75, fontSize * 1.5, textAngle);
-        drawTextPolar
-        (
-            value.toString() + ' more',
-            0, // inner text
-            textAngle,
-            labelRadius,
-            true, // radial
-            hiddenSearchResults, // bubble
-            this == highlightedNode || this == focusNode, // bold
-            false,
-            hiddenSearchResults
-        );
-    }
-
-    this.drawHighlight = function (bold) {
-        var angleStartCurrent = this.angleStart.current() + rotationOffset;
-        var angleEndCurrent = this.angleEnd.current() + rotationOffset;
-        var radiusInner = this.radiusInner.current() * gRadius;
-
-        //this.setHighlightStyle();
-
-        if (this == focusNode && this
-            == highlightedNode && this.hasChildren()) {
-//			context.fillStyle = "rgba(255, 255, 255, .3)";
-            arrow
-            (
-                angleStartCurrent,
-                angleEndCurrent,
-                radiusInner
-            );
-        }
-        else {
-            drawWedge
-            (
-                angleStartCurrent,
-                angleEndCurrent,
-                radiusInner,
-                gRadius,
-                highlightFill,
-                0,
-                true
-            );
-        }
-
-        // check if hidden children should be highlighted
-        //
-        for (var i = 0; i < this.children.length; i++) {
-            if
-            (
-                this.children[i].getDepth() - selectedNode.getDepth() + 1 <=
-                maxDisplayDepth &&
-                this.children[i].hiddenEnd != null
-            ) {
-                var firstChild = this.children[i];
-                var lastChild = this.children[firstChild.hiddenEnd];
-                var hiddenAngleStart = firstChild.angleStart.current()
-                    + rotationOffset;
-                var hiddenAngleEnd = lastChild.angleEnd.current()
-                    + rotationOffset;
-                var hiddenRadiusInner = gRadius
-                    * firstChild.radiusInner.current();
-
-                drawWedge
-                (
-                    hiddenAngleStart,
-                    hiddenAngleEnd,
-                    hiddenRadiusInner,
-                    gRadius,
-                    'rgba(255, 255, 255, .3)',
-                    0,
-                    true
-                );
-
-                if (false && !this.searchResults) {
-                    this.drawHiddenLabel
-                    (
-                        hiddenAngleStart,
-                        hiddenAngleEnd,
-                        firstChild.hiddenEnd - i + 1
-                    );
-                }
-
-                i = firstChild.hiddenEnd;
-            }
-        }
-
-//			context.strokeStyle = 'black';
-        context.fillStyle = 'black';
-
-        var highlight = !(progress < 1 && zoomOut
-            && this == selectedNodeLast);
-
-        var angle = (angleEndCurrent + angleStartCurrent) / 2;
-
-        if (!(this.keyed && showKeys)) {
-            this.drawLabel(angle, true, bold, true, this.radial);
-        }
-    }
-
-    this.drawHighlightCenter = function () {
-        if (!this.canDisplayHistory()) {
-            return;
-        }
-
-        context.lineWidth = highlightLineWidth;
-        context.strokeStyle = 'black';
-        context.fillStyle = "rgba(255, 255, 255, .6)";
-
-        context.fillStyle = 'black';
-        this.drawLabel(3 * Math.PI / 2, true, true, false);
-        context.font = fontNormal;
-    }
-
-    this.drawKey = function (angle, highlight, bold) {
-        var offset = keyOffset();
-        var color;
-        var colorText = this.magnitude == 0 ? 'gray' : 'black';
-        var patternAlpha = this.alphaPattern.end;
-        var boxLeft = imageWidth - keySize - margin;
-        var textY = offset + keySize / 2;
-
-        var label;
-        var keyNameWidth;
-
-        if (this == selectedNode) {
-            color = colorUnclassified;
-            label =
-                this.getUnclassifiedText() +
-                '   ' +
-                this.getUnclassifiedPercentage();
-            keyNameWidth = measureText(label, false);
-        }
-        else {
-            label = this.keyLabel;
-            color = rgbText(this.r.end, this.g.end, this.b.end);
-
-            if (highlight) {
-                if (this.searchResultChildren()) {
-                    label = label
-                        + searchResultString(this.searchResultChildren());
-                }
-
-                keyNameWidth = measureText(label, bold);
-            }
-            else {
-                keyNameWidth = this.keyNameWidth;
-            }
-        }
-
-        var textLeft = boxLeft - keyBuffer - keyNameWidth - fontSize / 2;
-        var labelLeft = textLeft;
-
-        if (labelLeft > keyMinTextLeft - fontSize / 2) {
-            keyMinTextLeft -= fontSize / 2;
-
-            if (keyMinTextLeft < centerX - gRadius + fontSize / 2) {
-                keyMinTextLeft = centerX - gRadius + fontSize / 2;
-            }
-
-            labelLeft = keyMinTextLeft;
-        }
-
-        var lineX = new Array();
-        var lineY = new Array();
-
-        var bendRadius;
-        var keyAngle = Math.atan((textY - centerY) / (labelLeft - centerX));
-        var arcAngle;
-
-        if (keyAngle < 0) {
-            keyAngle += Math.PI;
-        }
-
-        if (keyMinAngle == 0 || angle < keyMinAngle) {
-            keyMinAngle = angle;
-        }
-
-        if (angle > Math.PI && keyMinAngle > Math.PI) {
-            // allow lines to come underneath the chart
-
-            angle -= Math.PI * 2;
-        }
-
-        lineX.push(Math.cos(angle) * gRadius);
-        lineY.push(Math.sin(angle) * gRadius);
-
-        if (angle < keyAngle
-            && textY > centerY
-            + Math.sin(angle) * (gRadius + buffer * (currentKey - 1)
-                / (keys + 1) / 2 + buffer / 2)) {
-            bendRadius = gRadius + buffer - buffer * currentKey
-                / (keys + 1) / 2;
-        }
-        else {
-            bendRadius = gRadius + buffer * currentKey
-                / (keys + 1) / 2 + buffer / 2;
-        }
-
-        var outside =
-            Math.sqrt
-            (
-                Math.pow(labelLeft - centerX, 2) +
-                Math.pow(textY - centerY, 2)
-            ) > bendRadius;
-
-        if (!outside) {
-            arcAngle = Math.asin((textY - centerY) / bendRadius);
-
-            keyMinTextLeft = min(keyMinTextLeft, centerX
-                + bendRadius * Math.cos(arcAngle) - fontSize / 2);
-
-            if (labelLeft < textLeft && textLeft > centerX
-                + bendRadius * Math.cos(arcAngle)) {
-                lineX.push(textLeft - centerX);
-                lineY.push(textY - centerY);
-            }
-        }
-        else {
-            keyMinTextLeft = min(keyMinTextLeft, labelLeft - fontSize / 2);
-
-            if (angle < keyAngle) {
-                // flip everything over y = x
-                //
-                arcAngle = Math.PI / 2 - keyLineAngle
-                (
-                    Math.PI / 2 - angle,
-                    Math.PI / 2 - keyAngle,
-                    bendRadius,
-                    textY - centerY,
-                    labelLeft - centerX,
-                    lineY,
-                    lineX
-                );
-
-            }
-            else {
-                arcAngle = keyLineAngle
-                (
-                    angle,
-                    keyAngle,
-                    bendRadius,
-                    labelLeft - centerX,
-                    textY - centerY,
-                    lineX,
-                    lineY
-                );
-            }
-        }
-
-        if (labelLeft > centerX + bendRadius * Math.cos(arcAngle) ||
-            textY > centerY + bendRadius * Math.sin(arcAngle) + .01)
-//		if ( outside ||  )
-        {
-            lineX.push(labelLeft - centerX);
-            lineY.push(textY - centerY);
-
-            if (textLeft != labelLeft) {
-                lineX.push(textLeft - centerX);
-                lineY.push(textY - centerY);
-            }
-        }
-
-        context.globalAlpha = this.alphaWedge.current();
-
-        if (snapshotMode) {
-            var labelSVG;
-
-            if (this == selectedNode) {
-                labelSVG =
-                    this.getUnclassifiedText() +
-                    spacer() +
-                    this.getUnclassifiedPercentage();
-            }
-            else {
-                labelSVG = this.name + spacer() + this.getPercentage() + '%';
-            }
-
-            svg +=
-                '<rect fill="' + color + '" ' +
-                'x="' + boxLeft + '" y="' + offset +
-                '" width="' + keySize + '" height="' + keySize + '"/>';
-
-            if (patternAlpha) {
-                svg +=
-                    '<rect fill="url(#hiddenPattern)" style="stroke:none" ' +
-                    'x="' + boxLeft + '" y="' + offset +
-                    '" width="' + keySize + '" height="' + keySize + '"/>';
-            }
-
-            svg +=
-                '<path class="line' +
-                (highlight ? ' highlight' : '') +
-                '" d="M ' + (lineX[0] + centerX) + ',' +
-                (lineY[0] + centerY);
-
-            if (angle != arcAngle) {
-                svg +=
-                    ' L ' + (centerX + bendRadius * Math.cos(angle)) + ',' +
-                    (centerY + bendRadius * Math.sin(angle)) +
-                    ' A ' + bendRadius + ',' + bendRadius + ' 0 ' +
-                    '0,' + (angle > arcAngle ? '0' : '1') + ' ' +
-                    (centerX + bendRadius * Math.cos(arcAngle)) + ',' +
-                    (centerY + bendRadius * Math.sin(arcAngle));
-            }
-
-            for (var i = 1; i < lineX.length; i++) {
-                svg +=
-                    ' L ' + (centerX + lineX[i]) + ',' +
-                    (centerY + lineY[i]);
-            }
-
-            svg += '"/>';
-
-            if (highlight) {
-                if (this.searchResultChildren()) {
-                    labelSVG = labelSVG
-                        + searchResultString(this.searchResultChildren());
-                }
-
-                drawBubbleSVG
-                (
-                    boxLeft - keyBuffer - keyNameWidth - fontSize / 2,
-                    textY - fontSize,
-                    keyNameWidth + fontSize,
-                    fontSize * 2,
-                    fontSize,
-                    0
-                );
-
-                if (this.isSearchResult) {
-                    drawSearchHighlights
-                    (
-                        label,
-                        boxLeft - keyBuffer - keyNameWidth,
-                        textY,
-                        0
-                    )
-                }
-            }
-
-            svg += svgText(labelSVG, boxLeft - keyBuffer, textY, 'end', bold,
-                colorText);
-        }
-        else {
-            context.fillStyle = color;
-            context.translate(-centerX, -centerY);
-            context.strokeStyle = 'black';
-            context.globalAlpha = 1;//this.alphaWedge.current();
-
-            context.fillRect(boxLeft, offset, keySize, keySize);
-
-            if (patternAlpha) {
-                context.globalAlpha = patternAlpha;
-                context.fillStyle = hiddenPattern;
-
-                // make clipping box for Firefox performance
-                context.beginPath();
-                context.moveTo(boxLeft, offset);
-                context.lineTo(boxLeft + keySize, offset);
-                context.lineTo(boxLeft + keySize, offset + keySize);
-                context.lineTo(boxLeft, offset + keySize);
-                context.closePath();
-                context.save();
-                context.clip();
-
-                context.fillRect(boxLeft, offset, keySize, keySize);
-                context.fillRect(boxLeft, offset, keySize, keySize);
-
-                context.restore(); // remove clipping region
-            }
-
-            if (highlight) {
-                this.setHighlightStyle();
-                context.fillRect(boxLeft, offset, keySize, keySize);
-            }
-            else {
-                context.lineWidth = thinLineWidth;
-            }
-
-            context.strokeRect(boxLeft, offset, keySize, keySize);
-
-            if (lineX.length) {
-                context.beginPath();
-                context.moveTo(lineX[0] + centerX, lineY[0] + centerY);
-
-                context.arc(centerX, centerY, bendRadius, angle, arcAngle,
-                    angle > arcAngle);
-
-                for (var i = 1; i < lineX.length; i++) {
-                    context.lineTo(lineX[i] + centerX, lineY[i] + centerY);
-                }
-
-                context.globalAlpha = this == selectedNode ?
-                    this.children[0].alphaWedge.current() :
-                    this.alphaWedge.current();
-                context.lineWidth = highlight
-                    ? highlightLineWidth : thinLineWidth;
-                context.stroke();
-                context.globalAlpha = 1;
-            }
-
-            if (highlight) {
-                drawBubbleCanvas
-                (
-                    boxLeft - keyBuffer - keyNameWidth - fontSize / 2,
-                    textY - fontSize,
-                    keyNameWidth + fontSize,
-                    fontSize * 2,
-                    fontSize,
-                    0
-                );
-
-                if (this.isSearchResult) {
-                    drawSearchHighlights
-                    (
-                        label,
-                        boxLeft - keyBuffer - keyNameWidth,
-                        textY,
-                        0
-                    )
-                }
-            }
-
-            drawText(label, boxLeft - keyBuffer, offset + keySize / 2, 0,
-                'end', bold, colorText);
-
-            context.translate(centerX, centerY);
-        }
-
-        currentKey++;
-    }
-
-    this.drawLabel = function (angle, bubble, bold, selected, radial) {
-        if (context.globalAlpha == 0) {
-            return;
-        }
-
-        var innerText;
-        var label;
-        var radius;
-
-        if (radial) {
-            radius = (this.radiusInner.current() + 1) * gRadius / 2;
-        }
-        else {
-            radius = this.labelRadius.current() * gRadius;
-        }
-
-        if (radial && (selected || bubble)) {
-            var percentage = this.getPercentage();
-            innerText = percentage + '%';
-        }
-
-        if
-        (
-            !radial &&
-            this != selectedNode &&
-            !bubble &&
-            (!zoomOut || this != selectedNodeLast)
-        ) {
-            label = this.shortenLabel();
-        }
-        else {
-            label = this.name;
-        }
-
-        var flipped = drawTextPolar
-        (
-            label,
-            innerText,
-            angle,
-            radius,
-            radial,
-            bubble,
-            bold,
-//			this.isSearchResult && this.shouldAddSearchResultsString() && (!selected || this == selectedNode || highlight),
-            this.isSearchResult
-            && (!selected || this == selectedNode || bubble),
-            (this.hideAlone || !selected || this == selectedNode)
-                ? this.searchResultChildren() : 0
-        );
-
-        var depth = this.getDepth() - selectedNode.getDepth() + 1;
-
-        if
-        (
-            !radial &&
-            !bubble &&
-            this != selectedNode &&
-            this.angleEnd.end != this.angleStart.end &&
-            nLabelOffsets[depth - 2] > 2 &&
-            this.labelWidth.current()
-            > (this.angleEnd.end - this.angleStart.end) * Math.abs(radius) &&
-            !(zoomOut && this == selectedNodeLast) &&
-            this.labelRadius.end > 0
-        ) {
-            // name extends beyond wedge; draw tick mark towards the central
-            // radius for easier identification
-
-            var radiusCenter = compress ?
-                (compressedRadii[depth - 1] + compressedRadii[depth - 2]) / 2 :
-                (depth - .5) * nodeRadius;
-
-            if (this.labelRadius.end > radiusCenter) {
-                if (flipped) {
-                    drawTick(radius - tickLength * 1.4, tickLength, angle);
-                }
-                else {
-                    drawTick(radius - tickLength * 1.7, tickLength, angle);
-                }
-            }
-            else {
-                if (flipped) {
-                    drawTick(radius + tickLength * .7, tickLength, angle);
-                }
-                else {
-                    drawTick(radius + tickLength * .4, tickLength, angle);
-                }
-            }
-        }
-    }
-
-    this.drawLines = function (angleStart, angleEnd, radiusInner, drawRadial,
-                               selected) {
-        if (snapshotMode) {
-            if (this != selectedNode) {
-                if (angleEnd == angleStart + Math.PI * 2) {
-                    // fudge to prevent overlap, which causes arc ambiguity
-                    //
-                    angleEnd -= .1 / gRadius;
-                }
-
-                var longArc = angleEnd - angleStart > Math.PI ? 1 : 0;
-
-                var x1 = centerX + radiusInner * Math.cos(angleStart);
-                var y1 = centerY + radiusInner * Math.sin(angleStart);
-
-                var x2 = centerX + gRadius * Math.cos(angleStart);
-                var y2 = centerY + gRadius * Math.sin(angleStart);
-
-                var x3 = centerX + gRadius * Math.cos(angleEnd);
-                var y3 = centerY + gRadius * Math.sin(angleEnd);
-
-                var x4 = centerX + radiusInner * Math.cos(angleEnd);
-                var y4 = centerY + radiusInner * Math.sin(angleEnd);
-
-                if (this.alphaArc.end) {
-                    var dArray =
-                        [
-                            " M ", x4, ",", y4,
-                            " A ", radiusInner, ",", radiusInner, " 0 ",
-                            longArc,
-                            " 0 ", x1, ",", y1
-                        ];
-
-                    svg += '<path class="line" d="' + dArray.join('') + '"/>';
-                }
-
-                if (drawRadial && this.alphaLine.end) {
-                    svg += '<line x1="' + x3 + '" y1="' + y3 + '" x2="' + x4
-                        + '" y2="' + y4 + '"/>';
-                }
-            }
-        }
-        else {
-            context.lineWidth = thinLineWidth;
-            context.strokeStyle = 'black';
-            context.beginPath();
-            context.arc(0, 0, radiusInner, angleStart, angleEnd, false);
-            context.globalAlpha = this.alphaArc.current();
-            context.stroke();
-
-            if (drawRadial) {
-                var x1 = radiusInner * Math.cos(angleEnd);
-                var y1 = radiusInner * Math.sin(angleEnd);
-                var x2 = gRadius * Math.cos(angleEnd);
-                var y2 = gRadius * Math.sin(angleEnd);
-
-                context.beginPath();
-                context.moveTo(x1, y1);
-                context.lineTo(x2, y2);
-
-//				if ( this.getCollapse() )//( selected && this != selectedNode )
-                {
-                    context.globalAlpha = this.alphaLine.current();
-                }
-
-                context.stroke();
-            }
-        }
-    }
-
-    this.drawMap = function (child) {
-        if (this.parent) {
-            this.parent.drawMap(child);
-        }
-
-        if (this.getCollapse() && this != child || this == focusNode) {
-            return;
-        }
-
-        var angleStart =
-            (child.baseMagnitude - this.baseMagnitude) / this.magnitude
-            * Math.PI * 2 + rotationOffset;
-        var angleEnd =
-            (child.baseMagnitude - this.baseMagnitude + child.magnitude) /
-            this.magnitude * Math.PI * 2 +
-            rotationOffset;
-
-        var box = this.getMapPosition();
-
-        context.save();
-        context.fillStyle = 'black';
-        context.textAlign = 'end';
-        context.textBaseline = 'middle';
-
-        var textX = box.x - mapRadius - mapBuffer;
-        var percentage = getPercentage(child.magnitude / this.magnitude);
-
-        var highlight = this == selectedNode || this == highlightedNode;
-
-        if (highlight) {
-            context.font = fontBold;
-        }
-        else {
-            context.font = fontNormal;
-        }
-
-        context.fillText(percentage + '% of', textX, box.y - mapRadius / 3);
-        context.fillText(this.name, textX, box.y + mapRadius / 3);
-
-        if (highlight) {
-            context.font = fontNormal;
-        }
-
-        if (this == highlightedNode && this != selectedNode) {
-            context.fillStyle = 'rgb(245, 245, 245)';
-//			context.fillStyle = 'rgb(200, 200, 200)';
-        }
-        else {
-            context.fillStyle = 'rgb(255, 255, 255)';
-        }
-
-        context.beginPath();
-        context.arc(box.x, box.y, mapRadius, 0, Math.PI * 2, true);
-        context.closePath();
-        context.fill();
-
-        if (this == selectedNode) {
-            context.lineWidth = 1;
-            context.fillStyle = 'rgb(100, 100, 100)';
-        }
-        else {
-            if (this == highlightedNode) {
-                context.lineWidth = .2;
-                context.fillStyle = 'rgb(190, 190, 190)';
-            }
-            else {
-                context.lineWidth = .2;
-                context.fillStyle = 'rgb(200, 200, 200)';
-            }
-        }
-
-        var maxDepth = this.getMaxDepth();
-
-        if (!compress && maxDepth > maxPossibleDepth + this.getDepth() - 1) {
-            maxDepth = maxPossibleDepth + this.getDepth() - 1;
-        }
-
-        if (this.getDepth() < selectedNode.getDepth()) {
-            if (child.getDepth() - 1 >= maxDepth) {
-                maxDepth = child.getDepth();
-            }
-        }
-
-        var radiusInner;
-
-        if (compress) {
-            radiusInner = 0;
-//				Math.atan(child.getDepth() - this.getDepth()) /
-//				Math.PI * 2 * .9;
-        }
-        else {
-            radiusInner =
-                (child.getDepth() - this.getDepth()) /
-                (maxDepth - this.getDepth() + 1);
-        }
-
-        context.stroke();
-        context.beginPath();
-
-        if (radiusInner == 0) {
-            context.moveTo(box.x, box.y);
-        }
-        else {
-            context.arc(box.x, box.y, mapRadius * radiusInner, angleEnd,
-                angleStart, true);
-        }
-
-        context.arc(box.x, box.y, mapRadius, angleStart, angleEnd, false);
-        context.closePath();
-        context.fill();
-
-        if (this == highlightedNode && this != selectedNode) {
-            context.lineWidth = 1;
-            context.stroke();
-        }
-
-        context.restore();
-    }
-
-    this.drawReferenceRings = function (childRadiusInner) {
-        if (snapshotMode) {
-            svg +=
-                '<circle cx="' + centerX + '" cy="' + centerY +
-                '" r="' + childRadiusInner + '"/>';
-            svg +=
-                '<circle cx="' + centerX + '" cy="' + centerY +
-                '" r="' + gRadius + '"/>';
-        }
-        else {
-            context.globalAlpha = 1 - this.alphaLine.current();//this.getUncollapsed().alphaLine.current();
-            context.beginPath();
-            context.arc(0, 0, childRadiusInner, 0, Math.PI * 2, false);
-            context.stroke();
-            context.beginPath();
-            context.arc(0, 0, gRadius, 0, Math.PI * 2, false);
-            context.stroke();
-        }
-    }
-
-    this.getCollapse = function () {
-        return (
-            collapse &&
-            this.collapse &&
-            this.depth != maxAbsoluteDepth
-        );
-    }
-
-    this.getDepth = function () {
-        if (collapse) {
-            return this.depthCollapsed;
-        }
-        else {
-            return this.depth;
-        }
-    };
-
-    this.getHue = function () {
-        return this.hues[currentDataset];
-    };
-
-    this.getMagnitude = function () {
-        return this.attributes[magnitudeIndex][currentDataset];
-    };
-
-    this.getMapPosition = function () {
-        return {
-            x: (details.offsetLeft + details.clientWidth - mapRadius),
-            y: ((focusNode.getDepth() - this.getDepth()) *
-                (mapBuffer + mapRadius * 2) - mapRadius) +
-            details.clientHeight + details.offsetTop
-        };
-    }
-
-    this.getMaxDepth = function (limit) {
-        var max;
-
-        if (collapse) {
-            return this.maxDepthCollapsed;
-        }
-        else {
-            if (this.maxDepth > maxAbsoluteDepth) {
-                return maxAbsoluteDepth;
-            }
-            else {
-                return this.maxDepth;
-            }
-        }
-    }
-
-    this.getData = function (index, summary) {
-        var files = new Array();
-
-        if
-        (
-            this.attributes[index] != null &&
-            this.attributes[index][currentDataset] != null &&
-            this.attributes[index][currentDataset] != ''
-        ) {
-            files.push
-            (
-                document.location +
-                '.files/' +
-                this.attributes[index][currentDataset]
-            );
-        }
-
-        if (summary) {
-            for (var i = 0; i < this.children.length; i++) {
-                files = files.concat(this.children[i].getData(index, true));
-            }
-        }
-
-        return files;
-    }
-
-    this.getList = function (index, summary) {
-        var list;
-
-        if
-        (
-            this.attributes[index] != null &&
-            this.attributes[index][currentDataset] != null
-        ) {
-            list = this.attributes[index][currentDataset];
-        }
-        else {
-            list = new Array();
-        }
-
-        if (summary) {
-            for (var i = 0; i < this.children.length; i++) {
-                list = list.concat(this.children[i].getList(index, true));
-            }
-        }
-
-        return list;
-    }
-
-    this.getParent = function () {
-        // returns parent, accounting for collapsing or 0 if doesn't exist
-
-        var parent = this.parent;
-
-        while (parent != 0 && parent.getCollapse()) {
-            parent = parent.parent;
-        }
-
-        return parent;
-    }
-
-    this.getPercentage = function () {
-        return getPercentage(this.magnitude / selectedNode.magnitude);
-    }
-
-    this.getUnclassifiedPercentage = function () {
-        if (this.children.length) {
-            var lastChild = this.children[this.children.length - 1];
-
-            return getPercentage
-            (
-                (
-                    this.baseMagnitude +
-                    this.magnitude -
-                    lastChild.magnitude -
-                    lastChild.baseMagnitude
-                ) / this.magnitude
-            ) + '%';
-        }
-        else {
-            return '100%';
-        }
-    }
-
-    this.getUnclassifiedText = function () {
-        return '[other ' + this.name + ']';
-    }
-
-    this.getUncollapsed = function () {
-        // recurse through collapsed children until uncollapsed node is found
-
-        if (this.getCollapse()) {
-            return this.children[0].getUncollapsed();
-        }
-        else {
-            return this;
-        }
-    };
-
-    this.hasChildren = function () {
-        return this.depth < maxAbsoluteDepth && this.magnitude
-            && this.children.length;
-    };
-
-    this.hasParent = function (parent) {
-        if (this.parent) {
-            if (this.parent === parent) {
-                return true;
-            }
-            else {
-                return this.parent.hasParent(parent);
-            }
-        }
-        else {
-            return false;
-        }
-    };
-
-    this.isLeaf = function (_recursing) {
-        // Returns true/1 for a real leave, false/0 otherwise, counting the
-        //   non-empty leaves downstream and checking for positive counts.
-        // Param _recursing is an internal auxiliar variable not to be used
-        var leaves = 0;
-        if (this.children.length) {  // Node has children -> recurse
-            for (var i = 0; i < this.children.length; i++) {
-                leaves += this.children[i].isLeaf(true);
-            }
-            if (_recursing) {
-                return leaves ? leaves : +!!this.magnitude;
-                // If this has no leaves but has magnitude, this is a leaf.
-                // NOTE: +!!num is 0 for num=0 and is 1 otherwise
-            } else {
-                return !!this.magnitude && !leaves;
-            }
-        } else {  // Node has not children
-            if (!this.magnitude) {
-                return 0;  // Fake leaf (empty)
-            } else {
-                return 1;  // This is true leaf
-            }
-        }
-    };
-
-    this.maxVisibleDepth = function (maxDepth) {
-        var childInnerRadius;
-        var depth = this.getDepth() - selectedNode.getDepth() + 1;
-        var currentMaxDepth = depth;
-
-        if (this.hasChildren() && depth < maxDepth) {
-            var lastChild = this.children[this.children.length - 1];
-
-            if (lastChild.baseMagnitude + lastChild.magnitude <
-                this.baseMagnitude + this.magnitude) {
-                currentMaxDepth++;
-            }
-
-            if (compress) {
-                childInnerRadius = compressedRadii[depth - 1];
-            }
-            else {
-                childInnerRadius = (depth) / maxDepth;
-            }
-
-            for (var i = 0; i < this.children.length; i++) {
-                if
-                (//true ||
-                    this.children[i].magnitude *
-                    angleFactor *
-                    (childInnerRadius + 1) *
-                    gRadius >=
-                    minWidth()
-                ) {
-                    var childMaxDepth
-                        = this.children[i].maxVisibleDepth(maxDepth);
-
-                    if (childMaxDepth > currentMaxDepth) {
-                        currentMaxDepth = childMaxDepth;
-                    }
-                }
-            }
-        }
-
-        return currentMaxDepth;
-    }
-
-    this.resetLabelWidth = function () {
-        var nameWidthOld = this.nameWidth;
-
-        if (true || !this.radial)//&& fontSize != fontSizeLast )
-        {
-            var dim = context.measureText(this.name);
-            this.nameWidth = dim.width;
-        }
-
-        if (fontSize != fontSizeLast
-            && this.labelWidth.end == nameWidthOld * labelWidthFudge) {
-            // font size changed; adjust start of tween to match
-
-            this.labelWidth.start = this.nameWidth * labelWidthFudge;
-        }
-        else {
-            this.labelWidth.start = this.labelWidth.current();
-        }
-
-        this.labelWidth.end = this.nameWidth * labelWidthFudge;
-    }
-
-    this.restrictLabelWidth = function (width) {
-        if (width < this.labelWidth.end) {
-            this.labelWidth.end = width;
-        }
-    }
-
-    this.search = function () {
-        this.isSearchResult = false;
-        this.searchResults = 0;
-
-        if
-        (
-            !this.getCollapse() &&
-            search.value !== '' &&
-            this.name.toLowerCase().indexOf(search.value.toLowerCase()) !== -1
-        ) {
-            this.isSearchResult = true;
-            this.searchResults = 1;
-            nSearchResults++;
-        }
-
-        for (var i = 0; i < this.children.length; i++) {
-            this.searchResults += this.children[i].search();
-        }
-
-        return this.searchResults;
-    }
-
-    this.searchResultChildren = function () {
-        if (this.isSearchResult) {
-            return this.searchResults - 1;
-        }
-        else {
-            return this.searchResults;
-        }
-    }
-
-    this.setDepth = function (depth, depthCollapsed) {
-        this.depth = depth;
-        this.depthCollapsed = depthCollapsed;
-
-        if
-        (
-            this.children.length === 1 &&
-            //			this.magnitude > 0 &&
-            this.children[0].magnitude === this.magnitude &&
-            (head.children.length > 1 || this.children[0].children.length)
-        ) {
-            this.collapse = true;
-        }
-        else {
-            this.collapse = false;
-            depthCollapsed++;
-        }
-
-        for (var i = 0; i < this.children.length; i++) {
-            this.children[i].setDepth(depth + 1, depthCollapsed);
-        }
-    }
-
-    this.setHighlightStyle = function () {
-        context.lineWidth = highlightLineWidth;
-
-        if (this.hasChildren() || this !== focusNode
-            || this !== highlightedNode) {
-            context.strokeStyle = 'black';
-            context.fillStyle = "rgba(255, 255, 255, .3)";
-        }
-        else {
-            context.strokeStyle = 'rgb(90,90,90)';
-            context.fillStyle = "rgba(155, 155, 155, .3)";
-        }
-    }
-
-    this.setLabelWidth = function (node) {
-        if (!shorten || this.radial) {
-            return; // don't need to set width
-        }
-
-        if (node.hide) {
-            alert('wtf');
-            return;
-        }
-
-        var angle = (this.angleStart.end + this.angleEnd.end) / 2;
-        var a; // angle difference
-
-        if (node == selectedNode) {
-            a = Math.abs(angle - node.angleOther);
-        }
-        else {
-            a = Math.abs(angle
-                - (node.angleStart.end + node.angleEnd.end) / 2);
-        }
-
-        if (a == 0) {
-            return;
-        }
-
-        if (a > Math.PI) {
-            a = 2 * Math.PI - a;
-        }
-
-        if (node.radial || node == selectedNode) {
-            var nodeLabelRadius;
-
-            if (node == selectedNode) {
-                // radial 'other' label
-
-                nodeLabelRadius = (node.children[0].radiusInner.end + 1) / 2;
-            }
-            else {
-                nodeLabelRadius = (node.radiusInner.end + 1) / 2;
-            }
-
-            if (a < Math.PI / 2) {
-                var r = this.labelRadius.end * gRadius + .5 * fontSize
-                var hypotenuse = r / Math.cos(a);
-                var opposite = r * Math.tan(a);
-                var fontRadius = .8 * fontSize;
-
-                if
-                (
-                    nodeLabelRadius * gRadius < hypotenuse &&
-                    this.labelWidth.end / 2 + fontRadius > opposite
-                ) {
-                    this.labelWidth.end = 2 * (opposite - fontRadius);
-                }
-            }
-        }
-        else if
-        (
-            this.labelRadius.end == node.labelRadius.end &&
-            a < Math.PI / 4
-        ) {
-            // same radius with small angle; use circumferential approximation
-
-            var dist = a * this.labelRadius.end * gRadius - fontSize
-                * (1 - a * 4 / Math.PI) * 1.3;
-
-            if (this.labelWidth.end < dist) {
-                node.restrictLabelWidth((dist - this.labelWidth.end / 2) * 2);
-            }
-            else if (node.labelWidth.end < dist) {
-                this.restrictLabelWidth((dist - node.labelWidth.end / 2) * 2);
-            }
-            else {
-                // both labels reach halfway point; restrict both
-
-                this.labelWidth.end = dist;
-                node.labelWidth.end = dist
-            }
-        }
-        else {
-            var r1 = this.labelRadius.end * gRadius;
-            var r2 = node.labelRadius.end * gRadius;
-
-            // first adjust the radii to account for the height of the font
-            // by shifting them toward each other
-            //
-            var fontFudge = .35 * fontSize;
-            //
-            if (this.labelRadius.end < node.labelRadius.end) {
-                r1 += fontFudge;
-                r2 -= fontFudge;
-            }
-            else if (this.labelRadius.end > node.labelRadius.end) {
-                r1 -= fontFudge;
-                r2 += fontFudge;
-            }
-            else {
-                r1 -= fontFudge;
-                r2 -= fontFudge;
-            }
-
-            var r1s = r1 * r1;
-            var r2s = r2 * r2;
-
-            // distance between the centers of the two labels
-            //
-            var dist = Math.sqrt(r1s + r2s - 2 * r1 * r2 * Math.cos(a));
-
-            // angle at our label center between our radius and the line to the
-            // other label center
-            //
-            var b = Math.acos((r1s + dist * dist - r2s) / (2 * r1 * dist));
-
-            // distance from our label center to the intersection of the
-            // two tangents
-            //
-            var l1 = Math.sin(a + b - Math.PI / 2) * dist / Math.sin(Math.PI - a);
-
-            // distance from other label center the the intersection of the
-            // two tangents
-            //
-            var l2 = Math.sin(Math.PI / 2 - b) * dist / Math.sin(Math.PI - a);
-
-            l1 = Math.abs(l1) - .4 * fontSize;
-            l2 = Math.abs(l2) - .4 * fontSize;
-            /*
-			// amount to shorten the distances because of height of the font
-			//
-			var l3 = 0;
-			var fontRadius = fontSize * .55;
-			//
-			if ( l1 < 0 || l2 < 0 )
-			{
-				var l4 = fontRadius / Math.tan(a);
-			l1 = Math.abs(l1);
-			l2 = Math.abs(l2);
-
-				l1 -= l4;
-				l2 -= l4;
-			}
-			else
-			{
-				var c = Math.PI - a;
-
-				l3 = fontRadius * Math.tan(c / 2);
-			}
-*/
-            if (this.labelWidth.end / 2 > l1 && node.labelWidth.end / 2 > l2) {
-                // shorten the farthest one from the intersection
-
-                if (l1 > l2) {
-                    this.restrictLabelWidth(2 * (l1));// - l3 - fontRadius));
-                }
-                else {
-                    node.restrictLabelWidth(2 * (l2));// - l3 - fontRadius));
-                }
-            }
-            /*
-			else if ( this.labelWidth.end / 2 > l1 + l3 && node.labelWidth.end
-			/ 2 > l2 - l3 )
-			{
-				node.restrictLabelWidth(2 * (l2 - l3));
-			}
-			else if ( this.labelWidth.end / 2 > l1 - l3 && node.labelWidth.end
-			/ 2 > l2 + l3 )
-			{
-				this.restrictLabelWidth(2 * (l1 - l3));
-			}*/
-        }
-    }
-
-    this.setMagnitudes = function (baseMagnitude) {
-        this.magnitude = this.getMagnitude();
-        this.baseMagnitude = baseMagnitude;
-
-        for (var i = 0; i < this.children.length; i++) {
-            this.children[i].setMagnitudes(baseMagnitude);
-            baseMagnitude += this.children[i].magnitude;
-        }
-
-        this.maxChildMagnitude = baseMagnitude;
-    }
-
-    this.setMaxDepths = function () {
-        this.maxDepth = this.depth;
-        this.maxDepthCollapsed = this.depthCollapsed;
-
-        for (i in this.children) {
-            var child = this.children[i];
-
-            child.setMaxDepths();
-
-            if (child.maxDepth > this.maxDepth) {
-                this.maxDepth = child.maxDepth;
-            }
-
-            if
-            (
-                child.maxDepthCollapsed > this.maxDepthCollapsed &&
-                (child.depth <= maxAbsoluteDepth || maxAbsoluteDepth == 0)
-            ) {
-                this.maxDepthCollapsed = child.maxDepthCollapsed;
-            }
-        }
-    }
-
-    this.setTargetLabelRadius = function () {
-        var depth = this.getDepth() - selectedNode.getDepth() + 1;
-        var index = depth - 2;
-        var labelOffset = labelOffsets[index];
-
-        if (this.radial) {
-            //this.labelRadius.setTarget((this.radiusInner.end + 1) / 2);
-            var max =
-                depth == maxDisplayDepth ?
-                    1 :
-                    compressedRadii[index + 1];
-
-            this.labelRadius.setTarget((compressedRadii[index] + max) / 2);
-        }
-        else {
-            var radiusCenter;
-            var width;
-
-            if (compress) {
-                if (nLabelOffsets[index] > 1) {
-                    this.labelRadius.setTarget
-                    (
-                        lerp
-                        (
-                            labelOffset + .75,
-                            0,
-                            nLabelOffsets[index] + .5,
-                            compressedRadii[index],
-                            compressedRadii[index + 1]
-                        )
-                    );
-                }
-                else {
-                    this.labelRadius.setTarget((compressedRadii[index]
-                        + compressedRadii[index + 1]) / 2);
-                }
-            }
-            else {
-                radiusCenter =
-                    nodeRadius * (depth - 1) +
-                    nodeRadius / 2;
-                width = nodeRadius;
-
-                this.labelRadius.setTarget
-                (
-                    radiusCenter + width
-                    * ((labelOffset + 1) / (nLabelOffsets[index] + 1) - .5)
-                );
-            }
-        }
-
-        if (!this.hide && !this.keyed && nLabelOffsets[index]) {
-            // check last and first labels in each track for overlap
-
-            for (var i = 0; i < maxDisplayDepth - 1; i++) {
-                for (var j = 0; j <= nLabelOffsets[i]; j++) {
-                    var last = labelLastNodes[i][j];
-                    var first = labelFirstNodes[i][j];
-
-                    if (last) {
-                        if (j == nLabelOffsets[i]) {
-                            // last is radial
-                            this.setLabelWidth(last);
-                        }
-                        else {
-                            last.setLabelWidth(this);
-                        }
-                    }
-
-                    if (first) {
-                        if (j == nLabelOffsets[i]) {
-                            this.setLabelWidth(first);
-                        }
-                        else {
-                            first.setLabelWidth(this);
-                        }
-                    }
-                }
-            }
-
-            if (selectedNode.canDisplayLabelOther) {
-                // in case there is an 'other' label
-                this.setLabelWidth(selectedNode);
-            }
-
-            if (this.radial) {
-                // use the last 'track' of this depth for radial
-
-                labelLastNodes[index][nLabelOffsets[index]] = this;
-
-                if (labelFirstNodes[index][nLabelOffsets[index]] == 0) {
-                    labelFirstNodes[index][nLabelOffsets[index]] = this;
-                }
-            }
-            else {
-                labelLastNodes[index][labelOffset] = this;
-
-                // update offset
-
-                labelOffsets[index] += 1;
-
-                if (labelOffsets[index] > nLabelOffsets[index]) {
-                    labelOffsets[index] -= nLabelOffsets[index];
-
-                    if (!(nLabelOffsets[index] & 1)) {
-                        labelOffsets[index]--;
-                    }
-                }
-                else if (labelOffsets[index] == nLabelOffsets[index]) {
-                    labelOffsets[index] -= nLabelOffsets[index];
-
-                    if (false && !(nLabelOffsets[index] & 1)) {
-                        labelOffsets[index]++;
-                    }
-                }
-
-                if (labelFirstNodes[index][labelOffset] == 0) {
-                    labelFirstNodes[index][labelOffset] = this;
-                }
-            }
-        }
-        else if (this.hide) {
-            this.labelWidth.end = 0;
-        }
-    }
-
-    this.setTargets = function () {
-        if (this == selectedNode) {
-            this.setTargetsSelected
-            (
-                0,
-                1,
-                lightnessBase,
-                false,
-                false
-            );
-            return;
-        }
-
-        var depthRelative = this.getDepth() - selectedNode.getDepth();
-
-        var parentOfSelected = selectedNode.hasParent(this);
-        /*		(
-//			! this.getCollapse() &&
-			this.baseMagnitude <= selectedNode.baseMagnitude &&
-			this.baseMagnitude + this.magnitude >=
-			selectedNode.baseMagnitude + selectedNode.magnitude
-		);
-*/
-        if (parentOfSelected) {
-            this.resetLabelWidth();
-        }
-        else {
-            //context.font = fontNormal;
-            var dim = context.measureText(this.name);
-            this.nameWidth = dim.width;
-            //this.labelWidth.setTarget(this.labelWidth.end);
-            this.labelWidth.setTarget(0);
-        }
-
-        // set angles
-        //
-        if (this.baseMagnitude <= selectedNode.baseMagnitude) {
-            this.angleStart.setTarget(0);
-        }
-        else {
-            this.angleStart.setTarget(Math.PI * 2);
-        }
-        //
-        if
-        (
-            parentOfSelected ||
-            this.baseMagnitude + this.magnitude >=
-            selectedNode.baseMagnitude + selectedNode.magnitude
-        ) {
-            this.angleEnd.setTarget(Math.PI * 2);
-        }
-        else {
-            this.angleEnd.setTarget(0);
-        }
-
-        // children
-        //
-        for (var i = 0; i < this.children.length; i++) {
-            this.children[i].setTargets();
-        }
-
-        if (this.getDepth() <= selectedNode.getDepth()) {
-            // collapse in
-
-            this.radiusInner.setTarget(0);
-
-            if (parentOfSelected) {
-                this.labelRadius.setTarget
-                (
-                    (depthRelative) *
-                    historySpacingFactor * fontSize / gRadius
-                );
-                //this.scale.setTarget(1 - (selectedNode.getDepth()
-                // - this.getDepth()) / 18); // TEMP
-            }
-            else {
-                this.labelRadius.setTarget(0);
-                //this.scale.setTarget(1); // TEMP
-            }
-        }
-        else if (depthRelative + 1 > maxDisplayDepth) {
-            // collapse out
-
-            this.radiusInner.setTarget(1);
-            this.labelRadius.setTarget(1);
-            //this.scale.setTarget(1); // TEMP
-        }
-        else {
-            // don't collapse
-
-            if (compress) {
-                this.radiusInner.setTarget(compressedRadii[depthRelative - 1]);
-            }
-            else {
-                this.radiusInner.setTarget(nodeRadius * (depthRelative));
-            }
-
-            //this.scale.setTarget(1); // TEMP
-
-            if (this == selectedNode) {
-                this.labelRadius.setTarget(0);
-            }
-            else {
-                if (compress) {
-                    this.labelRadius.setTarget
-                    (
-                        (compressedRadii[depthRelative - 1]
-                            + compressedRadii[depthRelative]) / 2
-                    );
-                }
-                else {
-                    this.labelRadius.setTarget(nodeRadius * (depthRelative)
-                        + nodeRadius / 2);
-                }
-            }
-        }
-
-//		this.r.start = this.r.end;
-//		this.g.start = this.g.end;
-//		this.b.start = this.b.end;
-
-        this.r.setTarget(255);
-        this.g.setTarget(255);
-        this.b.setTarget(255);
-
-        this.alphaLine.setTarget(0);
-        this.alphaArc.setTarget(0);
-        this.alphaWedge.setTarget(0);
-        this.alphaPattern.setTarget(0);
-        this.alphaOther.setTarget(0);
-
-        if (parentOfSelected && !this.getCollapse()) {
-            var alpha =
-                (
-                    1 -
-                    (selectedNode.getDepth() - this.getDepth()) /
-                    (Math.floor((compress ? compressedRadii[0] : nodeRadius)
-                        * gRadius / (historySpacingFactor * fontSize) - .5) + 1)
-                );
-
-            if (alpha < 0) {
-                alpha = 0;
-            }
-
-            this.alphaLabel.setTarget(alpha);
-            this.radial = false;
-        }
-        else {
-            this.alphaLabel.setTarget(0);
-        }
-
-        this.hideAlonePrev = this.hideAlone;
-        this.hidePrev = this.hide;
-
-        if (parentOfSelected) {
-            this.hideAlone = false;
-            this.hide = false;
-        }
-
-        if (this.getParent() == selectedNode.getParent()) {
-            this.hiddenEnd = null;
-        }
-
-        this.radialPrev = this.radial;
-    }
-
-    this.setTargetsSelected = function (hueMin, hueMax, lightness, hide,
-                                        nextSiblingHidden) {
-        var collapse = this.getCollapse();
-        var depth = this.getDepth() - selectedNode.getDepth() + 1;
-        var canDisplayChildLabels = false;
-        var lastChild;
-
-        if (this.hasChildren())//&& ! hide )
-        {
-            lastChild = this.children[this.children.length - 1];
-            this.hideAlone = true;
-        }
-        else {
-            this.hideAlone = false;
-        }
-
-        // set child wedges
-        //
-        for (var i = 0; i < this.children.length; i++) {
-            this.children[i].setTargetWedge();
-
-            if
-            (
-                !this.children[i].hide &&
-                (collapse || depth < maxDisplayDepth) &&
-                this.depth < maxAbsoluteDepth
-            ) {
-                canDisplayChildLabels = true;
-                this.hideAlone = false;
-            }
-        }
-
-        if (this == selectedNode || lastChild && lastChild.angleEnd.end
-            < this.angleEnd.end - .01) {
-            this.hideAlone = false;
-        }
-
-        if (this.hideAlonePrev == undefined) {
-            this.hideAlonePrev = this.hideAlone;
-        }
-
-        if (this == selectedNode) {
-            var otherArc =
-                this.children.length ?
-                    angleFactor *
-                    (
-                        this.baseMagnitude + this.magnitude -
-                        lastChild.baseMagnitude - lastChild.magnitude
-                    )
-                    : this.baseMagnitude + this.magnitude;
-            this.canDisplayLabelOther =
-                this.children.length ?
-                    otherArc *
-                    (this.children[0].radiusInner.end + 1) * gRadius >=
-                    minWidth()
-                    : true;
-
-            this.keyUnclassified = false;
-
-            if (this.canDisplayLabelOther) {
-                this.angleOther = Math.PI * 2 - otherArc / 2;
-            }
-            else if (otherArc > 0.0000000001) {
-                this.keyUnclassified = true;
-                keys++;
-            }
-
-            this.angleStart.setTarget(0);
-            this.angleEnd.setTarget(Math.PI * 2);
-
-            if (this.children.length) {
-                this.radiusInner.setTarget(0);
-            }
-            else {
-                this.radiusInner.setTarget(compressedRadii[0]);
-            }
-
-            this.hidePrev = this.hide;
-            this.hide = false;
-            this.hideAlonePrev = this.hideAlone;
-            this.hideAlone = false;
-            this.keyed = false;
-        }
-
-        if (hueMax - hueMin > 1 / 12) {
-            hueMax = hueMin + 1 / 12;
-        }
-
-        // set lightness
-        //
-        if (!(hide || this.hideAlone)) {
-            if (useHue()) {
-                lightness = (lightnessBase + lightnessMax) / 2;
-            }
-            else {
-                lightness = lightnessBase + (depth - 1) * lightnessFactor;
-
-                if (lightness > lightnessMax) {
-                    lightness = lightnessMax;
-                }
-            }
-        }
-
-        if (hide) {
-            this.hide = true;
-        }
-
-        if (this.hidePrev == undefined) {
-            this.hidePrev = this.hide;
-        }
-
-        var hiddenStart = -1;
-        var hiddenHueNumer = 0;
-        var hiddenHueDenom = 0;
-
-
-        if (!this.hide) {
-            this.hiddenEnd = null;
-        }
-
-        for (var i = 0; true; i++) {
-            if (!this.hideAlone && !hide && (i == this.children.length
-                || !this.children[i].hide)) {
-                // reached a non-hidden child or the end; set targets for
-                // previous group of hidden children (if any) using their
-                // average hue
-
-                if (hiddenStart != -1) {
-                    var hiddenHue = hiddenHueDenom ? hiddenHueNumer
-                        / hiddenHueDenom : hueMin;
-
-                    for (var j = hiddenStart; j < i; j++) {
-                        this.children[j].setTargetsSelected
-                        (
-                            hiddenHue,
-                            null,
-                            lightness,
-                            false,
-                            j < i - 1
-                        );
-
-                        this.children[j].hiddenEnd = null;
-                    }
-
-                    this.children[hiddenStart].hiddenEnd = i - 1;
-                }
-            }
-
-            if (i == this.children.length) {
-                break;
-            }
-
-            var child = this.children[i];
-            var childHueMin;
-            var childHueMax;
-
-            if (this.magnitude > 0 && !this.hide && !this.hideAlone) {
-                if (useHue()) {
-                    childHueMin = child.hues[currentDataset];
-                }
-                else if (this == selectedNode) {
-                    var min = 0.0;
-                    var max = 1.0;
-
-                    if (this.children.length > 6) {
-                        childHueMin = lerp((1 - Math.pow(
-                            1 - i / this.children.length, 1.4)) * .95,
-                            0, 1, min, max);
-                        childHueMax = lerp((1 - Math.pow(
-                            1 - (i + .55) / this.children.length, 1.4)) * .95,
-                            0, 1, min, max);
-                    }
-                    else {
-                        childHueMin = lerp(i / this.children.length, 0, 1,
-                            min, max);
-                        childHueMax = lerp((i + .55) / this.children.length,
-                            0, 1, min, max);
-                    }
-                }
-                else {
-                    childHueMin = lerp
-                    (
-                        child.baseMagnitude,
-                        this.baseMagnitude,
-                        this.baseMagnitude + this.magnitude,
-                        hueMin,
-                        hueMax
-                    );
-                    childHueMax = lerp
-                    (
-                        child.baseMagnitude + child.magnitude * .99,
-                        this.baseMagnitude,
-                        this.baseMagnitude + this.magnitude,
-                        hueMin,
-                        hueMax
-                    );
-                }
-            }
-            else {
-                childHueMin = hueMin;
-                childHueMax = hueMax;
-            }
-
-            if (!this.hideAlone && !hide && !this.hide && child.hide) {
-                if (hiddenStart == -1) {
-                    hiddenStart = i;
-                }
-
-                if (useHue()) {
-                    hiddenHueNumer += childHueMin * child.magnitude;
-                    hiddenHueDenom += child.magnitude;
-                }
-                else {
-                    hiddenHueNumer += childHueMin;
-                    hiddenHueDenom++;
-                }
-            }
-            else {
-                hiddenStart = -1;
-
-                this.children[i].setTargetsSelected
-                (
-                    childHueMin,
-                    childHueMax,
-                    lightness,
-                    hide || this.keyed || this.hideAlone
-                    || this.hide && !collapse,
-                    false
-                );
-            }
-        }
-
-        if (this.hue && this.magnitude) {
-            this.hue.setTarget(this.hues[currentDataset]);
-
-            if (this.attributes[magnitudeIndex][lastDataset] == 0) {
-                this.hue.start = this.hue.end;
-            }
-        }
-
-        this.radialPrev = this.radial;
-
-        if (this == selectedNode) {
-            this.resetLabelWidth();
-            this.labelWidth.setTarget(this.nameWidth * labelWidthFudge);
-            this.alphaWedge.setTarget(0);
-            this.alphaLabel.setTarget(1);
-            this.alphaOther.setTarget(1);
-            this.alphaArc.setTarget(0);
-            this.alphaLine.setTarget(0);
-            this.alphaPattern.setTarget(0);
-            this.r.setTarget(255);
-            this.g.setTarget(255);
-            this.b.setTarget(255);
-            this.radial = false;
-            this.labelRadius.setTarget(0);
-        }
-        else {
-            var rgb = hslToRgb
-            (
-                hueMin,
-                saturation,
-                lightness
-            );
-
-            this.r.setTarget(rgb.r);
-            this.g.setTarget(rgb.g);
-            this.b.setTarget(rgb.b);
-            this.alphaOther.setTarget(0);
-
-            this.alphaWedge.setTarget(1);
-
-            if (this.hide || this.hideAlone) {
-                this.alphaPattern.setTarget(1);
-            }
-            else {
-                this.alphaPattern.setTarget(0);
-            }
-
-            // set radial
-            //
-            if (!(hide || this.hide))//&& ! this.keyed )
-            {
-                if (this.hideAlone) {
-                    this.radial = true;
-                }
-                else if (false && canDisplayChildLabels) {
-                    this.radial = false;
-                }
-                else {
-                    this.radial = true;
-
-                    if (this.hasChildren() && depth < maxDisplayDepth) {
-                        var lastChild = this.children[this.children.length - 1];
-
-                        if
-                        (
-                            lastChild.angleEnd.end == this.angleEnd.end ||
-                            (
-                                (this.angleStart.end + this.angleEnd.end) / 2 -
-                                lastChild.angleEnd.end
-                            ) * (this.radiusInner.end + 1) * gRadius * 2 <
-                            minWidth()
-                        ) {
-                            this.radial = false;
-                        }
-                    }
-                }
-            }
-
-            // set alphaLabel
-            //
-            if
-            (
-                collapse ||
-                hide ||
-                this.hide ||
-                this.keyed ||
-                depth > maxDisplayDepth ||
-                !this.canDisplayDepth()
-            ) {
-                this.alphaLabel.setTarget(0);
-            }
-            else {
-                if
-                (
-                    (this.radial || nLabelOffsets[depth - 2])
-                ) {
-                    this.alphaLabel.setTarget(1);
-                }
-                else {
-                    this.alphaLabel.setTarget(0);
-
-                    if (this.radialPrev) {
-                        this.alphaLabel.start = 0;
-                    }
-                }
-            }
-
-            // set alphaArc
-            //
-            if
-            (
-                collapse ||
-                hide ||
-                depth > maxDisplayDepth ||
-                !this.canDisplayDepth()
-            ) {
-                this.alphaArc.setTarget(0);
-            }
-            else {
-                this.alphaArc.setTarget(1);
-            }
-
-            // set alphaLine
-            //
-            if
-            (
-                hide ||
-                this.hide && nextSiblingHidden ||
-                depth > maxDisplayDepth ||
-                !this.canDisplayDepth()
-            ) {
-                this.alphaLine.setTarget(0);
-            }
-            else {
-                this.alphaLine.setTarget(1);
-            }
-
-            //if (  ! this.radial )
-            {
-                this.resetLabelWidth();
-            }
-
-            // set labelRadius target
-            //
-            if (collapse) {
-                this.labelRadius.setTarget(this.radiusInner.end);
-            }
-            else {
-                if (depth > maxDisplayDepth || !this.canDisplayDepth()) {
-                    this.labelRadius.setTarget(1);
-                }
-                else {
-                    this.setTargetLabelRadius();
-                }
-            }
-        }
-    }
-
-    this.setTargetWedge = function () {
-        var depth = this.getDepth() - selectedNode.getDepth() + 1;
-
-        // set angles
-        //
-        var baseMagnitudeRelative = this.baseMagnitude
-            - selectedNode.baseMagnitude;
-        //
-        this.angleStart.setTarget(baseMagnitudeRelative * angleFactor);
-        this.angleEnd.setTarget((baseMagnitudeRelative + this.magnitude)
-            * angleFactor);
-
-        // set radiusInner
-        //
-        if (depth > maxDisplayDepth || !this.canDisplayDepth()) {
-            this.radiusInner.setTarget(1);
-        }
-        else {
-            if (compress) {
-                this.radiusInner.setTarget(compressedRadii[depth - 2]);
-            }
-            else {
-                this.radiusInner.setTarget(nodeRadius * (depth - 1));
-            }
-        }
-
-        if (this.hide != undefined) {
-            this.hidePrev = this.hide;
-        }
-
-        if (this.hideAlone != undefined) {
-            this.hideAlonePrev = this.hideAlone;
-        }
-
-        // set hide
-        //
-        if
-        (
-            (this.angleEnd.end - this.angleStart.end) *
-            (this.radiusInner.end * gRadius + gRadius) <
-            minWidth()
-        ) {
-            if (depth == 2 && !this.getCollapse() && this.depth
-                <= maxAbsoluteDepth) {
-                this.keyed = true;
-                keys++;
-                this.hide = false;
-
-                var percentage = this.getPercentage();
-                this.keyLabel = this.name + '   ' + percentage + '%';
-                var dim = context.measureText(this.keyLabel);
-                this.keyNameWidth = dim.width;
-            }
-            else {
-                this.keyed = false;
-                this.hide = depth > 2;
-            }
-        }
-        else {
-            this.keyed = false;
-            this.hide = false;
-        }
-    }
-
-    this.shortenLabel = function () {
-        var label = this.name;
-
-        var labelWidth = this.nameWidth;
-        var maxWidth = this.labelWidth.current();
-        var minEndLength = 0;
-
-        if (labelWidth > maxWidth && label.length > minEndLength * 2) {
-            var endLength =
-                Math.floor((label.length - 1) * maxWidth / labelWidth / 2);
-
-            if (endLength < minEndLength) {
-                endLength = minEndLength;
-            }
-
-            return (
-                label.substring(0, endLength) +
-                '...' +
-                label.substring(label.length - endLength));
-        }
-        else {
-            return label;
-        }
-    }
-
-    /*	this.shouldAddSearchResultsString = function()
-	{
-		if ( this.isSearchResult )
-		{
-			return this.searchResults > 1;
-		}
-		else
-		{
-			return this.searchResults > 0;
-		}
-	}
-*/
-    this.sort = function () {
-        this.children.sort(function (a, b) {
-            if (sortByScoreCheckBox.checked) {
-                return b.getHue() - a.getHue()
-            } else {
-                return b.getMagnitude() - a.getMagnitude()
-            }
-        });
-
-        for (var i = 0; i < this.children.length; i++) {
-            this.children[i].sort();
-        }
-    }
-}
-
-var options;
-
-function addOptionElement(position, innerHTML, title, padding) {
-    var div = document.createElement("div");
-//	div.style.position = 'absolute';
-//	div.style.top = position + 'px';
-    div.innerHTML = innerHTML;
-//	div.style.display = 'block';
-    div.style.padding = padding || '2px';
-
-    if (title) {
-        div.title = title;
-    }
-
-    options.appendChild(div);
-    var height = 0;//div.clientHeight;
-    return position + height;
-}
-
-function addOptionElements(hueName, hueDefault) {
-    options = document.createElement('div');
-    options.style.position = 'absolute';
-    options.style.top = '0px';
-    options.addEventListener('mousedown', function (e) {
-        mouseClick(e)
-    }, false);
-//	options.onmouseup = function(e) {mouseUp(e)}
-    document.body.appendChild(options);
-
-    if (chart === ChartEnum.TAXOMIC) {
-        document.body.style.font = '11px Ubuntu';
-    } else {
-        document.body.style.font = '12px Saira Semi Condensed';
-    }
-    var position = 5;
-
-    function logLoaded(fontFace) {
-        console.log(fontFace.family, 'loaded successfully.');
-    }
-
-// Loading FontFaces via JavaScript is alternative to using CSS's @font-face rule.
-//     var ubuntuMonoFontFace = new FontFace('Ubuntu Mono', 'url(https://fonts.gstatic.com/s/ubuntumono/v7/KFOjCneDtsqEr0keqCMhbCc6CsTYl4BO.woff2)');
-//     document.fonts.add(ubuntuMonoFontFace);
-//     ubuntuMonoFontFace.loaded.then(logLoaded);
-//     var oxygenFontFace = new FontFace('Oxygen', 'url(https://fonts.gstatic.com/s/oxygen/v5/qBSyz106i5ud7wkBU-FrPevvDin1pK8aKteLpeZ5c0A.woff2)');
-//     document.fonts.add(oxygenFontFace);
-//     oxygenFontFace.loaded.then(logLoaded);
-    var oxygenMonoFontFace = new FontFace('Oxygen Mono', 'url(https://fonts.gstatic.com/s/oxygenmono/v5/h0GsssGg9FxgDgCjLeAd7hjYx-6tPUUv.woff2)');
-    document.fonts.add(oxygenMonoFontFace);
-    oxygenMonoFontFace.loaded.then(logLoaded);
-    var sairaCondensedFontFace = new FontFace('Saira Condensed', 'url(https://fonts.gstatic.com/s/sairacondensed/v3/EJROQgErUN8XuHNEtX81i9TmEkrvoutF2o-Srg.woff2)');
-    document.fonts.add(sairaCondensedFontFace);
-    sairaCondensedFontFace.loaded.then(logLoaded);
-    var sairaSemiCondensedFontFace = new FontFace('Saira Semi Condensed', 'url(https://fonts.gstatic.com/s/sairasemicondensed/v3/U9MD6c-2-nnJkHxyCjRcnMHcWVWV1cWRRX8MaOY8q3T_.woff2)');
-    document.fonts.add(sairaSemiCondensedFontFace);
-    sairaSemiCondensedFontFace.loaded.then(logLoaded);
-
-// The .ready promise resolves when all fonts that have been previously requested
-// are loaded and layout operations are complete.
-    document.fonts.ready.then(function () {
-        console.log('There are', document.fonts.size, 'FontFaces loaded.\n');
-
-        // document.fonts has a Set-like interface. Here, we're iterating over its values.
-        for (var fontFace of document.fonts.values()) {
-            console.log('FontFace:');
-            for (var property in fontFace) {
-                console.log('  ' + property + ': ' + fontFace[property]);
-            }
-            console.log('\n');
-        }
-    });
-
-    details = document.createElement('div');
-    details.style.position = 'absolute';
-    details.style.top = '1%';
-    details.style.right = '2%';
-    details.style.textAlign = 'right';
-    document.body.insertBefore(details, canvas);
-//<div id="details" style="position:absolute;top:1%;right:2%;text-align:right;">
-
-    details.innerHTML = '\
-<span id="detailsName" style="font-weight:bold"></span>&nbsp;\
-<input type="button" id="detailsExpand" onclick="expand(focusNode);"\
-value="&harr;" title="Expand this wedge to become the new focus of the chart"/><br/>\
-<div id="detailsInfo" style="float:right"></div>';
-
-    keyControl = document.createElement('input');
-    keyControl.type = 'button';
-    keyControl.value = showKeys ? 'x' : '…';
-    keyControl.style.position = '';
-    keyControl.style.position = 'fixed';
-    keyControl.style.visibility = 'hidden';
-
-    document.body.insertBefore(keyControl, canvas);
-
-    var logoElement = document.getElementById('logo');
-
-    if (logoElement) {
-        logoImage = logoElement.src;
-    }
-    else {
-        logoImage = 'https://raw.githubusercontent.com/khyox/recentrifuge/master/recentrifuge/img/logo-rcf-mini.uri';
-    }
-    var placeholderTit;
-    if (chart === ChartEnum.GENOMIC) {
-        placeholderTit = "Complete or partial function, process, component...";
-    } else {
-        placeholderTit = "Taxon scientific name, complete or partial name...";
-    }
-    position = addOptionElement
-    (
-        position,
-        '<a style="margin:2px" target="_blank" href="http://www.recentrifuge.org"><img style="vertical-align:middle;width:136px;height:32px;padding:8px 10px 6px 10px" src="' + logoImage + '"/></a><input type="button" id="back" value="&larr;" title="Go back (Shortcut: &larr;)"/>\
-<input type="button" id="forward" value="&rarr;" title="Go forward (Shortcut: &rarr;)"/> \
-&nbsp;&nbsp;&nbsp;Search: <input type="text" placeholder="' + placeholderTit + '" size="45" id="search"/>\
-<input id="searchClear" type="button" value="x" onclick="clearSearch()"/> \
-<span id="searchResults"></span>'
-    );
-
-    if (datasets > 1) {
-        var size = datasets < DATASET_MAX_SIZE ? datasets : DATASET_MAX_SIZE;
-
-        var select =
-            '<table style="border-collapse:collapse;margin-left:10px"><tr><td style="padding:0px">' +
-            '<select id="datasets" style="min-width:100px" size="' + size + '" onchange="onDatasetChange()">';
-
-        for (var i = 0; i < datasetNames.length; i++) {
-            select += '<option>' + datasetNames[i] + '</option>';
-        }
-        select +=
-            '</select></td><td style="vertical-align:top;padding:2px;">' +
-            '<input style="display:block" title="Previous dataset ' +
-            '(Shortcut: &uarr;)" id="prevDataset" type="button"' +
-            ' value="&uarr;" onclick="prevDataset()" disabled="true"/>' +
-            '<input title="Next dataset (Shortcut: &darr;)" ' +
-            'id="nextDataset" type="button" value="&darr;" ' +
-            'onclick="nextDataset()"/><br/></td>' +
-            '<td style="vertical-align:top;padding:2px;">' +
-            '<input style="display:block" ' +
-            'title="Switch to the prior dataset that was viewed ' +
-            '(Shortcut: TAB)" id="lastDataset" type="button" ' +
-            'style="font:11px Ubuntu" value="prior" ' +
-            'onclick="selectLastDataset()"/>' +
-            '<select id="ranks" onchange="onRankChange()" ' +
-            'title="Filter samples by taxonomic rank">' +
-            '<option value="SUMMARY">SUMMARY</option>' +
-            '<option value="strain">strain</option>' +
-            '<option value="species">species</option>' +
-            '<option value="genus">genus</option>' +
-            '<option value="family">family</option>' +
-            '<option value="order">order</option>' +
-            '<option value="class">class</option>' +
-            '<option value="phylum">phylum</option>' +
-            '<option value="kingdom">kingdom</option>' +
-            '<option value="domain">domain</option>' +
-            '<option value="ALL">ALL</option>' +
-            '<option value="NONE">NONE</option>' +
-            '</select></td></tr></table>';
-
-        position = addOptionElement(position + 5, select);
-
-        datasetDropDown = document.getElementById('datasets');
-        datasetButtonLast = document.getElementById('lastDataset');
-        datasetButtonPrev = document.getElementById('prevDataset');
-        datasetButtonNext = document.getElementById('nextDataset');
-        rankDropDown = document.getElementById('ranks');
-        if (chart === ChartEnum.GENOMIC) {
-            for (i = 1; i < 10; i++) {
-                rankDropDown.remove(1);  // Remove taxonomic ranks from options
-            }
-            datasetDropDown.style.color='#FFFFFF'
-            datasetDropDown.style.backgroundColor='#555555'  // #B20DFF22'
-        }
-        position += datasetDropDown.clientHeight;
-    }
-
-    position = addOptionElement
-    (
-        position + 5,
-        '<input type="button" id="maxAbsoluteDepthDecrease" style="margin:1px 4px 0 10px" value="-"/>\
-<span id="maxAbsoluteDepth"></span>\
-&nbsp;<input type="button" id="maxAbsoluteDepthIncrease" style="margin:2px 1px 0 2px" value="+"/> Max depth',
-        'Maximum depth to display, counted from the top level \
-and including collapsed wedges.'
-    );
-
-    position = addOptionElement
-    (
-        position,
-        '<input type="button" id="fontSizeDecrease" style="margin:0 4px 0 10px" value="-"/>\
-<span id="fontSize"></span>\
-&nbsp;<input type="button" id="fontSizeIncrease" style="margin:0 2px 0 2px" value="+"/> Font size'
-    );
-
-    position = addOptionElement
-    (
-        position,
-        '<input type="button" id="radiusDecrease" style="margin:0 4px 0 10px" value="-"/>\
-<input type="button" id="radiusIncrease" style="margin:0 2px 0 1px" value="+"/> Chart size'
-    );
-
-    position = addOptionElement
-    (
-        position,
-        '<input type="button" id="bkgBrightDecrease" style="margin:0 4px 5px 10px" value="-"/>\
-<input type="button" id="bkgBrightIncrease" style="margin:0 2px 5px 1px" value="+"/> Bkg bright'
-    );
-
-    if (hueName) {
-        hueDisplayName = attributes[attributeIndex(hueName)].displayName;
-
-        position = addOptionElement
-        (
-            position + 5,
-            '<input type="checkbox" id="useHue" style="float:left; ' +
-            'margin:1px 4px 0 12px"/><div>Color by ' + hueDisplayName +
-            '</div>'
-        );
-
-        useHueCheckBox = document.getElementById('useHue');
-        useHueCheckBox.checked = hueDefault;
-        useHueCheckBox.onclick = handleResize;
-        useHueCheckBox.onmousedown = suppressEvent;
-
-        position = addOptionElement
-        (
-            position,
-            '<input type="checkbox" id="sortByScore"/> Use to sort',
-            'Activates sorting the taxa by this magnitude',
-            '0px 2px 2px 25px'
-        );
-
-        sortByScoreCheckBox = document.getElementById('sortByScore');
-        sortByScoreCheckBox.onclick = onSortChange;
-        sortByScoreCheckBox.onmousedown = suppressEvent;
-    }
-
-    position = addOptionElement
-    (
-        position,
-        '<input type="checkbox" id="collapse" style="margin:4px 4px 0 12px" ' +
-        'checked="checked"/>Collapse',
-        'Collapse wedges that are redundant (entirely composed of another ' +
-        'wedge). Also affects score navigation, restricting to lowest level.'
-    );
-
-    /*
-	position = addOptionElement
-	(
-		position,
-		'&nbsp;<input type="checkbox" id="shorten" checked="checked" />Shorten labels</div>',
-		'Prevent labels from overlapping by shortening them'
-	);
-
-	position = addOptionElement
-	(
-		position,
-		'&nbsp;<input type="checkbox" id="compress" checked="checked" />Compress',
-		'Compress wedges if needed to show the entire depth'
-	);
-    */
-
-    position = addOptionElement
-    (
-        position,
-        '<input type="button" id="snapshot" style="margin:5px 2px 0 10px"\
-         value="Snapshot" title="Render the current view as SVG (Scalable \
-Vector Graphics), a vectorial publication-quality format that can be saved or \
-printed as PDF"/> <input type="button" id="help" value="?"\
-    onclick="window.open(\'https://github.com/khyox/recentrifuge/wiki\',\
-     \'help\')" title="Help"/>');
-
-    position = addOptionElement
-    (
-        position + 5,
-        '<input type="button" id="linkButton" style="margin:5px 2px 0 10px"  value="Link"/>\
-<input type="text" size="30" id="linkText"/>',
-        'Show a link to this view that can be copied for bookmarking or sharing'
-    );
-}
-
-function arrow(angleStart, angleEnd, radiusInner) {
-    if (context.globalAlpha == 0) {
-        return;
-    }
-
-    var angleCenter = (angleStart + angleEnd) / 2;
-    var radiusArrowInner = radiusInner - gRadius / 10;//nodeRadius * gRadius;
-    var radiusArrowOuter = gRadius * 1.1;//(1 + nodeRadius);
-    var radiusArrowCenter = (radiusArrowInner + radiusArrowOuter) / 2;
-    var pointLength = (radiusArrowOuter - radiusArrowInner) / 5;
-
-    context.fillStyle = highlightFill;
-    context.lineWidth = highlightLineWidth;
-
-    // First, mask out the first half of the arrow.  This will prevent the tips
-    // from superimposing if the arrow goes most of the way around the circle.
-    // Masking is done by setting the clipping region to the inverse of the
-    // half-arrow, which is defined by cutting the half-arrow out of a large
-    // rectangle
-    //
-    context.beginPath();
-    context.arc(0, 0, radiusInner, angleCenter, angleEnd, false);
-    context.lineTo
-    (
-        radiusArrowInner * Math.cos(angleEnd),
-        radiusArrowInner * Math.sin(angleEnd)
-    );
-    context.lineTo
-    (
-        radiusArrowCenter * Math.cos(angleEnd)
-        - pointLength * Math.sin(angleEnd),
-        radiusArrowCenter * Math.sin(angleEnd)
-        + pointLength * Math.cos(angleEnd)
-    );
-    context.lineTo
-    (
-        radiusArrowOuter * Math.cos(angleEnd),
-        radiusArrowOuter * Math.sin(angleEnd)
-    );
-    context.arc(0, 0, gRadius, angleEnd, angleCenter, true);
-    context.closePath();
-    context.moveTo(-imageWidth, -imageHeight);
-    context.lineTo(imageWidth, -imageHeight);
-    context.lineTo(imageWidth, imageHeight);
-    context.lineTo(-imageWidth, imageHeight);
-    context.closePath();
-    context.save();
-    context.clip();
-
-    // Next, draw the other half-arrow with the first half masked out
-    //
-    context.beginPath();
-    context.arc(0, 0, radiusInner, angleCenter, angleStart, true);
-    context.lineTo
-    (
-        radiusArrowInner * Math.cos(angleStart),
-        radiusArrowInner * Math.sin(angleStart)
-    );
-    context.lineTo
-    (
-        radiusArrowCenter * Math.cos(angleStart)
-        + pointLength * Math.sin(angleStart),
-        radiusArrowCenter * Math.sin(angleStart)
-        - pointLength * Math.cos(angleStart)
-    );
-    context.lineTo
-    (
-        radiusArrowOuter * Math.cos(angleStart),
-        radiusArrowOuter * Math.sin(angleStart)
-    );
-    context.arc(0, 0, gRadius, angleStart, angleCenter, false);
-    context.fill();
-    context.stroke();
-
-    // Finally, remove the clipping region and draw the first half-arrow.  This
-    // half is extended slightly to fill the seam.
-    //
-    context.restore();
-    context.beginPath();
-    context.arc(0, 0, radiusInner, angleCenter
-        - 2 / (2 * Math.PI * radiusInner), angleEnd, false);
-    context.lineTo
-    (
-        radiusArrowInner * Math.cos(angleEnd),
-        radiusArrowInner * Math.sin(angleEnd)
-    );
-    context.lineTo
-    (
-        radiusArrowCenter * Math.cos(angleEnd)
-        - pointLength * Math.sin(angleEnd),
-        radiusArrowCenter * Math.sin(angleEnd)
-        + pointLength * Math.cos(angleEnd)
-    );
-    context.lineTo
-    (
-        radiusArrowOuter * Math.cos(angleEnd),
-        radiusArrowOuter * Math.sin(angleEnd)
-    );
-    context.arc(0, 0, gRadius, angleEnd, angleCenter - 2
-        / (2 * Math.PI * gRadius), true);
-    context.fill();
-    context.stroke();
-}
-
-function attributeIndex(aname) {
-    for (var i = 0; i < attributes.length; i++) {
-        if (aname == attributes[i].name) {
-            return i;
-        }
-    }
-
-    return null;
-}
-
-function bkgBrightDecrease() {
-    var bkgBrightInt = parseInt(bkgBright, 16)
-    if (bkgBrightInt > parseInt('555555', 16)) {
-        bkgBright = (bkgBrightInt - 0x111111).toString(16)
-        document.body.style.backgroundColor = '#' + bkgBright
-        updateViewNeeded = true;
-    }
-}
-
-function bkgBrightIncrease() {
-    var bkgBrightInt = parseInt(bkgBright, 16)
-    if (bkgBrightInt < parseInt('ffffff', 16)) {
-        bkgBright = (bkgBrightInt + 0x111111).toString(16)
-        document.body.style.backgroundColor = '#' + bkgBright
-        updateViewNeeded = true;
-    }
-}
-
-function checkHighlight() {
-    var lastHighlightedNode = highlightedNode;
-    var lastHighlightingHidden = highlightingHidden;
-
-    highlightedNode = selectedNode;
-    resetKeyOffset();
-
-    if (progress == 1) {
-        selectedNode.checkHighlight();
-        if (selectedNode.getParent()) {
-            selectedNode.getParent().checkHighlightCenter();
-        }
-
-        focusNode.checkHighlightMap();
-    }
-
-    if (highlightedNode != selectedNode) {
-        if (highlightedNode == focusNode) {
-//			canvas.style.display='none';
-//			window.resizeBy(1,0);
-//			canvas.style.cursor='ew-resize';
-//			window.resizeBy(-1,0);
-//			canvas.style.display='inline';
-        }
-        else {
-//			canvas.style.cursor='pointer';
-        }
-    }
-    else {
-//		canvas.style.cursor='auto';
-    }
-
-    if
-    (
-        (
-            true ||
-            highlightedNode != lastHighlightedNode ||
-            highlightingHidden != highlightingHiddenLast
-        ) &&
-        progress == 1
-    ) {
-        draw(); // TODO: handle in update()
-    }
-}
-
-function checkSelectedCollapse() {
-    var newNode = selectedNode;
-
-    while (newNode.getCollapse()) {
-        newNode = newNode.children[0];
-    }
-
-    if (newNode.children.length == 0 && newNode.getParent()) {
-        newNode = newNode.getParent();
-    }
-
-    if (newNode != selectedNode) {
-        selectNode(newNode);
-    }
-}
-
-function clearSearch() {
-    if (search.value != '') {
-        search.value = '';
-        nodesIndex = undefined;
-        onSearchChange();
-    }
-}
-
-function createSVG() {
-    svgNS = "http://www.w3.org/2000/svg";
-    var SVG = {};
-    SVG.xlinkns = "http://www.w3.org/1999/xlink";
-
-    var newSVG = document.createElementNS(svgNS, "svg:svg");
-
-    newSVG.setAttribute("id", "canvas");
-    // How big is the canvas in pixels
-    newSVG.setAttribute("width", '100%');
-    newSVG.setAttribute("height", '100%');
-    // Set the coordinates used by drawings in the canvas
-//	newSVG.setAttribute("viewBox", "0 0 " + imageWidth + " " + imageHeight);
-    // Define the XLink namespace that SVG uses
-    newSVG.setAttributeNS
-    (
-        "http://www.w3.org/2000/xmlns/",
-        "xmlns:xlink",
-        SVG.xlinkns
-    );
-
-    return newSVG;
-}
-
-function degrees(radians) {
-    return radians * 180 / Math.PI;
-}
-
-function draw() {
-    tweenFrames++;
-    //resize();
-//	context.fillRect(0, 0, imageWidth, imageHeight);
-    context.clearRect(0, 0, imageWidth, imageHeight);
-
-    context.font = fontNormal;
-    context.textBaseline = 'middle';
-
-    //context.strokeStyle = 'rgba(0, 0, 0, 0.3)';
-    context.translate(centerX, centerY);
-
-    resetKeyOffset();
-
-    head.draw(false, false); // draw pie slices
-    head.draw(true, false); // draw labels
-
-    var pathRoot = selectedNode;
-
-    if (focusNode != 0 && focusNode != selectedNode) {
-        context.globalAlpha = 1;
-        focusNode.drawHighlight(true);
-        pathRoot = focusNode;
-    }
-
-    if
-    (
-        highlightedNode &&
-        highlightedNode.getDepth() >= selectedNode.getDepth() &&
-        highlightedNode != focusNode
-    ) {
-        if
-        (
-            progress == 1 &&
-            highlightedNode != selectedNode &&
-            (
-                highlightedNode != focusNode ||
-                focusNode.children.length > 0
-            )
-        ) {
-            context.globalAlpha = 1;
-            highlightedNode.drawHighlight(true);
-        }
-
-        //pathRoot = highlightedNode;
-    }
-    else if
-    (
-        progress == 1 &&
-        highlightedNode.getDepth() < selectedNode.getDepth()
-    ) {
-        context.globalAlpha = 1;
-        highlightedNode.drawHighlightCenter();
-    }
-
-    if (quickLook && false) // TEMP
-    {
-        context.globalAlpha = 1 - progress / 2;
-        selectedNode.drawHighlight(true);
-    }
-    else if (progress < 1)//&& zoomOut() )
-    {
-        if (!zoomOut)//() )
-        {
-            context.globalAlpha = selectedNode.alphaLine.current();
-            selectedNode.drawHighlight(true);
-        }
-        else if (selectedNodeLast) {
-            context.globalAlpha = 1 - 4 * Math.pow(progress - .5, 2);
-            selectedNodeLast.drawHighlight(false);
-        }
-    }
-
-    drawDatasetName();
-
-    //drawHistory();
-
-    context.translate(-centerX, -centerY);
-    context.globalAlpha = 1;
-
-    mapRadius =
-        (imageHeight / 2 - details.clientHeight - details.offsetTop) /
-        (pathRoot.getDepth() - 1) * 3 / 4 / 2;
-
-    if (mapRadius > maxMapRadius) {
-        mapRadius = maxMapRadius;
-    }
-
-    mapBuffer = mapRadius / 2;
-
-    //context.font = fontNormal;
-    pathRoot.drawMap(pathRoot);
-
-    if (hueDisplayName && useHue()) {
-        drawLegend();
-    }
-}
-
-function drawBubble(angle, radius, width, radial, flip) {
-    var height = fontSize * 2;
-    var x;
-    var y;
-
-    width = width + fontSize;
-
-    if (radial) {
-        y = -fontSize;
-
-        if (flip) {
-            x = radius - width + fontSize / 2;
-        }
-        else {
-            x = radius - fontSize / 2;
-        }
-    }
-    else {
-        x = -width / 2;
-        y = -radius - fontSize;
-    }
-
-    if (snapshotMode) {
-        drawBubbleSVG(x + centerX, y + centerY, width, height, fontSize, angle);
-    }
-    else {
-        drawBubbleCanvas(x, y, width, height, fontSize, angle);
-    }
-}
-
-function drawBubbleCanvas(x, y, width, height, radius, rotation) {
-    context.strokeStyle = 'black';
-    context.lineWidth = highlightLineWidth;
-    context.fillStyle = 'rgba(255, 255, 255, .75)';
-    context.rotate(rotation);
-    roundedRectangle(x, y, width, fontSize * 2, fontSize);
-    context.fill();
-    context.stroke();
-    context.rotate(-rotation);
-}
-
-function drawBubbleSVG(x, y, width, height, radius, rotation) {
-    svg +=
-        '<rect x="' + x + '" y="' + y +
-        '" width="' + width +
-        '" height="' + height +
-        '" rx="' + radius +
-        '" ry="' + radius +
-        '" fill="rgba(255, 255, 255, .75)' +
-        '" class="highlight" ' +
-        'transform="rotate(' +
-        degrees(rotation) + ',' + centerX + ',' + centerY +
-        ')"/>';
-}
-
-function drawDatasetName() {
-    var alpha = datasetAlpha.current();
-
-    if (alpha > 0) {
-        var radius = gRadius * compressedRadii[0] / -2;
-
-        if (alpha > 1) {
-            alpha = 1;
-        }
-
-        context.globalAlpha = alpha;
-
-        drawBubble(0, -radius, datasetWidths[currentDataset], false, false);
-        drawText(datasetNames[currentDataset], 0, radius, 0, 'center', true);
-    }
-}
-
-function drawHistory() {
-    var alpha = 1;
-    context.textAlign = 'center';
-
-    for (var i = 0; i < nodeHistoryPosition && alpha > 0; i++) {
-
-        context.globalAlpha = alpha - historyAlphaDelta * tweenFactor;
-        context.fillText
-        (
-            nodeHistory[nodeHistoryPosition - i - 1].name,
-            0,
-            (i + tweenFactor) * historySpacingFactor * fontSize - 1
-        );
-
-        if (alpha > 0) {
-            alpha -= historyAlphaDelta;
-        }
-    }
-
-    context.globalAlpha = 1;
-}
-
-function drawLegend() {
-    var width = imageHeight * .0265;
-    var side = width * 0.9
-    var left_buttons = imageWidth * .008;
-    var left = left_buttons + side + fontSize;
-    var height = imageHeight * .15;
-    var top = imageHeight - fontSize * 3.5 - height;
-    var textLeft = left + width + fontSize / 2;
-    var delta = (height - side) / 3;
-
-    canvasButtons = []  // Delete previous buttons
-    var buttonMost = new CanvasButton('mostScore', left_buttons,
-        top, side, side, '#c87cca');
-    var buttonLest = new CanvasButton('lestScore', left_buttons,
-        top + 3 * delta, side, side, '#d38381');
-    canvasButtons.push(buttonMost, buttonLest);
-    if (nodesIndex !== undefined) {
-        var buttonMore = new CanvasButton('moreScore', left_buttons,
-            top + delta, side, side, '#81c8d3');
-        var buttonLess = new CanvasButton('lessScore', left_buttons,
-            top + 2 * delta, side, side, '#96d281');
-        canvasButtons.push(buttonMore, buttonLess)
-    }
-    canvasButtons.forEach(function (element) {
-        element.draw(context);
-    });
-    context.fillStyle = 'black';
-    context.textAlign = 'start';
-    context.font = fontNormal;
-    context.fillText(hueDisplayName, left_buttons, imageHeight - fontSize * 1.5);
-
-    var gradient = context.createLinearGradient(0, top + height, 0, top);
-
-    for (var i = 0; i < hueStopPositions.length; i++) {
-        gradient.addColorStop(hueStopPositions[i], hueStopHsl[i]);
-
-        var textY = top + (1 - hueStopPositions[i]) * height;
-
-        if
-        (
-            i === 0 ||
-            i === hueStopPositions.length - 1 ||
-            textY > top + fontSize && textY < top + height - fontSize
-        ) {
-            context.fillText(hueStopText[i], textLeft, textY);
-        }
-    }
-
-    context.fillStyle = gradient;
-    context.fillRect(left, top, width, height);
-    context.lineWidth = thinLineWidth;
-    context.strokeRect(left, top, width, height);
-
-    // Sample statistics
-    if (currentDataset < numRawSamples) {
-        var stat = stats[currentDataset];
-        // Define aux position variables
-        var statsX = textLeft + 2 * width;
-        var statsY = top;
-        var rad = width;
-        context.font = "Bold 11px Ubuntu";
-        var statLabelText;
-        if (chart === ChartEnum.GENOMIC) {
-            context.fillStyle = 'rgba(170, 20, 255, 1)';
-            statLabelText = 'Functional sample statistics';
-        } else if (stat.is_ctrl) {
-            context.fillStyle = 'rgba(50, 50, 200, 1)';
-            statLabelText = 'Control statistics';
-        } else {
-            context.fillStyle = 'rgba(200, 50, 50, 1)';
-            statLabelText = 'Sample statistics';
-        }
-        context.fillText(statLabelText, statsX + width,
-            imageHeight - fontSize * 1.5);
-        // Get the set of strings
-        var oldFont = context.font;
-        context.font = "10.5px monospace";  // In case the next line fails
-        context.font = "10.5px Oxygen Mono";
-        var readTit;
-        var nodeTit;
-        if (chart === ChartEnum.GENOMIC) {
-            readTit = 'Annotations read: '
-            nodeTit = 'GOs'
-        } else {
-            readTit = 'Sequences read: '
-            nodeTit = 'TaxIDs'
-        }
-        var statsStrs = [
-            readTit + stat.sread,
-            '  those classified: ' + (
-                stat.sclas / stat.sread * 100).toPrecision(3) + '%',
-            '    those accepted: '
-            + (stat.sfilt / stat.sclas * 100).toPrecision(3) + '%',
-            'Score average: ' + parseFloat(stat.scavg).toFixed(1),
-            '  min: ' + parseFloat(stat.scmin).toFixed(1) +
-            '  max: ' + parseFloat(stat.scmax).toFixed(1),
-            'Length average: ' + stat.lnavg,
-            '  min: ' + stat.lnmin + '  max: ' + stat.lnmax,
-            nodeTit + ' by classifier: ' + stat.tclas,
-            '  those accepted: ' +
-            (stat.tfilt / stat.tclas * 100).toPrecision(3) + '%',
-            '    final: '  +
-            (stat.tfold / stat.tfilt * 100).toPrecision(3) + '% ['
-            + stat.tfold + ']'
-        ];
-        var maxTextWidth = Math.max.apply(null, statsStrs.map(function (text) {
-            return context.measureText(text).width
-        }));
-        // Draw the rounded rectangle
-        context.lineWidth = 3;
-        if (chart === ChartEnum.GENOMIC) {
-            context.strokeStyle = '#B20DFF';
-            context.fillStyle = 'rgba(180, 100, 255, 0.2)';
-        } else if (stat.is_ctrl) {
-            context.strokeStyle = '#3333CC';
-            context.fillStyle = 'rgba(0, 255, 255, 0.2)';
-        } else {
-            context.strokeStyle = '#CC3333';
-            context.fillStyle = 'rgba(255, 255, 0, 0.2)';
-        }
-        var box = new roundedRectangle(
-            statsX, statsY, 1.2 * maxTextWidth, height, {tr: rad, bl: rad});
-        context.stroke();
-        context.fill();
-        context.fillStyle = context.strokeStyle = '#222222';
-        // Write the stats inside
-        var statsNum = statsStrs.length;
-        var statsLeft = statsX + maxTextWidth * 0.1;
-        var statsDelta = height / (statsNum + 1);
-        for (i = 0; i < statsNum; i++) {
-            context.fillText(statsStrs[i],
-                statsLeft, top + i * statsDelta + fontSize);
-        }
-        // Restore font
-        context.font = oldFont;
-    }
-}
-
-function drawLegendSVG() {
-    var left = imageWidth * .01;
-    var width = imageHeight * .0265;
-    var height = imageHeight * .15;
-    var top = imageHeight - fontSize * 3.5 - height;
-    var textLeft = left + width + fontSize / 2;
-
-    var text = '';
-
-    text += svgText(hueDisplayName, left, imageHeight - fontSize * 1.5);
-
-    var svgtest =
-        '<linearGradient id="gradient" x1="0%" y1="100%" x2="0%" y2="0%">';
-
-    for (var i = 0; i < hueStopPositions.length; i++) {
-        svgtest +=
-            '<stop offset="' + round(hueStopPositions[i] * 100) +
-            '%" style="stop-color:' + hueStopHsl[i] + '"/>';
-
-        var textY = top + (1 - hueStopPositions[i]) * height;
-
-        if
-        (
-            i == 0 ||
-            i == hueStopPositions.length - 1 ||
-            textY > top + fontSize && textY < top + height - fontSize
-        ) {
-            text += svgText(hueStopText[i], textLeft, textY);
-        }
-    }
-
-    svgtest += '</linearGradient>';
-    //alert(svgtest);
-    svg += svgtest;
-    svg +=
-        '<rect style="fill:url(#gradient)" x="' + left + '" y="' + top +
-        '" width="' + width + '" height="' + height + '"/>';
-
-    svg += text;
-}
-
-function drawSearchHighlights(label, bubbleX, bubbleY, rotation, center) {
-    var index = -1;
-    var labelLength = label.length;
-
-    bubbleX -= fontSize / 4;
-
-    do {
-        index = label.toLowerCase().indexOf(search.value.toLowerCase(),
-            index + 1);
-
-        if (index != -1 && index < labelLength) {
-            var dim = context.measureText(label.substr(0, index));
-            var x = bubbleX + dim.width;
-
-            dim = context.measureText(label.substr(index, search.value.length));
-
-            var y = bubbleY - fontSize * 3 / 4;
-            var width = dim.width + fontSize / 2;
-            var height = fontSize * 3 / 2;
-            var radius = fontSize / 2;
-
-            if (snapshotMode) {
-                if (center) {
-                    x += centerX;
-                    y += centerY;
-                }
-
-                svg +=
-                    '<rect x="' + x + '" y="' + y +
-                    '" width="' + width +
-                    '" height="' + height +
-                    '" rx="' + radius +
-                    '" ry="' + radius +
-                    '" class="searchHighlight' +
-                    '" transform="rotate(' +
-                    degrees(rotation) + ',' + centerX + ',' + centerY +
-                    ')"/>';
-            }
-            else {
-                context.fillStyle = 'rgb(255, 255, 100)';
-                context.rotate(rotation);
-                roundedRectangle(x, y, width, height, radius);
-                context.fill();
-                context.rotate(-rotation);
-            }
-        }
-    }
-    while (index != -1 && index < labelLength);
-}
-
-function drawText(text, x, y, angle, anchor, bold, color) {
-    if (color == undefined) {
-        color = 'black';
-    }
-
-    if (snapshotMode) {
-        svg +=
-            '<text x="' + (centerX + x) + '" y="' + (centerY + y) +
-            '" text-anchor="' + anchor + '" style="font-color:' + color
-            + ';font-weight:' + (bold ? 'bold' : 'normal') +
-            '" transform="rotate(' + degrees(angle) + ',' + centerX
-            + ',' + centerY + ')">' +
-            text + '</text>';
-    }
-    else {
-        context.fillStyle = color;
-        context.textAlign = anchor;
-        context.font = bold ? fontBold : fontNormal;
-        context.rotate(angle);
-        context.fillText(text, x, y);
-        context.rotate(-angle);
-    }
-}
-
-function drawTextPolar
-(text,
- innerText,
- angle,
- radius,
- radial,
- bubble,
- bold,
- searchResult,
- searchResults) {
-    var anchor;
-    var textX;
-    var textY;
-    var spacer;
-    var totalText = text;
-    var flip;
-
-    if (snapshotMode) {
-        spacer = '&#160;&#160;&#160;';
-    }
-    else {
-        spacer = '   ';
-    }
-
-    if (radial) {
-        flip = angle < 3 * Math.PI / 2;
-
-        if (flip) {
-            angle -= Math.PI;
-            radius = -radius;
-            anchor = 'end';
-
-            if (innerText) {
-                totalText = text + spacer + innerText;
-            }
-        }
-        else {
-            anchor = 'start';
-
-            if (innerText) {
-                totalText = innerText + spacer + text;
-            }
-        }
-
-        textX = radius;
-        textY = 0;
-    }
-    else {
-        flip = angle < Math.PI || angle > 2 * Math.PI;
-        var label;
-
-        anchor = snapshotMode ? 'middle' : 'center';
-
-        if (flip) {
-            angle -= Math.PI;
-            radius = -radius;
-        }
-
-        angle += Math.PI / 2;
-        textX = 0;
-        textY = -radius;
-    }
-
-    if (bubble) {
-        var textActual = totalText;
-
-        if (innerText && snapshotMode) {
-            if (flip) {
-                textActual = text + '   ' + innerText;
-            }
-            else {
-                textActual = innerText + '   ' + text;
-            }
-        }
-
-        if (searchResults) {
-            textActual = textActual + searchResultString(searchResults);
-        }
-
-        var textWidth = measureText(textActual, bold);
-
-        var x = textX;
-
-        if (anchor == 'end') {
-            x -= textWidth;
-        }
-        else if (anchor != 'start') {
-            // centered
-            x -= textWidth / 2;
-        }
-
-        drawBubble(angle, radius, textWidth, radial, flip);
-
-        if (searchResult) {
-            drawSearchHighlights
-            (
-                textActual,
-                x,
-                textY,
-                angle,
-                true
-            )
-        }
-    }
-
-    if (searchResults) {
-        totalText = totalText + searchResultString(searchResults);
-    }
-
-    drawText(totalText, textX, textY, angle, anchor, bold);
-
-    return flip;
-}
-
-function drawTick(start, length, angle) {
-    if (snapshotMode) {
-        svg +=
-            '<line x1="' + (centerX + start) +
-            '" y1="' + centerY +
-            '" x2="' + (centerX + start + length) +
-            '" y2="' + centerY +
-            '" class="tick" transform="rotate(' +
-            degrees(angle) + ',' + centerX + ',' + centerY +
-            ')"/>';
-    }
-    else {
-        context.rotate(angle);
-        context.beginPath();
-        context.moveTo(start, 0);
-        context.lineTo(start + length, 0);
-        context.lineWidth = thinLineWidth * 2;
-        context.stroke();
-        context.rotate(-angle);
-    }
-}
-
-function drawWedge
-(angleStart,
- angleEnd,
- radiusInner,
- radiusOuter,
- color,
- patternAlpha,
- highlight) {
-    if (context.globalAlpha == 0) {
-        return;
-    }
-
-    if (snapshotMode) {
-        if (angleEnd == angleStart + Math.PI * 2) {
-            // fudge to prevent overlap, which causes arc ambiguity
-            //
-            angleEnd -= .1 / gRadius;
-        }
-
-        var longArc = angleEnd - angleStart > Math.PI ? 1 : 0;
-
-        var x1 = centerX + radiusInner * Math.cos(angleStart);
-        var y1 = centerY + radiusInner * Math.sin(angleStart);
-
-        var x2 = centerX + gRadius * Math.cos(angleStart);
-        var y2 = centerY + gRadius * Math.sin(angleStart);
-
-        var x3 = centerX + gRadius * Math.cos(angleEnd);
-        var y3 = centerY + gRadius * Math.sin(angleEnd);
-
-        var x4 = centerX + radiusInner * Math.cos(angleEnd);
-        var y4 = centerY + radiusInner * Math.sin(angleEnd);
-
-        var dArray =
-            [
-                " M ", x1, ",", y1,
-                " L ", x2, ",", y2,
-                " A ", gRadius, ",", gRadius, " 0 ", longArc, ",1 ", x3
-                , ",", y3,
-                " L ", x4, ",", y4,
-                " A ", radiusInner, ",", radiusInner, " 0 ", longArc,
-                " 0 ", x1, ",", y1,
-                " Z "
-            ];
-
-        svg +=
-            '<path class="' + (highlight ? 'highlight' : 'wedge')
-            + '" fill="' + color +
-            '" d="' + dArray.join('') + '"/>';
-
-        if (patternAlpha > 0) {
-            svg +=
-                '<path class="wedge" fill="url(#hiddenPattern)" d="' +
-                dArray.join('') + '"/>';
-        }
-    }
-    else {
-        // fudge to prevent seams during animation
-        //
-        angleEnd += 1 / gRadius;
-
-        context.fillStyle = color;
-        context.beginPath();
-        context.arc(0, 0, radiusInner, angleStart, angleEnd, false);
-        context.arc(0, 0, radiusOuter, angleEnd, angleStart, true);
-        context.closePath();
-        context.fill();
-
-        if (patternAlpha > 0) {
-            context.save();
-            context.clip();
-            context.globalAlpha = patternAlpha;
-            context.fillStyle = hiddenPattern;
-            context.fill();
-            context.restore();
-        }
-
-        if (highlight) {
-            context.lineWidth = highlight ? highlightLineWidth : thinLineWidth;
-            context.strokeStyle = 'black';
-            context.stroke();
-        }
-    }
-}
-
-function expand(node) {
-    selectNode(node);
-    updateView();
-}
-
-function focusLost() {
-    mouseX = -1;
-    mouseY = -1;
-    checkHighlight();
-    document.body.style.cursor = 'auto';
-}
-
-function fontSizeDecrease() {
-    if (fontSize > 1) {
-        fontSize--;
-        updateViewNeeded = true;
-    }
-}
-
-function fontSizeIncrease() {
-    fontSize++;
-    updateViewNeeded = true;
-}
-
-function getGetString(name, value, bool) {
-    return name + '=' + (bool ? value ? 'true' : 'false' : value);
-}
-
-function hideLink() {
-    hide(linkText);
-    show(linkButton);
-}
-
-function show(object) {
-    object.style.display = 'inline';
-}
-
-function hide(object) {
-    object.style.display = 'none';
-}
-
-function showLink() {
-    var urlHalves = String(document.location).split('?');
-    var newGetVariables = new Array();
-
-    newGetVariables.push
-    (
-        getGetString('dataset', currentDataset, false),
-        getGetString('node', selectedNode.id, false),
-        getGetString('collapse', collapse, true),
-        getGetString('color', useHue(), true),
-        getGetString('depth', maxAbsoluteDepth - 1, false),
-        getGetString('font', fontSize, false),
-        getGetString('key', showKeys, true)
-    );
-
-    hide(linkButton);
-    show(linkText);
-    linkText.value = urlHalves[0] + '?'
-        + getVariables.concat(newGetVariables).join('&');
-    //linkText.disabled = false;
-    linkText.focus();
-    linkText.select();
-    //linkText.disabled = true;
-//	document.location = urlHalves[0] + '?' + getVariables.join('&');
-}
-
-function getFirstChild(element) {
-    element = element.firstChild;
-
-    if (element && element.nodeType != 1) {
-        element = getNextSibling(element);
-    }
-
-    return element;
-}
-
-function getNextSibling(element) {
-    do {
-        element = element.nextSibling;
-    }
-    while (element && element.nodeType != 1);
-
-    return element;
-}
-
-function getPercentage(fraction) {
-    return round(fraction * 100);
-}
-
-function hslText(hue) {
-    if (1 || snapshotMode) {
-        // Safari doesn't seem to allow hsl() in SVG
-
-        var rgb = hslToRgb(hue, saturation, (lightnessBase + lightnessMax) / 2);
-
-        return rgbText(rgb.r, rgb.g, rgb.b);
-    }
-    else {
-        var hslArray =
-            [
-                'hsl(',
-                Math.floor(hue * 360),
-                ',',
-                Math.floor(saturation * 100),
-                '%,',
-                Math.floor((lightnessBase + lightnessMax) * 50),
-                '%)'
-            ];
-
-        return hslArray.join('');
-    }
-}
-
-function hslToRgb(h, s, l) {
-    var m1, m2;
-    var r, g, b;
-
-    if (s == 0) {
-        r = g = b = Math.floor((l * 255));
-    }
-    else {
-        if (l <= 0.5) {
-            m2 = l * (s + 1);
-        }
-        else {
-            m2 = l + s - l * s;
-        }
-
-        m1 = l * 2 - m2;
-
-        r = Math.floor(hueToRgb(m1, m2, h + 1 / 3));
-        g = Math.floor(hueToRgb(m1, m2, h));
-        b = Math.floor(hueToRgb(m1, m2, h - 1 / 3));
-    }
-
-    return {r: r, g: g, b: b};
-}
-
-function hueToRgb(m1, m2, hue) {
-    var v;
-
-    while (hue < 0) {
-        hue += 1;
-    }
-
-    while (hue > 1) {
-        hue -= 1;
-    }
-
-    if (6 * hue < 1)
-        v = m1 + (m2 - m1) * hue * 6;
-    else if (2 * hue < 1)
-        v = m2;
-    else if (3 * hue < 2)
-        v = m1 + (m2 - m1) * (2 / 3 - hue) * 6;
-    else
-        v = m1;
-
-    return 255 * v;
-}
-
-function interpolateHue(hueStart, hueEnd, valueStart, valueEnd) {
-    // since the gradient will be RGB based, we need to add stops to hit all the
-    // colors in the hue spectrum
-
-    function selective_round(value){
-        // Selective round depending on the hue scale width
-        if(valueEnd - valueStart < 10){
-            return(value.toFixed(1))
-        } else {
-            return(round(value))
-        }
-    }
-
-    hueStopPositions = new Array();
-    hueStopHsl = new Array();
-    hueStopText = new Array();
-
-    hueStopPositions.push(0);
-    hueStopHsl.push(hslText(hueStart));
-    hueStopText.push(selective_round(valueStart));
-
-    for
-    (
-        var i = (hueStart > hueEnd ? 5 / 6 : 1 / 6);
-        (hueStart > hueEnd ? i > 0 : i < 1);
-        i += (hueStart > hueEnd ? -1 : 1) / 6
-    ) {
-        if
-        (
-            hueStart > hueEnd ?
-                i > hueEnd && i < hueStart :
-                i > hueStart && i < hueEnd
-        ) {
-            hueStopPositions.push(lerp(i, hueStart, hueEnd, 0, 1));
-            hueStopHsl.push(hslText(i));
-            hueStopText.push(selective_round(lerp(
-                i, hueStart, hueEnd, valueStart, valueEnd)));
-        }
-    }
-
-    hueStopPositions.push(1);
-    hueStopHsl.push(hslText(hueEnd));
-    hueStopText.push(selective_round(valueEnd));
-}
-
-function keyLineAngle(angle, keyAngle, bendRadius, keyX, keyY, pointsX,
-                      pointsY) {
-    if (angle < Math.PI / 2 && keyY < bendRadius * Math.sin(angle)
-        || angle > Math.PI / 2 && keyY < bendRadius) {
-        return Math.asin(keyY / bendRadius);
-    }
-    else {
-        // find the angle of the normal to a tangent line that goes to
-        // the label
-
-        var textDist = Math.sqrt
-        (
-            Math.pow(keyX, 2) +
-            Math.pow(keyY, 2)
-        );
-
-        var tanAngle = Math.acos(bendRadius / textDist) + keyAngle;
-
-        if (angle < tanAngle || angle < Math.PI / 2)//|| labelLeft < centerX )
-        {
-            // angle doesn't reach far enough for tangent; collapse and
-            // connect directly to label
-
-            if (keyY / Math.tan(angle) > 0) {
-                pointsX.push(keyY / Math.tan(angle));
-                pointsY.push(keyY);
-            }
-            else {
-                pointsX.push(bendRadius * Math.cos(angle));
-                pointsY.push(bendRadius * Math.sin(angle));
-            }
-
-            return angle;
-        }
-        else {
-            return tanAngle;
-        }
-    }
-}
-
-function keyOffset() {
-    return imageHeight - (keys - currentKey + 1) * (keySize + keyBuffer) +
-        keyBuffer - margin;
-}
-
-function lerp(value, fromStart, fromEnd, toStart, toEnd) {
-    // Rescale value from source scale [fromStart, fromEnd]
-    //  to target scale [toStart, toEnd]
-    return (value - fromStart) *
-        (toEnd - toStart) /
-        (fromEnd - fromStart) +
-        toStart;
-}
-
-function createCanvas() {
-    canvas = document.createElement('canvas');
-    document.body.appendChild(canvas);
-    context = canvas.getContext('2d');
-}
-
-function load() {
-    document.body.style.overflow = "hidden";
-    document.body.style.margin = 0;
-    document.body.style.backgroundColor = '#' + bkgBright;
-    createCanvas();
-
-    if (context == undefined) {
-        document.body.innerHTML = '\
-<br/>Recentrifuge: Sorry, this browser does not support HTML5 (please see \
-<a href="https://github.com/khyox/recentrifuge/wiki/Browser-support">Browser support</a>).\
-	';
-        return;
-    }
-
-    if (typeof context.fillText != 'function') {
-        document.body.innerHTML = '\
-<br/>Recentrifuge: Sorry, this browser does not support HTML5 canvas text (please see \
-<a href="https://github.com/khyox/recentrifuge/wiki/Browser-support">Browser support</a>).\
-	';
-        return;
-    }
-
-    resize();
-
-    var kronaElement = document.getElementsByTagName('krona')[0];
-
-    var magnitudeName;
-    var hueName;
-    var hueDefault;
-    var hueStart;
-    var hueEnd;
-    var valueStart;
-    var valueEnd;
-
-    if (kronaElement.getAttribute('collapse') !== undefined) {
-        collapse = kronaElement.getAttribute('collapse') === 'true';
-    }
-
-    if (kronaElement.getAttribute('key') !== undefined) {
-        showKeys = kronaElement.getAttribute('key') === 'true';
-    }
-
-    if (kronaElement.getAttribute('chart') !== undefined) {
-         switch (kronaElement.getAttribute('chart')) {
-             case 'TAXOMIC':
-                 chart = ChartEnum.TAXOMIC;
-                 fontFamily = 'Ubuntu'
-                 fontSize = 11
-                 break;
-             case 'GENOMIC':
-                 chart = ChartEnum.GENOMIC;
-                 fontFamily = 'Saira Condensed'
-                 fontSize = 12
-                 break;
-         }
-    }
-
-    for
-    (
-        var element = getFirstChild(kronaElement);
-        element;
-        element = getNextSibling(element)
-    ) {
-        switch (element.tagName.toLowerCase()) {
-            case 'attributes':
-                magnitudeName = element.getAttribute('magnitude');
-                //
-                for
-                (
-                    var attributeElement = getFirstChild(element);
-                    attributeElement;
-                    attributeElement = getNextSibling(attributeElement)
-                ) {
-                    var tag = attributeElement.tagName.toLowerCase();
-
-                    if (tag == 'attribute') {
-                        var attribute = new Attribute();
-                        attribute.name =
-                            attributeElement.firstChild.nodeValue.toLowerCase();
-                        attribute.displayName =
-                            attributeElement.getAttribute('display');
-
-                        if (attributeElement.getAttribute('tip')) {
-                            attribute.tip =
-                                attributeElement.getAttribute('tip');
-                        }
-
-                        if (attributeElement.getAttribute('hrefBase')) {
-                            attribute.hrefBase =
-                                attributeElement.getAttribute('hrefBase');
-                        }
-
-                        if (attributeElement.getAttribute('target')) {
-                            attribute.target =
-                                attributeElement.getAttribute('target');
-                        }
-
-                        if (attribute.name === magnitudeName) {
-                            magnitudeIndex = attributes.length;
-                        }
-
-                        if (attributeElement.getAttribute('listAll')) {
-                            attribute.listAll =
-                                attributeElement.getAttribute('listAll').toLowerCase();
-                        }
-                        else if (attributeElement.getAttribute('listNode')) {
-                            attribute.listNode =
-                                attributeElement.getAttribute('listNode').toLowerCase();
-                        }
-                        else if (attributeElement.getAttribute('dataAll')) {
-                            attribute.dataAll =
-                                attributeElement.getAttribute('dataAll').toLowerCase();
-                        }
-                        else if (attributeElement.getAttribute('dataNode')) {
-                            attribute.dataNode =
-                                attributeElement.getAttribute('dataNode').toLowerCase();
-                        }
-
-                        if (attributeElement.getAttribute('postUrl')) {
-                            attribute.postUrl =
-                                attributeElement.getAttribute('postUrl');
-                        }
-
-                        if (attributeElement.getAttribute('postVar')) {
-                            attribute.postVar =
-                                attributeElement.getAttribute('postVar');
-                        }
-
-                        if (attributeElement.getAttribute('mono')) {
-                            attribute.mono = true;
-                        }
-
-                        attributes.push(attribute);
-                    }
-                    else if (tag == 'list') {
-                        var attribute = new Attribute();
-
-                        attribute.name = attributeElement.firstChild.nodeValue;
-                        attribute.list = true;
-                        attributes.push(attribute);
-                    }
-                    else if (tag == 'data') {
-                        var attribute = new Attribute();
-
-                        attribute.name = attributeElement.firstChild.nodeValue;
-                        attribute.data = true;
-                        attributes.push(attribute);
-
-                        var enableScript = document.createElement('script');
-                        var date = new Date();
-                        enableScript.src =
-                            attributeElement.getAttribute('enable') + '?' +
-                            date.getTime();
-                        document.body.appendChild(enableScript);
-                    }
-                }
-                break;
-
-            case 'color':
-                hueName = element.getAttribute('attribute');
-                hueStart = Number(element.getAttribute('hueStart')) / 360;
-                hueEnd = Number(element.getAttribute('hueEnd')) / 360;
-                valueStart = Number(element.getAttribute('valueStart'));
-                valueEnd = Number(element.getAttribute('valueEnd'));
-                //
-                interpolateHue(hueStart, hueEnd, valueStart, valueEnd);
-                //
-                if (element.getAttribute('default') == 'true') {
-                    hueDefault = true;
-                }
-                break;
-
-            case 'datasets':
-                datasetNames = [];
-                stats = [];
-                numRawSamples = element.getAttribute('rawSamples');
-                var i = 0;
-                for (var j = getFirstChild(element); j; j = getNextSibling(j)) {
-                    var datasetName = j.firstChild.nodeValue;
-                    datasetNames.push(datasetName);
-                    if (i < numRawSamples) {  // Get stats of raw samples
-                        var stat = new SampleStats(
-                            datasetName,
-                            j.getAttribute('isctr'),
-                            j.getAttribute('sread'),
-                            j.getAttribute('sclas'),
-                            j.getAttribute('sfilt'),
-                            j.getAttribute('scmin'),
-                            j.getAttribute('scavg'),
-                            j.getAttribute('scmax'),
-                            j.getAttribute('lnmin'),
-                            j.getAttribute('lnavg'),
-                            j.getAttribute('lnmax'),
-                            j.getAttribute('tclas'),
-                            j.getAttribute('tfilt'),
-                            j.getAttribute('tfold')
-                        );
-                        stats.push(stat)
-                    }
-                }
-                datasets = datasetNames.length;
-                break;
-
-            case 'node':
-                head = loadTreeDOM
-                (
-                    element,
-                    magnitudeName,
-                    hueName,
-                    hueStart,
-                    hueEnd,
-                    valueStart,
-                    valueEnd
-                );
-                break;
-        }
-    }
-
-    // get GET options
-    //
-    var urlHalves = String(document.location).split('?');
-    var datasetDefault = 0;
-    var maxDepthDefault;
-    var nodeDefault = 0;
-    //
-    if (urlHalves[1]) {
-        var vars = urlHalves[1].split('&');
-
-        for (i = 0; i < vars.length; i++) {
-            var pair = vars[i].split('=');
-
-            switch (pair[0]) {
-                case 'collapse':
-                    collapse = pair[1] == 'true';
-                    break;
-
-                case 'color':
-                    hueDefault = pair[1] == 'true';
-                    break;
-
-                case 'dataset':
-                    datasetDefault = Number(pair[1]);
-                    break;
-
-                case 'depth':
-                    maxDepthDefault = Number(pair[1]) + 1;
-                    break;
-
-                case 'key':
-                    showKeys = pair[1] == 'true';
-                    break;
-
-                case 'font':
-                    fontSize = Number(pair[1]);
-                    break;
-
-                case 'node':
-                    nodeDefault = Number(pair[1]);
-                    break;
-
-                default:
-                    getVariables.push(pair[0] + '=' + pair[1]);
-                    break;
-            }
-        }
-    }
-
-    addOptionElements(hueName, hueDefault);
-    if (datasets > 1) {
-        if (datasets > numRawSamples) {  // Check for cross-analysis samples
-            selectRank(DEFAULT_RANK);
-        } else {
-            selectRank(NO_RANK);
-        }
-    }
-    setCallBacks();
-
-    head.sort();
-    maxAbsoluteDepth = 0;
-    selectDataset(datasetDefault);
-
-    if (maxDepthDefault && maxDepthDefault < head.maxDepth) {
-        maxAbsoluteDepth = maxDepthDefault;
-    }
-    else {
-        maxAbsoluteDepth = head.maxDepth;
-    }
-
-    selectNode(nodes[nodeDefault]);
-
-    setInterval(update, 20);
-
-    window.onresize = handleResize;
-    updateMaxAbsoluteDepth();
-    updateViewNeeded = true;
-}
-
-function loadTreeDOM
-(domNode,
- magnitudeName,
- hueName,
- hueStart,
- hueEnd,
- valueStart,
- valueEnd) {
-    var newNode = new Node();
-
-    newNode.name = domNode.getAttribute('name');
-
-    if (domNode.getAttribute('href')) {
-        newNode.href = domNode.getAttribute('href');
-    }
-
-    if (hueName) {
-        newNode.hues = new Array();
-    }
-
-    for (var i = getFirstChild(domNode); i; i = getNextSibling(i)) {
-        switch (i.tagName.toLowerCase()) {
-            case 'node':
-                var newChild = loadTreeDOM
-                (
-                    i,
-                    magnitudeName,
-                    hueName,
-                    hueStart,
-                    hueEnd,
-                    valueStart,
-                    valueEnd
-                );
-                newChild.parent = newNode;
-                newNode.children.push(newChild);
-                break;
-
-            default:
-                var attributeName = i.tagName.toLowerCase();
-                var index = attributeIndex(attributeName);
-                //
-                newNode.attributes[index] = new Array();
-                //
-                for (var j = getFirstChild(i); j; j = getNextSibling(j)) {
-                    if (attributes[index] == undefined) {
-                        var x = 5;
-                    }
-                    if (attributes[index].list) {
-                        newNode.attributes[index].push(new Array());
-
-                        for (var k = getFirstChild(j); k; k = getNextSibling(k)) {
-                            newNode.attributes[index][
-                            newNode.attributes[
-                                index].length - 1].push(
-                                k.firstChild.nodeValue);
-                        }
-                    }
-                    else {
-                        var value = j.firstChild ? j.firstChild.nodeValue : '';
-
-                        if (j.getAttribute('href')) {
-                            var target;
-
-                            if (attributes[index].target) {
-                                target = ' target="'
-                                    + attributes[index].target + '"';
-                            }
-
-                            value = '<a href="' + attributes[index].hrefBase
-                                + j.getAttribute('href') + '"'
-                                + target + '>' + value + '</a>';
-                        }
-
-                        newNode.attributes[index].push(value);
-                    }
-                }
-                //
-                if (attributeName == magnitudeName
-                    || attributeName == hueName) {
-                    for (j = 0; j < datasets; j++) {
-                        // j is the dataset index (goes from 0 to datasets-1)
-                        var value = newNode.attributes[index][j]
-                        == undefined ? 0 : Number(newNode.attributes[index][j]);
-
-                        newNode.attributes[index][j] = value;
-
-                        if (attributeName == hueName) {
-                            var hue = lerp
-                            (
-                                value,
-                                valueStart,
-                                valueEnd,
-                                hueStart,
-                                hueEnd
-                            );
-
-                            if (hue < hueStart == hueStart < hueEnd) {
-                                hue = hueStart;
-                            }
-                            else if (hue > hueEnd == hueStart < hueEnd) {
-                                hue = hueEnd;
-                            }
-
-                            newNode.hues[j] = hue;
-                        }
-                    }
-
-                    if (attributeName == hueName) {
-                        newNode.hue = new Tween(newNode.hues[0],
-                            newNode.hues[0]);
-                    }
-                }
-                break;
-        }
-    }
-
-    return newNode;
-}
-
-function maxAbsoluteDepthDecrease() {
-    if (maxAbsoluteDepth > 2) {
-        maxAbsoluteDepth--;
-        head.setMaxDepths();
-        handleResize();
-    }
-}
-
-function maxAbsoluteDepthIncrease() {
-    if (maxAbsoluteDepth < head.maxDepth) {
-        maxAbsoluteDepth++;
-        head.setMaxDepths();
-        handleResize();
-    }
-}
-
-function measureText(text, bold) {
-    context.font = bold ? fontBold : fontNormal;
-    var dim = context.measureText(text);
-    return dim.width;
-}
-
-function min(a, b) {
-    return a < b ? a : b;
-}
-
-function minWidth() {
-    // Min wedge width (at center) for displaying a node (or for displaying a
-    // label if it's at the highest level being viewed, multiplied by 2 to make
-    // further calculations simpler
-
-    return (fontSize * 2.3);
-}
-
-function mouseMove(e) {
-    mouseX = e.pageX;
-    mouseY = e.pageY - headerHeight;
-    mouseXRel = (mouseX - centerX) * backingScale()
-    mouseYRel = (mouseY - centerY) * backingScale()
-
-    if (head && !quickLook) {
-        checkHighlight();
-    }
-}
-
-function mouseClick(e) {
-    // Event listener function for mouse click on CANVAS
-    if (highlightedNode == focusNode && focusNode != selectedNode
-        || selectedNode.hasParent(highlightedNode)) {
-        if (highlightedNode.hasChildren()) {
-            expand(highlightedNode);
-        }
-    }
-    else if (progress == 1)//( highlightedNode != selectedNode )
-    {
-        setFocus(highlightedNode);
-//		document.body.style.cursor='ew-resize';
-        draw();
-        checkHighlight();
-        var date = new Date();
-        mouseDownTime = date.getTime();
-        mouseDown = true;
-        var button = undefined;
-        for (var i = 0; i < canvasButtons.length; i++) {
-            if (canvasButtons[i].is_inside(e.pageX, e.pageY)) {
-                context.strokeStyle = '#CC0000';
-                context.lineWidth = 2;
-                button = canvasButtons[i];
-                context.strokeRect(button.x, button.y, button.w, button.h);
-            }
-        }
-        if (button) {
-            // Reorder the array of nodes only when needed
-            if (nodesIndex === undefined || !nodes.reduce(
-                function (acc, current, index) {
-                    // Calculate deviation from id == index for every node
-                    return acc + Math.abs(current.id - index)
-                }, 0)) {
-                nodes.sort(function (a, b) {
-                    return b.getHue() - a.getHue()
-                });
-            }
-
-            function lookForLeaf(testIndex, reverse) {
-                // Look for nodes without children but with counts
-                for (; testIndex >= 0 && testIndex <= nodes.length - 1
-                       && !nodes[testIndex].isLeaf();
-                       reverse ? testIndex-- : testIndex++) {
-                }
-                if (testIndex >= 0 && testIndex <= nodes.length - 1
-                    && nodes[testIndex].isLeaf()) nodesIndex = testIndex;
-            }
-
-            function lookForNode(testIndex, reverse) {
-                // Look for nodes with counts
-                for (; testIndex >= 0 && testIndex <= nodes.length - 1
-                       && nodes[testIndex].getHue() <= 0;
-                       reverse ? testIndex-- : testIndex++) {
-                }
-                if (testIndex >= 0 && testIndex <= nodes.length - 1
-                    && nodes[testIndex].getHue() > 0)
-                    nodesIndex = testIndex;
-            }
-
-            switch (button.name) {
-                case 'mostScore':
-                    nodesIndex = 0;
-                    if (collapseCheckBox.checked) {
-                        lookForLeaf(nodesIndex, false);
-                    } else {
-                        lookForNode(nodesIndex, false);
-                    }
-                    break;
-                case 'moreScore':
-                    if (collapseCheckBox.checked) {
-                        lookForLeaf(nodesIndex - 1, true);
-                    } else {
-                        lookForNode(nodesIndex - 1, true);
-                    }
-                    break;
-                case 'lessScore':
-                    if (collapseCheckBox.checked) {
-                        lookForLeaf(nodesIndex + 1, false);
-                    } else {
-                        lookForNode(nodesIndex + 1, false);
-                    }
-                    break;
-                case 'lestScore':
-                    nodesIndex = nodes.length - 1;
-                    if (collapseCheckBox.checked) {
-                        lookForLeaf(nodesIndex, true);
-                    } else {
-                        lookForNode(nodesIndex, true);
-                    }
-                    break;
-                default:
-                    alert('ERROR! Unknown button in canvas. Ignoring!')
-            }
-            search.value = nodes[nodesIndex].name;
-            onSearchChange();
-            context.strokeStyle = '#CC0000';
-            context.lineWidth = 2;
-            context.strokeRect(button.x, button.y, button.w, button.h);
-            setTimeout(function () {
-                drawLegend()
-            }, 700)
-        }
-    }
-}
-
-function mouseUp(e) {
-    if (quickLook) {
-        navigateBack();
-        quickLook = false;
-    }
-
-    mouseDown = false;
-}
-
-function navigateBack() {
-    if (nodeHistoryPosition > 0) {
-        nodeHistory[nodeHistoryPosition] = selectedNode;
-        nodeHistoryPosition--;
-
-        if (nodeHistory[nodeHistoryPosition].collapse) {
-            collapseCheckBox.checked = collapse = false;
-        }
-
-        setSelectedNode(nodeHistory[nodeHistoryPosition]);
-        updateDatasetButtons();
-        updateView();
-    }
-}
-
-function navigateUp() {
-    if (selectedNode.getParent()) {
-        selectNode(selectedNode.getParent());
-        updateView();
-    }
-}
-
-function navigateForward() {
-    if (nodeHistoryPosition < nodeHistory.length - 1) {
-        nodeHistoryPosition++;
-        var newNode = nodeHistory[nodeHistoryPosition];
-
-        if (newNode.collapse) {
-            collapseCheckBox.checked = collapse = false;
-        }
-
-        if (nodeHistoryPosition == nodeHistory.length - 1) {
-            // this will ensure the forward button is disabled
-
-            nodeHistory.length = nodeHistoryPosition;
-        }
-
-        setSelectedNode(newNode);
-        updateDatasetButtons();
-        updateView();
-    }
-}
-
-function nextDataset() {
-    var newDataset = currentDataset;
-
-    do {
-        if (newDataset === datasets - 1) {
-            newDataset = 0;
-        }
-        else {
-            newDataset++;
-        }
-    }
-    while (datasetDropDown.options[newDataset].disabled
-    || datasetDropDown.options[newDataset].hidden)
-
-    selectDataset(newDataset);
-}
-
-function onDatasetChange() {
-    selectDataset(datasetDropDown.selectedIndex);
-    nodesIndex = undefined;
-}
-
-function onKeyDown(event) {
-    if
-    (
-        event.keyCode == 37 &&
-        document.activeElement.id != 'search' &&
-        document.activeElement.id != 'linkText'
-    ) {
-        navigateBack();
-        event.preventDefault();
-    }
-    else if
-    (
-        event.keyCode == 39 &&
-        document.activeElement.id != 'search' &&
-        document.activeElement.id != 'linkText'
-    ) {
-        navigateForward();
-        event.preventDefault();
-    }
-    else if (event.keyCode == 38 && datasets > 1) {
-        prevDataset();
-
-        //if ( document.activeElement.id == 'datasets' )
-        {
-            event.preventDefault();
-        }
-    }
-    else if (event.keyCode == 40 && datasets > 1) {
-        nextDataset();
-
-        //if ( document.activeElement.id == 'datasets' )
-        {
-            event.preventDefault();
-        }
-    }
-    else if (event.keyCode == 9 && datasets > 1) {
-        selectLastDataset();
-        event.preventDefault();
-    }
-    else if (event.keyCode == 83) {
-        progress += .2;
-    }
-    else if (event.keyCode == 66) {
-        progress -= .2;
-    }
-    else if (event.keyCode == 70) {
-        progress = 1;
-    }
-}
-
-function onKeyPress(event) {
-    if (event.keyCode == 38 && datasets > 1) {
-//		prevDataset();
-
-        //if ( document.activeElement.id == 'datasets' )
-        {
-            event.preventDefault();
-        }
-    }
-    else if (event.keyCode == 40 && datasets > 1) {
-//		nextDataset();
-
-        //if ( document.activeElement.id == 'datasets' )
-        {
-            event.preventDefault();
-        }
-    }
-}
-
-function onKeyUp(event) {
-    if (event.keyCode == 27 && document.activeElement.id == 'search') {
-        search.value = '';
-        onSearchChange();
-    }
-    else if (event.keyCode == 38 && datasets > 1) {
-//		prevDataset();
-
-        //if ( document.activeElement.id == 'datasets' )
-        {
-            event.preventDefault();
-        }
-    }
-    else if (event.keyCode == 40 && datasets > 1) {
-//		nextDataset();
-
-        //if ( document.activeElement.id == 'datasets' )
-        {
-            event.preventDefault();
-        }
-    }
-}
-
-function onRankChange() {
-    selectRank(rankDropDown.value);
-}
-
-function onSearchChange() {
-    nSearchResults = 0;
-    head.search();
-
-    if (search.value == '') {
-        searchResults.innerHTML = '';
-    }
-    else {
-        searchResults.innerHTML = nSearchResults + ' results';
-    }
-
-    setFocus(selectedNode);
-    draw();
-}
-
-function onSortChange() {
-    head.sort();
-    head.setMagnitudes(0);
-    handleResize();
-}
-
-function post(url, variable, value, postWindow) {
-    var form = document.createElement('form');
-    var input = document.createElement('input');
-    var inputDataset = document.createElement('input');
-
-    form.appendChild(input);
-    form.appendChild(inputDataset);
-
-    form.method = "POST";
-    form.action = url;
-
-    if (postWindow == undefined) {
-        form.target = '_blank';
-        postWindow = window;
-    }
-
-    input.type = 'hidden';
-    input.name = variable;
-    input.value = value;
-
-    inputDataset.type = 'hidden';
-    inputDataset.name = 'dataset';
-    inputDataset.value = currentDataset;
-
-    postWindow.document.body.appendChild(form);
-    form.submit();
-}
-
-function prevDataset() {
-    var newDataset = currentDataset;
-
-    do {
-        if (newDataset == 0) {
-            newDataset = datasets - 1;
-        }
-        else {
-            newDataset--;
-        }
-    }
-    while (datasetDropDown.options[newDataset].disabled
-    || datasetDropDown.options[newDataset].hidden);
-
-    selectDataset(newDataset);
-}
-
-function radiusDecrease() {
-    if (bufferFactor < .309) {
-        bufferFactor += .03;
-        updateViewNeeded = true;
-    }
-}
-
-function radiusIncrease() {
-    if (bufferFactor > .041) {
-        bufferFactor -= .03;
-        updateViewNeeded = true;
-    }
-}
-
-function resetKeyOffset() {
-    currentKey = 1;
-    keyMinTextLeft = centerX + gRadius + buffer - buffer / (keys + 1) /
-        2 + fontSize / 2;
-    keyMinAngle = 0;
-}
-
-function rgbText(r, g, b) {
-    var rgbArray =
-        [
-            "rgb(",
-            Math.floor(r),
-            ",",
-            Math.floor(g),
-            ",",
-            Math.floor(b),
-            ")"
-        ];
-
-    return rgbArray.join('');
-}
-
-function round(number) {
-    if (number >= 1 || number <= -1) {
-        return number.toFixed(0);
-    }
-    else {
-        return number.toPrecision(1);
-    }
-}
-
-function roundedRectangle(x, y, width, height, radius, fill, stroke) {
-    // Optionals: radius, stroke, fill
-    if (typeof stroke === 'undefined') {
-        stroke = true;
-    }
-    if (typeof radius === 'undefined') {
-        radius = 5;
-    } else if (typeof radius === 'number') {
-        if (radius * 2 > width) {
-            radius = width / 2;
-        }
-        if (radius * 2 > height) {
-            radius = height / 2;
-        }
-        radius = {tl: radius, tr: radius, br: radius, bl: radius};
-    } else {
-        var defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};
-        for (var side in defaultRadius) {
-            radius[side] = radius[side] || defaultRadius[side];
-        }
-    }
-
-    context.beginPath();
-    context.arc(x + radius.tl, y + radius.tl, radius.tl,
-        Math.PI, Math.PI * 3 / 2, false);
-    context.lineTo(x + width - radius.tr, y);
-    context.arc(x + width - radius.tr, y + radius.tr, radius.tr,
-        Math.PI * 3 / 2, Math.PI * 2, false);
-    context.lineTo(x + width, y + height - radius.br);
-    context.arc(x + width - radius.br, y + height - radius.br, radius.br,
-        0, Math.PI / 2, false);
-    context.lineTo(x + radius.bl, y + height);
-    context.arc(x + radius.bl, y + height - radius.bl, radius.bl,
-        Math.PI / 2, Math.PI, false);
-    context.lineTo(x, y + radius.tl);
-
-    if (fill) {
-        context.fill();
-    }
-    if (stroke) {
-        context.stroke();
-    }
-}
-
-function passClick(e) {
-    mouseClick(e);
-}
-
-function searchResultString(results) {
-    var searchResults = this.searchResults;
-
-    if (this.isSearchResult) {
-        // don't count ourselves
-        searchResults--;
-    }
-
-    return ' - ' + results + (results > 1 ? ' results' : ' result');
-}
-
-function setCallBacks() {
-    canvas.onselectstart = function () {
-        return false;
-    } // prevent unwanted highlighting
-    options.onselectstart = function () {
-        return false;
-    } // prevent unwanted highlighting
-    document.onmousemove = mouseMove;
-    window.onblur = focusLost;
-    window.onmouseout = focusLost;
-    document.onkeyup = onKeyUp;
-    document.onkeydown = onKeyDown;
-    canvas.onmousedown = mouseClick;
-    document.onmouseup = mouseUp;
-    keyControl.onclick = toggleKeys;
-    collapseCheckBox = document.getElementById('collapse');
-    collapseCheckBox.checked = collapse;
-    collapseCheckBox.onclick = handleResize;
-    collapseCheckBox.onmousedown = suppressEvent;
-    maxAbsoluteDepthText = document.getElementById('maxAbsoluteDepth');
-    maxAbsoluteDepthButtonDecrease =
-        document.getElementById('maxAbsoluteDepthDecrease');
-    maxAbsoluteDepthButtonIncrease =
-        document.getElementById('maxAbsoluteDepthIncrease');
-    maxAbsoluteDepthButtonDecrease.onclick = maxAbsoluteDepthDecrease;
-    maxAbsoluteDepthButtonIncrease.onclick = maxAbsoluteDepthIncrease;
-    maxAbsoluteDepthButtonDecrease.onmousedown = suppressEvent;
-    maxAbsoluteDepthButtonIncrease.onmousedown = suppressEvent;
-    fontSizeText = document.getElementById('fontSize');
-    fontSizeButtonDecrease = document.getElementById('fontSizeDecrease');
-    fontSizeButtonIncrease = document.getElementById('fontSizeIncrease');
-    fontSizeButtonDecrease.onclick = fontSizeDecrease;
-    fontSizeButtonIncrease.onclick = fontSizeIncrease;
-    fontSizeButtonDecrease.onmousedown = suppressEvent;
-    fontSizeButtonIncrease.onmousedown = suppressEvent;
-    bkgBrightButtonDecrease = document.getElementById('bkgBrightDecrease');
-    bkgBrightButtonIncrease = document.getElementById('bkgBrightIncrease');
-    bkgBrightButtonDecrease.onclick = bkgBrightDecrease;
-    bkgBrightButtonIncrease.onclick = bkgBrightIncrease;
-    bkgBrightButtonDecrease.onmousedown = suppressEvent;
-    bkgBrightButtonIncrease.onmousedown = suppressEvent;
-    radiusButtonDecrease = document.getElementById('radiusDecrease');
-    radiusButtonIncrease = document.getElementById('radiusIncrease');
-    radiusButtonDecrease.onclick = radiusDecrease;
-    radiusButtonIncrease.onclick = radiusIncrease;
-    radiusButtonDecrease.onmousedown = suppressEvent;
-    radiusButtonIncrease.onmousedown = suppressEvent;
-    maxAbsoluteDepth = 0;
-    backButton = document.getElementById('back');
-    backButton.onclick = navigateBack;
-    backButton.onmousedown = suppressEvent;
-    forwardButton = document.getElementById('forward');
-    forwardButton.onclick = navigateForward;
-    forwardButton.onmousedown = suppressEvent;
-    snapshotButton = document.getElementById('snapshot');
-    snapshotButton.onclick = snapshot;
-    snapshotButton.onmousedown = suppressEvent;
-    detailsName = document.getElementById('detailsName');
-    detailsExpand = document.getElementById('detailsExpand');
-    detailsInfo = document.getElementById('detailsInfo');
-    search = document.getElementById('search');
-    search.onkeyup = onSearchChange;
-    search.onmousedown = suppressEvent;
-    searchResults = document.getElementById('searchResults');
-    useHueDiv = document.getElementById('useHueDiv');
-    linkButton = document.getElementById('linkButton');
-    linkButton.onclick = showLink;
-    linkButton.onmousedown = suppressEvent;
-    linkText = document.getElementById('linkText');
-    linkText.onblur = hideLink;
-    linkText.onmousedown = suppressEvent;
-    hide(linkText);
-    var helpButton = document.getElementById('help');
-    helpButton.onmousedown = suppressEvent;
-    var searchClear = document.getElementById('searchClear');
-    searchClear.onmousedown = suppressEvent;
-    if (datasets > 1) {
-        datasetDropDown.onmousedown = suppressEvent;
-        var prevDatasetButton = document.getElementById('prevDataset');
-        prevDatasetButton.onmousedown = suppressEvent;
-        var nextDatasetButton = document.getElementById('nextDataset');
-        nextDatasetButton.onmousedown = suppressEvent;
-        var lastDatasetButton = document.getElementById('lastDataset');
-        lastDatasetButton.onmousedown = suppressEvent;
-    }
-
-    image = document.getElementById('hiddenImage');
-
-    if (image.complete) {
-        hiddenPattern = context.createPattern(image, 'repeat');
-    }
-    else {
-        image.onload = function () {
-            hiddenPattern = context.createPattern(image, 'repeat');
-        }
-    }
-
-    var loadingImageElement = document.getElementById('loadingImage');
-
-    if (loadingImageElement) {
-        loadingImage = loadingImageElement.src;
-    }
-}
-
-function selectDataset(newDataset) {
-    lastDataset = currentDataset;
-    currentDataset = newDataset
-    if (datasets > 1) {
-        datasetDropDown.selectedIndex = currentDataset;
-        updateDatasetButtons();
-        datasetAlpha.start = 1.5;
-        datasetChanged = true;
-    }
-    head.setMagnitudes(0);
-    head.setDepth(1, 1);
-    head.setMaxDepths();
-    handleResize();
-}
-
-function selectLastDataset() {
-    selectDataset(lastDataset);
-}
-
-function selectNode(newNode) {
-    if (selectedNode != newNode) {
-        // truncate history at current location to create a new branch
-        //
-        nodeHistory.length = nodeHistoryPosition;
-
-        if (selectedNode != 0) {
-            nodeHistory.push(selectedNode);
-            nodeHistoryPosition++;
-        }
-
-        setSelectedNode(newNode);
-        //updateView();
-    }
-
-    updateDatasetButtons();
-}
-
-function selectRank(rank) {
-    rankDropDown.value = rank;
-    currentRank = rank;
-    datasetsVisible = 0;
-    for (var i = 0; i < datasets; i++) {
-        if (currentRank === 'ALL'
-            || i < numRawSamples
-            || (currentRank !== NO_RANK && (
-                datasetNames[i].endsWith('EXCLUSIVE_' + currentRank) ||
-                datasetNames[i].endsWith('SHARED_' + currentRank) ||
-                datasetNames[i].endsWith('CONTROL_SHARED' + currentRank) ||
-                datasetNames[i].endsWith('CTRL_' + currentRank)))) {
-            datasetDropDown.options[i].hidden = false;
-            datasetsVisible++;
-        } else {
-            datasetDropDown.options[i].hidden = true;
-        }
-    }
-    if (datasetDropDown.options[currentDataset].hidden === true) {
-        selectDataset(0);
-    } else {
-        selectDataset(currentDataset);
-    }
-    datasetDropDown.size = (datasetsVisible < DATASET_MAX_SIZE ?
-        datasetsVisible : DATASET_MAX_SIZE);
-}
-
-function setFocus(node) {
-    if (node == focusNode) {
-//		return;
-    }
-
-    focusNode = node;
-
-    if (node.href) {
-        detailsName.innerHTML =
-            '<a target="_blank" href="' + node.href + '">' + node.name + '</a>';
-    }
-    else {
-        detailsName.innerHTML = node.name;
-    }
-
-    var table = '<table>';
-
-    table += '<tr><td></td></tr>';
-
-    for (var i = 0; i < node.attributes.length; i++) {
-        if (attributes[i].displayName && node.attributes[i] != undefined) {
-            var index = node.attributes[i].length == 1
-            && attributes[i].mono ? 0 : currentDataset;
-
-            if (typeof node.attributes[i][currentDataset] == 'number'
-                || node.attributes[i][index] != undefined
-                && node.attributes[i][currentDataset] != '') {
-                var value = node.attributes[i][index];
-
-                if (attributes[i].listNode != undefined) {
-                    value =
-                        '<a href="" onclick="showList(' +
-                        attributeIndex(attributes[i].listNode) + ',' + i +
-                        ',false);return false;" title="Show list">' +
-                        value + '</a>';
-                }
-                else if (attributes[i].listAll != undefined) {
-                    value =
-                        '<a href="" onclick="showList(' +
-                        attributeIndex(attributes[i].listAll) + ',' + i +
-                        ',true);return false;" title="Show list">' +
-                        value + '</a>';
-                }
-                else if (attributes[i].dataNode != undefined && dataEnabled) {
-                    value =
-                        '<a href="" onclick="showData(' +
-                        attributeIndex(attributes[i].dataNode) + ',' + i +
-                        ',false);return false;" title="Show data">' +
-                        value + '</a>';
-                }
-                else if (attributes[i].dataAll != undefined && dataEnabled) {
-                    value =
-                        '<a href="" onclick="showData(' +
-                        attributeIndex(attributes[i].dataAll) + ',' + i +
-                        ',true);return false;" title="Show data">' +
-                        value + '</a>';
-                }
-
-                table +=
-                    '<tr><td class="CellWithTooltip">' +
-                    '<strong>' + attributes[i].displayName + ':</strong>' +
-                    '<span class="Tooltip">' +
-                    attributes[i].tip + '</span>' +
-                    '</td><td>' + value + '</td></tr>';
-            }
-        }
-    }
-
-    table += '</table>';
-    detailsInfo.innerHTML = table;
-
-    detailsExpand.disabled = !focusNode.hasChildren()
-        || focusNode == selectedNode;
-}
-
-function setSelectedNode(newNode) {
-    if (selectedNode && selectedNode.hasParent(newNode)) {
-        zoomOut = true;
-    }
-    else {
-        zoomOut = false;
-    }
-
-    selectedNodeLast = selectedNode;
-    selectedNode = newNode;
-
-    //if ( focusNode != selectedNode )
-    {
-        setFocus(selectedNode);
-    }
-}
-
-function waitForData(dataWindow, target, title, time, postUrl, postVar) {
-    if (nodeData.length == target) {
-        if (postUrl != undefined) {
-            for (var i = 0; i < nodeData.length; i++) {
-                nodeData[i] = nodeData[i].replace(/\n/g, ',');
-            }
-
-            var postString = nodeData.join('');
-            postString = postString.slice(0, -1);
-
-            dataWindow.document.body.removeChild(dataWindow.document.getElementById('loading'));
-            document.body.removeChild(document.getElementById('data'));
-
-            post(postUrl, postVar, postString, dataWindow);
-        }
-        else {
-            //dataWindow.document.body.removeChild(dataWindow.document.getElementById('loading'));
-            //document.body.removeChild(document.getElementById('data'));
-
-            dataWindow.document.open();
-            dataWindow.document.write('<pre>' + nodeData.join('') + '</pre>');
-            dataWindow.document.close();
-        }
-
-        dataWindow.document.title = title; // replace after document.write()
-    }
-    else {
-        var date = new Date();
-
-        if (date.getTime() - time > 10000) {
-            dataWindow.document.body.removeChild(dataWindow.document.getElementById('loading'));
-            document.body.removeChild(document.getElementById('data'));
-            dataWindow.document.body.innerHTML =
-                'Timed out loading supplemental files for:<br/>' + document.location;
-        }
-        else {
-            setTimeout(function () {
-                waitForData(dataWindow, target, title, time, postUrl, postVar);
-            }, 100);
-        }
-    }
-}
-
-function data(newData) {
-    nodeData.push(newData);
-}
-
-function enableData() {
-    dataEnabled = true;
-}
-
-function showData(indexData, indexAttribute, summary) {
-    var dataWindow = window.open('', '_blank');
-    var title = 'Re@ - ' + attributes[indexAttribute].displayName
-        + ' - ' + focusNode.name;
-    dataWindow.document.title = title;
-
-    nodeData = new Array();
-
-    if (dataWindow && dataWindow.document && dataWindow.document.body != null) {
-        //var loadImage = document.createElement('img');
-        //loadImage.src = "file://localhost/Users/ondovb/Krona/KronaTools/img/loading.gif";
-        //loadImage.id = "loading";
-        //loadImage.alt = "Loading...";
-        //dataWindow.document.body.appendChild(loadImage);
-        dataWindow.document.body.innerHTML =
-            '<img id="loading" src="' + loadingImage + '" alt="Loading..."></img>';
-    }
-
-    var scripts = document.createElement('div');
-    scripts.id = 'data';
-    document.body.appendChild(scripts);
-
-    var files = focusNode.getData(indexData, summary);
-
-    var date = new Date();
-    var time = date.getTime();
-
-    for (var i = 0; i < files.length; i++) {
-        var script = document.createElement('script');
-        script.src = files[i] + '?' + time;
-        scripts.appendChild(script);
-    }
-
-    waitForData(dataWindow, files.length, title, time,
-        attributes[indexAttribute].postUrl, attributes[indexAttribute].postVar);
-
-    return false;
-}
-
-function showList(indexList, indexAttribute, summary) {
-    var list = focusNode.getList(indexList, summary);
-
-    if (attributes[indexAttribute].postUrl != undefined) {
-        post(attributes[indexAttribute].postUrl,
-            attributes[indexAttribute].postVar, list.join(','));
-    }
-    else {
-        var dataWindow = window.open('', '_blank');
-
-        if (true || navigator.appName == 'Microsoft Internet Explorer') // :(
-        {
-            dataWindow.document.open();
-            dataWindow.document.write('<pre>' + list.join('\n') + '</pre>');
-            dataWindow.document.close();
-        }
-        else {
-            var pre = document.createElement('pre');
-            dataWindow.document.body.appendChild(pre);
-            pre.innerHTML = list;
-        }
-
-        dataWindow.document.title = 'Re@ - ' +
-            attributes[indexAttribute].displayName + ' - ' + focusNode.name;
-    }
-}
-
-function snapshot() {
-    svg = svgHeader();
-
-    resetKeyOffset();
-
-    snapshotMode = true;
-
-    selectedNode.draw(false, true);
-    selectedNode.draw(true, true);
-
-    if (focusNode != 0 && focusNode != selectedNode) {
-        context.globalAlpha = 1;
-        focusNode.drawHighlight(true);
-    }
-
-    if (hueDisplayName && useHue()) {
-        drawLegendSVG();
-    }
-
-    snapshotMode = false;
-
-    svg += svgFooter();
-
-   	var snapshotWindow = window.open('', '_blank', '', 'replace=false');
-	snapshotWindow.document.write('<html><body>' +
-        '<button title="Download Rec@ntrifuge snapshot as SVG file" ' +
-        'onclick="document.getElementById(\'link\').click()">' +
-        'Download</button><a id="link" href="data:image/svg+xml,' +
-        encodeURIComponent(svg) + '" download="Recfg_snapshot.svg" hidden>' +
-        'Download</a><br></html></body>');
-    snapshotWindow.document.title = 'Re@ [snapshot] ' +
-       location.href.split("/").slice(-1)[0].split(".html")[0];
-	snapshotWindow.document.write(svg);
-}
-
-function save() {
-    alert(document.body.innerHTML);
-}
-
-function spacer() {
-    if (snapshotMode) {
-        return '&#160;&#160;&#160;';
-    }
-    else {
-        return '   ';
-    }
-}
-
-function suppressEvent(e) {
-    e.cancelBubble = true;
-    if (e.stopPropagation) e.stopPropagation();
-}
-
-function svgFooter() {
-    return '</svg>';
-}
-
-function svgHeader() {
-    var patternWidth = fontSize * .6;//radius / 50;
-
-    return '\
-<?xml version="1.0" standalone="no"?>\
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" \
-	"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\
-<svg width="' + imageWidth + '" height="' + imageHeight + '" version="1.1"\
-	xmlns="http://www.w3.org/2000/svg">\
-<title>Rec@ntrifuge (snapshot) - ' +
-        (datasets > 1 ? datasetNames[currentDataset] + ' - ' : '')
-        + selectedNode.name +
-        '</title>\
-<defs>\
-	<style type="text/css">\
-	@import url("https://fonts.googleapis.com/css?family=' + fontFamily + '");\
-	text {font-size: ' + fontSize + 'px; font-family: ' + fontFamily
-        + '; dominant-baseline:central}\
-	path {stroke-width:' + thinLineWidth * fontSize / 12 + ';}\
-	path.wedge {stroke:none}\
-	path.line {fill:none;stroke:black;}\
-	line {stroke:black;stroke-width:' + thinLineWidth * fontSize / 12 + ';}\
-	line.tick {stroke-width:' + thinLineWidth * fontSize / 6 + ';}\
-	line.pattern {stroke-width:' + thinLineWidth * fontSize / 18 + ';}\
-	circle {fill:none;stroke:black;stroke-width:' + thinLineWidth
-        * fontSize / 12 + ';}\
-	rect {stroke:black;stroke-width:' + thinLineWidth * fontSize / 12 + ';}\
-	.highlight {stroke:black;stroke-width:' + highlightLineWidth
-        * fontSize / 12 + ';}\
-	.searchHighlight {fill:rgb(255, 255, 100);stroke:none;}\
-	</style>\
-<pattern id="hiddenPattern" patternUnits="userSpaceOnUse" \
-x="0" y="0" width="' + patternWidth + '" height="' + patternWidth + '">\
-<line class="pattern" x1="0" y1="0" x2="' + patternWidth / 2 + '" y2="'
-        + patternWidth / 2 + '"/>\
-<line class="pattern" x1="' + patternWidth / 2 + '" y1="' + patternWidth +
-        '" x2="' + patternWidth + '" y2="' + patternWidth / 2 + '"/>\
-</pattern>\
-</defs>\
-';
-}
-
-function svgText(text, x, y, anchor, bold, color) {
-    if (typeof(anchor) == 'undefined') {
-        anchor = 'start';
-    }
-
-    if (color == undefined) {
-        color = 'black';
-    }
-
-    return '<text x="' + x + '" y="' + y +
-        '" style="font-color:' + color + ';font-weight:'
-        + (bold ? 'bold' : 'normal') +
-        '" text-anchor="' + anchor + '">' + text + '</text>';
-}
-
-function toggleKeys() {
-    if (showKeys) {
-        keyControl.value = '…';
-        showKeys = false;
-    }
-    else {
-        keyControl.value = 'x';
-        showKeys = true;
-    }
-
-    updateKeyControl();
-
-    if (progress == 1) {
-        draw();
-    }
-}
-
-function update() {
-    if (!head) {
-        return;
-    }
-
-    if (mouseDown && focusNode != selectedNode) {
-        var date = new Date();
-
-        if (date.getTime() - mouseDownTime > quickLookHoldLength) {
-            if (focusNode.hasChildren()) {
-                expand(focusNode);
-                quickLook = true;
-            }
-        }
-    }
-
-    if (updateViewNeeded) {
-        resize();
-        mouseX = -1;
-        mouseY = -1;
-
-        collapse = collapseCheckBox.checked;
-        compress = true;//compressCheckBox.checked;
-        shorten = true;//shortenCheckBox.checked;
-
-        checkSelectedCollapse();
-        updateMaxAbsoluteDepth();
-
-        if (focusNode.getCollapse() || focusNode.depth > maxAbsoluteDepth) {
-            setFocus(selectedNode);
-        }
-        else {
-            setFocus(focusNode);
-        }
-
-        updateView();
-
-        updateViewNeeded = false;
-    }
-
-    var date = new Date();
-    progress = (date.getTime() - tweenStartTime) / tweenLength;
-//	progress += .01;
-
-    if (progress >= 1) {
-        progress = 1;
-    }
-
-    if (progress != progressLast) {
-        tweenFactor =// progress;
-            (1 / (1 + Math.exp(-tweenCurvature * (progress - .5))) - .5) /
-            (tweenMax - .5) / 2 + .5;
-
-        if (progress == 1) {
-            snapshotButton.disabled = false;
-            zoomOut = false;
-
-            //updateKeyControl();
-
-            if (!quickLook) {
-                //checkHighlight();
-            }
-
-
-            if (fpsDisplay) {
-                fpsDisplay.innerHTML = 'fps: '
-                    + Math.round(tweenFrames * 1000 / tweenLength);
-            }
-        }
-
-        draw();
-    }
-
-    progressLast = progress;
-}
-
-function updateDatasetButtons() {
-    if (datasets == 1) {
-        return;
-    }
-
-    var node = selectedNode ? selectedNode : head;
-
-    datasetButtonLast.disabled =
-        node.attributes[magnitudeIndex][lastDataset] == 0;
-
-    datasetButtonPrev.disabled = true;
-    datasetButtonNext.disabled = true;
-
-    for (var i = 0; i < datasets; i++) {
-        var disable = node.attributes[magnitudeIndex][i] == 0;
-
-        datasetDropDown.options[i].disabled = disable;
-
-        if (!disable) {
-            if (i != currentDataset) {
-                datasetButtonPrev.disabled = false;
-                datasetButtonNext.disabled = false;
-            }
-        }
-    }
-}
-
-function updateDatasetWidths() {
-    if (datasets > 1) {
-        for (var i = 0; i < datasets; i++) {
-            context.font = fontBold;
-            var dim = context.measureText(datasetNames[i]);
-            datasetWidths[i] = dim.width;
-        }
-    }
-}
-
-function updateKeyControl() {
-    if (keys == 0)//|| progress != 1 )
-    {
-        keyControl.style.visibility = 'hidden';
-    }
-    else {
-        keyControl.style.visibility = 'visible';
-        keyControl.style.right = margin + 'px';
-
-        if (showKeys) {
-            keyControl.style.top =
-                imageHeight -
-                (
-                    keys * (keySize + keyBuffer) -
-                    keyBuffer +
-                    margin +
-                    keyControl.clientHeight * 1.5
-                ) + 'px';
-        }
-        else {
-            keyControl.style.top =
-                (imageHeight - margin - keyControl.clientHeight) + 'px';
-        }
-    }
-}
-
-function updateView() {
-    if (selectedNode.depth > maxAbsoluteDepth - 1) {
-        maxAbsoluteDepth = selectedNode.depth + 1;
-    }
-
-    highlightedNode = selectedNode;
-
-    angleFactor = 2 * Math.PI / (selectedNode.magnitude);
-
-    maxPossibleDepth = Math.floor(gRadius / (fontSize * minRingWidthFactor));
-
-    if (maxPossibleDepth < 4) {
-        maxPossibleDepth = 4;
-    }
-
-    var minRadiusInner = fontSize * 8 / gRadius;
-    var minRadiusFirst = fontSize * 6 / gRadius;
-    var minRadiusOuter = fontSize * 5 / gRadius;
-
-    if (.25 < minRadiusInner) {
-        minRadiusInner = .25;
-    }
-
-    if (.15 < minRadiusFirst) {
-        minRadiusFirst = .15;
-    }
-
-    if (.15 < minRadiusOuter) {
-        minRadiusOuter = .15;
-    }
-
-    // visibility of nodes depends on the depth they are displayed at,
-    // so we need to set the max depth assuming they can all be displayed
-    // and iterate it down based on the deepest child node we can display
-    //
-    var maxDepth;
-    var newMaxDepth = selectedNode.getMaxDepth() - selectedNode.getDepth() + 1;
-    //
-    do {
-        maxDepth = newMaxDepth;
-
-        if (!compress && maxDepth > maxPossibleDepth) {
-            maxDepth = maxPossibleDepth;
-        }
-
-        if (compress) {
-            compressedRadii = new Array(maxDepth);
-
-            compressedRadii[0] = minRadiusInner;
-
-            var offset = 0;
-
-            while
-                (
-                lerp
-                (
-                    Math.atan(offset + 2),
-                    Math.atan(offset + 1),
-                    Math.atan(maxDepth + offset - 1),
-                    minRadiusInner,
-                    1 - minRadiusOuter
-                ) - minRadiusInner > minRadiusFirst &&
-                offset < 10
-                ) {
-                offset++;
-            }
-
-            offset--;
-
-            for (var i = 1; i < maxDepth; i++) {
-                compressedRadii[i] = lerp
-                (
-                    Math.atan(i + offset),
-                    Math.atan(offset),
-                    Math.atan(maxDepth + offset - 1),
-                    minRadiusInner,
-                    1 - minRadiusOuter
-                )
-            }
-        }
-        else {
-            nodeRadius = 1 / maxDepth;
-        }
-
-        newMaxDepth = selectedNode.maxVisibleDepth(maxDepth);
-
-        if (compress) {
-            if (newMaxDepth <= maxPossibleDepth) {
-//				compress
-            }
-        }
-        else {
-            if (newMaxDepth > maxPossibleDepth) {
-                newMaxDepth = maxPossibleDepth;
-            }
-        }
-    }
-    while (newMaxDepth < maxDepth);
-
-    maxDisplayDepth = maxDepth;
-
-    lightnessFactor = (lightnessMax - lightnessBase)
-        / (maxDepth > 8 ? 8 : maxDepth);
-    keys = 0;
-
-    nLabelOffsets = new Array(maxDisplayDepth - 1);
-    labelOffsets = new Array(maxDisplayDepth - 1);
-    labelLastNodes = new Array(maxDisplayDepth - 1);
-    labelFirstNodes = new Array(maxDisplayDepth - 1);
-
-    for (var i = 0; i < maxDisplayDepth - 1; i++) {
-        if (compress) {
-            if (i == maxDisplayDepth - 1) {
-                nLabelOffsets[i] = 0;
-            }
-            else {
-                var width =
-                    (compressedRadii[i + 1] - compressedRadii[i]) *
-                    gRadius;
-
-                nLabelOffsets[i] = Math.floor(width / fontSize / 1.2);
-
-                if (nLabelOffsets[i] > 2) {
-                    nLabelOffsets[i] = min
-                    (
-                        Math.floor(width / fontSize / 1.75),
-                        5
-                    );
-                }
-            }
-        }
-        else {
-            nLabelOffsets[i] = Math.max
-            (
-                Math.floor(Math.sqrt((nodeRadius * gRadius / fontSize)) * 1.5),
-                3
-            );
-        }
-
-        labelOffsets[i] = Math.floor((nLabelOffsets[i] - 1) / 2);
-        labelLastNodes[i] = new Array(nLabelOffsets[i] + 1);
-        labelFirstNodes[i] = new Array(nLabelOffsets[i] + 1);
-
-        for (var j = 0; j <= nLabelOffsets[i]; j++) {
-            // these arrays will allow nodes with neighboring labels to link to
-            // each other to determine max label length
-
-            labelLastNodes[i][j] = 0;
-            labelFirstNodes[i][j] = 0;
-        }
-    }
-
-    fontSizeText.innerHTML = fontSize;
-    fontNormal = fontSize + 'px ' + fontFamily;
-    context.font = fontNormal;
-    fontBold = 'bold ' + fontSize + 'px ' + fontFamily;
-    tickLength = fontSize * .7;
-
-    head.setTargets(0);
-
-    keySize = ((imageHeight - margin * 3) * 1 / 2) / keys * 3 / 4;
-
-    if (keySize > fontSize * maxKeySizeFactor) {
-        keySize = fontSize * maxKeySizeFactor;
-    }
-
-    keyBuffer = keySize / 3;
-
-    fontSizeLast = fontSize;
-
-    if (datasetChanged) {
-        datasetChanged = false;
-    }
-    else {
-        datasetAlpha.start = 0;
-    }
-
-    var date = new Date();
-    tweenStartTime = date.getTime();
-    progress = 0;
-    tweenFrames = 0;
-
-    updateKeyControl();
-    updateDatasetWidths();
-
-    document.title = ('Re@ - ' +
-        location.href.split("/").slice(-1)[0].split(".html")[0]);
-    updateNavigationButtons();
-    snapshotButton.disabled = true;
-
-    maxAbsoluteDepthText.innerHTML = maxAbsoluteDepth - 1;
-
-    maxAbsoluteDepthButtonDecrease.disabled = (maxAbsoluteDepth == 2);
-    maxAbsoluteDepthButtonIncrease.disabled =
-        (maxAbsoluteDepth == head.maxDepth);
-
-    bkgBrightButtonDecrease.disabled = (bkgBright == '555555');
-    bkgBrightButtonIncrease.disabled = (bkgBright == 'ffffff');
-
-    if (collapse != collapseLast && search.value != '') {
-        onSearchChange();
-        collapseLast = collapse;
-    }
-}
-
-function updateMaxAbsoluteDepth() {
-    while (maxAbsoluteDepth > 1 && selectedNode.depth > maxAbsoluteDepth - 1) {
-        selectedNode = selectedNode.getParent();
-    }
-}
-
-function updateNavigationButtons() {
-    backButton.disabled = (nodeHistoryPosition == 0);
-//	upButton.disabled = (selectedNode.getParent() == 0);
-    forwardButton.disabled = (nodeHistoryPosition == nodeHistory.length);
-}
-
-function useHue() {
-    return useHueCheckBox && useHueCheckBox.checked;
-}
-
-/*
-function zoomOut()
-{
-	return (
-		selectedNodeLast != 0 &&
-		selectedNodeLast.getDepth() < selectedNode.getDepth());
-}
-*/</script></head><body><img id="hiddenImage" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oLCBQhNQwWVnsAAAAidEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVAgb24gYSBNYWOHqHdDAAABE0lEQVQYGQEIAff+AwAAABkAAAAAAAAA+gAAAAAAAAAAAAAAAAAAAAAAAAAMAwAAAAAAAAANAAAAAAAAAPoAAAAAAAAADAAAAAYAAAD0AwAAAPoAAAAAAAAAAAAAAPoAAAAMAAAADQAAAPoAAAD6AAAAAAAAAAAAAAAAAAAAAAwAAAAZAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAABkAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAGQAAAAwAAAAAAAAADAAAAAwAAAAABAAAAAAAAAAAAAAA8wAAAPQAAAAAAAAAAAAAAA0AAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAZRssKC5OpXwYAAAAASUVORK5CYII=" style="display:none"><img id="loadingImage" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" style="display:none"><img id="logo" src="data:image/png;base64,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
-" style="display:none"><noscript>Javascript must be enabled to view this page.</noscript><div style="display:none"><krona collapse="true" key="true" chart="TAXOMIC"><attributes magnitude="count"><attribute display="Count" dataAll="members" tip="Number of reads assigned to this and child taxa">count</attribute><attribute display="Unassigned" dataNode="members" tip="Number of reads assigned specifically to this taxon">unassigned</attribute><attribute display="TaxID" mono="true" hrefBase="https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&amp;id=" tip="Taxonomic identifier">tid</attribute><attribute display="Rank" mono="true" tip="Taxonomic rank/level">rank</attribute><attribute display="Kmer coverage (%)" tip="Averaged score of reads assigned to this and child taxa">score</attribute></attributes><datasets rawSamples="1"><dataset isctr="False" sread="99" sclas="99" sfilt="99" scmin="36" scavg="99.94949494949495" scmax="347" lnmin="198 nt" lnavg="533 nt" lnmax="602 nt" tclas="13" tfilt="13" tfold="2" sclim="None" totnt="52.81 knt">test-data/kraken_test/kraken</dataset></datasets><color attribute="score" hueStart="0" hueEnd="300" valueStart="26.8" valueEnd="31.6" default="true"> </color><node name="root" href="https://www.google.com/search?q=root"><count><val>34</val></count><unassigned><val></val></unassigned><tid><val href="1">1</val></tid><rank><val>no_rank</val></rank><score><val>26.8</val></score><node name="Bacteria" href="https://www.google.com/search?q=Bacteria"><count><val>34</val></count><unassigned><val></val></unassigned><tid><val href="2">2</val></tid><rank><val>superkingdom</val></rank><score><val>26.8</val></score><node name="Proteobacteria" href="https://www.google.com/search?q=Proteobacteria"><count><val>34</val></count><unassigned><val></val></unassigned><tid><val href="1224">1224</val></tid><rank><val>phylum</val></rank><score><val>26.8</val></score><node name="Gammaproteobacteria" href="https://www.google.com/search?q=Gammaproteobacteria"><count><val>34</val></count><unassigned><val></val></unassigned><tid><val href="1236">1236</val></tid><rank><val>class</val></rank><score><val>26.8</val></score><node name="Unnamed" href="https://www.google.com/search?q=Unnamed"><count><val>34</val></count><unassigned><val></val></unassigned><tid><val href="91347">91347</val></tid><rank><val>order</val></rank><score><val>26.8</val></score><node name="Enterobacteriaceae" href="https://www.google.com/search?q=Enterobacteriaceae"><count><val>34</val></count><unassigned><val>9</val></unassigned><tid><val href="543">543</val></tid><rank><val>family</val></rank><score><val>26.8</val></score><node name="Enterobacter" href="https://www.google.com/search?q=Enterobacter"><count><val>25</val></count><unassigned><val>25</val></unassigned><tid><val href="547">547</val></tid><rank><val>genus</val></rank><score><val>31.6</val></score></node></node></node></node></node></node></node></krona></div></body></html>
\ No newline at end of file
--- a/output.rcf.stat.csv	Wed May 18 09:28:48 2022 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-,test-data/kraken_test/kraken
-Seqs. read,99.0
-Seqs. unclass.,0.0
-Seqs. class.,99.0
-Seqs. filtered,99.0
-Score min,36.0
-Score mean,99.94949494949495
-Score max,347.0
-Length min,198.0
-Length mean,533.0
-Length max,602.0
-Total nt read,52814.0
-TIDs class.,13.0
-TIDs filtered,13.0
-TIDs folded,2.0
-Score limit,