OSCR

Quantifying dexterity and grip strength associations between age, cognitive function (MoCA), and cerebellar gray matter volume in healthy adults across the adult lifespan.

Code ↔ Paper

6 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 6 matches · all tie a paragraph to a whole file without given lines: weak matches, whose lines are not tinted
  1. [1] § Materials and methods › Gray matter volume extraction ↔ bhn_eval/niivue.umd.js, the whole file · a weak match · score 0.74 · brain structure, cerebrospinal, fluid, MNI, renderings, bundled · Report a mismatch
  2. [2] § Materials and methods › Scanning protocol ↔ bhn_eval/tf.min.js, the whole file · a weak match · score 0.65 · repetition, protocol, channel, RAGE, flip, sequence · Report a mismatch
  3. [3] § Materials and methods › Gray matter volume extraction ↔ bhn_eval/niivue.umd.js, the whole file · a weak match · score 0.62 · right lateral, left lateral, inferior, renderings, slices, surface · Report a mismatch
  4. [4] § Materials and methods › Gray matter volume extraction ↔ bundles/aal3/data.js, the whole file · a weak match · score 0.58 · right lateral, left lateral, posterolateral, inferior, right Crus, posterior · Report a mismatch
  5. [5] § Materials and methods › Cognitive assessment ↔ bhn_eval/tf-backend-wasm.min.js, the whole file · a weak match · score 0.51 · routinely, bias, rank, status, ceiling, zero · Report a mismatch
  6. [6] § Materials and methods › Participants ↔ bhn_eval/tf.min.js, the whole file · a weak match · score 0.50 · hour, Unknown, SD, status, race · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

