UNPKG

ngraph.leiden

Version:

Leiden/Louvain community detection for ngraph.graph (JS)

2 lines (1 loc) 17.4 kB
(function(V,Q){typeof exports=="object"&&typeof module<"u"?Q(exports,require("ngraph.graph")):typeof define=="function"&&define.amd?define(["exports","ngraph.graph"],Q):(V=typeof globalThis<"u"?globalThis:V||self,Q(V.ngraphLeiden={},V.createGraph))})(this,function(V,Q){"use strict";function Z(t,o={}){const n=o.linkWeight||(w=>w.data&&typeof w.data.weight=="number"?w.data.weight:1),s=o.nodeSize||(w=>w.data&&typeof w.data.size=="number"?w.data.size:1),i=!!o.directed,l=o.baseNodeIds,m=[],g=new Map;if(Array.isArray(l)&&l.length>0)for(let w=0;w<l.length;w++){const S=l[w];if(!(t.getNode?t.getNode(S):null))throw new Error("Multilayer graphs must share identical node ids. Missing: "+S);g.set(S,w),m.push(S)}else t.forEachNode(w=>{g.set(w.id,m.length),m.push(w.id)});const e=m.length,u=new Float64Array(e),a=new Float64Array(e),f=new Float64Array(e),y=new Float64Array(e),h=new Array(e),d=new Array(e);for(let w=0;w<e;w++)h[w]=[],d[w]=[];if(i)t.forEachLink(w=>{const S=g.get(w.fromId),I=g.get(w.toId);if(S==null||I==null)return;const z=+n(w)||0;S===I&&(a[S]+=z),h[S].push({to:I,w:z}),d[I].push({from:S,w:z}),f[S]+=z,y[I]+=z});else{const w=new Map;t.forEachLink(S=>{const I=g.get(S.fromId),z=g.get(S.toId);if(I==null||z==null)return;const b=+n(S)||0;if(I===z){a[I]+=b;return}const M=I<z?I:z,P=I<z?z:I,v=M+":"+P;let N=w.get(v);N||(N={sum:0,seenAB:0,seenBA:0},w.set(v,N)),N.sum+=b,I===M?N.seenAB=1:N.seenBA=1});for(const[S,I]of w.entries()){const[z,b]=S.split(":"),M=+z,P=+b,v=(I.seenAB?1:0)+(I.seenBA?1:0),N=v>0?I.sum/v:0;N!==0&&(h[M].push({to:P,w:N}),h[P].push({to:M,w:N}),d[M].push({from:P,w:N}),d[P].push({from:M,w:N}),f[M]+=N,f[P]+=N,y[M]+=N,y[P]+=N)}for(let S=0;S<e;S++){const I=a[S];I!==0&&(h[S].push({to:S,w:I}),d[S].push({from:S,w:I}),f[S]+=I,y[S]+=I)}}t.forEachNode(w=>{const S=g.get(w.id);u[S]=+s(w)||0});const T=f.reduce((w,S)=>w+S,0);function F(w,S){const I=h[w];for(let z=0;z<I.length;z++)S(I[z].to,I[z].w)}return{n:e,nodeIds:m,idToIndex:g,size:u,selfLoop:a,strengthOut:f,strengthIn:y,outEdges:h,inEdges:d,directed:i,totalWeight:T,forEachNeighbor:F}}function $(t){const o=t.n,n=new Int32Array(o);for(let r=0;r<o;r++)n[r]=r;let s=o,i=new Float64Array(s),l=new Int32Array(s),m=new Float64Array(s),g=new Float64Array(s),e=new Float64Array(s),u=new Float64Array(s),a=new Int32Array(o),f=0,y=new Float64Array(o),h=new Float64Array(o),d=new Float64Array(o),T=new Uint8Array(o);function F(r){if(r<=i.length)return;const c=Math.max(r,Math.ceil(i.length*1.5));i=J(i,c),l=lt(l,c),m=J(m,c),g=J(g,c),e=J(e,c),u=J(u,c)}function w(){i.fill(0),l.fill(0),m.fill(0),g.fill(0),e.fill(0),u.fill(0);for(let r=0;r<o;r++){const c=n[r];i[c]+=t.size[r],l[c]+=1,t.directed?(e[c]+=t.strengthOut[r],u[c]+=t.strengthIn[r]):g[c]+=t.strengthOut[r],t.selfLoop[r]!==0&&(m[c]+=t.selfLoop[r])}if(t.directed)for(let r=0;r<o;r++){const c=n[r],x=t.outEdges[r];for(let A=0;A<x.length;A++){const{to:E,w:_}=x[A];c===n[E]&&(m[c]+=_)}}else for(let r=0;r<o;r++){const c=n[r],x=t.outEdges[r];for(let A=0;A<x.length;A++){const{to:E,w:_}=x[A];E<=r||c===n[E]&&(m[c]+=_)}}}function S(){for(let r=0;r<f;r++){const c=a[r];T[c]=0,y[c]=0,h[c]=0,d[c]=0}f=0}function I(r){T[r]||(T[r]=1,a[f++]=r)}function z(r){S();const c=n[r];if(I(c),t.directed){const x=t.outEdges[r];for(let E=0;E<x.length;E++){const _=x[E].to,L=x[E].w,p=n[_];I(p),h[p]+=L}const A=t.inEdges[r];for(let E=0;E<A.length;E++){const _=A[E].from,L=A[E].w,p=n[_];I(p),d[p]+=L}}else{const x=t.outEdges[r];for(let A=0;A<x.length;A++){const E=x[A].to,_=x[A].w,L=n[E];I(L),y[L]+=_}}return f}const b=t.totalWeight;function M(r,c){const x=n[r];if(c===x)return 0;const A=t.strengthOut[r],E=c<y.length&&y[c]||0,_=y[x]||0,L=c<g.length?g[c]:0,p=g[x],G=-(_/b-A*p/(b*b)),B=E/b-A*L/(b*b);return G+B}function P(r,c){const x=n[r];if(c===x)return 0;const A=t.totalWeight,E=t.strengthOut[r],_=t.strengthIn[r],L=c<d.length&&d[c]||0,p=c<h.length&&h[c]||0,G=d[x]||0,B=h[x]||0,C=c<u.length?u[c]:0,O=c<e.length?e[c]:0,D=u[x],q=e[x],H=(L+p-G-B)/A,Y=(E*(C-D)+_*(O-q))/(A*A);return H-Y}function v(r,c,x=1){const A=n[r];if(c===A)return 0;const E=y[A]||0,_=c<y.length&&y[c]||0,L=t.size[r]||1,p=i[A]||0,G=c<i.length?i[c]:0;return _-E-x*L*(G-p+L)}function N(r,c){const x=n[r];if(x===c)return!1;c>=s&&(F(c+1),s=c+1);const A=t.strengthOut[r],E=t.strengthIn[r],_=t.selfLoop[r],L=t.size[r];if(l[x]-=1,l[c]+=1,i[x]-=L,i[c]+=L,t.directed?(e[x]-=A,e[c]+=A,u[x]-=E,u[c]+=E):(g[x]-=A,g[c]+=A),t.directed){const p=h[x]||0,G=d[x]||0,B=c<h.length&&h[c]||0,C=c<d.length&&d[c]||0;m[x]-=p+G+_,m[c]+=B+C+_}else{const p=y[x]||0,G=y[c]||0;m[x]-=2*p+_,m[c]+=2*G+_}return n[r]=c,!0}function R(r={}){const c=[];for(let C=0;C<s;C++)l[C]>0&&c.push(C);r.keepOldOrder?c.sort((C,O)=>C-O):r.preserveMap instanceof Map?c.sort((C,O)=>{const D=r.preserveMap.get(C),q=r.preserveMap.get(O);return D!=null&&q!=null&&D!==q?D-q:D!=null&&q==null?-1:q!=null&&D==null?1:i[O]-i[C]||l[O]-l[C]||C-O}):c.sort((C,O)=>i[O]-i[C]||l[O]-l[C]||C-O);const x=new Int32Array(s).fill(-1);c.forEach((C,O)=>{x[C]=O});for(let C=0;C<n.length;C++)n[C]=x[n[C]];const A=c.length,E=new Float64Array(A),_=new Int32Array(A),L=new Float64Array(A),p=new Float64Array(A),G=new Float64Array(A),B=new Float64Array(A);for(let C=0;C<o;C++){const O=n[C];E[O]+=t.size[C],_[O]+=1,t.directed?(G[O]+=t.strengthOut[C],B[O]+=t.strengthIn[C]):p[O]+=t.strengthOut[C]}if(t.directed)for(let C=0;C<o;C++){const O=n[C],D=t.outEdges[C];for(let q=0;q<D.length;q++){const{to:H,w:Y}=D[q];O===n[H]&&(L[O]+=Y)}}else for(let C=0;C<o;C++){const O=n[C],D=t.outEdges[C];for(let q=0;q<D.length;q++){const{to:H,w:Y}=D[q];H<=C||O===n[H]&&(L[O]+=Y)}}s=A,i=E,l=_,m=L,g=p,e=G,u=B}function W(){const r=new Array(s);for(let c=0;c<s;c++)r[c]=[];for(let c=0;c<o;c++)r[n[c]].push(c);return r}function k(r){return r<i.length?i[r]:0}function j(r){return r<l.length?l[r]:0}return{n:o,get communityCount(){return s},nodeCommunity:n,communityTotalSize:i,communityNodeCount:l,communityInternalEdgeWeight:m,communityTotalStrength:g,communityTotalOutStrength:e,communityTotalInStrength:u,initializeAggregates:w,accumulateNeighborCommunityEdgeWeights:z,getCandidateCommunityCount:()=>f,getCandidateCommunityAt:r=>a[r],getNeighborEdgeWeightToCommunity:r=>y[r]||0,getOutEdgeWeightToCommunity:r=>h[r]||0,getInEdgeWeightFromCommunity:r=>d[r]||0,deltaModularityUndirected:M,deltaModularityDirected:P,deltaCPM:v,moveNodeToCommunity:N,compactCommunityIds:R,getCommunityMembers:W,getCommunityTotalSize:k,getCommunityNodeCount:j}}function J(t,o){const n=new Float64Array(o);return n.set(t),n}function lt(t,o){const n=new Int32Array(o);return n.set(t),n}function dt(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var K={exports:{}},tt;function at(){if(tt)return K.exports;tt=1,K.exports=t,K.exports.random=t,K.exports.randomIterator=g;function t(e){var u=typeof e=="number"?e:+new Date;return new o(u)}function o(e){this.seed=e}o.prototype.next=m,o.prototype.nextDouble=l,o.prototype.uniform=l,o.prototype.gaussian=n,o.prototype.random=l;function n(){var e,u,a;do u=this.nextDouble()*2-1,a=this.nextDouble()*2-1,e=u*u+a*a;while(e>=1||e===0);return u*Math.sqrt(-2*Math.log(e)/e)}o.prototype.levy=s;function s(){var e=1.5,u=Math.pow(i(1+e)*Math.sin(Math.PI*e/2)/(i((1+e)/2)*e*Math.pow(2,(e-1)/2)),1/e);return this.gaussian()*u/Math.pow(Math.abs(this.gaussian()),1/e)}function i(e){return Math.sqrt(2*Math.PI/e)*Math.pow(1/Math.E*(e+1/(12*e-1/(10*e))),e)}function l(){var e=this.seed;return e=e+2127912214+(e<<12)&4294967295,e=(e^3345072700^e>>>19)&4294967295,e=e+374761393+(e<<5)&4294967295,e=(e+3550635116^e<<9)&4294967295,e=e+4251993797+(e<<3)&4294967295,e=(e^3042594569^e>>>16)&4294967295,this.seed=e,(e&268435455)/268435456}function m(e){return Math.floor(this.nextDouble()*e)}function g(e,u){var a=u||t();if(typeof a.next!="function")throw new Error("customRandom does not match expected API: next() function is missing");return{forEach:y,shuffle:f};function f(){var h,d,T;for(h=e.length-1;h>0;--h)d=a.next(h+1),T=e[d],e[d]=e[h],e[h]=T;return e}function y(h){var d,T,F;for(d=e.length-1;d>0;--d)T=a.next(d+1),F=e[T],e[T]=e[d],e[d]=F,h(F);e.length&&h(e[0])}}return K.exports}var mt=at();const ft=dt(mt);function gt(t,o,n,s){if(o.directed)return et(t,o,n,s);const i=t.nodeCommunity[n];if(s===i)return 0;const l=o.strengthOut[n],m=o.totalWeight,g=t.getNeighborEdgeWeightToCommunity(s)||0,e=t.getNeighborEdgeWeightToCommunity(i)||0,u=s<t.communityTotalStrength.length?t.communityTotalStrength[s]:0,a=t.communityTotalStrength[i],f=-(e/m-l*a/(m*m)),y=g/m-l*u/(m*m);return f+y}function et(t,o,n,s){const i=t.nodeCommunity[n];if(s===i)return 0;const l=o.totalWeight,m=o.strengthOut[n],g=o.strengthIn[n],e=s<o.n&&t.getInEdgeWeightFromCommunity(s)||0,u=s<o.n&&t.getOutEdgeWeightToCommunity(s)||0,a=t.getInEdgeWeightFromCommunity(i)||0,f=t.getOutEdgeWeightToCommunity(i)||0,y=s<t.communityTotalInStrength.length?t.communityTotalInStrength[s]:0,h=s<t.communityTotalOutStrength.length?t.communityTotalOutStrength[s]:0,d=t.communityTotalInStrength[i],T=t.communityTotalOutStrength[i],F=(e+u-a-f)/l,w=(m*(y-d)+g*(h-T))/(l*l);return F-w}function nt(t,o){const n=o.totalWeight;let s=0;if(o.directed)for(let i=0;i<t.communityCount;i++)s+=t.communityInternalEdgeWeight[i]/n-t.communityTotalOutStrength[i]*t.communityTotalInStrength[i]/(n*n);else for(let i=0;i<t.communityCount;i++){const l=t.communityInternalEdgeWeight[i],m=t.communityTotalStrength[i];s+=l/n-m*m/(n*n)}return s}function ht(t,o,n,s,i=1){const l=t.nodeCommunity[n];if(s===l)return 0;const m=t.getNeighborEdgeWeightToCommunity(l)||0,g=s<o.n&&t.getNeighborEdgeWeightToCommunity(s)||0,e=o.size[n]||1,u=t.communityTotalSize[l]||0,a=s<t.communityTotalSize.length?t.communityTotalSize[s]:0;return g-m-i*e*(a-u+e)}function ot(t,o,n=1){let s=0;for(let i=0;i<t.communityCount;i++)s+=t.communityInternalEdgeWeight[i]-n*(t.communityNodeCount[i]*(t.communityNodeCount[i]-1))/2;return s}function it(t,o,n=1){let s=0;for(let i=0;i<t.communityCount;i++){const l=t.communityTotalSize[i]||0;s+=t.communityInternalEdgeWeight[i]-n*(l*(l-1))/2}return s}const yt=50,rt=20,st=1e-12,U={Neighbors:0,All:1,RandomAny:2,RandomNeighbor:3};function wt(t,o={}){const n=xt(o);let s=t;const i=[],l=ft(n.randomSeed),m=()=>l.nextDouble(),g=Z(s,{directed:n.directed,...o}),e=g.n,u=new Int32Array(e);for(let y=0;y<e;y++)u[y]=y;let a=null;if(n.fixedNodes){const y=new Uint8Array(e),h=n.fixedNodes instanceof Set?n.fixedNodes:new Set(n.fixedNodes);for(const d of h){const T=g.idToIndex.get(d);T!=null&&(y[T]=1)}a=y}for(let y=0;y<n.maxLevels;y++){const h=y===0?g:Z(s,{directed:n.directed,...o}),d=$(h);d.graph=h,d.initializeAggregates();const T=new Int32Array(h.n);for(let b=0;b<h.n;b++)T[b]=b;let F=!0,w=0;const S=n.candidateStrategyCode;for(;F;){F=!1,w++,ct(T,m);for(let b=0;b<T.length;b++){const M=T[b];if(y===0&&a&&a[M])continue;const P=d.accumulateNeighborCommunityEdgeWeights(M);let v=d.nodeCommunity[M],N=0;const R=n.maxCommunitySize;if(S===U.All)for(let W=0;W<d.communityCount;W++){if(W===d.nodeCommunity[M]||R<1/0&&d.getCommunityTotalSize(W)+h.size[M]>R)continue;const k=X(d,M,W,n);k>N&&(N=k,v=W)}else if(S===U.RandomAny){const W=Math.min(10,Math.max(1,d.communityCount));for(let k=0;k<W;k++){const j=m()*d.communityCount|0;if(j===d.nodeCommunity[M]||R<1/0&&d.getCommunityTotalSize(j)+h.size[M]>R)continue;const r=X(d,M,j,n);r>N&&(N=r,v=j)}}else if(S===U.RandomNeighbor){const W=Math.min(10,Math.max(1,P));for(let k=0;k<W;k++){const j=d.getCandidateCommunityAt(m()*P|0);if(j===d.nodeCommunity[M]||R<1/0&&d.getCommunityTotalSize(j)+h.size[M]>R)continue;const r=X(d,M,j,n);r>N&&(N=r,v=j)}}else for(let W=0;W<P;W++){const k=d.getCandidateCommunityAt(W);if(R<1/0&&d.getCommunityTotalSize(k)+h.size[M]>R)continue;const j=X(d,M,k,n);j>N&&(N=j,v=k)}if(n.allowNewCommunity){const W=d.communityCount,k=X(d,M,W,n);k>N&&(N=k,v=W)}v!==d.nodeCommunity[M]&&N>st&&(d.moveNodeToCommunity(M,v),F=!0)}if(w>n.maxLocalPasses)break}ut(d,n.preserveLabels);let I=d;if(n.refine){const b=It(h,d,m,n,y===0?a:null);ut(b,n.preserveLabels),I=b}i.push({graph:h,partition:I});const z=I.nodeCommunity;for(let b=0;b<u.length;b++)u[b]=z[u[b]];if(d.communityCount===h.n)break;s=Ct(h,I)}const f=i[i.length-1];return{graph:f.graph,partition:f.partition,levels:i,originalToCurrent:u,originalNodeIds:g.nodeIds}}function Ct(t,o){const n=Q();for(let i=0;i<o.communityCount;i++)n.addNode(i,{size:o.communityTotalSize[i]});const s=new Map;for(let i=0;i<t.n;i++){const l=o.nodeCommunity[i],m=t.outEdges[i];for(let g=0;g<m.length;g++){const e=m[g].to,u=m[g].w,a=o.nodeCommunity[e],f=l+":"+a;s.set(f,(s.get(f)||0)+u)}}for(const[i,l]of s.entries()){const[m,g]=i.split(":"),e=+m,u=+g;n.addLink(e,u,{weight:l})}return n}function It(t,o,n,s,i){const l=$(t);l.initializeAggregates(),l.graph=t;const m=o.nodeCommunity;let g=new Int32Array(l.communityCount);for(let f=0;f<l.communityCount;f++)g[f]=m[f];const e=new Int32Array(t.n);for(let f=0;f<t.n;f++)e[f]=f;let u=!0,a=0;for(;u;){u=!1,a++,ct(e,n);for(let f=0;f<e.length;f++){const y=e[f];if(i&&i[y])continue;const h=m[y],d=l.accumulateNeighborCommunityEdgeWeights(y);let T=l.nodeCommunity[y],F=0;const w=Number.isFinite(s.maxCommunitySize)?s.maxCommunitySize:1/0;for(let S=0;S<d;S++){const I=l.getCandidateCommunityAt(S);if(g[I]!==h||w<1/0&&l.getCommunityTotalSize(I)+t.size[y]>w)continue;const z=X(l,y,I,s);z>F&&(F=z,T=I)}T!==l.nodeCommunity[y]&&F>st&&(l.moveNodeToCommunity(y,T),u=!0)}if(a>(s.maxLocalPasses||rt))break}return l}function X(t,o,n,s){if((s.quality||"modularity").toLowerCase()==="cpm"){const l=typeof s.resolution=="number"?s.resolution:1;return ht(t,t.graph||{},o,n,l)||t.deltaCPM?.(o,n,l)||0}return s.directed?et(t,t.graph||{},o,n)||t.deltaModularityDirected?.(o,n)||0:gt(t,t.graph||{},o,n)||t.deltaModularityUndirected?.(o,n)||0}function ct(t,o=Math.random){for(let n=t.length-1;n>0;n--){const s=Math.floor(o()*(n+1)),i=t[n];t[n]=t[s],t[s]=i}return t}function St(t){const o=t.candidateStrategy;if(typeof o!="string")return U.Neighbors;switch(o){case"neighbors":return U.Neighbors;case"all":return U.All;case"random":return U.RandomAny;case"random-neighbor":return U.RandomNeighbor;default:return U.Neighbors}}function xt(t={}){const o=!!t.directed,n=Number.isFinite(t.randomSeed)?t.randomSeed:42,s=Number.isFinite(t.maxLevels)?t.maxLevels:yt,i=Number.isFinite(t.maxLocalPasses)?t.maxLocalPasses:rt,l=!!t.allowNewCommunity,m=St(t),g=(t.quality||"modularity").toLowerCase(),e=typeof t.resolution=="number"?t.resolution:1,u=t.refine!==!1,a=t.preserveLabels,f=Number.isFinite(t.maxCommunitySize)?t.maxCommunitySize:1/0;return{directed:o,randomSeed:n,maxLevels:s,maxLocalPasses:i,allowNewCommunity:l,candidateStrategyCode:m,quality:g,resolution:e,refine:u,preserveLabels:a,maxCommunitySize:f,fixedNodes:t.fixedNodes}}function ut(t,o){o&&o instanceof Map?t.compactCommunityIds({preserveMap:o}):o===!0?t.compactCommunityIds({keepOldOrder:!0}):t.compactCommunityIds()}function At(t,o={}){if(!Array.isArray(t)||t.length===0)throw new Error("layers must be a non-empty array");o.directed;const n=t[0].graph,s=[],i=new Set;n.forEachNode(e=>{s.push(e.id),i.add(e.id)});for(let e=1;e<t.length;e++)t[e].graph.forEachNode(a=>{if(!i.has(a.id))throw new Error("All layers must share identical node ids. Missing in base: "+a.id)});const l=Q(),m=t[0].nodeSize||(e=>e.data&&typeof e.data.size=="number"?e.data.size:1);for(let e=0;e<s.length;e++){const u=s[e],a=n.getNode?n.getNode(u):null,f=a?m(a):1;l.addNode(u,{size:f})}const g=new Map;for(let e=0;e<t.length;e++){const{graph:u,weight:a=1,linkWeight:f}=t[e],y=f||(h=>h.data&&typeof h.data.weight=="number"?h.data.weight:1);u.forEachLink(h=>{const d=h.fromId,T=h.toId;if(!i.has(d)||!i.has(T))return;const F=a*y(h);if(F===0)return;const w=d+"\0"+T;g.set(w,(g.get(w)||0)+F)})}for(const[e,u]of g.entries()){const a=e.indexOf("\0"),f=e.substring(0,a),y=e.substring(a+1);l.addLink(f,y,{weight:u})}return l}function Nt(t,o={}){let n=t;Array.isArray(t)&&(n=At(t,{directed:!!o.directed}));const{graph:s,partition:i,levels:l,originalToCurrent:m,originalNodeIds:g}=wt(n,o),e=new Map;for(let u=0;u<g.length;u++){const a=m[u];e.set(g[u],a)}return{getClass(u){return e.get(u)},getCommunities(){const u=new Map;for(const[a,f]of e)u.has(f)||u.set(f,[]),u.get(f).push(a);return u},quality(){if((o.quality||"modularity").toLowerCase()==="cpm"){const a=typeof o.resolution=="number"?o.resolution:1;return(o.cpmMode||"unit")==="size-aware"?it(i,s,a):ot(i,s,a)}else return nt(i,s)},toJSON(){const u={};for(const[a,f]of e)u[a]=f;return{membership:u,meta:{levels:l.length,quality:this.quality(),options:o}}}}}function Tt(t,o,n={}){const s=!!n.directed,i=Z(t,{directed:s,...n}),l=$(i);l.graph=i;const m=i.idToIndex,g=u=>o instanceof Map?o.get(u):o?.[u];for(let u=0;u<i.nodeIds.length;u++){const a=i.nodeIds[u],f=g(a);if(f==null){if(n.requireMembership)throw new Error("Missing membership for node: "+a);continue}const y=bt(f);l.nodeCommunity[m.get(a)]=y}if(l.compactCommunityIds(),(n.quality||"modularity").toLowerCase()==="cpm"){const u=typeof n.resolution=="number"?n.resolution:1;return(n.cpmMode||"unit")==="size-aware"?it(l,i,u):ot(l,i,u)}return nt(l,i)}function bt(t){if(typeof t=="number")return t|0;if(typeof t=="string"){const o=Number(t);return Number.isFinite(o)?o|0:Mt(t)}return 0}function Mt(t){let o=2166136261;for(let n=0;n<t.length;n++)o^=t.charCodeAt(n),o=Math.imul(o,16777619);return o>>>0}V.detectClusters=Nt,V.evaluateQuality=Tt,Object.defineProperty(V,Symbol.toStringTag,{value:"Module"})});