JavaScript · 10 lines · 195 KB · CC-BY-NC-4.0 · 2 matches

  1. (function(sA,qA){typeof exports=="object"&&typeof module<"u"?qA(exports):typeof define=="function"&&define.amd?define(["exports"],qA):(sA=typeof globalThis<"u"?globalThis:sA||self,qA(sA.niivue={}))})(this,function(sA){"use strict";var hc=Object.defineProperty;var ko=sA=>{throw TypeError(sA)};var Dc=(sA,qA,uA)=>qA in sA?hc(sA,qA,{enumerable:!0,configurable:!0,writable:!0,value:uA}):sA[qA]=uA;var G=(sA,qA,uA)=>Dc(sA,typeof qA!="symbol"?qA+"":qA,uA),ZQ=(sA,qA,uA)=>qA.has(sA)||ko("Cannot "+uA);var IA=(sA,qA,uA)=>(ZQ(sA,qA,"read from private field"),uA?uA.call(sA):qA.get(sA)),PA=(sA,qA,uA)=>qA.has(sA)?ko("Cannot add the same private member more than once"):qA instanceof WeakSet?qA.add(sA):qA.set(sA,uA),xA=(sA,qA,uA,Gg)=>(ZQ(sA,qA,"write to private field"),Gg?Gg.call(sA,uA):qA.set(sA,uA),uA),OQ=(sA,qA,uA)=>(ZQ(sA,qA,"access private method"),uA);var GA,cI,wB,lC,Hg,FI,pg,iI,lB,gg,FB,GB,qg,SB,RB,NB,xg,dB,UB,fB,Ro,No,hg,Uo,LB,kB,MB,XQ,Dg,NI,PI,VI;var qA=1e-6,uA=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var B=0,I=arguments.length;I--;)B+=arguments[I]*arguments[I];return Math.sqrt(B)});function Gg(){var B=new uA(9);return uA!=Float32Array&&(B[1]=0,B[2]=0,B[3]=0,B[5]=0,B[6]=0,B[7]=0),B[0]=1,B[4]=1,B[8]=1,B}function Mo(B,I){return B[0]=I[0],B[1]=I[1],B[2]=I[2],B[3]=I[4],B[4]=I[5],B[5]=I[6],B[6]=I[8],B[7]=I[9],B[8]=I[10],B}function XI(B,I,A,g,C,Q,E,i,o){var t=new uA(9);return t[0]=B,t[1]=I,t[2]=A,t[3]=g,t[4]=C,t[5]=Q,t[6]=E,t[7]=i,t[8]=o,t}function Jo(B,I){var A=I[0],g=I[1],C=I[2],Q=I[3],E=I[4],i=I[5],o=I[6],t=I[7],s=I[8],a=s*E-i*t,e=-s*Q+i*o,r=t*Q-E*o,n=A*a+g*e+C*r;return n?(n=1/n,B[0]=a*n,B[1]=(-s*g+C*t)*n,B[2]=(i*g-C*E)*n,B[3]=e*n,B[4]=(s*A-C*o)*n,B[5]=(-i*A+C*Q)*n,B[6]=r*n,B[7]=(-t*A+g*o)*n,B[8]=(E*A-g*Q)*n,B):null}function zQ(B,I,A){var g=I[0],C=I[1],Q=I[2],E=I[3],i=I[4],o=I[5],t=I[6],s=I[7],a=I[8],e=A[0],r=A[1],n=A[2],h=A[3],D=A[4],w=A[5],y=A[6],F=A[7],c=A[8];return B[0]=e*g+r*E+n*t,B[1]=e*C+r*i+n*s,B[2]=e*Q+r*o+n*a,B[3]=h*g+D*E+w*t,B[4]=h*C+D*i+w*s,B[5]=h*Q+D*o+w*a,B[6]=y*g+F*E+c*t,B[7]=y*C+F*i+c*s,B[8]=y*Q+F*o+c*a,B}function MA(){var B=new uA(16);return uA!=Float32Array&&(B[1]=0,B[2]=0,B[3]=0,B[4]=0,B[6]=0,B[7]=0,B[8]=0,B[9]=0,B[11]=0,B[12]=0,B[13]=0,B[14]=0),B[0]=1,B[5]=1,B[10]=1,B[15]=1,B}function jA(B){var I=new uA(16);return I[0]=B[0],I[1]=B[1],I[2]=B[2],I[3]=B[3],I[4]=B[4],I[5]=B[5],I[6]=B[6],I[7]=B[7],I[8]=B[8],I[9]=B[9],I[10]=B[10],I[11]=B[11],I[12]=B[12],I[13]=B[13],I[14]=B[14],I[15]=B[15],I}function Yo(B,I){return B[0]=I[0],B[1]=I[1],B[2]=I[2],B[3]=I[3],B[4]=I[4],B[5]=I[5],B[6]=I[6],B[7]=I[7],B[8]=I[8],B[9]=I[9],B[10]=I[10],B[11]=I[11],B[12]=I[12],B[13]=I[13],B[14]=I[14],B[15]=I[15],B}function yI(B,I,A,g,C,Q,E,i,o,t,s,a,e,r,n,h){var D=new uA(16);return D[0]=B,D[1]=I,D[2]=A,D[3]=g,D[4]=C,D[5]=Q,D[6]=E,D[7]=i,D[8]=o,D[9]=t,D[10]=s,D[11]=a,D[12]=e,D[13]=r,D[14]=n,D[15]=h,D}function jQ(B){return B[0]=1,B[1]=0,B[2]=0,B[3]=0,B[4]=0,B[5]=1,B[6]=0,B[7]=0,B[8]=0,B[9]=0,B[10]=1,B[11]=0,B[12]=0,B[13]=0,B[14]=0,B[15]=1,B}function rI(B,I){if(B===I){var A=I[1],g=I[2],C=I[3],Q=I[6],E=I[7],i=I[11];B[1]=I[4],B[2]=I[8],B[3]=I[12],B[4]=A,B[6]=I[9],B[7]=I[13],B[8]=g,B[9]=Q,B[11]=I[14],B[12]=C,B[13]=E,B[14]=i}else B[0]=I[0],B[1]=I[4],B[2]=I[8],B[3]=I[12],B[4]=I[1],B[5]=I[5],B[6]=I[9],B[7]=I[13],B[8]=I[2],B[9]=I[6],B[10]=I[10],B[11]=I[14],B[12]=I[3],B[13]=I[7],B[14]=I[11],B[15]=I[15];return B}function nI(B,I){var A=I[0],g=I[1],C=I[2],Q=I[3],E=I[4],i=I[5],o=I[6],t=I[7],s=I[8],a=I[9],e=I[10],r=I[11],n=I[12],h=I[13],D=I[14],w=I[15],y=A*i-g*E,F=A*o-C*E,c=A*t-Q*E,R=g*o-C*i,l=g*t-Q*i,S=C*t-Q*o,N=s*h-a*n,d=s*D-e*n,L=s*w-r*n,k=a*D-e*h,U=a*w-r*h,Y=e*w-r*D,K=y*Y-F*U+c*k+R*L-l*d+S*N;return K?(K=1/K,B[0]=(i*Y-o*U+t*k)*K,B[1]=(C*U-g*Y-Q*k)*K,B[2]=(h*S-D*l+w*R)*K,B[3]=(e*l-a*S-r*R)*K,B[4]=(o*L-E*Y-t*d)*K,B[5]=(A*Y-C*L+Q*d)*K,B[6]=(D*c-n*S-w*F)*K,B[7]=(s*S-e*c+r*F)*K,B[8]=(E*U-i*L+t*N)*K,B[9]=(g*L-A*U-Q*N)*K,B[10]=(n*l-h*c+w*y)*K,B[11]=(a*c-s*l-r*y)*K,B[12]=(i*d-E*k-o*N)*K,B[13]=(A*k-g*d+C*N)*K,B[14]=(h*F-n*R-D*y)*K,B[15]=(s*R-a*F+e*y)*K,B):null}function HI(B,I,A){var g=I[0],C=I[1],Q=I[2],E=I[3],i=I[4],o=I[5],t=I[6],s=I[7],a=I[8],e=I[9],r=I[10],n=I[11],h=I[12],D=I[13],w=I[14],y=I[15],F=A[0],c=A[1],R=A[2],l=A[3];return B[0]=F*g+c*i+R*a+l*h,B[1]=F*C+c*o+R*e+l*D,B[2]=F*Q+c*t+R*r+l*w,B[3]=F*E+c*s+R*n+l*y,F=A[4],c=A[5],R=A[6],l=A[7],B[4]=F*g+c*i+R*a+l*h,B[5]=F*C+c*o+R*e+l*D,B[6]=F*Q+c*t+R*r+l*w,B[7]=F*E+c*s+R*n+l*y,F=A[8],c=A[9],R=A[10],l=A[11],B[8]=F*g+c*i+R*a+l*h,B[9]=F*C+c*o+R*e+l*D,B[10]=F*Q+c*t+R*r+l*w,B[11]=F*E+c*s+R*n+l*y,F=A[12],c=A[13],R=A[14],l=A[15],B[12]=F*g+c*i+R*a+l*h,B[13]=F*C+c*o+R*e+l*D,B[14]=F*Q+c*t+R*r+l*w,B[15]=F*E+c*s+R*n+l*y,B}function Eg(B,I,A){var g=A[0],C=A[1],Q=A[2],E,i,o,t,s,a,e,r,n,h,D,w;return I===B?(B[12]=I[0]*g+I[4]*C+I[8]*Q+I[12],B[13]=I[1]*g+I[5]*C+I[9]*Q+I[13],B[14]=I[2]*g+I[6]*C+I[10]*Q+I[14],B[15]=I[3]*g+I[7]*C+I[11]*Q+I[15]):(E=I[0],i=I[1],o=I[2],t=I[3],s=I[4],a=I[5],e=I[6],r=I[7],n=I[8],h=I[9],D=I[10],w=I[11],B[0]=E,B[1]=i,B[2]=o,B[3]=t,B[4]=s,B[5]=a,B[6]=e,B[7]=r,B[8]=n,B[9]=h,B[10]=D,B[11]=w,B[12]=E*g+s*C+n*Q+I[12],B[13]=i*g+a*C+h*Q+I[13],B[14]=o*g+e*C+D*Q+I[14],B[15]=t*g+r*C+w*Q+I[15]),B}function FC(B,I,A){var g=A[0],C=A[1],Q=A[2];return B[0]=I[0]*g,B[1]=I[1]*g,B[2]=I[2]*g,B[3]=I[3]*g,B[4]=I[4]*C,B[5]=I[5]*C,B[6]=I[6]*C,B[7]=I[7]*C,B[8]=I[8]*Q,B[9]=I[9]*Q,B[10]=I[10]*Q,B[11]=I[11]*Q,B[12]=I[12],B[13]=I[13],B[14]=I[14],B[15]=I[15],B}function jg(B,I,A){var g=Math.sin(A),C=Math.cos(A),Q=I[4],E=I[5],i=I[6],o=I[7],t=I[8],s=I[9],a=I[10],e=I[11];return I!==B&&(B[0]=I[0],B[1]=I[1],B[2]=I[2],B[3]=I[3],B[12]=I[12],B[13]=I[13],B[14]=I[14],B[15]=I[15]),B[4]=Q*C+t*g,B[5]=E*C+s*g,B[6]=i*C+a*g,B[7]=o*C+e*g,B[8]=t*C-Q*g,B[9]=s*C-E*g,B[10]=a*C-i*g,B[11]=e*C-o*g,B}function mo(B,I,A){var g=Math.sin(A),C=Math.cos(A),Q=I[0],E=I[1],i=I[2],o=I[3],t=I[8],s=I[9],a=I[10],e=I[11];return I!==B&&(B[4]=I[4],B[5]=I[5],B[6]=I[6],B[7]=I[7],B[12]=I[12],B[13]=I[13],B[14]=I[14],B[15]=I[15]),B[0]=Q*C-t*g,B[1]=E*C-s*g,B[2]=i*C-a*g,B[3]=o*C-e*g,B[8]=Q*g+t*C,B[9]=E*g+s*C,B[10]=i*g+a*C,B[11]=o*g+e*C,B}function _g(B,I,A){var g=Math.sin(A),C=Math.cos(A),Q=I[0],E=I[1],i=I[2],o=I[3],t=I[4],s=I[5],a=I[6],e=I[7];return I!==B&&(B[8]=I[8],B[9]=I[9],B[10]=I[10],B[11]=I[11],B[12]=I[12],B[13]=I[13],B[14]=I[14],B[15]=I[15]),B[0]=Q*C+t*g,B[1]=E*C+s*g,B[2]=i*C+a*g,B[3]=o*C+e*g,B[4]=t*C-Q*g,B[5]=s*C-E*g,B[6]=a*C-i*g,B[7]=e*C-o*g,B}function Ko(B,I,A){var g=A[0],C=A[1],Q=A[2],E=Math.hypot(g,C,Q),i,o,t;return E<qA?null:(E=1/E,g*=E,C*=E,Q*=E,i=Math.sin(I),o=Math.cos(I),t=1-o,B[0]=g*g*t+o,B[1]=C*g*t+Q*i,B[2]=Q*g*t-C*i,B[3]=0,B[4]=g*C*t-Q*i,B[5]=C*C*t+o,B[6]=Q*C*t+g*i,B[7]=0,B[8]=g*Q*t+C*i,B[9]=C*Q*t-g*i,B[10]=Q*Q*t+o,B[11]=0,B[12]=0,B[13]=0,B[14]=0,B[15]=1,B)}function uo(B,I,A,g,C,Q,E){var i=1/(I-A),o=1/(g-C),t=1/(Q-E);return B[0]=-2*i,B[1]=0,B[2]=0,B[3]=0,B[4]=0,B[5]=-2*o,B[6]=0,B[7]=0,B[8]=0,B[9]=0,B[10]=2*t,B[11]=0,B[12]=(I+A)*i,B[13]=(C+g)*o,B[14]=(E+Q)*t,B[15]=1,B}var bB=uo;function Ho(B,I,A){return B[0]=I[0]*A,B[1]=I[1]*A,B[2]=I[2]*A,B[3]=I[3]*A,B[4]=I[4]*A,B[5]=I[5]*A,B[6]=I[6]*A,B[7]=I[7]*A,B[8]=I[8]*A,B[9]=I[9]*A,B[10]=I[10]*A,B[11]=I[11]*A,B[12]=I[12]*A,B[13]=I[13]*A,B[14]=I[14]*A,B[15]=I[15]*A,B}var _Q=HI;function TA(){var B=new uA(3);return uA!=Float32Array&&(B[0]=0,B[1]=0,B[2]=0),B}function UI(B){var I=new uA(3);return I[0]=B[0],I[1]=B[1],I[2]=B[2],I}function zI(B){var I=B[0],A=B[1],g=B[2];return Math.hypot(I,A,g)}function BA(B,I,A){var g=new uA(3);return g[0]=B,g[1]=I,g[2]=A,g}function $Q(B,I){return B[0]=I[0],B[1]=I[1],B[2]=I[2],B}function ig(B,I,A){return B[0]=I[0]+A[0],B[1]=I[1]+A[1],B[2]=I[2]+A[2],B}function bA(B,I,A){return B[0]=I[0]-A[0],B[1]=I[1]-A[1],B[2]=I[2]-A[2],B}function GC(B,I,A){return B[0]=Math.min(I[0],A[0]),B[1]=Math.min(I[1],A[1]),B[2]=Math.min(I[2],A[2]),B}function SC(B,I,A){return B[0]=Math.max(I[0],A[0]),B[1]=Math.max(I[1],A[1]),B[2]=Math.max(I[2],A[2]),B}function po(B,I,A){return B[0]=I[0]*A,B[1]=I[1]*A,B[2]=I[2]*A,B}function qo(B,I){var A=I[0]-B[0],g=I[1]-B[1],C=I[2]-B[2];return Math.hypot(A,g,C)}function xo(B,I){return B[0]=-I[0],B[1]=-I[1],B[2]=-I[2],B}function RI(B,I){var A=I[0],g=I[1],C=I[2],Q=A*A+g*g+C*C;return Q>0&&(Q=1/Math.sqrt(Q)),B[0]=I[0]*Q,B[1]=I[1]*Q,B[2]=I[2]*Q,B}function To(B,I){return B[0]*I[0]+B[1]*I[1]+B[2]*I[2]}function WB(B,I,A){var g=I[0],C=I[1],Q=I[2],E=A[0],i=A[1],o=A[2];return B[0]=C*o-Q*i,B[1]=Q*E-g*o,B[2]=g*i-C*E,B}function bo(B,I,A,g){var C=I[0],Q=I[1],E=I[2];return B[0]=C+g*(A[0]-C),B[1]=Q+g*(A[1]-Q),B[2]=E+g*(A[2]-E),B}function AE(B,I,A){var g=I[0],C=I[1],Q=I[2];return B[0]=g*A[0]+C*A[3]+Q*A[6],B[1]=g*A[1]+C*A[4]+Q*A[7],B[2]=g*A[2]+C*A[5]+Q*A[8],B}function RC(B,I){var A=B[0],g=B[1],C=B[2],Q=I[0],E=I[1],i=I[2],o=Math.sqrt(A*A+g*g+C*C),t=Math.sqrt(Q*Q+E*E+i*i),s=o*t,a=s&&To(B,I)/s;return Math.acos(Math.min(Math.max(a,-1),1))}function Wo(B,I){var A=B[0],g=B[1],C=B[2],Q=I[0],E=I[1],i=I[2];return Math.abs(A-Q)<=qA*Math.max(1,Math.abs(A),Math.abs(Q))&&Math.abs(g-E)<=qA*Math.max(1,Math.abs(g),Math.abs(E))&&Math.abs(C-i)<=qA*Math.max(1,Math.abs(C),Math.abs(i))}var IE=bA,$g=zI;(function(){var B=TA();return function(I,A,g,C,Q,E){var i,o;for(A||(A=3),g||(g=0),C?o=Math.min(C*A+g,I.length):o=I.length,i=g;i<o;i+=A)B[0]=I[i],B[1]=I[i+1],B[2]=I[i+2],Q(B,B,E),I[i]=B[0],I[i+1]=B[1],I[i+2]=B[2];return I}})();function pI(){var B=new uA(4);return uA!=Float32Array&&(B[0]=0,B[1]=0,B[2]=0,B[3]=0),B}function qI(B){var I=new uA(4);return I[0]=B[0],I[1]=B[1],I[2]=B[2],I[3]=B[3],I}function WA(B,I,A,g){var C=new uA(4);return C[0]=B,C[1]=I,C[2]=A,C[3]=g,C}function gE(B,I,A){return B[0]=I[0]+A[0],B[1]=I[1]+A[1],B[2]=I[2]+A[2],B[3]=I[3]+A[3],B}function vo(B,I,A){return B[0]=I[0]-A[0],B[1]=I[1]-A[1],B[2]=I[2]-A[2],B[3]=I[3]-A[3],B}function Po(B,I,A){return B[0]=I[0]*A,B[1]=I[1]*A,B[2]=I[2]*A,B[3]=I[3]*A,B}function CI(B,I,A){var g=I[0],C=I[1],Q=I[2],E=I[3];return B[0]=A[0]*g+A[4]*C+A[8]*Q+A[12]*E,B[1]=A[1]*g+A[5]*C+A[9]*Q+A[13]*E,B[2]=A[2]*g+A[6]*C+A[10]*Q+A[14]*E,B[3]=A[3]*g+A[7]*C+A[11]*Q+A[15]*E,B}var Vo=vo;(function(){var B=pI();return function(I,A,g,C,Q,E){var i,o;for(A||(A=4),g||(g=0),C?o=Math.min(C*A+g,I.length):o=I.length,i=g;i<o;i+=A)B[0]=I[i],B[1]=I[i+1],B[2]=I[i+2],B[3]=I[i+3],Q(B,B,E),I[i]=B[0],I[i+1]=B[1],I[i+2]=B[2],I[i+3]=B[3];return I}})();function Zo(){var B=new uA(2);return uA!=Float32Array&&(B[0]=0,B[1]=0),B}function Oo(B,I){var A=new uA(2);return A[0]=B,A[1]=I,A}(function(){var B=Zo();return function(I,A,g,C,Q,E){var i,o;for(A||(A=2),g||(g=0),C?o=Math.min(C*A+g,I.length):o=I.length,i=g;i<o;i+=A)B[0]=I[i],B[1]=I[i+1],Q(B,B,E),I[i]=B[0],I[i+1]=B[1];return I}})();const Xo={version:"0.69.0"},JA={TEXTURE0_BACK_VOL:33984,TEXTURE1_COLORMAPS:33985,TEXTURE2_OVERLAY_VOL:33986,TEXTURE3_FONT:33987,TEXTURE5_MATCAP:33989,TEXTURE6_GRADIENT:33990,TEXTURE7_DRAW:33991,TEXTURE8_PAQD:33992,TEXTURE10_DRAW_SMOOTH:33994,TEXTURE9_ORIENT:33993,TEXTURE11_GC_BACK:33995,TEXTURE12_GC_STRENGTH0:33996,TEXTURE13_GC_STRENGTH1:33997,TEXTURE14_GC_LABEL0:33998,TEXTURE15_GC_LABEL1:33999},zo=new Float32Array([-1,-1,-1,.28,.28,.28,-1,-1,-1,.28,.28,.28,-1,1,-1,.28,.28,.28,1,-1,-1,.28,.28,.28,1,1,-1,.28,.28,.28,1,1,-1,.28,.28,.28,-1,-1,1,.8,.8,.8,-1,-1,1,.8,.8,.8,1,-1,1,.8,.8,.8,-1,1,1,.8,.8,.8,1,1,1,.8,.8,.8,1,1,1,.8,.8,.8,-1,1,-1,0,0,.74,-1,1,-1,0,0,.74,-1,1,1,0,0,.74,1,1,-1,0,0,.74,1,1,1,0,0,.74,1,1,1,0,0,.74,-1,-1,-1,.42,0,.42,-1,-1,-1,.42,0,.42,1,-1,-1,.42,0,.42,-1,-1,1,.42,0,.42,1,-1,1,.42,0,.42,1,-1,1,.42,0,.42,-1,-1,-1,.64,0,0,-1,-1,-1,.64,0,0,-1,-1,1,.64,0,0,-1,1,-1,.64,0,0,-1,1,1,.64,0,0,-1,1,1,.64,0,0,1,-1,-1,0,.5,0,1,-1,-1,0,.5,0,1,1,-1,0,.5,0,1,-1,1,0,.5,0,1,1,1,0,.5,0,1,1,1,0,.5,0,-.45,1,-.8,0,0,0,-.45,1,-.8,0,0,0,-.45,1,.8,0,0,0,-.25,1,-.8,0,0,0,-.25,1,.8,0,0,0,-.25,1,.8,0,0,0,-.25,1,.6,0,0,0,-.25,1,.6,0,0,0,-.25,1,.8,0,0,0,.45,1,.6,0,0,0,.25,1,.8,0,0,0,.25,1,.8,0,0,0,.25,1,.1,0,0,0,.25,1,.1,0,0,0,.25,1,.6,0,0,0,.45,1,.1,0,0,0,.45,1,.6,0,0,0,.45,1,.6,0,0,0,-.25,1,-.1,0,0,0,-.25,1,-.1,0,0,0,-.25,1,.1,0,0,0,.25,1,-.1,0,0,0,.45,1,.1,0,0,0,.45,1,.1,0,0,0,.45,-1,-.8,0,0,0,.45,-1,-.8,0,0,0,.05,-1,.8,0,0,0,.25,-1,-.8,0,0,0,-.15,-1,.8,0,0,0,-.15,-1,.8,0,0,0,-.25,-1,-.8,0,0,0,-.25,-1,-.8,0,0,0,.05,-1,.8,0,0,0,-.45,-1,-.8,0,0,0,-.15,-1,.8,0,0,0,-.15,-1,.8,0,0,0,.13,-1,-.3,0,0,0,.13,-1,-.3,0,0,0,.07,-1,-.1,0,0,0,-.33,-1,-.3,0,0,0,-.27,-1,-.1,0,0,0,-.27,-1,-.1,0,0,0,-.45,.6,1,0,0,0,-.45,.6,1,0,0,0,-.45,.4,1,0,0,0,-.25,.8,1,0,0,0,-.25,.4,1,0,0,0,-.25,.4,1,0,0,0,-.25,.8,1,0,0,0,-.25,.8,1,0,0,0,-.25,.6,1,0,0,0,.25,.8,1,0,0,0,.45,.6,1,0,0,0,.45,.6,1,0,0,0,.25,.8,1,0,0,0,.25,.8,1,0,0,0,.25,-.1,1,0,0,0,.45,.6,1,0,0,0,.45,.1,1,0,0,0,.45,.1,1,0,0,0,-.25,.1,1,0,0,0,-.25,.1,1,0,0,0,-.45,-.1,1,0,0,0,.25,.1,1,0,0,0,.25,-.1,1,0,0,0,.25,-.1,1,0,0,0,-.45,-.1,1,0,0,0,-.45,-.1,1,0,0,0,-.45,-.6,1,0,0,0,-.25,-.1,1,0,0,0,-.25,-.8,1,0,0,0,-.25,-.8,1,0,0,0,-.25,-.6,1,0,0,0,-.25,-.6,1,0,0,0,-.25,-.8,1,0,0,0,.45,-.6,1,0,0,0,.25,-.8,1,0,0,0,.25,-.8,1,0,0,0,.25,-.4,1,0,0,0,.25,-.4,1,0,0,0,.25,-.6,1,0,0,0,.45,-.4,1,0,0,0,.45,-.6,1,0,0,0,.45,-.6,1,0,0,0,-.1,-.8,-1,0,0,0,-.1,-.8,-1,0,0,0,-.1,.8,-1,0,0,0,.1,-.8,-1,0,0,0,.1,.8,-1,0,0,0,.1,.8,-1,0,0,0,-1,-.45,-.8,0,0,0,-1,-.45,-.8,0,0,0,-1,-.45,.8,0,0,0,-1,-.25,-.8,0,0,0,-1,-.25,.8,0,0,0,-1,-.25,.8,0,0,0,-1,-.25,-.8,0,0,0,-1,-.25,-.8,0,0,0,-1,-.25,-.6,0,0,0,-1,.45,-.8,0,0,0,-1,.45,-.6,0,0,0,-1,.45,-.6,0,0,0,1,.45,-.8,0,0,0,1,.45,-.8,0,0,0,1,.45,.8,0,0,0,1,.25,-.8,0,0,0,1,.25,.8,0,0,0,1,.25,.8,0,0,0,1,.25,.6,0,0,0,1,.25,.6,0,0,0,1,.25,.8,0,0,0,1,-.45,.6,0,0,0,1,-.25,.8,0,0,0,1,-.25,.8,0,0,0,1,-.25,.1,0,0,0,1,-.25,.1,0,0,0,1,-.25,.6,0,0,0,1,-.45,.1,0,0,0,1,-.45,.6,0,0,0,1,-.45,.6,0,0,0,1,.25,-.1,0,0,0,1,.25,-.1,0,0,0,1,.25,.1,0,0,0,1,-.25,-.1,0,0,0,1,-.45,.1,0,0,0,1,-.45,.1,0,0,0,1,-.25,-.8,0,0,0,1,-.25,-.8,0,0,0,1,-.05,-.1,0,0,0,1,-.45,-.8,0,0,0,1,-.25,-.1,0,0,0,1,-.25,-.1,0,0,0]),HA=class HA{constructor(I,A,g,C,Q=null,E=null){G(this,"sphereIdx",[]);G(this,"sphereVtx",[]);G(this,"renderShaders",[]);G(this,"isVisible",!0);G(this,"isPickable",!0);G(this,"vertexBuffer");G(this,"indexCount");G(this,"indexBuffer");G(this,"vao");G(this,"mode");G(this,"glFlags",0);G(this,"id");G(this,"colorId");G(this,"modelMatrix",MA());G(this,"scale",[1,1,1]);G(this,"position",[0,0,0]);G(this,"rotation",[0,0,0]);G(this,"rotationRadians",0);G(this,"extentsMin",[]);G(this,"extentsMax",[]);G(this,"furthestVertexFromOrigin");G(this,"originNegate");G(this,"fieldOfViewDeObliqueMM");G(this,"mm");this.vertexBuffer=A,this.indexCount=C,this.indexBuffer=Q,this.vao=E,this.mode=g,this.id=I,this.colorId=[(I>>0&255)/255,(I>>8&255)/255,(I>>16&255)/255,(I>>24&255)/255]}};G(HA,"BLEND",1),G(HA,"CULL_FACE",2),G(HA,"CULL_FRONT",4),G(HA,"CULL_BACK",8),G(HA,"ENABLE_DEPTH_TEST",16),G(HA,"generateCrosshairs",function(I,A,g,C,Q,E,i=20,o=0){const t=HA.generateCrosshairsGeometry(I,g,C,Q,E,i,o);return new HA(A,t.vertexBuffer,I.TRIANGLES,t.indexCount,t.indexBuffer,t.vao)}),G(HA,"generateCrosshairsGeometry",function(I,A,g,C,Q,E=20,i=0){const o=[],t=[],s=Q*i;if(s<=0){let n=BA(g[0],A[1],A[2]),h=BA(C[0],A[1],A[2]);HA.makeCylinder(o,t,n,h,Q,E),n=BA(A[0],g[1],A[2]),h=BA(A[0],C[1],A[2]),HA.makeCylinder(o,t,n,h,Q,E),n=BA(A[0],A[1],g[2]),h=BA(A[0],A[1],C[2]),HA.makeCylinder(o,t,n,h,Q,E)}else{let n=BA(g[0],A[1],A[2]),h=BA(A[0]-s,A[1],A[2]);HA.makeCylinder(o,t,n,h,Q,E,!1),n=BA(A[0]+s,A[1],A[2]),h=BA(C[0],A[1],A[2]),HA.makeCylinder(o,t,n,h,Q,E,!1),n=BA(A[0],g[1],A[2]),h=BA(A[0],A[1]-s,A[2]),HA.makeCylinder(o,t,n,h,Q,E,!1),n=BA(A[0],A[1]+s,A[2]),h=BA(A[0],C[1],A[2]),HA.makeCylinder(o,t,n,h,Q,E,!1),n=BA(A[0],A[1],g[2]),h=BA(A[0],A[1],A[2]-s),HA.makeCylinder(o,t,n,h,Q,E,!1),n=BA(A[0],A[1],A[2]+s),h=BA(A[0],A[1],C[2]),HA.makeCylinder(o,t,n,h,Q,E,!1)}const a=I.createBuffer();if(a===null)throw new Error("could not instantiate vertex buffer");I.bindBuffer(I.ARRAY_BUFFER,a),I.bufferData(I.ARRAY_BUFFER,new Float32Array(o),I.STATIC_DRAW);const e=I.createBuffer();if(e===null)throw new Error("could not instantiate index buffer");I.bindBuffer(I.ELEMENT_ARRAY_BUFFER,e),I.bufferData(I.ELEMENT_ARRAY_BUFFER,new Uint32Array(t),I.STATIC_DRAW);const r=I.createVertexArray();return I.bindVertexArray(r),I.bindBuffer(I.ELEMENT_ARRAY_BUFFER,e),I.bindBuffer(I.ARRAY_BUFFER,a),I.enableVertexAttribArray(0),I.vertexAttribPointer(0,3,I.FLOAT,!1,0,0),I.bindVertexArray(null),{vertexBuffer:a,indexBuffer:e,indexCount:t.length,vao:r}}),G(HA,"getFirstPerpVector",function(I){const A=BA(0,0,0);return I[0]===0?A[0]=1:I[1]===0?A[1]=1:I[2]===0?A[2]=1:(A[0]=I[2],A[1]=I[2],A[2]=-(I[0]+I[1]),RI(A,A)),A}),G(HA,"subdivide",function(I,A){let g=I.length/3,C=A.length/3;const Q=C,E=TA(),i=TA();for(let o=0;o<Q;o++){const t=A[o*3+0],s=A[o*3+1],a=A[o*3+2],e=BA(I[t*3+0],I[t*3+1],I[t*3+2]),r=BA(I[s*3+0],I[s*3+1],I[s*3+2]),n=BA(I[a*3+0],I[a*3+1],I[a*3+2]);ig(E,e,r),RI(i,E),I.push(...i),ig(E,r,n),RI(i,E),I.push(...i),ig(E,e,n),RI(i,E),I.push(...i);let h=[g,g+1,g+2];A.push(...h),h=[t,g,g+2],A.push(...h),h=[g,s,g+1],A.push(...h),A[o*3+0]=g+2,A[o*3+1]=g+1,A[o*3+2]=a,C=C+3,g=g+3}}),G(HA,"weldVertices",function(I,A){const g=I.length/3;let C=0;const Q=new Int32Array(g);for(let o=0;o<g-1;o++){if(Q[o]!==0)continue;Q[o]=C;let t=o*3;const s=I[t],a=I[t+1],e=I[t+2];for(let r=o+1;r<g;r++)t+=3,s===I[t]&&a===I[t+1]&&e===I[t+2]&&(Q[r]=C);C++}if(C===g)return I;const E=A.length;for(let o=0;o<E;o++)A[o]=Q[A[o]];const i=I.slice(0,C*3-1);for(let o=0;o<g-1;o++){const t=o*3,s=Q[o]*3;i[s]=I[t],i[s+1]=I[t+1],i[s+2]=I[t+2]}return i}),G(HA,"makeSphere",function(I,A,g,C=[0,0,0]){let Q=[0,0,1,.894,0,.447,.276,.851,.447,-.724,.526,.447,-.724,-.526,.447,.276,-.851,.447,.724,.526,-.447,-.276,.851,-.447,-.894,0,-.447,-.276,-.851,-.447,.724,-.526,-.447,0,0,-1];const E=[0,1,2,0,2,3,0,3,4,0,4,5,0,5,1,7,6,11,8,7,11,9,8,11,10,9,11,6,10,11,6,2,1,7,3,2,8,4,3,9,5,4,10,1,5,6,7,2,7,8,3,8,9,4,9,10,5,10,6,1];HA.subdivide(Q,E),HA.subdivide(Q,E),Q=HA.weldVertices(Q,E);for(let s=0;s<Q.length;s++)Q[s]=Q[s]*g;const i=Q.length/3;let o=0;for(let s=0;s<i;s++)Q[o]=Q[o]+C[0],o++,Q[o]=Q[o]+C[1],o++,Q[o]=Q[o]+C[2],o++;const t=Math.floor(I.length/3);for(let s=0;s<E.length;s++)E[s]=E[s]+t;A.push(...E),I.push(...Q)}),G(HA,"makeCylinder",function(I,A,g,C,Q,E=20,i=!0){E<3&&(E=3);const o=TA();bA(o,C,g),RI(o,o);const t=HA.getFirstPerpVector(o),s=TA();WB(s,o,t),RI(s,s);let a=2*E,e=2*E;i&&(e+=2*E,a+=2);const r=Math.floor(I.length/3),n=new Uint32Array(e*3),h=new Float32Array(a*3);function D(l,S){h[l*3+0]=S[0],h[l*3+1]=S[1],h[l*3+2]=S[2]}function w(l,S,N,d){n[l*3+0]=S+r,n[l*3+1]=N+r,n[l*3+2]=d+r}const y=2*E,F=y+1;i&&(D(y,g),D(F,C));const c=TA(),R=TA();for(let l=0;l<E;l++){const S=Math.cos(l/E*2*Math.PI),N=Math.sin(l/E*2*Math.PI);c[0]=Q*(S*t[0]+N*s[0]),c[1]=Q*(S*t[1]+N*s[1]),c[2]=Q*(S*t[2]+N*s[2]),ig(R,g,c),D(l,R),ig(R,C,c),D(l+E,R);let d=0;l<E-1&&(d=l+1),w(l*2,l,d,l+E),w(l*2+1,d,d+E,l+E),i&&(w(E*2+l,l,y,d),w(E*2+l+E,F,l+E,d+E))}A.push(...n),I.push(...h)}),G(HA,"makeColoredCylinder",function(I,A,g,C,Q,E,i=[192,0,0,255],o=20,t=!1){let s=I.length/3;HA.makeCylinder(I,A,C,Q,E,o,t),s=I.length/3-s;const a=[];for(let e=0;e<s*4-1;e+=4)a[e]=i[0],a[e+1]=i[1],a[e+2]=i[2],a[e+3]=i[3];g.push(...a)}),G(HA,"makeColoredSphere",function(I,A,g,C,Q=[0,0,0],E=[0,0,192,255]){let i=I.length/3;HA.makeSphere(I,A,C,Q),i=I.length/3-i;const o=[];for(let t=0;t<i*4-1;t+=4)o[t]=E[0],o[t+1]=E[1],o[t+2]=E[2],o[t+3]=E[3];g.push(...o)});let xI=HA;for(var og=256,vB=[],PB;og--;)vB[og]=(og+256).toString(16).substring(1);function VB(){var B=0,I,A="";if(!PB||og+16>256){for(PB=Array(B=256);B--;)PB[B]=256*Math.random()|0;B=og=0}for(;B<16;B++)I=PB[og+B],B==6?A+=vB[I&15|64]:B==8?A+=vB[I&63|128]:A+=vB[I],B&1&&B>1&&B<11&&(A+="-");return og++,A}const lI=class lI{constructor({name:I="niivue",level:A="info"}={}){G(this,"level");G(this,"name");this.name=`${I}`,this.level=A}debug(...I){lI.levels[this.level]>lI.levels.debug||console.debug(`${this.name}-debug`,...I)}info(...I){lI.levels[this.level]>lI.levels.info||console.info(`${this.name}-info`,...I)}warn(...I){lI.levels[this.level]>lI.levels.warn||console.warn(`${this.name}-warn`,...I)}error(...I){lI.levels[this.level]>lI.levels.error||console.error(`${this.name}-error`,...I)}fatal(...I){lI.levels[this.level]>lI.levels.fatal||console.error(`${this.name}-fatal`,...I)}setLogLevel(I){this.level=I}setName(I){this.name=I}};G(lI,"levels",{debug:0,info:1,warn:2,error:3,fatal:4,silent:1/0});let NC=lI;const J=new NC({name:"niivue",level:"info"}),dC=Object.freeze(Object.defineProperty({__proto__:null,$itksnap:{R:[0,255,0,0,255,0,255,255,0,205,210,102,0,0,46,255,106,221,233,165,255,147,218,75,255,60,255,255,218,0,188,255,255,222,127,139,124,255,70,0,238,238,240,245,184,32,255,25,112,34,248,245,255,144,173,65,255,250,128,50,244,255,123,255,173,255,127,255,143,220,253,255,0,0,128,255,250,148,178,255,135,100,240,250,255,107,135,0,139,245,186,255,255,0,210,255,47,72,175,128,176,255,139,240,255,216,119,219,72,255,199,154,189,240,230,0,85,64,153,205,250,95,0,255,224,176,138,30,240,152,160],G:[0,0,255,0,255,255,0,239,0,133,180,205,0,139,139,228,90,160,150,42,250,112,112,0,182,179,235,228,165,128,143,105,218,184,255,69,252,255,130,100,130,232,255,222,134,178,20,25,128,139,248,255,160,238,255,105,99,240,0,205,164,255,104,165,216,192,255,140,188,20,245,250,206,255,0,250,128,0,34,127,206,149,230,235,245,142,206,0,0,245,85,228,222,191,105,248,79,61,238,128,224,240,0,255,215,191,136,112,209,0,21,205,183,248,230,250,107,224,50,92,250,158,128,69,255,196,43,144,128,251,82],B:[0,0,0,255,0,255,255,213,205,63,140,170,128,139,87,225,205,221,122,42,250,219,214,130,193,113,205,196,32,128,143,180,185,135,0,19,0,224,180,0,238,170,240,179,11,170,147,112,144,34,255,250,122,144,47,225,71,230,0,50,96,240,238,0,230,203,212,0,143,60,230,240,209,127,128,205,114,211,34,80,235,237,140,215,238,35,250,139,139,220,211,181,173,255,30,220,79,139,238,0,230,245,0,255,0,216,153,147,204,255,133,50,107,255,250,154,47,208,204,92,210,160,0,0,255,222,226,255,128,152,45],A:[0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],I:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130]},$slicer3d:{labels:["background","tissue","bone","skin","connective tissue","blood","organ","mass","muscle","foreign object","waste","teeth","fat","gray matter","white matter","nerve","vein","artery","capillary","ligament","tendon","cartilage","meniscus","lymph node","lymphatic vessel","cerebro-spinal fluid","bile","urine","feces","gas","fluid","edema","bleeding","necrosis","clot","embolism","head","central nervous system","brain","gray matter of brain","telencephalon","cerebral cortex","right frontal lobe","left frontal lobe","right temporal lobe","left temporal lobe","right parietal lobe","left parietal lobe","right occipital lobe","left occipital lobe","right insular lobe","left insular lobe","right limbic lobe","left limbic lobe","right striatum","left striatum","right caudate nucleus","left caudate nucleus","right putamen","left putamen","right pallidum","left pallidum","right amygdaloid complex","left amygdaloid complex","diencephalon","thalamus","right thalamus","left thalamus","pineal gland","midbrain","substantia nigra","right substantia nigra","left substantia nigra","cerebral white matter","right superior longitudinal fasciculus","left superior longitudinal fasciculus","right inferior longitudinal fasciculus","left inferior longitudinal fasciculus","right arcuate fasciculus","left arcuate fasciculus","right uncinate fasciculus","left uncinate fasciculus","right cingulum bundle","left cingulum bundle","projection fibers","right corticospinal tract","left corticospinal tract","right optic radiation","left optic radiation","right medial lemniscus","left medial lemniscus","right superior cerebellar peduncle","left superior cerebellar peduncle","right middle cerebellar peduncle","left middle cerebellar peduncle","right inferior cerebellar peduncle","left inferior cerebellar peduncle","optic chiasm","right optic tract","left optic tract","right fornix","left fornix","commissural fibers","corpus callosum","posterior commissure","cerebellar white matter","CSF space","ventricles of brain","right lateral ventricle","left lateral ventricle","right third ventricle","left third ventricle","cerebral aqueduct","fourth ventricle","subarachnoid space","spinal cord","gray matter of spinal cord","white matter of spinal cord","endocrine system of brain","pituitary gland","adenohypophysis","neurohypophysis","meninges","dura mater","arachnoid","pia mater","muscles of head","salivary glands","lips","nose","tongue","soft palate","right inner ear","left inner ear","right external ear","left external ear","right middle ear","left middle ear","right eyeball","left eyeball","skull","right frontal bone","left frontal bone","right parietal bone","left parietal bone","right temporal bone","left temporal bone","right sphenoid bone","left sphenoid bone","right ethmoid bone","left ethmoid bone","occipital bone","maxilla","right zygomatic bone","right lacrimal bone","vomer bone","right palatine bone","left palatine bone","mandible","neck","muscles of neck","pharynx","larynx","thyroid gland","right parathyroid glands","left parathyroid glands","skeleton of neck","hyoid bone","cervical vertebral column","thorax","trachea","bronchi","right lung","left lung","superior lobe of right lung","superior lobe of left lung","middle lobe of right lung","inferior lobe of right lung","inferior lobe of left lung","pleura","heart","right atrium","left atrium","atrial septum","ventricular septum","right ventricle of heart","left ventricle of heart","mitral valve","tricuspid valve","aortic valve","pulmonary valve","aorta","pericardium","pericardial cavity","esophagus","thymus","mediastinum","skin of thoracic wall","muscles of thoracic wall","skeleton of thorax","thoracic vertebral column","ribs","sternum","right clavicle","left clavicle","abdominal cavity","abdomen","peritoneum","omentum","peritoneal cavity","retroperitoneal space","stomach","duodenum","small bowel","colon","anus","liver","biliary tree","gallbladder","pancreas","spleen","urinary system","right kidney","left kidney","right ureter","left ureter","urinary bladder","urethra","right adrenal gland","left adrenal gland","female internal genitalia","uterus","right fallopian tube","left fallopian tube","right ovary","left ovary","vagina","male internal genitalia","prostate","right seminal vesicle","left seminal vesicle","right deferent duct","left deferent duct","skin of abdominal wall","muscles of abdominal wall","skeleton of abdomen","lumbar vertebral column","female external genitalia","male external genitalia","skeleton of upper limb","muscles of upper limb","right upper limb","left upper limb","right shoulder","left shoulder","right arm"],R:[0,128,241,177,111,216,221,144,192,220,78,255,230,200,250,244,0,216,183,183,152,111,178,68,111,85,0,214,78,218,170,140,188,216,145,150,177,244,250,200,68,128,83,83,162,162,141,141,182,182,188,188,154,154,177,177,30,30,210,210,48,48,98,98,69,166,122,122,253,145,46,0,0,250,127,127,159,159,125,125,106,106,154,154,126,201,201,78,78,174,174,139,139,148,148,186,186,99,156,156,64,64,138,97,126,194,85,88,88,88,88,88,88,88,88,244,200,250,82,57,60,92,255,255,255,255,201,70,188,177,166,182,229,229,174,174,201,201,194,194,241,203,203,229,229,255,255,209,209,248,248,255,196,255,255,255,242,242,222,177,213,184,150,62,62,62,242,250,255,177,182,175,197,197,172,172,202,224,224,255,206,210,203,233,195,181,152,159,166,218,225,224,255,184,211,47,255,173,188,255,226,253,244,205,205,186,177,255,234,204,180,216,255,205,204,255,221,0,139,249,157,203,185,185,247,247,222,124,249,249,244,255,255,227,213,213,193,216,230,245,245,241,241,177,171,217,212,185,185,198,194,177,177,177,177,177],G:[0,174,214,122,184,101,130,238,104,245,63,250,220,200,250,214,151,101,156,214,189,184,212,172,197,188,145,230,63,255,250,224,65,191,60,98,122,214,250,200,131,174,146,146,115,115,93,93,166,166,135,135,150,150,140,140,111,111,157,157,129,129,153,153,110,113,101,101,135,92,101,108,108,250,150,150,116,116,102,102,174,174,146,146,126,160,160,152,152,140,140,126,126,120,120,135,135,106,171,171,123,123,95,113,161,195,188,106,106,106,106,106,106,106,106,214,200,250,174,157,143,162,244,244,244,244,121,163,91,122,84,105,147,147,122,122,112,112,142,142,213,179,179,204,204,243,243,185,185,223,223,230,172,255,250,237,217,217,198,122,124,105,208,162,162,162,206,210,255,122,228,216,165,165,138,138,164,186,186,245,110,115,108,138,100,85,55,63,70,123,130,97,244,122,171,150,244,121,95,239,202,232,217,179,179,124,122,255,234,142,119,132,253,167,168,224,130,145,150,180,108,136,102,102,182,182,154,186,186,186,170,181,190,153,141,141,123,146,158,172,172,172,172,124,85,198,188,135,135,175,98,122,122,122,122,122],B:[0,128,145,101,210,79,101,144,88,20,0,220,70,235,210,49,206,79,220,211,207,210,242,100,131,255,30,130,0,255,250,228,28,216,66,83,101,49,225,215,98,128,164,164,105,105,137,137,110,110,166,166,201,201,190,190,85,85,166,166,126,126,112,112,53,137,38,38,192,109,131,112,112,225,88,88,163,163,154,154,155,155,83,83,55,133,133,141,141,103,103,177,177,72,72,135,135,24,108,108,147,147,74,158,197,164,255,215,215,215,215,215,215,215,215,49,215,225,128,110,83,109,209,209,209,209,77,117,95,101,94,107,118,118,90,90,73,73,0,0,144,77,77,109,109,152,152,85,85,131,131,138,68,167,160,145,123,123,101,101,109,108,243,114,114,114,142,139,207,101,255,244,145,145,115,115,140,162,162,217,84,89,81,112,73,57,13,27,38,97,104,76,209,154,143,103,209,88,76,172,134,158,154,108,108,161,101,220,194,178,153,105,229,142,143,199,101,30,98,111,162,116,83,83,164,164,132,223,150,150,147,158,165,130,113,113,103,127,140,147,147,151,151,92,68,131,102,134,134,125,79,101,101,101,101,101],A:[0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],I:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]},actc:{R:[0,0,24,248,255],G:[0,0,177,254,0],B:[0,136,0,0,0],A:[0,32,64,78,128],I:[0,64,128,156,255]},afni_blues_inv:{min:0,max:0,R:[0,37],G:[242,0],B:[255,255],A:[0,64],I:[0,255]},afni_reds_inv:{R:[255,255],G:[255,11],B:[0,0],A:[0,64],I:[0,255]},batlow:{R:[1,10,15,17,21,27,36,49,65,82,99,118,140,161,183,203,222,238,248,253,253,253,252,250],G:[25,42,56,68,79,88,97,105,111,116,122,127,133,138,142,146,150,155,162,170,178,186,195,204],B:[89,92,95,96,98,98,96,91,83,74,64,55,46,43,49,62,79,100,126,151,175,199,223,250],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,11,22,33,44,55,66,77,88,99,110,121,133,144,155,166,177,188,199,210,221,232,243,255]},bcgwhw:{R:[255,248,242,235,229,222,212,202,193,183,173,145,117,78,39,0,0,0,0,0,0,64,128,191,255,255,255,255,255,238,221,204,214,224,235,245,255,249,242,236,229,223,217,210,204,197,191,184,176,169,161,154,146,139,132,124,117,109,102,0],G:[255,251,247,243,239,235,235,235,235,235,235,216,197,174,150,127,153,178,204,229,255,255,255,255,255,220,185,150,115,77,38,0,31,61,92,122,153,138,122,107,92,77,61,46,31,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0],B:[255,254,253,252,251,250,251,252,253,254,255,226,198,132,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,80,120,160,200,199,198,197,196,196,195,194,193,192,191,184,176,169,161,154,146,139,132,124,117,109,102,0],A:[256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256],I:[0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,255]},bcgwhw_dark:{R:[0,248,242,235,229,222,212,202,193,183,173,145,117,78,39,0,0,0,0,0,0,64,128,191,255,255,255,255,255,238,221,204,214,224,235,245,255,249,242,236,229,223,217,210,204,197,191,184,176,169,161,154,146,139,132,124,117,109,102,0],G:[0,251,247,243,239,235,235,235,235,235,235,216,197,174,150,127,153,178,204,229,255,255,255,255,255,220,185,150,115,77,38,0,31,61,92,122,153,138,122,107,92,77,61,46,31,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0],B:[0,254,253,252,251,250,251,252,253,254,255,226,198,132,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,80,120,160,200,199,198,197,196,196,195,194,193,192,191,184,176,169,161,154,146,139,132,124,117,109,102,0],A:[256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256],I:[0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,255]},blue:{R:[0,0,0],G:[0,0,0],B:[0,128,255],A:[0,64,128],I:[0,128,255]},blue2cyan:{R:[0,0],G:[0,255],B:[255,255],A:[0,128],I:[0,255]},blue2magenta:{R:[0,255],G:[0,0],B:[255,255],A:[0,128],I:[0,255]},blue2red:{R:[0,0,0,0,196,255],G:[0,32,128,128,128,32],B:[0,255,196,0,0,0],A:[0,128,64,64,64,128],I:[0,1,64,128,192,255]},bluegrn:{R:[0,0,0,0],G:[0,1,128,255],B:[0,222,127,32],A:[0,0,64,128],I:[0,1,128,255]},bone:{R:[0,103,255],G:[0,126,255],B:[0,165,255],A:[0,76,128],I:[0,153,255]},bronze:{R:[0,43,103,199,216,255],G:[0,0,37,155,213,255],B:[0,0,20,97,201,255],A:[0,44,48,54,56,56],I:[0,64,128,196,240,255]},cet_l17:{R:[0,9,24,33,40,46,52,57,62,66,70,74,78,81,85,88,91,94,98,101,103,106,109,112,114,117,119,121,124,126,128,130,133,135,137,139,141,143,145,147,149,151,153,155,157,159,161,163,164,166,168,169,171,172,174,175,177,178,180,181,183,184,186,187,189,190,191,193,194,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,222,223,224,224,225,226,226,227,228,228,229,229,230,231,231,232,233,233,234,234,235,235,236,236,236,237,237,237,238,238,238,239,239,239,240,240,240,241,241,241,242,242,242,243,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,243,243,243,243,243,243,243,243,243,243,243,243,242,242,242,242,242,242,242,242,241,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,243,243,244,244,245,246,246,247,247,248,249,249,250,250,251,251,252,252,253,253,254,254,254],G:[42,41,41,41,40,40,40,39,39,39,38,38,37,37,36,36,35,35,34,34,33,32,32,31,30,30,30,30,29,29,29,29,28,28,28,27,27,27,26,26,26,25,25,25,24,24,24,24,24,25,25,26,27,27,28,28,29,30,30,31,31,32,33,33,34,34,35,36,36,37,38,39,40,42,43,44,45,47,48,49,50,51,53,54,55,56,57,58,59,60,62,63,64,65,66,68,69,71,72,73,75,76,77,79,80,81,83,84,85,87,88,89,90,92,93,94,95,97,98,100,101,102,104,105,107,108,109,111,112,113,115,116,117,119,120,121,122,124,125,126,128,129,130,132,133,134,136,137,138,140,141,142,144,145,146,147,149,150,151,153,154,155,156,158,159,160,161,163,164,165,167,168,169,170,172,173,174,175,176,178,179,180,181,183,184,185,186,187,189,190,191,192,193,194,196,197,198,199,200,201,203,204,205,206,207,208,209,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,228,229,230,231,232,233,234,235,236,237,238,238,239,240,241,241,242,243,244,244,245,246,247,248,248,249,250,251,251,252,253,254,255],B:[167,167,166,166,166,165,165,165,164,164,164,163,163,162,162,162,161,161,161,160,160,160,159,159,158,158,157,157,156,155,155,154,154,153,153,152,151,151,150,150,149,149,148,147,147,146,146,145,144,144,143,143,142,141,141,140,139,139,138,137,137,136,135,135,134,133,133,132,131,131,130,130,129,128,128,127,127,126,125,125,124,124,123,123,122,121,121,120,119,119,118,118,117,116,116,116,115,115,114,114,113,113,113,112,112,111,111,110,110,109,109,109,108,108,107,107,106,106,106,106,106,105,105,105,105,105,105,105,104,104,104,104,104,103,103,103,103,103,102,102,102,103,103,103,103,104,104,104,104,104,105,105,105,105,106,106,106,106,106,107,107,107,107,108,108,109,110,111,111,112,113,113,114,115,115,116,117,117,118,119,120,120,121,122,122,123,124,125,126,128,129,130,131,132,134,135,136,137,138,140,141,142,143,144,146,147,148,149,150,152,153,155,157,158,160,162,163,165,167,168,170,172,173,175,177,178,180,182,183,185,187,188,190,193,196,199,201,204,207,210,212,215,218,221,224,226,229,232,235,238,240,243,246,249,252,255],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]},cividis:{R:[0,86,166,255],G:[32,92,156,233],B:[76,108,117,69],A:[0,56,80,88],I:[0,64,192,255]},cool:{R:[0,0,0],G:[127,196,254],B:[255,255,255],A:[0,64,128],I:[0,128,255]},copper:{R:[0,61,122,183,244,255],G:[0,41,81,122,163,203],B:[0,25,51,76,102,127],A:[0,25,51,71,102,128],I:[0,51,102,153,204,255]},copper2:{R:[0,61,122,183,244,255],G:[0,41,81,122,163,255],B:[0,25,51,76,102,255],A:[0,25,51,71,102,128],I:[0,51,102,153,204,255]},ct_airways:{min:-643,max:-235,R:[0,0,0],G:[154,154,154],B:[179,179,101],A:[0,32,0],I:[0,163,255]},ct_artery:{min:114,max:800,R:[0,255,255,255],G:[0,0,129,255],B:[0,0,0,255],A:[0,64,88,228],I:[0,80,160,255]},ct_bones:{min:180,max:600,R:[0,0,113,255],G:[0,0,109,250],B:[0,0,101,245],A:[0,0,100,160],I:[0,1,128,255]},ct_brain:{min:-10,max:110,R:[0,199,255],G:[0,127,255],B:[0,127,255],A:[0,48,128],I:[0,124,255]},ct_brain_gray:{min:-10,max:110,R:[0,127,255],G:[0,127,255],B:[0,127,255],A:[0,48,128],I:[0,124,255]},ct_cardiac:{min:-80,max:1e3,R:[0,189,150,150,150,150,255],G:[0,169,54,54,54,54,240],B:[0,153,52,52,52,52,242],A:[0,32,64,0,0,64,64],I:[0,1,82,92,234,242,255]},ct_head:{min:-590,max:600,R:[0,241,241,248,248,178,178,232,255,255,255],G:[0,156,156,222,222,36,36,51,255,255,255],B:[0,130,130,169,169,24,24,37,255,255,255],A:[0,8,0,0,0,64,64,0,0,222,222],I:[0,2,3,64,122,142,172,182,252,253,255]},ct_kidneys:{min:114,max:302,R:[0,255,255],G:[0,129,255],B:[0,0,255],A:[0,88,228],I:[0,103,255]},ct_liver:{min:-23,max:246,R:[0,44,255,255,255],G:[0,128,90,255,255],B:[0,0,70,0,255],A:[0,0,82,184,228],I:[0,64,131,196,255]},ct_muscles:{min:-100,max:246,R:[0,128,159,255,255,255,255],G:[0,0,56,90,0,255,255],B:[0,0,41,70,0,0,255],A:[0,63,105,135,167,184,228],I:[0,100,128,155,180,209,255]},ct_scalp:{min:-590,max:600,R:[0,241,241,248,248,178,232,255,255],G:[0,156,156,222,222,36,51,255,255],B:[0,130,130,169,169,24,37,255,255],A:[0,63,105,135,167,184,228,228,228],I:[0,1,52,127,137,162,172,252,255]},ct_skull:{min:140,max:1024,R:[0,2,113,255],G:[0,1,109,250],B:[0,1,101,245],A:[0,1,96,168],I:[0,1,128,255]},ct_soft:{min:-923,max:679,R:[0,0,0,0,0,255,255,255],G:[154,154,154,154,0,0,254,255],B:[179,179,179,179,0,0,0,255],A:[0,3,8,0,0,10,15,20],I:[0,30,62,88,170,200,232,255]},ct_soft_tissue:{min:-10,max:110,R:[0,199,255],G:[0,127,255],B:[0,127,255],A:[0,48,128],I:[0,124,255]},ct_surface:{min:-600,max:100,R:[0,134,255],G:[0,109,250],B:[0,101,245],A:[0,60,148],I:[0,128,255]},ct_vessels:{min:114,max:246,R:[0,255,255],G:[0,128,255],B:[0,128,255],A:[0,64,96],I:[0,87,255]},ct_w_contrast:{min:50,max:1e3,R:[98,210,169,128,255],G:[94,26,77,128,255],B:[45,21,74,128,255],A:[0,25,0,4,168],I:[0,41,87,154,255]},cubehelix:{R:[0,13,21,26,27,25,22,21,22,28,39,54,75,98,124,148,171,189,202,210,213,211,206,200,195,193,195,201,211,225,240,255],G:[0,5,11,20,31,44,58,72,86,99,109,116,120,122,122,122,121,121,124,129,137,147,161,175,190,205,218,229,238,245,251,255],B:[0,14,30,46,61,71,77,78,75,68,60,52,48,47,53,65,83,105,131,157,183,205,222,235,241,243,242,240,239,240,245,255],A:[0,4,8,12,17,21,25,29,33,37,41,45,50,54,58,62,66,70,74,78,83,87,91,95,99,103,107,111,116,120,124,128],I:[0,8,16,25,33,41,49,58,66,74,82,90,99,107,115,123,132,140,148,156,165,173,181,189,197,206,214,222,230,239,247,255]},electric_blue:{R:[0,10,136,255],G:[0,39,220,255],B:[0,223,253,255],A:[0,48,64,70],I:[0,92,192,255]},freesurfer:{R:[0,245,205,120,196,220,230,0,122,236,12,204,42,119,220,103,60,255,165,160,0,245,205,120,196,220,230,0,122,236,13,220,103,255,165,160,0,120,200,255,255,164,164,164,234,0,0,0,0,0],G:[0,245,62,18,58,248,148,118,186,13,48,182,204,159,216,255,60,165,42,32,200,245,62,18,58,248,148,118,186,13,48,216,255,165,42,32,200,190,70,148,148,108,108,108,169,0,0,0,0,0],B:[0,245,78,134,250,164,34,14,220,176,255,142,164,176,20,255,60,0,42,240,200,245,78,134,250,164,34,14,220,176,255,20,255,0,42,240,221,150,255,10,10,226,226,226,30,64,112,160,208,255],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,2,3,4,5,7,8,10,11,12,13,14,15,16,17,18,24,26,28,30,31,41,42,43,44,46,47,49,50,51,52,53,54,58,60,62,63,72,77,78,79,80,81,82,85,251,252,253,254,255]},ge_color:{R:[0,0,128,255,255],G:[0,128,0,128,255],B:[0,125,255,0,255],A:[0,32,64,96,128],I:[0,63,128,192,255]},gold:{R:[0,142,227,255],G:[0,85,170,255],B:[0,14,76,255],A:[0,42,84,128],I:[0,85,170,255]},gray:{R:[0,255],G:[0,255],B:[0,255],A:[0,128],I:[0,255]},green:{R:[0,0,0],G:[0,128,255],B:[0,0,0],A:[0,64,128],I:[0,128,255]},green2cyan:{R:[0,0,0],G:[72,72,255],B:[0,255,255],A:[0,64,128],I:[0,88,255]},green2orange:{R:[0,255,255],G:[72,88,255],B:[0,0,0],A:[0,64,128],I:[0,88,255]},hot:{R:[3,255,255,255],G:[0,0,255,255],B:[0,0,0,255],A:[0,48,96,128],I:[0,95,191,255]},hotiron:{R:[0,255,255,255],G:[0,0,126,255],B:[0,0,0,255],A:[0,64,96,128],I:[0,128,191,255]},hsv:{R:[255,255,0,0,0,255,255],G:[0,255,255,255,0,0,0],B:[0,0,0,255,255,255,0],A:[0,14,28,43,57,71,85],I:[0,43,85,128,170,213,255]},inferno:{R:[0,120,237,240],G:[0,28,105,249],B:[4,109,37,33],A:[0,56,80,88],I:[0,64,192,255]},jet:{R:[0,0,127,255,127],G:[0,127,255,127,0],B:[127,255,127,0,0],A:[0,32,64,96,128],I:[0,63,128,192,255]},kry:{R:[0,255,255],G:[0,0,255],B:[0,0,0],A:[0,64,64],I:[0,86,255]},linspecer:{R:[94,50,90,152,215,238,249,254,252,241,209,158],G:[79,131,186,214,240,244,237,210,157,100,57,1],B:[162,189,167,164,155,169,168,123,86,68,79,66],A:[0,12,23,35,47,58,70,81,93,105,116,128],I:[0,23,46,70,93,116,139,162,185,209,232,255]},lipari:{R:[3,7,13,25,45,67,84,98,110,124,138,154,173,191,210,225,233,233,231,229,230,235,243,253],G:[19,33,48,63,77,87,92,94,95,96,96,97,99,101,106,118,133,149,163,177,192,208,225,245],B:[38,58,79,99,114,122,122,120,117,113,110,105,101,97,94,96,103,112,122,134,149,169,192,218],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,11,22,33,44,55,66,77,88,99,110,121,133,144,155,166,177,188,199,210,221,232,243,255]},magma:{R:[0,148,183,223,247,252],G:[0,44,55,74,112,253],B:[4,128,121,104,92,191],A:[0,44,53,64,75,107],I:[0,107,128,154,179,255]},mako:{R:[11,59,55,222],G:[4,45,165,245],B:[5,91,172,229],A:[0,23,70,107],I:[0,56,167,255]},navia:{R:[3,5,6,8,12,19,28,36,42,48,54,61,68,76,86,96,110,129,154,181,205,224,239,252],G:[19,32,44,58,72,86,98,108,116,122,128,134,141,149,157,167,178,191,204,216,225,232,239,244],B:[39,60,82,104,123,137,144,145,142,138,134,130,126,121,116,110,105,104,112,131,155,178,198,217],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,11,22,33,44,55,66,77,88,99,110,121,133,144,155,166,177,188,199,210,221,232,243,255]},nih:{R:[0,85,0,0,0,0,0,0,85,255,255,255,172],G:[0,0,0,0,85,170,255,255,255,255,85,0,0],B:[0,170,85,255,255,170,170,0,85,0,0,0,0],A:[0,5,10,21,26,32,37,42,48,53,64,72,85],I:[0,15,31,63,79,95,111,127,143,159,191,217,255]},plasma:{R:[13,156,237,240],G:[8,23,121,249],B:[135,158,83,33],A:[0,56,80,88],I:[0,64,192,255]},random:{R:[208,71,33,192,32,195,208,173,233,202,25,210,145,89,87,245,246,38,3,25,57,167,245,86,227,208,81,64,90,199,140,48,212,180,70,120,9,192,245,177,65,157,9,193,100,181,125,145,62,8,108,36,140,237,242,248,161,189,41,114,65,121,97,50,238,149,44,214,124,167,40,167,127,178,231,30,173,244,193,203,204,238,139,135,71,234,234,217,66,14,129,19,97,165,112,244,35,73,192,12,149,71,33,192,32,195,208,173,233,202,25,210,145,89,87,245,246,38,3,25,57,167,245,86,227,208,81,64,90,199,140,48,212,180,70,120,9,192,245,177,65,157,9,193,100,181,125,145,62,8,108,36,140,237,242,248,161,189,41,114,65,121,97,50,238,149,44,214,124,167,40,167,127,178,231,30,173,244,193,203,204,238,139,135,71,234,234,217,66,14,129,19,97,165,112,244,35,73,192,12,149,71,33,192,32,195,208,173,233,202,25,210,145,89,87,245,246,38,3,25,57,167,245,86,227,208,81,64,90,199,140,48,212,180,70,120,9,192,245,177,65,157,9,193,100,181,125,145,62,8,108,36,140,237,242,248],G:[182,46,78,199,79,89,41,208,135,20,154,35,21,43,230,113,191,147,208,37,28,27,86,203,25,209,148,187,139,111,48,102,76,110,106,130,37,160,34,222,90,165,245,222,102,47,19,130,4,232,137,211,240,11,140,21,42,22,241,61,99,115,199,166,114,190,204,60,233,66,115,230,125,103,203,125,13,176,94,131,39,198,167,124,67,175,254,1,15,198,62,237,159,31,218,58,244,47,61,67,94,46,78,199,79,89,41,208,135,20,154,35,21,43,230,113,191,147,208,37,28,27,86,203,25,209,148,187,139,111,48,102,76,110,106,130,37,160,34,222,90,165,245,222,102,47,19,130,4,232,137,211,240,11,140,21,42,22,241,61,99,115,199,166,114,190,204,60,233,66,115,230,125,103,203,125,13,176,94,131,39,198,167,124,67,175,254,1,15,198,62,237,159,31,218,58,244,47,61,67,94,46,78,199,79,89,41,208,135,20,154,35,21,43,230,113,191,147,208,37,28,27,86,203,25,209,148,187,139,111,48,102,76,110,106,130,37,160,34,222,90,165,245,222,102,47,19,130,4,232,137,211,240,11,140,21],B:[191,154,43,10,207,204,164,231,136,58,239,30,147,230,101,111,150,35,128,57,252,79,173,120,25,126,81,85,8,7,122,237,190,152,246,182,130,219,67,76,167,178,235,250,28,61,186,250,199,67,58,50,86,182,108,77,89,112,59,125,226,50,205,227,125,128,104,27,59,66,53,133,159,203,97,125,139,159,158,7,215,47,140,226,223,231,44,110,184,61,233,47,67,148,22,120,173,156,117,181,94,154,43,10,207,204,164,231,136,58,239,30,147,230,101,111,150,35,128,57,252,79,173,120,25,126,81,85,8,7,122,237,190,152,246,182,130,219,67,76,167,178,235,250,28,61,186,250,199,67,58,50,86,182,108,77,89,112,59,125,226,50,205,227,125,128,104,27,59,66,53,133,159,203,97,125,139,159,158,7,215,47,140,226,223,231,44,110,184,61,233,47,67,148,22,120,173,156,117,181,94,154,43,10,207,204,164,231,136,58,239,30,147,230,101,111,150,35,128,57,252,79,173,120,25,126,81,85,8,7,122,237,190,152,246,182,130,219,67,76,167,178,235,250,28,61,186,250,199,67,58,50,86,182,108,77],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]},red:{R:[0,128,255],G:[0,0,0],B:[0,0,0],A:[0,64,128],I:[0,128,255]},redyell:{R:[192,224,255],G:[1,128,255],B:[0,0,0],A:[0,64,128],I:[0,128,255]},rocket:{R:[3,112,144,188,236,246,255],G:[5,31,29,22,76,158,250],B:[26,87,91,86,62,117,235],A:[0,30,38,49,67,85,107],I:[0,73,92,118,160,205,255]},roi_i256:{min:0,max:0,R:[65,10,223,120,216,207,251,93,252,217,21,253,131,165,173,143,144,217,86,89,63,254,172,1,142,107,42,78,221,8,222,71,127,126,167,33,104,2,208,216,0,251,7,105,2,101,248,190,253,62,255,224,166,37,110,138,45,34,6,37,69,201,43,122,199,37,173,194,103,211,75,159,96,4,239,98,110,193,253,166,40,255,48,130,140,243,101,9,177,220,133,32,4,81,48,48,210,109,60,132,1,119,1,159,247,33,212,187,253,144,196,254,168,79,64,196,39,97,73,173,104,216,217,43,101,119,254,5,237,103,203,122,57,87,251,164,19,75,200,2,252,150,66,0,255,157,23,254,55,16,240,161,69,253,207,195,5,60,255,251,200,217,134,123,253,180,27,246,130,136,250,232,4,125,140,22,253,255,13,180,123,61,254,111,10,185,76,192,255,223,186,61,198,5,172,13,83,172,171,6,23,73,134,133,109,61,213,55,57,132,36,209,2,144,1,253,68,155,3,160,2,77,121,70,67,176,223,131,4,162,232,255,150,94,235,191,207,10,246,0,225,4,209,116,57,112,172,253,1,6,92,227,73,62,135,223],G:[162,50,112,245,4,124,176,243,56,125,183,139,182,68,189,4,225,10,20,223,7,46,31,193,225,250,219,41,2,100,83,181,34,150,72,223,168,248,80,253,7,117,214,2,248,10,3,59,179,160,90,244,146,4,207,4,125,255,96,100,1,208,130,51,116,181,236,53,244,5,165,28,181,86,96,42,254,1,134,194,214,92,41,204,137,86,207,3,143,3,100,239,164,94,65,251,131,244,173,57,143,107,217,53,210,0,148,250,45,198,81,40,61,218,252,88,171,0,248,24,248,4,41,100,187,46,208,145,43,168,121,46,175,250,125,107,233,112,207,231,174,215,53,9,43,153,52,124,128,65,210,147,255,147,63,200,148,254,0,179,241,42,239,2,230,8,82,135,87,16,3,87,86,151,254,8,255,86,53,19,7,192,171,201,253,247,197,103,251,126,0,149,54,183,61,126,79,113,10,103,184,75,11,195,222,136,149,131,8,99,240,177,252,255,198,16,7,68,178,66,191,150,73,26,211,109,78,209,240,254,1,166,247,131,2,0,167,127,133,10,43,99,235,3,214,142,176,82,132,38,10,249,255,215,44,81],B:[176,182,248,37,117,35,96,69,32,152,108,20,237,250,2,89,141,216,111,251,211,149,10,44,214,103,31,251,3,32,252,246,97,1,219,167,197,4,36,116,206,118,106,43,205,204,114,69,127,205,87,80,41,251,145,204,253,161,247,1,149,9,43,253,97,72,136,161,171,181,26,255,108,80,218,214,231,255,84,31,109,4,218,3,217,36,68,85,241,39,221,2,240,2,173,42,206,5,110,46,103,27,212,184,2,207,246,45,116,72,110,253,38,105,248,159,243,81,192,93,141,145,24,157,234,131,57,178,62,75,65,176,148,40,253,66,76,240,51,154,17,251,139,253,207,9,114,49,200,254,96,73,138,118,204,102,137,89,145,161,4,112,66,234,147,178,212,205,185,11,203,131,2,250,118,169,1,185,154,53,171,197,61,175,249,96,15,254,95,5,222,75,246,194,2,61,180,25,133,165,15,233,59,35,221,140,109,7,114,255,198,0,115,168,252,23,242,80,75,142,137,255,12,182,68,201,4,111,37,228,83,248,24,192,249,5,54,223,160,122,160,114,145,119,252,31,253,250,10,214,8,47,0,142,222,70],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255]},surface:{R:[1,240,255],G:[1,128,255],B:[1,128,255],A:[0,76,128],I:[0,153,255]},thermal:{R:[0,5,18,34,53,72,90,107,126,144,161,178,194,209,222,233,242,248,251,251,249,244,241,252],G:[0,4,10,11,9,11,17,23,30,36,43,50,59,70,83,98,117,136,157,177,199,220,240,254],B:[3,24,50,76,96,106,109,110,108,104,97,89,79,67,55,42,26,12,6,22,47,79,121,164],A:[0,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64],I:[0,11,22,33,44,55,66,77,88,99,110,121,133,144,155,166,177,188,199,210,221,232,243,255]},turbo:{R:[48,48,64,70,65,25,132,195,244,254,218,122],G:[18,18,64,107,150,226,255,241,199,158,57,4],B:[59,59,162,227,255,187,81,52,58,47,7,3],A:[0,22,26,30,34,43,52,57,63,67,77,86],I:[0,1,16,32,49,83,118,140,164,181,219,255]},violet:{R:[0,128,255],G:[0,0,0],B:[0,128,255],A:[0,64,128],I:[0,128,255]},viridis:{R:[68,49,53,253],G:[1,104,183,231],B:[84,142,121,37],A:[0,56,80,88],I:[0,64,192,255]},warm:{R:[255,255,255],G:[127,196,254],B:[0,0,0],A:[0,64,128],I:[0,128,255]},winter:{R:[0,0,0],G:[0,128,255],B:[255,196,128],A:[0,64,128],I:[0,128,255]},x_rain:{R:[3,64,0,0,255,255,255],G:[0,0,0,255,255,192,3],B:[0,32,48,56,64,96,128],A:[0,8,16,24,32,52,80],I:[0,32,64,96,160,192,255]}},Symbol.toStringTag,{value:"Module"}));var JI=(B=>(B[B.MIN_TO_MAX=0]="MIN_TO_MAX",B[B.ZERO_TO_MAX_TRANSPARENT_BELOW_MIN=1]="ZERO_TO_MAX_TRANSPARENT_BELOW_MIN",B[B.ZERO_TO_MAX_TRANSLUCENT_BELOW_MIN=2]="ZERO_TO_MAX_TRANSLUCENT_BELOW_MIN",B))(JI||{});class BE{constructor(){G(this,"gamma",1);G(this,"version",.1);G(this,"cluts",{});const A=Object.keys(dC).filter(g=>!g.startsWith("$")).sort(new Intl.Collator("en").compare);for(const g of A)this.cluts[g]=dC[g]}addColormap(I,A){this.cluts[I]=A}colormaps(){return Object.keys(this.cluts)}colorMaps(){return this.colormaps()}colormapFromKey(I){let A=this.cluts[I];return A!==void 0||(A=this.cluts[I.toLowerCase()],A!==void 0)?A:(I.length>0&&J.warn("No color map named "+I),{min:0,max:0,R:[0,255],G:[0,255],B:[0,255],A:[0,255],I:[0,255]})}colormap(I="",A=!1){const g=this.colormapFromKey(I);return this.makeLut(g.R,g.G,g.B,g.A,g.I,A)}makeLabelLut(I,A=255,g=1/0){if(I.R===void 0||I.G===void 0||I.B===void 0)throw new Error(`Invalid colormap table: ${I}`);const C=I.R.length,Q=I.I??[...Array(C).keys()];let E=!1;for(let n=0;n<Q.length;n++)Q[n]>g&&(E=!0,Q[n]=g);if(E&&J.warn("Some colormap indices clamped to match label range."),C!==I.G.length||C!==I.B.length||C!==Q.length)throw new Error(`colormap does not make sense: ${I} Rs ${I.R.length} Gs ${I.G.length} Bs ${I.B.length} Is ${Q.length}`);let i=new Uint8ClampedArray(C).fill(A);const o=Q.indexOf(0);o>=0&&(i[o]=0),I.A!==void 0&&(i=Uint8ClampedArray.from(I.A));const t=Math.min(...Q),s=Math.max(...Q),a=s-t+1,e=new Uint8ClampedArray(a*4).fill(0);for(let n=0;n<C;n++){let h=(Q[n]-t)*4;e[h++]=I.R[n],e[h++]=I.G[n],e[h++]=I.B[n],e[h++]=i[n]}const r={lut:e,min:t,max:s};if(I.labels){const n=I.labels.length;if(n===a)r.labels=I.labels;else if(n===C){r.labels=Array(a).fill("?");for(let h=0;h<C;h++)r.labels[Q[h]-t]=I.labels[h]}}return r}async makeLabelLutFromUrl(I,A=255,g=1/0){const Q=await(await fetch(I)).json();return this.makeLabelLut(Q,A,g)}makeDrawLut(I){let A=typeof I=="object"?I:dC[I];A===void 0&&(J.warn("colormap undefined ",I),A=this.colormapFromKey(""));const g=this.makeLabelLut(A,255);if(g.labels===void 0&&(g.labels=[]),g.labels.length<256){const i=g.labels.length;for(let o=i;o<256;o++)g.labels.push(o.toString())}const C=new Uint8ClampedArray(256*4);let Q=0;for(let i=0;i<256;i++)C[Q++]=255,C[Q++]=0,C[Q++]=0,C[Q++]=255;C[3]=0;const E=Math.min(g.lut.length,256*4);if(E>0)for(let i=0;i<E;i++)C[i]=g.lut[i];return{lut:C,labels:g.labels}}makeLut(I,A,g,C,Q,E){const i=I.length,o=[...I],t=[...A],s=[...g];if(!Q){Q=new Array(i);for(let n=0;n<i;n++)Q[n]=n/(i-1)*255}C||(C=new Array(i).fill(64),C[0]=0);let a=Uint8ClampedArray.from(C),e=Uint8ClampedArray.from(Q);if(E)for(let n=0;n<i;n++)o[n]=I[i-1-n],t[n]=A[i-1-n],s[n]=g[i-1-n],a[n]=255-C[i-1-n],e[n]=255-Q[i-1-n];const r=new Uint8ClampedArray(256*4);if(typeof e>"u"){e=new Uint8ClampedArray(i).fill(0);for(let n=0;n<i;n++)e[n]=Math.round(n*255/(i-1))}typeof a>"u"&&(a=new Uint8ClampedArray(i).fill(64),a[0]=0);for(let n=0;n<i-1;n++){const h=e[n];let D=e[n+1];n===0&&h!==0&&J.warn("colormap issue: indices expected to start with 0 not ",h),n===e.length-2&&D!==255&&(J.warn("padding colormap: indices expected end with 255 not ",D),D=255);const w=D-h;let y=h*4;for(let F=h;F<=D;F++){const c=(F-h)/w;r[y++]=o[n]+c*(o[n+1]-o[n]),r[y++]=t[n]+c*(t[n+1]-t[n]),r[y++]=s[n]+c*(s[n+1]-s[n]),r[y++]=a[n]+c*(a[n+1]-a[n])}}if(this.gamma===1)return r;for(let n=0;n<255*4;n++)n%4!==3&&(r[n]=Math.pow(r[n]/255,1/this.gamma)*255);return r}}const pA=new BE;class jI{static getClusterBoundaryU8(I,A){const g=new Array(I.length).fill(!1),C=new Array(I.length).fill(!1);for(let i=0;i<I.length;i++)I[i]>0&&(C[i]=!0);const Q=A.length/3;let E=0;for(let i=0;i<Q;i++){const o=A[E],t=A[E+1],s=A[E+2];E+=3,!(C[o]===C[t]&&C[o]===C[s]&&C[t]===C[s])&&(g[o]=!0,g[t]=!0,g[s]=!0)}return g}static async gzip(I){const A=new CompressionStream("gzip"),g=A.writable.getWriter();g.write(I).catch(console.error);const C=g.close().catch(console.error),Q=new Response(A.readable),E=new Uint8Array(await Q.arrayBuffer());return await C,E}static createMZ3(I,A,g=!1,C=null,Q=null,E=null){const r=A?A.length/3:0,n=I?I.length/3:0;if(!Number.isInteger(r)||r<0)throw new Error("indices length must be a multiple of 3");if(!Number.isInteger(n)||n<0)throw new Error("vertices length must be a multiple of 3");const h=A&&A.length>0,D=I&&I.length>0,w=C instanceof Uint8Array&&C.length===n*4;let y=null,F=0;if(E!=null){const P=typeof E=="string"?E:JSON.stringify(E);y=new TextEncoder().encode(P),F=y.byteLength}let c=!1,R=0;if(Q!=null){if(!(Q instanceof Float32Array))throw new Error("scalars must be a Float32Array or null/undefined");if(n===0)throw new Error("cannot have scalars without vertices (nvert === 0)");if(Q.length>0&&Q.length%n===0)c=!0,R=Q.length/n;else throw new Error(`scalars.length (${Q.length}) must be a positive integer multiple of nvert (${n})`)}let l=0;h&&(l|=1),D&&(l|=2),w&&(l|=4),c&&(l|=8),y&&(l|=64);const S=16,N=h?r*3*4:0,d=D?n*3*4:0,L=w?n*4:0,k=c?R*n*4:0,U=S+F+N+d+L+k,Y=new ArrayBuffer(U),K=new DataView(Y);let b=0;K.setUint16(b,23117,!0),b+=2,K.setUint16(b,l,!0),b+=2,K.setUint32(b,r,!0),b+=4,K.setUint32(b,n,!0),b+=4,K.setUint32(b,F,!0),b+=4;let m=S;if(F>0&&y&&(new Uint8Array(Y,m,y.length).set(y),m+=F),h&&(new Uint32Array(Y,m,A.length).set(A),m+=N),D&&(new Float32Array(Y,m,I.length).set(I),m+=d),w&&(new Uint8Array(Y,m,C.length).set(C),m+=L),c&&(new Float32Array(Y,m,Q.length).set(Q),m+=k),m!==U)throw new Error(`mz3 internal size mismatch: offset ${m} !== totalSize ${U}`);if(g)throw new Error("Call async createMZ3Async() for compression");return Y}static async createMZ3Async(I,A,g=!1,C=null,Q=null,E=null){const i=this.createMZ3(I,A,g,C,Q,E);return g?await this.gzip(new Uint8Array(i)):i}static createOBJ(I,A){let g="";for(let E=0;E<I.length;E+=3)g+=`v ${I[E]} ${I[E+1]} ${I[E+2]}
  2. `;for(let E=0;E<A.length;E+=3)g+=`f ${A[E]+1} ${A[E+1]+1} ${A[E+2]+1}
  3. `;return new TextEncoder().encode(g).buffer}static createSTL(I,A){const g=A.length/3,C=84+g*50,Q=new ArrayBuffer(C),E=new DataView(Q);for(let o=0;o<80;o++)E.setUint8(o,0);E.setUint32(80,g,!0);let i=84;for(let o=0;o<A.length;o+=3){const t=A[o]*3,s=A[o+1]*3,a=A[o+2]*3;E.setFloat32(i,0,!0),E.setFloat32(i+4,0,!0),E.setFloat32(i+8,0,!0),i+=12,E.setFloat32(i,I[t],!0),E.setFloat32(i+4,I[t+1],!0),E.setFloat32(i+8,I[t+2],!0),i+=12,E.setFloat32(i,I[s],!0),E.setFloat32(i+4,I[s+1],!0),E.setFloat32(i+8,I[s+2],!0),i+=12,E.setFloat32(i,I[a],!0),E.setFloat32(i+4,I[a+1],!0),E.setFloat32(i+8,I[a+2],!0),i+=12,E.setUint16(i,0,!0),i+=2}return Q}static downloadArrayBuffer(I,A){const g=new Blob([I],{type:"application/octet-stream"}),C=URL.createObjectURL(g),Q=document.createElement("a");Q.href=C,Q.download=A,document.body.appendChild(Q),Q.style.display="none",Q.click(),setTimeout(()=>{document.body.removeChild(Q),URL.revokeObjectURL(C)},0)}static async saveMesh(I,A,g=".mz3",C=!1){let Q=new ArrayBuffer(0);return/\.obj$/i.test(g)?Q=this.createOBJ(I,A):/\.stl$/i.test(g)?Q=this.createSTL(I,A):(/\.mz3$/i.test(g)||(g+=".mz3"),Q=await this.createMZ3Async(I,A,C)),g.length>4&&this.downloadArrayBuffer(Q,g),Q}static getClusterBoundary(I,A){const g=new Uint32Array(I.buffer),C=new Array(g.length).fill(!1),Q=A.length/3;let E=0;for(let i=0;i<Q;i++){const o=A[E],t=A[E+1],s=A[E+2];E+=3,!(g[o]===g[t]&&g[o]===g[s]&&g[t]===g[s])&&(C[o]=!0,C[t]=!0,C[s]=!0)}return C}static getExtents(I){if(!ArrayBuffer.isView(I)&&!Array.isArray(I)||I.length<3)return{mxDx:0,extentsMin:0,extentsMax:0};let A=0;const g=BA(I[0],I[1],I[2]),C=BA(I[0],I[1],I[2]);for(let i=0;i<I.length;i+=3){const o=BA(I[i],I[i+1],I[i+2]);A=Math.max(A,$g(o)),GC(g,g,o),SC(C,C,o)}const Q=[g[0],g[1],g[2]],E=[C[0],C[1],C[2]];return{mxDx:A,extentsMin:Q,extentsMax:E}}static generateNormals(I,A){const g=[];let C;const Q=I.length;let E,i,o,t,s,a,e,r,n;const h=new Float32Array(Q),D=A.length;for(C=0;C<D;C+=3){e=A[C]*3,r=A[C+1]*3,n=A[C+2]*3;const w=[I[e],I[e+1],I[e+2]],y=[I[r],I[r+1],I[r+2]],F=[I[n],I[n+1],I[n+2]];E=y[0]-w[0],i=y[1]-w[1],o=y[2]-w[2],t=F[0]-w[0],s=F[1]-w[1],a=F[2]-w[2],g[0]=s*o-a*i,g[1]=a*E-t*o,g[2]=t*i-s*E,h[e]+=g[0],h[e+1]+=g[1],h[e+2]+=g[2],h[r]+=g[0],h[r+1]+=g[1],h[r+2]+=g[2],h[n]+=g[0],h[n+1]+=g[1],h[n+2]+=g[2]}for(C=0;C<Q;C+=3){g[0]=-1*h[C],g[1]=-1*h[C+1],g[2]=-1*h[C+2];let w=g[0]*g[0]+g[1]*g[1]+g[2]*g[2];w>0&&(w=1/Math.sqrt(w),g[0]*=w,g[1]*=w,g[2]*=w),h[C]=g[0],h[C+1]=g[1],h[C+2]=g[2]}return h}}function jo(B){return B&&B.__esModule&&Object.prototype.hasOwnProperty.call(B,"default")?B.default:B}var _o=function(I,A){var g=I.length;if(I===A)return!0;if(g!==A.length)return!1;for(var C=0;C<g;C++)if(I[C]!==A[C])return!1;return!0};const $o=jo(_o);class CE{constructor(I){PA(this,GA);PA(this,cI,0);PA(this,wB,[]);PA(this,lC,[]);PA(this,Hg);xA(this,GA,new DataView(I)),this.read()}async extract(I){const A=new Uint8Array(IA(this,GA).buffer.slice(I.startsAt,I.startsAt+I.compressedSize));if(I.compressionMethod===0)return A;if(I.compressionMethod===8){const g=new DecompressionStream("deflate-raw"),C=g.writable.getWriter();C.write(A).catch(console.error);const Q=C.close().catch(console.error),E=new Response(g.readable),i=new Uint8Array(await E.arrayBuffer());return await Q,i}throw new Error(`Unsupported compression method: ${I.compressionMethod}`)}read(){for(;!IA(this,Hg)&&IA(this,cI)<IA(this,GA).byteLength;){const I=IA(this,GA).getUint32(IA(this,cI),!0);if(I===67324752){const A=this.readLocalFile(IA(this,cI));A.extract=this.extract.bind(this,A),IA(this,wB).push(A);const g=(A.generalPurpose&8)!==0;if(A.startsAt=IA(this,cI)+30+A.fileNameLength+A.extraLength,A.compressedSize===0&&g){let C=A.startsAt;for(;C+20<=IA(this,GA).byteLength;){if(IA(this,GA).getUint32(C,!0)===134695760&&IA(this,GA).getUint16(C+16,!0)===19280){C+=4;break}C++}A.crc=IA(this,GA).getUint32(C,!0),A.compressedSize=IA(this,GA).getUint32(C+4,!0),A.uncompressedSize=IA(this,GA).getUint32(C+8,!0),xA(this,cI,C+12)}else xA(this,cI,A.startsAt+A.compressedSize)}else if(I===33639248){const A=this.readCentralDirectory(IA(this,cI));IA(this,lC).push(A),xA(this,cI,IA(this,cI)+(46+A.fileNameLength+A.extraLength+A.fileCommentLength))}else if(I===101010256){xA(this,Hg,this.readEndCentralDirectory(IA(this,cI)));break}else if(I===101075792){xA(this,Hg,this.readEndCentralDirectory64(IA(this,cI)));break}else{console.error(`Unexpected ZIP signature 0x${I.toString(16).padStart(8,"0")} at index ${IA(this,cI)}`);break}}}readLocalFile(I){let A=IA(this,GA).getUint32(I+18,!0),g=IA(this,GA).getUint32(I+22,!0);const C=IA(this,GA).getUint16(I+26,!0),Q=IA(this,GA).getUint16(I+28,!0),E=I+30+C;if(this.readString(E,Q),A===4294967295&&g===4294967295){let i=E,o=!1;for(;i<E+Q-4;){const t=IA(this,GA).getUint16(i,!0),s=IA(this,GA).getUint16(i+2,!0);if(i+=4,t===1)if(s>=16){g=Number(IA(this,GA).getBigUint64(i,!0)),i+=8,A=Number(IA(this,GA).getBigUint64(i,!0)),o=!0;break}else throw new Error(`ZIP64 extra field found but is too small (expected at least 16 bytes, got ${s}).`);i+=s}if(!o)throw new Error("ZIP64 format missing extra field with signature 0x0001.")}return{signature:this.readString(I,4),version:IA(this,GA).getUint16(I+4,!0),generalPurpose:IA(this,GA).getUint16(I+6,!0),compressionMethod:IA(this,GA).getUint16(I+8,!0),lastModifiedTime:IA(this,GA).getUint16(I+10,!0),lastModifiedDate:IA(this,GA).getUint16(I+12,!0),crc:IA(this,GA).getUint32(I+14,!0),compressedSize:A,uncompressedSize:g,fileNameLength:C,extraLength:Q,fileName:this.readString(I+30,C),extra:this.readString(I+30+C,Q)}}readCentralDirectory(I){return{versionCreated:IA(this,GA).getUint16(I+4,!0),versionNeeded:IA(this,GA).getUint16(I+6,!0),fileNameLength:IA(this,GA).getUint16(I+28,!0),extraLength:IA(this,GA).getUint16(I+30,!0),fileCommentLength:IA(this,GA).getUint16(I+32,!0),diskNumber:IA(this,GA).getUint16(I+34,!0),internalAttributes:IA(this,GA).getUint16(I+36,!0),externalAttributes:IA(this,GA).getUint32(I+38,!0),offset:IA(this,GA).getUint32(I+42,!0),comments:this.readString(I+46,IA(this,GA).getUint16(I+32,!0))}}readEndCentralDirectory(I){const A=IA(this,GA).getUint16(I+20,!0);return{numberOfDisks:IA(this,GA).getUint16(I+4,!0),centralDirectoryStartDisk:IA(this,GA).getUint16(I+6,!0),numberCentralDirectoryRecordsOnThisDisk:IA(this,GA).getUint16(I+8,!0),numberCentralDirectoryRecords:IA(this,GA).getUint16(I+10,!0),centralDirectorySize:IA(this,GA).getUint32(I+12,!0),centralDirectoryOffset:IA(this,GA).getUint32(I+16,!0),commentLength:A,comment:this.readString(I+22,A)}}readEndCentralDirectory64(I){const A=Number(IA(this,GA).getBigUint64(I+0,!0));return{numberOfDisks:IA(this,GA).getUint32(I+16,!0),centralDirectoryStartDisk:IA(this,GA).getUint32(I+20,!0),numberCentralDirectoryRecordsOnThisDisk:Number(IA(this,GA).getBigUint64(I+24,!0)),numberCentralDirectoryRecords:Number(IA(this,GA).getBigUint64(I+32,!0)),centralDirectorySize:Number(IA(this,GA).getBigUint64(I+40,!0)),centralDirectoryOffset:Number(IA(this,GA).getBigUint64(I+48,!0)),commentLength:A,comment:""}}readString(I,A){return Array.from({length:A},(g,C)=>String.fromCharCode(IA(this,GA).getUint8(I+C))).join("")}get entries(){return IA(this,wB)}}GA=new WeakMap,cI=new WeakMap,wB=new WeakMap,lC=new WeakMap,Hg=new WeakMap;class DA{static arrayBufferToBase64(I){const A=new Uint8Array(I);return DA.uint8tob64(A)}static async decompress(I){const A=I[0]===31&&I[1]===139&&I[2]===8?"gzip":I[0]===120&&(I[1]===1||I[1]===94||I[1]===156||I[1]===218)?"deflate":"deflate-raw",g=new DecompressionStream(A),C=g.writable.getWriter();C.write(I).catch(console.error);const Q=C.close().catch(console.error),E=new Response(g.readable),i=new Uint8Array(await E.arrayBuffer());return await Q,i}static async decompressToBuffer(I){const A=await DA.decompress(I);return A.buffer.slice(A.byteOffset,A.byteOffset+A.byteLength)}static async readMatV4(I,A=!1){let g=I.byteLength;if(g<40)throw new Error("File too small to be MAT v4: bytes = "+I.byteLength);let C=new DataView(I),Q=C.getUint16(0,!0),E=I;if(Q===35615||Q===8075){const n=await this.decompress(new Uint8Array(I));C=new DataView(n.buffer),Q=C.getUint16(0,!0),E=n.buffer,g=E.byteLength}const i=new TextDecoder("utf-8"),o=new Uint8Array(E);let t=0;const s={};function a(n){return Math.floor(n/10)%10}function e(n,h,D){const w=new Uint8Array(o.subarray(h,D));return n===1?new Float32Array(w.buffer):n===2?new Int32Array(w.buffer):n===3?new Int16Array(w.buffer):n===4?new Uint16Array(w.buffer):n===5?new Uint8Array(w.buffer):new Float64Array(w.buffer)}function r(){const n=C.getUint32(t,!0),h=C.getUint32(t+4,!0),D=C.getUint32(t+8,!0),w=C.getUint32(t+12,!0),y=C.getUint32(t+16,!0);if(t+=20,w!==0)throw new Error("Matlab V4 reader does not support imaginary numbers");const F=h*D;if(F<1)throw new Error("mrows * ncols must be greater than one");const c=new Uint8Array(o.subarray(t,t+y));let R=i.decode(c).trim().replaceAll("\0","");A&&(R=R.replaceAll(".","_"));const l=a(n);let S=8;if(l>=1&&l<=2)S=4;else if(l>=3&&l<=4)S=2;else if(l===5)S=1;else if(l!==0)throw new Error("impossible Matlab v4 datatype");if(t+=y,n>50)throw new Error("Does not appear to be little-endian V4 Matlab file");const N=t+F*S;s[R]=e(l,t,N),t=N}for(;t+20<g;)r();return s}static b64toUint8(I){const A=atob(I),g=A.length,C=new Uint8Array(g);for(let Q=0;Q<g;Q++)C[Q]=A.charCodeAt(Q);return C}static uint8tob64(I){let A="";const g="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",C=I.byteLength,Q=C%3,E=C-Q;let i,o,t,s,a;for(let e=0;e<E;e=e+3)a=I[e]<<16|I[e+1]<<8|I[e+2],i=(a&16515072)>>18,o=(a&258048)>>12,t=(a&4032)>>6,s=a&63,A+=g[i]+g[o]+g[t]+g[s];return Q===1?(a=I[E],i=(a&252)>>2,o=(a&3)<<4,A+=g[i]+g[o]+"=="):Q===2&&(a=I[E]<<8|I[E+1],i=(a&64512)>>10,o=(a&1008)>>4,t=(a&15)<<2,A+=g[i]+g[o]+g[t]+"="),A}static download(I,A,g){const C=document.createElement("a"),Q=Array.isArray(I)?I:[I],E=new Blob(Q,{type:g});C.href=URL.createObjectURL(E),C.download=A,C.click()}static readFileAsync(I){return new Promise((A,g)=>{const C=new FileReader;C.onload=()=>{A(C.result)},C.onerror=g,C.readAsArrayBuffer(I)})}static blobToBase64(I){return new Promise(A=>{const g=new FileReader;g.onloadend=()=>A(g.result),g.readAsDataURL(I)})}static async decompressBase64String(I){const A=atob(I),g=new ArrayBuffer(A.length),C=new Uint8Array(g);for(let Q=0;Q<A.length;Q++)C[Q]=A.charCodeAt(Q);return DA.decompressArrayBuffer(C)}static async compressToBase64String(I){const A=await DA.compressStringToArrayBuffer(I);return DA.uint8tob64(new Uint8Array(A))}static strToU8(I,A){if(A){const o=new Uint8Array(I.length);for(let t=0;t<I.length;++t)o[t]=I.charCodeAt(t);return o}const g=I.length,C=(o,t,s)=>((s==null||s>o.length)&&(s=o.length),new Uint8Array(o.subarray(t,s)));let Q=new Uint8Array(I.length+(I.length>>1)),E=0;const i=o=>{Q[E++]=o};for(let o=0;o<g;++o){if(E+5>Q.length){const s=new Uint8Array(E+8+(g-o<<1));s.set(Q),Q=s}let t=I.charCodeAt(o);t<128||A?i(t):t<2048?(i(192|t>>6),i(128|t&63)):(t>55295&&t<57344,t=65536+(t&1047552)|I.charCodeAt(++o)&1023,i(240|t>>18),i(128|t>>12&63),i(128|t>>6&63),i(128|t&63))}return C(Q,0,E)}static async compress(I,A="gzip"){const g=new CompressionStream(A),C=g.writable.getWriter();C.write(I).catch(console.error);const Q=C.close().catch(console.error),i=await new Response(g.readable).arrayBuffer();return await Q,i}static async compressStringToArrayBuffer(I){const A=this.strToU8(I);return await this.compress(A)}static isArrayBufferCompressed(I){if(I&&I.byteLength){const A=new Uint8Array(I);return(A[0]<<8|A[1])===8075}else return!1}static strFromU8(I,A){if(A){let g="";for(let C=0;C<I.length;C+=16384)g+=String.fromCharCode.apply(null,I.subarray(C,C+16384));return g}else{const g=(i,o,t)=>((o==null||o<0)&&(o=0),(t==null||t>i.length)&&(t=i.length),new Uint8Array(i.subarray(o,t))),C=i=>{for(let o="",t=0;;){let s=i[t++];const a=(s>127)+(s>223)+(s>239);if(t+a>i.length)return{s:o,r:g(i,t-1)};a?a===3?(s=((s&15)<<18|(i[t++]&63)<<12|(i[t++]&63)<<6|i[t++]&63)-65536,o+=String.fromCharCode(55296|s>>10,56320|s&1023)):a&1?o+=String.fromCharCode((s&31)<<6|i[t++]&63):o+=String.fromCharCode((s&15)<<12|(i[t++]&63)<<6|i[t++]&63):o+=String.fromCharCode(s)}},{s:Q,r:E}=C(I);if(E.length)throw new Error("Unexpected trailing bytes in UTF-8 decoding");return Q}}static async decompressArrayBuffer(I){const A=await this.decompress(new Uint8Array(I));return this.strFromU8(A)}static arraysAreEqual(I,A){return $o(I,A)}static range(I,A,g){return Array.from({length:(A-I)/g+1},(C,Q)=>I+Q*g)}static sph2cartDeg(I,A){const g=-A*(Math.PI/180),C=(I-90)%360*(Math.PI/180),Q=[Math.cos(g)*Math.cos(C),Math.cos(g)*Math.sin(C),Math.sin(g)],E=Math.sqrt(Q[0]*Q[0]+Q[1]*Q[1]+Q[2]*Q[2]);return E<=0||(Q[0]/=E,Q[1]/=E,Q[2]/=E),Q}static vox2mm(I,A){const g=jA(A);rI(g,g);const C=WA(I[0],I[1],I[2],1);return CI(C,C,g),BA(C[0],C[1],C[2])}}const AB=J;class dA{static readTRACT(I){const A=I.byteLength;if(A<20)throw new Error("File too small to be niml.tract: bytes = "+A);const g=new DataView(I),C=new Uint8Array(I);let Q=0;function E(){for(;Q<A&&C[Q]!==60;)Q++;const h=Q;for(;Q<A&&C[Q]!==62;)Q++;return Q++,Q-h<1?"":new TextDecoder().decode(I.slice(h,Q-1)).trim()}let i=E();function o(h){const D=i.indexOf(h);if(D<0)return 0;const w=i.indexOf('"',D)+1,y=i.indexOf('"',w),F=i.slice(w,y);return parseInt(F)}const t=o("N_tracts=");(!i.startsWith("<network")||t<1)&&J.warn("This is not a valid niml.tract file "+i);let s=0;const a=[];a.push(s);const e=[],r=[];for(let h=0;h<t;h++){i=E();const D=o("ni_dimen="),w=o("Bundle_Tag="),y=i.includes("binary.lsbfirst");for(let F=0;F<D;F++){Q+=4;const c=g.getUint32(Q,y)/3;Q+=4;for(let R=0;R<c;R++)e.push(g.getFloat32(Q,y)),Q+=4,e.push(-g.getFloat32(Q,y)),Q+=4,e.push(g.getFloat32(Q,y)),Q+=4;s+=c,a.push(s),r.push(w)}i=E()}const n=[];return n.push({id:"tract",vals:Float32Array.from(r)}),{pts:new Float32Array(e),offsetPt0:new Uint32Array(a),dps:n}}static async readTT(I){let A=new Uint32Array(0),g=new Float32Array(0);const C=await DA.readMatV4(I);if(!("trans_to_mni"in C))throw new Error("TT format file must have 'trans_to_mni'");if(!("voxel_size"in C))throw new Error("TT format file must have 'voxel_size'");if(!("track"in C))throw new Error("TT format file must have 'track'");let Q=MA();const E=C.trans_to_mni;Q=yI(E[0],E[1],E[2],E[3],E[4],E[5],E[6],E[7],E[8],E[9],E[10],E[11],E[12],E[13],E[14],E[15]),rI(Q,Q);function i(o){const t=new DataView(o.buffer),s=[];let a=0,e=0;for(;e<o.length;){s.push(e);const h=t.getUint32(e,!0);e=e+h+13,a+=h}A=new Uint32Array(s.length+1),g=new Float32Array(a);let r=0;for(let h=0;h<s.length;h++){A[h]=r/3;let D=s[h];const w=t.getUint32(D,!0)/3;let y=t.getInt32(D+4,!0),F=t.getInt32(D+8,!0),c=t.getInt32(D+12,!0);D+=16,g[r++]=y,g[r++]=F,g[r++]=c;for(let R=2;R<=w;R++)y=y+t.getInt8(D++),F=F+t.getInt8(D++),c=c+t.getInt8(D++),g[r++]=y,g[r++]=F,g[r++]=c}for(let h=0;h<r;h++)g[h]=g[h]/32;let n=0;for(let h=0;h<r/3;h++){const D=WA(g[n],g[n+1],g[n+2],1);CI(D,D,Q),g[n++]=D[0],g[n++]=D[1],g[n++]=D[2]}A[s.length]=r/3}return i(C.track),{pts:g,offsetPt0:A}}static assembleDpgFromMap(I,A){if(!Array.isArray(A)||A.length===0)throw new Error('assembleDpgFromMap: "groups" is empty or missing; cannot assemble dpg.');const g=new Set;for(const Q in I)I[Q].forEach(E=>g.add(E.id));const C=[];for(const Q of g){const E=[];let i=0;for(let s=0;s<A.length;s++){const a=String(A[s].id),r=(I[a]||[]).find(n=>n.id===Q);if(r){const n=r.vals instanceof Float32Array?r.vals:Float32Array.from(r.vals);E.push(n),i+=n.length}else{const n=new Float32Array([NaN]);E.push(n),i+=n.length}}const o=new Float32Array(i);let t=0;for(const s of E)o.set(s,t),t+=s.length;C.push({id:Q,vals:o})}return C}static async readTRX(I){function A(h){const D=(h&31744)>>10,w=h&1023;return(h>>15?-1:1)*(D?D===31?w?NaN:1/0:Math.pow(2,D-15)*(1+w/1024):6103515625e-14*(w/1024))}let g=0,C=0,Q=new Float32Array([]);const E=[],i={},o=[],t=[],s=[];let a=[],e=!1;const r=new CE(I);for(let h=0;h<r.entries.length;h++){const D=r.entries[h];if(D.uncompressedSize===0)continue;const w=D.fileName.split("/"),y=w.slice(-1)[0];if(y.startsWith("."))continue;const F=w.slice(-3)[0],c=w.slice(-2)[0],R=y.split(".")[0],l=await D.extract();if(y.includes("header.json")){const d=new TextDecoder().decode(l);a=JSON.parse(d);continue}let S=0,N=[];if(y.endsWith(".uint64")||y.endsWith(".int64")){S=l.length/8,N=new Uint32Array(S);const d=new Uint32Array(l.buffer);let L=0;for(let k=0;k<S;k++)N[k]=d[L],d[L+1]!==0&&(e=!0),L+=2}else if(y.endsWith(".uint32"))N=new Uint32Array(l.buffer);else if(y.endsWith(".uint16"))N=new Uint16Array(l.buffer);else if(y.endsWith(".uint8"))N=new Uint8Array(l.buffer);else if(y.endsWith(".int32"))N=new Int32Array(l.buffer);else if(y.endsWith(".int16"))N=new Int16Array(l.buffer);else if(y.endsWith(".int8"))N=new Int8Array(l.buffer);else if(y.endsWith(".float64"))N=new Float64Array(l.buffer);else if(y.endsWith(".float32"))N=new Float32Array(l.buffer);else if(y.endsWith(".float16")){S=l.length/2,N=new Float32Array(S);const d=new Uint16Array(l.buffer),L=new Float32Array(65536);for(let k=0;k<65536;k++)L[k]=A(k);for(let k=0;k<S;k++)N[k]=L[d[k]]}else continue;if(S=N.length,c.includes("groups")){o.push({id:R,vals:Float32Array.from(N.slice())});continue}if(F.includes("dpg")){const d=String(c);i[d]||(i[d]=[]),i[d].push({id:R,vals:Float32Array.from(N.slice())});continue}if(c.includes("dpv")){s.push({id:R,vals:Float32Array.from(N.slice())});continue}if(c.includes("dps")){t.push({id:R,vals:Float32Array.from(N.slice())});continue}if(y.startsWith("offsets.")){g=S;for(let d=0;d<S;d++)E[d]=N[d]}y.startsWith("positions.3.")&&(C=S,Q=new Float32Array(N))}if(g===0||C===0)throw new Error("Failure reading TRX format (no offsets or points).");if(e)throw new Error("Too many vertices: JavaScript does not support 64 bit integers");let n=[];return o.length>0&&i&&Object.keys(i).length>0&&(n=this.assembleDpgFromMap(i,o)),E[g]=C/3,{pts:Q,offsetPt0:new Uint32Array(E),dpg:n,dps:t,dpv:s,groups:o,header:a}}static readTXT(I,A=0){const C=new TextDecoder("utf-8").decode(I).split(/\r?\n|\r/).filter(E=>E.trim().length>0);A<=0&&(A=C.length);const Q=new Float32Array(A);for(let E=0;E<A&&E<C.length;E++){const i=parseFloat(C[E].trim());Q[E]=Number.isFinite(i)?i:0}return Q}static readTSF(I,A=0){const g=new Float32Array(A),C=I.byteLength;if(C<20)throw new Error("File too small to be TSF: bytes = "+C);const Q=new Uint8Array(I);let E=0;function i(){for(;E<C&&Q[E]===10;)E++;const e=E;for(;E<C&&Q[E]!==10;)E++;return E++,E-e<1?"":new TextDecoder().decode(I.slice(e,E-1))}let o=i();if(!o.includes("mrtrix track scalars"))throw new Error("Not a valid TSF file");let t=-1;for(;E<C&&!o.includes("END");)if(o=i(),o.toLowerCase().startsWith("file:")&&(t=parseInt(o.split(" ").pop())),o.toLowerCase().startsWith("datatype:")&&!o.endsWith("Float32LE"))throw new Error("Only supports TSF files with Float32LE");if(t<20)throw new Error("Not a valid TSF file (missing file offset)");E=t;const s=new DataView(I);let a=0;for(;E+4<=C&&a<A;){const e=s.getFloat32(E,!0);if(E+=4,isFinite(e))g[a++]=e;else if(!isNaN(e))break}return g}static readTCK(I){const A=I.byteLength;if(A<20)throw new Error("File too small to be TCK: bytes = "+A);const g=new Uint8Array(I);let C=0;function Q(){for(;C<A&&g[C]===10;)C++;const n=C;for(;C<A&&g[C]!==10;)C++;return C++,C-n<1?"":new TextDecoder().decode(I.slice(n,C-1))}let E=Q();if(!E.includes("mrtrix tracks"))throw new Error("Not a valid TCK file");let i=-1;for(;C<A&&!E.includes("END");)E=Q(),E.toLowerCase().startsWith("file:")&&(i=parseInt(E.split(" ").pop()));if(i<20)throw new Error("Not a valid TCK file (missing file offset)");C=i;const o=new DataView(I);let t=0,s=new Uint32Array(A/(4*4)),a=0,e=0,r=new Float32Array(A/4);for(s[0]=0;C+12<A;){const n=o.getFloat32(C,!0);C+=4;const h=o.getFloat32(C,!0);C+=4;const D=o.getFloat32(C,!0);if(C+=4,isFinite(n))r[e++]=n,r[e++]=h,r[e++]=D,t++;else if(s[a++]=t,!isNaN(n))break}return r=r.slice(0,e),s=s.slice(0,a),{pts:r,offsetPt0:s}}static async readTRK(I){let A=new DataView(I),g=A.getUint32(0,!0);if(g!==1128354388){let k;if(g===4247762216)throw new Error("zstd TRK decompression is not supported");k=await DA.decompress(new Uint8Array(I)),I=k.buffer,A=new DataView(I),g=A.getUint32(0,!0)}const C=A.getUint32(992,!0),Q=A.getUint32(996,!0);if(C>3||Q!==1e3||g!==1128354388)throw new Error(`Not a valid TRK file expected version ≤3 (${C}), header size 1000 (${Q}) and magic of 1128354388 (${g})`);const E=A.getInt16(36,!0),i=[];for(let k=0;k<E;k++){const U=new Uint8Array(I.slice(38+k*20,58+k*20)),Y=new TextDecoder().decode(U).split("\0").shift();i.push({id:Y.trim(),vals:[]})}const o=A.getFloat32(12,!0),t=A.getFloat32(16,!0),s=A.getFloat32(20,!0),a=yI(1/o,0,0,-.5,0,1/t,0,-.5,0,0,1/s,-.5,0,0,0,1),e=A.getInt16(238,!0),r=[];for(let k=0;k<e;k++){const U=new Uint8Array(I.slice(240+k*20,260+k*20)),Y=new TextDecoder().decode(U).split("\0").shift();r.push({id:Y.trim(),vals:[]})}const n=MA();for(let k=0;k<16;k++)n[k]=A.getFloat32(440+k*4,!0);n[15]===0&&(J.warn("TRK vox_to_ras not set"),jQ(n));const h=MA();_Q(h,a,n);let D=null,w=null;D=new Int32Array(I.slice(Q)),w=new Float32Array(D.buffer);const y=D.length;if(y<1)throw new Error("Empty TRK file.");let F=0,c=0,R=new Uint32Array(D.length/4),l=0,S=new Float32Array(D.length),N=0;for(;F<y;){const k=D[F];F=F+1,R[l++]=c;for(let U=0;U<k;U++){const Y=w[F+0],K=w[F+1],b=w[F+2];if(F+=3,S[N++]=Y*h[0]+K*h[1]+b*h[2]+h[3],S[N++]=Y*h[4]+K*h[5]+b*h[6]+h[7],S[N++]=Y*h[8]+K*h[9]+b*h[10]+h[11],E>0)for(let m=0;m<E;m++)i[m].vals.push(w[F]),F++;c++}if(e>0)for(let U=0;U<e;U++)r[U].vals.push(w[F]),F++}const d=[];for(let k=0;k<r.length;k++)d.push({id:r[k].id,vals:Float32Array.from(r[k].vals)});const L=[];for(let k=0;k<i.length;k++)L.push({id:i[k].id,vals:Float32Array.from(i[k].vals)});return R[l++]=c,S=S.slice(0,N),R=R.slice(0,l),{pts:S,offsetPt0:R,dps:d,dpv:L}}static readTxtVTK(I){const C=new TextDecoder("utf-8").decode(I).split(`
  4. `);if(C.length<7||!C[0].startsWith("# vtk DataFile"))throw new Error("Invalid VTK image");if(!C[2].startsWith("ASCII"))throw new Error("Not ASCII VTK mesh");let E=3;for(;C[E].length<1;)E++;if(!C[E].includes("POLYDATA"))throw new Error("Not ASCII VTK polydata");for(E++;C[E].length<1;)E++;if(!C[E].startsWith("POINTS"))throw new Error("Not VTK POINTS");let i=C[E].trim().split(/\s+/);const o=parseInt(i[1]),t=o*3,s=new Float32Array(o*3);let a=0;for(;a<o*3;){E++;const h=C[E].trim().trim().split(/\s+/);for(let D=0;D<h.length&&!(a>=t);D++)s[a]=parseFloat(h[D]),a++}const e=[];for(E++;C[E].length<1;)E++;if(C[E].startsWith("METADATA")){for(;C[E].length>1;)E++;E++}if(i=C[E].trim().split(/\s+/),E++,i[0].includes("LINES")){const n=parseInt(i[1]);if(n<1)throw new Error("Corrupted VTK ASCII");let h=C[E].trim();const D=[];let w=[];if(h.startsWith("OFFSETS")){E++;let y=0;for(;y<n;){h=C[E].trim(),E++;const F=h.trim().split(/\s+/);for(let c=0;c<F.length&&(D[y]=parseInt(F[c]),y++,!(y>=n));c++);}w=Array.from(s)}else{let y=function(){h=C[E].trim();const l=h.trim().split(/\s+/);c=[];for(let S=0;S<l.length;S++)c.push(parseInt(l[S]));R=0,E++},F=0;D[0]=0;let c=[],R=0;y();for(let l=0;l<n;l++){R>=c.length&&y();const S=c[R++];F+=S,D[l+1]=F;for(let N=0;N<S;N++){R>=c.length&&y();const d=c[R++]*3;w.push(s[d+0]),w.push(s[d+1]),w.push(s[d+2])}}}return{pts:Float32Array.from(w),offsetPt0:Uint32Array.from(D)}}else if(i[0].includes("TRIANGLE_STRIPS")){const n=parseInt(i[1]);for(let h=0;h<n;h++){const D=C[E].trim();E++;const w=D.trim().split(/\s+/),y=parseInt(w[0])-2;let F=1;for(let c=0;c<y;c++)c%2?(e.push(parseInt(w[F+2])),e.push(parseInt(w[F+1])),e.push(parseInt(w[F]))):(e.push(parseInt(w[F])),e.push(parseInt(w[F+1])),e.push(parseInt(w[F+2]))),F+=1}}else if(i[0].includes("POLYGONS")){const n=parseInt(i[1]);for(let h=0;h<n;h++){const D=C[E].trim();E++;const w=D.trim().split(/\s+/),y=parseInt(w[0])-2,F=parseInt(w[1]);let c=parseInt(w[2]);for(let R=0;R<y;R++){const l=parseInt(w[3+R]);e.push(F),e.push(c),e.push(l),c=l}}}else throw new Error("Unsupported ASCII VTK datatype "+i[0]);const r=new Uint32Array(e);return{positions:s,indices:r}}static async readLayer(I="",A,g,C=.5,Q="warm",E="winter",i=!1,o=null,t=null,s=0){const a={...QE,colormapInvert:!1,colormapType:0,isTransparentBelowCalMin:!0,isAdditiveBlend:!1,colorbarVisible:!0,colormapLabel:null},e=/(?:\.([^.]+))?$/;let r=e.exec(I)[1];r=r.toUpperCase(),r==="GZ"&&(r=e.exec(I.slice(0,-3))[1],r=r.toUpperCase());const n=g.vertexCount/3;if(g.offsetPt0){const w=I.split("/");let y="Unknown";if(w.length>1&&w.pop()&&(y=y.split(".").slice(0,-1).join(".")),r==="TXT"){const S=g.offsetPt0.length-1,N=dA.readTXT(A,S);if(N.length!==S)throw new Error(`TXT file has ${N.length} items, expected one per streamline (${S}).`);g.dps||(g.dps=[]);const d=N.reduce((k,U)=>Math.min(k,U)),L=N.reduce((k,U)=>Math.max(k,U));return g.dps.push({id:y,vals:Float32Array.from(N.slice()),global_min:d,global_max:L,cal_min:d,cal_max:L}),a}if(r==="NII"){const S=await dA.readNII(A,g.pts,""),N=S.reduce((L,k)=>Math.min(L,k)),d=S.reduce((L,k)=>Math.max(L,k));return g.dpv.push({id:y,vals:Float32Array.from(S.slice()),global_min:N,global_max:d,cal_min:N,cal_max:d}),a}if(r!=="TSF")throw new Error("readLayer for streamlines only supports TSF and TXT files.");const F=g.pts.length/3,c=dA.readTSF(A,F);g.dpv||(g.dpv=[]);const R=c.reduce((S,N)=>Math.min(S,N)),l=c.reduce((S,N)=>Math.max(S,N));return g.dpv.push({id:y,vals:Float32Array.from(c.slice()),global_min:R,global_max:l,cal_min:R,cal_max:l}),a}if(n<3){J.error("n_vert < 3 in layer");return}if(r==="MZ3"){const w=await dA.readMZ3(A,n);a.values=w.scalars,"colormapLabel"in w&&(a.colormapLabel=w.colormapLabel)}else if(r==="ANNOT"){const w=dA.readANNOT(A,n,!0);w instanceof Uint32Array?a.values=w:(a.values=w.scalars,a.colormapLabel=w.colormapLabel)}else if(r==="CRV"||r==="CURV"||r==="THICKNESS"||r==="AREA")a.values=dA.readCURV(A,n),a.isTransparentBelowCalMin=!1;else if(r==="GII"){const w=await dA.readGII(A,n);a.values=w.scalars,a.colormapLabel=w.colormapLabel}else if(r==="MGH"||r==="MGZ"){const w=await dA.readMGH(A,n,!0);"scalars"in w?(a.values=w.scalars,a.colormapLabel=w.colormapLabel):a.values=w}else if(r==="NII")a.values=await dA.readNII(A,g.pts,g.anatomicalStructurePrimary);else if(r==="SMP")a.values=await dA.readSMP(A,n);else if(r==="STC")a.values=dA.readSTC(A,n);else if(dA.isCurv(A))a.values=dA.readCURV(A,n),a.isTransparentBelowCalMin=!1;else return J.warn("Unknown layer overlay format "+I),a;if(!a.values){J.error("no values in layer");return}a.nFrame4D=a.values.length/n,a.frame4D=0,a.outlineBorder=s;let h=a.values[0],D=a.values[0];for(let w=0;w<a.values.length;w++)h=Math.min(h,a.values[w]),D=Math.max(D,a.values[w]);return a.global_min=h,a.global_max=D,a.cal_min=o||0,o||(a.cal_min=h),a.cal_max=t||0,t||(a.cal_max=D),a.cal_minNeg=NaN,a.cal_maxNeg=NaN,a.opacity=C,a.colormap=Q,a.colormapNegative=E,a.useNegativeCmap=i,a}static async readSMP(I,A){const g=I.byteLength;let C=new DataView(I),Q=C.getUint16(0,!0);if(Q>5){const a=await DA.decompress(new Uint8Array(I));C=new DataView(a.buffer),Q=C.getUint16(0,!0),I=a.buffer}Q>5&&J.error("Unsupported or invalid BrainVoyager SMP version "+Q);const E=C.getUint32(2,!0);E!==A&&J.error("SMP file has "+E+" vertices, background mesh has "+A);const i=C.getUint16(6,!0),o=new Float32Array(E*i);let t=9;function s(){const a=t;for(;t<g&&C.getUint8(t)!==0;)t++;return t++,new TextDecoder().decode(I.slice(a,t-1))}s();for(let a=0;a<i;a++){const e={};e.mapType=C.getUint32(t,!0),t+=4,Q>=3&&e.mapType===3&&(e.nLags=C.getUint32(t,!0),t+=4,e.mnLag=C.getUint32(t,!0),t+=4,e.mxLag=C.getUint32(t,!0),t+=4,e.ccOverlay=C.getUint32(t,!0),t+=4),e.clusterSize=C.getUint32(t,!0),t+=4,e.clusterCheck=C.getUint8(t),t+=1,e.critThresh=C.getFloat32(t,!0),t+=4,e.maxThresh=C.getFloat32(t,!0),t+=4,Q>=4&&(e.includeValuesGreaterThreshMax=C.getUint32(t,!0),t+=4),e.df1=C.getUint32(t,!0),t+=4,e.df2=C.getUint32(t,!0),t+=4,Q>=5?(e.posNegFlag=C.getUint32(t,!0),t+=4):e.posNegFlag=3,e.cortexBonferroni=C.getUint32(t,!0),t+=4,e.posMinRGB=[0,0,0],e.posMaxRGB=[0,0,0],e.negMinRGB=[0,0,0],e.negMaxRGB=[0,0,0],Q>=2&&(e.posMinRGB[0]=C.getUint8(t),t++,e.posMinRGB[1]=C.getUint8(t),t++,e.posMinRGB[2]=C.getUint8(t),t++,e.posMaxRGB[0]=C.getUint8(t),t++,e.posMaxRGB[1]=C.getUint8(t),t++,e.posMaxRGB[2]=C.getUint8(t),t++,Q>=4&&(e.negMinRGB[0]=C.getUint8(t),t++,e.negMinRGB[1]=C.getUint8(t),t++,e.negMinRGB[2]=C.getUint8(t),t++,e.negMaxRGB[0]=C.getUint8(t),t++,e.negMaxRGB[1]=C.getUint8(t),t++,e.negMaxRGB[2]=C.getUint8(t),t++),e.enableSMPColor=C.getUint8(t),t++,Q>=4&&(e.lut=s()),e.colorAlpha=C.getFloat32(t,!0),t+=4),e.name=s();const r=new Float32Array(I,t,E);o.set(r,a*E),t+=E*4}return o}static readSTC(I,A){const g=new DataView(I),C=g.getInt32(8,!1);if(C!==A)throw new Error("Overlay has "+C+" vertices, expected "+A);let Q=12+C*4;const E=g.getUint32(Q,!1);Q+=4;const i=new Float32Array(E*C);for(let o=0;o<E*C;o++)i[o]=g.getFloat32(Q,!1),Q+=4;return i}static isCurv(I){const A=new DataView(I),g=A.getUint8(0),C=A.getUint8(1),Q=A.getUint8(2);return g!==255||C!==255||Q!==255?(AB.debug("Unable to recognize file type: does not appear to be FreeSurfer format."),!1):!0}static readCURV(I,A){const g=new DataView(I),C=g.getUint8(0),Q=g.getUint8(1),E=g.getUint8(2),i=g.getUint32(3,!1),o=g.getUint32(11,!1);if((C!==255||Q!==255||E!==255)&&AB.debug("Unable to recognize file type: does not appear to be FreeSurfer format."),A!==i)throw new Error("CURV file has different number of vertices ( "+i+")than mesh ("+A+")");if(I.byteLength<15+4*i*o)throw new Error("CURV file smaller than specified");const t=new Float32Array(o*i);let s=15;for(let n=0;n<o*i;n++)t[n]=g.getFloat32(s,!1),s+=4;let a=t[0],e=t[0];for(let n=0;n<t.length;n++)a=Math.min(a,t[n]),e=Math.max(e,t[n]);const r=1/(e-a);for(let n=0;n<t.length;n++)t[n]=1-(t[n]-a)*r;return t}static readANNOT(I,A,g=!1){const C=new DataView(I),Q=C.getUint32(0,!1),E=this.decimateLayerVertices(Q,A);if(A!==E)throw new Error("ANNOT file has different number of vertices than mesh");if(I.byteLength<4+8*Q)throw new Error("ANNOT file smaller than specified");let i=0;const o=new Uint32Array(Q);for(let c=0;c<Q;c++){const R=C.getUint32(i+=4,!1);o[R]=C.getUint32(i+=4,!1)}if(!g)return o;let t=0;try{t=C.getInt32(i+=4,!1)}catch{return o}if(t!==1||C.getInt32(i+=4,!1)>0)return o;const e=C.getInt32(i+=4,!1),r=C.getInt32(i+=4,!1);i+=r;const n=C.getInt32(i+=4,!1);if(n<1)return o;const h={R:Array(e).fill(0),G:Array(e).fill(0),B:Array(e).fill(0),A:Array(e).fill(0),I:Array(e).fill(0),labels:Array(e).fill("")};for(let c=0;c<n;c++){const R=C.getInt32(i+=4,!1),l=C.getInt32(i+=4,!1);i+=4;let S="";for(let U=0;U<l;U++){const Y=C.getUint8(i++);if(Y===0)break;S+=String.fromCharCode(Y)}i-=4;const N=C.getInt32(i+=4,!1),d=C.getInt32(i+=4,!1),L=C.getInt32(i+=4,!1),k=C.getInt32(i+=4,!1);if(R<0||R>=e){J.warn("annot entry out of range");continue}h.R[R]=N,h.G[R]=d,h.B[R]=L,h.A[R]=k,h.I[R]=(k<<24)+(L<<16)+(d<<8)+N,h.labels[R]=S}let D=!0;for(let c=0;c<e;c++)h.A[c]>0&&(D=!1);if(D)for(let c=0;c<e;c++)h.A[c]=255;const w=new Float32Array(Q);w.fill(-1);let y=0;for(let c=0;c<A;c++){const R=o[c];for(let l=0;l<e;l++)if(h.I[l]===R){w[c]=l;break}w[c]<0&&(y++,w[c]=0)}y>0&&J.error(`annot vertex colors do not match ${y} of ${Q} vertices.`);for(let c=0;c<e;c++)h.I[c]=c;const F=pA.makeLabelLut(h);return{scalars:w,colormapLabel:F}}static readNV(I){const A=I.byteLength,g=new Uint8Array(I);let C=0;function Q(){for(;C<A&&g[C]===10;)C++;const e=C;for(;C<A&&g[C]!==10;)C++;return C++,C-e<1?"":new TextDecoder().decode(I.slice(e,C-1))}let E=0,i=0,o=0,t=0,s,a;for(;C<A;){const e=Q();if(e.startsWith("#"))continue;const r=e.trim().split(/\s+/);if(E<1){E=parseInt(r[0]),s=new Float32Array(E*3);continue}if(o<E*3){s[o]=parseFloat(r[0]),s[o+1]=parseFloat(r[1]),s[o+2]=parseFloat(r[2]),o+=3;continue}if(i<1){i=parseInt(r[0]),a=new Uint32Array(i*3);continue}if(t>=i*3)break;a[t+2]=parseInt(r[0])-1,a[t+1]=parseInt(r[1])-1,a[t+0]=parseInt(r[2])-1,t+=3}return{positions:s,indices:a}}static readASC(I){const A=I.byteLength,g=new Uint8Array(I);let C=0;function Q(){for(;C<A&&g[C]===10;)C++;const r=C;for(;C<A&&g[C]!==10;)C++;return C++,C-r<1?"":new TextDecoder().decode(I.slice(r,C-1))}let E=Q();E.startsWith("#!ascii")||J.warn("Invalid ASC mesh"),E=Q();let i=E.trim().split(/\s+/);const o=parseInt(i[0]),t=parseInt(i[1]),s=new Float32Array(o*3);let a=0;for(let r=0;r<o;r++)E=Q(),i=E.trim().split(/\s+/),s[a]=parseFloat(i[0]),s[a+1]=parseFloat(i[1]),s[a+2]=parseFloat(i[2]),a+=3;const e=new Uint32Array(t*3);a=0;for(let r=0;r<t;r++)E=Q(),i=E.trim().split(/\s+/),e[a]=parseInt(i[0]),e[a+1]=parseInt(i[1]),e[a+2]=parseInt(i[2]),a+=3;return{positions:s,indices:e}}static readVTK(I){const A=I.byteLength;if(A<20)throw new Error("File too small to be VTK: bytes = "+I.byteLength);const g=new Uint8Array(I);let C=0;function Q(h=!0){if(h)for(;C<A&&g[C]===10;)C++;const D=C;for(;C<A&&g[C]!==10;)C++;return C++,C-D<1?"":new TextDecoder().decode(I.slice(D,C-1))}let E=Q();if(!E.startsWith("# vtk DataFile"))throw new Error("Invalid VTK mesh");if(E=Q(!1),E=Q(),E.startsWith("ASCII"))return dA.readTxtVTK(I);if(!E.startsWith("BINARY"))throw new Error("Invalid VTK image, expected ASCII or BINARY "+E);if(E=Q(),!E.includes("POLYDATA"))throw new Error("Only able to read VTK POLYDATA "+E);E=Q(),(!E.includes("POINTS")||!E.includes("double")&&!E.includes("float"))&&J.warn("Only able to read VTK float or double POINTS"+E);const i=E.includes("double");let o=E.trim().split(/\s+/);const s=parseInt(o[1])*3,a=new Float32Array(s),e=new DataView(I);if(i)for(let h=0;h<s;h++)a[h]=e.getFloat64(C,!1),C+=8;else for(let h=0;h<s;h++)a[h]=e.getFloat32(C,!1),C+=4;E=Q(),o=E.trim().split(/\s+/);const r=[];if(o[0].includes("LINES")){const h=parseInt(o[1]),D=C;if(E=Q(),E.startsWith("OFFSETS")){let c=!1;E.includes("int64")&&(c=!0);const R=new Uint32Array(h);if(c){let S=!1;for(let N=0;N<h;N++){let d=e.getInt32(C,!1);d!==0&&(S=!0),C+=4,d=e.getInt32(C,!1),C+=4,R[N]=d}S&&J.warn("int32 overflow: JavaScript does not support int64")}else for(let S=0;S<h;S++){const N=e.getInt32(C,!1);C+=4,R[S]=N}return{pts:a,offsetPt0:R}}C=D;let w=0;const y=[],F=[];y.push(w);for(let c=0;c<h;c++){const R=e.getInt32(C,!1);C+=4,w+=R,y.push(w);for(let l=0;l<R;l++){const S=e.getInt32(C,!1)*3;C+=4,F.push(a[S+0]),F.push(a[S+1]),F.push(a[S+2])}}return{pts:Float32Array.from(F),offsetPt0:Uint32Array.from(y)}}else if(o[0].includes("TRIANGLE_STRIPS")){const h=parseInt(o[1]);for(let D=0;D<h;D++){const w=e.getInt32(C,!1)-2;C+=4;for(let y=0;y<w;y++)y%2?(r.push(e.getInt32(C+8,!1)),r.push(e.getInt32(C+4,!1)),r.push(e.getInt32(C,!1))):(r.push(e.getInt32(C,!1)),r.push(e.getInt32(C+4,!1)),r.push(e.getInt32(C+8,!1))),C+=4;C+=8}}else if(o[0].includes("POLYGONS")){const h=parseInt(o[1]),D=C,w=Q();if(w.startsWith("OFFSETS")){let y=w.includes("int64");const F=new Uint32Array(h);let c=!1;for(let N=0;N<h;N++)y&&(e.getInt32(C,!1)!==0&&(c=!0),C+=4),F[N]=e.getInt32(C,!1),C+=4;if(!Number.isSafeInteger(h)||h>=2147483648||c)throw new Error("values exceed 2GB limit");const R=Q();if(!R.startsWith("CONNECTIVITY"))throw new Error("Expected CONNECTIVITY after OFFSETS");y=R.includes("int64");const l=F[h-1],S=new Uint32Array(l);for(let N=0;N<l;N++)y&&(C+=4),S[N]=e.getInt32(C,!1),C+=4;for(let N=0;N<h;N++){const d=N===0?0:F[N-1],L=F[N];for(let k=1;k<L-d-1;k++)r.push(S[d]),r.push(S[d+k]),r.push(S[d+k+1])}}else{C=D;for(let y=0;y<h;y++){const F=e.getInt32(C,!1)-2;if(y===0&&F>65535)throw new Error("Invalid VTK binary polygons using little-endian data (MRtrix)");C+=4;const c=e.getInt32(C,!1);C+=4;let R=e.getInt32(C,!1);C+=4;for(let l=0;l<F;l++){const S=e.getInt32(C,!1);C+=4,r.push(c,R,S),R=S}}}}else throw new Error("Unsupported binary VTK datatype "+o[0]);const n=new Uint32Array(r);return{positions:a,indices:n}}static readWRL(I){const A=new TextDecoder("utf-8").decode(I),g=/coord\s+Coordinate\s*\{\s*point\s*\[([\s\S]*?)\]/,C=/coordIndex\s*\[([\s\S]*?)\]/,Q=/color\s+Color\s*\{\s*color\s*\[([\s\S]*?)\]/,E=g.exec(A),i=C.exec(A),o=Q.exec(A);if(!E||!i)throw new Error("Invalid WRL file: Could not find vertices or indices.");const t=new Float32Array(E[1].trim().split(/[\s,]+/).map(Number));let s=null;if(o){s=new Float32Array(o[1].trim().split(/[\s,]+/).map(Number));const e=t.length/3;s.length!==e*3&&(console.warn(`Unexpected color count: expected ${e*3}, got ${s.length}`),s=null)}const a=new Uint32Array(i[1].trim().split(/[\s,]+/).map(Number).filter(e=>e!==-1));return{positions:t,indices:a,colors:s}}static readDFS(I){const A=new DataView(I),g=A.getUint32(0,!0),C=A.getUint16(4,!0);(g!==1599292996||C!==17740)&&J.warn("Not a little-endian brainsuite DFS mesh");const Q=A.getUint32(12,!0),E=A.getUint32(24,!0),i=A.getUint32(28,!0),o=A.getUint32(48,!0);let t=Q;const s=new Uint32Array(I,t,E*3);t+=E*3*4;const a=new Float32Array(I,t,i*3);for(let r=0;r<i*3;r+=3){const n=a[r];a[r]=a[r+1],a[r+1]=n}let e;return o>=0&&(e=new Float32Array(I,o,i*3)),{positions:a,indices:s,colors:e}}static async readMZ3(I,A=0){if(I.byteLength<20)throw new Error("File too small to be mz3: bytes = "+I.byteLength);let g=new DataView(I),C=I,Q=g.getUint16(0,!0);if(Q===35615||Q===8075){const d=await DA.decompress(new Uint8Array(I));g=new DataView(d.buffer),Q=g.getUint16(0,!0),C=d.buffer}const E=g.getUint16(2,!0),i=g.getUint32(4,!0);let o=g.getUint32(8,!0);const t=g.getUint32(12,!0);if(AB.debug("MZ3 magic %d attr %d face %d vert %d skip %d",Q,E,i,o,t),Q!==23117)throw new Error("Invalid MZ3 file");const s=(E&1)!==0,a=(E&2)!==0,e=(E&4)!==0;let r=(E&8)!==0;const n=(E&16)!==0,h=(E&32)!==0,D=(E&64)!==0;if(AB.debug(`isFace=${s} isVert=${a} isRGBA=${e} isSCALAR=${r} isDOUBLE=${n} isAOMAP=${h} isLOOKUP=${D}`),E>127)throw new Error("Unsupported future version of MZ3 file");let w=4;n&&(w=8);let y=0;if(A>0&&!s&&i<1&&!e&&(r=!0),r){const d=A||o,L=16+t+(s?i*12:0)+(a?d*12:0)+(e?d*4:0),k=Math.floor((C.byteLength-L)/w);o!==A&&k%A===0&&(o=A),y=Math.floor(k/o),y<1&&(J.warn("Corrupt MZ3: file reports NSCALAR but not enough bytes"),r=!1)}if(o<3&&A<3)throw new Error("Not a mesh MZ3 file (maybe scalar)");A>0&&A!==o&&J.warn("Layer has "+o+"vertices, but background mesh has "+A);let F=16+t;const c=new DataView(C);let R=null;if(s){R=new Uint32Array(i*3);for(let d=0;d<i*3;d++)R[d]=c.getUint32(F,!0),F+=4}let l=null;if(a){l=new Float32Array(o*3);for(let d=0;d<o*3;d++)l[d]=c.getFloat32(F,!0),F+=4}let S=null;if(e){S=new Float32Array(o*3);for(let d=0;d<o;d++){for(let L=0;L<3;L++)S[d*3+L]=c.getUint8(F++)/255;F++}}let N=new Float32Array;if(r&&y>0)if(n){const d=new Float64Array(y*o);for(let L=0;L<y*o;L++)d[L]=c.getFloat64(F,!0),F+=8;N=Float32Array.from(d)}else{N=new Float32Array(y*o);for(let d=0;d<y*o;d++)N[d]=c.getFloat32(F,!0),F+=4}if(A>0&&D&&r){const d=new TextDecoder("utf-8"),L=new Uint8Array(C,16,t),k=d.decode(L),U=JSON.parse(k),Y=pA.makeLabelLut(U);return{scalars:N,colormapLabel:Y}}if(A>0&&e&&r){let d=N[0];for(let U=0;U<o;U++)d=Math.max(d,N[U]);const L={R:[],G:[],B:[],A:[],I:[],labels:[]};for(let U=0;U<=d;U++)for(let Y=0;Y<o;Y++)if(U===N[Y]){const K=Y*3;L.I.push(U),L.R.push(S[K]*255),L.G.push(S[K+1]*255),L.B.push(S[K+2]*255),L.A.push(255),L.labels.push(`${U}`);break}const k=pA.makeLabelLut(L);return{scalars:N,colormapLabel:k}}return A>0?{scalars:N}:{positions:l,indices:R,scalars:N,colors:S}}static readPLY(I){const A=I.byteLength,g=new Uint8Array(I);let C=0;function Q(){for(;C<A&&g[C]===10;)C++;const m=C;for(;C<A&&g[C]!==10;)C++;return C++,C-m<1?"":new TextDecoder().decode(I.slice(m,C-1))}let E=Q();if(!E.startsWith("ply"))throw new Error("Not a valid PLY file");E=Q();const i=E.includes("ascii");function o(m){if(m==="char"||m==="uchar"||m==="int8"||m==="uint8")return 1;if(m==="short"||m==="ushort"||m==="int16"||m==="uint16")return 2;if(m==="int"||m==="uint"||m==="int32"||m==="uint32"||m==="float"||m==="float32")return 4;if(m==="double")return 8;throw new Error("Unknown data type: "+m)}const t=E.includes("binary_little_endian");let s=0,a=!1,e=0,r=0,n=0,h=0,D=0,w=0,y=0;const F=[];let c=0,R=-1,l=-1,S=-1,N=!1;for(;C<A&&!E.startsWith("end_header");){if(E=Q(),E.startsWith("comment"))continue;let m=E.split(/\s/);if(E.startsWith("element vertex"))for(s=parseInt(m[m.length-1]),E=Q(),m=E.split(/\s/),c=0,F.length=0;E.startsWith("property");){const P=m[1],_=m[2];F.push(_),_==="red"?(R=c,N=!0):_==="green"?(l=c,N=!0):_==="blue"&&(S=c,N=!0),_==="x"&&P.startsWith("double")?a=!0:_==="x"&&!P.startsWith("float")&&J.error("Error: expect ply xyz to be float or double: "+E);const CA=o(P);e+=CA,c+=CA,E=Q(),m=E.split(/\s/)}if(E.startsWith("element face"))for(y=parseInt(m[m.length-1]),E=Q(),m=E.split(/\s/);E.startsWith("property");){if(m[1]==="list")n=o(m[2]),h=o(m[3]),r+=n+3*h;else{const P=o(m[1]);r+=P,h===0&&(D+=P,w++)}E=Q(),m=E.split(/\s/)}}if(i){y<1&&J.error(`Malformed ply format: faces ${y} `);const m=new Float32Array(s*3);let P;const _=F.indexOf("x"),CA=F.indexOf("y"),eA=F.indexOf("z"),yA=F.indexOf("red"),nA=F.indexOf("green"),lA=F.indexOf("blue");yA!==-1&&nA!==-1&&lA!==-1&&(P=new Float32Array(s*3),N=!0);let AA=0;for(let kA=0;kA<s;kA++){E=Q();const SA=E.split(/\s/),zA=_>=0?parseFloat(SA[_]):parseFloat(SA[0]),NA=CA>=0?parseFloat(SA[CA]):parseFloat(SA[1]),XA=eA>=0?parseFloat(SA[eA]):parseFloat(SA[2]);if(m[AA]=zA,m[AA+1]=NA,m[AA+2]=XA,N&&P){const RA=yA>=0?parseInt(SA[yA]):0,AI=nA>=0?parseInt(SA[nA]):0,GI=lA>=0?parseInt(SA[lA]):0,dI=kA*3;P[dI]=RA/255,P[dI+1]=AI/255,P[dI+2]=GI/255}AA+=3}let oA=new Uint32Array(y*3),O=0;for(let kA=0;kA<y;kA++){E=Q();const SA=E.split(/\s/),zA=parseInt(SA[w])-2;if(zA<1)break;if(O+zA*3>oA.length){const RA=new Uint32Array(oA.length+oA.length);RA.set(oA),oA=RA.slice()}const NA=parseInt(SA[w+1]);let XA=parseInt(SA[w+2]);for(let RA=0;RA<zA;RA++){const AI=parseInt(SA[w+3+RA]);oA[O+0]=NA,oA[O+1]=XA,oA[O+2]=AI,XA=AI,O+=3}}oA.length!==O&&(oA=oA.slice(0,O));const FA={positions:m,indices:oA};return N&&(FA.colors=typeof P<"u"?P:void 0),FA}(e<12||n<1||h<1||y<1)&&J.warn(`Malformed ply format: stride ${e} count ${n} iBytes ${h} iStrideBytes ${r} iPadBytes ${D} faces ${y}`);const d=new DataView(I);let L,k;if(N&&(k=new Float32Array(s*3)),C%4===0&&e===12&&t)L=new Float32Array(I,C,s*3),C+=s*e;else{L=new Float32Array(s*3);let m=0;for(let P=0;P<s;P++){if(a?(L[m]=d.getFloat64(C,t),L[m+1]=d.getFloat64(C+8,t),L[m+2]=d.getFloat64(C+16,t)):(L[m]=d.getFloat32(C,t),L[m+1]=d.getFloat32(C+4,t),L[m+2]=d.getFloat32(C+8,t)),N&&k){const _=C,CA=R>=0?d.getUint8(_+R):0,eA=l>=0?d.getUint8(_+l):0,yA=S>=0?d.getUint8(_+S):0,nA=P*3;k[nA]=CA/255,k[nA+1]=eA/255,k[nA+2]=yA/255}m+=3,C+=e}}const U=new Uint32Array(y*3);let Y=!0,K=0;if(n===1&&h===4&&r===13)for(let m=0;m<y;m++){const P=d.getUint8(C);C+=n,P!==3&&(Y=!1),U[K]=d.getUint32(C,t),C+=4,U[K+1]=d.getUint32(C,t),C+=4,U[K+2]=d.getUint32(C,t),C+=4,K+=3}else{let m=C;for(let P=0;P<y;P++){C=m+D;let _=0;n===1?_=d.getUint8(C):n===2?_=d.getUint16(C,t):n===4&&(_=d.getUint32(C,t)),C+=n,_!==3&&(Y=!1);for(let CA=0;CA<3;CA++)h===1?U[K]=d.getUint8(C):h===2?U[K]=d.getUint16(C,t):h===4&&(U[K]=d.getUint32(C,t)),K++,C+=h;m+=r}}Y||J.warn("Only able to read PLY meshes limited to triangles.");const b={positions:L,indices:U};return N&&typeof k<"u"&&(b.colors=k),b}static readICO(I){const C=new TextDecoder("utf-8").decode(I).split(`
  5. `);let Q=C[0].trim().split(/\s+/);Q.length>1&&J.warn("This is not a valid FreeSurfer ICO/TRI mesh.");const E=parseInt(Q[0]),i=new Float32Array(E*3);let o=1;for(let a=0;a<E;a++){const e=C[o].trim().split(/\s+/);o++;let r=parseInt(e[0])-1;const n=parseFloat(e[1]),h=parseFloat(e[2]),D=parseFloat(e[3]);if(r<0||r>=E){J.error("ICO vertices corrupted");break}r*=3,i[r]=n,i[r+1]=h,i[r+2]=D}Q=C[o].trim().split(/\s+/),o++;const t=parseInt(Q[0]),s=new Uint32Array(t*3);for(let a=0;a<t;a++){const e=C[o].trim().split(/\s+/);o++;let r=parseInt(e[0])-1;const n=parseInt(e[1])-1,h=parseInt(e[2])-1,D=parseInt(e[3])-1;if(r<0||r>=t){J.error("ICO indices corrupted");break}r*=3,s[r]=n,s[r+1]=h,s[r+2]=D}for(let a=0;a<s.length;a+=3){const e=s[a];s[a]=s[a+1],s[a+1]=e}return{positions:i,indices:s}}static readGEO(I,A=!1){const Q=new TextDecoder("utf-8").decode(I).split(`
  6. `),E=Q[0].trim().split(/\s+/),i=parseInt(E[0]);let o=parseInt(E[1]),t=parseInt(E[2]);const s=parseInt(E[3]);(i>1||s!==t*3)&&J.warn("Multi-part BYU/GEO header or not a triangular mesh.");const a=[];o*=3;let e=0,r=2;for(;e<o;){const y=Q[r].trim().split(/\s+/);r++;for(let F=0;F<y.length&&(a.push(parseFloat(y[F])),e++,!(e>=o));F++);}const n=[];t*=3;let h=0;for(;h<t;){const y=Q[r].trim().split(/\s+/);r++;for(let F=0;F<y.length&&(n.push(Math.abs(parseInt(y[F]))-1),h++,!(h>=t));F++);}if(A)for(let y=0;y<n.length;y+=3){const F=n[y];n[y]=n[y+1],n[y+1]=F}const D=new Float32Array(a),w=new Uint32Array(n);return{positions:D,indices:w}}static readOFF(I){const C=new TextDecoder("utf-8").decode(I).split(`
  7. `),Q=[],E=[];let i=0;C[i].includes("OFF")?i++:J.warn("File does not start with OFF");let o=C[i].trim().split(/\s+/);const t=parseInt(o[0]),s=parseInt(o[1]);i++;for(let r=0;r<t;r++)o=C[i].trim().split(/\s+/),Q.push(parseFloat(o[0])),Q.push(parseFloat(o[1])),Q.push(parseFloat(o[2])),i++;for(let r=0;r<s;r++)o=C[i].trim().split(/\s+/),parseInt(o[0])!==3&&J.warn("Only able to read OFF files with triangular meshes"),E.push(parseInt(o[1])),E.push(parseInt(o[2])),E.push(parseInt(o[3])),i++;const a=new Float32Array(Q),e=new Uint32Array(E);return{positions:a,indices:e}}static readOBJMNI(I){const C=new TextDecoder("utf-8").decode(I).trim().split(/\s*,\s*|\s+/);(C.length<1||C[0]!=="P")&&J.warn("This is not a valid MNI OBJ mesh.");let Q=6;const E=parseInt(C[Q++]),i=E*3,o=new Float32Array(i);for(let n=0;n<i;n++)o[n]=parseFloat(C[Q++]);Q+=i;const t=parseInt(C[Q++]),s=parseInt(C[Q++]);(t<1||s<0||s>2)&&J.warn("This is not a valid MNI OBJ mesh.");let a=1;s===1?a=t:s===1&&(a=E),Q+=a*4,Q+=t;const e=t*3,r=new Uint32Array(e);for(let n=0;n<e;n++)r[n]=parseInt(C[Q++]);return{positions:o,indices:r}}static async readOBJ(I){const A=new Uint8Array(I,0,2);A[0]===31&&A[1]===139&&(I=await DA.decompressToBuffer(new Uint8Array(I)));const C=new TextDecoder("utf-8").decode(I);if(C[0]==="P")return this.readOBJMNI(I);const Q=C.split(`
  8. `),E=Q.length,i=[],o=[];for(let r=0;r<E;r++){const n=Q[r];if(n[0]==="v"&&n[1]===" "){const h=n.trim().split(/\s+/);i.push(parseFloat(h[1])),i.push(parseFloat(h[2])),i.push(parseFloat(h[3]))}if(n[0]==="f"){const h=n.trim().split(/\s+/),D=h.length-3;if(D<1)break;let w=h[1].split("/");const y=parseInt(w[0])-1;w=h[2].split("/");let F=parseInt(w[0])-1;for(let c=0;c<D;c++){w=h[3+c].split("/");const R=parseInt(w[0])-1;o.push(y),o.push(F),o.push(R),F=R}}}const t=new Float32Array(i),s=new Uint32Array(o);let a=s[0],e=s[0];for(let r=1;r<s.length;r++)s[r]<a&&(a=s[r]),s[r]>e&&(e=s[r]);if(e-a+1>t.length/3)throw new Error("Not a valid OBJ file");for(let r=0;r<s.length;r++)s[r]-=a;return{positions:t,indices:s}}static readFreeSurfer(I){const A=new Uint8Array(I);if(A[0]===35&&A[1]===33&&A[2]===97)return dA.readASC(I);const g=new DataView(I),C=g.getUint32(0,!1),Q=g.getUint32(4,!1);(C!==4294966883||Q!==1919246708)&&AB.debug("Unable to recognize file type: does not appear to be FreeSurfer format.");let E=0;for(;g.getUint8(E)!==10;)E++;E+=2;let i=g.getUint32(E,!1);E+=4;let o=g.getUint32(E,!1);E+=4,i*=3;const t=new Float32Array(i);for(let r=0;r<i;r++)t[r]=g.getFloat32(E,!1),E+=4;o*=3;const s=new Uint32Array(o);for(let r=0;r<o;r++)s[r]=g.getUint32(E,!1),E+=4;const a=g.getUint32(E,!1);E+=4;let e=a===20;if(!e){const r=g.getUint32(E,!1);E+=4;const n=g.getUint32(E,!1);E+=4,e=a===2&&r===0&&n===20}if(!e)J.warn("Unknown FreeSurfer Mesh extension code.");else{const n=new TextDecoder().decode(I.slice(E)).trim().split(`
  9. `);for(let h=0;h<n.length;h++){if(!n[h].startsWith("cras"))continue;const w=n[h].split("=")[1].trim().split(" ").map(Number),y=Math.floor(t.length/3);let F=0;for(let c=0;c<y;c++)t[F]+=w[0],F++,t[F]+=w[1],F++,t[F]+=w[2],F++}}return{positions:t,indices:s}}static async readSRF(I){const A=new Uint8Array(I);if(A[0]===35&&A[1]===33&&A[2]===97)return dA.readASC(I);A[0]===31&&A[1]===139&&(I=(await DA.decompress(new Uint8Array(I))).buffer);const g=new DataView(I),C=g.getFloat32(0,!0),Q=g.getUint32(8,!0),E=g.getUint32(12,!0),i=g.getFloat32(16,!0),o=g.getFloat32(20,!0),t=g.getFloat32(24,!0),s=new Float32Array(Q*3);let a=28,e=1;for(let l=0;l<Q;l++)s[e]=-g.getFloat32(a,!0)+i,e+=3,a+=4;e=2;for(let l=0;l<Q;l++)s[e]=-g.getFloat32(a,!0)+o,e+=3,a+=4;e=0;for(let l=0;l<Q;l++)s[e]=-g.getFloat32(a,!0)+t,e+=3,a+=4;a=28+4*6*Q;const r=g.getFloat32(a,!0),n=g.getFloat32(a+4,!0),h=g.getFloat32(a+8,!0),D=g.getFloat32(a+16,!0),w=g.getFloat32(a+20,!0),y=g.getFloat32(a+24,!0);a+=8*4;const F=new Float32Array(Q*3),c=new Uint32Array(I,a,Q);e=0;for(let l=0;l<Q;l++){const S=c[l];S>1056964608&&(F[e+0]=(S>>16&255)/255,F[e+1]=(S>>8&255)/255,F[e+2]=(S&255)/255),S===0&&(F[e+0]=r,F[e+1]=n,F[e+2]=h),S===1&&(F[e+0]=D,F[e+1]=w,F[e+2]=y),e+=3}a+=Q*4;for(let l=0;l<Q;l++){const S=g.getUint32(a,!0);a+=4+4*S}const R=new Uint32Array(E*3);for(let l=0;l<E*3;l++)R[l]=g.getInt32(a,!0),a+=4;return C!==4&&J.warn("Not valid SRF"),{positions:s,indices:R,colors:F}}static readTxtSTL(I){const C=new TextDecoder("utf-8").decode(I).split(`
  10. `);if(!C[0].startsWith("solid"))throw new Error("Not a valid STL file");const Q=[];for(let t=1;t<C.length;t++){if(!C[t].includes("vertex"))continue;const s=C[t].trim().split(/\s+/);for(let a=1;a<s.length;a++)Q.push(parseFloat(s[a]))}const E=Math.floor(Q.length/3);if(E*3!==Q.length)throw new Error("Unable to parse ASCII STL file.");const i=new Float32Array(Q),o=new Uint32Array(E);for(let t=0;t<E;t++)o[t]=t;return{positions:i,indices:o}}static readSTL(I){if(I.byteLength<134)throw new Error("File too small to be STL: bytes = "+I.byteLength);const A=new DataView(I);if(A.getUint32(0,!0)===1768714099)return dA.readTxtSTL(I);const C=A.getUint32(80,!0),Q=3*C;if(I.byteLength<84+C*50)throw new Error("STL file too small to store triangles = "+C);const E=new Uint32Array(Q),i=new Float32Array(Q*3);let o=96,t=0;for(let s=0;s<C;s++){for(let a=0;a<9;a++)i[t]=A.getFloat32(o,!0),t+=1,o+=4;o+=14}for(let s=0;s<Q;s++)E[s]=s;return{positions:i,indices:E}}static decimateLayerVertices(I,A){if(I%A===0)return I;const g=12,C=Math.round(Math.log((I-2)/(g-2))/Math.log(4)),Q=Math.round(Math.log((A-2)/(g-2))/Math.log(4)),E=Math.pow(4,C)*(g-2)+2,i=Math.pow(4,Q)*(g-2)+2;return E!==I||i!==A?I:A}static async readNII2(I,A=0,g=""){let C=new Float32Array;const Q=I.byteLength;let E=!0;const i=new DataView(I);let o=i.getUint16(0,E);if(o===469893120&&(E=!1,o=i.getUint16(0,E)),o!==540)throw new Error("Not a valid NIfTI-2 dataset");const t=Number(i.getBigInt64(168,E)),s=i.getFloat64(176,E),a=i.getFloat64(184,E);(s!==1||a!==0)&&J.warn("ignoring scale slope and intercept");const e=i.getUint32(504,E),r=i.getUint16(12,E);if(r!==2&&r!==4&&r!==8&&r!==16)throw new Error("Unsupported NIfTI datatype "+r);let n=1;const h=[1,1,1,1,1,1,1,1];for(let D=1;D<8;D++)h[D]=Math.max(Number(i.getBigInt64(16+D*8,E)),1),n*=h[D];if(e>=3e3&&e<=3099&&t>580){let D=function(){for(;d<Q&&N[d]===10;)d++;const m=d;for(;d<Q&&N[d]!==10;)d++;return d++,d-m<1?"":new TextDecoder().decode(I.slice(m,d-1)).trim()},w=function(){let m=D();if(!m.startsWith("<")||m.endsWith(">"))return m;for(;d<Q&&!m.endsWith(">");)m+=D();return m},y=function(m,P=!1){const _=L.indexOf(m);if(_<0)return 1;const CA=L.indexOf('"',_)+1,eA=L.indexOf('"',CA),yA=L.slice(CA,eA);return P?yA:parseInt(yA)},F=0,c=0,R=0,l="",S=new Uint32Array;const N=new Uint8Array(I);let d=552,L;const k=h[5],U=new Float32Array(A*k);for(;d<Q&&(L=w(),!L.includes("</CIFTI>"));)if(L.includes("<BrainModel")){const m=y("SurfaceNumberOfVertices="),P=y("BrainStructure=",!0).toUpperCase();if(m%A!==0)continue;let _=!1;if(g.includes("CORTEX")&&P.includes("CORTEX")&&(_=!0),!_||(_=!1,g.includes("LEFT")&&P.includes("LEFT")&&(_=!0),g.includes("RIGHT")&&P.includes("RIGHT")&&(_=!0),!_))continue;if(R=m,F=y("IndexOffset="),c=y("IndexCount="),l=P,L.includes("<VertexIndices>")||(L=w()),!L.startsWith("<VertexIndices>")||!L.endsWith("</VertexIndices>"))return J.warn("Unable to find CIfTI <VertexIndices>"),U;L=L.slice(15,-16);const CA=L.trim().split(/\s+/);CA.length<c&&J.error("Error parsing VertexIndices"),S=new Uint32Array(c);for(let eA=0;eA<c;eA++)S[eA]=parseInt(CA[eA])}if(R===0||S.length===0)return J.warn("Unable to find CIfTI structure that matches the mesh."),U;if(r!==16)return J.warn("Only able to read float32 CIfTI (only known datatype)."),U;const Y=new Float32Array(c*k),K=t+k*F*4;for(let m=0;m<c*k;m++)Y[m]=i.getFloat32(K+m*4,E);let b=0;for(let m=0;m<c;m++)for(let P=0;P<k;P++)U[S[m]+P*A]=Y[b],b++;return J.debug("CIfTI diagnostics",R,l,F,c,F,g),U}if(n=this.decimateLayerVertices(n,A),n%A!==0)throw new Error("Vertices in layer ("+n+") is not a multiple of number of vertices ("+A+")");if(E)r===16?C=new Float32Array(I,t,n):r===8?C=new Int32Array(I,t,n):r===4&&(C=new Int16Array(I,t,n));else if(r===16){C=new Float32Array(n);for(let D=0;D<n;D++)C[D]=i.getFloat32(t+D*4,E)}else if(r===8){C=new Int32Array(n);for(let D=0;D<n;D++)C[D]=i.getInt32(t+D*4,E)}else if(r===4){C=new Int16Array(n);for(let D=0;D<n;D++)C[D]=i.getInt16(t+D*2,E)}return r===2&&(C=new Uint8Array(I,t,n)),C}static async readNII(I,A,g=""){const C=A.length/3;let Q=new Float32Array,E=!0,i=new DataView(I),o=i.getUint16(0,E);if(o===540||o===469893120)return dA.readNII2(I,C,g);if(o===23553&&(E=!1,o=i.getUint16(0,E)),o!==348){const l=await DA.decompress(new Uint8Array(I));if(i=new DataView(l.buffer),I=l.buffer,o=i.getUint16(0,E),o===540||o===469893120)return dA.readNII2(I,C,g);o===23553&&(E=!1,o=i.getUint16(0,E))}o!==348&&J.error("Not a valid NIfTI image.");const t=i.getFloat32(108,E),s=i.getFloat32(112,E),a=i.getFloat32(116,E),e=i.getUint16(252,E),r=i.getUint16(254,E),n=i.getUint16(70,E);if(n!==2&&n!==4&&n!==8&&n!==16)throw new Error("Unsupported NIfTI datatype "+n);const h=MA();for(let l=0;l<12;l++)h[l]=i.getFloat32(280+l*4,E);let D=1;const w=new Array(8);for(let l=0;l<8;l++)w[l]=i.getUint16(40+l*2,E),!(l<1)&&(D*=w[l]||1);let y=!1,F=this.decimateLayerVertices(D,C);if(F%C!==0)if(w[0]>=3&&w[1]>1&&w[2]>1&&w[3]>1)y=!0,F=w[1]*w[2]*w[3];else throw new Error("Voxels in layer ("+D+") is not a multiple of number of vertices ("+C+")");if(D=F,E)n===16?Q=new Float32Array(I,t,D):n===8?Q=new Int32Array(I,t,D):n===4&&(Q=new Int16Array(I,t,D));else if(n===16){Q=new Float32Array(D);for(let l=0;l<D;l++)Q[l]=i.getFloat32(t+l*4,E)}else if(n===8){Q=new Int32Array(D);for(let l=0;l<D;l++)Q[l]=i.getInt32(t+l*4,E)}else if(n===4){Q=new Int16Array(D);for(let l=0;l<D;l++)Q[l]=i.getInt16(t+l*2,E)}if(n===2&&(Q=new Uint8Array(I,t,D)),Number.isFinite(s)&&Number.isFinite(a)&&s!==0&&(s!==1||a!==0)){const l=new Float32Array(D);for(let S=0;S<D;S++)l[S]=Q[S]*s+a;Q=l}let c=Q[0],R=c;for(let l=0;l<D;l++)isNaN(Q[l])&&(Q[l]=0),c=Math.min(c,Q[l]),R=Math.max(R,Q[l]);if(J.debug(`Layer Range ${c}..${R} slope ${s} inter ${a}`),y){let l=function(P,_){const CA=[0,0,0];return CA[0]=_[0]*P[0]+_[1]*P[1]+_[2]*P[2]+_[3],CA[1]=_[4]*P[0]+_[5]*P[1]+_[6]*P[2]+_[7],CA[2]=_[8]*P[0]+_[9]*P[1]+_[10]*P[2]+_[11],CA};const S=new Float32Array(C);J.warn("Sampling voxel intensities at mesh vertices (assumes precise alignment)."),(e>r||r<=0)&&J.warn(`Requires valid sform (sform_code = ${r})`);const N=MA();nI(N,h);const d=w[1],L=w[2],k=w[3],U=d*L;let Y=0,K=0,b=0;for(;K<C;){const P=[A[Y],A[Y+1],A[Y+2]],_=l(P,N);Y+=3,K+=1;const CA=Math.floor(_[0]),eA=Math.floor(_[1]),yA=Math.floor(_[2]),nA=Math.ceil(_[0]),lA=Math.ceil(_[1]),AA=Math.ceil(_[2]);if(CA<0||nA>=d||eA<0||lA>=L||yA<0||AA>=k)continue;const oA=CA+eA*d+yA*U,O=new Float32Array(8);O[0]=Q[oA],O[1]=Q[oA+1],O[2]=Q[oA+d],O[3]=Q[oA+d+1],O[4]=Q[oA+U],O[5]=Q[oA+U+1],O[6]=Q[oA+U+d],O[7]=Q[oA+U+d+1];let FA=O[0],kA=FA;for(let SA=1;SA<8;SA++)FA=Math.max(FA,O[SA]),kA=Math.min(kA,O[SA]);Math.abs(kA)>FA&&(FA=kA),S[K-1]=FA,b++}const m=b/C;m<.1&&J.warn(`${b} of ${C} vertices in range (${(m*100).toFixed(1)}%)`),Q=S}return Q}static async readMGH(I,A=0,g=!1){let C=new DataView(I),Q=I;if(C.getUint8(0)===31&&C.getUint8(1)===139){const S=await DA.decompress(new Uint8Array(I));Q=new ArrayBuffer(S.byteLength),new Uint8Array(Q).set(new Uint8Array(S)),C=new DataView(S.buffer)}const E=C.getInt32(0,!1),i=Math.max(1,C.getInt32(4,!1)),o=Math.max(1,C.getInt32(8,!1)),t=Math.max(1,C.getInt32(12,!1)),s=Math.max(1,C.getInt32(16,!1)),a=C.getInt32(20,!1);let e=284;const r=!1;(E!==1||a<0||a>4)&&J.warn("Not a valid MGH file");let n=i*o*t*s,h=[];if(n=this.decimateLayerVertices(n,A),n%A!==0)return J.warn("Vertices in layer ("+n+") is not a multiple of number of vertices ("+A+")"),h;if(a===3){h=new Float32Array(n);for(let S=0;S<n;S++)h[S]=C.getFloat32(e+S*4,r)}else if(a===1){h=new Int32Array(n);for(let S=0;S<n;S++)h[S]=C.getInt32(e+S*4,r)}else if(a===4){h=new Int16Array(n);for(let S=0;S<n;S++)h[S]=C.getInt16(e+S*2,r)}else a===0&&(h=new Uint8Array(I,e,n));if(!g)return h;let D=4;a===4&&(D=2),a===0&&(D=1),e+=D*n,e+=4*4;const w=1,y=2,F=20,c=30,R=Q.byteLength;let l;for(;e<R-8;){const S=C.getInt32(e+=4,r);let N=0;switch(S){case c:N=C.getInt32(e+=4,r)-1;break;case F:case y:N=0;break;case w:N=0;{let d=C.getInt32(e+=4,r);if(d>0)return J.warn("unsupported CTABreadFromBinaryV1"),h;if(d=-d,d!==2)return J.warn("CTABreadFromBinary: unknown version"),h;const L=C.getInt32(e+=4,r);if(L<0)return J.warn("CTABreadFromBinaryV2: nentries was ",L),h;const k=C.getInt32(e+=4,r);e+=k;const U=C.getInt32(e+=4,r);if(U<0)return h;const Y={R:[],G:[],B:[],A:[],I:[],labels:[]};for(let K=0;K<U;K++){const b=C.getInt32(e+=4,r),m=C.getInt32(e+=4,r);let P=e+4,_="";for(let lA=0;lA<m;lA++){const AA=C.getUint8(P++);if(AA===0)break;_+=String.fromCharCode(AA)}e+=m;const CA=C.getInt32(e+=4,r),eA=C.getInt32(e+=4,r),yA=C.getInt32(e+=4,r),nA=255-C.getInt32(e+=4,r);Y.I.push(b),Y.R.push(CA),Y.G.push(eA),Y.B.push(yA),Y.A.push(nA),Y.labels.push(_)}l=pA.makeLabelLut(Y)}break;default:N=C.getInt32(e+=8,r)}e+=N}return{scalars:h,colormapLabel:l}}static readX3D(I){const A=I.byteLength;if(A<20)throw new Error("File too small to be X3D: bytes = "+A);const g=new Uint8Array(I);let C=0;function Q(){for(;C<A&&g[C]!==60;)C++;const F=C;for(;C<A&&g[C]!==62;)C++;const c=C;return new TextDecoder().decode(I.slice(F,c+1)).trim()}let E=Q();function i(F){const c=E.indexOf(F+"=");if(c<0)return"";const R=E[c+F.length+1],l=E.indexOf(R,c)+1,S=E.indexOf(R,l);return E.slice(l,S)}function o(F){const c=E.indexOf(F+"=");if(c<0)return 1;const R=E[c+F.length+1],l=E.indexOf(R,c)+1,S=E.indexOf(R,l);let N=E.slice(l,S).trim();N=N.replace(/,\s*$/,"");const d=N.trim().split(/\s*,\s*|\s+/);if(d.length<2)return parseFloat(N);let L=new Array(d.length),k=0;for(let U=0;U<d.length;U++){const Y=parseFloat(d[U]);isFinite(Y)&&(L[k]=Y,k++)}return L=L.slice(0,k),L}E.includes("xml version")||J.warn("Not a X3D image");let t=[],s=[],a=[],e=[],r=[0,0,0,0],n=[0,0,0,0],h=[255,255,255,255],D=[255,255,255,255];const w={};function y(){if(!E.endsWith("/>"))if(E.startsWith("<Appearance>"))for(;C<A&&!E.endsWith("</Appearance>");)E+=Q();else for(;C<A&&!E.endsWith("/>");)E+=Q();const F=i("USE");if(F.length>1){F in w?h=w[F]:J.warn("Unable to find DEF for "+F);return}const c=o("diffuseColor");if(c.length<3)return;h[0]=Math.round(c[0]*255),h[1]=Math.round(c[1]*255),h[2]=Math.round(c[2]*255);const R=i("DEF");R.length<1||(w[R]=h)}for(;C<A;)if(E=Q(),h=D.slice(),E.startsWith("<Transform")&&(r=o("translation"),n=o("rotation")),E.startsWith("<Appearance")&&(y(),D=h.slice()),E.startsWith("<Shape")){let F=1,c=1,R=[],l=[];for(;C<A&&(E=Q(),E.startsWith("<Appearance")&&y(),!E.startsWith("</Shape"));){if(E.startsWith("<Sphere")&&(F=o("radius"),c=-1),E.startsWith("<Cylinder")&&(F=o("radius"),c=o("height")),E.startsWith("<IndexedFaceSet")&&(c=-2,R=o("coordIndex")),E.startsWith("<IndexedTriangleSet")&&(c=-7,R=o("index")),E.startsWith("<IndexedTriangleStripSet")&&(c=-3,R=o("index")),E.startsWith("<Coordinate")){l=o("point");const S=l.length%3;S!==0&&(l=l.slice(0,-S))}E.startsWith("<Color")&&(e=o("color")),E.startsWith("<Box")&&(c=-4,J.warn("Unsupported x3d shape: Box")),E.startsWith("<Cone")&&(c=-5,J.warn("Unsupported x3d shape: Cone")),E.startsWith("<ElevationGrid")&&(c=-6,J.warn("Unsupported x3d shape: ElevationGrid"))}if(!(c<-3&&c!==-7))if(c<-1){if(R.length<1||l.length<3||l.length===void 0){J.warn("Indexed mesh must specify indices and points");break}const S=Math.floor(t.length/3);let N=2;if(c===-7)s=[...s,...R];else if(c===-2){let k=0;for(;N<R.length;)R[N]>=0?(s.push(R[k]+S),s.push(R[N-1]+S),s.push(R[N-0]+S),N+=1):(N+=3,k=N-2)}else for(;N<R.length;)R[N]>=0?(s.push(R[N-2]+S),s.push(R[N-1]+S),s.push(R[N-0]+S),N+=1):N+=3;t=[...t,...l];const d=Math.floor(l.length/3),L=Array(d).fill(h).flat();if(e.length===d*3){let k=0,U=0;for(let Y=0;Y<d;Y++){for(let K=0;K<3;K++)L[U]=Math.round(e[k]*255),k++,U++;U++}}a=[...a,...L]}else if(c<0)xI.makeColoredSphere(t,s,a,F,r,h);else{const S=MA();Ko(S,n[3],[n[0],n[1],n[2]]);const N=WA(0,-c*.5,0,1),d=WA(0,+c*.5,0,1);CI(N,N,S),CI(d,d,S),gE(N,N,r),gE(d,d,r);const L=BA(N[0],N[1],N[2]),k=BA(d[0],d[1],d[2]);xI.makeColoredCylinder(t,s,a,L,k,F,h)}}return{positions:Float32Array.from(t),indices:Uint32Array.from(s),rgba255:Uint8Array.from(a)}}static async readGII(I,A=0){let g=I.byteLength;if(g<20)throw new Error("File too small to be GII: bytes = "+g);let C=new TextDecoder("ascii").decode(I);if(C[0].charCodeAt(0)===31){const U=await DA.decompress(new Uint8Array(I));I=U.buffer,C=new TextDecoder("ascii").decode(U.buffer)}let Q=0;function E(){let U=!0,Y=Q;for(;U;){for(;Q<g&&C[Q]!=="<";)Q++;for(Y=Q;Q<g&&C[Q]!==">";)Q++;if(U=C[Q-1]==="/",Y+1<g&&C[Y+1]==="/"&&(Q+=1,U=!0),Q>=g)break}const K=new TextDecoder().decode(I.slice(Y+1,Q)).trim(),b=K.split(" ")[0].trim(),m=Q;let P=Q,_=Q;if(C[Y+1]!=="?"&&C[Y+1]!=="!"){const CA="</"+b+">";P=C.indexOf(CA,m),_=P+CA.length-1}return{name:K,startPos:Y,contentStartPos:m,contentEndPos:P,endPos:_}}let i=E();if(!i.name.startsWith("?xml"))throw new Error("readGII: Invalid XML file");for(;!i.name.startsWith("GIFTI")&&i.endPos<g;)i=E();if(!i.name.startsWith("GIFTI")||i.contentStartPos===i.contentEndPos)throw new Error("readGII: XML file does not include GIFTI tag");g=i.contentEndPos;let o=new Float32Array,t=new Uint32Array,s=new Float32Array,a="",e=!1,r=!1,n=!1,h=!1,D=[1,1,1];const w=[0,0,0];let y=0,F=!1,c=!1,R=0,l=!1;i.endPos=i.contentStartPos;let S="";function N(U,Y=!1){const K=S.indexOf(U);if(K<0)return 1;const b=S.indexOf('"',K)+1,m=S.indexOf('"',b),P=S.slice(b,m);return Y?parseFloat(P):parseInt(P)}function d(U){const Y=S.indexOf(U);if(Y<0)return"";const K=Y+U.length,b=S.indexOf("]",K);return S.slice(K,b)}const L={R:[],G:[],B:[],A:[],I:[],labels:[]};for(;i.endPos<g&&i.name.length>1;){if(i=E(),i.name.startsWith("Label Key")&&(S=i.name,L.I.push(N("Key=")),L.R.push(Math.round(255*N("Red=",!0))),L.G.push(Math.round(255*N("Green=",!0))),L.B.push(Math.round(255*N("Blue=",!0))),L.A.push(Math.round(255*N("Alpha",!0))),S=new TextDecoder().decode(I.slice(i.contentStartPos+1,i.contentEndPos)).trim(),L.labels.push(d("<![CDATA["))),i.name.trim()==="Data"){if(n)continue;S=new TextDecoder().decode(I.slice(i.contentStartPos+1,i.contentEndPos)).trim();let U;if(c){const Y=D[0]*D[1]*D[2],K=S.split(/\s+/);if(Y!==K.length)throw new Error("Unable to parse ASCII GIfTI");if(y===2&&(y=8),y===32&&(y=16),y===8){U=new Int32Array(Y);for(let b=0;b<Y;b++)U[b]=parseInt(K[b])}if(y===16){U=new Float32Array(Y);for(let b=0;b<Y;b++)U[b]=parseFloat(K[b])}}else if(typeof Buffer>"u"){let Y=function(K){const b=atob(K),m=b.length,P=new Uint8Array(m);for(let _=0;_<m;_++)P[_]=b.charCodeAt(_);return P};if(F){const K=Y(S.slice());U=await DA.decompress(new Uint8Array(K))}else U=Y(S.slice())}else if(F){const Y=Buffer.from(S.slice(),"base64");U=await DA.decompress(new Uint8Array(Y))}else U=Buffer.from(S.slice(),"base64");if(r){if(y!==16&&J.warn("expect positions as FLOAT32"),o=new Float32Array(U.buffer),h){const Y=o.slice(),K=Y.length/3;let b=0;for(let m=0;m<K;m++)for(let P=0;P<3;P++)o[b]=Y[P*K+m],b++}}else if(e){if(y!==8&&J.warn("expect indices as INT32"),t=new Uint32Array(U.buffer),h){const Y=t.slice(),K=Y.length/3;let b=0;for(let m=0;m<K;m++)for(let P=0;P<3;P++)t[b]=Y[P*K+m],b++}}else{let Y=function(b,m){const P=b.length,_=new Float32Array(P+m.length);return _.set(b),_.set(m,P),_};R=D[0]*D[1]*D[2],A!==0&&R%A!==0&&J.warn("Number of vertices in scalar overlay ("+R+") does not match mesh ("+A+")");let K;if(y===2){const b=new Uint8Array(U.buffer);K=Float32Array.from(b)}else if(y===8){const b=new Int32Array(U.buffer);K=Float32Array.from(b)}else if(y===16)K=new Float32Array(U.buffer);else if(y===32){const b=new Float64Array(U.buffer);K=Float32Array.from(b)}else throw new Error(`Invalid dataType: ${y}`);s=Y(s,K)}continue}if(i.name.trim()==="DataSpace"&&(S=new TextDecoder().decode(I.slice(i.contentStartPos+1,i.contentEndPos)).trim(),S.includes("NIFTI_XFORM_SCANNER_ANAT")&&(l=!0)),i.name.trim()==="MD"&&(S=new TextDecoder().decode(I.slice(i.contentStartPos+1,i.contentEndPos)).trim(),S.includes("AnatomicalStructurePrimary")&&S.includes("CDATA[")&&(a=d("<Value><![CDATA[").toUpperCase()),S.includes("VolGeom")&&S.includes("CDATA["))){let U=-1;if(S.includes("VolGeomC_R")&&(U=0),S.includes("VolGeomC_A")&&(U=1),S.includes("VolGeomC_S")&&(U=2),U<0)continue;w[U]=parseFloat(d("<Value><![CDATA["))}i.name.startsWith("DataArray")&&(S=i.name,D=[1,1,1],F=S.includes('Encoding="GZipBase64Binary"'),c=S.includes('Encoding="ASCII"'),e=S.includes('Intent="NIFTI_INTENT_TRIANGLE"'),r=S.includes('Intent="NIFTI_INTENT_POINTSET"'),n=S.includes('Intent="NIFTI_INTENT_VECTOR"'),h=S.includes('ArrayIndexingOrder="ColumnMajorOrder"'),S.includes('DataType="NIFTI_TYPE_UINT8"')&&(y=2),S.includes('DataType="NIFTI_TYPE_INT32"')&&(y=8),S.includes('DataType="NIFTI_TYPE_FLOAT32"')&&(y=16),S.includes('DataType="NIFTI_TYPE_FLOAT64"')&&(y=32),D[0]=N("Dim0="),D[1]=N("Dim1="),D[2]=N("Dim2="))}let k;if(L.I.length>1&&(L.A.some(Y=>Y>0)||L.A.fill(255),k=pA.makeLabelLut(L)),A>0)return{scalars:s,colormapLabel:k,anatomicalStructurePrimary:a};if(o.length>2&&!l&&(w[0]!==0||w[1]!==0||w[2]!==0)){R=Math.floor(o.length/3);let U=0;for(let Y=0;Y<R;Y++)o[U]+=w[0],U++,o[U]+=w[1],U++,o[U]+=w[2],U++}return{positions:o,indices:t,scalars:s,colormapLabel:k,anatomicalStructurePrimary:a}}}var tg=(B=>(B.LEFT="left",B.RIGHT="right",B.CENTER="center",B))(tg||{}),Sg=(B=>(B.NONE="none",B.CIRCLE="circle",B.RING="ring",B))(Sg||{}),wI=(B=>(B[B.NONE=0]="NONE",B[B.LEFT=1]="LEFT",B[B.CENTER=2]="CENTER",B[B.RIGHT=4]="RIGHT",B[B.TOP=8]="TOP",B[B.MIDDLE=16]="MIDDLE",B[B.BOTTOM=32]="BOTTOM",B))(wI||{}),IB=(B=>(B[B.NONE=0]="NONE",B[B.TOPLEFT=9]="TOPLEFT",B[B.TOPCENTER=10]="TOPCENTER",B[B.TOPRIGHT=12]="TOPRIGHT",B[B.MIDDLELEFT=17]="MIDDLELEFT",B[B.MIDDLECENTER=18]="MIDDLECENTER",B[B.MIDDLERIGHT=20]="MIDDLERIGHT",B[B.BOTTOMLEFT=33]="BOTTOMLEFT",B[B.BOTTOMCENTER=34]="BOTTOMCENTER",B[B.BOTTOMRIGHT=36]="BOTTOMRIGHT",B))(IB||{});class At{constructor(I=[1,1,1,1],A=1,g="left",C=0,Q=[0,0,0],E="none",i,o,t){G(this,"textColor");G(this,"textScale");G(this,"textAlignment");G(this,"lineWidth");G(this,"lineColor");G(this,"lineTerminator");G(this,"bulletScale");G(this,"bulletColor");G(this,"backgroundColor");this.textColor=I,this.textScale=A,this.textAlignment=g,this.lineWidth=C,this.lineColor=Q,this.lineTerminator=E,this.bulletScale=i,this.bulletColor=o,this.backgroundColor=t}}class ZB{constructor(I,A,g,C,Q){G(this,"text");G(this,"style");G(this,"points");G(this,"anchor");G(this,"onClick");this.text=I,this.style=A,this.points=g,this.anchor=C||0,this.onClick=Q}}var sg=(B=>(B.MESH="mesh",B.CONNECTOME="connectome",B.FIBER="fiber",B))(sg||{});const QE={colormap:"gray",opacity:0,nFrame4D:0,frame4D:0,outlineBorder:0,cal_min:0,cal_max:0,cal_minNeg:0,cal_maxNeg:0,colormapType:JI.MIN_TO_MAX,values:new Array,useNegativeCmap:!1,showLegend:!0};class It{constructor(I="",A=null,g="",C=1,Q=new Uint8Array([255,255,255,255]),E=!0,i=[],o=!0,t=0){G(this,"url");G(this,"gl");G(this,"name");G(this,"opacity");G(this,"rgba255");G(this,"visible");G(this,"layers");G(this,"colorbarVisible");G(this,"meshShaderIndex");this.url=I,this.gl=A,this.name=g,this.opacity=C,this.rgba255=Q,this.visible=E,this.layers=i,this.colorbarVisible=o,this.meshShaderIndex=t}}class QI{constructor(I,A,g="",C=new Uint8Array([255,255,255,255]),Q=1,E=!0,i,o=null,t=null,s=null,a=null,e=null,r=!0,n=""){G(this,"id");G(this,"name");G(this,"anatomicalStructurePrimary");G(this,"colorbarVisible");G(this,"furthestVertexFromOrigin");G(this,"extentsMin");G(this,"extentsMax");G(this,"opacity");G(this,"visible");G(this,"meshShaderIndex",0);G(this,"offsetPt0",null);G(this,"colormapInvert",!1);G(this,"fiberGroupColormap",null);G(this,"indexBuffer");G(this,"vertexBuffer");G(this,"vao");G(this,"vaoFiber");G(this,"pts");G(this,"tris");G(this,"layers");G(this,"type","mesh");G(this,"data_type");G(this,"rgba255");G(this,"fiberLength");G(this,"fiberLengths");G(this,"fiberDensity");G(this,"fiberDither",.1);G(this,"fiberColor","Global");G(this,"fiberDecimationStride",1);G(this,"fiberSides",5);G(this,"fiberRadius",0);G(this,"fiberOcclusion",0);G(this,"f32PerVertex",5);G(this,"dpsThreshold",NaN);G(this,"fiberMask");G(this,"colormap");G(this,"dpg");G(this,"dps");G(this,"dpv");G(this,"groups");G(this,"hasConnectome",!1);G(this,"connectome");G(this,"indexCount");G(this,"vertexCount",1);G(this,"nodeScale",4);G(this,"edgeScale",1);G(this,"legendLineThickness",0);G(this,"showLegend",!0);G(this,"nodeColormap","warm");G(this,"edgeColormap","warm");G(this,"nodeColormapNegative");G(this,"edgeColormapNegative");G(this,"nodeMinColor");G(this,"nodeMaxColor");G(this,"edgeMin");G(this,"edgeMax");G(this,"nodes");G(this,"edges");G(this,"points");this.anatomicalStructurePrimary=n,this.name=g,this.colorbarVisible=r,this.id=VB();const h=jI.getExtents(I);if(this.furthestVertexFromOrigin=h.mxDx,this.extentsMin=h.extentsMin,this.extentsMax=h.extentsMax,this.opacity=Q>1?1:Q,this.visible=E,this.meshShaderIndex=0,this.indexBuffer=i.createBuffer(),this.vertexBuffer=i.createBuffer(),this.vao=i.createVertexArray(),i.bindVertexArray(this.vao),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,this.indexBuffer),i.bindBuffer(i.ARRAY_BUFFER,this.vertexBuffer),i.enableVertexAttribArray(0),i.enableVertexAttribArray(1),this.f32PerVertex!==7?(i.vertexAttribPointer(0,3,i.FLOAT,!1,20,0),i.vertexAttribPointer(1,4,i.BYTE,!0,20,12),i.enableVertexAttribArray(2),i.vertexAttribPointer(2,4,i.UNSIGNED_BYTE,!0,20,16)):(i.vertexAttribPointer(0,3,i.FLOAT,!1,28,0),i.vertexAttribPointer(1,3,i.FLOAT,!1,28,12),i.enableVertexAttribArray(2),i.vertexAttribPointer(2,4,i.UNSIGNED_BYTE,!0,28,24)),i.bindVertexArray(null),this.vaoFiber=i.createVertexArray(),this.offsetPt0=null,this.hasConnectome=!1,this.colormapInvert=!1,this.fiberGroupColormap=null,this.pts=I,this.layers=[],this.type="mesh",this.tris=A,C[3]<1){this.rgba255=C,this.fiberLength=2,this.fiberDither=.1,this.fiberColor="Global",this.fiberDecimationStride=1,this.fiberMask=[],this.colormap=o,this.dpg=t,this.dps=s,this.dpv=a,this.groups=e,t&&this.initValuesArray(t),s&&this.initValuesArray(s),a&&this.initValuesArray(a),e&&this.initValuesArray(e),this.offsetPt0=new Uint32Array(A),this.tris=new Uint32Array(0),this.updateFibers(i),i.bindVertexArray(this.vaoFiber),i.bindBuffer(i.ELEMENT_ARRAY_BUFFER,this.indexBuffer),i.bindBuffer(i.ARRAY_BUFFER,this.vertexBuffer),i.enableVertexAttribArray(0),i.vertexAttribPointer(0,3,i.FLOAT,!1,16,0),i.enableVertexAttribArray(1),i.vertexAttribPointer(1,4,i.UNSIGNED_BYTE,!0,16,12),i.bindVertexArray(null);return}if(o){this.connectome=o,this.hasConnectome=!0;const w=Object.keys(o);for(let y=0,F=w.length;y<F;y++)this[w[y]]=o[w[y]]}this.rgba255=C,this.updateMesh(i)}initValuesArray(I){for(let A=0;A<I.length;A++){const g=I[A].vals.reduce((Q,E)=>Math.min(Q,E)),C=I[A].vals.reduce((Q,E)=>Math.max(Q,E));I[A].global_min=g,I[A].global_max=C,I[A].cal_min=g,I[A].cal_max=C}return I}linesToCylinders(I,A,g){function C(d){return BA(d[0],d[1],d[2])}const Q=Math.pow(2,32)-1,E=g.length;let i=0,o=0;for(let d=0;d<E;d++){if(g[d]===Q){o++;continue}i++}const t=this.fiberSides,s=t*i,a=this.f32PerVertex;if(a!==5)throw Error("fiberSides > 1 requires f32PerVertex == 5");const e=new Float32Array(s*a),r=new Uint8Array(e.buffer);let n=0,h=pI(),D=pI(),w=pI();const y=TA();let F=TA(),c=0;const R=this.fiberRadius;for(let d=0;d<E;d++){const L=g[d]===Q;if(L&&c<1)continue;let k=g[d]*4;if(c++,c<=1){h=WA(A[k+0],A[k+1],A[k+2],A[k+3]),D=qI(h),d+1<E&&g[d+1]!==Q&&(k=g[d+1]*4,w=WA(A[k+0],A[k+1],A[k+2],A[k+3]),bA(y,C(h),C(w)),RI(y,y),F=xI.getFirstPerpVector(y));continue}L?w=qI(D):w=WA(A[k+0],A[k+1],A[k+2],A[k+3]),bA(y,C(h),C(w)),RI(y,y);const U=TA();WB(U,F,y);const Y=TA();WB(Y,y,U),F=UI(F);const K=TA();WB(K,y,Y),RI(K,K);const b=TA();for(let m=0;m<t;m++){const P=Math.cos(m/t*2*Math.PI),_=Math.sin(m/t*2*Math.PI);b[0]=R*(P*Y[0]+_*K[0]),b[1]=R*(P*Y[1]+_*K[1]),b[2]=R*(P*Y[2]+_*K[2]),ig(b,C(D),b);const CA=n*a;e[CA+0]=b[0],e[CA+1]=b[1],e[CA+2]=b[2];const eA=TA();bA(eA,b,C(D)),RI(eA,eA);const yA=(CA+3)*4;r[yA+0]=eA[0]*127,r[yA+1]=eA[1]*127,r[yA+2]=eA[2]*127,e[CA+4]=D[3],n++}h=qI(D),D=qI(w),L&&(c=0)}const l=(i-o)*t*2*3,S=new Uint32Array(l);let N=0;n=0;for(let d=1;d<E;d++){if(g[d]===Q){n+=t;continue}if(g[d-1]===Q)continue;let L=n,k=n+t;const U=k,Y=k+t;for(let K=0;K<t;K++)S[N++]=L,S[N++]=k++,k===Y&&(k=Y-t),S[N++]=k,S[N++]=L++,L===U&&(L=U-t),S[N++]=k,S[N++]=L;n+=t}I.bindBuffer(I.ELEMENT_ARRAY_BUFFER,this.indexBuffer),I.bufferData(I.ELEMENT_ARRAY_BUFFER,Uint32Array.from(S),I.STATIC_DRAW),I.bindBuffer(I.ARRAY_BUFFER,this.vertexBuffer),I.bufferData(I.ARRAY_BUFFER,r,I.STATIC_DRAW),this.indexCount=l}createFiberDensityMap(){if(this.fiberDensity)return;const I=this.pts,A=I.length/3;let g=0;for(let y=0;y<3;y++){const F=this.extentsMax[y]-this.extentsMin[y];g=Math.max(g,F)}if(this.fiberDensity=new Float32Array(A),g===0)return;const C=64,E=g/(C-1)/2,i=(C-1)/g;let o=new Float32Array(C*C*C);const t=[this.extentsMin[0]-E,this.extentsMin[1]-E,this.extentsMin[2]-E],s=[0,0,0],a=-1,e=C*C;let r=0;for(let y=0;y<A;y++){s[0]=Math.round((I[r++]-t[0])*i),s[1]=Math.round((I[r++]-t[1])*i),s[2]=Math.round((I[r++]-t[2])*i);const F=s[0]+s[1]*C+s[2]*e;F!==a&&o[F]++}function n(y,F){let c=y.slice(),R=-1;const l=F-1;for(let N=0;N<F;N++)for(let d=0;d<F;d++)for(let L=0;L<F;L++)R++,!(L<1||L>=l)&&(y[R]=c[R-1]+c[R]+c[R]+c[R+1]);R=-1,c=y.slice();for(let N=0;N<F;N++)for(let d=0;d<F;d++)for(let L=0;L<F;L++)R++,!(d<1||d>=l)&&(y[R]=c[R-F]+c[R]+c[R]+c[R+F]);const S=F*F;R=-1,c=y.slice();for(let N=0;N<F;N++)for(let d=0;d<F;d++)for(let L=0;L<F;L++)R++,!(N<1||N>=l)&&(y[R]=c[R-S]+c[R]+c[R]+c[S]);return y}o=n(o,C),o=n(o,C);let h=0,D=1/0;const w=C*C*C;for(let y=0;y<w;y++)o[y]<=0||(h=Math.max(h,o[y]),D=Math.min(D,o[y]));if(!(h<=1||h<=D)){r=0;for(let y=0;y<w;y++)o[y]=Math.max(0,o[y]-D);h-=D;for(let y=0;y<A;y++){s[0]=Math.round((I[r++]-t[0])*i),s[1]=Math.round((I[r++]-t[1])*i),s[2]=Math.round((I[r++]-t[2])*i);const F=s[0]+s[1]*C+s[2]*e;this.fiberDensity[y]=o[F]/h}}}updateFibers(I){if(!this.offsetPt0||!this.fiberLength)return;const A=this.pts,g=this.offsetPt0,C=g.length-1,Q=A.length/3;if(!this.fiberLengths){this.fiberLengths=new Uint32Array(C);for(let l=0;l<C;l++){const S=g[l]*3,N=(g[l+1]-1)*3;let d=0;for(let L=S;L<N;L+=3){const k=BA(A[L+0]-A[L+3],A[L+1]-A[L+4],A[L+2]-A[L+5]);d+=$g(k)}this.fiberLengths[l]=d}}const E=new Float32Array(Q*4),i=new Uint32Array(E.buffer);let o=0,t=0;for(let l=0;l<Q;l++)E[t+0]=A[o+0],E[t+1]=A[o+1],E[t+2]=A[o+2],o+=3,t+=4;const s=this.fiberDither,a=s*.5;function e(l,S,N){const L=255*(s*Math.random()-a);return l=Math.max(Math.min(l+L,255),0),S=Math.max(Math.min(S+L,255),0),N=Math.max(Math.min(N+L,255),0),l+(S<<8)+(N<<16)}function r(l,S,N,d,L,k,U){const Y=BA(Math.abs(l-d),Math.abs(S-L),Math.abs(N-k));RI(Y,Y);const K=U-a;for(let b=0;b<3;b++)Y[b]=255*Math.max(Math.min(Math.abs(Y[b])+K,1),0);return Y[0]+(Y[1]<<8)+(Y[2]<<16)}const n=this.fiberColor.toLowerCase();let h=null,D=null;if(n.startsWith("dps")&&this.dps&&this.dps.length>0){const l=parseInt(n.substring(3));l<this.dps.length&&this.dps[l].vals.length===C&&(h=this.dps[l].vals)}if(n.startsWith("dpv")&&this.dpv&&this.dpv.length>0){const l=parseInt(n.substring(3));l<this.dpv.length&&this.dpv[l].vals.length===Q&&(D=this.dpv[l])}const w=new Int16Array(C);if(this.groups&&this.fiberGroupColormap!==null||n.startsWith("dpg")&&this.dpg.length>0){const l=new Uint8ClampedArray(this.groups.length*4),S=new Array(this.groups.length).fill(!1);if(this.fiberGroupColormap){const N=this.fiberGroupColormap;N.A===void 0&&(N.A=Array.from(new Uint8ClampedArray(N.I.length).fill(255)));for(let d=0;d<N.I.length;d++){let L=N.I[d];L<0||L>=this.groups.length||N.A[d]<1||(S[L]=!0,L*=4,l[L]=N.R[d],l[L+1]=N.G[d],l[L+2]=N.B[d],l[L+3]=255)}}else if(n.startsWith("dpg")&&this.dpg.length>0){const N=parseInt(n.substring(3)),d=N<this.dpg.length?this.dpg[N]:this.dpg[0],L=pA.colormap(this.colormap,this.colormapInvert),k=d.cal_min,U=d.cal_max,Y=this.groups.length;for(let K=0;K<Y;K++){const b=d.vals[K];if(b<k)continue;let m=Math.round(255*Math.min(Math.max((b-k)/(U-k),0),1));S[K]=!0;const P=K*4;m*=4,l[P]=L[m+0],l[P+1]=L[m+1],l[P+2]=L[m+2],l[P+3]=255}}w.fill(-1);for(let N=0;N<this.groups.length;N++){if(!S[N])continue;const d=this.groups[N];for(let L=0;L<d.vals.length;L++)w[d.vals[L]]=N}for(let N=0;N<C;N++){if(w[N]<0)continue;const d=w[N]%256*4,L=e(l[d],l[d+1],l[d+2]),k=g[N],U=g[N+1]-1,Y=k*4+3,K=U*4+3;for(let b=Y;b<=K;b+=4)i[b]=L}}else if(D){const l=pA.colormap(this.colormap,this.colormapInvert),S=D.cal_min,N=D.cal_max;let d=3;for(let L=0;L<Q;L++){let k=Math.min(Math.max((D.vals[L]-S)/(N-S),0),1);k=Math.round(Math.max(Math.min(255,k*255)))*4;const U=l[k]+(l[k+1]<<8)+(l[k+2]<<16);i[d]=U,d+=4}}else if(h){const l=pA.colormap(this.colormap,this.colormapInvert);let S=h[0],N=h[0];for(let d=0;d<C;d++)S=Math.min(S,h[d]),N=Math.max(N,h[d]);N===S&&(S-=1);for(let d=0;d<C;d++){let L=(h[d]-S)/(N-S);L=Math.round(Math.max(Math.min(255,L*255)))*4;const k=l[L]+(l[L+1]<<8)+(l[L+2]<<16),U=g[d],Y=g[d+1]-1,K=U*4+3,b=Y*4+3;for(let m=K;m<=b;m+=4)i[m]=k}}else if(n.includes("fixed"))if(s===0){const l=this.rgba255[0]+(this.rgba255[1]<<8)+(this.rgba255[2]<<16);let S=3;for(let N=0;N<Q;N++)i[S]=l,S+=4}else for(let l=0;l<C;l++){const S=e(this.rgba255[0],this.rgba255[1],this.rgba255[2]),N=g[l],d=g[l+1]-1,L=N*4+3,k=d*4+3;for(let U=L;U<=k;U+=4)i[U]=S}else if(n.includes("local"))for(let l=0;l<C;l++){const S=g[l],N=g[l+1]-1;let d=S*3;const L=N*3,k=s*Math.random();let U=r(A[d],A[d+1],A[d+2],A[d+4],A[d+5],A[d+6],k),Y=S*4+3;for(;d<L;)i[Y]=U,Y+=4,d+=3,U=r(A[d-3],A[d-2],A[d-1],A[d+3],A[d+4],A[d+5],k);i[Y]=i[Y-4]}else for(let l=0;l<C;l++){const S=g[l],N=g[l+1]-1,d=S*3,L=N*3,k=r(A[d],A[d+1],A[d+2],A[L],A[L+1],A[L+2],s*Math.random()),U=S*4+3,Y=N*4+3;for(let K=U;K<=Y;K+=4)i[K]=k}if(this.fiberOcclusion>0){let l=function(S,N){const d=N*(S&255),L=N*(S>>8&255),k=N*(S>>16&255);return d+(L<<8)+(k<<16)};this.createFiberDensityMap();for(let S=0;S<C;S++){const N=g[S],d=g[S+1]-1,L=N*4+3,k=d*4+3;let U=N;const Y=Math.min(this.fiberOcclusion,.99);for(let K=L;K<=k;K+=4){let b=this.fiberDensity[U++];if(b<=0)continue;b=b/((1/Y-2)*(1-b)+1);const m=1-Math.min(b,.9);let P=i[K];P=l(P,m),i[K]=P}}}if(Number.isFinite(this.dpsThreshold)&&this.dps&&(h||this.dps[0].vals.length===C&&(h=this.dps[0].vals),h))for(let l=0;l<C;l++)h[l]<this.dpsThreshold&&(w[l]=-1);const y=this.fiberLength,F=Math.pow(2,32)-1,c=[];let R=-1;for(let l=0;l<C;l++)if(!(w[l]<0)&&!(this.fiberLengths[l]<y)&&(R++,R%this.fiberDecimationStride===0)){for(let S=g[l];S<g[l+1];S++)c.push(S);c.push(F)}this.fiberSides>2&&this.fiberRadius>0?this.linesToCylinders(I,E,c):(this.indexCount=c.length,I.bindBuffer(I.ARRAY_BUFFER,this.vertexBuffer),I.bufferData(I.ARRAY_BUFFER,Uint32Array.from(i),I.STATIC_DRAW),I.bindBuffer(I.ELEMENT_ARRAY_BUFFER,this.indexBuffer),I.bufferData(I.ELEMENT_ARRAY_BUFFER,Uint32Array.from(c),I.STATIC_DRAW))}indexNearestXYZmm(I,A,g){const C=this.pts,Q=this.pts.length/3;let E=0,i=1/0,o=0;for(let t=0;t<Q;t++){const s=Math.pow(C[E]-I,2)+Math.pow(C[E+1]-A,2)+Math.pow(C[E+2]-g,2);s<i&&(i=s,o=t),E+=3}return i=Math.sqrt(i),[o,i]}unloadMesh(I){if(I.bindBuffer(I.ARRAY_BUFFER,null),I.bindBuffer(I.ELEMENT_ARRAY_BUFFER,null),I.bindVertexArray(null),I.deleteBuffer(this.vertexBuffer),I.deleteBuffer(this.indexBuffer),I.deleteVertexArray(this.vao),I.deleteVertexArray(this.vaoFiber),this.offsetPt0=null,this.tris=null,this.pts=null,this.layers&&this.layers.length>0)for(let A=0;A<this.layers.length;A++)this.layers[A].values=null;if(this.dpg&&this.dpg.length>0)for(let A=0;A<this.dpg.length;A++)this.dpg[A].vals=null;if(this.dps&&this.dps.length>0)for(let A=0;A<this.dps.length;A++)this.dps[A].vals=null}scalars2RGBA(I,A,g,C=!1){const Q=g.length;if(4*Q<I.length)return J.error(`colormap2RGBA incorrectly specified ${Q}*4 != ${I.length}`),I;const E=Math.round(A.opacity*255);let i=A.cal_min,o=A.cal_max,t=pA.colormap(A.colormap,this.colormapInvert),s=1;if(C){if(!A.useNegativeCmap)return I;s=-1,t=pA.colormap(A.colormapNegative,A.colormapInvert),i=A.cal_min,o=A.cal_max,isFinite(A.cal_minNeg)&&isFinite(A.cal_minNeg)&&(i=-A.cal_minNeg,o=-A.cal_maxNeg)}let a=i;A.isTransparentBelowCalMin||(a=Number.NEGATIVE_INFINITY);const e=A.colormapType===JI.ZERO_TO_MAX_TRANSLUCENT_BELOW_MIN;A.colormapType!==JI.MIN_TO_MAX&&(i=Math.min(i,0));const r=255/(o-i);for(let n=0;n<Q;n++){let h=g[n]*s;if(isNaN(h))continue;let D=E;if(h<a)if(h>0&&e)D=Math.round(A.opacity*255*Math.pow(h/a,2));else continue;if(h=(h-i)*r,h<0&&A.isTransparentBelowCalMin)continue;h=Math.min(255,Math.max(0,Math.round(h)))*4;const w=n*4;I[w+0]=t[h+0],I[w+1]=t[h+1],I[w+2]=t[h+2],I[w+3]=D}return I}blendColormap(I,A,g,C,Q,E,i=!1){const o=this.pts.length/3,t=Math.min(g.opacity,1);function s(F,c,R){return F*(1-R)+c*R}function a(F,c){return Math.min(F+c,255)}const e=i?-1:1,r=Math.min(Math.max(g.frame4D,0),g.nFrame4D-1),n=o*r;let h=C;g.isTransparentBelowCalMin||(h=Number.NEGATIVE_INFINITY),g.colormapType!==JI.MIN_TO_MAX&&(C=Math.min(C,0));const D=255/(Q-C);let w=new Array(o).fill(!1);if(g.outlineBorder!==0){const F=new Uint8Array(o).fill(0);for(let c=0;c<o;c++)e*g.values[c+n]>=h&&(F[c]=1);w=jI.getClusterBoundaryU8(F,this.tris);for(let c=0;c<o;c++)e*g.values[c+n]<h&&(w[c]=!1)}const y=new Float32Array(256).fill(t);if(h>C&&g.colormapType===JI.ZERO_TO_MAX_TRANSLUCENT_BELOW_MIN){let F=Math.round((h-C)*D);F=Math.max(F,1);for(let c=1;c<F;c++)y[c]=t*Math.pow(c/F,2);y[0]=0,h=C+Number.EPSILON}for(let F=0;F<o;F++){const c=e*g.values[F+n];if(c<h)continue;let R=Math.round((c-C)*D);if(R<0&&g.isTransparentBelowCalMin)continue;R=Math.max(0,R),R=Math.min(255,R);let l=y[R];R*=4;let S=F*28+24;if(this.f32PerVertex!==7&&(S=F*20+16),g.isAdditiveBlend){const N=F*4;A[N+0]=a(A[N+0],E[R+0]),A[N+1]=a(A[N+1],E[R+1]),A[N+2]=a(A[N+2],E[R+2]),A[N+3]=a(A[N+3],255)}else{if(w[F]&&(l=g.outlineBorder,g.outlineBorder<0)){I[S+0]=0,I[S+1]=0,I[S+2]=0;continue}I[S+0]=s(I[S+0],E[R+0],l),I[S+1]=s(I[S+1],E[R+1],l),I[S+2]=s(I[S+2],E[R+2],l)}}}updateMesh(I){if(this.offsetPt0){this.updateFibers(I);return}if(this.hasConnectome)return;if(!this.pts||!this.tris||!this.rgba255){J.warn("underspecified mesh");return}function A(t,s,a){return t*(1-a)+s*a}const g=this.generatePosNormClr(this.pts,this.tris,this.rgba255),C=this.pts.length/3,Q=new Uint8Array(g.buffer);let E=0;const i=new Uint8Array(C*4);let o=this.tris;if(this.layers&&this.layers.length>0)for(let t=0;t<this.layers.length;t++){const s=this.layers[t],a=s.opacity;if(a<=0||s.cal_min>s.cal_max)continue;if(s.outlineBorder===void 0&&(s.outlineBorder=0),s.isAdditiveBlend===void 0&&(s.isAdditiveBlend=!1),s.colormapLabel&&s.colormapLabel.R&&!s.colormapLabel.lut&&(s.colormapLabel=pA.makeLabelLut(s.colormapLabel,255,s.global_max)),s.colormapLabel&&s.colormapLabel.lut){const r=s.colormapLabel;let n=0;s.colormapLabel.min&&(n=s.colormapLabel.min);let h=r.lut;const D=Math.floor(h.length/4);if(s.atlasValues&&D>0&&D===s.atlasValues.length&&s.colormap){const l=s.atlasValues;let S=!1,N=!0;for(let d=0;d<D;d++)isNaN(l[d])?S=!0:N=!1;if(N){J.debug("invisible mesh: all atlasValues are NaN.");return}if(S){J.debug("some vertices have NaN atlasValues (mesh will be decimated).");const d=new Array(C).fill(!1);for(let K=0;K<C;K++){const b=Math.round(s.values[K])-n;isNaN(l[b])&&(d[K]=!0)}const L=new Array(o.length).fill(!1);for(let K=0;K<o.length;K++)d[o[K]]&&(L[K]=!0);const k=this.tris;let U=0;for(let K=0;K<k.length;K+=3)!L[K]&&!L[K+1]&&!L[K+2]&&U++;U===0&&J.debug("invisible mesh: all triangles of a vertex with a NaN atlasValue."),o=new Uint32Array(U*3);let Y=0;for(let K=0;K<k.length;K+=3)!L[K]&&!L[K+1]&&!L[K+2]&&(o[Y++]=k[K],o[Y++]=k[K+1],o[Y++]=k[K+2])}h.fill(0),h=this.scalars2RGBA(h,s,l),s.useNegativeCmap&&(h=this.scalars2RGBA(h,s,l,!0))}else s.atlasValues&&J.warn(`Expected ${D} atlasValues but got ${s.atlasValues.length} for mesh layer`);if(s.showLegend&&D===s.colormapLabel.labels.length){s.labels=[];for(let l=0;l<D;l++){const S=Array.from(h.slice(l*4,l*4+4)).map(U=>U/255),N=s.colormapLabel.labels[l],d=[0,0,0];let L=0;for(let U=0;U<C;U++)if(s.values[U]===l){const Y=U*3;d[0]+=this.pts[Y],d[1]+=this.pts[Y+1],d[2]+=this.pts[Y+2],L++}if(L>0&&(d[0]/=L,d[1]/=L,d[2]/=L),S[3]===0||!N||N.startsWith("_"))continue;S[3]=1;const k=new ZB(N,{textColor:S,bulletScale:1,bulletColor:S,lineWidth:0,lineColor:S,textScale:1,textAlignment:tg.LEFT,lineTerminator:Sg.NONE},d);s.labels.push(k),J.debug("label for mesh layer:",k)}}else delete s.labels;const w=Math.min(Math.max(s.frame4D,0),s.nFrame4D-1),y=C*w,F=new Uint8Array(C*4);let c=0;for(let l=0;l<C;l++){const S=s.values[l+y]-n,N=4*Math.min(Math.max(S,0),D-1);F[c+0]=h[N+0],F[c+1]=h[N+1],F[c+2]=h[N+2],F[c+3]=Math.round(h[N+3]/255*s.opacity*255),c+=4}let R=new Array(C).fill(!1);s.outlineBorder!==0&&(R=jI.getClusterBoundary(F,this.tris)),c=0;for(let l=0;l<C;l++){let S=l*28+24;this.f32PerVertex!==7&&(S=l*20+16);let N=F[c+3]/255;if(R[l]&&(N=s.outlineBorder,s.outlineBorder<0)){Q[S+0]=0,Q[S+1]=0,Q[S+2]=0,c+=4;continue}Q[S+0]=A(Q[S+0],F[c+0],N),Q[S+1]=A(Q[S+1],F[c+1],N),Q[S+2]=A(Q[S+2],F[c+2],N),c+=4}continue}if(s.values instanceof Uint8Array){const r=new Uint8Array(s.values.buffer);let n=new Array(C).fill(!0);s.outlineBorder!==0&&(n=jI.getClusterBoundary(r,this.tris));let h=0;for(let D=0;D<s.values.length;D++){let w=D*28+24;this.f32PerVertex!==7&&(w=D*20+16);let y=a;if(n[D]&&(y=s.outlineBorder,s.outlineBorder<0)){Q[w+0]=0,Q[w+1]=0,Q[w+2]=0,h+=4;continue}Q[w+0]=A(Q[w+0],r[h+0],y),Q[w+1]=A(Q[w+1],r[h+1],y),Q[w+2]=A(Q[w+2],r[h+2],y),h+=4}continue}s.useNegativeCmap&&(s.cal_min=Math.max(Number.EPSILON,s.cal_min),s.cal_max=Math.max(s.cal_min+1e-6,s.cal_max)),s.isTransparentBelowCalMin===void 0&&(s.isTransparentBelowCalMin=!0);const e=pA.colormap(s.colormap,s.colormapInvert);if(s.isAdditiveBlend&&E++,this.blendColormap(Q,i,s,s.cal_min,s.cal_max,e),s.useNegativeCmap){const r=pA.colormap(s.colormapNegative,s.colormapInvert);let n=s.cal_min,h=s.cal_max;isFinite(s.cal_minNeg)&&isFinite(s.cal_minNeg)&&(n=-s.cal_minNeg,h=-s.cal_maxNeg),this.blendColormap(Q,i,s,n,h,r,!0)}}if(E>0)for(let t=0;t<C;t++){let s=function(n,h){return Math.min(n*h*.00392156862745098,255)},a=t*28+24;this.f32PerVertex!==7&&(a=t*20+16);const e=t*4,r=Math.min(E,i[e+3]/255);r<=0||(Q[a+0]=s(Q[a+0],i[e+0]),Q[a+1]=s(Q[a+1],i[e+1]),Q[a+2]=s(Q[a+2],i[e+2]),Q[a+0]=A(Q[a+0],i[e+0],r),Q[a+1]=A(Q[a+1],i[e+1],r),Q[a+2]=A(Q[a+2],i[e+2],r))}I.bindBuffer(I.ELEMENT_ARRAY_BUFFER,this.indexBuffer),I.bufferData(I.ELEMENT_ARRAY_BUFFER,Uint32Array.from(o),I.STATIC_DRAW),I.bindBuffer(I.ARRAY_BUFFER,this.vertexBuffer),I.bufferData(I.ARRAY_BUFFER,Q,I.STATIC_DRAW),this.indexCount=o.length,this.vertexCount=this.pts.length}reverseFaces(I){if(this.offsetPt0||this.hasConnectome)return;const A=this.tris||[];for(let g=0;g<A.length;g+=3){const C=A[g];A[g]=A[g+1],A[g+1]=C}this.updateMesh(I)}hierarchicalOrder(){const g=this.tris.length/3,C=Math.log(g/20)/Math.log(4);if(g!==Math.pow(4,C)*20)return NaN;if(this.pts.length/3!==Math.pow(4,C)*10+2)return NaN;for(let E=0;E<15;E+=3)if(this.tris[E]!==0)return NaN;for(let E=15;E<24;E+=3)if(this.tris[E]!==3)return NaN;for(let E=24;E<30;E+=3)if(this.tris[E]!==4)return NaN;return C}decimateFaces(I,A){let g=this.tris;const C=12,Q=20;for(let E=I-1;E>=A;E--){const i=Math.pow(4,E+1)*(C-2)+2,o=Math.pow(4,E)*(C-2)+2,t=g.length/3,s=Math.pow(4,E)*Q;J.info(`order ${E+1} -> ${E} vertices ${i} -> ${o} faces ${t} -> ${s}`);const a=Array.from({length:i},(r,n)=>n+1);for(let r=0;r<t;r++){const n=g[3*r],h=g[3*r+1],D=g[3*r+2];a[n-1]=Math.min(a[n-1],h,D)}const e=new Uint32Array(s*3);for(let r=0;r<s;r++)e[3*r]=a[g[3*r]-1],e[3*r+1]=a[g[3*r+1]-1],e[3*r+2]=a[g[3*r+2]-1];g=e}this.tris=new Uint32Array(g)}decimateHierarchicalMesh(I,A=4){const g=this.hierarchicalOrder();if(isNaN(g))return J.warn("Unable to decimate mesh: it does not have a hierarchical structure"),!1;if(A>=g)return J.warn(`Unable to decimate mesh: input order (${g}) must be larger than downsampled order (${A})`),!1;const C=this.pts.length/3,E=Math.pow(4,A)*(12-2)+2;if(this.pts=new Float32Array(this.pts.slice(0,E*3)),this.decimateFaces(g,A),this.layers&&this.layers.length>0)for(let i=0;i<this.layers.length;i++){const o=this.layers[i];o.values instanceof Float32Array||o.values.length!==C?o.values=new Float32Array(o.values.slice(0,E)):J.warn("decimation logic needs to be updated")}return this.updateMesh(I),!0}async setLayerProperty(I,A,g,C){const Q=this.layers[I];if(!Q||!(A in Q)){J.warn("mesh does not have property ",A," for layer ",Q);return}if(A==="colormapLabel")if(typeof g=="object")Q[A]=pA.makeLabelLut(g,255,Q.global_max);else if(typeof g=="string"){const E=await pA.makeLabelLutFromUrl(g);Q[A]=E,this.updateMesh(C);return}else J.error("colormapLabel requires a string or object");else Q[A]=g;this.updateMesh(C)}setProperty(I,A,g){if(!(I in this)){console.warn("Mesh does not have property:",I,this);return}this[I]=A,this.updateMesh(g)}generatePosNormClr(I,A,g){(I.length<3||g.length<4)&&(J.error("Catastrophic failure generatePosNormClr()"),J.debug("this",this),J.debug("pts",I),J.debug("rgba",g));const C=jI.generateNormals(I,A),Q=I.length/3,E=Q===g.length/4,i=this.f32PerVertex,o=new Float32Array(Q*i),t=new Uint8Array(o.buffer);let s=0,a=0,e=0,r=(i-1)*4;for(let n=0;n<Q;n++)o[e+0]=I[s+0],o[e+1]=I[s+1],o[e+2]=I[s+2],i!==7?(t[r-4]=C[s+0]*127,t[r-3]=C[s+1]*127,t[r-2]=C[s+2]*127):(o[e+3]=C[s+0],o[e+4]=C[s+1],o[e+5]=C[s+2]),t[r]=g[a+0],t[r+1]=g[a+1],t[r+2]=g[a+2],t[r+3]=g[a+3],E&&(a+=4),s+=3,e+=i,r+=i*4;return o}static async readMesh(I,A,g,C=1,Q=new Uint8Array([255,255,255,255]),E=!0){let i=new Uint32Array([]),o=new Float32Array([]),t="",s;const a=/(?:\.([^.]+))?$/;let e=a.exec(A)[1];if(e=e.toUpperCase(),e==="GZ"&&(e=a.exec(A.slice(0,-3))[1],e=e.toUpperCase()),e==="JCON"&&J.error("you should never see this message: load using nvconnectome not nvmesh"),e==="JSON"&&J.error("you should never see this message: load using nvconnectome not nvmesh"),Q[3]=Math.max(1,Q[3]),e==="TCK"||e==="TRK"||e==="TT"||e==="TRX"||e==="TRACT"){if(e==="TCK"?s=dA.readTCK(I):e==="TRACT"?s=dA.readTRACT(I):e==="TT"?s=await dA.readTT(I):e==="TRX"?s=await dA.readTRX(I):s=await dA.readTRK(I),typeof s>"u"){const D=new Float32Array([0,0,0,0,0,0]),w=new Uint32Array([0]);s={pts:D,offsetPt0:w},J.error("Creating empty tracts")}return Q[3]=0,new QI(s.pts,s.offsetPt0,A,Q,C,E,g,"inferno",s.dpg||null,s.dps||null,s.dpv||null,s.groups)}if(e==="GII")s=await dA.readGII(I);else if(e==="MZ3")s=await dA.readMZ3(I),"positions"in s||J.warn("MZ3 does not have positions (statistical overlay?)");else if(e==="ASC")s=dA.readASC(I);else if(e==="DFS")s=dA.readDFS(I);else if(e==="BYU"||e==="G")s=dA.readGEO(I);else if(e==="GEO")s=dA.readGEO(I,!0);else if(e==="ICO"||e==="TRI")s=dA.readICO(I);else if(e==="OFF")s=dA.readOFF(I);else if(e==="NV")s=dA.readNV(I);else if(e==="OBJ")s=await dA.readOBJ(I);else if(e==="PLY")s=dA.readPLY(I);else if(e==="WRL")s=dA.readWRL(I);else if(e==="X3D")s=dA.readX3D(I);else if(e==="FIB"||e==="VTK"){if(s=dA.readVTK(I),"offsetPt0"in s)return Q[3]=0,new QI(s.pts,s.offsetPt0,A,Q,C,E,g,"inferno")}else e==="SRF"?s=await dA.readSRF(I):e==="STL"?s=dA.readSTL(I):s=dA.readFreeSurfer(I);if(s.anatomicalStructurePrimary&&(t=s.anatomicalStructurePrimary),s instanceof Float32Array)throw new Error("fatal: unknown mesh type loaded");if(!("positions"in s))throw new Error("positions not loaded");if(!s.indices)throw new Error("indices not loaded");if(o=s.positions,i=s.indices,"rgba255"in s&&s.rgba255.length>0&&(Q=s.rgba255),"colors"in s&&s.colors&&s.colors.length===o.length){const D=o.length/3;Q=new Uint8Array(D*4);let w=0,y=0;for(let F=0;F<D;F++)Q[y++]=s.colors[w]*255,Q[y++]=s.colors[w+1]*255,Q[y++]=s.colors[w+2]*255,Q[y++]=255,w+=3}const r=o.length/3;if(i.length/3<1||r<3)throw new Error("Mesh should have at least one triangle and three vertices");Q[3]=Math.max(1,Q[3]);const h=new QI(o,i,A,Q,C,E,g,null,null,null,null,null,!0,t);if("scalars"in s&&s.scalars.length>0){const D=await dA.readLayer(A,I,h,C,"gray");typeof D>"u"?J.warn("readLayer() failed to convert scalars"):(h.layers.push(D),h.updateMesh(g))}return h}static async loadLayer(I,A){let g=new Uint8Array().buffer;function C(n){const h=window.atob(n),D=h.length,w=new Uint8Array(D);for(let y=0;y<D;y++)w[y]=h.charCodeAt(y);return w.buffer}if(I.base64!==void 0)g=C(I.base64);else{if(!I.url)throw new Error("layer: missing url");const n=await fetch(I.url,{headers:I.headers});if(!n.ok)throw Error(n.statusText);g=await n.arrayBuffer()}let Q,E=[];if(I.name&&I.name!=="")Q=I.name;else{if(!I.url)throw new Error("layer: missing url");try{E=new URL(I.url).pathname.split("/")}catch{E=I.url.split("/")}finally{Q=E.slice(-1)[0]}}Q.indexOf("?")>-1&&(Q=Q.slice(0,Q.indexOf("?")));let i=.5;"opacity"in I&&(i=I.opacity);let o="warm";"colormap"in I&&(o=I.colormap);let t="winter";"colormapNegative"in I&&(t=I.colormapNegative);let s=!1;"useNegativeCmap"in I&&(s=I.useNegativeCmap);let a=null;"cal_min"in I&&(a=I.cal_min);let e=null;"cal_max"in I&&(e=I.cal_max);const r=await dA.readLayer(Q,g,A,i,o,t,s,a,e);r&&A.layers.push(r)}static async loadFromUrl({url:I="",headers:A={},gl:g,name:C="",opacity:Q=1,rgba255:E=[255,255,255,255],visible:i=!0,layers:o=[],buffer:t=new ArrayBuffer(0),meshShaderIndex:s=0}={}){let a=I.split("/");if(C===""){try{a=new URL(I).pathname.split("/")}catch{a=I.split("/")}C=a.slice(-1)[0],C.indexOf("?")>-1&&(C=C.slice(0,C.indexOf("?")))}if(I==="")throw Error("url must not be empty");if(!g)throw Error("gl context is null");let e;if(t.byteLength>0)e=t;else{const n=await fetch(I,{headers:A});if(!n.ok)throw Error(n.statusText);e=await n.arrayBuffer()}const r=await this.readMesh(e,C,g,Q,new Uint8Array(E),i);if(s!==void 0&&(r.meshShaderIndex=s),!o||o.length<1)return r;for(let n=0;n<o.length;n++)await QI.loadLayer(o[n],r);return r.updateMesh(g),r}static async readFileAsync(I){return new Promise((A,g)=>{const C=new FileReader;C.onload=()=>{A(C.result)},C.onerror=g,C.readAsArrayBuffer(I)})}static async loadFromFile({file:I,gl:A,name:g="",opacity:C=1,rgba255:Q=[255,255,255,255],visible:E=!0,layers:i=[]}={}){if(!I)throw new Error("file must be set");if(!A)throw new Error("rendering context must be set");const o=await QI.readFileAsync(I),t=await QI.readMesh(o,g,A,C,new Uint8Array(Q),E);if(!i||i.length<1)return t;for(let s=0;s<i.length;s++)await QI.loadLayer(i[s],t);return t.updateMesh(A),t}async loadFromBase64({base64:I,gl:A,name:g="",opacity:C=1,rgba255:Q=[255,255,255,255],visible:E=!0,layers:i=[]}={}){if(!I)throw new Error("base64 must bet set");if(!A)throw new Error("rendering context must be set");function o(a){const e=window.atob(a),r=e.length,n=new Uint8Array(r);for(let h=0;h<r;h++)n[h]=e.charCodeAt(h);return n.buffer}const t=o(I),s=await QI.readMesh(t,g,A,C,new Uint8Array(Q),E);if(!i||i.length<1)return s;for(let a=0;a<i.length;a++)await QI.loadLayer(i[a],s);return s.updateMesh(A),s}}const gt="data:image/jpeg;base64,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ZwAAAAAAAAALY3JvcFJlY3RUb3Bsb25nAAAAAAA4QklNA+0AAAAAABAASAAAAAEAAQBIAAAAAQABOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD+AAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNJxAAAAAAAAoAAQAAAAAAAAABOEJJTQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0EAAAAAAAAAgAAOEJJTQQCAAAAAAACAAA4QklNBDAAAAAAAAEBADhCSU0ELQAAAAAABgABAAAAMjhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAAM9AAAABgAAAAAAAAAAAAACAAAAAgAAAAAEAG0AYwA2ADEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAABudWxsAAAAAgAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAIAAAAAAFJnaHRsb25nAAACAAAAAAZzbGljZXNWbExzAAAAAU9iamMAAAABAAAAAAAFc2xpY2UAAAASAAAAB3NsaWNlSURsb25nAAAAAAAAAAdncm91cElEbG9uZwAAAAAAAAAGb3JpZ2luZW51bQAAAAxFU2xpY2VPcmlnaW4AAAANYXV0b0dlbmVyYXRlZAAAAABUeXBlZW51bQAAAApFU2xpY2VUeXBlAAAAAEltZyAAAAAGYm91bmRzT2JqYwAAAAEAAAAAAABSY3QxAAAABAAA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bnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9IjIwMTgtMDctMTJUMjA6MDc6NDcrMDE6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDE4LTA3LTEzVDE3OjU0OjI3KzAxOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDE4LTA3LTEzVDE3OjU0OjI3KzAxOjAwIiBkYzpmb3JtYXQ9ImltYWdlL2pwZWciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3MmVhYjVmZS02NDZkLWVhNDMtODQyNC0xNWQzZTgwOWExNDQiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo0OGNjMGI3YS1iYTJkLWZmNDAtYmNkNC1jNGQzMzIyZjBiNzQiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDphYzFjM2NhNS1hYTg4LWI5NGMtOGE4MS05YmU4MjA3ZGZiODciPiA8cGhvdG9zaG9wOkRvY3VtZW50QW5jZXN0b3JzPiA8cmRmOkJhZz4gPHJkZjpsaT5hZG9iZTpkb2NpZDpwaG90b3Nob3A6YThjMGNhZTYtODNjYy1hYzQ4LWI2YzAtN2FiODNlOWJkMGM3PC9yZGY6bGk+IDwvcmRmOkJhZz4gPC9waG90b3Nob3A6RG9jdW1lbnRBbmNlc3RvcnM+IDx4bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249ImNyZWF0ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6YWMxYzNjYTUtYWE4OC1iOTRjLThhODEtOWJlODIwN2RmYjg3IiBzdEV2dDp3aGVuPSIyMDE4LTA3LTEyVDIwOjA3OjQ3KzAxOjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ0MgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpjYmI3MzZlZC0zOTRhLTM2NDgtYThiOC02Mzk1MmY0NDcxMjIiIHN0RXZ0OndoZW49IjIwMTgtMDctMTNUMTY6MTM6NTgrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjQ2YjNkYTI3LWI4YjEtYmU0Yi1hYTQ4LTExZGM5NmZkNTIyZiIgc3RFdnQ6d2hlbj0iMjAxOC0wNy0xM1QxNzo1NDoyNyswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iY29udmVydGVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJmcm9tIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3AgdG8gaW1hZ2UvanBlZyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iZGVyaXZlZCIgc3RFdnQ6cGFyYW1ldGVycz0iY29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCB0byBpbWFnZS9qcGVnIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3MmVhYjVmZS02NDZkLWVhNDMtODQyNC0xNWQzZTgwOWExNDQiIHN0RXZ0OndoZW49IjIwMTgtMDctMTNUMTc6NTQ6MjcrMDE6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAoV2luZG93cykiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjQ2YjNkYTI3LWI4YjEtYmU0Yi1hYTQ4LTExZGM5NmZkNTIyZiIgc3RSZWY6ZG9jdW1lbnRJRD0iYWRvYmU6ZG9jaWQ6cGhvdG9zaG9wOjg3NjM1NDk5LWZiMTItYWU0MC04NWEzLThkMWFiN2NkZGVhOSIgc3RSZWY6b3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmFjMWMzY2E1LWFhODgtYjk0Yy04YTgxLTliZTgyMDdkZmI4NyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSJ3Ij8+/+IMWElDQ19QUk9GSUxFAAEBAAAMSExpbm8CEAAAbW50clJHQiBYWVogB84AAgAJAAYAMQAAYWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAAAAEAAPbWAAEAAAAA0y1IUCAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARY3BydAAAAVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAUclhZWgAAAhgAAAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABwZG1kZAAAAsQAAACIdnVlZAAAA0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gAAAAUbWVhcwAABAwAAAAkdGVjaAAABDAAAAAMclRSQwAABDwAAAgMZ1RSQwAABDwAAAgMYlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmlnaHQgKGMpIDE5OTggSGV3bGV0dC1Q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

niivue.umd.js at commit 51c01f3, under CC-BY-NC-4.0 · at the source

Overview

Authors: Pranesh Rajesh Kannan1, Raghav Pallapothu1, Santosh Kudaravalli1, Sriya Pallapothu1, Roger D. Newman-Norlund1
  1. Department of Psychology, McCausland College of Arts and Sciences, University of South Carolina,Columbia, SC USA
Institutions: University of South Carolina (United States)
Journal: Brain structure & function, volume 231, issue 8, article 156
Dates: received 16 July 2026; accepted 7 October 2026; published online 22 October 2026; in print 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1007/s00429-026-03213-6 · PMID 42911437 · PMCID PMC13690861 · OpenAlex W7223170657
Open access: hybrid, a free copy (OpenAlex)
Status: code verified (how the code is found and verified)
Categories: structural MRI / diffusion (modality), human (organism), Alzheimer's / dementia (population), cognitive (subfield)
Methods: Statistics, Machine learning, Connectivity, fMRI & imaging, Preprocessing
Keywords: Cerebellum, Crus II, Grip strength, Manual dexterity, Cognitive aging, Gray matter volume
MeSH: Aging*, Cerebellum*, Cognition*, Gray Matter*, Hand Strength*, Adult, Aged, Female, Humans, Magnetic Resonance Imaging, Male, Mental Status and Dementia Tests, Middle Aged, Organ Size, Young Adult (* major topic)
Topic: Dementia and Cognitive Impairment Research (Psychiatry and Mental health, Medicine), according to OpenAlex
Funding: National Institutes of Health (P50-DC01466)
Citations: not cited yet (Europe PMC); 34 references in the paper

Abstract

Cerebellar Crus I/II gray matter volume (GMV) is a structural marker of cognitive aging, and motor performance predicts age-related cognitive decline. Whether grip strength and manual dexterity dissociate in their cerebellar and cognitive correlates is unknown. We computed Pearson partial correlations (age, sex, and race covaried) between grip strength, Nine-Hole Peg Test (9HPT) dexterity, cerebellar Crus I/II GMV, and Montreal Cognitive Assessment (MoCA) subscores in 304 healthy adults aged 20–79 from the University of South Carolina Aging Brain Cohort. GMV was derived from T1-weighted MRI using CAT12 with the AAL3 atlas. After false discovery rate (FDR) correction, dominant 9HPT time correlated with MoCA total score (r=-.240) and memory index (r=-.220; both pFDR<0.001). Grip strength was unrelated to any MoCA measure but correlated bilaterally with Crus II GMV (r=.156–.224, all pFDR≤0.041). Bootstrapped mediation indicated that dexterity statistically accounted for 28.8% of the age–cognition association and Crus II volume for 34.4–41.4% of the age–grip association. Dichotomizing at the MoCA cut-off of 26, each additional second of peg time carried 17.6% higher odds of scoring below cut-off (odds ratio = 1.176, 95% CI [1.062,1.302]) while grip strength carried none. Grip strength, but not dexterity, was independently associated with Crus II GMV, whereas dexterity, but not grip, was associated with cognition. Grip strength and dexterity are therefore not interchangeable indices of motor function. Because the design is cross-sectional, mediation estimates describe shared variance rather than causal pathways, and the pronounced MoCA ceiling likely attenuated the cognitive associations.

Supplementary Information: The online version contains supplementary material available at https://doi.org/10.1007/s00429-026-03213-6.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 6 matches between paragraphs and lines of code.

Zenodo 21246441

License: CC-BY-NC-4.0
State: the link answers, verified on 25 October 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: the references
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (6 files), NiBabel (4 files), SciPy (3 files), Nilearn (2 files), scikit-image (2 files), Matplotlib (1 file)
Availability: 1 check, the latest on 25 October 2026: the link answers (HTTP 200)
  • 25 October 2026: the link answers (HTTP 200)
24 files
At the source:

rnorlund/brainWhiz

License: CC-BY-NC-4.0
State: the link answers, verified on 25 October 2026
Evidence: files inventoried
Commit: 51c01f3bad4dbb95b6323e43ee34a71bcfca7b38, 14 September 2026
Languages: JavaScript (118), Python (25), Shell (4), MATLAB (1)
Size: 283 files, 148 scripts
Software Heritage: not archived
Found in: the Zenodo archive record
Holds: README, license file, CITATION.cff, environment (Dockerfile), continuous integration, documentation
Not found: tests
Tools: NumPy (15 files), NiBabel (10 files), SciPy (9 files), PyTorch (7 files), Pillow (3 files), Matplotlib (2 files), Nilearn (2 files), scikit-image (2 files), SPM (1 file)
Availability: 1 check, the latest on 25 October 2026: the link answers
  • 25 October 2026: the link answers
53 files

Code availability

All analysis code is provided with this article as the archive dex_grip_analysis_code.zip, which reproduces every value reported in Tables 1, 2, 3, 4 and 5 and in the Sensitivity Analyses once the dataset has been obtained and placed as described in the archive. The code contains no participant-level data.

Reproduced under the paper's license (CC BY), from the paper cited above.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 73 scripts, each with its path and the digest of its content;
  • 6 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data availability

The data that support the findings of this study were obtained from the University of South Carolina Aging Brain Cohort (ABC) Study Repository. These data are owned and maintained by the ABC study, and are not publicly available, as they contain information that could compromise the privacy of individual participants. De-identified data are available from the University of South Carolina Aging Brain Cohort Study Repository on reasonable request, with the permission of the ABC study team and subject to a data use agreement and the relevant institutional and ethical (IRB) approvals.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 25 October 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 5 authors, 6 keywords, 15 MeSH terms, 1 funder, 33 references.

Cite

This paper

Rajesh Kannan, P., Pallapothu, R., Kudaravalli, S., Pallapothu, S., & Newman-Norlund, R. D. (2026). Quantifying dexterity and grip strength associations between age, cognitive function (MoCA), and cerebellar gray matter volume in healthy adults across the adult lifespan. Brain structure & function, 231(8), 156. https://doi.org/10.1007/s00429-026-03213-6

BibTeX

@article{rajeshkannan2026quantifying,
author = {Rajesh Kannan, Pranesh and Pallapothu, Raghav and Kudaravalli, Santosh and Pallapothu, Sriya and Newman-Norlund, Roger D.},
title = {{Quantifying dexterity and grip strength associations between age, cognitive function (MoCA), and cerebellar gray matter volume in healthy adults across the adult lifespan}},
journal = {Brain structure \& function},
year = {2026},
month = oct,
volume = {231},
number = {8},
pages = {156},
publisher = {Springer Science+Business Media},
issn = {1863-2653},
doi = {10.1007/s00429-026-03213-6},
url = {https://doi.org/10.1007/s00429-026-03213-6},
pmid = {42911437},
pmcid = {PMC13690861}
}

RIS

TY - JOUR
AU - Rajesh Kannan, Pranesh
AU - Pallapothu, Raghav
AU - Kudaravalli, Santosh
AU - Pallapothu, Sriya
AU - Newman-Norlund, Roger D.
TI - Quantifying dexterity and grip strength associations between age, cognitive function (MoCA), and cerebellar gray matter volume in healthy adults across the adult lifespan
T2 - Brain structure & function
J2 - Brain Struct Funct
PY - 2026
DA - 2026/10/22
VL - 231
IS - 8
SP - 156
SN - 1863-2653
PB - Springer Science+Business Media
DO - 10.1007/s00429-026-03213-6
UR - https://doi.org/10.1007/s00429-026-03213-6
LA - en
ER -

CSL-JSON

{
"id": "10.1007/s00429-026-03213-6",
"type": "article-journal",
"title": "Quantifying dexterity and grip strength associations between age, cognitive function (MoCA), and cerebellar gray matter volume in healthy adults across the adult lifespan",
"container-title": "Brain structure & function",
"author": [
{
"family": "Rajesh Kannan",
"given": "Pranesh"
},
{
"family": "Pallapothu",
"given": "Raghav"
},
{
"family": "Kudaravalli",
"given": "Santosh"
},
{
"family": "Pallapothu",
"given": "Sriya"
},
{
"family": "Newman-Norlund",
"given": "Roger D."
}
],
"container-title-short": "Brain Struct Funct",
"volume": "231",
"issue": "8",
"page": "156",
"DOI": "10.1007/s00429-026-03213-6",
"PMID": "42911437",
"PMCID": "PMC13690861",
"ISSN": "1863-2653",
"publisher": "Springer Science+Business Media",
"URL": "https://doi.org/10.1007/s00429-026-03213-6",
"language": "en",
"issued": {
"date-parts": [
[
2026,
10,
22
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1126/sciadv.adq4037 [code]
Within-individual organization of the human cognitive cerebellum: Evidence for closely juxtaposed, functionally specialized regions.
Journal: Science advances
In common: Nilearn, SPM, NiBabel, 4 other tools, cognitive, 3 references
[2] doi:10.1038/s41467-025-66124-w [code]
Constructing the human brain metabolic connectome with MR spectroscopic imaging reveals cerebral biochemical organization.
Journal: Nature communications
In common: Nilearn, scikit-image, Pillow, 4 other tools, structural MRI / diffusion, 2 references
[3] doi:10.1162/imag_a_00494 [code]
Transcriptomic gradients of the human cerebellum.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Nilearn, SPM, Pillow, 4 other tools, 2 references
[4] doi:10.1371/journal.pone.0317566 [code]
Predicting Parkinson's disease trajectory using clinical and functional MRI features: A reproduction and replication study.
Journal: PloS one
In common: Nilearn, SPM, Pillow, 4 other tools, 2 references
[5] doi:10.1016/j.neuroimage.2024.120603 [code]
Fetal brain MRI atlases and datasets: A review.
Journal: NeuroImage
In common: Nilearn, scikit-image, NiBabel, 4 other tools, structural MRI / diffusion, 1 reference
[6] doi:10.1162/imag_a_00245 [code]
Feature attention graph neural network for estimating brain age and identifying important neural connections in mouse models of genetic risk for Alzheimer's disease.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Nilearn, PyTorch, SciPy, 2 other tools, Alzheimer's / dementia, structural MRI / diffusion, 3 references
[7] doi:10.7554/elife.97184 [code]
Cortical beta oscillations map to shared brain networks modulated by dopamine.
Journal: eLife
In common: Nilearn, SPM, NiBabel, 3 other tools, structural MRI / diffusion, 2 references
[8] doi:10.1007/s10916-025-02244-6 [code]
K-operator for Modelling Neurodegeneration: Simulations, fMRI Application, Eigenvalue Analysis and Recurrence Plots.
Journal: Journal of medical systems
In common: Nilearn, NiBabel, PyTorch, 2 other tools, Alzheimer's / dementia, 2 references
[9] doi:10.1016/j.neubiorev.2025.106418 [code]
A bias-accounting meta-analytic approach refines and expands the cerebellar behavioral topography.
Journal: Neuroscience and biobehavioral reviews
In common: Nilearn, NiBabel, PyTorch, 3 other tools, 2 references
[10] doi:10.1038/s41598-022-14904-5 [code]
Tissue volume estimation and age prediction using rapid structural brain scans.
Journal: Scientific reports
In common: Nilearn, SPM, NiBabel, 3 other tools, structural MRI / diffusion, 1 reference

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.1007/s00429-026-03213-6.svg)](https://openscicode.org/badge/doi/10.1007/s00429-026-03213-6)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.1007/s00429-026-03213-6.svg
   :target: https://openscicode.org/badge/doi/10.1007/s00429-026-03213-6
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1007/s00429-026-03213-6"><img src="https://openscicode.org/badge/doi/10.1007/s00429-026-03213-6.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.