@toclocoinc/lattice-grid 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/docs/API.html +323 -9
- package/docs/api-detail.html +205 -22
- package/lattice-grid.d.ts +277 -8
- package/lattice-grid.esm.min.js +1888 -561
- package/lattice-grid.min.cjs +1888 -561
- package/lattice-grid.min.css +1 -1
- package/lattice-grid.min.js +1888 -561
- package/modules/charts.esm.min.js +2 -2
- package/modules/devtools.esm.min.js +2 -2
- package/modules/dhtmlx-compat.esm.min.js +46 -4
- package/modules/htmx.esm.min.js +1888 -561
- package/modules/htmx.min.cjs +1888 -561
- package/modules/htmx.min.js +1888 -561
- package/modules/react.esm.min.js +2 -2
- package/modules/svelte.esm.min.js +2 -2
- package/modules/vue.esm.min.js +2 -2
- package/modules/webcomponent.esm.min.js +1888 -561
- package/package.json +1 -1
package/lattice-grid.esm.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.18.0, core + DOM renderer
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -49,9 +49,10 @@ Object.defineProperty(__exports,"now",{enumerable:true,get:function(){return now
|
|
|
49
49
|
Object.defineProperty(__exports,"nextFrame",{enumerable:true,get:function(){return nextFrame;}});
|
|
50
50
|
Object.defineProperty(__exports,"cancelFrame",{enumerable:true,get:function(){return cancelFrame;}});
|
|
51
51
|
Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){return frameBatched;}});
|
|
52
|
+
Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
|
|
52
53
|
Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
|
|
53
54
|
Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
|
|
54
|
-
const STAMPED_VERSION="1.
|
|
55
|
+
const STAMPED_VERSION="1.18.0";
|
|
55
56
|
async function resolveVersion(){
|
|
56
57
|
if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
|
|
57
58
|
try{
|
|
@@ -68,7 +69,7 @@ return JSON.parse(text).version||STAMPED_VERSION;
|
|
|
68
69
|
return STAMPED_VERSION;
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
|
-
const VERSION="1.
|
|
72
|
+
const VERSION="1.18.0";
|
|
72
73
|
const warned=new Set();
|
|
73
74
|
const reported=[];
|
|
74
75
|
const REPORT_LIMIT=500;
|
|
@@ -362,6 +363,47 @@ run();
|
|
|
362
363
|
};
|
|
363
364
|
return wrapped;
|
|
364
365
|
}
|
|
366
|
+
function settleDebounce(fn,waitMs){
|
|
367
|
+
let timer=null;
|
|
368
|
+
let held=null;
|
|
369
|
+
const trailing=()=>{
|
|
370
|
+
timer=null;
|
|
371
|
+
if(held===null)return;
|
|
372
|
+
const args=held;
|
|
373
|
+
held=null;
|
|
374
|
+
fn(...args);
|
|
375
|
+
arm();
|
|
376
|
+
};
|
|
377
|
+
const arm=()=>{
|
|
378
|
+
timer=setTimeout(trailing,waitMs);
|
|
379
|
+
if(typeof timer?.unref==='function')timer.unref();
|
|
380
|
+
};
|
|
381
|
+
const wrapped=(...args)=>{
|
|
382
|
+
if(timer===null){
|
|
383
|
+
fn(...args);
|
|
384
|
+
arm();
|
|
385
|
+
}else{
|
|
386
|
+
held=args;
|
|
387
|
+
clearTimeout(timer);
|
|
388
|
+
arm();
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
wrapped.flush=()=>{
|
|
392
|
+
if(timer!==null)clearTimeout(timer);
|
|
393
|
+
timer=null;
|
|
394
|
+
if(held===null)return;
|
|
395
|
+
const args=held;
|
|
396
|
+
held=null;
|
|
397
|
+
fn(...args);
|
|
398
|
+
};
|
|
399
|
+
wrapped.cancel=()=>{
|
|
400
|
+
if(timer!==null)clearTimeout(timer);
|
|
401
|
+
timer=null;
|
|
402
|
+
held=null;
|
|
403
|
+
};
|
|
404
|
+
wrapped.pending=()=>timer!==null||held!==null;
|
|
405
|
+
return wrapped;
|
|
406
|
+
}
|
|
365
407
|
function whenIdle(fn,timeout=50){
|
|
366
408
|
if(typeof requestIdleCallback==='function'){
|
|
367
409
|
return requestIdleCallback(fn,{timeout});
|
|
@@ -3656,6 +3698,9 @@ other:'Paste preview: {changes} cell changes, {rejected} rejected. Review, then
|
|
|
3656
3698
|
'menu.totalColumn':'Total this column',
|
|
3657
3699
|
'menu.aggregate':'Aggregate',
|
|
3658
3700
|
'menu.aggregateNone':'None',
|
|
3701
|
+
'menu.aggregateGroup':'Group subtotals',
|
|
3702
|
+
'menu.aggregateGrand':'Grand total',
|
|
3703
|
+
'menu.aggregateSame':'Same as total',
|
|
3659
3704
|
'menu.redactColumn':'Redact column',
|
|
3660
3705
|
'menu.stopRedacting':'Stop redacting',
|
|
3661
3706
|
'menu.stopRedactingAll':'Stop redacting everything',
|
|
@@ -4550,6 +4595,28 @@ resolved={index,base,binary:cfg.binary===true};
|
|
|
4550
4595
|
if(typeof cfg==='object'&&cfg!==null)configs.set(cfg,resolved);
|
|
4551
4596
|
return resolved;
|
|
4552
4597
|
}
|
|
4598
|
+
const compounds=new WeakMap();
|
|
4599
|
+
function resolveCompound(cfg,ctx){
|
|
4600
|
+
if(!cfg||!ctx||!Array.isArray(cfg.compound)||cfg.compound.length===0)return null;
|
|
4601
|
+
const memo=compounds.get(cfg);
|
|
4602
|
+
if(memo!==undefined)return memo;
|
|
4603
|
+
const seen=new Set();
|
|
4604
|
+
const units=[];
|
|
4605
|
+
for(const symbol of cfg.compound){
|
|
4606
|
+
const u=findUnit(cfg.system||'data',symbol);
|
|
4607
|
+
if(!u){
|
|
4608
|
+
warnOnce(`unit:compound:${cfg.system}:${symbol}`,`unknown compound unit "${symbol}" in system "${cfg.system||'data'}"; ignoring it`);
|
|
4609
|
+
continue;
|
|
4610
|
+
}
|
|
4611
|
+
if(seen.has(u.symbol))continue;
|
|
4612
|
+
seen.add(u.symbol);
|
|
4613
|
+
units.push(u);
|
|
4614
|
+
}
|
|
4615
|
+
units.sort((a,b)=>b.factor-a.factor);
|
|
4616
|
+
const out=units.length>=2?units:null;
|
|
4617
|
+
compounds.set(cfg,out);
|
|
4618
|
+
return out;
|
|
4619
|
+
}
|
|
4553
4620
|
function convert(value,from,to){
|
|
4554
4621
|
if(from===to||from.factor===to.factor)return value;
|
|
4555
4622
|
return(value*from.factor)/to.factor;
|
|
@@ -4603,6 +4670,34 @@ const ladder=ladderOf(index,binary);
|
|
|
4603
4670
|
const onLadder=candidates.filter((u)=>ladder.includes(u));
|
|
4604
4671
|
return onLadder.length===1?onLadder[0]:null;
|
|
4605
4672
|
}
|
|
4673
|
+
function parseCompound(s,ctx,parts,opts){
|
|
4674
|
+
let rest=s;
|
|
4675
|
+
let total=0;
|
|
4676
|
+
let read=false;
|
|
4677
|
+
let bare=false;
|
|
4678
|
+
while(rest!==''){
|
|
4679
|
+
const head=NUMBER_HEAD.exec(rest)[0];
|
|
4680
|
+
if(head==='')return null;
|
|
4681
|
+
const n=parseLocaleNumber(head,opts&&opts.locale);
|
|
4682
|
+
if(n===null)return null;
|
|
4683
|
+
rest=rest.slice(head.length).trim();
|
|
4684
|
+
const nextNum=rest.search(/[+-]?[\d]/);
|
|
4685
|
+
const token=(nextNum>=0?rest.slice(0,nextNum):rest).trim();
|
|
4686
|
+
rest=nextNum>=0?rest.slice(nextNum).trim():'';
|
|
4687
|
+
if(token===''){
|
|
4688
|
+
if(read)return null;
|
|
4689
|
+
bare=true;
|
|
4690
|
+
total+=convert(n,parts[0],ctx.base);
|
|
4691
|
+
}else{
|
|
4692
|
+
const from=resolveToken(token,ctx.index,ctx.binary);
|
|
4693
|
+
if(!from)return null;
|
|
4694
|
+
total+=convert(n,from,ctx.base);
|
|
4695
|
+
}
|
|
4696
|
+
read=true;
|
|
4697
|
+
if(bare&&rest!=='')return null;
|
|
4698
|
+
}
|
|
4699
|
+
return read?total:null;
|
|
4700
|
+
}
|
|
4606
4701
|
function parseUnit(text,opts){
|
|
4607
4702
|
if(isNil(text))return null;
|
|
4608
4703
|
if(typeof text==='number')return Number.isFinite(text)?text:null;
|
|
@@ -4612,6 +4707,13 @@ let s=String(text).trim();
|
|
|
4612
4707
|
if(s==='')return null;
|
|
4613
4708
|
let negative=false;
|
|
4614
4709
|
if(s.startsWith('(')&&s.endsWith(')')){negative=true;s=s.slice(1,-1).trim();}
|
|
4710
|
+
const parts=resolveCompound(opts,ctx);
|
|
4711
|
+
if(parts){
|
|
4712
|
+
if(s.startsWith('-')){negative=true;s=s.slice(1).trim();}
|
|
4713
|
+
const value=parseCompound(s,ctx,parts,opts);
|
|
4714
|
+
if(value===null)return null;
|
|
4715
|
+
return negative?-value:value;
|
|
4716
|
+
}
|
|
4615
4717
|
let leading=null;
|
|
4616
4718
|
const front=LEADING_SYMBOL.exec(s);
|
|
4617
4719
|
if(front&&front[0]){
|
|
@@ -4683,6 +4785,30 @@ if(loose&&loose!==AMBIGUOUS)return loose;
|
|
|
4683
4785
|
warnOnce(`unit:display:${symbol}`,`unknown display unit "${symbol}"; rendering in ${ctx.base.symbol}`);
|
|
4684
4786
|
return ctx.base;
|
|
4685
4787
|
}
|
|
4788
|
+
function formatCompound(value,ctx,parts,cfg){
|
|
4789
|
+
const negative=value<0;
|
|
4790
|
+
let remaining=Math.abs(value)*ctx.base.factor;
|
|
4791
|
+
const min=typeof cfg.decimals==='number'?cfg.decimals:(cfg.minDecimals??0);
|
|
4792
|
+
const max=typeof cfg.decimals==='number'?cfg.decimals:(cfg.maxDecimals??Math.max(min,2));
|
|
4793
|
+
const gap=cfg.space??' ';
|
|
4794
|
+
const pieces=[];
|
|
4795
|
+
for(let i=0;i<parts.length;i++){
|
|
4796
|
+
const u=parts[i];
|
|
4797
|
+
const last=i===parts.length-1;
|
|
4798
|
+
let count=last?remaining/u.factor:Math.floor(remaining/u.factor);
|
|
4799
|
+
remaining-=count*u.factor;
|
|
4800
|
+
if(last){
|
|
4801
|
+
const p=10**max;
|
|
4802
|
+
count=Math.round(count*p)/p+0;
|
|
4803
|
+
}
|
|
4804
|
+
const fmt=last
|
|
4805
|
+
?numberFormat(cfg.locale,min,max,cfg.group!==false)
|
|
4806
|
+
:numberFormat(cfg.locale,0,0,cfg.group!==false);
|
|
4807
|
+
pieces.push(`${fmt.format(count)}${gap}${u.symbol}`);
|
|
4808
|
+
}
|
|
4809
|
+
const body=pieces.join(' ');
|
|
4810
|
+
return negative?`-${body}`:body;
|
|
4811
|
+
}
|
|
4686
4812
|
function formatUnit(value,opts){
|
|
4687
4813
|
const cfg=opts||{};
|
|
4688
4814
|
const blank=cfg.nullDisplay??'';
|
|
@@ -4691,6 +4817,8 @@ const n=typeof value==='number'?value:Number(value);
|
|
|
4691
4817
|
if(!Number.isFinite(n))return blank;
|
|
4692
4818
|
const ctx=resolve(cfg);
|
|
4693
4819
|
if(!ctx)return String(n);
|
|
4820
|
+
const parts=resolveCompound(cfg,ctx);
|
|
4821
|
+
if(parts)return formatCompound(n,ctx,parts,cfg);
|
|
4694
4822
|
const figures=typeof cfg.significantFigures==='number'&&cfg.significantFigures>0
|
|
4695
4823
|
?cfg.significantFigures:0;
|
|
4696
4824
|
const rounded=figures?roundToSignificant(n,figures):n;
|
|
@@ -6891,6 +7019,12 @@ filter:{...(m.filter||{})},
|
|
|
6891
7019
|
group:{enabled:false,index:-1,explode:false,...(m.group||{})},
|
|
6892
7020
|
pivot:{enabled:false,index:-1,...(m.pivot||{})},
|
|
6893
7021
|
total:this.#resolveTotal(m.total,type,def.id||def.field||'(unnamed)'),
|
|
7022
|
+
groupTotal:m.groupTotal===undefined
|
|
7023
|
+
?null
|
|
7024
|
+
:this.#resolveTotal(m.groupTotal,type,def.id||def.field||'(unnamed)'),
|
|
7025
|
+
grandTotal:m.grandTotal===undefined
|
|
7026
|
+
?null
|
|
7027
|
+
:this.#resolveTotal(m.grandTotal,type,def.id||def.field||'(unnamed)'),
|
|
6894
7028
|
tags:normaliseTags(m.tags),
|
|
6895
7029
|
typeOptions:m.typeOptions??null,
|
|
6896
7030
|
...(isObject(m[typeName])?{[typeName]:m[typeName]}:{}),
|
|
@@ -7095,6 +7229,8 @@ sortIndex:c.sort.direction?(c.sort.order??0):null,
|
|
|
7095
7229
|
groupIndex:c.group.enabled?(c.group.index??0):null,
|
|
7096
7230
|
pivotIndex:c.pivot.enabled?(c.pivot.index??0):null,
|
|
7097
7231
|
total:typeof c.total==='string'?c.total:null,
|
|
7232
|
+
groupTotal:typeof c.groupTotal==='string'?c.groupTotal:undefined,
|
|
7233
|
+
grandTotal:typeof c.grandTotal==='string'?c.grandTotal:undefined,
|
|
7098
7234
|
}));
|
|
7099
7235
|
}
|
|
7100
7236
|
applyState(state){
|
|
@@ -7114,6 +7250,8 @@ if(entry.sortIndex!=null)column.sort.order=entry.sortIndex;
|
|
|
7114
7250
|
if(entry.groupIndex!=null){column.group.enabled=true;column.group.index=entry.groupIndex;}
|
|
7115
7251
|
if(entry.pivotIndex!=null){column.pivot.enabled=true;column.pivot.index=entry.pivotIndex;}
|
|
7116
7252
|
if(entry.total!==undefined)column.total=entry.total;
|
|
7253
|
+
if(entry.groupTotal!==undefined)column.groupTotal=entry.groupTotal;
|
|
7254
|
+
if(entry.grandTotal!==undefined)column.grandTotal=entry.grandTotal;
|
|
7117
7255
|
report.applied.push(entry.id);
|
|
7118
7256
|
}
|
|
7119
7257
|
const ids=order||list.map((e)=>e&&e.id).filter(Boolean);
|
|
@@ -8163,7 +8301,7 @@ varianceP:'rescan',
|
|
|
8163
8301
|
stddev:'rescan',
|
|
8164
8302
|
stddevP:'rescan',
|
|
8165
8303
|
sumSquares:'rescan',
|
|
8166
|
-
weightedAvg:'
|
|
8304
|
+
weightedAvg:'rescan',
|
|
8167
8305
|
median:'rescan',
|
|
8168
8306
|
p25:'rescan',
|
|
8169
8307
|
p75:'rescan',
|
|
@@ -10219,6 +10357,548 @@ this.#fill=w;
|
|
|
10219
10357
|
}
|
|
10220
10358
|
}
|
|
10221
10359
|
});
|
|
10360
|
+
__def("packages/core/src/compute/sort.js",function(__exports,__req){
|
|
10361
|
+
'use strict';
|
|
10362
|
+
Object.defineProperty(__exports,"radixSortFloat64",{enumerable:true,get:function(){return radixSortFloat64;}});
|
|
10363
|
+
Object.defineProperty(__exports,"radixSortInt32",{enumerable:true,get:function(){return radixSortInt32;}});
|
|
10364
|
+
Object.defineProperty(__exports,"rankSortDictionary",{enumerable:true,get:function(){return rankSortDictionary;}});
|
|
10365
|
+
Object.defineProperty(__exports,"mergeSortComparator",{enumerable:true,get:function(){return mergeSortComparator;}});
|
|
10366
|
+
Object.defineProperty(__exports,"rankSortStrings",{enumerable:true,get:function(){return rankSortStrings;}});
|
|
10367
|
+
Object.defineProperty(__exports,"collateStringRanks",{enumerable:true,get:function(){return collateStringRanks;}});
|
|
10368
|
+
Object.defineProperty(__exports,"sortColumn",{enumerable:true,get:function(){return sortColumn;}});
|
|
10369
|
+
Object.defineProperty(__exports,"sortMulti",{enumerable:true,get:function(){return sortMulti;}});
|
|
10370
|
+
const __m0=__req("packages/core/src/compute/handle.js");
|
|
10371
|
+
const bitReader=__m0["bitReader"];
|
|
10372
|
+
const dictRanks=__m0["dictRanks"];
|
|
10373
|
+
const dictSize=__m0["dictSize"];
|
|
10374
|
+
const identity=__m0["identity"];
|
|
10375
|
+
const isMissing=__m0["isMissing"];
|
|
10376
|
+
const presenceReader=__m0["presenceReader"];
|
|
10377
|
+
const rowCount=__m0["rowCount"];
|
|
10378
|
+
const valueComparator=__m0["valueComparator"];
|
|
10379
|
+
const valueReader=__m0["valueReader"];
|
|
10380
|
+
const EMPTY_INDICES=new Uint32Array(0);
|
|
10381
|
+
const SCRATCH=new ArrayBuffer(8);
|
|
10382
|
+
const SCRATCH_F64=new Float64Array(SCRATCH);
|
|
10383
|
+
const SCRATCH_U32=new Uint32Array(SCRATCH);
|
|
10384
|
+
const HI=(()=>{
|
|
10385
|
+
SCRATCH_F64[0]=-1;
|
|
10386
|
+
return(SCRATCH_U32[1]&0x80000000)!==0?1:0;
|
|
10387
|
+
})();
|
|
10388
|
+
const LO=HI===1?0:1;
|
|
10389
|
+
function transformDouble(value,out){
|
|
10390
|
+
SCRATCH_F64[0]=value;
|
|
10391
|
+
let hi=SCRATCH_U32[HI];
|
|
10392
|
+
let lo=SCRATCH_U32[LO];
|
|
10393
|
+
if((hi&0x80000000)!==0){
|
|
10394
|
+
hi=~hi>>>0;
|
|
10395
|
+
lo=~lo>>>0;
|
|
10396
|
+
}else{
|
|
10397
|
+
hi=(hi^0x80000000)>>>0;
|
|
10398
|
+
}
|
|
10399
|
+
out[0]=lo;
|
|
10400
|
+
out[1]=hi;
|
|
10401
|
+
}
|
|
10402
|
+
function radixLsd64(idx,lo,hi,n){
|
|
10403
|
+
if(n<2)return idx;
|
|
10404
|
+
const hist=new Uint32Array(256*8);
|
|
10405
|
+
for(let i=0;i<n;i++){
|
|
10406
|
+
const l=lo[i];
|
|
10407
|
+
const h=hi[i];
|
|
10408
|
+
hist[l&0xff]++;
|
|
10409
|
+
hist[256+((l>>>8)&0xff)]++;
|
|
10410
|
+
hist[512+((l>>>16)&0xff)]++;
|
|
10411
|
+
hist[768+((l>>>24)&0xff)]++;
|
|
10412
|
+
hist[1024+(h&0xff)]++;
|
|
10413
|
+
hist[1280+((h>>>8)&0xff)]++;
|
|
10414
|
+
hist[1536+((h>>>16)&0xff)]++;
|
|
10415
|
+
hist[1792+((h>>>24)&0xff)]++;
|
|
10416
|
+
}
|
|
10417
|
+
let srcIdx=idx;
|
|
10418
|
+
let srcLo=lo;
|
|
10419
|
+
let srcHi=hi;
|
|
10420
|
+
let dstIdx=new Uint32Array(n);
|
|
10421
|
+
let dstLo=new Uint32Array(n);
|
|
10422
|
+
let dstHi=new Uint32Array(n);
|
|
10423
|
+
const offset=new Uint32Array(256);
|
|
10424
|
+
for(let pass=0;pass<8;pass++){
|
|
10425
|
+
const base=pass<<8;
|
|
10426
|
+
const shift=(pass&3)<<3;
|
|
10427
|
+
const useHi=pass>=4;
|
|
10428
|
+
let skip=false;
|
|
10429
|
+
for(let b=0;b<256;b++){
|
|
10430
|
+
if(hist[base+b]===n){skip=true;break;}
|
|
10431
|
+
}
|
|
10432
|
+
if(skip)continue;
|
|
10433
|
+
let sum=0;
|
|
10434
|
+
for(let b=0;b<256;b++){
|
|
10435
|
+
offset[b]=sum;
|
|
10436
|
+
sum+=hist[base+b];
|
|
10437
|
+
}
|
|
10438
|
+
for(let i=0;i<n;i++){
|
|
10439
|
+
const l=srcLo[i];
|
|
10440
|
+
const h=srcHi[i];
|
|
10441
|
+
const digit=((useHi?h:l)>>>shift)&0xff;
|
|
10442
|
+
const p=offset[digit]++;
|
|
10443
|
+
dstIdx[p]=srcIdx[i];
|
|
10444
|
+
dstLo[p]=l;
|
|
10445
|
+
dstHi[p]=h;
|
|
10446
|
+
}
|
|
10447
|
+
let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
|
|
10448
|
+
t=srcLo;srcLo=dstLo;dstLo=t;
|
|
10449
|
+
t=srcHi;srcHi=dstHi;dstHi=t;
|
|
10450
|
+
}
|
|
10451
|
+
return srcIdx;
|
|
10452
|
+
}
|
|
10453
|
+
function radixLsd32(idx,keys,n){
|
|
10454
|
+
if(n<2)return idx;
|
|
10455
|
+
const hist=new Uint32Array(256*4);
|
|
10456
|
+
for(let i=0;i<n;i++){
|
|
10457
|
+
const k=keys[i];
|
|
10458
|
+
hist[k&0xff]++;
|
|
10459
|
+
hist[256+((k>>>8)&0xff)]++;
|
|
10460
|
+
hist[512+((k>>>16)&0xff)]++;
|
|
10461
|
+
hist[768+((k>>>24)&0xff)]++;
|
|
10462
|
+
}
|
|
10463
|
+
let srcIdx=idx;
|
|
10464
|
+
let srcKeys=keys;
|
|
10465
|
+
let dstIdx=new Uint32Array(n);
|
|
10466
|
+
let dstKeys=new Uint32Array(n);
|
|
10467
|
+
const offset=new Uint32Array(256);
|
|
10468
|
+
for(let pass=0;pass<4;pass++){
|
|
10469
|
+
const base=pass<<8;
|
|
10470
|
+
const shift=pass<<3;
|
|
10471
|
+
let skip=false;
|
|
10472
|
+
for(let b=0;b<256;b++){
|
|
10473
|
+
if(hist[base+b]===n){skip=true;break;}
|
|
10474
|
+
}
|
|
10475
|
+
if(skip)continue;
|
|
10476
|
+
let sum=0;
|
|
10477
|
+
for(let b=0;b<256;b++){
|
|
10478
|
+
offset[b]=sum;
|
|
10479
|
+
sum+=hist[base+b];
|
|
10480
|
+
}
|
|
10481
|
+
for(let i=0;i<n;i++){
|
|
10482
|
+
const k=srcKeys[i];
|
|
10483
|
+
const p=offset[(k>>>shift)&0xff]++;
|
|
10484
|
+
dstIdx[p]=srcIdx[i];
|
|
10485
|
+
dstKeys[p]=k;
|
|
10486
|
+
}
|
|
10487
|
+
let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
|
|
10488
|
+
t=srcKeys;srcKeys=dstKeys;dstKeys=t;
|
|
10489
|
+
}
|
|
10490
|
+
return srcIdx;
|
|
10491
|
+
}
|
|
10492
|
+
function countingSort(idx,keys,n,radix){
|
|
10493
|
+
const counts=new Uint32Array(radix+1);
|
|
10494
|
+
for(let i=0;i<n;i++)counts[keys[i]]++;
|
|
10495
|
+
let sum=0;
|
|
10496
|
+
for(let k=0;k<=radix;k++){
|
|
10497
|
+
const c=counts[k];
|
|
10498
|
+
counts[k]=sum;
|
|
10499
|
+
sum+=c;
|
|
10500
|
+
}
|
|
10501
|
+
const out=new Uint32Array(n);
|
|
10502
|
+
for(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];
|
|
10503
|
+
return out;
|
|
10504
|
+
}
|
|
10505
|
+
function sortUint32Keys(idx,keys,n,radix){
|
|
10506
|
+
if(n<2)return idx;
|
|
10507
|
+
if(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);
|
|
10508
|
+
return radixLsd32(idx,keys,n);
|
|
10509
|
+
}
|
|
10510
|
+
function exact(buffer,n){
|
|
10511
|
+
if(buffer.length===n&&buffer.byteOffset===0)return buffer;
|
|
10512
|
+
return Uint32Array.prototype.slice.call(buffer,0,n);
|
|
10513
|
+
}
|
|
10514
|
+
function radixSortFloat64(values,order,descending=false){
|
|
10515
|
+
const src=order||identity(values.length);
|
|
10516
|
+
const n=src.length;
|
|
10517
|
+
if(n<2)return Uint32Array.from(src);
|
|
10518
|
+
const idx=new Uint32Array(n);
|
|
10519
|
+
const lo=new Uint32Array(n);
|
|
10520
|
+
const hi=new Uint32Array(n);
|
|
10521
|
+
const nans=new Uint32Array(n);
|
|
10522
|
+
const pair=new Uint32Array(2);
|
|
10523
|
+
let m=0;
|
|
10524
|
+
let nanCount=0;
|
|
10525
|
+
for(let i=0;i<n;i++){
|
|
10526
|
+
const row=src[i];
|
|
10527
|
+
const v=values[row];
|
|
10528
|
+
if(Number.isNaN(v)){nans[nanCount++]=row;continue;}
|
|
10529
|
+
transformDouble(v,pair);
|
|
10530
|
+
if(descending){
|
|
10531
|
+
lo[m]=~pair[0]>>>0;
|
|
10532
|
+
hi[m]=~pair[1]>>>0;
|
|
10533
|
+
}else{
|
|
10534
|
+
lo[m]=pair[0];
|
|
10535
|
+
hi[m]=pair[1];
|
|
10536
|
+
}
|
|
10537
|
+
idx[m++]=row;
|
|
10538
|
+
}
|
|
10539
|
+
const sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);
|
|
10540
|
+
if(nanCount===0)return exact(sorted,m);
|
|
10541
|
+
const out=new Uint32Array(n);
|
|
10542
|
+
out.set(sorted.subarray(0,m),0);
|
|
10543
|
+
out.set(nans.subarray(0,nanCount),m);
|
|
10544
|
+
return out;
|
|
10545
|
+
}
|
|
10546
|
+
function radixSortInt32(values,order,descending=false){
|
|
10547
|
+
const src=order||identity(values.length);
|
|
10548
|
+
const n=src.length;
|
|
10549
|
+
if(n<2)return Uint32Array.from(src);
|
|
10550
|
+
const idx=Uint32Array.from(src);
|
|
10551
|
+
const keys=new Uint32Array(n);
|
|
10552
|
+
for(let i=0;i<n;i++){
|
|
10553
|
+
const k=(values[idx[i]]^0x80000000)>>>0;
|
|
10554
|
+
keys[i]=descending?(~k>>>0):k;
|
|
10555
|
+
}
|
|
10556
|
+
return exact(radixLsd32(idx,keys,n),n);
|
|
10557
|
+
}
|
|
10558
|
+
function rankSortDictionary(handle,order,opts={}){
|
|
10559
|
+
const src=order||identity(rowCount(handle,opts));
|
|
10560
|
+
const n=src.length;
|
|
10561
|
+
if(n<2)return Uint32Array.from(src);
|
|
10562
|
+
const ranks=dictRanks(handle.dict,opts.locale);
|
|
10563
|
+
const codes=handle.values;
|
|
10564
|
+
const present=presenceReader(handle);
|
|
10565
|
+
const size=Math.max(dictSize(handle.dict),ranks.length);
|
|
10566
|
+
const absentRank=size;
|
|
10567
|
+
const idx=Uint32Array.from(src);
|
|
10568
|
+
const keys=new Uint32Array(n);
|
|
10569
|
+
const descending=!!opts.descending;
|
|
10570
|
+
for(let i=0;i<n;i++){
|
|
10571
|
+
const row=idx[i];
|
|
10572
|
+
let rank=present&&present(row)===0?absentRank:ranks[codes[row]];
|
|
10573
|
+
if(rank===undefined)rank=absentRank;
|
|
10574
|
+
keys[i]=descending?absentRank-rank:rank;
|
|
10575
|
+
}
|
|
10576
|
+
return exact(sortUint32Keys(idx,keys,n,size+1),n);
|
|
10577
|
+
}
|
|
10578
|
+
function mergeSortComparator(values,order,compare){
|
|
10579
|
+
const n=order.length;
|
|
10580
|
+
let src=Uint32Array.from(order);
|
|
10581
|
+
if(n<2)return src;
|
|
10582
|
+
let dst=new Uint32Array(n);
|
|
10583
|
+
for(let width=1;width<n;width<<=1){
|
|
10584
|
+
for(let start=0;start<n;start+=width<<1){
|
|
10585
|
+
const mid=Math.min(start+width,n);
|
|
10586
|
+
const end=Math.min(start+(width<<1),n);
|
|
10587
|
+
let i=start;
|
|
10588
|
+
let j=mid;
|
|
10589
|
+
let k=start;
|
|
10590
|
+
while(i<mid&&j<end){
|
|
10591
|
+
dst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];
|
|
10592
|
+
}
|
|
10593
|
+
while(i<mid)dst[k++]=src[i++];
|
|
10594
|
+
while(j<end)dst[k++]=src[j++];
|
|
10595
|
+
}
|
|
10596
|
+
const t=src;src=dst;dst=t;
|
|
10597
|
+
}
|
|
10598
|
+
return src;
|
|
10599
|
+
}
|
|
10600
|
+
function sortBitsetColumn(handle,idx,descending){
|
|
10601
|
+
const bit=bitReader(handle.values);
|
|
10602
|
+
const n=idx.length;
|
|
10603
|
+
const out=new Uint32Array(n);
|
|
10604
|
+
const first=descending?1:0;
|
|
10605
|
+
let k=0;
|
|
10606
|
+
for(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];
|
|
10607
|
+
for(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];
|
|
10608
|
+
return out;
|
|
10609
|
+
}
|
|
10610
|
+
function indexableValues(handle,idx){
|
|
10611
|
+
const values=handle.values;
|
|
10612
|
+
const kind=handle.kind;
|
|
10613
|
+
const direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));
|
|
10614
|
+
if(direct&&!handle.presence)return values;
|
|
10615
|
+
const reader=valueReader(handle);
|
|
10616
|
+
const materialised=new Array(rowCount(handle)||0);
|
|
10617
|
+
for(let i=0;i<idx.length;i++){
|
|
10618
|
+
const row=idx[i];
|
|
10619
|
+
materialised[row]=reader(row);
|
|
10620
|
+
}
|
|
10621
|
+
return materialised;
|
|
10622
|
+
}
|
|
10623
|
+
function allStrings(values,idx){
|
|
10624
|
+
for(let i=0;i<idx.length;i++){
|
|
10625
|
+
if(typeof values[idx[i]]!=='string')return false;
|
|
10626
|
+
}
|
|
10627
|
+
return true;
|
|
10628
|
+
}
|
|
10629
|
+
function rankSortStrings(idx,codes,ranks,d,descending){
|
|
10630
|
+
const n=idx.length;
|
|
10631
|
+
const idxOut=Uint32Array.from(idx);
|
|
10632
|
+
if(n<2||d<1)return idxOut;
|
|
10633
|
+
const keys=new Uint32Array(n);
|
|
10634
|
+
const top=d-1;
|
|
10635
|
+
for(let i=0;i<n;i++){
|
|
10636
|
+
const rank=ranks[codes[i]];
|
|
10637
|
+
keys[i]=descending?top-rank:rank;
|
|
10638
|
+
}
|
|
10639
|
+
return exact(sortUint32Keys(idxOut,keys,n,d),n);
|
|
10640
|
+
}
|
|
10641
|
+
function collateStringRanks(table,d,locale){
|
|
10642
|
+
const compare=valueComparator(locale);
|
|
10643
|
+
const order=new Array(d);
|
|
10644
|
+
for(let i=0;i<d;i++)order[i]=i;
|
|
10645
|
+
order.sort((a,b)=>compare(table[a],table[b])||a-b);
|
|
10646
|
+
const ranks=new Uint32Array(d);
|
|
10647
|
+
for(let r=0;r<d;r++)ranks[order[r]]=r;
|
|
10648
|
+
return ranks;
|
|
10649
|
+
}
|
|
10650
|
+
function keyedSortStrings(values,idx,opts){
|
|
10651
|
+
const n=idx.length;
|
|
10652
|
+
const codeOf=new Map();
|
|
10653
|
+
const table=[];
|
|
10654
|
+
const codes=new Uint32Array(n);
|
|
10655
|
+
for(let i=0;i<n;i++){
|
|
10656
|
+
const v=values[idx[i]];
|
|
10657
|
+
let c=codeOf.get(v);
|
|
10658
|
+
if(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}
|
|
10659
|
+
codes[i]=c;
|
|
10660
|
+
}
|
|
10661
|
+
const d=table.length;
|
|
10662
|
+
const ranks=collateStringRanks(table,d,opts.locale);
|
|
10663
|
+
return rankSortStrings(idx,codes,ranks,d,!!opts.descending);
|
|
10664
|
+
}
|
|
10665
|
+
function sortByComparator(handle,idx,opts){
|
|
10666
|
+
const values=indexableValues(handle,idx);
|
|
10667
|
+
if(idx.length>=2&&allStrings(values,idx)){
|
|
10668
|
+
const index=handle.stringRank;
|
|
10669
|
+
if(index&&index.version===handle.version&&index.usable(idx,values,opts.locale)){
|
|
10670
|
+
return index.sort(idx,opts);
|
|
10671
|
+
}
|
|
10672
|
+
return keyedSortStrings(values,idx,opts);
|
|
10673
|
+
}
|
|
10674
|
+
const base=valueComparator(opts.locale);
|
|
10675
|
+
const compare=opts.descending?(a,b)=>base(b,a):base;
|
|
10676
|
+
return mergeSortComparator(values,idx,compare);
|
|
10677
|
+
}
|
|
10678
|
+
function sortByCompare(handle,idx,opts){
|
|
10679
|
+
const values=indexableValues(handle,idx);
|
|
10680
|
+
const user=opts.compare;
|
|
10681
|
+
const descending=!!opts.descending;
|
|
10682
|
+
const compare=descending
|
|
10683
|
+
?(a,b)=>-user(a,b,undefined,undefined,true)
|
|
10684
|
+
:(a,b)=>user(a,b,undefined,undefined,false);
|
|
10685
|
+
return mergeSortComparator(values,idx,compare);
|
|
10686
|
+
}
|
|
10687
|
+
function partitionPresent(handle,idx){
|
|
10688
|
+
const n=idx.length;
|
|
10689
|
+
const present=presenceReader(handle);
|
|
10690
|
+
const values=handle.values;
|
|
10691
|
+
const checkNaN=handle.kind==='float64'&&!!values;
|
|
10692
|
+
const looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;
|
|
10693
|
+
if(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};
|
|
10694
|
+
const keep=new Uint32Array(n);
|
|
10695
|
+
const drop=new Uint32Array(n);
|
|
10696
|
+
let p=0;
|
|
10697
|
+
let a=0;
|
|
10698
|
+
if(present&&checkNaN){
|
|
10699
|
+
for(let i=0;i<n;i++){
|
|
10700
|
+
const row=idx[i];
|
|
10701
|
+
if(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
|
|
10702
|
+
}
|
|
10703
|
+
}else if(checkNaN&&!present){
|
|
10704
|
+
for(let i=0;i<n;i++){
|
|
10705
|
+
const row=idx[i];
|
|
10706
|
+
if(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
|
|
10707
|
+
}
|
|
10708
|
+
}else if(present&&!looseKind){
|
|
10709
|
+
for(let i=0;i<n;i++){
|
|
10710
|
+
const row=idx[i];
|
|
10711
|
+
if(present(row)===1)keep[p++]=row;else drop[a++]=row;
|
|
10712
|
+
}
|
|
10713
|
+
}else{
|
|
10714
|
+
const reader=valueReader(handle);
|
|
10715
|
+
for(let i=0;i<n;i++){
|
|
10716
|
+
const row=idx[i];
|
|
10717
|
+
if(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;
|
|
10718
|
+
}
|
|
10719
|
+
}
|
|
10720
|
+
if(a===0)return{present:idx,absent:EMPTY_INDICES};
|
|
10721
|
+
return{present:keep.subarray(0,p),absent:drop.subarray(0,a)};
|
|
10722
|
+
}
|
|
10723
|
+
function joinRuns(sorted,absent,nullsFirst){
|
|
10724
|
+
if(absent.length===0)return sorted;
|
|
10725
|
+
const out=new Uint32Array(sorted.length+absent.length);
|
|
10726
|
+
if(nullsFirst){
|
|
10727
|
+
out.set(absent,0);
|
|
10728
|
+
out.set(sorted,absent.length);
|
|
10729
|
+
}else{
|
|
10730
|
+
out.set(sorted,0);
|
|
10731
|
+
out.set(absent,sorted.length);
|
|
10732
|
+
}
|
|
10733
|
+
return out;
|
|
10734
|
+
}
|
|
10735
|
+
function sortColumn(handle,order,opts={}){
|
|
10736
|
+
const src=order||identity(rowCount(handle,opts));
|
|
10737
|
+
if(!handle||src.length<2)return Uint32Array.from(src);
|
|
10738
|
+
const{present,absent}=partitionPresent(handle,src);
|
|
10739
|
+
if(present.length===0)return Uint32Array.from(src);
|
|
10740
|
+
const descending=!!opts.descending;
|
|
10741
|
+
let sorted;
|
|
10742
|
+
if(typeof opts.compare==='function'){
|
|
10743
|
+
sorted=sortByCompare(handle,present,opts);
|
|
10744
|
+
}else{
|
|
10745
|
+
switch(handle.kind){
|
|
10746
|
+
case'float64':
|
|
10747
|
+
sorted=radixSortFloat64(handle.values,present,descending);
|
|
10748
|
+
break;
|
|
10749
|
+
case'int32':
|
|
10750
|
+
sorted=radixSortInt32(handle.values,present,descending);
|
|
10751
|
+
break;
|
|
10752
|
+
case'dictionary':
|
|
10753
|
+
sorted=rankSortDictionary(handle,present,opts);
|
|
10754
|
+
break;
|
|
10755
|
+
case'bitset':
|
|
10756
|
+
sorted=sortBitsetColumn(handle,present,descending);
|
|
10757
|
+
break;
|
|
10758
|
+
default:
|
|
10759
|
+
sorted=sortByComparator(handle,present,opts);
|
|
10760
|
+
break;
|
|
10761
|
+
}
|
|
10762
|
+
}
|
|
10763
|
+
return joinRuns(sorted,absent,!!opts.nullsFirst);
|
|
10764
|
+
}
|
|
10765
|
+
function sortMulti(handles,entries,order,opts={}){
|
|
10766
|
+
const list=entries||[];
|
|
10767
|
+
const first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);
|
|
10768
|
+
let current=order||identity(rowCount(first,opts));
|
|
10769
|
+
for(let i=list.length-1;i>=0;i--){
|
|
10770
|
+
const entry=list[i];
|
|
10771
|
+
const handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);
|
|
10772
|
+
if(!handle)continue;
|
|
10773
|
+
current=sortColumn(handle,current,{
|
|
10774
|
+
descending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',
|
|
10775
|
+
nullsFirst:!!entry.nullsFirst,
|
|
10776
|
+
locale:entry.locale!==undefined?entry.locale:opts.locale,
|
|
10777
|
+
compare:entry.compare,
|
|
10778
|
+
});
|
|
10779
|
+
}
|
|
10780
|
+
return current instanceof Uint32Array?current:Uint32Array.from(current);
|
|
10781
|
+
}
|
|
10782
|
+
function byId(handles,id){
|
|
10783
|
+
if(!handles||id===undefined)return undefined;
|
|
10784
|
+
for(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];
|
|
10785
|
+
return undefined;
|
|
10786
|
+
}
|
|
10787
|
+
});
|
|
10788
|
+
__def("packages/core/src/store/stringrank.js",function(__exports,__req){
|
|
10789
|
+
'use strict';
|
|
10790
|
+
Object.defineProperty(__exports,"DEFAULT_MAX_DISTINCT",{enumerable:true,get:function(){return DEFAULT_MAX_DISTINCT;}});
|
|
10791
|
+
Object.defineProperty(__exports,"StringRankIndex",{enumerable:true,get:function(){return StringRankIndex;}});
|
|
10792
|
+
const __m0=__req("packages/core/src/compute/sort.js");
|
|
10793
|
+
const collateStringRanks=__m0["collateStringRanks"];
|
|
10794
|
+
const rankSortStrings=__m0["rankSortStrings"];
|
|
10795
|
+
const DEFAULT_MAX_DISTINCT=100000;
|
|
10796
|
+
class StringRankIndex{
|
|
10797
|
+
#table=[];
|
|
10798
|
+
#codeOf=new Map();
|
|
10799
|
+
#codeByRow;
|
|
10800
|
+
#length=0;
|
|
10801
|
+
#generation=0;
|
|
10802
|
+
#stamp=-1;
|
|
10803
|
+
#maxDistinct;
|
|
10804
|
+
#capped=false;
|
|
10805
|
+
#ranks=null;
|
|
10806
|
+
#ranksGeneration=-1;
|
|
10807
|
+
#ranksLocale='\u0000';
|
|
10808
|
+
constructor(maxDistinct=DEFAULT_MAX_DISTINCT){
|
|
10809
|
+
this.#maxDistinct=maxDistinct>0?maxDistinct:DEFAULT_MAX_DISTINCT;
|
|
10810
|
+
this.#codeByRow=new Uint32Array(0);
|
|
10811
|
+
}
|
|
10812
|
+
get version(){return this.#stamp;}
|
|
10813
|
+
set version(version){this.#stamp=version;}
|
|
10814
|
+
get generation(){return this.#generation;}
|
|
10815
|
+
get size(){return this.#table.length;}
|
|
10816
|
+
get capped(){return this.#capped;}
|
|
10817
|
+
get length(){return this.#length;}
|
|
10818
|
+
get bytes(){
|
|
10819
|
+
let total=this.#codeByRow.byteLength;
|
|
10820
|
+
const table=this.#table;
|
|
10821
|
+
for(let i=0;i<table.length;i++)total+=table[i].length*2+24;
|
|
10822
|
+
return total;
|
|
10823
|
+
}
|
|
10824
|
+
#intern(value,capOnGrowth){
|
|
10825
|
+
const existing=this.#codeOf.get(value);
|
|
10826
|
+
if(existing!==undefined)return existing;
|
|
10827
|
+
if(this.#capped)return-1;
|
|
10828
|
+
if(capOnGrowth&&this.#table.length>=this.#maxDistinct){
|
|
10829
|
+
this.#capped=true;
|
|
10830
|
+
return-1;
|
|
10831
|
+
}
|
|
10832
|
+
const code=this.#table.length;
|
|
10833
|
+
this.#table.push(value);
|
|
10834
|
+
this.#codeOf.set(value,code);
|
|
10835
|
+
this.#generation++;
|
|
10836
|
+
return code;
|
|
10837
|
+
}
|
|
10838
|
+
build(values,count){
|
|
10839
|
+
const n=count|0;
|
|
10840
|
+
this.#table=[];
|
|
10841
|
+
this.#codeOf=new Map();
|
|
10842
|
+
this.#generation=0;
|
|
10843
|
+
this.#capped=false;
|
|
10844
|
+
this.#ranks=null;
|
|
10845
|
+
this.#ranksGeneration=-1;
|
|
10846
|
+
this.#codeByRow=new Uint32Array(n);
|
|
10847
|
+
for(let row=0;row<n;row++){
|
|
10848
|
+
const v=values[row];
|
|
10849
|
+
const code=typeof v==='string'?this.#intern(v,false):-1;
|
|
10850
|
+
this.#codeByRow[row]=code<0?0:code;
|
|
10851
|
+
}
|
|
10852
|
+
this.#length=n;
|
|
10853
|
+
}
|
|
10854
|
+
append(values,from,count){
|
|
10855
|
+
const to=(from|0)+(count|0);
|
|
10856
|
+
if(to>this.#codeByRow.length){
|
|
10857
|
+
const next=new Uint32Array(to);
|
|
10858
|
+
next.set(this.#codeByRow.subarray(0,this.#length));
|
|
10859
|
+
this.#codeByRow=next;
|
|
10860
|
+
}
|
|
10861
|
+
for(let row=from|0;row<to;row++){
|
|
10862
|
+
const v=values[row];
|
|
10863
|
+
const code=typeof v==='string'?this.#intern(v,true):-1;
|
|
10864
|
+
this.#codeByRow[row]=code<0?0:code;
|
|
10865
|
+
}
|
|
10866
|
+
this.#length=Math.max(this.#length,to);
|
|
10867
|
+
}
|
|
10868
|
+
ranks(locale){
|
|
10869
|
+
const key=locale||'';
|
|
10870
|
+
if(this.#ranks&&this.#ranksGeneration===this.#generation&&this.#ranksLocale===key){
|
|
10871
|
+
return this.#ranks;
|
|
10872
|
+
}
|
|
10873
|
+
const ranks=collateStringRanks(this.#table,this.#table.length,locale);
|
|
10874
|
+
this.#ranks=ranks;
|
|
10875
|
+
this.#ranksGeneration=this.#generation;
|
|
10876
|
+
this.#ranksLocale=key;
|
|
10877
|
+
return ranks;
|
|
10878
|
+
}
|
|
10879
|
+
usable(idx,values,locale){
|
|
10880
|
+
if(this.#capped||this.#table.length===0)return false;
|
|
10881
|
+
const codeByRow=this.#codeByRow;
|
|
10882
|
+
const table=this.#table;
|
|
10883
|
+
const covered=this.#length;
|
|
10884
|
+
for(let i=0;i<idx.length;i++){
|
|
10885
|
+
const row=idx[i];
|
|
10886
|
+
if(row>=covered)return false;
|
|
10887
|
+
if(table[codeByRow[row]]!==values[row])return false;
|
|
10888
|
+
}
|
|
10889
|
+
return true;
|
|
10890
|
+
}
|
|
10891
|
+
sort(idx,opts){
|
|
10892
|
+
const ranks=this.ranks(opts.locale);
|
|
10893
|
+
const d=this.#table.length;
|
|
10894
|
+
const n=idx.length;
|
|
10895
|
+
const codes=new Uint32Array(n);
|
|
10896
|
+
const codeByRow=this.#codeByRow;
|
|
10897
|
+
for(let i=0;i<n;i++)codes[i]=codeByRow[idx[i]];
|
|
10898
|
+
return rankSortStrings(idx,codes,ranks,d,!!opts.descending);
|
|
10899
|
+
}
|
|
10900
|
+
}
|
|
10901
|
+
});
|
|
10222
10902
|
__def("packages/core/src/store/columnstore.js",function(__exports,__req){
|
|
10223
10903
|
'use strict';
|
|
10224
10904
|
Object.defineProperty(__exports,"REMOVED",{enumerable:true,get:function(){return REMOVED;}});
|
|
@@ -10235,6 +10915,8 @@ const __m2=__req("packages/core/src/store/dictionary.js");
|
|
|
10235
10915
|
const Dictionary=__m2["Dictionary"];
|
|
10236
10916
|
const __m3=__req("packages/core/src/store/multivalue.js");
|
|
10237
10917
|
const MultiValue=__m3["MultiValue"];
|
|
10918
|
+
const __m4=__req("packages/core/src/store/stringrank.js");
|
|
10919
|
+
const StringRankIndex=__m4["StringRankIndex"];
|
|
10238
10920
|
const REMOVED=0xFFFFFFFF;
|
|
10239
10921
|
const DEFAULT_CAPACITY=1024;
|
|
10240
10922
|
const DEFAULT_COLUMNAR_BELOW=5000;
|
|
@@ -10301,6 +10983,10 @@ class ColumnHandle{
|
|
|
10301
10983
|
#bits=null;
|
|
10302
10984
|
#mv=null;
|
|
10303
10985
|
#dict=null;
|
|
10986
|
+
#stringRank=null;
|
|
10987
|
+
#stringRankOn;
|
|
10988
|
+
#stringRankMax;
|
|
10989
|
+
#stringRankVersion=-1;
|
|
10304
10990
|
#presence=null;
|
|
10305
10991
|
#capacity=0;
|
|
10306
10992
|
#version=0;
|
|
@@ -10322,6 +11008,10 @@ this.#host=host;
|
|
|
10322
11008
|
this.#read=isFunction(schema.read)
|
|
10323
11009
|
?schema.read
|
|
10324
11010
|
:pathGetter(schema.field||schema.id);
|
|
11011
|
+
this.#stringRankOn=schema.stringRankIndex!=='off';
|
|
11012
|
+
this.#stringRankMax=typeof schema.stringRankMaxDistinct==='number'
|
|
11013
|
+
?schema.stringRankMaxDistinct
|
|
11014
|
+
:0;
|
|
10325
11015
|
this.#overlay=new Map();
|
|
10326
11016
|
}
|
|
10327
11017
|
get id(){return this.#id;}
|
|
@@ -10343,6 +11033,33 @@ get dict(){
|
|
|
10343
11033
|
if(this.#released||!this.#columnar)return null;
|
|
10344
11034
|
return this.#kind==='dictionary'||this.#kind==='multi'?this.#dict:null;
|
|
10345
11035
|
}
|
|
11036
|
+
get stringRank(){
|
|
11037
|
+
if(this.#released||!this.#stringRankOn)return null;
|
|
11038
|
+
if(this.kind!=='object')return null;
|
|
11039
|
+
const values=this.values;
|
|
11040
|
+
const n=this.#host.physical();
|
|
11041
|
+
if(!values||n===0)return null;
|
|
11042
|
+
if(this.#stringRank===null){
|
|
11043
|
+
if(typeof values[0]!=='string')return null;
|
|
11044
|
+
const index=new StringRankIndex(this.#resolveStringRankMax());
|
|
11045
|
+
index.build(values,n);
|
|
11046
|
+
index.version=this.#version;
|
|
11047
|
+
this.#stringRank=index;
|
|
11048
|
+
this.#stringRankVersion=this.#version;
|
|
11049
|
+
return index.capped?null:index;
|
|
11050
|
+
}
|
|
11051
|
+
if(this.#stringRank.length<n){
|
|
11052
|
+
this.#stringRank.append(values,this.#stringRank.length,n-this.#stringRank.length);
|
|
11053
|
+
}
|
|
11054
|
+
this.#stringRank.version=this.#version;
|
|
11055
|
+
this.#stringRankVersion=this.#version;
|
|
11056
|
+
return this.#stringRank.capped?null:this.#stringRank;
|
|
11057
|
+
}
|
|
11058
|
+
#resolveStringRankMax(){return this.#stringRankMax;}
|
|
11059
|
+
#dropStringRank(){
|
|
11060
|
+
this.#stringRank=null;
|
|
11061
|
+
this.#stringRankVersion=-1;
|
|
11062
|
+
}
|
|
10346
11063
|
get offsets(){
|
|
10347
11064
|
if(this.#released||!this.#columnar||this.#kind!=='multi')return null;
|
|
10348
11065
|
return this.#mv.offsets;
|
|
@@ -10381,6 +11098,7 @@ set(physical,value){
|
|
|
10381
11098
|
if(this.#released)return;
|
|
10382
11099
|
if(this.#columnar)this.#writeValue(physical,value);
|
|
10383
11100
|
else this.#overlay.set(physical,value===undefined?null:value);
|
|
11101
|
+
if(this.#stringRank)this.#dropStringRank();
|
|
10384
11102
|
this.#version++;
|
|
10385
11103
|
}
|
|
10386
11104
|
read(row){return this.#read(row);}
|
|
@@ -10473,6 +11191,11 @@ if(sawAbsent){
|
|
|
10473
11191
|
warnOnce(`store.null.${this.#id}`,
|
|
10474
11192
|
`column "${this.#id}" is declared non-nullable but received null; storing a filler value`);
|
|
10475
11193
|
}
|
|
11194
|
+
if(this.#stringRank&&this.#kind==='object'){
|
|
11195
|
+
this.#stringRank.append(this.#buf,from,n);
|
|
11196
|
+
this.#stringRank.version=this.#version+1;
|
|
11197
|
+
this.#stringRankVersion=this.#version+1;
|
|
11198
|
+
}
|
|
10476
11199
|
this.#version++;
|
|
10477
11200
|
}
|
|
10478
11201
|
appendPacked(frag,from,n){
|
|
@@ -10548,6 +11271,7 @@ this.#alloc(capacity);
|
|
|
10548
11271
|
for(let p=0;p<fill;p++)this.#writeValue(p,values[p]);
|
|
10549
11272
|
this.#overlay.clear();
|
|
10550
11273
|
this.#cache=null;
|
|
11274
|
+
this.#dropStringRank();
|
|
10551
11275
|
this.#version++;
|
|
10552
11276
|
}
|
|
10553
11277
|
grow(capacity){
|
|
@@ -10581,11 +11305,13 @@ const gone=presence!==null&&presence.get(p)===0;
|
|
|
10581
11305
|
if(gone&&kind!=='multi')continue;
|
|
10582
11306
|
this.#writeValue(p,gone?null:decodeFrom(old,p));
|
|
10583
11307
|
}
|
|
11308
|
+
this.#dropStringRank();
|
|
10584
11309
|
this.#version++;
|
|
10585
11310
|
return true;
|
|
10586
11311
|
}
|
|
10587
11312
|
compact(remap,oldFill,liveCount){
|
|
10588
11313
|
if(this.#released)return;
|
|
11314
|
+
this.#dropStringRank();
|
|
10589
11315
|
if(!this.#columnar){
|
|
10590
11316
|
const overlay=this.#overlay;
|
|
10591
11317
|
if(overlay.size){
|
|
@@ -10631,6 +11357,7 @@ this.#mv=null;
|
|
|
10631
11357
|
if(this.#presence)this.#presence.release();
|
|
10632
11358
|
this.#presence=null;
|
|
10633
11359
|
this.#dict=null;
|
|
11360
|
+
this.#stringRank=null;
|
|
10634
11361
|
this.#overlay=new Map();
|
|
10635
11362
|
this.#cache=null;
|
|
10636
11363
|
this.#capacity=0;
|
|
@@ -10979,418 +11706,6 @@ return shared;
|
|
|
10979
11706
|
}
|
|
10980
11707
|
let shared=null;
|
|
10981
11708
|
});
|
|
10982
|
-
__def("packages/core/src/compute/sort.js",function(__exports,__req){
|
|
10983
|
-
'use strict';
|
|
10984
|
-
Object.defineProperty(__exports,"radixSortFloat64",{enumerable:true,get:function(){return radixSortFloat64;}});
|
|
10985
|
-
Object.defineProperty(__exports,"radixSortInt32",{enumerable:true,get:function(){return radixSortInt32;}});
|
|
10986
|
-
Object.defineProperty(__exports,"rankSortDictionary",{enumerable:true,get:function(){return rankSortDictionary;}});
|
|
10987
|
-
Object.defineProperty(__exports,"mergeSortComparator",{enumerable:true,get:function(){return mergeSortComparator;}});
|
|
10988
|
-
Object.defineProperty(__exports,"sortColumn",{enumerable:true,get:function(){return sortColumn;}});
|
|
10989
|
-
Object.defineProperty(__exports,"sortMulti",{enumerable:true,get:function(){return sortMulti;}});
|
|
10990
|
-
const __m0=__req("packages/core/src/compute/handle.js");
|
|
10991
|
-
const bitReader=__m0["bitReader"];
|
|
10992
|
-
const dictRanks=__m0["dictRanks"];
|
|
10993
|
-
const dictSize=__m0["dictSize"];
|
|
10994
|
-
const identity=__m0["identity"];
|
|
10995
|
-
const isMissing=__m0["isMissing"];
|
|
10996
|
-
const presenceReader=__m0["presenceReader"];
|
|
10997
|
-
const rowCount=__m0["rowCount"];
|
|
10998
|
-
const valueComparator=__m0["valueComparator"];
|
|
10999
|
-
const valueReader=__m0["valueReader"];
|
|
11000
|
-
const EMPTY_INDICES=new Uint32Array(0);
|
|
11001
|
-
const SCRATCH=new ArrayBuffer(8);
|
|
11002
|
-
const SCRATCH_F64=new Float64Array(SCRATCH);
|
|
11003
|
-
const SCRATCH_U32=new Uint32Array(SCRATCH);
|
|
11004
|
-
const HI=(()=>{
|
|
11005
|
-
SCRATCH_F64[0]=-1;
|
|
11006
|
-
return(SCRATCH_U32[1]&0x80000000)!==0?1:0;
|
|
11007
|
-
})();
|
|
11008
|
-
const LO=HI===1?0:1;
|
|
11009
|
-
function transformDouble(value,out){
|
|
11010
|
-
SCRATCH_F64[0]=value;
|
|
11011
|
-
let hi=SCRATCH_U32[HI];
|
|
11012
|
-
let lo=SCRATCH_U32[LO];
|
|
11013
|
-
if((hi&0x80000000)!==0){
|
|
11014
|
-
hi=~hi>>>0;
|
|
11015
|
-
lo=~lo>>>0;
|
|
11016
|
-
}else{
|
|
11017
|
-
hi=(hi^0x80000000)>>>0;
|
|
11018
|
-
}
|
|
11019
|
-
out[0]=lo;
|
|
11020
|
-
out[1]=hi;
|
|
11021
|
-
}
|
|
11022
|
-
function radixLsd64(idx,lo,hi,n){
|
|
11023
|
-
if(n<2)return idx;
|
|
11024
|
-
const hist=new Uint32Array(256*8);
|
|
11025
|
-
for(let i=0;i<n;i++){
|
|
11026
|
-
const l=lo[i];
|
|
11027
|
-
const h=hi[i];
|
|
11028
|
-
hist[l&0xff]++;
|
|
11029
|
-
hist[256+((l>>>8)&0xff)]++;
|
|
11030
|
-
hist[512+((l>>>16)&0xff)]++;
|
|
11031
|
-
hist[768+((l>>>24)&0xff)]++;
|
|
11032
|
-
hist[1024+(h&0xff)]++;
|
|
11033
|
-
hist[1280+((h>>>8)&0xff)]++;
|
|
11034
|
-
hist[1536+((h>>>16)&0xff)]++;
|
|
11035
|
-
hist[1792+((h>>>24)&0xff)]++;
|
|
11036
|
-
}
|
|
11037
|
-
let srcIdx=idx;
|
|
11038
|
-
let srcLo=lo;
|
|
11039
|
-
let srcHi=hi;
|
|
11040
|
-
let dstIdx=new Uint32Array(n);
|
|
11041
|
-
let dstLo=new Uint32Array(n);
|
|
11042
|
-
let dstHi=new Uint32Array(n);
|
|
11043
|
-
const offset=new Uint32Array(256);
|
|
11044
|
-
for(let pass=0;pass<8;pass++){
|
|
11045
|
-
const base=pass<<8;
|
|
11046
|
-
const shift=(pass&3)<<3;
|
|
11047
|
-
const useHi=pass>=4;
|
|
11048
|
-
let skip=false;
|
|
11049
|
-
for(let b=0;b<256;b++){
|
|
11050
|
-
if(hist[base+b]===n){skip=true;break;}
|
|
11051
|
-
}
|
|
11052
|
-
if(skip)continue;
|
|
11053
|
-
let sum=0;
|
|
11054
|
-
for(let b=0;b<256;b++){
|
|
11055
|
-
offset[b]=sum;
|
|
11056
|
-
sum+=hist[base+b];
|
|
11057
|
-
}
|
|
11058
|
-
for(let i=0;i<n;i++){
|
|
11059
|
-
const l=srcLo[i];
|
|
11060
|
-
const h=srcHi[i];
|
|
11061
|
-
const digit=((useHi?h:l)>>>shift)&0xff;
|
|
11062
|
-
const p=offset[digit]++;
|
|
11063
|
-
dstIdx[p]=srcIdx[i];
|
|
11064
|
-
dstLo[p]=l;
|
|
11065
|
-
dstHi[p]=h;
|
|
11066
|
-
}
|
|
11067
|
-
let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
|
|
11068
|
-
t=srcLo;srcLo=dstLo;dstLo=t;
|
|
11069
|
-
t=srcHi;srcHi=dstHi;dstHi=t;
|
|
11070
|
-
}
|
|
11071
|
-
return srcIdx;
|
|
11072
|
-
}
|
|
11073
|
-
function radixLsd32(idx,keys,n){
|
|
11074
|
-
if(n<2)return idx;
|
|
11075
|
-
const hist=new Uint32Array(256*4);
|
|
11076
|
-
for(let i=0;i<n;i++){
|
|
11077
|
-
const k=keys[i];
|
|
11078
|
-
hist[k&0xff]++;
|
|
11079
|
-
hist[256+((k>>>8)&0xff)]++;
|
|
11080
|
-
hist[512+((k>>>16)&0xff)]++;
|
|
11081
|
-
hist[768+((k>>>24)&0xff)]++;
|
|
11082
|
-
}
|
|
11083
|
-
let srcIdx=idx;
|
|
11084
|
-
let srcKeys=keys;
|
|
11085
|
-
let dstIdx=new Uint32Array(n);
|
|
11086
|
-
let dstKeys=new Uint32Array(n);
|
|
11087
|
-
const offset=new Uint32Array(256);
|
|
11088
|
-
for(let pass=0;pass<4;pass++){
|
|
11089
|
-
const base=pass<<8;
|
|
11090
|
-
const shift=pass<<3;
|
|
11091
|
-
let skip=false;
|
|
11092
|
-
for(let b=0;b<256;b++){
|
|
11093
|
-
if(hist[base+b]===n){skip=true;break;}
|
|
11094
|
-
}
|
|
11095
|
-
if(skip)continue;
|
|
11096
|
-
let sum=0;
|
|
11097
|
-
for(let b=0;b<256;b++){
|
|
11098
|
-
offset[b]=sum;
|
|
11099
|
-
sum+=hist[base+b];
|
|
11100
|
-
}
|
|
11101
|
-
for(let i=0;i<n;i++){
|
|
11102
|
-
const k=srcKeys[i];
|
|
11103
|
-
const p=offset[(k>>>shift)&0xff]++;
|
|
11104
|
-
dstIdx[p]=srcIdx[i];
|
|
11105
|
-
dstKeys[p]=k;
|
|
11106
|
-
}
|
|
11107
|
-
let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
|
|
11108
|
-
t=srcKeys;srcKeys=dstKeys;dstKeys=t;
|
|
11109
|
-
}
|
|
11110
|
-
return srcIdx;
|
|
11111
|
-
}
|
|
11112
|
-
function countingSort(idx,keys,n,radix){
|
|
11113
|
-
const counts=new Uint32Array(radix+1);
|
|
11114
|
-
for(let i=0;i<n;i++)counts[keys[i]]++;
|
|
11115
|
-
let sum=0;
|
|
11116
|
-
for(let k=0;k<=radix;k++){
|
|
11117
|
-
const c=counts[k];
|
|
11118
|
-
counts[k]=sum;
|
|
11119
|
-
sum+=c;
|
|
11120
|
-
}
|
|
11121
|
-
const out=new Uint32Array(n);
|
|
11122
|
-
for(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];
|
|
11123
|
-
return out;
|
|
11124
|
-
}
|
|
11125
|
-
function sortUint32Keys(idx,keys,n,radix){
|
|
11126
|
-
if(n<2)return idx;
|
|
11127
|
-
if(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);
|
|
11128
|
-
return radixLsd32(idx,keys,n);
|
|
11129
|
-
}
|
|
11130
|
-
function exact(buffer,n){
|
|
11131
|
-
if(buffer.length===n&&buffer.byteOffset===0)return buffer;
|
|
11132
|
-
return Uint32Array.prototype.slice.call(buffer,0,n);
|
|
11133
|
-
}
|
|
11134
|
-
function radixSortFloat64(values,order,descending=false){
|
|
11135
|
-
const src=order||identity(values.length);
|
|
11136
|
-
const n=src.length;
|
|
11137
|
-
if(n<2)return Uint32Array.from(src);
|
|
11138
|
-
const idx=new Uint32Array(n);
|
|
11139
|
-
const lo=new Uint32Array(n);
|
|
11140
|
-
const hi=new Uint32Array(n);
|
|
11141
|
-
const nans=new Uint32Array(n);
|
|
11142
|
-
const pair=new Uint32Array(2);
|
|
11143
|
-
let m=0;
|
|
11144
|
-
let nanCount=0;
|
|
11145
|
-
for(let i=0;i<n;i++){
|
|
11146
|
-
const row=src[i];
|
|
11147
|
-
const v=values[row];
|
|
11148
|
-
if(Number.isNaN(v)){nans[nanCount++]=row;continue;}
|
|
11149
|
-
transformDouble(v,pair);
|
|
11150
|
-
if(descending){
|
|
11151
|
-
lo[m]=~pair[0]>>>0;
|
|
11152
|
-
hi[m]=~pair[1]>>>0;
|
|
11153
|
-
}else{
|
|
11154
|
-
lo[m]=pair[0];
|
|
11155
|
-
hi[m]=pair[1];
|
|
11156
|
-
}
|
|
11157
|
-
idx[m++]=row;
|
|
11158
|
-
}
|
|
11159
|
-
const sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);
|
|
11160
|
-
if(nanCount===0)return exact(sorted,m);
|
|
11161
|
-
const out=new Uint32Array(n);
|
|
11162
|
-
out.set(sorted.subarray(0,m),0);
|
|
11163
|
-
out.set(nans.subarray(0,nanCount),m);
|
|
11164
|
-
return out;
|
|
11165
|
-
}
|
|
11166
|
-
function radixSortInt32(values,order,descending=false){
|
|
11167
|
-
const src=order||identity(values.length);
|
|
11168
|
-
const n=src.length;
|
|
11169
|
-
if(n<2)return Uint32Array.from(src);
|
|
11170
|
-
const idx=Uint32Array.from(src);
|
|
11171
|
-
const keys=new Uint32Array(n);
|
|
11172
|
-
for(let i=0;i<n;i++){
|
|
11173
|
-
const k=(values[idx[i]]^0x80000000)>>>0;
|
|
11174
|
-
keys[i]=descending?(~k>>>0):k;
|
|
11175
|
-
}
|
|
11176
|
-
return exact(radixLsd32(idx,keys,n),n);
|
|
11177
|
-
}
|
|
11178
|
-
function rankSortDictionary(handle,order,opts={}){
|
|
11179
|
-
const src=order||identity(rowCount(handle,opts));
|
|
11180
|
-
const n=src.length;
|
|
11181
|
-
if(n<2)return Uint32Array.from(src);
|
|
11182
|
-
const ranks=dictRanks(handle.dict,opts.locale);
|
|
11183
|
-
const codes=handle.values;
|
|
11184
|
-
const present=presenceReader(handle);
|
|
11185
|
-
const size=Math.max(dictSize(handle.dict),ranks.length);
|
|
11186
|
-
const absentRank=size;
|
|
11187
|
-
const idx=Uint32Array.from(src);
|
|
11188
|
-
const keys=new Uint32Array(n);
|
|
11189
|
-
const descending=!!opts.descending;
|
|
11190
|
-
for(let i=0;i<n;i++){
|
|
11191
|
-
const row=idx[i];
|
|
11192
|
-
let rank=present&&present(row)===0?absentRank:ranks[codes[row]];
|
|
11193
|
-
if(rank===undefined)rank=absentRank;
|
|
11194
|
-
keys[i]=descending?absentRank-rank:rank;
|
|
11195
|
-
}
|
|
11196
|
-
return exact(sortUint32Keys(idx,keys,n,size+1),n);
|
|
11197
|
-
}
|
|
11198
|
-
function mergeSortComparator(values,order,compare){
|
|
11199
|
-
const n=order.length;
|
|
11200
|
-
let src=Uint32Array.from(order);
|
|
11201
|
-
if(n<2)return src;
|
|
11202
|
-
let dst=new Uint32Array(n);
|
|
11203
|
-
for(let width=1;width<n;width<<=1){
|
|
11204
|
-
for(let start=0;start<n;start+=width<<1){
|
|
11205
|
-
const mid=Math.min(start+width,n);
|
|
11206
|
-
const end=Math.min(start+(width<<1),n);
|
|
11207
|
-
let i=start;
|
|
11208
|
-
let j=mid;
|
|
11209
|
-
let k=start;
|
|
11210
|
-
while(i<mid&&j<end){
|
|
11211
|
-
dst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];
|
|
11212
|
-
}
|
|
11213
|
-
while(i<mid)dst[k++]=src[i++];
|
|
11214
|
-
while(j<end)dst[k++]=src[j++];
|
|
11215
|
-
}
|
|
11216
|
-
const t=src;src=dst;dst=t;
|
|
11217
|
-
}
|
|
11218
|
-
return src;
|
|
11219
|
-
}
|
|
11220
|
-
function sortBitsetColumn(handle,idx,descending){
|
|
11221
|
-
const bit=bitReader(handle.values);
|
|
11222
|
-
const n=idx.length;
|
|
11223
|
-
const out=new Uint32Array(n);
|
|
11224
|
-
const first=descending?1:0;
|
|
11225
|
-
let k=0;
|
|
11226
|
-
for(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];
|
|
11227
|
-
for(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];
|
|
11228
|
-
return out;
|
|
11229
|
-
}
|
|
11230
|
-
function indexableValues(handle,idx){
|
|
11231
|
-
const values=handle.values;
|
|
11232
|
-
const kind=handle.kind;
|
|
11233
|
-
const direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));
|
|
11234
|
-
if(direct&&!handle.presence)return values;
|
|
11235
|
-
const reader=valueReader(handle);
|
|
11236
|
-
const materialised=new Array(rowCount(handle)||0);
|
|
11237
|
-
for(let i=0;i<idx.length;i++){
|
|
11238
|
-
const row=idx[i];
|
|
11239
|
-
materialised[row]=reader(row);
|
|
11240
|
-
}
|
|
11241
|
-
return materialised;
|
|
11242
|
-
}
|
|
11243
|
-
function allStrings(values,idx){
|
|
11244
|
-
for(let i=0;i<idx.length;i++){
|
|
11245
|
-
if(typeof values[idx[i]]!=='string')return false;
|
|
11246
|
-
}
|
|
11247
|
-
return true;
|
|
11248
|
-
}
|
|
11249
|
-
function keyedSortStrings(values,idx,opts){
|
|
11250
|
-
const n=idx.length;
|
|
11251
|
-
const codeOf=new Map();
|
|
11252
|
-
const table=[];
|
|
11253
|
-
const codes=new Uint32Array(n);
|
|
11254
|
-
for(let i=0;i<n;i++){
|
|
11255
|
-
const v=values[idx[i]];
|
|
11256
|
-
let c=codeOf.get(v);
|
|
11257
|
-
if(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}
|
|
11258
|
-
codes[i]=c;
|
|
11259
|
-
}
|
|
11260
|
-
const d=table.length;
|
|
11261
|
-
const compare=valueComparator(opts.locale);
|
|
11262
|
-
const order=new Array(d);
|
|
11263
|
-
for(let i=0;i<d;i++)order[i]=i;
|
|
11264
|
-
order.sort((a,b)=>compare(table[a],table[b])||a-b);
|
|
11265
|
-
const ranks=new Uint32Array(d);
|
|
11266
|
-
for(let r=0;r<d;r++)ranks[order[r]]=r;
|
|
11267
|
-
const descending=!!opts.descending;
|
|
11268
|
-
const idxOut=Uint32Array.from(idx);
|
|
11269
|
-
const keys=new Uint32Array(n);
|
|
11270
|
-
const top=d-1;
|
|
11271
|
-
for(let i=0;i<n;i++){
|
|
11272
|
-
const rank=ranks[codes[i]];
|
|
11273
|
-
keys[i]=descending?top-rank:rank;
|
|
11274
|
-
}
|
|
11275
|
-
return exact(sortUint32Keys(idxOut,keys,n,d),n);
|
|
11276
|
-
}
|
|
11277
|
-
function sortByComparator(handle,idx,opts){
|
|
11278
|
-
const values=indexableValues(handle,idx);
|
|
11279
|
-
if(idx.length>=2&&allStrings(values,idx))return keyedSortStrings(values,idx,opts);
|
|
11280
|
-
const base=valueComparator(opts.locale);
|
|
11281
|
-
const compare=opts.descending?(a,b)=>base(b,a):base;
|
|
11282
|
-
return mergeSortComparator(values,idx,compare);
|
|
11283
|
-
}
|
|
11284
|
-
function sortByCompare(handle,idx,opts){
|
|
11285
|
-
const values=indexableValues(handle,idx);
|
|
11286
|
-
const user=opts.compare;
|
|
11287
|
-
const descending=!!opts.descending;
|
|
11288
|
-
const compare=descending
|
|
11289
|
-
?(a,b)=>-user(a,b,undefined,undefined,true)
|
|
11290
|
-
:(a,b)=>user(a,b,undefined,undefined,false);
|
|
11291
|
-
return mergeSortComparator(values,idx,compare);
|
|
11292
|
-
}
|
|
11293
|
-
function partitionPresent(handle,idx){
|
|
11294
|
-
const n=idx.length;
|
|
11295
|
-
const present=presenceReader(handle);
|
|
11296
|
-
const values=handle.values;
|
|
11297
|
-
const checkNaN=handle.kind==='float64'&&!!values;
|
|
11298
|
-
const looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;
|
|
11299
|
-
if(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};
|
|
11300
|
-
const keep=new Uint32Array(n);
|
|
11301
|
-
const drop=new Uint32Array(n);
|
|
11302
|
-
let p=0;
|
|
11303
|
-
let a=0;
|
|
11304
|
-
if(present&&checkNaN){
|
|
11305
|
-
for(let i=0;i<n;i++){
|
|
11306
|
-
const row=idx[i];
|
|
11307
|
-
if(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
|
|
11308
|
-
}
|
|
11309
|
-
}else if(checkNaN&&!present){
|
|
11310
|
-
for(let i=0;i<n;i++){
|
|
11311
|
-
const row=idx[i];
|
|
11312
|
-
if(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
|
|
11313
|
-
}
|
|
11314
|
-
}else if(present&&!looseKind){
|
|
11315
|
-
for(let i=0;i<n;i++){
|
|
11316
|
-
const row=idx[i];
|
|
11317
|
-
if(present(row)===1)keep[p++]=row;else drop[a++]=row;
|
|
11318
|
-
}
|
|
11319
|
-
}else{
|
|
11320
|
-
const reader=valueReader(handle);
|
|
11321
|
-
for(let i=0;i<n;i++){
|
|
11322
|
-
const row=idx[i];
|
|
11323
|
-
if(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;
|
|
11324
|
-
}
|
|
11325
|
-
}
|
|
11326
|
-
if(a===0)return{present:idx,absent:EMPTY_INDICES};
|
|
11327
|
-
return{present:keep.subarray(0,p),absent:drop.subarray(0,a)};
|
|
11328
|
-
}
|
|
11329
|
-
function joinRuns(sorted,absent,nullsFirst){
|
|
11330
|
-
if(absent.length===0)return sorted;
|
|
11331
|
-
const out=new Uint32Array(sorted.length+absent.length);
|
|
11332
|
-
if(nullsFirst){
|
|
11333
|
-
out.set(absent,0);
|
|
11334
|
-
out.set(sorted,absent.length);
|
|
11335
|
-
}else{
|
|
11336
|
-
out.set(sorted,0);
|
|
11337
|
-
out.set(absent,sorted.length);
|
|
11338
|
-
}
|
|
11339
|
-
return out;
|
|
11340
|
-
}
|
|
11341
|
-
function sortColumn(handle,order,opts={}){
|
|
11342
|
-
const src=order||identity(rowCount(handle,opts));
|
|
11343
|
-
if(!handle||src.length<2)return Uint32Array.from(src);
|
|
11344
|
-
const{present,absent}=partitionPresent(handle,src);
|
|
11345
|
-
if(present.length===0)return Uint32Array.from(src);
|
|
11346
|
-
const descending=!!opts.descending;
|
|
11347
|
-
let sorted;
|
|
11348
|
-
if(typeof opts.compare==='function'){
|
|
11349
|
-
sorted=sortByCompare(handle,present,opts);
|
|
11350
|
-
}else{
|
|
11351
|
-
switch(handle.kind){
|
|
11352
|
-
case'float64':
|
|
11353
|
-
sorted=radixSortFloat64(handle.values,present,descending);
|
|
11354
|
-
break;
|
|
11355
|
-
case'int32':
|
|
11356
|
-
sorted=radixSortInt32(handle.values,present,descending);
|
|
11357
|
-
break;
|
|
11358
|
-
case'dictionary':
|
|
11359
|
-
sorted=rankSortDictionary(handle,present,opts);
|
|
11360
|
-
break;
|
|
11361
|
-
case'bitset':
|
|
11362
|
-
sorted=sortBitsetColumn(handle,present,descending);
|
|
11363
|
-
break;
|
|
11364
|
-
default:
|
|
11365
|
-
sorted=sortByComparator(handle,present,opts);
|
|
11366
|
-
break;
|
|
11367
|
-
}
|
|
11368
|
-
}
|
|
11369
|
-
return joinRuns(sorted,absent,!!opts.nullsFirst);
|
|
11370
|
-
}
|
|
11371
|
-
function sortMulti(handles,entries,order,opts={}){
|
|
11372
|
-
const list=entries||[];
|
|
11373
|
-
const first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);
|
|
11374
|
-
let current=order||identity(rowCount(first,opts));
|
|
11375
|
-
for(let i=list.length-1;i>=0;i--){
|
|
11376
|
-
const entry=list[i];
|
|
11377
|
-
const handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);
|
|
11378
|
-
if(!handle)continue;
|
|
11379
|
-
current=sortColumn(handle,current,{
|
|
11380
|
-
descending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',
|
|
11381
|
-
nullsFirst:!!entry.nullsFirst,
|
|
11382
|
-
locale:entry.locale!==undefined?entry.locale:opts.locale,
|
|
11383
|
-
compare:entry.compare,
|
|
11384
|
-
});
|
|
11385
|
-
}
|
|
11386
|
-
return current instanceof Uint32Array?current:Uint32Array.from(current);
|
|
11387
|
-
}
|
|
11388
|
-
function byId(handles,id){
|
|
11389
|
-
if(!handles||id===undefined)return undefined;
|
|
11390
|
-
for(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];
|
|
11391
|
-
return undefined;
|
|
11392
|
-
}
|
|
11393
|
-
});
|
|
11394
11709
|
__def("packages/core/src/compute/filter.js",function(__exports,__req){
|
|
11395
11710
|
'use strict';
|
|
11396
11711
|
Object.defineProperty(__exports,"releaseMask",{enumerable:true,get:function(){return releaseMask;}});
|
|
@@ -12384,7 +12699,9 @@ Object.defineProperty(__exports,"createRowFactory",{enumerable:true,get:function
|
|
|
12384
12699
|
Object.defineProperty(__exports,"RowFactory",{enumerable:true,get:function(){return RowFactory;}});
|
|
12385
12700
|
Object.defineProperty(__exports,"pinnedRow",{enumerable:true,get:function(){return pinnedRow;}});
|
|
12386
12701
|
Object.defineProperty(__exports,"lazyRowView",{enumerable:true,get:function(){return lazyRowView;}});
|
|
12702
|
+
Object.defineProperty(__exports,"groupPathElement",{enumerable:true,get:function(){return groupPathElement;}});
|
|
12387
12703
|
Object.defineProperty(__exports,"groupKey",{enumerable:true,get:function(){return groupKey;}});
|
|
12704
|
+
Object.defineProperty(__exports,"groupPrefixKeys",{enumerable:true,get:function(){return groupPrefixKeys;}});
|
|
12388
12705
|
const __m0=__req("packages/core/src/internal/util.js");
|
|
12389
12706
|
const warnOnce=__m0["warnOnce"];
|
|
12390
12707
|
const isFunction=__m0["isFunction"];
|
|
@@ -12582,8 +12899,20 @@ return Reflect.has(target,prop);
|
|
|
12582
12899
|
},
|
|
12583
12900
|
})));
|
|
12584
12901
|
}
|
|
12902
|
+
function groupPathElement(value){
|
|
12903
|
+
return value===null||value===undefined?'':String(value);
|
|
12904
|
+
}
|
|
12585
12905
|
function groupKey(path){
|
|
12586
|
-
return`g${KEY_SEP}${(path||[]).map(
|
|
12906
|
+
return`g${KEY_SEP}${(path||[]).map(groupPathElement).join(KEY_SEP)}`;
|
|
12907
|
+
}
|
|
12908
|
+
function groupPrefixKeys(path){
|
|
12909
|
+
const keys=new Array(path.length);
|
|
12910
|
+
const acc=[];
|
|
12911
|
+
for(let level=0;level<path.length;level++){
|
|
12912
|
+
acc.push(groupPathElement(path[level]));
|
|
12913
|
+
keys[level]=groupKey(acc);
|
|
12914
|
+
}
|
|
12915
|
+
return keys;
|
|
12587
12916
|
}
|
|
12588
12917
|
});
|
|
12589
12918
|
__def("packages/core/src/source/handles.js",function(__exports,__req){
|
|
@@ -12592,14 +12921,17 @@ Object.defineProperty(__exports,"HandleProvider",{enumerable:true,get:function()
|
|
|
12592
12921
|
Object.defineProperty(__exports,"createHandleProvider",{enumerable:true,get:function(){return createHandleProvider;}});
|
|
12593
12922
|
const __m0=__req("packages/core/src/internal/util.js");
|
|
12594
12923
|
const isFunction=__m0["isFunction"];
|
|
12924
|
+
const warnOnce=__m0["warnOnce"];
|
|
12595
12925
|
class HandleProvider{
|
|
12596
12926
|
#ctx;
|
|
12597
12927
|
#readRows;
|
|
12928
|
+
#dropped;
|
|
12598
12929
|
#cache=new Map();
|
|
12599
12930
|
#version=0;
|
|
12600
|
-
constructor(ctx,readRows){
|
|
12931
|
+
constructor(ctx,readRows,dropped){
|
|
12601
12932
|
this.#ctx=ctx;
|
|
12602
12933
|
this.#readRows=readRows;
|
|
12934
|
+
this.#dropped=isFunction(dropped)?dropped:()=>false;
|
|
12603
12935
|
}
|
|
12604
12936
|
get store(){
|
|
12605
12937
|
const store=(this.#ctx).store;
|
|
@@ -12618,6 +12950,17 @@ const cached=this.#cache.get(colId);
|
|
|
12618
12950
|
if(cached&&cached.builtAt===this.#version)return cached.handle;
|
|
12619
12951
|
const column=this.#column(colId);
|
|
12620
12952
|
if(!column)return undefined;
|
|
12953
|
+
if(store&&this.#dropped()){
|
|
12954
|
+
warnOnce(
|
|
12955
|
+
`source.dropped.${colId}`,
|
|
12956
|
+
`column "${colId}" cannot be served under ingest.dropSourceRows: it is an `
|
|
12957
|
+
+'impure computed column (a shadow or a positional/rank column) that is '
|
|
12958
|
+
+'never stored, so it can only be read from the caller\'s row objects — '
|
|
12959
|
+
+'which dropSourceRows has released. Do not sort, filter, group or total '
|
|
12960
|
+
+'on such a column with dropSourceRows enabled.',
|
|
12961
|
+
);
|
|
12962
|
+
return undefined;
|
|
12963
|
+
}
|
|
12621
12964
|
const handle=this.#buildObjectHandle(column);
|
|
12622
12965
|
this.#cache.set(colId,{handle,builtAt:this.#version});
|
|
12623
12966
|
return handle;
|
|
@@ -12648,8 +12991,8 @@ version,
|
|
|
12648
12991
|
};
|
|
12649
12992
|
}
|
|
12650
12993
|
}
|
|
12651
|
-
function createHandleProvider(ctx,readRows){
|
|
12652
|
-
return new HandleProvider(ctx,readRows);
|
|
12994
|
+
function createHandleProvider(ctx,readRows,dropped){
|
|
12995
|
+
return new HandleProvider(ctx,readRows,dropped);
|
|
12653
12996
|
}
|
|
12654
12997
|
});
|
|
12655
12998
|
__def("packages/core/src/compute/incremental.js",function(__exports,__req){
|
|
@@ -13269,6 +13612,8 @@ const mergeRow=__m0["mergeRow"];
|
|
|
13269
13612
|
const __m1=__req("packages/core/src/source/rows.js");
|
|
13270
13613
|
const createRowFactory=__m1["createRowFactory"];
|
|
13271
13614
|
const groupKey=__m1["groupKey"];
|
|
13615
|
+
const groupPathElement=__m1["groupPathElement"];
|
|
13616
|
+
const groupPrefixKeys=__m1["groupPrefixKeys"];
|
|
13272
13617
|
const lazyRowView=__m1["lazyRowView"];
|
|
13273
13618
|
const __m2=__req("packages/core/src/source/handles.js");
|
|
13274
13619
|
const createHandleProvider=__m2["createHandleProvider"];
|
|
@@ -13287,6 +13632,11 @@ const resolveTree=__m6["resolveTree"];
|
|
|
13287
13632
|
const indexTree=__m6["indexTree"];
|
|
13288
13633
|
const STAGES=Object.freeze(['filter','sort','group','total','pivot','flatten']);
|
|
13289
13634
|
const EMPTY_HEADINGS=Object.freeze([]);
|
|
13635
|
+
function totalFnFor(column,scope){
|
|
13636
|
+
if(!column)return null;
|
|
13637
|
+
const override=scope==='grand'?column.grandTotal:column.groupTotal;
|
|
13638
|
+
return override!=null?override:column.total;
|
|
13639
|
+
}
|
|
13290
13640
|
function comparatorFor(column){
|
|
13291
13641
|
if(!column)return undefined;
|
|
13292
13642
|
if(column.value&&isFunction(column.value.compare))return column.value.compare;
|
|
@@ -13329,6 +13679,8 @@ mode='memory';
|
|
|
13329
13679
|
#ctx;
|
|
13330
13680
|
#config;
|
|
13331
13681
|
#rows;
|
|
13682
|
+
#dropped=false;
|
|
13683
|
+
#priorRows=null;
|
|
13332
13684
|
#factory;
|
|
13333
13685
|
#handles;
|
|
13334
13686
|
#stages=new Map();
|
|
@@ -13340,6 +13692,9 @@ mode='memory';
|
|
|
13340
13692
|
#running=new Map();
|
|
13341
13693
|
#runningId=-1;
|
|
13342
13694
|
#totalDeltas=[];
|
|
13695
|
+
#groupRunning=new Map();
|
|
13696
|
+
#groupRunningId=-1;
|
|
13697
|
+
#groupDeltas=[];
|
|
13343
13698
|
#totalsDirty=null;
|
|
13344
13699
|
#totalsBasis=null;
|
|
13345
13700
|
#lastGrand=null;
|
|
@@ -13360,7 +13715,7 @@ this.#ctx=ctx||{};
|
|
|
13360
13715
|
const gridConfig=(this.#ctx.config)||{};
|
|
13361
13716
|
this.#rows=(this.#config.rows||gridConfig.rows||[]);
|
|
13362
13717
|
this.#factory=createRowFactory((this.#ctx));
|
|
13363
|
-
this.#handles=createHandleProvider(this.#ctx,()=>this.#rows);
|
|
13718
|
+
this.#handles=createHandleProvider(this.#ctx,()=>this.#rows,()=>this.#dropped);
|
|
13364
13719
|
this.#rowCache=new Lru(Number(gridConfig.rowCacheSize)||DEFAULT_ROW_CACHE);
|
|
13365
13720
|
for(const name of STAGES)this.#stages.set(name,{key:null,result:null,id:0,computed:false});
|
|
13366
13721
|
}
|
|
@@ -13409,13 +13764,7 @@ return this.#materialise(index,index);
|
|
|
13409
13764
|
}
|
|
13410
13765
|
byKey(key){
|
|
13411
13766
|
this.#run();
|
|
13412
|
-
if(!this.#keyIndex)
|
|
13413
|
-
this.#keyIndex=new Map();
|
|
13414
|
-
for(let i=0;i<this.#rows.length;i++){
|
|
13415
|
-
if(this.#rows[i]===undefined)continue;
|
|
13416
|
-
this.#keyIndex.set(this.#factory.keyOf(this.#rows[i],i),i);
|
|
13417
|
-
}
|
|
13418
|
-
}
|
|
13767
|
+
if(!this.#keyIndex)this.#buildKeyIndex();
|
|
13419
13768
|
const physical=this.#keyIndex.get(key);
|
|
13420
13769
|
if(physical!==undefined)return this.#leafRow(physical);
|
|
13421
13770
|
for(let i=0;i<this.#slots.length;i++){
|
|
@@ -13461,8 +13810,10 @@ if(physical===undefined){
|
|
|
13461
13810
|
rejected.push({operation:'remove',id:this.#keyOfTarget(target),reason:'unknown-id'});
|
|
13462
13811
|
continue;
|
|
13463
13812
|
}
|
|
13464
|
-
result.removed.push(this.#factory.keyOf(
|
|
13465
|
-
this.#rows[physical]
|
|
13813
|
+
result.removed.push(this.#factory.keyOf(
|
|
13814
|
+
this.#dropped?this.#dataAt(physical):this.#rows[physical],physical,
|
|
13815
|
+
));
|
|
13816
|
+
if(!this.#dropped)this.#rows[physical]=undefined;
|
|
13466
13817
|
this.#rowCache.delete(physical);
|
|
13467
13818
|
this.#quickText.delete(physical);
|
|
13468
13819
|
structural=true;
|
|
@@ -13472,17 +13823,25 @@ if(change.update&&change.update.length){
|
|
|
13472
13823
|
const totalCols=this.#running.size||this.#onlyChangedTotals()
|
|
13473
13824
|
?this.#totalColumns()
|
|
13474
13825
|
:null;
|
|
13826
|
+
const groupCols=this.#groupRunning.size?this.#groupByColumns():null;
|
|
13827
|
+
const groupTotalCols=groupCols&&groupCols.length?this.#totalColumns():null;
|
|
13475
13828
|
for(const next of change.update){
|
|
13476
13829
|
const physical=this.#physicalOf(next);
|
|
13477
13830
|
if(physical===undefined){
|
|
13478
13831
|
rejected.push({operation:'update',id:this.#rowKeyOf(next),reason:'unknown-id'});
|
|
13479
13832
|
continue;
|
|
13480
13833
|
}
|
|
13481
|
-
const previous=this.#
|
|
13834
|
+
const previous=this.#dropped
|
|
13835
|
+
?(this.#priorRows&&this.#priorRows.has(physical)
|
|
13836
|
+
?this.#priorRows.get(physical):this.#dataAt(physical))
|
|
13837
|
+
:this.#rows[physical];
|
|
13482
13838
|
const merged=mergeRow(previous,next);
|
|
13483
13839
|
for(const colId of this.#changedColumns(previous,merged))touched.add(colId);
|
|
13484
|
-
this.#rows[physical]=merged;
|
|
13840
|
+
if(!this.#dropped)this.#rows[physical]=merged;
|
|
13485
13841
|
if(totalCols)this.#recordDeltas(totalCols,physical,previous,merged);
|
|
13842
|
+
if(groupTotalCols){
|
|
13843
|
+
this.#recordGroupDeltas(groupCols,groupTotalCols,physical,previous,merged);
|
|
13844
|
+
}
|
|
13486
13845
|
if(this.#keyIndex){
|
|
13487
13846
|
const wasKey=this.#factory.keyOf(previous,physical);
|
|
13488
13847
|
const nowKey=this.#factory.keyOf(merged,physical);
|
|
@@ -13496,7 +13855,18 @@ this.#quickText.delete(physical);
|
|
|
13496
13855
|
result.updated.push(this.#leafRow(physical));
|
|
13497
13856
|
}
|
|
13498
13857
|
}
|
|
13499
|
-
if(change.add&&change.add.length){
|
|
13858
|
+
if(change.add&&change.add.length&&this.#dropped){
|
|
13859
|
+
if(typeof change.at==='number'&&change.at<this.#physicalCount()){
|
|
13860
|
+
this.#rowCache.clear();
|
|
13861
|
+
this.#quickText.clear();
|
|
13862
|
+
}
|
|
13863
|
+
this.#keyIndex=null;
|
|
13864
|
+
for(const item of change.add){
|
|
13865
|
+
const physical=this.#byKeyIndex(this.#rowKeyOf(item));
|
|
13866
|
+
if(physical!==undefined)result.added.push(this.#leafRow(physical));
|
|
13867
|
+
}
|
|
13868
|
+
structural=true;
|
|
13869
|
+
}else if(change.add&&change.add.length){
|
|
13500
13870
|
const at=typeof change.at==='number'?change.at:this.#rows.length;
|
|
13501
13871
|
const before=this.#rows.length;
|
|
13502
13872
|
let additions=change.add===this.#rows?change.add.slice():change.add;
|
|
@@ -13542,6 +13912,7 @@ this.#emit('rows:changed',{
|
|
|
13542
13912
|
companion:true,
|
|
13543
13913
|
added:result.added.length,updated:result.updated.length,removed:result.removed.length,
|
|
13544
13914
|
});
|
|
13915
|
+
this.#priorRows=null;
|
|
13545
13916
|
return result;
|
|
13546
13917
|
}
|
|
13547
13918
|
groupHeadingsAt(index){
|
|
@@ -13562,6 +13933,15 @@ chain.reverse();
|
|
|
13562
13933
|
return chain;
|
|
13563
13934
|
}
|
|
13564
13935
|
moveRow(from,to){
|
|
13936
|
+
if(this.#dropped){
|
|
13937
|
+
warnOnce(
|
|
13938
|
+
'source.moveRow.dropped',
|
|
13939
|
+
'rows.move() is not supported under ingest.dropSourceRows: the source '
|
|
13940
|
+
+'objects have been released and the store cannot reorder its columns in '
|
|
13941
|
+
+'place. Enable retainSource (leave dropSourceRows off) to reorder rows.',
|
|
13942
|
+
);
|
|
13943
|
+
return false;
|
|
13944
|
+
}
|
|
13565
13945
|
const rows=this.#rows;
|
|
13566
13946
|
if(!Number.isInteger(from)||!Number.isInteger(to))return false;
|
|
13567
13947
|
if(from<0||from>=rows.length)return false;
|
|
@@ -13606,6 +13986,7 @@ for(const name of STAGES)this.#stages.set(name,{key:null,result:null,id:0,comput
|
|
|
13606
13986
|
}
|
|
13607
13987
|
setRows(rows){
|
|
13608
13988
|
this.#rows=rows||[];
|
|
13989
|
+
this.#dropped=false;
|
|
13609
13990
|
this.#dataVersion++;
|
|
13610
13991
|
this.#queryVersion++;
|
|
13611
13992
|
this.#keyIndex=null;
|
|
@@ -13615,7 +13996,26 @@ this.#dropTotalState();
|
|
|
13615
13996
|
this.#handles.invalidate();
|
|
13616
13997
|
this.invalidate('filter');
|
|
13617
13998
|
}
|
|
13618
|
-
|
|
13999
|
+
notePriorRows(prior){
|
|
14000
|
+
this.#priorRows=prior||null;
|
|
14001
|
+
}
|
|
14002
|
+
releaseSource(){
|
|
14003
|
+
this.#dropped=true;
|
|
14004
|
+
this.#rows=[];
|
|
14005
|
+
this.#keyIndex=null;
|
|
14006
|
+
this.#rowCache.clear();
|
|
14007
|
+
this.#quickText.clear();
|
|
14008
|
+
this.#handles.invalidate();
|
|
14009
|
+
}
|
|
14010
|
+
data(){
|
|
14011
|
+
if(!this.#dropped)return this.#rows;
|
|
14012
|
+
const store=(this.#ctx.store);
|
|
14013
|
+
if(!store||!isFunction(store.source))return this.#rows;
|
|
14014
|
+
const n=store.physical||0;
|
|
14015
|
+
const out=new Array(n);
|
|
14016
|
+
for(let p=0;p<n;p++)out[p]=store.live&&!store.live(p)?undefined:store.source(p);
|
|
14017
|
+
return out;
|
|
14018
|
+
}
|
|
13619
14019
|
#detailInline(){
|
|
13620
14020
|
const detail=this.#state('detail',null);
|
|
13621
14021
|
if(!detail||!isFunction(detail.isOpen)||detail.inline===false)return null;
|
|
@@ -13662,17 +14062,25 @@ const key=this.#factory.keyOf(target,-1);
|
|
|
13662
14062
|
const found=this.#byKeyIndex(key);
|
|
13663
14063
|
if(found!==undefined)return found;
|
|
13664
14064
|
}
|
|
14065
|
+
if(this.#dropped)return undefined;
|
|
13665
14066
|
const direct=this.#rows.indexOf(target);
|
|
13666
14067
|
return direct>=0?direct:undefined;
|
|
13667
14068
|
}
|
|
13668
14069
|
#byKeyIndex(key){
|
|
13669
|
-
if(!this.#keyIndex)
|
|
13670
|
-
this.#keyIndex
|
|
13671
|
-
for(let i=0;i<this.#rows.length;i++){
|
|
13672
|
-
if(this.#rows[i]!==undefined)this.#keyIndex.set(this.#factory.keyOf(this.#rows[i],i),i);
|
|
14070
|
+
if(!this.#keyIndex)this.#buildKeyIndex();
|
|
14071
|
+
return this.#keyIndex.get(key);
|
|
13673
14072
|
}
|
|
14073
|
+
#buildKeyIndex(){
|
|
14074
|
+
this.#keyIndex=new Map();
|
|
14075
|
+
const n=this.#physicalCount();
|
|
14076
|
+
const store=(this.#ctx.store);
|
|
14077
|
+
const isLive=store&&isFunction(store.live)?(i)=>store.live(i):null;
|
|
14078
|
+
for(let i=0;i<n;i++){
|
|
14079
|
+
if(isLive&&!isLive(i))continue;
|
|
14080
|
+
const data=this.#dataAt(i);
|
|
14081
|
+
if(data===undefined)continue;
|
|
14082
|
+
this.#keyIndex.set(this.#factory.keyOf(data,i),i);
|
|
13674
14083
|
}
|
|
13675
|
-
return this.#keyIndex.get(key);
|
|
13676
14084
|
}
|
|
13677
14085
|
#changedColumns(previous,next){
|
|
13678
14086
|
const changed=[];
|
|
@@ -13926,7 +14334,7 @@ const tuple=keys[b];
|
|
|
13926
14334
|
let parent=null;
|
|
13927
14335
|
const path=[];
|
|
13928
14336
|
for(let level=0;level<tuple.length;level++){
|
|
13929
|
-
path.push(
|
|
14337
|
+
path.push(groupPathElement(tuple[level]));
|
|
13930
14338
|
const key=groupKey(path);
|
|
13931
14339
|
let node=nodes.get(key);
|
|
13932
14340
|
if(!node){
|
|
@@ -13989,6 +14397,7 @@ const dirty=this.#onlyChangedTotals()&&reusable?this.#totalsDirty:null;
|
|
|
13989
14397
|
const groupColumns=dirty?columns.filter((c)=>dirty.has(c.id)):columns;
|
|
13990
14398
|
const previousGrand=reusable?this.#lastGrand:null;
|
|
13991
14399
|
const unfiltered=this.#totalFilteredOnly()?null:this.#unfilteredGroups();
|
|
14400
|
+
const groupRunning=this.#syncGroupRunning(columns);
|
|
13992
14401
|
const reduce=(row)=>{
|
|
13993
14402
|
const node=grouped.nodes.get(row.key);
|
|
13994
14403
|
let leaves=node&&node.leaves?node.leaves:null;
|
|
@@ -14003,9 +14412,10 @@ leaves=merged;
|
|
|
14003
14412
|
}
|
|
14004
14413
|
leaves=leaves||new Uint32Array(0);
|
|
14005
14414
|
const scope=unfiltered?(unfiltered.get(row.key)||EMPTY_INDICES):leaves;
|
|
14006
|
-
|
|
14007
|
-
?
|
|
14008
|
-
|
|
14415
|
+
const computed=this.#groupTotalsFor(
|
|
14416
|
+
row,dirty?groupColumns:columns,scope,groupRunning,
|
|
14417
|
+
);
|
|
14418
|
+
row.totals=dirty?{...row.totals,...computed}:computed;
|
|
14009
14419
|
return leaves;
|
|
14010
14420
|
};
|
|
14011
14421
|
if(grouped.roots&&groupColumns.length)for(const root of grouped.roots)reduce(root);
|
|
@@ -14027,13 +14437,13 @@ this.#totalDeltas=[];
|
|
|
14027
14437
|
for(const column of columns){
|
|
14028
14438
|
const handle=this.#handles.handle(column.id);
|
|
14029
14439
|
if(!handle)continue;
|
|
14030
|
-
const fn=column
|
|
14440
|
+
const fn=totalFnFor(column,'grand');
|
|
14031
14441
|
if(!isIncremental(fn,handle)){
|
|
14032
14442
|
if(dirty&&!dirty.has(column.id)&&carried&&column.id in carried){
|
|
14033
14443
|
totals[column.id]=carried[column.id];
|
|
14034
14444
|
continue;
|
|
14035
14445
|
}
|
|
14036
|
-
totals[column.id]=this.#totalsFor([column],leaves,null)[column.id];
|
|
14446
|
+
totals[column.id]=this.#totalsFor([column],leaves,null,'grand')[column.id];
|
|
14037
14447
|
continue;
|
|
14038
14448
|
}
|
|
14039
14449
|
let running=this.#running.get(column.id);
|
|
@@ -14053,10 +14463,78 @@ running.invalidate();
|
|
|
14053
14463
|
running.seedColumn(handle.values,presenceReader(handle),leaves);
|
|
14054
14464
|
totals[column.id]=running.valid
|
|
14055
14465
|
?running.value()
|
|
14056
|
-
:this.#totalsFor([column],leaves,null)[column.id];
|
|
14466
|
+
:this.#totalsFor([column],leaves,null,'grand')[column.id];
|
|
14057
14467
|
}
|
|
14058
14468
|
return totals;
|
|
14059
14469
|
}
|
|
14470
|
+
#syncGroupRunning(columns){
|
|
14471
|
+
const id=this.#idOf('group');
|
|
14472
|
+
if(id!==this.#groupRunningId){
|
|
14473
|
+
this.#groupRunning.clear();
|
|
14474
|
+
this.#groupRunningId=id;
|
|
14475
|
+
}
|
|
14476
|
+
const incremental=new Map();
|
|
14477
|
+
for(const column of columns){
|
|
14478
|
+
const handle=this.#handles.handle(column.id);
|
|
14479
|
+
const fn=totalFnFor(column,'group');
|
|
14480
|
+
if(isIncremental(fn,handle))incremental.set(column.id,{fn:(fn)});
|
|
14481
|
+
}
|
|
14482
|
+
if(!incremental.size){this.#groupDeltas.length=0;return incremental;}
|
|
14483
|
+
const deltas=this.#groupDeltas;
|
|
14484
|
+
this.#groupDeltas=[];
|
|
14485
|
+
for(const record of deltas){
|
|
14486
|
+
const{beforeKeys,afterKeys,colDeltas}=record;
|
|
14487
|
+
const beforeSet=beforeKeys.length?new Set(beforeKeys):null;
|
|
14488
|
+
const afterSet=afterKeys.length?new Set(afterKeys):null;
|
|
14489
|
+
for(const{colId,before,after}of colDeltas){
|
|
14490
|
+
if(!incremental.has(colId))continue;
|
|
14491
|
+
for(const key of beforeKeys){
|
|
14492
|
+
if(afterSet&&afterSet.has(key))continue;
|
|
14493
|
+
this.#applyGroupDelta(key,colId,before,null);
|
|
14494
|
+
}
|
|
14495
|
+
for(const key of afterKeys){
|
|
14496
|
+
if(beforeSet&&beforeSet.has(key))continue;
|
|
14497
|
+
this.#applyGroupDelta(key,colId,null,after);
|
|
14498
|
+
}
|
|
14499
|
+
for(const key of beforeKeys){
|
|
14500
|
+
if(afterSet&&!afterSet.has(key))continue;
|
|
14501
|
+
this.#applyGroupDelta(key,colId,before,after);
|
|
14502
|
+
}
|
|
14503
|
+
}
|
|
14504
|
+
}
|
|
14505
|
+
return incremental;
|
|
14506
|
+
}
|
|
14507
|
+
#applyGroupDelta(key,colId,before,after){
|
|
14508
|
+
const perColumn=this.#groupRunning.get(key);
|
|
14509
|
+
const running=perColumn&&perColumn.get(colId);
|
|
14510
|
+
if(!running||!running.valid)return;
|
|
14511
|
+
if(!running.update(before,after))running.invalidate();
|
|
14512
|
+
}
|
|
14513
|
+
#groupTotalsFor(row,columns,scope,incremental){
|
|
14514
|
+
if(!incremental||!incremental.size)return this.#totalsFor(columns,scope,row);
|
|
14515
|
+
const totals={};
|
|
14516
|
+
let rescan=null;
|
|
14517
|
+
let perColumn=this.#groupRunning.get(row.key);
|
|
14518
|
+
for(const column of columns){
|
|
14519
|
+
const spec=incremental.get(column.id);
|
|
14520
|
+
if(!spec){(rescan||(rescan=[])).push(column);continue;}
|
|
14521
|
+
const handle=this.#handles.handle(column.id);
|
|
14522
|
+
if(!handle)continue;
|
|
14523
|
+
if(!perColumn){perColumn=new Map();this.#groupRunning.set(row.key,perColumn);}
|
|
14524
|
+
let running=perColumn.get(column.id);
|
|
14525
|
+
if(!running||running.fn!==spec.fn){
|
|
14526
|
+
running=new RunningTotal(spec.fn);
|
|
14527
|
+
perColumn.set(column.id,running);
|
|
14528
|
+
}
|
|
14529
|
+
if(!running.valid){
|
|
14530
|
+
running.seedColumn(handle.values,presenceReader(handle),scope);
|
|
14531
|
+
}
|
|
14532
|
+
if(running.valid){totals[column.id]=running.value();continue;}
|
|
14533
|
+
(rescan||(rescan=[])).push(column);
|
|
14534
|
+
}
|
|
14535
|
+
if(rescan)Object.assign(totals,this.#totalsFor(rescan,scope,row));
|
|
14536
|
+
return totals;
|
|
14537
|
+
}
|
|
14060
14538
|
#recordDeltas(columns,physical,previous,merged){
|
|
14061
14539
|
const counted=!this.#totalFilteredOnly()||this.#inFilteredSet(physical);
|
|
14062
14540
|
for(const column of columns){
|
|
@@ -14071,6 +14549,41 @@ this.#totalDeltas.push({colId:column.id,before,after});
|
|
|
14071
14549
|
}
|
|
14072
14550
|
}
|
|
14073
14551
|
}
|
|
14552
|
+
#groupByColumns(){
|
|
14553
|
+
const groupBy=this.#state('groupBy',[]);
|
|
14554
|
+
const out=[];
|
|
14555
|
+
for(const colId of groupBy){
|
|
14556
|
+
const column=this.#column(colId);
|
|
14557
|
+
if(column)out.push(column);
|
|
14558
|
+
}
|
|
14559
|
+
return out;
|
|
14560
|
+
}
|
|
14561
|
+
#groupPathOf(groupCols,data){
|
|
14562
|
+
const path=new Array(groupCols.length);
|
|
14563
|
+
for(let i=0;i<groupCols.length;i++){
|
|
14564
|
+
const read=groupCols[i].getValue;
|
|
14565
|
+
path[i]=groupPathElement(isFunction(read)?read(data):undefined);
|
|
14566
|
+
}
|
|
14567
|
+
return path;
|
|
14568
|
+
}
|
|
14569
|
+
#recordGroupDeltas(groupCols,columns,physical,previous,merged){
|
|
14570
|
+
if(this.#totalFilteredOnly()&&!this.#inFilteredSet(physical))return;
|
|
14571
|
+
const beforeKeys=groupPrefixKeys(this.#groupPathOf(groupCols,previous));
|
|
14572
|
+
const afterKeys=groupPrefixKeys(this.#groupPathOf(groupCols,merged));
|
|
14573
|
+
const moved=beforeKeys.length!==afterKeys.length
|
|
14574
|
+
||beforeKeys.some((k,i)=>k!==afterKeys[i]);
|
|
14575
|
+
const colDeltas=[];
|
|
14576
|
+
for(const column of columns){
|
|
14577
|
+
const read=column.getValue;
|
|
14578
|
+
if(!isFunction(read))continue;
|
|
14579
|
+
const before=read(previous);
|
|
14580
|
+
const after=read(merged);
|
|
14581
|
+
if(!moved&&Object.is(before,after))continue;
|
|
14582
|
+
colDeltas.push({colId:column.id,before,after});
|
|
14583
|
+
}
|
|
14584
|
+
if(!colDeltas.length&&!moved)return;
|
|
14585
|
+
this.#groupDeltas.push({beforeKeys,afterKeys,colDeltas});
|
|
14586
|
+
}
|
|
14074
14587
|
#inFilteredSet(physical){
|
|
14075
14588
|
const entry=this.#stages.get('filter');
|
|
14076
14589
|
const indices=(entry&&entry.computed?entry.result:null);
|
|
@@ -14121,7 +14634,7 @@ for(let b=0;b<buckets.length;b++){
|
|
|
14121
14634
|
const tuple=keys[b];
|
|
14122
14635
|
const path=[];
|
|
14123
14636
|
for(let level=0;level<tuple.length;level++){
|
|
14124
|
-
path.push(
|
|
14637
|
+
path.push(groupPathElement(tuple[level]));
|
|
14125
14638
|
const at=groupKey(path);
|
|
14126
14639
|
let list=collected.get(at);
|
|
14127
14640
|
if(!list){list=[];collected.set(at,list);}
|
|
@@ -14139,6 +14652,7 @@ return!!((this.#ctx.config||{}))
|
|
|
14139
14652
|
}
|
|
14140
14653
|
#dropTotalState(){
|
|
14141
14654
|
this.#dropRunning();
|
|
14655
|
+
this.#dropGroupRunning();
|
|
14142
14656
|
this.#totalsDirty=null;
|
|
14143
14657
|
this.#totalsBasis=null;
|
|
14144
14658
|
this.#lastGrand=null;
|
|
@@ -14148,6 +14662,11 @@ this.#running.clear();
|
|
|
14148
14662
|
this.#totalDeltas.length=0;
|
|
14149
14663
|
this.#runningId=-1;
|
|
14150
14664
|
}
|
|
14665
|
+
#dropGroupRunning(){
|
|
14666
|
+
this.#groupRunning.clear();
|
|
14667
|
+
this.#groupDeltas.length=0;
|
|
14668
|
+
this.#groupRunningId=-1;
|
|
14669
|
+
}
|
|
14151
14670
|
#runPivot(grouped){
|
|
14152
14671
|
const pivotBy=this.#state('pivotBy',[]);
|
|
14153
14672
|
if(!pivotBy.length){this.#pivot=null;return null;}
|
|
@@ -14165,7 +14684,7 @@ groups:grouped.keys&&grouped.buckets
|
|
|
14165
14684
|
:null,
|
|
14166
14685
|
totals:totalColumns.map((c)=>c.id),
|
|
14167
14686
|
handle:(colId)=>this.#handles.handle(colId),
|
|
14168
|
-
totalOf:(colId)=>(totalColumns.find((c)=>c.id===colId)
|
|
14687
|
+
totalOf:(colId)=>totalFnFor(totalColumns.find((c)=>c.id===colId),'group'),
|
|
14169
14688
|
separator:((this.#ctx.config||{}).pivot||{}).separator,
|
|
14170
14689
|
maxColumns:((this.#ctx.config||{}).pivot||{}).maxColumns,
|
|
14171
14690
|
})||null;
|
|
@@ -14358,15 +14877,18 @@ return matches(text);
|
|
|
14358
14877
|
#totalColumns(){
|
|
14359
14878
|
const named=this.#state('totals',[]);
|
|
14360
14879
|
const wanted=named&&named.length?new Set(named):null;
|
|
14361
|
-
return this.#columnList().filter((c)=>(
|
|
14880
|
+
return this.#columnList().filter((c)=>(
|
|
14881
|
+
wanted?wanted.has(c.id):!!(c.total||c.groupTotal||c.grandTotal)
|
|
14882
|
+
));
|
|
14362
14883
|
}
|
|
14363
|
-
#totalsFor(columns,leaves,row){
|
|
14884
|
+
#totalsFor(columns,leaves,row,scope='group'){
|
|
14364
14885
|
const totals={};
|
|
14365
14886
|
const reduce=(this.#ctx.compute||{}).total;
|
|
14366
14887
|
for(const column of columns){
|
|
14367
14888
|
const handle=this.#handles.handle(column.id);
|
|
14368
14889
|
if(!handle)continue;
|
|
14369
|
-
const fn=column
|
|
14890
|
+
const fn=totalFnFor(column,scope);
|
|
14891
|
+
if(!fn)continue;
|
|
14370
14892
|
if(isFunction(fn)){
|
|
14371
14893
|
const values=new Array(leaves.length);
|
|
14372
14894
|
for(let i=0;i<leaves.length;i++)values[i]=handle.get(leaves[i]);
|
|
@@ -14629,12 +15151,14 @@ this.#blocks.set(id,block);
|
|
|
14629
15151
|
});
|
|
14630
15152
|
__def("packages/core/src/source/paged.js",function(__exports,__req){
|
|
14631
15153
|
'use strict';
|
|
15154
|
+
Object.defineProperty(__exports,"HINT_SETTLE_MS",{enumerable:true,get:function(){return HINT_SETTLE_MS;}});
|
|
14632
15155
|
Object.defineProperty(__exports,"createPagedSource",{enumerable:true,get:function(){return createPagedSource;}});
|
|
14633
15156
|
Object.defineProperty(__exports,"PagedSource",{enumerable:true,get:function(){return PagedSource;}});
|
|
14634
15157
|
const __m0=__req("packages/core/src/internal/util.js");
|
|
14635
15158
|
const Lru=__m0["Lru"];
|
|
14636
15159
|
const isFunction=__m0["isFunction"];
|
|
14637
15160
|
const warnOnce=__m0["warnOnce"];
|
|
15161
|
+
const settleDebounce=__m0["settleDebounce"];
|
|
14638
15162
|
const __m1=__req("packages/core/src/source/abort.js");
|
|
14639
15163
|
const createAbortScope=__m1["createAbortScope"];
|
|
14640
15164
|
const isAbortError=__m1["isAbortError"];
|
|
@@ -14648,6 +15172,7 @@ const __m4=__req("packages/core/src/source/filterwire.js");
|
|
|
14648
15172
|
const wireFilters=__m4["wireFilters"];
|
|
14649
15173
|
const querySignature=__m4["querySignature"];
|
|
14650
15174
|
const warnHostFilterNotApplied=__m4["warnHostFilterNotApplied"];
|
|
15175
|
+
const HINT_SETTLE_MS=120;
|
|
14651
15176
|
function createPagedSource(config,ctx){
|
|
14652
15177
|
return new PagedSource(config,ctx);
|
|
14653
15178
|
}
|
|
@@ -14665,6 +15190,7 @@ mode='paged';
|
|
|
14665
15190
|
#discovered=0;
|
|
14666
15191
|
#signature='';
|
|
14667
15192
|
#viewport={start:0,end:0};
|
|
15193
|
+
#settledFetch;
|
|
14668
15194
|
#destroyed=false;
|
|
14669
15195
|
constructor(config,ctx){
|
|
14670
15196
|
this.#config=config||({mode:'paged'});
|
|
@@ -14675,6 +15201,10 @@ maxCachedPages:this.#config.maxCachedPages||DEFAULT_MAX_CACHED_PAGES,
|
|
|
14675
15201
|
});
|
|
14676
15202
|
this.#factory=createRowFactory((this.#ctx));
|
|
14677
15203
|
this.#rows=new Lru(this.#cache.pageSize*4);
|
|
15204
|
+
this.#settledFetch=settleDebounce(
|
|
15205
|
+
(start,end)=>this.#fetchWindow(start,end),
|
|
15206
|
+
HINT_SETTLE_MS,
|
|
15207
|
+
);
|
|
14678
15208
|
this.#signature=this.#querySignature();
|
|
14679
15209
|
if(!isFunction(this.#config.fetch)){
|
|
14680
15210
|
warnOnce('source.paged.fetch','source.mode "paged" requires a fetch function; the grid will stay empty.');
|
|
@@ -14713,11 +15243,18 @@ return this.#cache.rowLoaded(index);
|
|
|
14713
15243
|
}
|
|
14714
15244
|
hint(start,end){
|
|
14715
15245
|
if(this.#destroyed)return;
|
|
14716
|
-
this.#restartIfQueryChanged();
|
|
15246
|
+
const queryChanged=this.#restartIfQueryChanged();
|
|
14717
15247
|
const from=Math.max(0,Math.floor(start));
|
|
14718
15248
|
const to=Math.max(from,Math.floor(end));
|
|
14719
15249
|
this.#viewport={start:from,end:to};
|
|
14720
15250
|
this.#cache.protect(from,to);
|
|
15251
|
+
for(const id of this.#cache.evict())this.#forgetBlock(id);
|
|
15252
|
+
this.#settledFetch(from,to);
|
|
15253
|
+
if(queryChanged)this.#settledFetch.flush();
|
|
15254
|
+
}
|
|
15255
|
+
#fetchWindow(from,to){
|
|
15256
|
+
if(this.#destroyed)return;
|
|
15257
|
+
this.#cache.protect(from,to);
|
|
14721
15258
|
const firstBlock=this.#cache.blockOf(from);
|
|
14722
15259
|
const lastBlock=this.#cache.blockOf(to);
|
|
14723
15260
|
for(let id=firstBlock;id<=lastBlock;id++){
|
|
@@ -14725,7 +15262,6 @@ if(this.#total!==null&&id*this.#cache.pageSize>=this.#total)break;
|
|
|
14725
15262
|
if(this.#cache.has(id))continue;
|
|
14726
15263
|
this.#fetchBlock(id);
|
|
14727
15264
|
}
|
|
14728
|
-
for(const id of this.#cache.evict())this.#forgetBlock(id);
|
|
14729
15265
|
}
|
|
14730
15266
|
apply(change){
|
|
14731
15267
|
const result={added:[],updated:[],removed:[]};
|
|
@@ -14748,10 +15284,12 @@ return result;
|
|
|
14748
15284
|
}
|
|
14749
15285
|
reload(_opts){
|
|
14750
15286
|
this.#invalidateAll('reload');
|
|
15287
|
+
this.#settledFetch.cancel();
|
|
14751
15288
|
this.hint(this.#viewport.start,this.#viewport.end);
|
|
14752
15289
|
}
|
|
14753
15290
|
destroy(){
|
|
14754
15291
|
this.#destroyed=true;
|
|
15292
|
+
this.#settledFetch.cancel();
|
|
14755
15293
|
this.#scope.abortAll('destroyed');
|
|
14756
15294
|
this.#cache.clear();
|
|
14757
15295
|
this.#rows.clear();
|
|
@@ -14808,9 +15346,10 @@ this.#rows.delete(i);
|
|
|
14808
15346
|
}
|
|
14809
15347
|
#restartIfQueryChanged(){
|
|
14810
15348
|
const signature=this.#querySignature();
|
|
14811
|
-
if(signature===this.#signature)return;
|
|
15349
|
+
if(signature===this.#signature)return false;
|
|
14812
15350
|
this.#signature=signature;
|
|
14813
15351
|
this.#invalidateAll('query');
|
|
15352
|
+
return true;
|
|
14814
15353
|
}
|
|
14815
15354
|
#invalidateAll(reason){
|
|
14816
15355
|
this.#scope.abortAll(reason);
|
|
@@ -14851,12 +15390,14 @@ if(isFunction(emit))emit(type,payload);
|
|
|
14851
15390
|
__def("packages/core/src/source/remote.js",function(__exports,__req){
|
|
14852
15391
|
'use strict';
|
|
14853
15392
|
Object.defineProperty(__exports,"PROTOCOL",{enumerable:true,get:function(){return PROTOCOL;}});
|
|
15393
|
+
Object.defineProperty(__exports,"HINT_SETTLE_MS",{enumerable:true,get:function(){return HINT_SETTLE_MS;}});
|
|
14854
15394
|
Object.defineProperty(__exports,"createRemoteSource",{enumerable:true,get:function(){return createRemoteSource;}});
|
|
14855
15395
|
Object.defineProperty(__exports,"RemoteSource",{enumerable:true,get:function(){return RemoteSource;}});
|
|
14856
15396
|
const __m0=__req("packages/core/src/internal/util.js");
|
|
14857
15397
|
const Lru=__m0["Lru"];
|
|
14858
15398
|
const isFunction=__m0["isFunction"];
|
|
14859
15399
|
const warnOnce=__m0["warnOnce"];
|
|
15400
|
+
const settleDebounce=__m0["settleDebounce"];
|
|
14860
15401
|
const __m1=__req("packages/core/src/source/abort.js");
|
|
14861
15402
|
const createAbortScope=__m1["createAbortScope"];
|
|
14862
15403
|
const isAbortError=__m1["isAbortError"];
|
|
@@ -14871,7 +15412,10 @@ const __m4=__req("packages/core/src/source/filterwire.js");
|
|
|
14871
15412
|
const wireFilters=__m4["wireFilters"];
|
|
14872
15413
|
const querySignature=__m4["querySignature"];
|
|
14873
15414
|
const warnHostFilterNotApplied=__m4["warnHostFilterNotApplied"];
|
|
15415
|
+
const __m5=__req("packages/core/src/source/memory.js");
|
|
15416
|
+
const MemorySource=__m5["MemorySource"];
|
|
14874
15417
|
const PROTOCOL=1;
|
|
15418
|
+
const HINT_SETTLE_MS=120;
|
|
14875
15419
|
function createRemoteSource(config,ctx){
|
|
14876
15420
|
return new RemoteSource(config,ctx);
|
|
14877
15421
|
}
|
|
@@ -14901,16 +15445,32 @@ mode='remote';
|
|
|
14901
15445
|
#keys=new Map();
|
|
14902
15446
|
#pivotFields=[];
|
|
14903
15447
|
#signature='';
|
|
15448
|
+
#settledFetch;
|
|
14904
15449
|
#destroyed=false;
|
|
15450
|
+
#fullMemory=null;
|
|
15451
|
+
#fullFrameVersion=-1;
|
|
14905
15452
|
constructor(config,ctx){
|
|
14906
15453
|
this.#config=config||({mode:'remote'});
|
|
14907
15454
|
this.#ctx=ctx||{};
|
|
15455
|
+
if(isFunction((this.#config).fullFrame)){
|
|
15456
|
+
this.filteredIndices=()=>this.#fullFilteredIndices();
|
|
15457
|
+
this.unfilteredIndices=()=>this.#fullUnfilteredIndices();
|
|
15458
|
+
this.handleFor=(colId)=>this.#fullHandleFor(colId);
|
|
15459
|
+
this.display=()=>this.#fullDisplay();
|
|
15460
|
+
this.grandTotalRow=()=>this.#fullGrandTotalRow();
|
|
15461
|
+
this.unfilteredRows=()=>this.#fullUnfilteredRows();
|
|
15462
|
+
this.facetIndices=(colId)=>this.#fullFacetIndices(colId);
|
|
15463
|
+
}
|
|
14908
15464
|
this.#bounds={
|
|
14909
15465
|
pageSize:this.#config.pageSize||DEFAULT_PAGE_SIZE,
|
|
14910
15466
|
maxCachedPages:this.#config.maxCachedPages||DEFAULT_MAX_CACHED_PAGES,
|
|
14911
15467
|
};
|
|
14912
15468
|
this.#factory=createRowFactory((this.#ctx));
|
|
14913
15469
|
this.#rows=new Lru(this.#bounds.pageSize*4);
|
|
15470
|
+
this.#settledFetch=settleDebounce(
|
|
15471
|
+
(start,end)=>this.#fetchWindow(start,end),
|
|
15472
|
+
HINT_SETTLE_MS,
|
|
15473
|
+
);
|
|
14914
15474
|
this.#root=new GroupNode([],0,this.#bounds);
|
|
14915
15475
|
this.#nodes.set(this.#root.key,this.#root);
|
|
14916
15476
|
this.#signature=this.#querySignature();
|
|
@@ -14920,10 +15480,14 @@ warnOnce('source.remote.fetch','source.mode "remote" requires a fetch function;
|
|
|
14920
15480
|
this.#warnHostFilter();
|
|
14921
15481
|
}
|
|
14922
15482
|
count(){
|
|
15483
|
+
const memory=this.#memory();
|
|
15484
|
+
if(memory)return memory.count();
|
|
14923
15485
|
this.#restartIfQueryChanged();
|
|
14924
15486
|
return this.#sizeOf(this.#root);
|
|
14925
15487
|
}
|
|
14926
15488
|
at(index){
|
|
15489
|
+
const memory=this.#memory();
|
|
15490
|
+
if(memory)return memory.at(index);
|
|
14927
15491
|
this.#restartIfQueryChanged();
|
|
14928
15492
|
if(index<0||index>=this.count())return undefined;
|
|
14929
15493
|
const found=this.#locate(this.#root,index);
|
|
@@ -14933,6 +15497,8 @@ if(row)row.index=index;
|
|
|
14933
15497
|
return row||this.#factory.skeleton(index,found.node.level);
|
|
14934
15498
|
}
|
|
14935
15499
|
byKey(key){
|
|
15500
|
+
const memory=this.#memory();
|
|
15501
|
+
if(memory)return memory.byKey(key);
|
|
14936
15502
|
const slot=this.#keys.get(key);
|
|
14937
15503
|
if(!slot)return undefined;
|
|
14938
15504
|
const sep=slot.lastIndexOf(':');
|
|
@@ -14940,15 +15506,25 @@ const node=this.#nodes.get(slot.slice(0,sep));
|
|
|
14940
15506
|
return node?this.#rowAt(node,Number(slot.slice(sep+1)))||undefined:undefined;
|
|
14941
15507
|
}
|
|
14942
15508
|
loaded(index){
|
|
15509
|
+
const memory=this.#memory();
|
|
15510
|
+
if(memory)return memory.loaded(index);
|
|
14943
15511
|
if(index<0||index>=this.count())return false;
|
|
14944
15512
|
const found=this.#locate(this.#root,index);
|
|
14945
15513
|
return!!found&&found.node.cache.rowLoaded(found.local);
|
|
14946
15514
|
}
|
|
14947
15515
|
hint(start,end){
|
|
14948
15516
|
if(this.#destroyed)return;
|
|
14949
|
-
this.#restartIfQueryChanged();
|
|
15517
|
+
const queryChanged=this.#restartIfQueryChanged();
|
|
14950
15518
|
const from=Math.max(0,Math.floor(start));
|
|
14951
15519
|
const to=Math.max(from,Math.floor(end));
|
|
15520
|
+
for(const[node,span]of this.#spans(from,to)){
|
|
15521
|
+
node.cache.protect(span.min,span.max);
|
|
15522
|
+
for(const id of node.cache.evict())this.#forgetBlock(node,id);
|
|
15523
|
+
}
|
|
15524
|
+
this.#settledFetch(from,to);
|
|
15525
|
+
if(queryChanged)this.#settledFetch.flush();
|
|
15526
|
+
}
|
|
15527
|
+
#spans(from,to){
|
|
14952
15528
|
const total=this.count();
|
|
14953
15529
|
const perNode=new Map();
|
|
14954
15530
|
for(let i=from;i<=to&&i<total;i++){
|
|
@@ -14959,7 +15535,11 @@ if(!span)perNode.set(found.node,{min:found.local,max:found.local});
|
|
|
14959
15535
|
else{span.min=Math.min(span.min,found.local);span.max=Math.max(span.max,found.local);}
|
|
14960
15536
|
}
|
|
14961
15537
|
if(!perNode.size)perNode.set(this.#root,{min:from,max:from});
|
|
14962
|
-
|
|
15538
|
+
return perNode;
|
|
15539
|
+
}
|
|
15540
|
+
#fetchWindow(from,to){
|
|
15541
|
+
if(this.#destroyed)return;
|
|
15542
|
+
for(const[node,span]of this.#spans(from,to)){
|
|
14963
15543
|
node.cache.protect(span.min,span.max);
|
|
14964
15544
|
const firstBlock=node.cache.blockOf(span.min);
|
|
14965
15545
|
const lastBlock=node.cache.blockOf(span.max);
|
|
@@ -14968,7 +15548,6 @@ if(node.count!==null&&id*node.cache.pageSize>=node.count)break;
|
|
|
14968
15548
|
if(node.cache.has(id))continue;
|
|
14969
15549
|
this.#fetchBlock(node,id);
|
|
14970
15550
|
}
|
|
14971
|
-
for(const id of node.cache.evict())this.#forgetBlock(node,id);
|
|
14972
15551
|
}
|
|
14973
15552
|
}
|
|
14974
15553
|
apply(change){
|
|
@@ -15004,16 +15583,20 @@ return result;
|
|
|
15004
15583
|
}
|
|
15005
15584
|
reload(opts){
|
|
15006
15585
|
this.#scope.abortAll('reload');
|
|
15586
|
+
this.#settledFetch.cancel();
|
|
15007
15587
|
if(opts&&opts.keepExpanded===false)this.#expanded.clear();
|
|
15008
15588
|
this.#dropCaches();
|
|
15009
15589
|
this.#emit('model:changed',{reason:'reload'});
|
|
15010
15590
|
}
|
|
15011
15591
|
destroy(){
|
|
15012
15592
|
this.#destroyed=true;
|
|
15593
|
+
this.#settledFetch.cancel();
|
|
15013
15594
|
this.#scope.abortAll('destroyed');
|
|
15014
15595
|
this.#dropCaches();
|
|
15015
15596
|
this.#nodes.clear();
|
|
15016
15597
|
this.#expanded.clear();
|
|
15598
|
+
if(this.#fullMemory&&isFunction(this.#fullMemory.destroy))this.#fullMemory.destroy();
|
|
15599
|
+
this.#fullMemory=null;
|
|
15017
15600
|
}
|
|
15018
15601
|
expand(key){
|
|
15019
15602
|
if(this.#expanded.has(key))return;
|
|
@@ -15028,6 +15611,65 @@ this.#emit('model:changed',{reason:'collapse',key});
|
|
|
15028
15611
|
}
|
|
15029
15612
|
expandedKeys(){return[...this.#expanded];}
|
|
15030
15613
|
pivotFields(){return this.#pivotFields;}
|
|
15614
|
+
#fullFrame(){
|
|
15615
|
+
const fn=(this.#config).fullFrame;
|
|
15616
|
+
return isFunction(fn)?fn():null;
|
|
15617
|
+
}
|
|
15618
|
+
#memory(){
|
|
15619
|
+
const frame=this.#fullFrame();
|
|
15620
|
+
if(!frame)return null;
|
|
15621
|
+
if(!this.#fullMemory){
|
|
15622
|
+
this.#fullMemory=new MemorySource({mode:'memory'},this.#delegateCtx());
|
|
15623
|
+
}
|
|
15624
|
+
if(frame.version!==this.#fullFrameVersion){
|
|
15625
|
+
this.#fullMemory.setRows(frame.rows);
|
|
15626
|
+
this.#fullFrameVersion=frame.version;
|
|
15627
|
+
}
|
|
15628
|
+
return this.#fullMemory;
|
|
15629
|
+
}
|
|
15630
|
+
#delegateCtx(){
|
|
15631
|
+
const base=this.#ctx;
|
|
15632
|
+
const state=(base.state)||{};
|
|
15633
|
+
return{
|
|
15634
|
+
...base,
|
|
15635
|
+
state:{...state,page:()=>0,pageSize:()=>0},
|
|
15636
|
+
};
|
|
15637
|
+
}
|
|
15638
|
+
#fullFilteredIndices(){
|
|
15639
|
+
const memory=this.#memory();
|
|
15640
|
+
return memory?memory.filteredIndices():new Uint32Array(0);
|
|
15641
|
+
}
|
|
15642
|
+
#fullUnfilteredIndices(){
|
|
15643
|
+
const memory=this.#memory();
|
|
15644
|
+
return memory?memory.unfilteredIndices():new Uint32Array(0);
|
|
15645
|
+
}
|
|
15646
|
+
#fullHandleFor(colId){
|
|
15647
|
+
const memory=this.#memory();
|
|
15648
|
+
return memory?memory.handleFor(colId):undefined;
|
|
15649
|
+
}
|
|
15650
|
+
#fullDisplay(){
|
|
15651
|
+
const memory=this.#memory();
|
|
15652
|
+
return memory?memory.display():[];
|
|
15653
|
+
}
|
|
15654
|
+
#fullFacetIndices(colId){
|
|
15655
|
+
const memory=this.#memory();
|
|
15656
|
+
return memory&&isFunction(memory.facetIndices)?memory.facetIndices(colId):new Uint32Array(0);
|
|
15657
|
+
}
|
|
15658
|
+
#fullGrandTotalRow(){
|
|
15659
|
+
const memory=this.#memory();
|
|
15660
|
+
return memory&&isFunction(memory.grandTotalRow)?memory.grandTotalRow():null;
|
|
15661
|
+
}
|
|
15662
|
+
#fullUnfilteredRows(){
|
|
15663
|
+
const memory=this.#memory();
|
|
15664
|
+
if(memory&&isFunction(memory.unfilteredRows))return memory.unfilteredRows();
|
|
15665
|
+
const out=[];
|
|
15666
|
+
const n=this.count();
|
|
15667
|
+
for(let i=0;i<n;i++){
|
|
15668
|
+
const row=this.at(i);
|
|
15669
|
+
if(row)out.push(row);
|
|
15670
|
+
}
|
|
15671
|
+
return out;
|
|
15672
|
+
}
|
|
15031
15673
|
#buildRequest(node,id,signal){
|
|
15032
15674
|
const{start,end}=node.cache.rangeOf(id);
|
|
15033
15675
|
const groupBy=this.#state('groupBy',[]);
|
|
@@ -15176,11 +15818,12 @@ this.#rows.delete(slot);
|
|
|
15176
15818
|
}
|
|
15177
15819
|
#restartIfQueryChanged(){
|
|
15178
15820
|
const signature=this.#querySignature();
|
|
15179
|
-
if(signature===this.#signature)return;
|
|
15821
|
+
if(signature===this.#signature)return false;
|
|
15180
15822
|
this.#signature=signature;
|
|
15181
15823
|
this.#scope.abortAll('query');
|
|
15182
15824
|
this.#dropCaches();
|
|
15183
15825
|
this.#emit('model:changed',{reason:'query'});
|
|
15826
|
+
return true;
|
|
15184
15827
|
}
|
|
15185
15828
|
#dropCaches(){
|
|
15186
15829
|
for(const node of this.#nodes.values()){
|
|
@@ -17158,6 +17801,205 @@ function createDerivedSource(config,ctx){
|
|
|
17158
17801
|
return new DerivedSource(config,ctx);
|
|
17159
17802
|
}
|
|
17160
17803
|
});
|
|
17804
|
+
__def("packages/core/src/source/aggregates.js",function(__exports,__req){
|
|
17805
|
+
'use strict';
|
|
17806
|
+
Object.defineProperty(__exports,"STAT_PUSHDOWN",{enumerable:true,get:function(){return STAT_PUSHDOWN;}});
|
|
17807
|
+
Object.defineProperty(__exports,"pushableAggregates",{enumerable:true,get:function(){return pushableAggregates;}});
|
|
17808
|
+
Object.defineProperty(__exports,"fillAggregateSql",{enumerable:true,get:function(){return fillAggregateSql;}});
|
|
17809
|
+
Object.defineProperty(__exports,"resolveAggregatesConfig",{enumerable:true,get:function(){return resolveAggregatesConfig;}});
|
|
17810
|
+
Object.defineProperty(__exports,"routeAggregate",{enumerable:true,get:function(){return routeAggregate;}});
|
|
17811
|
+
Object.defineProperty(__exports,"resolveAggregatePlan",{enumerable:true,get:function(){return resolveAggregatePlan;}});
|
|
17812
|
+
Object.defineProperty(__exports,"groupKeysPushable",{enumerable:true,get:function(){return groupKeysPushable;}});
|
|
17813
|
+
Object.defineProperty(__exports,"pushdownDocRows",{enumerable:true,get:function(){return pushdownDocRows;}});
|
|
17814
|
+
const STAT_PUSHDOWN=Object.freeze({
|
|
17815
|
+
sum:{pushable:true,class:'identical',sql:'sum(%c)'},
|
|
17816
|
+
avg:{pushable:true,class:'identical',sql:'avg(%c)'},
|
|
17817
|
+
min:{pushable:true,class:'identical',sql:'min(%c)'},
|
|
17818
|
+
max:{pushable:true,class:'identical',sql:'max(%c)'},
|
|
17819
|
+
count:{pushable:true,class:'identical',sql:'count(*)'},
|
|
17820
|
+
countValues:{pushable:true,class:'identical',sql:'count(%c)',blankAware:true},
|
|
17821
|
+
range:{pushable:true,class:'identical',sql:'(max(%c) - min(%c))'},
|
|
17822
|
+
variance:{pushable:true,class:'identical',sql:'var_samp(%c)'},
|
|
17823
|
+
varianceP:{pushable:true,class:'identical',sql:'var_pop(%c)'},
|
|
17824
|
+
stddev:{pushable:true,class:'identical',sql:'stddev_samp(%c)'},
|
|
17825
|
+
stddevP:{pushable:true,class:'identical',sql:'stddev_pop(%c)'},
|
|
17826
|
+
sumSquares:{pushable:true,class:'identical',sql:'sum(%c * %c)'},
|
|
17827
|
+
median:{pushable:true,class:'identical',sql:'median(%c)'},
|
|
17828
|
+
p25:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.25)'},
|
|
17829
|
+
p75:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.75)'},
|
|
17830
|
+
p90:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.9)'},
|
|
17831
|
+
p95:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.95)'},
|
|
17832
|
+
p99:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.99)'},
|
|
17833
|
+
iqr:{
|
|
17834
|
+
pushable:true,class:'identical',
|
|
17835
|
+
sql:'(quantile_cont(%c, 0.75) - quantile_cont(%c, 0.25))',
|
|
17836
|
+
},
|
|
17837
|
+
mad:{pushable:true,class:'identical',sql:'mad(%c)'},
|
|
17838
|
+
distinct:{pushable:true,class:'identical',sql:'count(DISTINCT %c)',blankAware:true},
|
|
17839
|
+
skewness:{pushable:true,class:'identical',sql:'skewness(%c)'},
|
|
17840
|
+
kurtosis:{pushable:true,class:'identical',sql:'kurtosis(%c)'},
|
|
17841
|
+
geomean:{pushable:true,class:'identical',sql:'exp(avg(ln(%c)))'},
|
|
17842
|
+
harmean:{pushable:true,class:'identical',sql:'(count(%c) / sum(1.0 / %c))'},
|
|
17843
|
+
entropy:{pushable:true,class:'identical',sql:'entropy(%c)',blankAware:true},
|
|
17844
|
+
correlation:{
|
|
17845
|
+
pushable:true,class:'identical',sql:'corr(%w, %c)',twoColumn:true,
|
|
17846
|
+
},
|
|
17847
|
+
hhi:{
|
|
17848
|
+
pushable:true,class:'identical',blankAware:true,
|
|
17849
|
+
sql:'CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_transform('
|
|
17850
|
+
+'map_values(histogram(%c)), lambda v: (v::DOUBLE/count(%c))*(v::DOUBLE/count(%c)))) END',
|
|
17851
|
+
},
|
|
17852
|
+
evenness:{
|
|
17853
|
+
pushable:true,class:'identical',blankAware:true,
|
|
17854
|
+
sql:'CASE WHEN count(%c)=0 THEN NULL WHEN count(DISTINCT %c)<2 THEN 1.0 '
|
|
17855
|
+
+'ELSE entropy(%c)/log2(count(DISTINCT %c)) END',
|
|
17856
|
+
},
|
|
17857
|
+
top3Share:{
|
|
17858
|
+
pushable:true,class:'identical',blankAware:true,
|
|
17859
|
+
sql:'CASE WHEN count(%c)=0 THEN NULL ELSE '
|
|
17860
|
+
+"list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,3))::DOUBLE/count(%c) END",
|
|
17861
|
+
},
|
|
17862
|
+
top10Share:{
|
|
17863
|
+
pushable:true,class:'identical',blankAware:true,
|
|
17864
|
+
sql:'CASE WHEN count(%c)=0 THEN NULL ELSE '
|
|
17865
|
+
+"list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,10))::DOUBLE/count(%c) END",
|
|
17866
|
+
},
|
|
17867
|
+
gini:{
|
|
17868
|
+
pushable:true,class:'identical',
|
|
17869
|
+
sql:'CASE WHEN list_min(list(%c) FILTER (WHERE isfinite(%c)))<0 THEN NULL '
|
|
17870
|
+
+'WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL '
|
|
17871
|
+
+'WHEN list_sum(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN 0 ELSE '
|
|
17872
|
+
+'2.0*list_sum(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v, i: i*v))'
|
|
17873
|
+
+'/(len(list(%c) FILTER (WHERE isfinite(%c)))*list_sum(list(%c) FILTER (WHERE isfinite(%c))))'
|
|
17874
|
+
+'-(len(list(%c) FILTER (WHERE isfinite(%c)))+1.0)/len(list(%c) FILTER (WHERE isfinite(%c))) END',
|
|
17875
|
+
},
|
|
17876
|
+
trimmedMean:{
|
|
17877
|
+
pushable:true,class:'identical',
|
|
17878
|
+
sql:'CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE '
|
|
17879
|
+
+'list_avg(list_slice(list_sort(list(%c) FILTER (WHERE isfinite(%c))), '
|
|
17880
|
+
+'floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1, '
|
|
17881
|
+
+'len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT)) END',
|
|
17882
|
+
},
|
|
17883
|
+
winsorizedMean:{
|
|
17884
|
+
pushable:true,class:'identical',
|
|
17885
|
+
sql:'CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE '
|
|
17886
|
+
+'list_avg(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v: '
|
|
17887
|
+
+'least(list_sort(list(%c) FILTER (WHERE isfinite(%c)))'
|
|
17888
|
+
+'[len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT], '
|
|
17889
|
+
+'greatest(list_sort(list(%c) FILTER (WHERE isfinite(%c)))'
|
|
17890
|
+
+'[floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1], v)))) END',
|
|
17891
|
+
},
|
|
17892
|
+
robustOutliers:{
|
|
17893
|
+
pushable:true,class:'identical',
|
|
17894
|
+
sql:'(SELECT CASE WHEN len(d.a)=0 THEN NULL WHEN d.mad=0 THEN NULL ELSE '
|
|
17895
|
+
+'len(list_filter(d.a, lambda v: abs(0.6745*(v-d.med)/d.mad)>3.5)) END FROM '
|
|
17896
|
+
+'(SELECT xs AS a, list_median(xs) AS med, '
|
|
17897
|
+
+'list_median(list_transform(xs, lambda w: abs(w-list_median(xs)))) AS mad '
|
|
17898
|
+
+'FROM (SELECT list(%c) FILTER (WHERE isfinite(%c)) AS xs)) d)',
|
|
17899
|
+
},
|
|
17900
|
+
jarqueBera:{
|
|
17901
|
+
pushable:true,class:'identical',
|
|
17902
|
+
sql:'CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))<8 THEN NULL '
|
|
17903
|
+
+'WHEN list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), '
|
|
17904
|
+
+'lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2)))=0 THEN NULL ELSE '
|
|
17905
|
+
+'(len(list(%c) FILTER (WHERE isfinite(%c)))/6.0)*('
|
|
17906
|
+
+'power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),3)))'
|
|
17907
|
+
+'/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),1.5),2)'
|
|
17908
|
+
+'+power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),4)))'
|
|
17909
|
+
+'/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),2)-3,2)/4.0) END',
|
|
17910
|
+
},
|
|
17911
|
+
weightedAvg:{
|
|
17912
|
+
pushable:true,class:'identical',twoColumn:true,
|
|
17913
|
+
sql:'sum(%c*%w) FILTER (WHERE isfinite(%c) AND isfinite(%w))'
|
|
17914
|
+
+'/nullif(sum(%w) FILTER (WHERE isfinite(%c) AND isfinite(%w)),0)',
|
|
17915
|
+
},
|
|
17916
|
+
mode:{
|
|
17917
|
+
pushable:true,class:'may-differ',sql:'mode(%c)',
|
|
17918
|
+
note:'DuckDB returns a modal value even for an all-distinct column; the grid '
|
|
17919
|
+
+'returns null. Tie-breaking can also differ, and on a text column an empty '
|
|
17920
|
+
+'string counts as a value. Under pushdown you will see a value.',
|
|
17921
|
+
},
|
|
17922
|
+
weightedQuantile:{
|
|
17923
|
+
pushable:false,class:'fallback',
|
|
17924
|
+
note:'No SQL equivalent for the grid\'s weighted-quantile midpoint convention; '
|
|
17925
|
+
+'always computed client-side (needs a full-dataset pull for a correct figure '
|
|
17926
|
+
+'over a remote source).',
|
|
17927
|
+
},
|
|
17928
|
+
});
|
|
17929
|
+
function pushableAggregates(){
|
|
17930
|
+
const set=new Set();
|
|
17931
|
+
for(const[name,spec]of Object.entries(STAT_PUSHDOWN))if(spec.pushable)set.add(name);
|
|
17932
|
+
return set;
|
|
17933
|
+
}
|
|
17934
|
+
function fillAggregateSql(template,colExpr,weightExpr){
|
|
17935
|
+
let out=template.split('%c').join(colExpr);
|
|
17936
|
+
if(weightExpr!==undefined)out=out.split('%w').join(weightExpr);
|
|
17937
|
+
return out;
|
|
17938
|
+
}
|
|
17939
|
+
function resolveAggregatesConfig(declared){
|
|
17940
|
+
const cfg=declared||{};
|
|
17941
|
+
const def=cfg.default==='engine'||cfg.default==='engine-if-identical'
|
|
17942
|
+
?cfg.default:'client';
|
|
17943
|
+
const overrides={};
|
|
17944
|
+
if(cfg.overrides&&typeof cfg.overrides==='object'){
|
|
17945
|
+
for(const[name,mode]of Object.entries(cfg.overrides)){
|
|
17946
|
+
if(mode==='engine'||mode==='client')overrides[name]=mode;
|
|
17947
|
+
}
|
|
17948
|
+
}
|
|
17949
|
+
return{default:def,overrides};
|
|
17950
|
+
}
|
|
17951
|
+
function routeAggregate(fn,config){
|
|
17952
|
+
const spec=STAT_PUSHDOWN[fn];
|
|
17953
|
+
if(!spec||!spec.pushable)return'client';
|
|
17954
|
+
const override=config.overrides[fn];
|
|
17955
|
+
if(override==='engine'||override==='client')return override;
|
|
17956
|
+
if(config.default==='client')return'client';
|
|
17957
|
+
if(config.default==='engine-if-identical'){
|
|
17958
|
+
return spec.class==='identical'?'engine':'client';
|
|
17959
|
+
}
|
|
17960
|
+
return'engine';
|
|
17961
|
+
}
|
|
17962
|
+
function resolveAggregatePlan(requested,declared){
|
|
17963
|
+
const config=resolveAggregatesConfig(declared);
|
|
17964
|
+
const engine=[];
|
|
17965
|
+
const client=[];
|
|
17966
|
+
for(const agg of requested||[]){
|
|
17967
|
+
const spec=STAT_PUSHDOWN[agg.fn];
|
|
17968
|
+
const where=routeAggregate(agg.fn,config);
|
|
17969
|
+
const record={
|
|
17970
|
+
id:agg.id,
|
|
17971
|
+
col:agg.col,
|
|
17972
|
+
fn:agg.fn,
|
|
17973
|
+
class:spec?spec.class:'fallback',
|
|
17974
|
+
};
|
|
17975
|
+
if(agg.weight!==undefined)record.weight=agg.weight;
|
|
17976
|
+
if(agg.params!==undefined)record.params=agg.params;
|
|
17977
|
+
if(where==='engine'){
|
|
17978
|
+
engine.push(record);
|
|
17979
|
+
}else{
|
|
17980
|
+
record.reason=spec&&!spec.pushable
|
|
17981
|
+
?(spec.note||'the engine cannot express this stat')
|
|
17982
|
+
:'client by config';
|
|
17983
|
+
client.push(record);
|
|
17984
|
+
}
|
|
17985
|
+
}
|
|
17986
|
+
return{engine,client,config};
|
|
17987
|
+
}
|
|
17988
|
+
const PLAIN_IDENTIFIER=/^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
17989
|
+
function groupKeysPushable(groupBy){
|
|
17990
|
+
const keys=groupBy||[];
|
|
17991
|
+
return keys.every((key)=>typeof key==='string'&&PLAIN_IDENTIFIER.test(key));
|
|
17992
|
+
}
|
|
17993
|
+
function pushdownDocRows(){
|
|
17994
|
+
return Object.entries(STAT_PUSHDOWN).map(([stat,spec])=>({
|
|
17995
|
+
stat,
|
|
17996
|
+
class:spec.class,
|
|
17997
|
+
sql:spec.sql?fillAggregateSql(spec.sql,'col',spec.twoColumn?'weight':undefined):'',
|
|
17998
|
+
note:spec.note||(spec.class==='identical'
|
|
17999
|
+
?'Pushes to DuckDB with the same result.':''),
|
|
18000
|
+
}));
|
|
18001
|
+
}
|
|
18002
|
+
});
|
|
17161
18003
|
__def("packages/core/src/source/pushdown.js",function(__exports,__req){
|
|
17162
18004
|
'use strict';
|
|
17163
18005
|
Object.defineProperty(__exports,"NO_CAPABILITIES",{enumerable:true,get:function(){return NO_CAPABILITIES;}});
|
|
@@ -17171,6 +18013,9 @@ const isFunction=__m0["isFunction"];
|
|
|
17171
18013
|
const warnOnce=__m0["warnOnce"];
|
|
17172
18014
|
const __m1=__req("packages/core/src/source/filterwire.js");
|
|
17173
18015
|
const isGroup=__m1["isGroup"];
|
|
18016
|
+
const __m2=__req("packages/core/src/source/aggregates.js");
|
|
18017
|
+
const resolveAggregatePlan=__m2["resolveAggregatePlan"];
|
|
18018
|
+
const groupKeysPushable=__m2["groupKeysPushable"];
|
|
17174
18019
|
const NO_CAPABILITIES=Object.freeze({
|
|
17175
18020
|
filter:false,
|
|
17176
18021
|
operators:Object.freeze([]),
|
|
@@ -17245,7 +18090,7 @@ const group=(list)=>(list.length===0?null
|
|
|
17245
18090
|
:(list.length===1?list[0]:{op:'and',conditions:list}));
|
|
17246
18091
|
return{pushed:group(pushed),residual:group(residual)};
|
|
17247
18092
|
}
|
|
17248
|
-
function planQuery(request,caps){
|
|
18093
|
+
function planQuery(request,caps,fullDataset=false){
|
|
17249
18094
|
const filters=splitFilters(request.filters||null,caps);
|
|
17250
18095
|
const unpushed=[];
|
|
17251
18096
|
if(filters.residual)unpushed.push('filter');
|
|
@@ -17262,7 +18107,8 @@ filters:filters.residual,
|
|
|
17262
18107
|
sort:sortPushable?null:wanted,
|
|
17263
18108
|
quick:quickPushable?'':quick,
|
|
17264
18109
|
};
|
|
17265
|
-
const
|
|
18110
|
+
const full=!!fullDataset;
|
|
18111
|
+
const needsAll=full||!!(residual.filters||residual.sort||residual.quick)||!caps.range;
|
|
17266
18112
|
const pushed={
|
|
17267
18113
|
...request,
|
|
17268
18114
|
filters:filters.pushed,
|
|
@@ -17270,7 +18116,7 @@ sort:sortPushable?wanted:[],
|
|
|
17270
18116
|
quick:quickPushable?quick:'',
|
|
17271
18117
|
range:needsAll?null:request.range,
|
|
17272
18118
|
};
|
|
17273
|
-
return{pushed,residual,needsAll,unpushed};
|
|
18119
|
+
return{pushed,residual,needsAll,unpushed,full};
|
|
17274
18120
|
}
|
|
17275
18121
|
function applyResidual(rows,residual,compute){
|
|
17276
18122
|
if(!residual)return rows;
|
|
@@ -17320,6 +18166,21 @@ groupPath:pushed.groupPath||[],
|
|
|
17320
18166
|
context:pushed.context??null,
|
|
17321
18167
|
});
|
|
17322
18168
|
}
|
|
18169
|
+
function estimateRowBytes(row){
|
|
18170
|
+
if(!row||typeof row!=='object')return 16;
|
|
18171
|
+
let text='';
|
|
18172
|
+
try{text=JSON.stringify(row);}catch{return 200;}
|
|
18173
|
+
return text.length*2+64;
|
|
18174
|
+
}
|
|
18175
|
+
function resolveFullDataset(declared){
|
|
18176
|
+
const cfg=declared||{};
|
|
18177
|
+
return{
|
|
18178
|
+
enabled:!!cfg.enabled,
|
|
18179
|
+
maxRows:Number.isFinite(cfg.maxRows)?cfg.maxRows:1_000_000,
|
|
18180
|
+
maxBytesEstimate:Number.isFinite(cfg.maxBytesEstimate)
|
|
18181
|
+
?cfg.maxBytesEstimate:512*1024*1024,
|
|
18182
|
+
};
|
|
18183
|
+
}
|
|
17323
18184
|
function createPushdownSource(config={}){
|
|
17324
18185
|
const adapter=config.adapter;
|
|
17325
18186
|
if(!adapter||!isFunction(adapter.execute)){
|
|
@@ -17329,10 +18190,24 @@ return{...config,mode:'remote',fetch:async()=>({rows:[],total:0})};
|
|
|
17329
18190
|
}
|
|
17330
18191
|
const caps=capabilitiesOf(adapter.capabilities);
|
|
17331
18192
|
const name=adapter.name||'adapter';
|
|
18193
|
+
const full=resolveFullDataset(config.fullDataset);
|
|
18194
|
+
const allowPartialResults=!!config.allowPartialResults;
|
|
18195
|
+
const aggregatesConfig=config.aggregates;
|
|
17332
18196
|
let held=null;
|
|
17333
18197
|
let lastPlan=null;
|
|
18198
|
+
let lastAggregates=null;
|
|
18199
|
+
let heldVersion=0;
|
|
18200
|
+
let heldVersionKey=null;
|
|
18201
|
+
const fullFrame=()=>{
|
|
18202
|
+
if(!full.enabled||!held)return null;
|
|
18203
|
+
if(heldVersionKey!==held.key){
|
|
18204
|
+
heldVersion++;
|
|
18205
|
+
heldVersionKey=held.key;
|
|
18206
|
+
}
|
|
18207
|
+
return{rows:held.rows,version:heldVersion};
|
|
18208
|
+
};
|
|
17334
18209
|
const fetch=async(request)=>{
|
|
17335
|
-
const plan=planQuery(request,caps);
|
|
18210
|
+
const plan=planQuery(request,caps,full.enabled);
|
|
17336
18211
|
lastPlan=plan;
|
|
17337
18212
|
if(!plan.needsAll){
|
|
17338
18213
|
const result=await adapter.execute(plan.pushed,request);
|
|
@@ -17348,21 +18223,51 @@ const key=planKey(plan.pushed);
|
|
|
17348
18223
|
if(!held||held.key!==key){
|
|
17349
18224
|
const result=await adapter.execute(plan.pushed,request);
|
|
17350
18225
|
const rows=result.rows||[];
|
|
18226
|
+
if(plan.full){
|
|
18227
|
+
const matching=typeof result.total==='number'
|
|
18228
|
+
?Math.max(result.total,rows.length):rows.length;
|
|
18229
|
+
if(matching>full.maxRows){
|
|
18230
|
+
throw new Error(
|
|
18231
|
+
`[lattice] fullDataset refused: the ${name} adapter's matching set is `
|
|
18232
|
+
+`${matching.toLocaleString()} rows, past the configured maxRows of `
|
|
18233
|
+
+`${full.maxRows.toLocaleString()}. The whole set cannot be held client-side, so it `
|
|
18234
|
+
+'is refused rather than truncated — a fraction shown as the whole would make every '
|
|
18235
|
+
+'total and statistic silently wrong. Narrow the filter or raise maxRows.');
|
|
18236
|
+
}
|
|
18237
|
+
const bytes=rows.length*estimateRowBytes(rows[0]);
|
|
18238
|
+
if(bytes>full.maxBytesEstimate){
|
|
18239
|
+
throw new Error(
|
|
18240
|
+
`[lattice] fullDataset refused: the ${name} adapter's matching set is an estimated `
|
|
18241
|
+
+`${Math.round(bytes/(1024*1024)).toLocaleString()} MB across `
|
|
18242
|
+
+`${rows.length.toLocaleString()} rows, past the configured maxBytesEstimate of `
|
|
18243
|
+
+`${Math.round(full.maxBytesEstimate/(1024*1024)).toLocaleString()} MB. The whole `
|
|
18244
|
+
+'set cannot be held client-side, so it is refused rather than truncated. Narrow the '
|
|
18245
|
+
+'filter or raise maxBytesEstimate.');
|
|
18246
|
+
}
|
|
18247
|
+
}
|
|
17351
18248
|
if(typeof result.total==='number'&&rows.length<result.total){
|
|
17352
18249
|
const hasResidual=!!(plan.residual.filters||plan.residual.quick
|
|
17353
18250
|
||(plan.residual.sort&&plan.residual.sort.length));
|
|
17354
|
-
if(hasResidual){
|
|
18251
|
+
if(hasResidual&&!allowPartialResults){
|
|
17355
18252
|
throw new Error(
|
|
17356
18253
|
`[lattice] the ${name} adapter returned ${rows.length} of ${result.total} matching `
|
|
17357
18254
|
+'rows when asked for the whole result, and the query has residual '
|
|
17358
18255
|
+`${plan.unpushed.join(' and ')||'work'} to finish in the browser. Filtering or `
|
|
17359
18256
|
+'sorting a fraction of the result would return wrong rows, so the result is refused. '
|
|
17360
|
-
+'
|
|
17361
|
-
|
|
18257
|
+
+'Fix the adapter to follow the engine\'s own paging before returning, hold the data in '
|
|
18258
|
+
+'memory, or set `allowPartialResults: true` on the source config to accept this knowingly.');
|
|
18259
|
+
}else if(hasResidual){
|
|
18260
|
+
warnOnce(`source.pushdown.partial.residual.${name}`,
|
|
18261
|
+
`the ${name} adapter returned ${rows.length} of ${result.total} matching rows when asked `
|
|
18262
|
+
+'for the whole result, and residual work will run over that fraction. '
|
|
18263
|
+
+'allowPartialResults is set, so the result is used as-is — it may be wrong. '
|
|
18264
|
+
+'The adapter must follow the engine\'s own paging to be correct.');
|
|
18265
|
+
}else{
|
|
17362
18266
|
warnOnce(`source.pushdown.partial.${name}`,
|
|
17363
18267
|
`the ${name} adapter returned ${rows.length} of ${result.total} matching rows when asked `
|
|
17364
18268
|
+'for the whole result. The adapter must follow the engine\'s own paging before returning.');
|
|
17365
18269
|
}
|
|
18270
|
+
}
|
|
17366
18271
|
held={key,rows};
|
|
17367
18272
|
}
|
|
17368
18273
|
const rows=applyResidual(held.rows,plan.residual,config.compute||{});
|
|
@@ -17370,11 +18275,56 @@ const start=request.range?request.range.start:0;
|
|
|
17370
18275
|
const end=request.range?request.range.end:rows.length;
|
|
17371
18276
|
return{rows:rows.slice(start,end),total:rows.length};
|
|
17372
18277
|
};
|
|
18278
|
+
const aggregate=async(request,requested)=>{
|
|
18279
|
+
const plan=planQuery(request,caps,full.enabled);
|
|
18280
|
+
lastPlan=plan;
|
|
18281
|
+
const split=resolveAggregatePlan(requested,aggregatesConfig);
|
|
18282
|
+
const groupBy=Array.isArray(request.groupBy)?request.groupBy:[];
|
|
18283
|
+
const grouped=groupBy.length>0;
|
|
18284
|
+
const filterFullyPushed=!plan.residual.filters;
|
|
18285
|
+
const groupingPushable=!grouped||groupKeysPushable(groupBy);
|
|
18286
|
+
let engine=split.engine;
|
|
18287
|
+
let client=split.client;
|
|
18288
|
+
const fallAllToClient=(reason)=>{
|
|
18289
|
+
client=[...engine.map((agg)=>({...agg,reason})),...client];
|
|
18290
|
+
engine=[];
|
|
18291
|
+
};
|
|
18292
|
+
if(engine.length&&!filterFullyPushed){
|
|
18293
|
+
fallAllToClient('residual filter forces all-client (no mixed provenance)');
|
|
18294
|
+
}else if(engine.length&&!groupingPushable){
|
|
18295
|
+
fallAllToClient('a grouping key the engine cannot form forces all-client (no mixed provenance)');
|
|
18296
|
+
}
|
|
18297
|
+
let values={};
|
|
18298
|
+
let groups;
|
|
18299
|
+
if(engine.length){
|
|
18300
|
+
const canCompute=grouped
|
|
18301
|
+
?isFunction(adapter.executeGroupedAggregates)
|
|
18302
|
+
:isFunction(adapter.executeAggregates);
|
|
18303
|
+
if(!canCompute){
|
|
18304
|
+
warnOnce(`source.pushdown.aggregates.${name}${grouped?'.grouped':''}`,
|
|
18305
|
+
`the ${name} adapter cannot compute ${grouped?'grouped ':''}aggregates, so every `
|
|
18306
|
+
+'requested statistic is computed client-side. Correct, and slower than it needs to be.');
|
|
18307
|
+
fallAllToClient(`adapter cannot compute ${grouped?'grouped ':''}aggregates`);
|
|
18308
|
+
}else if(grouped){
|
|
18309
|
+
groups=await adapter.executeGroupedAggregates(plan.pushed,groupBy,engine)||[];
|
|
18310
|
+
}else{
|
|
18311
|
+
values=await adapter.executeAggregates(plan.pushed,engine)||{};
|
|
18312
|
+
}
|
|
18313
|
+
}
|
|
18314
|
+
lastAggregates={engine,client,...(grouped?{groupBy}:{})};
|
|
18315
|
+
return{
|
|
18316
|
+
values,engine,client,...(groups!==undefined?{groups}:{}),
|
|
18317
|
+
};
|
|
18318
|
+
};
|
|
17373
18319
|
return{
|
|
17374
18320
|
...config,
|
|
17375
18321
|
mode:'remote',
|
|
17376
18322
|
fetch,
|
|
17377
|
-
|
|
18323
|
+
aggregate,
|
|
18324
|
+
lastPlan:()=>(lastPlan
|
|
18325
|
+
?{...lastPlan,...(lastAggregates?{aggregates:lastAggregates}:{})}
|
|
18326
|
+
:null),
|
|
18327
|
+
fullFrame,
|
|
17378
18328
|
};
|
|
17379
18329
|
}
|
|
17380
18330
|
});
|
|
@@ -17625,6 +18575,11 @@ const isFunction=__m0["isFunction"];
|
|
|
17625
18575
|
const warnOnce=__m0["warnOnce"];
|
|
17626
18576
|
const __m1=__req("packages/core/src/source/filterwire.js");
|
|
17627
18577
|
const isGroup=__m1["isGroup"];
|
|
18578
|
+
const __m2=__req("packages/core/src/source/aggregates.js");
|
|
18579
|
+
const STAT_PUSHDOWN=__m2["STAT_PUSHDOWN"];
|
|
18580
|
+
const fillAggregateSql=__m2["fillAggregateSql"];
|
|
18581
|
+
const pushableAggregates=__m2["pushableAggregates"];
|
|
18582
|
+
const groupKeysPushable=__m2["groupKeysPushable"];
|
|
17628
18583
|
const OPERATORS=Object.freeze([
|
|
17629
18584
|
'eq','ne','gt','gte','lt','lte','contains','startsWith','endsWith',
|
|
17630
18585
|
'blank','notBlank','in',
|
|
@@ -17686,6 +18641,7 @@ sort:'multi',
|
|
|
17686
18641
|
quick:false,
|
|
17687
18642
|
range:true,
|
|
17688
18643
|
total:true,
|
|
18644
|
+
aggregates:pushableAggregates(),
|
|
17689
18645
|
},
|
|
17690
18646
|
sqlFor(query){
|
|
17691
18647
|
const params=[];
|
|
@@ -17735,8 +18691,120 @@ return plain;
|
|
|
17735
18691
|
});
|
|
17736
18692
|
return{rows,total:total===null?rows.length:total};
|
|
17737
18693
|
},
|
|
18694
|
+
aggregateSqlFor(query,aggregates){
|
|
18695
|
+
const params=[];
|
|
18696
|
+
const where=filtersToSql(query.filters,params);
|
|
18697
|
+
const exprs=aggregateExprs(aggregates);
|
|
18698
|
+
let sql=`SELECT ${exprs.join(', ')} FROM ${from}`;
|
|
18699
|
+
if(where)sql+=` WHERE ${where}`;
|
|
18700
|
+
return{sql,params};
|
|
18701
|
+
},
|
|
18702
|
+
groupedAggregateSqlFor(query,groupBy,aggregates){
|
|
18703
|
+
const keys=Array.isArray(groupBy)?groupBy:[];
|
|
18704
|
+
if(!keys.length)throw new Error('duckdbAdapter: grouped aggregate needs a grouping key');
|
|
18705
|
+
if(!groupKeysPushable(keys)){
|
|
18706
|
+
throw new Error('duckdbAdapter: a grouping key is not a plain column the engine can group by');
|
|
18707
|
+
}
|
|
18708
|
+
const params=[];
|
|
18709
|
+
const where=filtersToSql(query.filters,params);
|
|
18710
|
+
const keyCols=keys.map((unused,i)=>`__lattice_k${i}`);
|
|
18711
|
+
const groupingCols=keys.map((unused,i)=>`__lattice_g${i}`);
|
|
18712
|
+
const keySelect=keys.map((key,i)=>`${ident(key)} AS ${ident(keyCols[i])}`);
|
|
18713
|
+
const groupingSelect=keys
|
|
18714
|
+
.map((key,i)=>`GROUPING(${ident(key)}) AS ${ident(groupingCols[i])}`);
|
|
18715
|
+
const aggExprs=aggregateExprs(aggregates);
|
|
18716
|
+
const rollup=`ROLLUP(${keys.map((key)=>ident(key)).join(', ')})`;
|
|
18717
|
+
let sql=`SELECT ${[...keySelect,...groupingSelect,...aggExprs].join(', ')} FROM ${from}`;
|
|
18718
|
+
if(where)sql+=` WHERE ${where}`;
|
|
18719
|
+
sql+=` GROUP BY ${rollup}`;
|
|
18720
|
+
return{sql,params,keyCols,groupingCols};
|
|
18721
|
+
},
|
|
18722
|
+
async executeGroupedAggregates(query,groupBy,aggregates){
|
|
18723
|
+
if(!connection||!isFunction(connection.query)){
|
|
18724
|
+
throw new Error('duckdbAdapter needs a connection with a query function');
|
|
18725
|
+
}
|
|
18726
|
+
const{
|
|
18727
|
+
sql,params,keyCols,groupingCols,
|
|
18728
|
+
}=this.groupedAggregateSqlFor(query,groupBy,aggregates);
|
|
18729
|
+
let result;
|
|
18730
|
+
if(params.length&&isFunction(connection.prepare)){
|
|
18731
|
+
const statement=await connection.prepare(sql);
|
|
18732
|
+
try{
|
|
18733
|
+
result=await statement.query(...params);
|
|
18734
|
+
}finally{
|
|
18735
|
+
if(isFunction(statement.close))await statement.close();
|
|
18736
|
+
}
|
|
18737
|
+
}else{
|
|
18738
|
+
if(params.length){
|
|
18739
|
+
warnOnce('source.duckdb.unprepared.grouped',
|
|
18740
|
+
'this DuckDB connection has no prepare(), so filter values cannot be bound. '
|
|
18741
|
+
+'Grouped aggregates are not pushed rather than being interpolated into SQL.');
|
|
18742
|
+
return[];
|
|
18743
|
+
}
|
|
18744
|
+
result=await connection.query(sql);
|
|
18745
|
+
}
|
|
18746
|
+
const raw=isFunction(result.toArray)?result.toArray():Array.from(result||[]);
|
|
18747
|
+
return raw.map((row)=>{
|
|
18748
|
+
const plain=isFunction(row.toJSON)?row.toJSON():{...row};
|
|
18749
|
+
const grouping=groupingCols.map((c)=>Number(normalise(plain[c])));
|
|
18750
|
+
const keys=keyCols.map((c)=>normalise(plain[c]));
|
|
18751
|
+
const level=grouping.reduce((acc,flag)=>acc+(flag?0:1),0);
|
|
18752
|
+
const values={};
|
|
18753
|
+
for(const key of Object.keys(plain)){
|
|
18754
|
+
if(keyCols.includes(key)||groupingCols.includes(key))continue;
|
|
18755
|
+
values[key]=normalise(plain[key]);
|
|
18756
|
+
}
|
|
18757
|
+
return{keys,grouping,level,values};
|
|
18758
|
+
});
|
|
18759
|
+
},
|
|
18760
|
+
async executeAggregates(query,aggregates){
|
|
18761
|
+
if(!connection||!isFunction(connection.query)){
|
|
18762
|
+
throw new Error('duckdbAdapter needs a connection with a query function');
|
|
18763
|
+
}
|
|
18764
|
+
const{sql,params}=this.aggregateSqlFor(query,aggregates);
|
|
18765
|
+
let result;
|
|
18766
|
+
if(params.length&&isFunction(connection.prepare)){
|
|
18767
|
+
const statement=await connection.prepare(sql);
|
|
18768
|
+
try{
|
|
18769
|
+
result=await statement.query(...params);
|
|
18770
|
+
}finally{
|
|
18771
|
+
if(isFunction(statement.close))await statement.close();
|
|
18772
|
+
}
|
|
18773
|
+
}else{
|
|
18774
|
+
if(params.length){
|
|
18775
|
+
warnOnce('source.duckdb.unprepared.aggregates',
|
|
18776
|
+
'this DuckDB connection has no prepare(), so filter values cannot be bound. '
|
|
18777
|
+
+'Aggregates are not pushed rather than being interpolated into SQL.');
|
|
18778
|
+
return{};
|
|
18779
|
+
}
|
|
18780
|
+
result=await connection.query(sql);
|
|
18781
|
+
}
|
|
18782
|
+
const raw=isFunction(result.toArray)?result.toArray():Array.from(result||[]);
|
|
18783
|
+
const first=raw[0];
|
|
18784
|
+
if(!first)return{};
|
|
18785
|
+
const plain=isFunction(first.toJSON)?first.toJSON():{...first};
|
|
18786
|
+
const out={};
|
|
18787
|
+
for(const key of Object.keys(plain))out[key]=normalise(plain[key]);
|
|
18788
|
+
return out;
|
|
18789
|
+
},
|
|
17738
18790
|
};
|
|
17739
18791
|
}
|
|
18792
|
+
function aggregateExprs(aggregates){
|
|
18793
|
+
const exprs=(aggregates||[]).map((agg)=>{
|
|
18794
|
+
const spec=STAT_PUSHDOWN[agg.fn];
|
|
18795
|
+
if(!spec||!spec.pushable||!spec.sql){
|
|
18796
|
+
throw new Error(`duckdbAdapter: cannot push aggregate "${agg.fn}"`);
|
|
18797
|
+
}
|
|
18798
|
+
const wrap=(colName)=>(spec.blankAware
|
|
18799
|
+
?`nullif(CAST(${ident(colName)} AS VARCHAR), '')`:ident(colName));
|
|
18800
|
+
const col=wrap(agg.col);
|
|
18801
|
+
const weight=agg.weight!==undefined?wrap(agg.weight):undefined;
|
|
18802
|
+
const body=fillAggregateSql(spec.sql,col,weight);
|
|
18803
|
+
return`${body} AS ${ident(agg.id)}`;
|
|
18804
|
+
});
|
|
18805
|
+
if(!exprs.length)throw new Error('duckdbAdapter: no aggregates to compute');
|
|
18806
|
+
return exprs;
|
|
18807
|
+
}
|
|
17740
18808
|
});
|
|
17741
18809
|
__def("packages/core/src/source/index.js",function(__exports,__req){
|
|
17742
18810
|
'use strict';
|
|
@@ -17800,51 +18868,60 @@ Object.defineProperty(__exports,"dfqlAdapter",{enumerable:true,get:function(){re
|
|
|
17800
18868
|
const __m10=__req("packages/core/src/source/adapters/duckdb.js");
|
|
17801
18869
|
Object.defineProperty(__exports,"duckdbAdapter",{enumerable:true,get:function(){return __m10["duckdbAdapter"];}});
|
|
17802
18870
|
Object.defineProperty(__exports,"filtersToSql",{enumerable:true,get:function(){return __m10["filtersToSql"];}});
|
|
17803
|
-
const __m11=__req("packages/core/src/source/
|
|
17804
|
-
Object.defineProperty(__exports,"
|
|
17805
|
-
Object.defineProperty(__exports,"
|
|
17806
|
-
Object.defineProperty(__exports,"
|
|
17807
|
-
Object.defineProperty(__exports,"
|
|
17808
|
-
Object.defineProperty(__exports,"
|
|
17809
|
-
Object.defineProperty(__exports,"
|
|
17810
|
-
Object.defineProperty(__exports,"
|
|
17811
|
-
Object.defineProperty(__exports,"
|
|
17812
|
-
|
|
17813
|
-
Object.defineProperty(__exports,"
|
|
17814
|
-
|
|
17815
|
-
Object.defineProperty(__exports,"
|
|
17816
|
-
Object.defineProperty(__exports,"
|
|
17817
|
-
Object.defineProperty(__exports,"
|
|
17818
|
-
Object.defineProperty(__exports,"
|
|
17819
|
-
Object.defineProperty(__exports,"
|
|
17820
|
-
|
|
17821
|
-
Object.defineProperty(__exports,"
|
|
17822
|
-
Object.defineProperty(__exports,"
|
|
17823
|
-
|
|
17824
|
-
Object.defineProperty(__exports,"
|
|
17825
|
-
Object.defineProperty(__exports,"
|
|
17826
|
-
Object.defineProperty(__exports,"
|
|
17827
|
-
Object.defineProperty(__exports,"
|
|
17828
|
-
Object.defineProperty(__exports,"
|
|
17829
|
-
|
|
17830
|
-
Object.defineProperty(__exports,"
|
|
17831
|
-
Object.defineProperty(__exports,"
|
|
17832
|
-
Object.defineProperty(__exports,"
|
|
17833
|
-
|
|
17834
|
-
Object.defineProperty(__exports,"
|
|
17835
|
-
Object.defineProperty(__exports,"
|
|
17836
|
-
Object.defineProperty(__exports,"
|
|
17837
|
-
|
|
17838
|
-
Object.defineProperty(__exports,"
|
|
17839
|
-
|
|
17840
|
-
Object.defineProperty(__exports,"
|
|
17841
|
-
Object.defineProperty(__exports,"
|
|
17842
|
-
|
|
17843
|
-
Object.defineProperty(__exports,"
|
|
17844
|
-
Object.defineProperty(__exports,"
|
|
17845
|
-
|
|
17846
|
-
|
|
17847
|
-
Object.defineProperty(__exports,"
|
|
18871
|
+
const __m11=__req("packages/core/src/source/aggregates.js");
|
|
18872
|
+
Object.defineProperty(__exports,"STAT_PUSHDOWN",{enumerable:true,get:function(){return __m11["STAT_PUSHDOWN"];}});
|
|
18873
|
+
Object.defineProperty(__exports,"pushableAggregates",{enumerable:true,get:function(){return __m11["pushableAggregates"];}});
|
|
18874
|
+
Object.defineProperty(__exports,"resolveAggregatePlan",{enumerable:true,get:function(){return __m11["resolveAggregatePlan"];}});
|
|
18875
|
+
Object.defineProperty(__exports,"resolveAggregatesConfig",{enumerable:true,get:function(){return __m11["resolveAggregatesConfig"];}});
|
|
18876
|
+
Object.defineProperty(__exports,"routeAggregate",{enumerable:true,get:function(){return __m11["routeAggregate"];}});
|
|
18877
|
+
Object.defineProperty(__exports,"fillAggregateSql",{enumerable:true,get:function(){return __m11["fillAggregateSql"];}});
|
|
18878
|
+
Object.defineProperty(__exports,"pushdownDocRows",{enumerable:true,get:function(){return __m11["pushdownDocRows"];}});
|
|
18879
|
+
Object.defineProperty(__exports,"groupKeysPushable",{enumerable:true,get:function(){return __m11["groupKeysPushable"];}});
|
|
18880
|
+
const __m12=__req("packages/core/src/source/derive.js");
|
|
18881
|
+
Object.defineProperty(__exports,"derive",{enumerable:true,get:function(){return __m12["derive"];}});
|
|
18882
|
+
Object.defineProperty(__exports,"unnest",{enumerable:true,get:function(){return __m12["unnest"];}});
|
|
18883
|
+
Object.defineProperty(__exports,"readPath",{enumerable:true,get:function(){return __m12["readPath"];}});
|
|
18884
|
+
Object.defineProperty(__exports,"bucketOf",{enumerable:true,get:function(){return __m12["bucketOf"];}});
|
|
18885
|
+
Object.defineProperty(__exports,"applyLimit",{enumerable:true,get:function(){return __m12["applyLimit"];}});
|
|
18886
|
+
Object.defineProperty(__exports,"applyCumulative",{enumerable:true,get:function(){return __m12["applyCumulative"];}});
|
|
18887
|
+
Object.defineProperty(__exports,"reduceValues",{enumerable:true,get:function(){return __m12["reduceValues"];}});
|
|
18888
|
+
Object.defineProperty(__exports,"FOLLOW_MODES",{enumerable:true,get:function(){return __m12["FOLLOW_MODES"];}});
|
|
18889
|
+
Object.defineProperty(__exports,"BUCKETS",{enumerable:true,get:function(){return __m12["BUCKETS"];}});
|
|
18890
|
+
Object.defineProperty(__exports,"DERIVED_ROW_KEY",{enumerable:true,get:function(){return __m12["DERIVED_ROW_KEY"];}});
|
|
18891
|
+
const __m13=__req("packages/core/src/source/abort.js");
|
|
18892
|
+
Object.defineProperty(__exports,"AbortScope",{enumerable:true,get:function(){return __m13["AbortScope"];}});
|
|
18893
|
+
Object.defineProperty(__exports,"RequestToken",{enumerable:true,get:function(){return __m13["RequestToken"];}});
|
|
18894
|
+
Object.defineProperty(__exports,"SupersededError",{enumerable:true,get:function(){return __m13["SupersededError"];}});
|
|
18895
|
+
Object.defineProperty(__exports,"createAbortScope",{enumerable:true,get:function(){return __m13["createAbortScope"];}});
|
|
18896
|
+
Object.defineProperty(__exports,"isAbortError",{enumerable:true,get:function(){return __m13["isAbortError"];}});
|
|
18897
|
+
const __m14=__req("packages/core/src/source/filterwire.js");
|
|
18898
|
+
Object.defineProperty(__exports,"RELATIVE_TOKENS",{enumerable:true,get:function(){return __m14["RELATIVE_TOKENS"];}});
|
|
18899
|
+
Object.defineProperty(__exports,"parseRelativeToken",{enumerable:true,get:function(){return __m14["parseRelativeToken"];}});
|
|
18900
|
+
Object.defineProperty(__exports,"resolveRelativeRange",{enumerable:true,get:function(){return __m14["resolveRelativeRange"];}});
|
|
18901
|
+
Object.defineProperty(__exports,"resolveRelativeCondition",{enumerable:true,get:function(){return __m14["resolveRelativeCondition"];}});
|
|
18902
|
+
Object.defineProperty(__exports,"relativeTokenOf",{enumerable:true,get:function(){return __m14["relativeTokenOf"];}});
|
|
18903
|
+
Object.defineProperty(__exports,"buildFilterSet",{enumerable:true,get:function(){return __m14["buildFilterSet"];}});
|
|
18904
|
+
Object.defineProperty(__exports,"normaliseFilterSet",{enumerable:true,get:function(){return __m14["normaliseFilterSet"];}});
|
|
18905
|
+
Object.defineProperty(__exports,"wireFilters",{enumerable:true,get:function(){return __m14["wireFilters"];}});
|
|
18906
|
+
Object.defineProperty(__exports,"querySignature",{enumerable:true,get:function(){return __m14["querySignature"];}});
|
|
18907
|
+
Object.defineProperty(__exports,"mapConditions",{enumerable:true,get:function(){return __m14["mapConditions"];}});
|
|
18908
|
+
Object.defineProperty(__exports,"forEachCondition",{enumerable:true,get:function(){return __m14["forEachCondition"];}});
|
|
18909
|
+
Object.defineProperty(__exports,"isGroup",{enumerable:true,get:function(){return __m14["isGroup"];}});
|
|
18910
|
+
const __m15=__req("packages/core/src/source/blockcache.js");
|
|
18911
|
+
Object.defineProperty(__exports,"BlockCache",{enumerable:true,get:function(){return __m15["BlockCache"];}});
|
|
18912
|
+
Object.defineProperty(__exports,"DEFAULT_PAGE_SIZE",{enumerable:true,get:function(){return __m15["DEFAULT_PAGE_SIZE"];}});
|
|
18913
|
+
Object.defineProperty(__exports,"DEFAULT_MAX_CACHED_PAGES",{enumerable:true,get:function(){return __m15["DEFAULT_MAX_CACHED_PAGES"];}});
|
|
18914
|
+
const __m16=__req("packages/core/src/source/gapbuffer.js");
|
|
18915
|
+
Object.defineProperty(__exports,"GapBuffer",{enumerable:true,get:function(){return __m16["GapBuffer"];}});
|
|
18916
|
+
const __m17=__req("packages/core/src/source/rows.js");
|
|
18917
|
+
Object.defineProperty(__exports,"RowFactory",{enumerable:true,get:function(){return __m17["RowFactory"];}});
|
|
18918
|
+
Object.defineProperty(__exports,"createRowFactory",{enumerable:true,get:function(){return __m17["createRowFactory"];}});
|
|
18919
|
+
Object.defineProperty(__exports,"groupKey",{enumerable:true,get:function(){return __m17["groupKey"];}});
|
|
18920
|
+
Object.defineProperty(__exports,"lazyRowView",{enumerable:true,get:function(){return __m17["lazyRowView"];}});
|
|
18921
|
+
Object.defineProperty(__exports,"DEFAULT_ROW_HEIGHT",{enumerable:true,get:function(){return __m17["DEFAULT_ROW_HEIGHT"];}});
|
|
18922
|
+
const __m18=__req("packages/core/src/source/handles.js");
|
|
18923
|
+
Object.defineProperty(__exports,"HandleProvider",{enumerable:true,get:function(){return __m18["HandleProvider"];}});
|
|
18924
|
+
Object.defineProperty(__exports,"createHandleProvider",{enumerable:true,get:function(){return __m18["createHandleProvider"];}});
|
|
17848
18925
|
const MODES=Object.freeze(['memory','paged','remote','stream','derived']);
|
|
17849
18926
|
function createSource(config,ctx){
|
|
17850
18927
|
if(!ctx)fail('createSource requires a SourceContext');
|
|
@@ -20575,6 +21652,12 @@ if(pinFrom!==pinTo)pinned.push({id,from:pinFrom,to:pinTo});
|
|
|
20575
21652
|
const totalFrom=source.total??null;
|
|
20576
21653
|
const totalTo=target.total??null;
|
|
20577
21654
|
if(totalFrom!==totalTo)totals.push({id,from:totalFrom,to:totalTo});
|
|
21655
|
+
const groupFrom=source.groupTotal??null;
|
|
21656
|
+
const groupTo=target.groupTotal??null;
|
|
21657
|
+
if(groupFrom!==groupTo)totals.push({id,scope:'group',from:groupFrom,to:groupTo});
|
|
21658
|
+
const grandFrom=source.grandTotal??null;
|
|
21659
|
+
const grandTo=target.grandTotal??null;
|
|
21660
|
+
if(grandFrom!==grandTo)totals.push({id,scope:'grand',from:grandFrom,to:grandTo});
|
|
20578
21661
|
}
|
|
20579
21662
|
const missing=[...from.keys()].filter((id)=>!to.has(id));
|
|
20580
21663
|
const extra=[...to.keys()].filter((id)=>!from.has(id));
|
|
@@ -27952,6 +29035,7 @@ const cancelFrame=__m0["cancelFrame"];
|
|
|
27952
29035
|
const whenIdle=__m0["whenIdle"];
|
|
27953
29036
|
const now=__m0["now"];
|
|
27954
29037
|
const getPath=__m0["getPath"];
|
|
29038
|
+
const DEV=__m0["DEV"];
|
|
27955
29039
|
const __m1=__req("packages/core/src/events/bus.js");
|
|
27956
29040
|
const EventBus=__m1["EventBus"];
|
|
27957
29041
|
const __m2=__req("packages/core/src/registry/registry.js");
|
|
@@ -28192,6 +29276,7 @@ quickFilterText:'string',
|
|
|
28192
29276
|
sampleSize:'number',
|
|
28193
29277
|
sharedMemory:'boolean',
|
|
28194
29278
|
shortcuts:'boolean',
|
|
29279
|
+
stripedRows:'boolean',
|
|
28195
29280
|
showColumnFunctions:'boolean',
|
|
28196
29281
|
showHeader:'boolean',
|
|
28197
29282
|
showTotalInHeader:'boolean',
|
|
@@ -28285,7 +29370,7 @@ const KNOWN_CONFIG_KEYS=new Set([
|
|
|
28285
29370
|
'quickFilterText','rangeChart','responsive','rowClass','rowForm','rowHeight','rowKey',
|
|
28286
29371
|
'rowReorder','rowStyle','rowTemplate','rowTransfer','rows','sampleSize',
|
|
28287
29372
|
'selection','sharedMemory','shortcuts','showColumnFunctions','showHeader',
|
|
28288
|
-
'showTotalInHeader','source','state','statusBar','stickyGroupHeaders',
|
|
29373
|
+
'showTotalInHeader','source','state','statusBar','stickyGroupHeaders','stripedRows',
|
|
28289
29374
|
'targetSize','theme','timeZone','title','toolPanel','totalFilteredOnly',
|
|
28290
29375
|
'totalFns','totalOnlyChangedColumns','tree','typeOptions','updates','useWorker',
|
|
28291
29376
|
'variants','views','workerThreshold','workerUrl',
|
|
@@ -28297,7 +29382,7 @@ direction:undefined,
|
|
|
28297
29382
|
theme:'light',
|
|
28298
29383
|
density:'compact',
|
|
28299
29384
|
rowHeight:null,
|
|
28300
|
-
headerHeight:
|
|
29385
|
+
headerHeight:null,
|
|
28301
29386
|
overscan:4,
|
|
28302
29387
|
columnVirtualisationAbove:30,
|
|
28303
29388
|
workerThreshold:50_000,
|
|
@@ -28318,6 +29403,8 @@ class Grid{
|
|
|
28318
29403
|
#store=null;
|
|
28319
29404
|
#pool;
|
|
28320
29405
|
#source;
|
|
29406
|
+
#sourceIdCache=null;
|
|
29407
|
+
static#nextSourceId=1;
|
|
28321
29408
|
#rowModel;
|
|
28322
29409
|
#selection;
|
|
28323
29410
|
#ranges;
|
|
@@ -28906,7 +29993,7 @@ this.#inferTypes(config.rows);
|
|
|
28906
29993
|
if(sourceConfig.mode==='memory'||sourceConfig.mode==='stream'){
|
|
28907
29994
|
this.#store=new ColumnStore(this.#columns.storeSchema(),{
|
|
28908
29995
|
columnarBelow:sourceConfig.columnarBelow,
|
|
28909
|
-
retainSource:this.#
|
|
29996
|
+
retainSource:this.#storeRetainSource(),
|
|
28910
29997
|
});
|
|
28911
29998
|
}
|
|
28912
29999
|
this.#facets?.invalidate();
|
|
@@ -28933,7 +30020,7 @@ groupBy:()=>this.#query.groupBy,
|
|
|
28933
30020
|
pivotBy:()=>this.#query.pivotBy,
|
|
28934
30021
|
pivotMode:()=>this.#query.pivotMode,
|
|
28935
30022
|
totals:()=>this.#permissions.readableColumns(this.#columns.all())
|
|
28936
|
-
.filter((c)=>c.total).map((c)=>c.id),
|
|
30023
|
+
.filter((c)=>c.total||c.groupTotal||c.grandTotal).map((c)=>c.id),
|
|
28937
30024
|
expanded:()=>this.#expandedView(),
|
|
28938
30025
|
detail:()=>this.#detailView(),
|
|
28939
30026
|
page:()=>this.#query.page,
|
|
@@ -28949,6 +30036,7 @@ cancel:(handle)=>cancelFrame(handle),
|
|
|
28949
30036
|
if(this.#store){
|
|
28950
30037
|
this.#ingest(config.rows||[]);
|
|
28951
30038
|
this.#interceptApply();
|
|
30039
|
+
this.#dropSourceRows();
|
|
28952
30040
|
}
|
|
28953
30041
|
}
|
|
28954
30042
|
#inferTypes(rows){
|
|
@@ -28989,6 +30077,24 @@ if(!store||!change)return inner(change);
|
|
|
28989
30077
|
const insertsMidway=change.add&&change.add.length
|
|
28990
30078
|
&&typeof change.at==='number'&&change.at<store.physical;
|
|
28991
30079
|
if(insertsMidway){
|
|
30080
|
+
if(this.#sourceDropped()){
|
|
30081
|
+
const{kept,rejected}=this.#screenAdds(change.add,source);
|
|
30082
|
+
const live=this.#reconstructRowsForRebuild().filter((r)=>r!==undefined);
|
|
30083
|
+
const at=this.#liveBefore(change.at);
|
|
30084
|
+
live.splice(Math.max(0,Math.min(live.length,at)),0,...kept);
|
|
30085
|
+
this.#store.destroy();
|
|
30086
|
+
this.#store=new ColumnStore(this.#columns.storeSchema(),{
|
|
30087
|
+
retainSource:this.#storeRetainSource(),
|
|
30088
|
+
});
|
|
30089
|
+
this.#ingest(live);
|
|
30090
|
+
this.#dropSourceRows();
|
|
30091
|
+
if(isFunction(source.invalidateRows))source.invalidateRows();
|
|
30092
|
+
this.#facets?.invalidate();
|
|
30093
|
+
this.#facetCache.clear();
|
|
30094
|
+
const result=inner({...change,add:kept});
|
|
30095
|
+
if(rejected.length)result.rejected=[...(result.rejected||[]),...rejected];
|
|
30096
|
+
return result;
|
|
30097
|
+
}
|
|
28992
30098
|
const result=inner(change);
|
|
28993
30099
|
this.#rebuildStore();
|
|
28994
30100
|
return result;
|
|
@@ -29006,17 +30112,20 @@ return result;
|
|
|
29006
30112
|
}
|
|
29007
30113
|
if(change.update&&change.update.length){
|
|
29008
30114
|
const merged=[];
|
|
30115
|
+
const priorRows=this.#sourceDropped()?new Map():null;
|
|
29009
30116
|
for(const next of change.update){
|
|
29010
30117
|
const key=this.#rowKey(next);
|
|
29011
30118
|
const row=source.byKey(key);
|
|
29012
30119
|
const physical=row&&row.physical;
|
|
29013
30120
|
if(physical==null){merged.push(next);continue;}
|
|
29014
30121
|
const previous=isFunction(store.source)?store.source(physical):row.data;
|
|
30122
|
+
if(priorRows)priorRows.set(physical,previous);
|
|
29015
30123
|
const next2=mergeRow(previous,next);
|
|
29016
30124
|
merged.push(next2);
|
|
29017
30125
|
store.setSource(physical,next2);
|
|
29018
30126
|
this.#writeRowToStore(store,physical,next2,row);
|
|
29019
30127
|
}
|
|
30128
|
+
if(priorRows&&isFunction(source.notePriorRows))source.notePriorRows(priorRows);
|
|
29020
30129
|
let adds=change.add||[];
|
|
29021
30130
|
let addRejects=[];
|
|
29022
30131
|
if(adds.length){
|
|
@@ -29042,15 +30151,48 @@ return inner(change);
|
|
|
29042
30151
|
}
|
|
29043
30152
|
#rebuildStore(){
|
|
29044
30153
|
if(!this.#store)return;
|
|
30154
|
+
const snapshot=this.#sourceDropped()
|
|
30155
|
+
?this.#reconstructRowsForRebuild().filter((r)=>r!==undefined)
|
|
30156
|
+
:null;
|
|
29045
30157
|
this.#store.destroy();
|
|
29046
30158
|
this.#store=new ColumnStore(this.#columns.storeSchema(),{
|
|
29047
|
-
retainSource:this.#
|
|
30159
|
+
retainSource:this.#storeRetainSource(),
|
|
29048
30160
|
});
|
|
29049
|
-
this.#ingest(this.#source.rows?this.#source.rows():this.rows.data());
|
|
30161
|
+
this.#ingest(snapshot||(this.#source.rows?this.#source.rows():this.rows.data()));
|
|
30162
|
+
this.#dropSourceRows();
|
|
29050
30163
|
if(isFunction(this.#source.invalidateRows))this.#source.invalidateRows();
|
|
29051
30164
|
this.#facets?.invalidate();
|
|
29052
30165
|
this.#facetCache.clear();
|
|
29053
30166
|
}
|
|
30167
|
+
#sourceDropped(){
|
|
30168
|
+
const ingest=this.#config.ingest;
|
|
30169
|
+
return!!(ingest&&ingest.dropSourceRows===true);
|
|
30170
|
+
}
|
|
30171
|
+
#storeRetainSource(){
|
|
30172
|
+
if(this.#sourceDropped())return false;
|
|
30173
|
+
return this.#config.ingest?this.#config.ingest.retainSource:undefined;
|
|
30174
|
+
}
|
|
30175
|
+
#dropSourceRows(){
|
|
30176
|
+
if(!this.#sourceDropped())return;
|
|
30177
|
+
if(isFunction(this.#source.releaseSource))this.#source.releaseSource();
|
|
30178
|
+
this.#config.rows=undefined;
|
|
30179
|
+
this.#suppliedConfig.rows=undefined;
|
|
30180
|
+
}
|
|
30181
|
+
#reconstructRowsForRebuild(){
|
|
30182
|
+
const store=this.#store;
|
|
30183
|
+
const out=new Array(store.physical);
|
|
30184
|
+
for(let p=0;p<store.physical;p++){
|
|
30185
|
+
out[p]=store.live(p)?store.source(p):undefined;
|
|
30186
|
+
}
|
|
30187
|
+
return out;
|
|
30188
|
+
}
|
|
30189
|
+
#liveBefore(physical){
|
|
30190
|
+
const store=this.#store;
|
|
30191
|
+
const limit=Math.max(0,Math.min(store.physical,physical|0));
|
|
30192
|
+
let live=0;
|
|
30193
|
+
for(let p=0;p<limit;p++)if(store.live(p))live++;
|
|
30194
|
+
return live;
|
|
30195
|
+
}
|
|
29054
30196
|
#expandedView(){
|
|
29055
30197
|
const collapsed=this.#collapsed;
|
|
29056
30198
|
return{
|
|
@@ -29173,6 +30315,9 @@ locale:'model:changed',
|
|
|
29173
30315
|
lookup:'model:changed',
|
|
29174
30316
|
state:'model:changed',
|
|
29175
30317
|
};
|
|
30318
|
+
if(kind==='state'){
|
|
30319
|
+
for(const stage of['sort','group','total','pivot'])this.#source.invalidate?.(stage);
|
|
30320
|
+
}
|
|
29176
30321
|
this.#bus.emit(map[kind]||'model:changed',payload||{},'api');
|
|
29177
30322
|
this.#renderer?.invalidate('columns');
|
|
29178
30323
|
}
|
|
@@ -29240,7 +30385,10 @@ return this.#store?this.#store.column(colId):undefined;
|
|
|
29240
30385
|
}
|
|
29241
30386
|
#columnValues(colId){
|
|
29242
30387
|
const handle=this.#handleFor(colId);
|
|
29243
|
-
|
|
30388
|
+
if(!handle)return new Float64Array(0);
|
|
30389
|
+
const indices=this.#statIndices();
|
|
30390
|
+
this.#warnWindowedStat('format',colId,indices.length);
|
|
30391
|
+
return statNumbers(handle,indices);
|
|
29244
30392
|
}
|
|
29245
30393
|
#filteredKeys(){
|
|
29246
30394
|
const indices=this.#statIndices();
|
|
@@ -29249,8 +30397,11 @@ return this.#filteredKeyCache.keys;
|
|
|
29249
30397
|
}
|
|
29250
30398
|
const keys=new Set();
|
|
29251
30399
|
const all=isFunction(this.#source.rows)?this.#source.rows():null;
|
|
30400
|
+
const dropped=this.#sourceDropped()&&this.#store&&isFunction(this.#store.source);
|
|
29252
30401
|
for(let i=0;i<indices.length;i++){
|
|
29253
|
-
const data=
|
|
30402
|
+
const data=dropped
|
|
30403
|
+
?this.#store.source(indices[i])
|
|
30404
|
+
:(all?all[indices[i]]:null);
|
|
29254
30405
|
const key=data==null?null:this.#rowKey(data);
|
|
29255
30406
|
if(key!==null&&key!==undefined)keys.add(String(key));
|
|
29256
30407
|
}
|
|
@@ -29295,6 +30446,7 @@ return values;
|
|
|
29295
30446
|
const values=this.#handleFor(colId);
|
|
29296
30447
|
if(!values)return null;
|
|
29297
30448
|
const indices=this.#statIndices();
|
|
30449
|
+
this.#warnWindowedStat('series',colId,indices.length);
|
|
29298
30450
|
const readValue=statValueReader(values);
|
|
29299
30451
|
if(!by){
|
|
29300
30452
|
const out=[];
|
|
@@ -29325,6 +30477,39 @@ const source=this.#source;
|
|
|
29325
30477
|
if(isFunction(source.filteredIndices))return source.filteredIndices();
|
|
29326
30478
|
return this.#store?this.#store.liveIndices():[];
|
|
29327
30479
|
}
|
|
30480
|
+
#statCoverage(covered){
|
|
30481
|
+
const source=this.#source;
|
|
30482
|
+
if(isFunction(source.filteredIndices)){
|
|
30483
|
+
return{covered,total:covered,windowed:false};
|
|
30484
|
+
}
|
|
30485
|
+
let total=isFunction(source.matchCount)?source.matchCount()
|
|
30486
|
+
:(isFunction(source.count)?source.count():covered);
|
|
30487
|
+
if(isFunction(source.progress)){
|
|
30488
|
+
const p=source.progress();
|
|
30489
|
+
if(p&&Number.isFinite(p.loaded))total=Math.max(total,p.loaded);
|
|
30490
|
+
}
|
|
30491
|
+
if(!Number.isFinite(total))total=covered;
|
|
30492
|
+
return{covered,total:Math.max(total,covered),windowed:true};
|
|
30493
|
+
}
|
|
30494
|
+
#warnWindowedStat(stat,colId,covered){
|
|
30495
|
+
const coverage=this.#statCoverage(covered);
|
|
30496
|
+
if(!DEV||!coverage.windowed||coverage.covered>=coverage.total)return coverage;
|
|
30497
|
+
warnOnce(
|
|
30498
|
+
`stat.windowed:${stat}:${colId}:${this.#sourceId()}`,
|
|
30499
|
+
`\`${stat}\` on \`${colId}\` computed over ${coverage.covered.toLocaleString()} of `
|
|
30500
|
+
+`${coverage.total.toLocaleString()} matching rows (windowed source); hold the data in a `
|
|
30501
|
+
+'memory source for whole-dataset statistics.',
|
|
30502
|
+
);
|
|
30503
|
+
return coverage;
|
|
30504
|
+
}
|
|
30505
|
+
#sourceId(){
|
|
30506
|
+
if(this.#sourceIdCache&&this.#sourceIdCache.source===this.#source){
|
|
30507
|
+
return this.#sourceIdCache.id;
|
|
30508
|
+
}
|
|
30509
|
+
const id=Grid.#nextSourceId++;
|
|
30510
|
+
this.#sourceIdCache={source:this.#source,id};
|
|
30511
|
+
return id;
|
|
30512
|
+
}
|
|
29328
30513
|
#displayRows(){
|
|
29329
30514
|
return this.#source.display?this.#source.display():[];
|
|
29330
30515
|
}
|
|
@@ -30289,7 +31474,7 @@ grid.#renderer?.invalidate('columns');
|
|
|
30289
31474
|
grid.#refresh('rows');
|
|
30290
31475
|
},{target:undefined});
|
|
30291
31476
|
},
|
|
30292
|
-
setTotal(id,fn){
|
|
31477
|
+
setTotal(id,fn,opts){
|
|
30293
31478
|
const column=model.get(id);
|
|
30294
31479
|
if(!column)return;
|
|
30295
31480
|
if(typeof fn==='string'&&!aggregateAllowed(column,fn)){
|
|
@@ -30301,7 +31486,16 @@ warnOnce(
|
|
|
30301
31486
|
);
|
|
30302
31487
|
return;
|
|
30303
31488
|
}
|
|
31489
|
+
const scope=opts&&opts.scope;
|
|
31490
|
+
if(scope==='group'){
|
|
31491
|
+
column.groupTotal=fn||null;
|
|
31492
|
+
}else if(scope==='grand'){
|
|
31493
|
+
column.grandTotal=fn||null;
|
|
31494
|
+
}else{
|
|
30304
31495
|
column.total=fn||null;
|
|
31496
|
+
column.groupTotal=null;
|
|
31497
|
+
column.grandTotal=null;
|
|
31498
|
+
}
|
|
30305
31499
|
grid.#source.invalidate?.('total');
|
|
30306
31500
|
grid.#bus.emit('column:grouped',{columns:grid.#query.groupBy},'api');
|
|
30307
31501
|
grid.#refresh('rows');
|
|
@@ -31279,12 +32473,15 @@ return{columns:[...grid.#shadows.keys()],rows,forgotten};
|
|
|
31279
32473
|
reduce(colId,fn){
|
|
31280
32474
|
const handle=grid.#handleFor(colId);
|
|
31281
32475
|
if(!handle)return null;
|
|
31282
|
-
|
|
32476
|
+
const indices=grid.#statIndices();
|
|
32477
|
+
grid.#warnWindowedStat(typeof fn==='string'?fn:'reduce',colId,indices.length);
|
|
32478
|
+
return total(handle,indices,fn,{grid,locale:grid.#config.locale});
|
|
31283
32479
|
},
|
|
31284
32480
|
profile(colId){
|
|
31285
32481
|
const handle=grid.#handleFor(colId);
|
|
31286
32482
|
if(!handle)return null;
|
|
31287
32483
|
const indices=grid.#statIndices();
|
|
32484
|
+
const coverage=grid.#warnWindowedStat('profile',colId,indices.length);
|
|
31288
32485
|
const values=statNumbers(handle,indices);
|
|
31289
32486
|
const{n,mean,m2}=statMoments(values);
|
|
31290
32487
|
const sorted=values.slice().sort();
|
|
@@ -31299,6 +32496,7 @@ if(v===null||v===undefined||v==='')absent++;
|
|
|
31299
32496
|
return{
|
|
31300
32497
|
column:colId,
|
|
31301
32498
|
rows:indices.length,
|
|
32499
|
+
...(coverage.windowed?{coverage:{covered:coverage.covered,total:coverage.total}}:{}),
|
|
31302
32500
|
present:indices.length-absent,
|
|
31303
32501
|
missing:absent,
|
|
31304
32502
|
numeric:n,
|
|
@@ -31319,37 +32517,48 @@ correlation(a,b){
|
|
|
31319
32517
|
const first=grid.#handleFor(a);
|
|
31320
32518
|
const second=grid.#handleFor(b);
|
|
31321
32519
|
if(!first||!second)return null;
|
|
31322
|
-
|
|
32520
|
+
const indices=grid.#statIndices();
|
|
32521
|
+
grid.#warnWindowedStat('correlation',`${a},${b}`,indices.length);
|
|
32522
|
+
return statCorrelation(first,second,indices);
|
|
31323
32523
|
},
|
|
31324
32524
|
covariance(a,b,opts={}){
|
|
31325
32525
|
const first=grid.#handleFor(a);
|
|
31326
32526
|
const second=grid.#handleFor(b);
|
|
31327
32527
|
if(!first||!second)return null;
|
|
31328
|
-
|
|
32528
|
+
const indices=grid.#statIndices();
|
|
32529
|
+
grid.#warnWindowedStat('covariance',`${a},${b}`,indices.length);
|
|
32530
|
+
return statCovariance(first,second,indices,opts.population===true);
|
|
31329
32531
|
},
|
|
31330
32532
|
regression(a,b){
|
|
31331
32533
|
const first=grid.#handleFor(a);
|
|
31332
32534
|
const second=grid.#handleFor(b);
|
|
31333
32535
|
if(!first||!second)return null;
|
|
31334
|
-
|
|
32536
|
+
const indices=grid.#statIndices();
|
|
32537
|
+
grid.#warnWindowedStat('regression',`${a},${b}`,indices.length);
|
|
32538
|
+
return statRegression(first,second,indices);
|
|
31335
32539
|
},
|
|
31336
32540
|
spearman(a,b){
|
|
31337
32541
|
const first=grid.#handleFor(a);
|
|
31338
32542
|
const second=grid.#handleFor(b);
|
|
31339
32543
|
if(!first||!second)return null;
|
|
31340
|
-
|
|
32544
|
+
const indices=grid.#statIndices();
|
|
32545
|
+
grid.#warnWindowedStat('spearman',`${a},${b}`,indices.length);
|
|
32546
|
+
return statSpearman(first,second,indices);
|
|
31341
32547
|
},
|
|
31342
32548
|
kendall(a,b){
|
|
31343
32549
|
const first=grid.#handleFor(a);
|
|
31344
32550
|
const second=grid.#handleFor(b);
|
|
31345
32551
|
if(!first||!second)return null;
|
|
31346
|
-
|
|
32552
|
+
const indices=grid.#statIndices();
|
|
32553
|
+
grid.#warnWindowedStat('kendall',`${a},${b}`,indices.length);
|
|
32554
|
+
return statKendall(first,second,indices);
|
|
31347
32555
|
},
|
|
31348
32556
|
weightedQuantile(colId,weightId,p=0.5){
|
|
31349
32557
|
const values=grid.#handleFor(colId);
|
|
31350
32558
|
const weights=grid.#handleFor(weightId);
|
|
31351
32559
|
if(!values||!weights)return null;
|
|
31352
32560
|
const indices=grid.#statIndices();
|
|
32561
|
+
grid.#warnWindowedStat('weightedQuantile',`${colId},${weightId}`,indices.length);
|
|
31353
32562
|
const readV=statValueReader(values);
|
|
31354
32563
|
const readW=statValueReader(weights);
|
|
31355
32564
|
const vs=[];
|
|
@@ -31429,7 +32638,9 @@ weightedAverage(colId,weightId){
|
|
|
31429
32638
|
const values=grid.#handleFor(colId);
|
|
31430
32639
|
const weights=grid.#handleFor(weightId);
|
|
31431
32640
|
if(!values||!weights)return null;
|
|
31432
|
-
|
|
32641
|
+
const indices=grid.#statIndices();
|
|
32642
|
+
grid.#warnWindowedStat('weightedAverage',`${colId},${weightId}`,indices.length);
|
|
32643
|
+
return statWeightedAverage(values,weights,indices);
|
|
31433
32644
|
},
|
|
31434
32645
|
keyOf(data){
|
|
31435
32646
|
if(data==null)return null;
|
|
@@ -32084,6 +33295,9 @@ other:'Aperçu du collage : {changes} modifications de cellules, {rejected} reje
|
|
|
32084
33295
|
'menu.totalColumn':'Totaliser cette colonne',
|
|
32085
33296
|
'menu.aggregate':'Agrégat',
|
|
32086
33297
|
'menu.aggregateNone':'Aucun',
|
|
33298
|
+
'menu.aggregateGroup':'Sous-totaux de groupe',
|
|
33299
|
+
'menu.aggregateGrand':'Total général',
|
|
33300
|
+
'menu.aggregateSame':'Comme le total',
|
|
32087
33301
|
'menu.redactColumn':'Masquer le contenu de la colonne',
|
|
32088
33302
|
'menu.stopRedacting':'Ne plus masquer',
|
|
32089
33303
|
'menu.stopRedactingAll':'Ne plus rien masquer',
|
|
@@ -32598,6 +33812,9 @@ other:'Anteprima incolla: {changes} modifiche alle celle, {rejected} rifiutate.
|
|
|
32598
33812
|
'menu.totalColumn':'Totalizza questa colonna',
|
|
32599
33813
|
'menu.aggregate':'Aggregazione',
|
|
32600
33814
|
'menu.aggregateNone':'Nessuno',
|
|
33815
|
+
'menu.aggregateGroup':'Subtotali di gruppo',
|
|
33816
|
+
'menu.aggregateGrand':'Totale generale',
|
|
33817
|
+
'menu.aggregateSame':'Come il totale',
|
|
32601
33818
|
'menu.redactColumn':'Oscura la colonna',
|
|
32602
33819
|
'menu.stopRedacting':'Non oscurare più',
|
|
32603
33820
|
'menu.stopRedactingAll':'Non oscurare più nulla',
|
|
@@ -33097,6 +34314,9 @@ other:'Vista previa del pegado: {changes} cambios de celdas, {rejected} rechazad
|
|
|
33097
34314
|
'menu.totalColumn':'Totalizar esta columna',
|
|
33098
34315
|
'menu.aggregate':'Agregación',
|
|
33099
34316
|
'menu.aggregateNone':'Ninguno',
|
|
34317
|
+
'menu.aggregateGroup':'Subtotales de grupo',
|
|
34318
|
+
'menu.aggregateGrand':'Total general',
|
|
34319
|
+
'menu.aggregateSame':'Igual que el total',
|
|
33100
34320
|
'menu.redactColumn':'Ocultar el contenido de la columna',
|
|
33101
34321
|
'menu.stopRedacting':'Dejar de ocultar',
|
|
33102
34322
|
'menu.stopRedactingAll':'Dejar de ocultar todo',
|
|
@@ -33626,6 +34846,9 @@ other:'Limpar {count} células',
|
|
|
33626
34846
|
'menu.totalColumn':'Totalizar esta coluna',
|
|
33627
34847
|
'menu.aggregate':'Agregação',
|
|
33628
34848
|
'menu.aggregateNone':'Nenhum',
|
|
34849
|
+
'menu.aggregateGroup':'Subtotais de grupo',
|
|
34850
|
+
'menu.aggregateGrand':'Total geral',
|
|
34851
|
+
'menu.aggregateSame':'Igual ao total',
|
|
33629
34852
|
'menu.redactColumn':'Ocultar o conteúdo da coluna',
|
|
33630
34853
|
'menu.stopRedacting':'Parar de ocultar',
|
|
33631
34854
|
'menu.stopRedactingAll':'Parar de ocultar tudo',
|
|
@@ -34152,6 +35375,9 @@ other:'{count} Zellen leeren',
|
|
|
34152
35375
|
'menu.totalColumn':'Diese Spalte summieren',
|
|
34153
35376
|
'menu.aggregate':'Aggregat',
|
|
34154
35377
|
'menu.aggregateNone':'Keine',
|
|
35378
|
+
'menu.aggregateGroup':'Gruppenzwischensummen',
|
|
35379
|
+
'menu.aggregateGrand':'Gesamtsumme',
|
|
35380
|
+
'menu.aggregateSame':'Wie Gesamtwert',
|
|
34155
35381
|
'menu.redactColumn':'Spalteninhalt schwärzen',
|
|
34156
35382
|
'menu.stopRedacting':'Schwärzung aufheben',
|
|
34157
35383
|
'menu.stopRedactingAll':'Alle Schwärzungen aufheben',
|
|
@@ -34678,6 +35904,9 @@ other:'{count} cellen wissen',
|
|
|
34678
35904
|
'menu.totalColumn':'Deze kolom totaliseren',
|
|
34679
35905
|
'menu.aggregate':'Aggregatie',
|
|
34680
35906
|
'menu.aggregateNone':'Geen',
|
|
35907
|
+
'menu.aggregateGroup':'Groepssubtotalen',
|
|
35908
|
+
'menu.aggregateGrand':'Eindtotaal',
|
|
35909
|
+
'menu.aggregateSame':'Zelfde als totaal',
|
|
34681
35910
|
'menu.redactColumn':'Kolominhoud afschermen',
|
|
34682
35911
|
'menu.stopRedacting':'Niet meer afschermen',
|
|
34683
35912
|
'menu.stopRedactingAll':'Niets meer afschermen',
|
|
@@ -35204,6 +36433,9 @@ other:'Rensa {count} celler',
|
|
|
35204
36433
|
'menu.totalColumn':'Summera den här kolumnen',
|
|
35205
36434
|
'menu.aggregate':'Aggregat',
|
|
35206
36435
|
'menu.aggregateNone':'Ingen',
|
|
36436
|
+
'menu.aggregateGroup':'Gruppdelsummor',
|
|
36437
|
+
'menu.aggregateGrand':'Slutsumma',
|
|
36438
|
+
'menu.aggregateSame':'Samma som total',
|
|
35207
36439
|
'menu.redactColumn':'Maskera kolumnens innehåll',
|
|
35208
36440
|
'menu.stopRedacting':'Sluta maskera',
|
|
35209
36441
|
'menu.stopRedactingAll':'Sluta maskera allt',
|
|
@@ -35730,6 +36962,9 @@ other:'Ryd {count} celler',
|
|
|
35730
36962
|
'menu.totalColumn':'Summér denne kolonne',
|
|
35731
36963
|
'menu.aggregate':'Aggregering',
|
|
35732
36964
|
'menu.aggregateNone':'Ingen',
|
|
36965
|
+
'menu.aggregateGroup':'Gruppesubtotaler',
|
|
36966
|
+
'menu.aggregateGrand':'Hovedtotal',
|
|
36967
|
+
'menu.aggregateSame':'Samme som total',
|
|
35733
36968
|
'menu.redactColumn':'Skjul kolonnens indhold',
|
|
35734
36969
|
'menu.stopRedacting':'Stop med at skjule',
|
|
35735
36970
|
'menu.stopRedactingAll':'Stop med at skjule alt',
|
|
@@ -36256,6 +37491,9 @@ other:'Tøm {count} celler',
|
|
|
36256
37491
|
'menu.totalColumn':'Summer denne kolonnen',
|
|
36257
37492
|
'menu.aggregate':'Aggregat',
|
|
36258
37493
|
'menu.aggregateNone':'Ingen',
|
|
37494
|
+
'menu.aggregateGroup':'Gruppedelsummer',
|
|
37495
|
+
'menu.aggregateGrand':'Totalsum',
|
|
37496
|
+
'menu.aggregateSame':'Samme som total',
|
|
36259
37497
|
'menu.redactColumn':'Skjul innholdet i kolonnen',
|
|
36260
37498
|
'menu.stopRedacting':'Slutt å skjule',
|
|
36261
37499
|
'menu.stopRedactingAll':'Slutt å skjule alt',
|
|
@@ -36782,6 +38020,9 @@ other:'Tyhjennä {count} solua',
|
|
|
36782
38020
|
'menu.totalColumn':'Summaa tämä sarake',
|
|
36783
38021
|
'menu.aggregate':'Koonti',
|
|
36784
38022
|
'menu.aggregateNone':'Ei mitään',
|
|
38023
|
+
'menu.aggregateGroup':'Ryhmän välisummat',
|
|
38024
|
+
'menu.aggregateGrand':'Kokonaissumma',
|
|
38025
|
+
'menu.aggregateSame':'Sama kuin summa',
|
|
36785
38026
|
'menu.redactColumn':'Peitä sarakkeen sisältö',
|
|
36786
38027
|
'menu.stopRedacting':'Lopeta peittäminen',
|
|
36787
38028
|
'menu.stopRedactingAll':'Lopeta kaiken peittäminen',
|
|
@@ -37340,6 +38581,9 @@ other:'Wyczyść {count} komórek',
|
|
|
37340
38581
|
'menu.totalColumn':'Sumuj tę kolumnę',
|
|
37341
38582
|
'menu.aggregate':'Agregacja',
|
|
37342
38583
|
'menu.aggregateNone':'Brak',
|
|
38584
|
+
'menu.aggregateGroup':'Sumy częściowe grup',
|
|
38585
|
+
'menu.aggregateGrand':'Suma końcowa',
|
|
38586
|
+
'menu.aggregateSame':'Tak jak suma',
|
|
37343
38587
|
'menu.redactColumn':'Ukryj zawartość kolumny',
|
|
37344
38588
|
'menu.stopRedacting':'Przestań ukrywać',
|
|
37345
38589
|
'menu.stopRedactingAll':'Przestań ukrywać wszystko',
|
|
@@ -37900,6 +39144,9 @@ other:'Vymazat {count} buněk',
|
|
|
37900
39144
|
'menu.totalColumn':'Sečíst tento sloupec',
|
|
37901
39145
|
'menu.aggregate':'Agregace',
|
|
37902
39146
|
'menu.aggregateNone':'Žádná',
|
|
39147
|
+
'menu.aggregateGroup':'Mezisoučty skupin',
|
|
39148
|
+
'menu.aggregateGrand':'Celkový součet',
|
|
39149
|
+
'menu.aggregateSame':'Stejné jako součet',
|
|
37903
39150
|
'menu.redactColumn':'Skrýt obsah sloupce',
|
|
37904
39151
|
'menu.stopRedacting':'Přestat skrývat',
|
|
37905
39152
|
'menu.stopRedactingAll':'Přestat vše skrývat',
|
|
@@ -38428,6 +39675,9 @@ other:'{count} cella törlése',
|
|
|
38428
39675
|
'menu.totalColumn':'Ezen oszlop összegzése',
|
|
38429
39676
|
'menu.aggregate':'Összesítés',
|
|
38430
39677
|
'menu.aggregateNone':'Nincs',
|
|
39678
|
+
'menu.aggregateGroup':'Csoport részösszegek',
|
|
39679
|
+
'menu.aggregateGrand':'Végösszeg',
|
|
39680
|
+
'menu.aggregateSame':'Ugyanaz mint az összeg',
|
|
38431
39681
|
'menu.redactColumn':'Oszlop tartalmának kitakarása',
|
|
38432
39682
|
'menu.stopRedacting':'Kitakarás megszüntetése',
|
|
38433
39683
|
'menu.stopRedactingAll':'Minden kitakarás megszüntetése',
|
|
@@ -38970,6 +40220,9 @@ other:'Golește {count} de celule',
|
|
|
38970
40220
|
'menu.totalColumn':'Totalizează această coloană',
|
|
38971
40221
|
'menu.aggregate':'Agregare',
|
|
38972
40222
|
'menu.aggregateNone':'Niciunul',
|
|
40223
|
+
'menu.aggregateGroup':'Subtotaluri de grup',
|
|
40224
|
+
'menu.aggregateGrand':'Total general',
|
|
40225
|
+
'menu.aggregateSame':'La fel ca totalul',
|
|
38973
40226
|
'menu.redactColumn':'Ascunde conținutul coloanei',
|
|
38974
40227
|
'menu.stopRedacting':'Nu mai ascunde',
|
|
38975
40228
|
'menu.stopRedactingAll':'Nu mai ascunde nimic',
|
|
@@ -39529,6 +40782,9 @@ other:'Очистити {count} комірок',
|
|
|
39529
40782
|
'menu.totalColumn':'Підсумувати цей стовпець',
|
|
39530
40783
|
'menu.aggregate':'Агрегація',
|
|
39531
40784
|
'menu.aggregateNone':'Немає',
|
|
40785
|
+
'menu.aggregateGroup':'Проміжні підсумки груп',
|
|
40786
|
+
'menu.aggregateGrand':'Загальний підсумок',
|
|
40787
|
+
'menu.aggregateSame':'Як у підсумку',
|
|
39532
40788
|
'menu.redactColumn':'Приховати вміст стовпця',
|
|
39533
40789
|
'menu.stopRedacting':'Припинити приховування',
|
|
39534
40790
|
'menu.stopRedactingAll':'Припинити приховування всього',
|
|
@@ -40057,6 +41313,9 @@ other:'Καθαρισμός {count} κελιών',
|
|
|
40057
41313
|
'menu.totalColumn':'Άθροισμα αυτής της στήλης',
|
|
40058
41314
|
'menu.aggregate':'Συνάθροιση',
|
|
40059
41315
|
'menu.aggregateNone':'Καμία',
|
|
41316
|
+
'menu.aggregateGroup':'Μερικά σύνολα ομάδας',
|
|
41317
|
+
'menu.aggregateGrand':'Γενικό σύνολο',
|
|
41318
|
+
'menu.aggregateSame':'Ίδιο με το σύνολο',
|
|
40060
41319
|
'menu.redactColumn':'Απόκρυψη περιεχομένου στήλης',
|
|
40061
41320
|
'menu.stopRedacting':'Διακοπή απόκρυψης',
|
|
40062
41321
|
'menu.stopRedactingAll':'Διακοπή κάθε απόκρυψης',
|
|
@@ -40566,6 +41825,9 @@ other:'{count} セルをクリア',
|
|
|
40566
41825
|
'menu.totalColumn':'この列を集計',
|
|
40567
41826
|
'menu.aggregate':'集計',
|
|
40568
41827
|
'menu.aggregateNone':'なし',
|
|
41828
|
+
'menu.aggregateGroup':'グループ小計',
|
|
41829
|
+
'menu.aggregateGrand':'総計',
|
|
41830
|
+
'menu.aggregateSame':'合計と同じ',
|
|
40569
41831
|
'menu.redactColumn':'列の内容を伏せる',
|
|
40570
41832
|
'menu.stopRedacting':'伏せるのをやめる',
|
|
40571
41833
|
'menu.stopRedactingAll':'すべて伏せるのをやめる',
|
|
@@ -41142,6 +42404,9 @@ other:'مسح {count} خلية',
|
|
|
41142
42404
|
'menu.totalColumn':'إجمالي هذا العمود',
|
|
41143
42405
|
'menu.aggregate':'تجميع',
|
|
41144
42406
|
'menu.aggregateNone':'بدون',
|
|
42407
|
+
'menu.aggregateGroup':'المجاميع الفرعية للمجموعة',
|
|
42408
|
+
'menu.aggregateGrand':'الإجمالي الكلي',
|
|
42409
|
+
'menu.aggregateSame':'مثل الإجمالي',
|
|
41145
42410
|
'menu.redactColumn':'إخفاء محتوى العمود',
|
|
41146
42411
|
'menu.stopRedacting':'إيقاف الإخفاء',
|
|
41147
42412
|
'menu.stopRedactingAll':'إيقاف الإخفاء بالكامل',
|
|
@@ -41510,27 +42775,30 @@ const __m0=__req("packages/core/src/store/bitset.js");
|
|
|
41510
42775
|
Object.defineProperty(__exports,"Bitset",{enumerable:true,get:function(){return __m0["Bitset"];}});
|
|
41511
42776
|
const __m1=__req("packages/core/src/store/dictionary.js");
|
|
41512
42777
|
Object.defineProperty(__exports,"Dictionary",{enumerable:true,get:function(){return __m1["Dictionary"];}});
|
|
41513
|
-
const __m2=__req("packages/core/src/store/
|
|
41514
|
-
Object.defineProperty(__exports,"
|
|
41515
|
-
|
|
41516
|
-
|
|
41517
|
-
Object.defineProperty(__exports,"
|
|
41518
|
-
const __m4=__req("packages/core/src/store/
|
|
41519
|
-
Object.defineProperty(__exports,"
|
|
41520
|
-
Object.defineProperty(__exports,"
|
|
41521
|
-
|
|
41522
|
-
|
|
41523
|
-
Object.defineProperty(__exports,"
|
|
41524
|
-
Object.defineProperty(__exports,"
|
|
41525
|
-
|
|
41526
|
-
Object.defineProperty(__exports,"
|
|
41527
|
-
Object.defineProperty(__exports,"
|
|
41528
|
-
Object.defineProperty(__exports,"
|
|
41529
|
-
Object.defineProperty(__exports,"
|
|
41530
|
-
|
|
41531
|
-
Object.defineProperty(__exports,"
|
|
41532
|
-
Object.defineProperty(__exports,"
|
|
41533
|
-
|
|
42778
|
+
const __m2=__req("packages/core/src/store/stringrank.js");
|
|
42779
|
+
Object.defineProperty(__exports,"StringRankIndex",{enumerable:true,get:function(){return __m2["StringRankIndex"];}});
|
|
42780
|
+
Object.defineProperty(__exports,"DEFAULT_MAX_DISTINCT",{enumerable:true,get:function(){return __m2["DEFAULT_MAX_DISTINCT"];}});
|
|
42781
|
+
const __m3=__req("packages/core/src/store/multivalue.js");
|
|
42782
|
+
Object.defineProperty(__exports,"MultiValue",{enumerable:true,get:function(){return __m3["MultiValue"];}});
|
|
42783
|
+
const __m4=__req("packages/core/src/store/pool.js");
|
|
42784
|
+
Object.defineProperty(__exports,"MaskPool",{enumerable:true,get:function(){return __m4["MaskPool"];}});
|
|
42785
|
+
Object.defineProperty(__exports,"sharedPool",{enumerable:true,get:function(){return __m4["sharedPool"];}});
|
|
42786
|
+
const __m5=__req("packages/core/src/store/columnstore.js");
|
|
42787
|
+
Object.defineProperty(__exports,"ColumnStore",{enumerable:true,get:function(){return __m5["ColumnStore"];}});
|
|
42788
|
+
Object.defineProperty(__exports,"ColumnHandle",{enumerable:true,get:function(){return __m5["ColumnHandle"];}});
|
|
42789
|
+
Object.defineProperty(__exports,"REMOVED",{enumerable:true,get:function(){return __m5["REMOVED"];}});
|
|
42790
|
+
const __m6=__req("packages/core/src/store/ingest.js");
|
|
42791
|
+
Object.defineProperty(__exports,"Ingest",{enumerable:true,get:function(){return __m6["Ingest"];}});
|
|
42792
|
+
Object.defineProperty(__exports,"ingest",{enumerable:true,get:function(){return __m6["ingest"];}});
|
|
42793
|
+
Object.defineProperty(__exports,"ingestSync",{enumerable:true,get:function(){return __m6["ingestSync"];}});
|
|
42794
|
+
Object.defineProperty(__exports,"createReaders",{enumerable:true,get:function(){return __m6["createReaders"];}});
|
|
42795
|
+
Object.defineProperty(__exports,"inferKind",{enumerable:true,get:function(){return __m6["inferKind"];}});
|
|
42796
|
+
Object.defineProperty(__exports,"decideText",{enumerable:true,get:function(){return __m6["decideText"];}});
|
|
42797
|
+
Object.defineProperty(__exports,"INGEST_DEFAULTS",{enumerable:true,get:function(){return __m6["INGEST_DEFAULTS"];}});
|
|
42798
|
+
const __m7=__req("packages/core/src/store/columnpack.js");
|
|
42799
|
+
Object.defineProperty(__exports,"packChunk",{enumerable:true,get:function(){return __m7["packChunk"];}});
|
|
42800
|
+
Object.defineProperty(__exports,"packedTransfers",{enumerable:true,get:function(){return __m7["packedTransfers"];}});
|
|
42801
|
+
Object.defineProperty(__exports,"isPortableSchema",{enumerable:true,get:function(){return __m7["isPortableSchema"];}});
|
|
41534
42802
|
});
|
|
41535
42803
|
__def("packages/core/src/model/index.js",function(__exports,__req){
|
|
41536
42804
|
'use strict';
|
|
@@ -41722,6 +42990,7 @@ Object.defineProperty(__exports,"DEFAULT_PARAMS",{enumerable:true,get:function()
|
|
|
41722
42990
|
Object.defineProperty(__exports,"dfqlAdapter",{enumerable:true,get:function(){return __m10["dfqlAdapter"];}});
|
|
41723
42991
|
Object.defineProperty(__exports,"duckdbAdapter",{enumerable:true,get:function(){return __m10["duckdbAdapter"];}});
|
|
41724
42992
|
Object.defineProperty(__exports,"filtersToSql",{enumerable:true,get:function(){return __m10["filtersToSql"];}});
|
|
42993
|
+
Object.defineProperty(__exports,"STAT_PUSHDOWN",{enumerable:true,get:function(){return __m10["STAT_PUSHDOWN"];}});
|
|
41725
42994
|
const __m11=__req("packages/core/src/model/index.js");
|
|
41726
42995
|
Object.defineProperty(__exports,"RowModel",{enumerable:true,get:function(){return __m11["RowModel"];}});
|
|
41727
42996
|
Object.defineProperty(__exports,"createRowKey",{enumerable:true,get:function(){return __m11["createRowKey"];}});
|
|
@@ -42006,6 +43275,7 @@ spanLayer:`${PREFIX}-span-layer`,
|
|
|
42006
43275
|
fullWidthLayer:`${PREFIX}-fullwidth-layer`,
|
|
42007
43276
|
row:`${PREFIX}-row`,
|
|
42008
43277
|
rowSelected:`${PREFIX}-row--selected`,
|
|
43278
|
+
rowAlternate:`${PREFIX}-row--alternate`,
|
|
42009
43279
|
rowDetailActive:`${PREFIX}-row--detail-active`,
|
|
42010
43280
|
rowGroupFooter:`${PREFIX}-row--group-footer`,
|
|
42011
43281
|
rowGroup:`${PREFIX}-row--group`,
|
|
@@ -43346,12 +44616,34 @@ this.#host=opts.host;
|
|
|
43346
44616
|
this.#layout=opts.layout;
|
|
43347
44617
|
this.#a11y=opts.a11y;
|
|
43348
44618
|
this.#on=opts.on;
|
|
43349
|
-
this
|
|
43350
|
-
?opts.host.config.headerHeight
|
|
43351
|
-
:DEFAULT_HEADER_HEIGHT;
|
|
44619
|
+
this.syncRowHeight();
|
|
43352
44620
|
this.handlePointerMove=this.handlePointerMove.bind(this);
|
|
43353
44621
|
this.handlePointerUp=this.handlePointerUp.bind(this);
|
|
43354
44622
|
}
|
|
44623
|
+
syncRowHeight(){
|
|
44624
|
+
const configured=this.#host.config?.headerHeight;
|
|
44625
|
+
if(configured>0){this.#rowHeight=configured;return;}
|
|
44626
|
+
const px=this.#tokenHeaderHeight();
|
|
44627
|
+
if(Number.isFinite(px)&&px>0)this.#rowHeight=px;
|
|
44628
|
+
else if(!(this.#rowHeight>0))this.#rowHeight=DEFAULT_HEADER_HEIGHT;
|
|
44629
|
+
}
|
|
44630
|
+
#tokenHeaderHeight(){
|
|
44631
|
+
const root=this.#viewport?.root;
|
|
44632
|
+
const doc=root?.ownerDocument;
|
|
44633
|
+
const view=doc?.defaultView;
|
|
44634
|
+
if(!root||!doc||!view||typeof view.getComputedStyle!=='function')return NaN;
|
|
44635
|
+
if(typeof doc.createElement!=='function')return NaN;
|
|
44636
|
+
const probe=doc.createElement('div');
|
|
44637
|
+
if(!probe.style)return NaN;
|
|
44638
|
+
probe.style.position='absolute';
|
|
44639
|
+
probe.style.visibility='hidden';
|
|
44640
|
+
probe.style.pointerEvents='none';
|
|
44641
|
+
probe.style.height='var(--lattice-header-height)';
|
|
44642
|
+
root.appendChild(probe);
|
|
44643
|
+
const px=parseFloat(view.getComputedStyle(probe).height);
|
|
44644
|
+
probe.remove?.();
|
|
44645
|
+
return px;
|
|
44646
|
+
}
|
|
43355
44647
|
get levels(){return this.#levels;}
|
|
43356
44648
|
get height(){return this.#levels*this.#rowHeight+this.#bandHeight();}
|
|
43357
44649
|
#bandHeight(){
|
|
@@ -43412,6 +44704,7 @@ for(const node of nodes)walk(node,0);
|
|
|
43412
44704
|
return depth;
|
|
43413
44705
|
}
|
|
43414
44706
|
build(){
|
|
44707
|
+
this.syncRowHeight();
|
|
43415
44708
|
const tree=this.#tree();
|
|
43416
44709
|
this.#levels=this.#depth(tree);
|
|
43417
44710
|
this.#viewport.root?.style?.setProperty?.('--lattice-facet-height',`${this.#bandHeight()}px`);
|
|
@@ -45699,6 +46992,7 @@ __def("packages/dom/src/renderer/renderer.js",function(__exports,__req){
|
|
|
45699
46992
|
Object.defineProperty(__exports,"resolveGroupHeadingDepth",{enumerable:true,get:function(){return resolveGroupHeadingDepth;}});
|
|
45700
46993
|
Object.defineProperty(__exports,"resolveGridLines",{enumerable:true,get:function(){return resolveGridLines;}});
|
|
45701
46994
|
Object.defineProperty(__exports,"resolveCornerRadius",{enumerable:true,get:function(){return resolveCornerRadius;}});
|
|
46995
|
+
Object.defineProperty(__exports,"resolveStripedRows",{enumerable:true,get:function(){return resolveStripedRows;}});
|
|
45702
46996
|
Object.defineProperty(__exports,"DEFAULT_OVERSCAN",{enumerable:true,get:function(){return DEFAULT_OVERSCAN;}});
|
|
45703
46997
|
Object.defineProperty(__exports,"textCellLayer",{enumerable:true,get:function(){return textCellLayer;}});
|
|
45704
46998
|
Object.defineProperty(__exports,"DomRenderer",{enumerable:true,get:function(){return DomRenderer;}});
|
|
@@ -45751,13 +47045,13 @@ const rowAtContent=__m18["rowAtContent"];
|
|
|
45751
47045
|
const __m19=__req("packages/dom/src/detailhost.js");
|
|
45752
47046
|
const insideDetail=__m19["insideDetail"];
|
|
45753
47047
|
function resolveGroupHeadingDepth(config){
|
|
45754
|
-
if(config===false)return 0;
|
|
45755
|
-
if(config===true
|
|
47048
|
+
if(config===false||config===undefined||config===null)return 0;
|
|
47049
|
+
if(config===true)return 2;
|
|
45756
47050
|
if(typeof config==='number')return Number.isInteger(config)&&config>0?config:0;
|
|
45757
47051
|
if(typeof config==='object'&&typeof config.depth==='number'){
|
|
45758
47052
|
return Number.isInteger(config.depth)&&config.depth>0?config.depth:0;
|
|
45759
47053
|
}
|
|
45760
|
-
return
|
|
47054
|
+
return 0;
|
|
45761
47055
|
}
|
|
45762
47056
|
function resolveGridLines(config){
|
|
45763
47057
|
if(config===false||config==='none')return'none';
|
|
@@ -45772,6 +47066,9 @@ if(typeof config==='number')return Number.isFinite(config)&&config>=0?`${config}
|
|
|
45772
47066
|
if(typeof config==='string'&&config.trim())return config.trim();
|
|
45773
47067
|
return null;
|
|
45774
47068
|
}
|
|
47069
|
+
function resolveStripedRows(config){
|
|
47070
|
+
return config===true;
|
|
47071
|
+
}
|
|
45775
47072
|
const EMPTY_LIST=Object.freeze([]);
|
|
45776
47073
|
const DEFAULT_OVERSCAN=4;
|
|
45777
47074
|
const ROW_BORDER=1;
|
|
@@ -45980,6 +47277,12 @@ this.#heights.setCount(this.#host.rowCount());
|
|
|
45980
47277
|
this.#heights.rebuild();
|
|
45981
47278
|
this.#forceNext=true;
|
|
45982
47279
|
}
|
|
47280
|
+
if(reason==='theme'||reason==='all'){
|
|
47281
|
+
this.#applyTheme();
|
|
47282
|
+
this.#applyDensity();
|
|
47283
|
+
this.#heights.clearMeasured();
|
|
47284
|
+
this.#forceNext=true;
|
|
47285
|
+
}
|
|
45983
47286
|
if(reason==='columns'||reason==='all'){
|
|
45984
47287
|
this.#needsSize=true;
|
|
45985
47288
|
this.#relayoutColumns();
|
|
@@ -45989,12 +47292,6 @@ if(reason==='size'||reason==='all')this.#needsSize=true;
|
|
|
45989
47292
|
this.#fullWidth.configure(this.#host.config?.fullWidth);
|
|
45990
47293
|
this.#configurePresentation();
|
|
45991
47294
|
this.#stickyGroupDepth=resolveGroupHeadingDepth(this.#host.config?.stickyGroupHeaders);
|
|
45992
|
-
if(reason==='theme'||reason==='all'){
|
|
45993
|
-
this.#applyTheme();
|
|
45994
|
-
this.#applyDensity();
|
|
45995
|
-
this.#heights.clearMeasured();
|
|
45996
|
-
this.#forceNext=true;
|
|
45997
|
-
}
|
|
45998
47295
|
if(reason==='rowHeight'||reason==='all'){
|
|
45999
47296
|
const configured=this.#host.config?.rowHeight;
|
|
46000
47297
|
if(typeof configured==='number')this.#heights.setRowHeight(configured);
|
|
@@ -46013,8 +47310,13 @@ if(typeof theme==='string'&&theme)root.setAttribute('data-theme',theme);
|
|
|
46013
47310
|
else root.removeAttribute('data-theme');
|
|
46014
47311
|
this.#applyGridLines(root);
|
|
46015
47312
|
this.#applyCorners(root);
|
|
47313
|
+
this.#applyStripes(root);
|
|
46016
47314
|
this.#applyDirection(root);
|
|
46017
47315
|
}
|
|
47316
|
+
#applyStripes(root){
|
|
47317
|
+
if(resolveStripedRows(this.#host.config?.stripedRows))root.setAttribute('data-striped-rows','');
|
|
47318
|
+
else root.removeAttribute('data-striped-rows');
|
|
47319
|
+
}
|
|
46018
47320
|
#applyGridLines(root){
|
|
46019
47321
|
const lines=resolveGridLines(this.#host.config?.gridLines);
|
|
46020
47322
|
root.setAttribute('data-grid-lines',lines);
|
|
@@ -46055,6 +47357,7 @@ else root.removeAttribute('data-density');
|
|
|
46055
47357
|
const targetSize=this.#host.config?.targetSize;
|
|
46056
47358
|
if(typeof targetSize==='string'&&targetSize)root.setAttribute('data-target-size',targetSize);
|
|
46057
47359
|
else root.removeAttribute('data-target-size');
|
|
47360
|
+
this.#header?.syncRowHeight?.();
|
|
46058
47361
|
if(this.#host.config?.rowHeight!=null)return;
|
|
46059
47362
|
const px=this.#tokenRowHeight(root);
|
|
46060
47363
|
if(Number.isFinite(px)&&px>0){
|
|
@@ -46558,6 +47861,8 @@ record.hostStyles=null;
|
|
|
46558
47861
|
}
|
|
46559
47862
|
if(!row)return;
|
|
46560
47863
|
el.classList.toggle(CLASS.rowSelected,row.selected===true);
|
|
47864
|
+
const structural=row.group===true||row.footer===true||row.grandTotal===true;
|
|
47865
|
+
el.classList.toggle(CLASS.rowAlternate,index%2===1&&!structural);
|
|
46561
47866
|
el.classList.toggle(CLASS.rowGroupFooter,row.footer===true);
|
|
46562
47867
|
el.classList.toggle(CLASS.rowGroup,row.group===true&&!row.footer&&!row.grandTotal);
|
|
46563
47868
|
el.classList.toggle(CLASS.rowGrandTotal,row.grandTotal===true);
|
|
@@ -61442,9 +62747,31 @@ name:totalLabel(name),
|
|
|
61442
62747
|
checked:current===name,
|
|
61443
62748
|
action:()=>grid.columns.setTotal(colId,name),
|
|
61444
62749
|
})),
|
|
62750
|
+
{separator:true},
|
|
62751
|
+
scopeSubmenu(grid,column,t,'group',t('menu.aggregateGroup')),
|
|
62752
|
+
scopeSubmenu(grid,column,t,'grand',t('menu.aggregateGrand')),
|
|
61445
62753
|
];
|
|
61446
62754
|
return{name:t('menu.aggregate'),children};
|
|
61447
62755
|
}
|
|
62756
|
+
function scopeSubmenu(grid,column,t,scope,name){
|
|
62757
|
+
const colId=column.id;
|
|
62758
|
+
const override=scope==='grand'?column.grandTotal:column.groupTotal;
|
|
62759
|
+
const current=typeof override==='string'?override:null;
|
|
62760
|
+
const children=[
|
|
62761
|
+
{
|
|
62762
|
+
name:t('menu.aggregateSame'),
|
|
62763
|
+
checked:override==null,
|
|
62764
|
+
action:()=>grid.columns.setTotal(colId,null,{scope}),
|
|
62765
|
+
},
|
|
62766
|
+
{separator:true},
|
|
62767
|
+
...aggregatesFor(column).map((agg)=>({
|
|
62768
|
+
name:totalLabel(agg),
|
|
62769
|
+
checked:current===agg,
|
|
62770
|
+
action:()=>grid.columns.setTotal(colId,agg,{scope}),
|
|
62771
|
+
})),
|
|
62772
|
+
];
|
|
62773
|
+
return{name,children};
|
|
62774
|
+
}
|
|
61448
62775
|
function headerMenuItems(grid,colId){
|
|
61449
62776
|
const t=(key,params)=>(grid&&grid.messages?grid.messages:defaultMessages).t(key,params);
|
|
61450
62777
|
const column=grid.columns.get(colId);
|
|
@@ -67866,7 +69193,7 @@ createLocalViewStorage,
|
|
|
67866
69193
|
const __default=LatticeGrid;
|
|
67867
69194
|
});
|
|
67868
69195
|
try{
|
|
67869
|
-
__req("packages/worker/src/inline.js").setWorkerSource("(function(root){\n'use strict';\nvar __mods=Object.create(null);\nvar __cache=Object.create(null);\nfunction __def(id,fn){__mods[id]=fn;}\nfunction __req(id){\nvar hit=__cache[id];\nif(hit)return hit;\nvar exports=Object.create(null);\n__cache[id]=exports;\nvar fn=__mods[id];\nif(!fn)throw new Error('[lattice] missing module: '+id);\nfn(exports,__req);\nreturn exports;\n}\n__def(\"packages/core/src/internal/util.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"VERSION\",{enumerable:true,get:function(){return VERSION;}});\nObject.defineProperty(__exports,\"reportedWarnings\",{enumerable:true,get:function(){return reportedWarnings;}});\nObject.defineProperty(__exports,\"warnOnce\",{enumerable:true,get:function(){return warnOnce;}});\nObject.defineProperty(__exports,\"infoOnce\",{enumerable:true,get:function(){return infoOnce;}});\nObject.defineProperty(__exports,\"resetWarnings\",{enumerable:true,get:function(){return resetWarnings;}});\nObject.defineProperty(__exports,\"fail\",{enumerable:true,get:function(){return fail;}});\nObject.defineProperty(__exports,\"invariant\",{enumerable:true,get:function(){return invariant;}});\nObject.defineProperty(__exports,\"DEV\",{enumerable:true,get:function(){return DEV;}});\nObject.defineProperty(__exports,\"isObject\",{enumerable:true,get:function(){return isObject;}});\nObject.defineProperty(__exports,\"isFunction\",{enumerable:true,get:function(){return isFunction;}});\nObject.defineProperty(__exports,\"isNil\",{enumerable:true,get:function(){return isNil;}});\nObject.defineProperty(__exports,\"isBlank\",{enumerable:true,get:function(){return isBlank;}});\nObject.defineProperty(__exports,\"isCtor\",{enumerable:true,get:function(){return isCtor;}});\nObject.defineProperty(__exports,\"pathGetter\",{enumerable:true,get:function(){return pathGetter;}});\nObject.defineProperty(__exports,\"pathSetter\",{enumerable:true,get:function(){return pathSetter;}});\nObject.defineProperty(__exports,\"getPath\",{enumerable:true,get:function(){return getPath;}});\nObject.defineProperty(__exports,\"setPath\",{enumerable:true,get:function(){return setPath;}});\nObject.defineProperty(__exports,\"humanise\",{enumerable:true,get:function(){return humanise;}});\nObject.defineProperty(__exports,\"escapeHtml\",{enumerable:true,get:function(){return escapeHtml;}});\nObject.defineProperty(__exports,\"titleCase\",{enumerable:true,get:function(){return titleCase;}});\nObject.defineProperty(__exports,\"expand\",{enumerable:true,get:function(){return expand;}});\nObject.defineProperty(__exports,\"toArray\",{enumerable:true,get:function(){return toArray;}});\nObject.defineProperty(__exports,\"merge\",{enumerable:true,get:function(){return merge;}});\nObject.defineProperty(__exports,\"mergeRow\",{enumerable:true,get:function(){return mergeRow;}});\nObject.defineProperty(__exports,\"Lru\",{enumerable:true,get:function(){return Lru;}});\nObject.defineProperty(__exports,\"collator\",{enumerable:true,get:function(){return collator;}});\nObject.defineProperty(__exports,\"defaultCompare\",{enumerable:true,get:function(){return defaultCompare;}});\nObject.defineProperty(__exports,\"now\",{enumerable:true,get:function(){return now;}});\nObject.defineProperty(__exports,\"nextFrame\",{enumerable:true,get:function(){return nextFrame;}});\nObject.defineProperty(__exports,\"cancelFrame\",{enumerable:true,get:function(){return cancelFrame;}});\nObject.defineProperty(__exports,\"frameBatched\",{enumerable:true,get:function(){return frameBatched;}});\nObject.defineProperty(__exports,\"whenIdle\",{enumerable:true,get:function(){return whenIdle;}});\nObject.defineProperty(__exports,\"uid\",{enumerable:true,get:function(){return uid;}});\nconst STAMPED_VERSION=\"1.16.0\";\nasync function resolveVersion(){\nif(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;\ntry{\nif(typeof process==='undefined'||!process.versions||!process.versions.node){\nreturn STAMPED_VERSION;\n}\nconst mod=await import('node:'+'module');\nconst req=mod.createRequire((typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst fs=req('node:'+'fs');\nconst url=new URL('../../../../package.json',(typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst text=fs.readFileSync(url,'utf8');\nreturn JSON.parse(text).version||STAMPED_VERSION;\n}catch{\nreturn STAMPED_VERSION;\n}\n}\nconst VERSION=\"1.16.0\";\nconst warned=new Set();\nconst reported=[];\nconst REPORT_LIMIT=500;\nfunction record(key,level,message){\nreported.push({\nkey,\nlevel,\nmessage:message.map((m)=>(typeof m==='string'?m:safeString(m))).join(' '),\nat:Date.now(),\n});\nif(reported.length>REPORT_LIMIT)reported.shift();\n}\nfunction safeString(value){\nif(value instanceof Error)return value.message;\ntry{return JSON.stringify(value);}catch{return String(value);}\n}\nfunction reportedWarnings(){return reported.map((r)=>({...r}));}\nfunction warnOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'warn',message);\nconsole.warn('[lattice]',...message);\n}\nfunction infoOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'info',message);\nconsole.info('[lattice]',...message);\n}\nfunction resetWarnings(){\nwarned.clear();\nreported.length=0;\n}\nfunction fail(message,extra){\nconst err=new Error(`[lattice] ${message}`);\nif(extra!==undefined)err.cause=extra;\nthrow err;\n}\nfunction invariant(condition,message){\nif(!condition)fail(message);\n}\nconst DEV=(()=>{\ntry{\nreturn!(typeof process!=='undefined'&&process.env\n&&process.env.NODE_ENV==='production');\n}catch{\nreturn true;\n}\n})();\nfunction isObject(v){\nreturn v!==null&&typeof v==='object'&&!Array.isArray(v);\n}\nfunction isFunction(v){\nreturn typeof v==='function';\n}\nfunction isNil(v){\nreturn v===null||v===undefined;\n}\nfunction isBlank(v){\nreturn v===null||v===undefined||v==='';\n}\nfunction isCtor(v){\nif(typeof v!=='function')return false;\nif(/^class[\\s{]/.test(Function.prototype.toString.call(v)))return true;\nreturn!!(v.prototype&&Object.getOwnPropertyNames(v.prototype).length>1);\n}\nconst pathCache=new Map();\nfunction pathGetter(path){\nlet fn=pathCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o)=>(o==null?undefined:o[path]);\n}else{\nconst parts=path.split('.');\nconst n=parts.length;\nfn=(o)=>{\nlet cur=o;\nfor(let i=0;i<n;i++){\nif(cur==null)return undefined;\ncur=cur[parts[i]];\n}\nreturn cur;\n};\n}\npathCache.set(path,fn);\nreturn fn;\n}\nconst setterCache=new Map();\nfunction pathSetter(path){\nlet fn=setterCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o,v)=>{if(o!=null)o[path]=v;};\n}else{\nconst parts=path.split('.');\nconst last=parts.length-1;\nfn=(o,v)=>{\nlet cur=o;\nfor(let i=0;i<last;i++){\nif(cur==null)return;\nconst k=parts[i];\nif(cur[k]==null)cur[k]={};\ncur=cur[k];\n}\nif(cur!=null)cur[parts[last]]=v;\n};\n}\nsetterCache.set(path,fn);\nreturn fn;\n}\nfunction getPath(obj,path){\nreturn pathGetter(path)(obj);\n}\nfunction setPath(obj,path,value){\npathSetter(path)(obj,value);\n}\nfunction humanise(field){\nif(!field)return'';\nconst leaf=field.includes('.')?field.slice(field.lastIndexOf('.')+1):field;\nreturn leaf\n.replace(/[_-]+/g,' ')\n.replace(/([a-z0-9])([A-Z])/g,'$1 $2')\n.replace(/([A-Z]+)([A-Z][a-z])/g,'$1 $2')\n.replace(/\\s+/g,' ')\n.trim()\n.replace(/^./,(c)=>c.toUpperCase());\n}\nconst ESCAPES={'&':'&','<':'<','>':'>','\"':'"',\"'\":'''};\nfunction escapeHtml(s){\nconst str=s==null?'':String(s);\nreturn/[&<>\"']/.test(str)?str.replace(/[&<>\"']/g,(c)=>ESCAPES[c]):str;\n}\nfunction titleCase(s){\nreturn String(s).replace(/\\w\\S*/g,(t)=>t[0].toUpperCase()+t.slice(1).toLowerCase());\n}\nfunction expand(value,key,whenTrue){\nif(value===undefined)return undefined;\nif(value===true)return{enabled:true,...whenTrue};\nif(value===false)return{enabled:false};\nif(isObject(value))return value;\nreturn{[key]:value,enabled:true};\n}\nfunction toArray(v){\nif(v===undefined||v===null)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction merge(a,b){\nif(!isObject(a))return isObject(b)?{...b}:b;\nif(!isObject(b))return b===undefined?a:b;\nconst out={...a};\nfor(const k of Object.keys(b)){\nconst bv=b[k];\nif(bv===undefined)continue;\nout[k]=isObject(bv)&&isObject(out[k])?merge(out[k],bv):bv;\n}\nreturn out;\n}\nfunction mergeRow(previous,patch){\nif(!isObject(previous)||!isObject(patch)||previous===patch)return patch;\nconst out=Object.create(Object.getPrototypeOf(previous));\nObject.assign(out,previous,patch);\nreturn out;\n}\nclass Lru{\n#max;\n#map=new Map();\n#onEvict;\nconstructor(max=256,onEvict=null){\nthis.#max=max;\nthis.#onEvict=onEvict;\n}\nget size(){\nreturn this.#map.size;\n}\nget max(){\nreturn this.#max;\n}\nset max(v){\nthis.#max=v;\nthis.#trim();\n}\nhas(k){\nreturn this.#map.has(k);\n}\nget(k){\nconst m=this.#map;\nif(!m.has(k))return undefined;\nconst v=m.get(k);\nm.delete(k);\nm.set(k,v);\nreturn v;\n}\npeek(k){\nreturn this.#map.get(k);\n}\nset(k,v){\nconst m=this.#map;\nif(m.has(k))m.delete(k);\nm.set(k,v);\nthis.#trim();\nreturn v;\n}\ndelete(k){\nconst v=this.#map.get(k);\nif(this.#map.delete(k)&&this.#onEvict)this.#onEvict(v,k);\nreturn v;\n}\nclear(){\nif(this.#onEvict)for(const[k,v]of this.#map)this.#onEvict(v,k);\nthis.#map.clear();\n}\nkeys(){\nreturn this.#map.keys();\n}\nvalues(){\nreturn this.#map.values();\n}\n#trim(){\nconst m=this.#map;\nwhile(m.size>this.#max){\nconst oldest=m.keys().next().value;\nconst v=m.get(oldest);\nm.delete(oldest);\nif(this.#onEvict)this.#onEvict(v,oldest);\n}\n}\n}\nconst collators=new Map();\nfunction collator(locale,opts){\nconst key=`${locale||''}|${opts?JSON.stringify(opts):''}`;\nlet c=collators.get(key);\nif(!c){\nc=new Intl.Collator(locale||undefined,{\nnumeric:true,sensitivity:'variant',...opts,\n});\ncollators.set(key,c);\n}\nreturn c;\n}\nfunction defaultCompare(a,b){\nif(a===b)return 0;\nif(a===null||a===undefined)return 1;\nif(b===null||b===undefined)return-1;\nif(typeof a==='number'&&typeof b==='number'){\nif(Number.isNaN(a))return Number.isNaN(b)?0:1;\nif(Number.isNaN(b))return-1;\nreturn a<b?-1:a>b?1:0;\n}\nconst sa=String(a);\nconst sb=String(b);\nreturn sa<sb?-1:sa>sb?1:0;\n}\nfunction now(){\nreturn typeof performance!=='undefined'&&performance.now\n?performance.now()\n:Date.now();\n}\nconst hasRaf=typeof requestAnimationFrame==='function';\nfunction nextFrame(fn){\nif(hasRaf)return requestAnimationFrame(fn);\nreturn setTimeout(()=>fn(now()),16);\n}\nfunction cancelFrame(handle){\nif(handle==null)return;\nif(hasRaf)cancelAnimationFrame(handle);\nelse clearTimeout(handle);\n}\nfunction frameBatched(fn){\nlet handle=null;\nlet lastArgs=null;\nconst run=()=>{\nhandle=null;\nconst a=lastArgs;\nlastArgs=null;\nfn(...(a||[]));\n};\nconst wrapped=(...args)=>{\nlastArgs=args;\nif(handle===null)handle=nextFrame(run);\n};\nwrapped.cancel=()=>{\ncancelFrame(handle);\nhandle=null;\nlastArgs=null;\n};\nwrapped.flush=()=>{\nif(handle!==null){\ncancelFrame(handle);\nrun();\n}\n};\nreturn wrapped;\n}\nfunction whenIdle(fn,timeout=50){\nif(typeof requestIdleCallback==='function'){\nreturn requestIdleCallback(fn,{timeout});\n}\nreturn setTimeout(()=>fn({timeRemaining:()=>0,didTimeout:true}),1);\n}\nlet idSeq=0;\nfunction uid(prefix='l'){\nreturn`${prefix}${(++idSeq).toString(36)}`;\n}\n});\n__def(\"packages/worker/src/transport.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"PROTOCOL\",{enumerable:true,get:function(){return PROTOCOL;}});\nObject.defineProperty(__exports,\"OPS\",{enumerable:true,get:function(){return OPS;}});\nObject.defineProperty(__exports,\"CONTROL\",{enumerable:true,get:function(){return CONTROL;}});\nObject.defineProperty(__exports,\"ERRORS\",{enumerable:true,get:function(){return ERRORS;}});\nObject.defineProperty(__exports,\"packHandle\",{enumerable:true,get:function(){return packHandle;}});\nObject.defineProperty(__exports,\"packHandles\",{enumerable:true,get:function(){return packHandles;}});\nObject.defineProperty(__exports,\"TransportedDictionary\",{enumerable:true,get:function(){return TransportedDictionary;}});\nObject.defineProperty(__exports,\"unpackHandle\",{enumerable:true,get:function(){return unpackHandle;}});\nObject.defineProperty(__exports,\"unpackHandles\",{enumerable:true,get:function(){return unpackHandles;}});\nObject.defineProperty(__exports,\"createMaskPool\",{enumerable:true,get:function(){return createMaskPool;}});\nObject.defineProperty(__exports,\"isTransferable\",{enumerable:true,get:function(){return isTransferable;}});\nObject.defineProperty(__exports,\"collectTransfers\",{enumerable:true,get:function(){return collectTransfers;}});\nObject.defineProperty(__exports,\"isPortable\",{enumerable:true,get:function(){return isPortable;}});\nObject.defineProperty(__exports,\"filterColumnIds\",{enumerable:true,get:function(){return filterColumnIds;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst isFunction=__m0[\"isFunction\"];\nconst PROTOCOL=1;\nconst OPS=Object.freeze({\nSORT_COLUMN:'sortColumn',\nSORT_MULTI:'sortMulti',\nEVALUATE_FILTERS:'evaluateFilters',\nCOMPACT:'compact',\nGROUP_BY_COLUMNS:'groupByColumns',\nTOTAL:'total',\nPIVOT:'pivot',\nFACET:'facet',\nCOLUMNIZE:'columnize',\n});\nconst CONTROL=Object.freeze({\nREADY:'ready',\nCANCEL:'cancel',\nPING:'ping',\n});\nconst ERRORS=Object.freeze({\nNO_COMPUTE:'E_NO_COMPUTE',\nNO_KERNEL:'E_NO_KERNEL',\nABORTED:'E_ABORTED',\nKERNEL:'E_KERNEL',\nPROTOCOL:'E_PROTOCOL',\n});\nfunction packHandle(handle){\nif(handle==null)return null;\nconst presence=handle.presence;\nreturn{\nid:handle.id,\nkind:handle.kind,\nnullable:!!handle.nullable,\nvalues:handle.values??null,\npresence:presence?(presence.words??presence):null,\npresenceBits:presence?(presence.size??(presence.words??presence).length*8):0,\ndict:handle.dict?sliceDictionary(handle.dict):null,\noffsets:handle.offsets??null,\nversion:handle.version??0,\n};\n}\nfunction sliceDictionary(dict){\nif(Array.isArray(dict))return dict;\nif(isFunction(dict.values))return dict.values();\nreturn[];\n}\nfunction packHandles(handles){\nconst out=new Array(handles.length);\nfor(let i=0;i<handles.length;i++)out[i]=packHandle(handles[i]);\nreturn out;\n}\nclass TransportedBitset{\n#words;\n#bits;\nconstructor(words,bits){\nthis.#words=words;\nthis.#bits=bits;\n}\nget words(){return this.#words;}\nget size(){return this.#bits;}\nget(i){return(this.#words[i>>>3]&(1<<(i&7)))!==0;}\ncount(){\nconst w=this.#words;\nlet n=0;\nfor(let i=0;i<w.length;i++){\nlet v=w[i];\nwhile(v){v&=v-1;n++;}\n}\nreturn n;\n}\n}\nclass TransportedDictionary{\n#values;\n#index=null;\n#version=0;\n#ranks=new Map();\nconstructor(values){\nthis.#values=values||[];\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\ncodeOf(value){\nif(this.#index===null){\nthis.#index=new Map();\nfor(let i=0;i<this.#values.length;i++)this.#index.set(this.#values[i],i);\n}\nconst found=this.#index.get(value);\nif(found!==undefined)return found;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#index.set(value,code);\nthis.#version++;\nreturn code;\n}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nconst cached=this.#ranks.get(key);\nif(cached&&cached.version===this.#version)return cached.ranks;\nconst n=this.#values.length;\nconst order=new Uint32Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst vals=this.#values;\nconst sorted=Array.from(order).sort((a,b)=>{\nconst av=vals[a];\nconst bv=vals[b];\nif(av===bv)return 0;\nif(av===null||av===undefined)return 1;\nif(bv===null||bv===undefined)return-1;\nreturn cmp(String(av),String(bv));\n});\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<sorted.length;r++)ranks[sorted[r]]=r;\nthis.#ranks.set(key,{version:this.#version,ranks});\nreturn ranks;\n}\n}\nfunction unpackHandle(packed){\nif(packed==null)return null;\nconst presence=packed.presence\n?new TransportedBitset(packed.presence,packed.presenceBits||packed.presence.length*8)\n:null;\nconst dict=packed.dict?new TransportedDictionary(packed.dict):null;\nconst values=packed.values;\nconst offsets=packed.offsets??null;\nconst kind=packed.kind;\nconst get=(physical)=>{\nif(presence&&!presence.get(physical))return null;\nswitch(kind){\ncase'dictionary':\nreturn dict?dict.valueOf(values[physical]):values[physical];\ncase'bitset':\nreturn(values[physical>>>3]&(1<<(physical&7)))!==0;\ncase'multi':{\nif(!offsets)return null;\nconst from=offsets[physical];\nconst to=offsets[physical+1];\nconst out=new Array(to-from);\nfor(let i=from;i<to;i++)out[i-from]=dict?dict.valueOf(values[i]):values[i];\nreturn out;\n}\ndefault:\nreturn values[physical];\n}\n};\nreturn{\nid:packed.id,\nkind,\nnullable:packed.nullable,\nvalues,\npresence,\ndict,\noffsets,\nget,\nversion:packed.version,\n};\n}\nfunction unpackHandles(packed){\nconst out=new Array(packed.length);\nfor(let i=0;i<packed.length;i++)out[i]=unpackHandle(packed[i]);\nreturn out;\n}\nfunction createMaskPool(){\nconst masks=[];\nconst indices=[];\nreturn{\nmask(n){\nfor(let i=0;i<masks.length;i++){\nif(masks[i].length>=n){\nconst buf=masks.splice(i,1)[0].subarray(0,n);\nbuf.fill(0);\nreturn buf;\n}\n}\nreturn new Uint8Array(n);\n},\nindices(n){\nfor(let i=0;i<indices.length;i++){\nif(indices[i].length>=n)return indices.splice(i,1)[0].subarray(0,n);\n}\nreturn new Uint32Array(n);\n},\nrelease(buf){\nif(!buf)return;\nif(buf instanceof Uint8Array)masks.push(buf);\nelse if(buf instanceof Uint32Array)indices.push(buf);\n},\nclear(){masks.length=0;indices.length=0;},\n};\n}\nfunction isTransferable(v){\nif(!ArrayBuffer.isView(v))return false;\nconst buf=(v).buffer;\nif(!buf)return false;\nreturn typeof SharedArrayBuffer==='undefined'||!(buf instanceof SharedArrayBuffer);\n}\nfunction collectTransfers(value,out=[]){\nconst add=(v)=>{\nif(!isTransferable(v))return;\nconst buf=(v).buffer;\nif(!out.includes(buf))out.push(buf);\n};\nif(value==null)return out;\nif(ArrayBuffer.isView(value)){add(value);return out;}\nif(Array.isArray(value)){\nfor(const item of value)add(item);\nreturn out;\n}\nif(typeof value==='object'){\nfor(const key of Object.keys(value)){\nconst item=(value)[key];\nif(Array.isArray(item))for(const sub of item)add(sub);\nelse add(item);\n}\n}\nreturn out;\n}\nfunction isPortable(value,depth=0){\nif(value==null)return true;\nconst t=typeof value;\nif(t==='function'||t==='symbol')return false;\nif(t!=='object')return true;\nif(depth>4)return true;\nif(ArrayBuffer.isView(value)||value instanceof ArrayBuffer||value instanceof Date)return true;\nif(Array.isArray(value)){\nfor(const item of value)if(!isPortable(item,depth+1))return false;\nreturn true;\n}\nfor(const key of Object.keys(value)){\nif(!isPortable((value)[key],depth+1))return false;\n}\nreturn true;\n}\nfunction filterColumnIds(filters,out=new Set()){\nif(!filters||typeof filters!=='object')return out;\nconst node=(filters);\nif(typeof node.col==='string')out.add(node.col);\nconst conditions=node.conditions;\nif(Array.isArray(conditions))for(const child of conditions)filterColumnIds(child,out);\nreturn out;\n}\n});\n__def(\"packages/core/src/store/bitset.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Bitset\",{enumerable:true,get:function(){return Bitset;}});\nconst WORD_BITS=8;\nclass Bitset{\nstatic#POP=new Uint8Array(256);\nstatic{\nfor(let i=1;i<256;i++)Bitset.#POP[i]=Bitset.#POP[i>>1]+(i&1);\n}\n#words;\n#bits;\nconstructor(bits=0){\nconst n=Math.max(0,bits|0);\nthis.#bits=n;\nthis.#words=new Uint8Array(Math.ceil(n/WORD_BITS));\n}\nget size(){return this.#bits;}\nget words(){return this.#words;}\nget bytes(){return this.#words?this.#words.byteLength:0;}\nget(i){\nif(i<0||i>=this.#bits)return 0;\nreturn(this.#words[i>>3]>>(i&7))&1;\n}\nset(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]|=1<<(i&7);\nreturn this;\n}\nclear(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]&=~(1<<(i&7));\nreturn this;\n}\nassign(i,bit){return bit?this.set(i):this.clear(i);}\nfill(bit=false){\nthis.#words.fill(bit?0xff:0);\nif(bit)this.#maskTail();\nreturn this;\n}\ngrow(bits){\nconst n=Math.max(0,bits|0);\nif(n<=this.#bits)return this;\nconst need=Math.ceil(n/WORD_BITS);\nif(need>this.#words.length){\nconst next=new Uint8Array(need);\nnext.set(this.#words);\nthis.#words=next;\n}\nthis.#bits=n;\nreturn this;\n}\ncount(){\nconst w=this.#words;\nconst pop=Bitset.#POP;\nlet total=0;\nfor(let i=0;i<w.length;i++)total+=pop[w[i]];\nreturn total;\n}\nand(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]&=b[i];\nfor(let i=shared;i<w.length;i++)w[i]=0;\nreturn this;\n}\nor(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]|=b[i];\nreturn this;\n}\nnot(){\nconst w=this.#words;\nfor(let i=0;i<w.length;i++)w[i]=~w[i]&0xff;\nthis.#maskTail();\nreturn this;\n}\nclone(){\nconst out=new Bitset(this.#bits);\nout.words.set(this.#words.subarray(0,out.words.length));\nreturn out;\n}\nrelease(){\nthis.#words=new Uint8Array(0);\nthis.#bits=0;\n}\n#maskTail(){\nconst used=this.#bits&7;\nif(used===0)return;\nconst last=(this.#bits>>3);\nif(last<this.#words.length)this.#words[last]&=(1<<used)-1;\n}\nstatic from(bools){\nconst arr=Array.isArray(bools)?bools:Array.from(bools);\nconst out=new Bitset(arr.length);\nfor(let i=0;i<arr.length;i++)if(arr[i])out.set(i);\nreturn out;\n}\n}\n});\n__def(\"packages/core/src/store/dictionary.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Dictionary\",{enumerable:true,get:function(){return Dictionary;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nclass Dictionary{\n#values;\n#codes=new Map();\n#version=0;\n#ranks=null;\n#ranksVersion=-1;\n#ranksLocale='\\u0000';\nconstructor(values=[]){\nthis.#values=[];\nfor(let i=0;i<values.length;i++){\nconst v=values[i];\nif(this.#codes.has(v))continue;\nthis.#codes.set(v,this.#values.length);\nthis.#values.push(v);\n}\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\nget bytes(){\nlet total=this.#values.length*8;\nfor(let i=0;i<this.#values.length;i++){\nconst v=this.#values[i];\nif(typeof v==='string')total+=v.length*2;\ntotal+=16;\n}\nreturn total;\n}\ncodeOf(value){\nconst existing=this.#codes.get(value);\nif(existing!==undefined)return existing;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#codes.set(value,code);\nthis.#version++;\nreturn code;\n}\nlookup(value){\nconst code=this.#codes.get(value);\nreturn code===undefined?-1:code;\n}\nhas(value){return this.#codes.has(value);}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nif(this.#ranks&&this.#ranksVersion===this.#version&&this.#ranksLocale===key){\nreturn this.#ranks;\n}\nconst n=this.#values.length;\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst values=this.#values;\norder.sort((a,b)=>this.#compare(values[a],values[b],cmp));\nconst ranks=new Uint32Array(n);\nfor(let rank=0;rank<n;rank++)ranks[order[rank]]=rank;\nthis.#ranks=ranks;\nthis.#ranksVersion=this.#version;\nthis.#ranksLocale=key;\nreturn ranks;\n}\n#compare(a,b,compare){\nif(typeof a==='string'&&typeof b==='string')return compare(a,b);\nreturn defaultCompare(a,b);\n}\n}\n});\n__def(\"packages/core/src/store/multivalue.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"MultiValue\",{enumerable:true,get:function(){return MultiValue;}});\nclass MultiValue{\n#values;\n#offsets;\n#rows=0;\n#fill=0;\nconstructor(capacity={}){\nconst rows=Math.max(1,capacity.rows??16);\nconst values=Math.max(1,capacity.values??rows);\nthis.#values=new Int32Array(values);\nthis.#offsets=new Uint32Array(rows+1);\n}\nget values(){return this.#values;}\nget offsets(){return this.#offsets;}\nget rows(){return this.#rows;}\nget length(){return this.#fill;}\nget bytes(){return this.#values.byteLength+this.#offsets.byteLength;}\ncount(r){\nif(r<0||r>=this.#rows)return 0;\nreturn this.#offsets[r+1]-this.#offsets[r];\n}\nat(r){\nif(r<0||r>=this.#rows)return this.#values.subarray(0,0);\nreturn this.#values.subarray(this.#offsets[r],this.#offsets[r+1]);\n}\nhas(r,code){\nif(r<0||r>=this.#rows)return false;\nconst v=this.#values;\nconst end=this.#offsets[r+1];\nfor(let i=this.#offsets[r];i<end;i++)if(v[i]===code)return true;\nreturn false;\n}\nhasAny(r,codes){\nfor(let i=0;i<codes.length;i++)if(this.has(r,codes[i]))return true;\nreturn false;\n}\nhasAll(r,codes){\nfor(let i=0;i<codes.length;i++)if(!this.has(r,codes[i]))return false;\nreturn true;\n}\nhasNone(r,codes){return!this.hasAny(r,codes);}\npush(codes){\nconst r=this.#rows;\nconst n=codes.length;\nthis.#ensureRows(r+1);\nthis.#ensureValues(this.#fill+n);\nconst start=this.#fill;\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nthis.#fill+=n;\nthis.#rows=r+1;\nthis.#offsets[r]=start;\nthis.#offsets[r+1]=this.#fill;\nreturn r;\n}\nwrite(r,codes){\nif(r===this.#rows){this.push(codes);return;}\nif(r<0||r>this.#rows)return;\nconst start=this.#offsets[r];\nconst end=this.#offsets[r+1];\nconst n=codes.length;\nif(end-start===n){\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nreturn;\n}\nthis.#rebuild(r,codes);\n}\ncompact(remap,liveCount,dead){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst oldRows=this.#rows;\nconst values=new Int32Array(Math.max(1,this.#fill));\nconst offsets=new Uint32Array(liveCount+1);\nlet w=0;\nfor(let p=0;p<oldRows;p++){\nif(remap[p]===dead)continue;\nconst start=oldOffsets[p];\nconst end=oldOffsets[p+1];\noffsets[remap[p]]=w;\nfor(let i=start;i<end;i++)values[w++]=oldValues[i];\noffsets[remap[p]+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#rows=liveCount;\nthis.#fill=w;\n}\nrelease(){\nthis.#values=new Int32Array(0);\nthis.#offsets=new Uint32Array(1);\nthis.#rows=0;\nthis.#fill=0;\n}\n#ensureRows(rows){\nif(rows+1<=this.#offsets.length)return;\nlet cap=this.#offsets.length-1;\nwhile(cap<rows)cap=cap*2||16;\nconst next=new Uint32Array(cap+1);\nnext.set(this.#offsets);\nthis.#offsets=next;\n}\n#ensureValues(n){\nif(n<=this.#values.length)return;\nlet cap=this.#values.length;\nwhile(cap<n)cap=cap*2||16;\nconst next=new Int32Array(cap);\nnext.set(this.#values);\nthis.#values=next;\n}\n#rebuild(r,codes){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst rows=this.#rows;\nconst delta=codes.length-(oldOffsets[r+1]-oldOffsets[r]);\nconst values=new Int32Array(Math.max(1,this.#fill+delta));\nconst offsets=new Uint32Array(oldOffsets.length);\nlet w=0;\nfor(let p=0;p<rows;p++){\noffsets[p]=w;\nif(p===r){\nfor(let i=0;i<codes.length;i++)values[w++]=codes[i]|0;\n}else{\nfor(let i=oldOffsets[p];i<oldOffsets[p+1];i++)values[w++]=oldValues[i];\n}\noffsets[p+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#fill=w;\n}\n}\n});\n__def(\"packages/core/src/store/columnstore.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"REMOVED\",{enumerable:true,get:function(){return REMOVED;}});\nObject.defineProperty(__exports,\"toFloat\",{enumerable:true,get:function(){return toFloat;}});\nObject.defineProperty(__exports,\"ColumnHandle\",{enumerable:true,get:function(){return ColumnHandle;}});\nObject.defineProperty(__exports,\"ColumnStore\",{enumerable:true,get:function(){return ColumnStore;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/bitset.js\");\nconst Bitset=__m1[\"Bitset\"];\nconst __m2=__req(\"packages/core/src/store/dictionary.js\");\nconst Dictionary=__m2[\"Dictionary\"];\nconst __m3=__req(\"packages/core/src/store/multivalue.js\");\nconst MultiValue=__m3[\"MultiValue\"];\nconst REMOVED=0xFFFFFFFF;\nconst DEFAULT_CAPACITY=1024;\nconst DEFAULT_COLUMNAR_BELOW=5000;\nconst DEFAULT_COMPACT_RATIO=0.2;\nconst KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction absent(v){return v===null||v===undefined;}\nfunction toFloat(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(typeof v==='boolean')return v?1:0;\nconst n=Number(v);\nreturn Number.isNaN(n)&&typeof v==='string'?Date.parse(v):n;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(absent(v))return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction decodeFrom(old,p){\nswitch(old.kind){\ncase'float64':\ncase'int32':return old.buf[p];\ncase'bitset':return old.bits.get(p)===1;\ncase'dictionary':return old.dict.valueOf(old.buf[p]);\ncase'multi':{\nconst codes=old.mv.at(p);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=old.dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return old.buf[p];\n}\n}\nfunction decodePacked(frag,i){\nswitch(frag.kind){\ncase'float64':\ncase'int32':return frag.values[i];\ncase'bitset':return(frag.values[i>>3]&(1<<(i&7)))!==0;\ncase'dictionary':return(frag.table||[])[frag.values[i]];\ncase'multi':{\nconst start=frag.offsets[i];\nconst end=frag.offsets[i+1];\nconst table=frag.table||[];\nconst out=new Array(end-start);\nfor(let k=start;k<end;k++)out[k-start]=table[frag.values[k]];\nreturn out;\n}\ndefault:return frag.values[i];\n}\n}\nclass ColumnHandle{\n#id;\n#kind;\n#target;\n#nullable;\n#read;\n#host;\n#seed;\n#columnar=false;\n#buf=null;\n#bits=null;\n#mv=null;\n#dict=null;\n#presence=null;\n#capacity=0;\n#version=0;\n#overlay=null;\n#cache=null;\n#released=false;\nconstructor(schema,host){\nthis.#id=schema.id;\nconst kind=KINDS.has(schema.kind)?schema.kind:'object';\nif(schema.kind&&!KINDS.has(schema.kind)){\nwarnOnce(`store.kind.${schema.id}`,\n`column \"${schema.id}\" declares unknown storage kind \"${schema.kind}\"; falling back to object`);\n}\nthis.#target=kind;\nthis.#kind=kind;\nthis.#nullable=schema.nullable!==false;\nthis.#seed=schema.dictionary??null;\nthis.#host=host;\nthis.#read=isFunction(schema.read)\n?schema.read\n:pathGetter(schema.field||schema.id);\nthis.#overlay=new Map();\n}\nget id(){return this.#id;}\nget kind(){return this.#columnar?this.#kind:'object';}\nget target(){return this.#target;}\nget nullable(){return this.#nullable;}\nget values(){\nif(this.#released)return null;\nif(!this.#columnar)return this.#lazy().values;\nif(this.#kind==='bitset')return this.#bits.words;\nif(this.#kind==='multi')return this.#mv.values;\nreturn this.#buf;\n}\nget presence(){\nif(this.#released||!this.#nullable)return null;\nreturn this.#columnar?this.#presence:this.#lazy().presence;\n}\nget dict(){\nif(this.#released||!this.#columnar)return null;\nreturn this.#kind==='dictionary'||this.#kind==='multi'?this.#dict:null;\n}\nget offsets(){\nif(this.#released||!this.#columnar||this.#kind!=='multi')return null;\nreturn this.#mv.offsets;\n}\nget version(){return this.#version;}\nget bytes(){\nlet total=0;\nif(this.#buf)total+=this.#buf.byteLength??this.#buf.length*8;\nif(this.#bits)total+=this.#bits.bytes;\nif(this.#mv)total+=this.#mv.bytes;\nif(this.#presence)total+=this.#presence.bytes;\nif(this.#dict)total+=this.#dict.bytes;\nif(this.#overlay)total+=this.#overlay.size*24;\nreturn total;\n}\nget(physical){\nif(this.#released)return undefined;\nif(physical<0||physical>=this.#host.physical())return undefined;\nif(!this.#columnar)return this.#rowValue(physical);\nif(this.#nullable&&this.#presence.get(physical)===0)return null;\nswitch(this.#kind){\ncase'float64':\ncase'int32':return this.#buf[physical];\ncase'bitset':return this.#bits.get(physical)===1;\ncase'dictionary':return this.#dict.valueOf(this.#buf[physical]);\ncase'multi':{\nconst codes=this.#mv.at(physical);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=this.#dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return this.#buf[physical];\n}\n}\nset(physical,value){\nif(this.#released)return;\nif(this.#columnar)this.#writeValue(physical,value);\nelse this.#overlay.set(physical,value===undefined?null:value);\nthis.#version++;\n}\nread(row){return this.#read(row);}\nappendColumn(objects,from,n){\nif(this.#released||n<=0)return;\nif(!this.#columnar){this.#version++;return;}\nconst read=this.#read;\nconst nullable=this.#nullable;\nconst presence=this.#presence;\nlet sawAbsent=false;\nswitch(this.#kind){\ncase'float64':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nif(typeof v==='number'){\nif(nullable)presence.set(from+i);\nbuf[from+i]=v;\ncontinue;\n}\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?NaN:toFloat(v);\n}\nbreak;\n}\ncase'int32':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:toInt(v);\n}\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbits.assign(from+i,!gone&&!!v);\n}\nbreak;\n}\ncase'dictionary':{\nconst buf=this.#buf;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:dict.codeOf(v);\n}\nbreak;\n}\ncase'multi':{\nconst mv=this.#mv;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nconst members=toMembers(v);\nconst codes=new Array(members.length);\nfor(let k=0;k<members.length;k++)codes[k]=dict.codeOf(members[k]);\nmv.write(from+i,codes);\n}\nbreak;\n}\ndefault:{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?null:v;\n}\nbreak;\n}\n}\nif(sawAbsent){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nthis.#version++;\n}\nappendPacked(frag,from,n){\nif(this.#released||n<=0||!frag)return;\nif(!this.#columnar){this.#version++;return;}\nconst presence=this.#presence;\nconst fragPresence=frag.presence;\nif(presence){\nif(fragPresence){\nfor(let i=0;i<n;i++)presence.assign(from+i,(fragPresence[i>>3]&(1<<(i&7)))!==0);\n}else{\nfor(let i=0;i<n;i++)presence.set(from+i);\n}\n}\nconst kindsAgree=frag.kind===this.#kind;\nif(kindsAgree&&(this.#kind==='float64'||this.#kind==='int32')){\nthis.#buf.set(frag.values,from);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='bitset'){\nconst words=frag.values;\nfor(let i=0;i<n;i++)this.#bits.assign(from+i,(words[i>>3]&(1<<(i&7)))!==0);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='dictionary'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst codes=frag.values;\nconst buf=this.#buf;\nconst pres=presence;\nfor(let i=0;i<n;i++){\nif(pres&&(fragPresence?(fragPresence[i>>3]&(1<<(i&7)))===0:false)){buf[from+i]=0;continue;}\nbuf[from+i]=remap[codes[i]]??0;\n}\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='multi'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst flat=frag.values;\nconst offsets=frag.offsets;\nfor(let i=0;i<n;i++){\nconst start=offsets[i];\nconst end=offsets[i+1];\nconst codes=new Array(end-start);\nfor(let k=start;k<end;k++)codes[k-start]=remap[flat[k]]??0;\nthis.#mv.write(from+i,codes);\n}\nthis.#version++;\nreturn;\n}\nfor(let i=0;i<n;i++){\nconst gone=fragPresence\n?(fragPresence[i>>3]&(1<<(i&7)))===0\n:(frag.kind==='object'?frag.values[i]===null:false);\nthis.#writeValue(from+i,gone?null:decodePacked(frag,i));\n}\nthis.#version++;\n}\ntouch(){this.#version++;}\ncolumnarise(capacity,fill){\nif(this.#columnar||this.#released)return;\nconst values=new Array(fill);\nfor(let p=0;p<fill;p++)values[p]=this.#rowValue(p);\nthis.#kind=this.#target;\nthis.#columnar=true;\nthis.#alloc(capacity);\nfor(let p=0;p<fill;p++)this.#writeValue(p,values[p]);\nthis.#overlay.clear();\nthis.#cache=null;\nthis.#version++;\n}\ngrow(capacity){\nif(!this.#columnar||this.#released||capacity<=this.#capacity)return;\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':{\nconst next=new this.#buf.constructor(capacity);\nnext.set(this.#buf);\nthis.#buf=next;\nbreak;\n}\ncase'bitset':this.#bits.grow(capacity);break;\ncase'multi':break;\ndefault:this.#buf.length=capacity;break;\n}\nif(this.#presence)this.#presence.grow(capacity);\nthis.#capacity=capacity;\nthis.#version++;\n}\nconvert(kind){\nif(this.#released||!KINDS.has(kind))return false;\nthis.#target=kind;\nif(!this.#columnar||kind===this.#kind)return false;\nconst old={kind:this.#kind,buf:this.#buf,bits:this.#bits,mv:this.#mv,dict:this.#dict};\nconst n=this.#host.physical();\nconst presence=this.#presence;\nthis.#kind=kind;\nthis.#alloc(this.#capacity);\nfor(let p=0;p<n;p++){\nconst gone=presence!==null&&presence.get(p)===0;\nif(gone&&kind!=='multi')continue;\nthis.#writeValue(p,gone?null:decodeFrom(old,p));\n}\nthis.#version++;\nreturn true;\n}\ncompact(remap,oldFill,liveCount){\nif(this.#released)return;\nif(!this.#columnar){\nconst overlay=this.#overlay;\nif(overlay.size){\nconst next=new Map();\nfor(const[p,v]of overlay)if(remap[p]!==REMOVED)next.set(remap[p],v);\nthis.#overlay=next;\n}\nthis.#cache=null;\nthis.#version++;\nreturn;\n}\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':case'object':{\nconst buf=this.#buf;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)buf[remap[p]]=buf[p];\nif(this.#kind==='object')for(let p=liveCount;p<oldFill;p++)buf[p]=undefined;\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)bits.assign(remap[p],bits.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)bits.clear(p);\nbreak;\n}\ncase'multi':this.#mv.compact(remap,liveCount,REMOVED);break;\ndefault:break;\n}\nif(this.#presence){\nconst pres=this.#presence;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)pres.assign(remap[p],pres.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)pres.clear(p);\n}\nthis.#version++;\n}\nrelease(){\nif(this.#released)return;\nthis.#released=true;\nthis.#buf=null;\nif(this.#bits)this.#bits.release();\nthis.#bits=null;\nif(this.#mv)this.#mv.release();\nthis.#mv=null;\nif(this.#presence)this.#presence.release();\nthis.#presence=null;\nthis.#dict=null;\nthis.#overlay=new Map();\nthis.#cache=null;\nthis.#capacity=0;\nthis.#version++;\n}\n#alloc(capacity){\nconst cap=Math.max(1,capacity);\nthis.#buf=null;\nthis.#bits=null;\nthis.#mv=null;\nswitch(this.#kind){\ncase'float64':this.#buf=new Float64Array(cap);break;\ncase'int32':this.#buf=new Int32Array(cap);break;\ncase'bitset':this.#bits=new Bitset(cap);break;\ncase'dictionary':\nthis.#buf=new Uint32Array(cap);\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ncase'multi':\nthis.#mv=new MultiValue({rows:cap,values:cap});\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ndefault:this.#buf=new Array(cap);break;\n}\nif(this.#kind!=='dictionary'&&this.#kind!=='multi')this.#dict=null;\nif(this.#nullable){\nif(this.#presence)this.#presence.grow(cap);\nelse this.#presence=new Bitset(cap);\n}\nthis.#capacity=cap;\n}\n#writeValue(p,value){\nconst gone=absent(value);\nif(this.#nullable)this.#presence.assign(p,!gone);\nelse if(gone){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nswitch(this.#kind){\ncase'float64':this.#buf[p]=gone?NaN:toFloat(value);break;\ncase'int32':this.#buf[p]=gone?0:toInt(value);break;\ncase'bitset':this.#bits.assign(p,!gone&&!!value);break;\ncase'dictionary':this.#buf[p]=gone?0:this.#dict.codeOf(value);break;\ncase'multi':{\nconst members=toMembers(value);\nconst codes=new Array(members.length);\nfor(let i=0;i<members.length;i++)codes[i]=this.#dict.codeOf(members[i]);\nthis.#mv.write(p,codes);\nbreak;\n}\ndefault:this.#buf[p]=gone?null:value;break;\n}\n}\n#rowValue(p){\nif(this.#overlay.has(p))return this.#overlay.get(p);\nconst v=this.#read(this.#host.rowAt(p));\nreturn v===undefined?null:v;\n}\n#lazy(){\nif(this.#cache&&this.#cache.version===this.#version)return this.#cache;\nconst n=this.#host.physical();\nconst values=new Array(n);\nconst presence=this.#nullable?new Bitset(n):null;\nfor(let p=0;p<n;p++){\nconst v=this.#rowValue(p);\nvalues[p]=v;\nif(presence&&!absent(v))presence.set(p);\n}\nthis.#cache={version:this.#version,values,presence};\nreturn this.#cache;\n}\n}\nclass ColumnStore{\n#schema;\n#handles=new Map();\n#list=[];\n#rows=[];\n#fill=0;\n#capacity=0;\n#live=0;\n#dead=0;\n#tombs=new Bitset(0);\n#columnar=false;\n#retainSource=true;\n#columnarBelow;\n#initial;\n#ratio;\n#destroyed=false;\nconstructor(schema,opts={}){\nthis.#schema=Array.isArray(schema)?schema:[];\nthis.#initial=Math.max(1,opts.initialCapacity??DEFAULT_CAPACITY);\nthis.#retainSource=opts.retainSource!==false;\nthis.#columnarBelow=this.#retainSource?(opts.columnarBelow??DEFAULT_COLUMNAR_BELOW):0;\nthis.#ratio=opts.compactRatio??DEFAULT_COMPACT_RATIO;\nconst host={\nrowAt:(p)=>this.#rows[p],\nphysical:()=>this.#fill,\n};\nfor(const entry of this.#schema){\nif(!entry||!entry.id)continue;\nif(this.#handles.has(entry.id)){\nwarnOnce(`store.dup.${entry.id}`,`duplicate column id \"${entry.id}\" in the store schema; ignoring the second`);\ncontinue;\n}\nconst handle=new ColumnHandle(entry,host);\nthis.#handles.set(entry.id,handle);\nthis.#list.push(handle);\n}\nif(this.#columnarBelow<=0)this.#columnarise();\n}\nget count(){return this.#live;}\nget physical(){return this.#fill;}\nget capacity(){return this.#columnar?this.#capacity:this.#rows.length;}\nget tombstones(){return this.#dead;}\nget columnar(){return this.#columnar;}\nget destroyed(){return this.#destroyed;}\nget bytes(){\nlet total=this.#tombs.bytes+this.#rows.length*8;\nfor(const h of this.#list)total+=h.bytes;\nreturn total;\n}\nappend(objects){\nconst from=this.#fill;\nif(this.#destroyed||!objects)return{from,to:from};\nconst n=objects.length|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource)for(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar){\nif(this.#fill>=this.#columnarBelow)this.#columnarise();\nelse for(const h of this.#list)h.touch();\nreturn{from,to:this.#fill};\n}\nthis.#ensure(this.#fill);\nconst cols=this.#list;\nfor(let c=0;c<cols.length;c++)cols[c].appendColumn(objects,from,n);\nreturn{from,to:this.#fill};\n}\nappendPacked(chunk,objects){\nconst from=this.#fill;\nif(this.#destroyed||!chunk)return{from,to:from};\nconst n=chunk.count|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource&&objects){\nfor(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\n}\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar)this.#columnarise();\nthis.#ensure(this.#fill);\nconst byId=new Map();\nfor(const col of chunk.columns)byId.set(col.id,col);\nfor(const h of this.#list){\nconst frag=byId.get(h.id);\nif(frag)h.appendPacked(frag,from,n);\nelse{\nh.grow(this.#capacity);\n}\n}\nreturn{from,to:this.#fill};\n}\nsource(physical){\nif(this.#retainSource)return this.#rows[physical];\nif(physical<0||physical>=this.#fill)return undefined;\nreturn this.#reconstruct(physical);\n}\nsetSource(physical,object){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nif(!this.#retainSource)return;\nthis.#rows[physical]=object;\n}\nget(colId,physical){\nconst h=this.#handles.get(colId);\nreturn h?h.get(physical):undefined;\n}\nset(colId,physical,value){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nconst h=this.#handles.get(colId);\nif(!h){\nwarnOnce(`store.set.${colId}`,`set() on unknown column \"${colId}\"`);\nreturn;\n}\nh.set(physical,value);\n}\nremove(physical){\nif(this.#destroyed||physical<0||physical>=this.#fill)return false;\nif(this.#tombs.get(physical)===1)return false;\nthis.#tombs.set(physical);\nthis.#dead++;\nthis.#live--;\nreturn true;\n}\nlive(physical){\nif(physical<0||physical>=this.#fill)return false;\nreturn this.#tombs.get(physical)===0;\n}\ncompact(opts={}){\nif(this.#destroyed||this.#dead===0)return null;\nif(!opts.force&&this.#dead/this.#fill<this.#ratio)return null;\nconst oldFill=this.#fill;\nconst remap=new Uint32Array(oldFill);\nlet w=0;\nfor(let p=0;p<oldFill;p++)remap[p]=this.#tombs.get(p)===1?REMOVED:w++;\nfor(const h of this.#list)h.compact(remap,oldFill,w);\nif(this.#retainSource){\nconst rows=this.#rows;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)rows[remap[p]]=rows[p];\nrows.length=w;\n}\nthis.#fill=w;\nthis.#live=w;\nthis.#dead=0;\nthis.#tombs=new Bitset(Math.max(this.#capacity,w));\nreturn remap;\n}\ncolumn(colId){return this.#handles.get(colId);}\ncolumns(){return this.#list.slice();}\nliveIndices(){\nconst out=new Uint32Array(this.#live);\nif(this.#dead===0){\nfor(let p=0;p<this.#fill;p++)out[p]=p;\nreturn out;\n}\nlet k=0;\nfor(let p=0;p<this.#fill;p++)if(this.#tombs.get(p)===0)out[k++]=p;\nreturn out;\n}\nconvert(colId,kind){\nconst h=this.#handles.get(colId);\nreturn h?h.convert(kind):false;\n}\ndestroy(){\nif(this.#destroyed)return;\nthis.#destroyed=true;\nfor(const h of this.#list)h.release();\nthis.#handles.clear();\nthis.#list.length=0;\nthis.#rows.length=0;\nthis.#tombs.release();\nthis.#fill=0;\nthis.#live=0;\nthis.#dead=0;\nthis.#capacity=0;\n}\n#ensure(n){\nif(n<=this.#capacity)return;\nlet cap=this.#capacity||this.#initial;\nwhile(cap<n)cap*=2;\nfor(const h of this.#list)h.grow(cap);\nthis.#tombs.grow(cap);\nthis.#capacity=cap;\n}\n#reconstruct(physical){\nconst out={};\nfor(const h of this.#list)out[h.id]=h.get(physical);\nreturn out;\n}\n#columnarise(){\nif(this.#columnar)return;\nlet cap=this.#initial;\nwhile(cap<this.#fill)cap*=2;\nthis.#columnar=true;\nthis.#capacity=cap;\nthis.#tombs.grow(cap);\nfor(const h of this.#list)h.columnarise(cap,this.#fill);\n}\n}\n});\n__def(\"packages/core/src/store/ingest.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"INGEST_DEFAULTS\",{enumerable:true,get:function(){return INGEST_DEFAULTS;}});\nObject.defineProperty(__exports,\"inferKind\",{enumerable:true,get:function(){return inferKind;}});\nObject.defineProperty(__exports,\"decideText\",{enumerable:true,get:function(){return decideText;}});\nObject.defineProperty(__exports,\"createReaders\",{enumerable:true,get:function(){return createReaders;}});\nObject.defineProperty(__exports,\"Ingest\",{enumerable:true,get:function(){return Ingest;}});\nObject.defineProperty(__exports,\"ingest\",{enumerable:true,get:function(){return ingest;}});\nObject.defineProperty(__exports,\"ingestSync\",{enumerable:true,get:function(){return ingestSync;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst now=__m0[\"now\"];\nconst nextFrame=__m0[\"nextFrame\"];\nconst infoOnce=__m0[\"infoOnce\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/columnstore.js\");\nconst ColumnStore=__m1[\"ColumnStore\"];\nconst INGEST_DEFAULTS=Object.freeze({\nchunkMs:8,\nchunkRows:512,\nsampleSize:100,\ndictionaryRatio:0.1,\ncolumnarBelow:5000,\ninitialCapacity:1024,\n});\nfunction inferKind(samples,hints={}){\nif(hints.multi)return'multi';\nif(samples.length===0)return'object';\nlet numbers=0;let booleans=0;let strings=0;let dates=0;let arrays=0;\nfor(let i=0;i<samples.length;i++){\nconst v=samples[i];\nif(typeof v==='number')numbers++;\nelse if(typeof v==='boolean')booleans++;\nelse if(typeof v==='string')strings++;\nelse if(v instanceof Date)dates++;\nelse if(Array.isArray(v))arrays++;\n}\nconst n=samples.length;\nif(numbers===n)return'float64';\nif(booleans===n)return'bitset';\nif(dates===n)return'float64';\nif(strings===n)return'text';\nif(arrays===n)return'multi';\nreturn'object';\n}\nfunction decideText(distinct,rows,ratio){\nif(rows<=0)return'dictionary';\nreturn distinct<ratio*rows?'dictionary':'object';\n}\nfunction createReaders(columns,computed,context){\nconst readers=new Map();\nconst base=new Map();\nfor(const col of columns){\nif(col.computed)continue;\nconst read=isFunction(col.read)?col.read:pathGetter(col.field||col.id);\nbase.set(col.id,read);\nreaders.set(col.id,read);\n}\nconst order=computed?.order??[];\nconst fns=computed?.fns??{};\nconst deps=computed?.deps??{};\nconst wrapDeps=computed?.wrapDeps??null;\nconst active=order.filter((id)=>isFunction(fns[id]));\nconst wildcard=active.some((id)=>deps[id]==='*');\nlet memo=new WeakMap();\nconst resolve=(data)=>{\nconst values={};\nif(wildcard)for(const[id,read]of base)values[id]=read(data);\nfor(const id of active){\nconst declared=deps[id];\nlet bag;\nif(declared==='*'){\nbag=values;\n}else{\nbag={};\nconst list=declared||[];\nfor(let i=0;i<list.length;i++){\nconst d=list[i];\nbag[d]=d in values?values[d]:base.get(d)?.(data);\n}\n}\nvalues[id]=fns[id](wrapDeps?wrapDeps(bag,id):bag,{\ndata,row:null,column:null,grid:null,context,\n});\n}\nreturn values;\n};\nconst valuesFor=(data)=>{\nif(data===null||(typeof data!=='object'&&typeof data!=='function'))return resolve(data);\nlet v=memo.get(data);\nif(v===undefined){v=resolve(data);memo.set(data,v);}\nreturn v;\n};\nfor(const id of active){\nreaders.set(id,\n(data)=>valuesFor(data)[id]);\n}\nreturn{\nreaders,\nreset(){memo=new WeakMap();},\n};\n}\nclass ColumnPlan{\nspec;\nread;\nkind;\ninferred;\nnullable;\ncandidate=false;\ndistinct=null;\nchange=null;\nreason='';\nconstructor(spec,read){\nthis.spec=spec;\nthis.read=read;\nthis.kind='object';\nthis.inferred=false;\nthis.nullable=spec.nullable!==false;\n}\n}\nclass Ingest{\n#rows;\n#plans=[];\n#store=null;\n#readers;\n#cursor=0;\n#opts;\n#done=false;\n#cancelled=false;\n#elapsed=0;\n#columnar;\nconstructor(rows,plan={},opts={}){\nthis.#rows=Array.isArray(rows)?rows:Array.from(rows||[]);\nthis.#opts={...INGEST_DEFAULTS,...opts};\nconst columns=plan.columns??[];\nthis.#readers=createReaders(columns,plan.computed??null,plan.context);\nthis.#columnar=this.#rows.length>=this.#opts.columnarBelow;\nthis.#planColumns(columns,plan.computed??null);\nthis.#store=new ColumnStore(this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\nread:p.read,\ndictionary:p.spec.dictionary,\n})),{\ninitialCapacity:this.#opts.initialCapacity,\ncolumnarBelow:this.#opts.columnarBelow,\n});\n}\nget store(){return this.#store;}\nget done(){return this.#done||this.#cancelled;}\nget progress(){return this.#cursor;}\nslice(){\nif(this.done)return false;\nif(this.#opts.signal?.aborted){this.#cancelled=true;return false;}\nconst started=now();\nconst{chunkMs,chunkRows}=this.#opts;\nconst total=this.#rows.length;\ndo{\nconst end=Math.min(this.#cursor+chunkRows,total);\nthis.#store.append(this.#rows.slice(this.#cursor,end));\nthis.#measure(this.#cursor,end);\nthis.#cursor=end;\nthis.#readers.reset();\nthis.#reviewCardinality(false);\n}while(this.#cursor<total&&now()-started<chunkMs);\nthis.#elapsed+=now()-started;\nthis.#opts.onProgress?.({loaded:this.#cursor,total});\nif(this.#cursor>=total){\nthis.#reviewCardinality(true);\nthis.#done=true;\nreturn false;\n}\nreturn true;\n}\ncancel(){this.#cancelled=true;}\nresult(){\nreturn{\nstore:this.#store,\nschema:this.#plans.map((p)=>({\nid:p.spec.id,kind:p.kind,nullable:p.nullable,read:p.read,\ndictionary:p.spec.dictionary,\n})),\ndecisions:this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\ninferred:p.inferred,\ndistinct:p.candidate||p.change?this.#distinctOf(p):null,\nchange:p.change,\nreason:p.reason,\n})),\ncount:this.#store.count,\nelapsed:this.#elapsed,\ncancelled:this.#cancelled,\n};\n}\n#planColumns(columns,computed){\nconst rows=this.#rows;\nconst sampleN=Math.min(this.#opts.sampleSize,rows.length);\nconst ratio=this.#opts.dictionaryRatio;\nconst pure=computed?.pure instanceof Set\n?computed.pure\n:new Set(computed?.pure??computed?.order??[]);\nfor(const spec of columns){\nif(!spec||!spec.id)continue;\nif(spec.computed&&(spec.pure===false||(computed&&!pure.has(spec.id)))){\nwarnOnce(`ingest.impure.${spec.id}`,\n`column \"${spec.id}\" is an impure computed column and is not materialised into the store`);\ncontinue;\n}\nconst read=this.#readers.readers.get(spec.id)\n??(isFunction(spec.read)?spec.read:pathGetter(spec.field||spec.id));\nconst plan=new ColumnPlan(spec,read);\nif(spec.kind){\nplan.kind=spec.kind;\nplan.reason='declared by the caller';\n}else if(spec.dictionary){\nplan.kind=spec.multi?'multi':'dictionary';\nplan.reason='value table supplied (lookup column)';\n}else{\nconst samples=[];\nfor(let i=0;i<sampleN&&samples.length<this.#opts.sampleSize;i++){\nconst v=read(rows[i]);\nif(v!==null&&v!==undefined)samples.push(v);\n}\nplan.inferred=true;\nconst kind=inferKind(samples,{multi:spec.multi});\nif(kind==='text'){\nconst distinct=new Set(samples).size;\nplan.kind=decideText(distinct,samples.length,ratio);\nplan.candidate=this.#columnar;\nplan.reason=`sampled ${distinct} distinct in ${samples.length}`;\n}else{\nplan.kind=kind;\nplan.reason=`inferred from ${samples.length} sampled values`;\nif(kind==='object'&&samples.length){\ninfoOnce(`ingest.mixed.${spec.id}`,\n`column \"${spec.id}\" holds mixed or unrecognised value types; storing as an object array. Declare a type to avoid this.`);\n}\n}\nif(plan.kind==='object'&&plan.candidate)plan.distinct=new Set(samples);\n}\nthis.#plans.push(plan);\n}\n}\n#measure(from,to){\nconst rows=this.#rows;\nfor(const plan of this.#plans){\nif(!plan.candidate||!plan.distinct)continue;\nconst set=plan.distinct;\nfor(let i=from;i<to;i++){\nconst v=plan.read(rows[i]);\nif(v!==null&&v!==undefined)set.add(v);\n}\n}\n}\n#distinctOf(plan){\nif(plan.distinct)return plan.distinct.size;\nconst handle=this.#store.column(plan.spec.id);\nreturn handle?.dict?handle.dict.size:0;\n}\n#reviewCardinality(final){\nconst ratio=this.#opts.dictionaryRatio;\nconst total=this.#rows.length;\nfor(const plan of this.#plans){\nif(!plan.candidate)continue;\nconst distinct=this.#distinctOf(plan);\nif(plan.kind==='dictionary'&&distinct>=ratio*total){\nconst handle=this.#store.column(plan.spec.id);\nplan.distinct=new Set(handle?.dict?handle.dict.values():[]);\nthis.#store.convert(plan.spec.id,'object');\nplan.kind='object';\nplan.change='demoted';\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(plan.kind==='object'&&distinct>=ratio*total){\nplan.candidate=false;\nplan.distinct=null;\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(final&&plan.kind==='object'&&distinct<ratio*total){\nthis.#store.convert(plan.spec.id,'dictionary');\nplan.kind='dictionary';\nplan.change=plan.change==='demoted'?null:'promoted';\nplan.reason=`${distinct} distinct values is below ${ratio*100}% of ${total} rows`;\nplan.distinct=null;\n}\nif(final)plan.candidate=false;\n}\n}\n}\nasync function ingest(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,opts);\nconst frame=opts.scheduler?.frame??nextFrame;\nwhile(run.slice()){\nawait new Promise((resolve)=>{frame(resolve);});\n}\nreturn run.result();\n}\nfunction ingestSync(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,{...opts,chunkMs:Infinity});\nwhile(run.slice());\nreturn run.result();\n}\n});\n__def(\"packages/core/src/store/columnpack.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"isPortableSchema\",{enumerable:true,get:function(){return isPortableSchema;}});\nObject.defineProperty(__exports,\"packChunk\",{enumerable:true,get:function(){return packChunk;}});\nObject.defineProperty(__exports,\"packedTransfers\",{enumerable:true,get:function(){return packedTransfers;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/ingest.js\");\nconst inferKind=__m1[\"inferKind\"];\nconst decideText=__m1[\"decideText\"];\nconst INGEST_DEFAULTS=__m1[\"INGEST_DEFAULTS\"];\nconst __m2=__req(\"packages/core/src/store/columnstore.js\");\nconst toFloat=__m2[\"toFloat\"];\nconst PORTABLE_KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction isPortableSchema(schema){\nif(!Array.isArray(schema)||schema.length===0)return false;\nfor(const col of schema){\nif(!col||typeof col.id!=='string')return false;\nif(typeof col.field!=='string'||col.field==='')return false;\nif(col.kind&&!PORTABLE_KINDS.has(col.kind))return false;\n}\nreturn true;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(v===null||v===undefined)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction resolveKind(col,values,rows,ratio){\nif(col.kind)return col.kind;\nconst samples=[];\nfor(let i=0;i<values.length&&samples.length<INGEST_DEFAULTS.sampleSize;i++){\nconst v=values[i];\nif(v!==null&&v!==undefined)samples.push(v);\n}\nconst kind=inferKind(samples,{multi:col.multi});\nif(kind!=='text')return kind;\nconst distinct=new Set(samples).size;\nreturn decideText(distinct,samples.length,ratio);\n}\nfunction packChunk(schema,rows,opts={}){\nconst n=rows.length|0;\nconst ratio=opts.dictionaryRatio??INGEST_DEFAULTS.dictionaryRatio;\nconst columns=[];\nfor(const col of schema){\nconst read=pathGetter(col.field||col.id);\nconst nullable=col.nullable!==false;\nconst raw=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=read(rows[i]);\nraw[i]=v===undefined?null:v;\n}\nconst kind=resolveKind(col,raw,n,ratio);\nconst presence=nullable?new Uint8Array((n+7)>>3):null;\nconst present=(i)=>{if(presence)presence[i>>3]|=1<<(i&7);};\nlet packed;\nswitch(kind){\ncase'float64':{\nconst values=new Float64Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?NaN:toFloat(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'int32':{\nconst values=new Int32Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?0:toInt(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'bitset':{\nconst words=new Uint8Array((n+7)>>3);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nif(!gone&&!!v)words[i>>3]|=1<<(i&7);\n}\npacked={id:col.id,kind,nullable,values:words,presence,offsets:null,table:null};\nbreak;\n}\ncase'dictionary':{\nconst codes=new Uint32Array(n);\nconst table=[];\nconst index=new Map();\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v===null){codes[i]=0;continue;}\npresent(i);\nlet code=index.get(v);\nif(code===undefined){code=table.length;table.push(v);index.set(v,code);}\ncodes[i]=code;\n}\npacked={id:col.id,kind,nullable,values:codes,presence,offsets:null,table};\nbreak;\n}\ncase'multi':{\nconst table=[];\nconst index=new Map();\nconst offsets=new Uint32Array(n+1);\nconst flat=[];\nfor(let i=0;i<n;i++){\nconst v=raw[i];\noffsets[i]=flat.length;\nconst gone=v===null;\nif(!gone)present(i);\nconst members=toMembers(v);\nfor(let k=0;k<members.length;k++){\nconst m=members[k];\nlet code=index.get(m);\nif(code===undefined){code=table.length;table.push(m);index.set(m,code);}\nflat.push(code);\n}\n}\noffsets[n]=flat.length;\npacked={id:col.id,kind,nullable,values:Int32Array.from(flat),presence,offsets,table};\nbreak;\n}\ndefault:{\nconst values=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v!==null)present(i);\nvalues[i]=v;\n}\npacked={id:col.id,kind:'object',nullable,values,presence,offsets:null,table:null};\nbreak;\n}\n}\ncolumns.push(packed);\n}\nreturn{count:n,columns};\n}\nfunction packedTransfers(chunk){\nconst out=[];\nif(!chunk||!Array.isArray(chunk.columns))return out;\nconst add=(v)=>{\nif(ArrayBuffer.isView(v)&&v.buffer&&!out.includes(v.buffer))out.push(v.buffer);\n};\nfor(const col of chunk.columns){\nadd(col.values);\nadd(col.presence);\nadd(col.offsets);\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/compute/handle.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return identity;}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return rowCount;}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return bitReader;}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return presenceReader;}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return dictSize;}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return dictValue;}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return multiValue;}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return valueReader;}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return numericTotalOrder;}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return valueComparator;}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return dictRanks;}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return isMissing;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nconst warnOnce=__m0[\"warnOnce\"];\nfunction identity(n){\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[i]=i;\nreturn out;\n}\nfunction rowCount(handle,opts){\nif(opts&&typeof opts.count==='number')return opts.count;\nif(!handle)return 0;\nif(typeof handle.count==='number')return handle.count;\nif(typeof handle.length==='number')return handle.length;\nconst values=handle.values;\nif(handle.kind==='multi'&&handle.offsets)return Math.max(0,handle.offsets.length-1);\nif(!values)return handle.presence&&typeof handle.presence.size==='number'?handle.presence.size:0;\nif(handle.kind==='bitset'){\nif(typeof values.size==='number')return values.size;\nif(handle.presence&&typeof handle.presence.size==='number')return handle.presence.size;\nwarnOnce(`count:${handle.id}`,`column \"${handle.id}\" is bitset-backed with no declared row count; assuming ${values.length*8}`);\nreturn values.length*8;\n}\nreturn values.length;\n}\nconst bitOrders=new WeakMap();\nfunction bitOrderOf(bitset){\nconst ctor=bitset.constructor;\nif(!ctor)return'unknown';\nconst cached=bitOrders.get(ctor);\nif(cached)return cached;\nlet order='unknown';\ntry{\nlet probe=null;\nif(typeof ctor.from==='function')probe=ctor.from([false,true]);\nelse{\nprobe=new ctor(8);\nprobe.set(1);\n}\nconst words=probe&&probe.words;\nif(words&&words.length){\nif(words[0]===0x02)order='lsb';\nelse if(words[0]===0x40)order='msb';\n}\n}catch{\norder='unknown';\n}\nbitOrders.set(ctor,order);\nreturn order;\n}\nfunction bitReader(bits){\nif(!bits)return()=>0;\nconst raw=bits instanceof Uint8Array?bits:bits.words;\nif(raw instanceof Uint8Array){\nconst order=bits instanceof Uint8Array?'lsb':bitOrderOf(bits);\nif(order==='lsb')return(i)=>(raw[i>>>3]>>>(i&7))&1;\nif(order==='msb')return(i)=>(raw[i>>>3]>>>(7-(i&7)))&1;\n}\nif(typeof bits.get==='function')return(i)=>(bits.get(i)?1:0);\nreturn()=>0;\n}\nfunction presenceReader(handle){\nif(!handle||!handle.presence)return null;\nreturn bitReader(handle.presence);\n}\nfunction dictSize(dict){\nif(!dict)return 0;\nif(typeof dict.size==='number')return dict.size;\nif(typeof dict.values==='function')return dict.values().length;\nreturn 0;\n}\nfunction dictValue(dict,code){\nif(!dict)return null;\nif(typeof dict.valueOf==='function')return dict.valueOf(code);\nif(typeof dict.values==='function')return dict.values()[code];\nreturn null;\n}\nfunction multiValue(handle,i){\nconst offsets=handle.offsets;\nconst values=handle.values;\nif(!offsets||!values)return[];\nconst from=offsets[i];\nconst to=offsets[i+1];\nif(!(to>from))return[];\nconst dict=handle.dict;\nconst out=new Array(to-from);\nfor(let k=from;k<to;k++)out[k-from]=dict?dictValue(dict,values[k]):values[k];\nreturn out;\n}\nfunction valueReader(handle){\nif(!handle)return()=>undefined;\nconst values=handle.values;\nconst present=presenceReader(handle);\nconst kind=handle.kind;\nif(kind==='dictionary'){\nconst dict=handle.dict;\nif(present)return(i)=>(present(i)?dictValue(dict,values[i]):null);\nreturn(i)=>dictValue(dict,values[i]);\n}\nif(kind==='bitset'){\nconst bit=bitReader(values);\nif(present)return(i)=>(present(i)?bit(i)===1:null);\nreturn(i)=>bit(i)===1;\n}\nif(kind==='multi'){\nif(present)return(i)=>(present(i)?multiValue(handle,i):null);\nreturn(i)=>multiValue(handle,i);\n}\nif(!values&&typeof handle.get==='function'){\nconst get=handle.get.bind(handle);\nreturn(i)=>{\nconst v=get(i);\nreturn v===undefined?null:v;\n};\n}\nif(present){\nreturn(i)=>{\nif(!present(i))return null;\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nreturn(i)=>{\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nfunction numericTotalOrder(a,b){\nif(a<b)return-1;\nif(a>b)return 1;\nif(a===b){\nconst na=Object.is(a,-0);\nconst nb=Object.is(b,-0);\nif(na===nb)return 0;\nreturn na?-1:1;\n}\nconst an=Number.isNaN(a);\nconst bn=Number.isNaN(b);\nif(an&&bn)return 0;\nreturn an?1:-1;\n}\nfunction valueComparator(locale){\nconst coll=collator(locale);\nreturn(a,b)=>{\nif(a===b)return 0;\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return coll.compare(a,b);\nif(ta==='number'&&tb==='number')return numericTotalOrder(a,b);\nif(ta==='boolean'&&tb==='boolean')return a===b?0:a?1:-1;\nif(a instanceof Date||b instanceof Date){\nconst na=a instanceof Date?a.getTime():Number(a);\nconst nb=b instanceof Date?b.getTime():Number(b);\nreturn numericTotalOrder(na,nb);\n}\nreturn defaultCompare(a,b);\n};\n}\nfunction dictRanks(dict,locale){\nif(dict&&typeof dict.ranks==='function')return dict.ranks(locale);\nconst table=dict&&typeof dict.values==='function'?dict.values():[];\nconst n=table.length;\nconst cmp=valueComparator(locale);\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\norder.sort((a,b)=>cmp(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<n;r++)ranks[order[r]]=r;\nreturn ranks;\n}\nfunction isMissing(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\n});\n__def(\"packages/core/src/compute/sort.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return radixSortFloat64;}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return radixSortInt32;}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return rankSortDictionary;}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return mergeSortComparator;}});\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return sortColumn;}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return sortMulti;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m0[\"bitReader\"];\nconst dictRanks=__m0[\"dictRanks\"];\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst isMissing=__m0[\"isMissing\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueComparator=__m0[\"valueComparator\"];\nconst valueReader=__m0[\"valueReader\"];\nconst EMPTY_INDICES=new Uint32Array(0);\nconst SCRATCH=new ArrayBuffer(8);\nconst SCRATCH_F64=new Float64Array(SCRATCH);\nconst SCRATCH_U32=new Uint32Array(SCRATCH);\nconst HI=(()=>{\nSCRATCH_F64[0]=-1;\nreturn(SCRATCH_U32[1]&0x80000000)!==0?1:0;\n})();\nconst LO=HI===1?0:1;\nfunction transformDouble(value,out){\nSCRATCH_F64[0]=value;\nlet hi=SCRATCH_U32[HI];\nlet lo=SCRATCH_U32[LO];\nif((hi&0x80000000)!==0){\nhi=~hi>>>0;\nlo=~lo>>>0;\n}else{\nhi=(hi^0x80000000)>>>0;\n}\nout[0]=lo;\nout[1]=hi;\n}\nfunction radixLsd64(idx,lo,hi,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*8);\nfor(let i=0;i<n;i++){\nconst l=lo[i];\nconst h=hi[i];\nhist[l&0xff]++;\nhist[256+((l>>>8)&0xff)]++;\nhist[512+((l>>>16)&0xff)]++;\nhist[768+((l>>>24)&0xff)]++;\nhist[1024+(h&0xff)]++;\nhist[1280+((h>>>8)&0xff)]++;\nhist[1536+((h>>>16)&0xff)]++;\nhist[1792+((h>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcLo=lo;\nlet srcHi=hi;\nlet dstIdx=new Uint32Array(n);\nlet dstLo=new Uint32Array(n);\nlet dstHi=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<8;pass++){\nconst base=pass<<8;\nconst shift=(pass&3)<<3;\nconst useHi=pass>=4;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst l=srcLo[i];\nconst h=srcHi[i];\nconst digit=((useHi?h:l)>>>shift)&0xff;\nconst p=offset[digit]++;\ndstIdx[p]=srcIdx[i];\ndstLo[p]=l;\ndstHi[p]=h;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcLo;srcLo=dstLo;dstLo=t;\nt=srcHi;srcHi=dstHi;dstHi=t;\n}\nreturn srcIdx;\n}\nfunction radixLsd32(idx,keys,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*4);\nfor(let i=0;i<n;i++){\nconst k=keys[i];\nhist[k&0xff]++;\nhist[256+((k>>>8)&0xff)]++;\nhist[512+((k>>>16)&0xff)]++;\nhist[768+((k>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcKeys=keys;\nlet dstIdx=new Uint32Array(n);\nlet dstKeys=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<4;pass++){\nconst base=pass<<8;\nconst shift=pass<<3;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst k=srcKeys[i];\nconst p=offset[(k>>>shift)&0xff]++;\ndstIdx[p]=srcIdx[i];\ndstKeys[p]=k;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcKeys;srcKeys=dstKeys;dstKeys=t;\n}\nreturn srcIdx;\n}\nfunction countingSort(idx,keys,n,radix){\nconst counts=new Uint32Array(radix+1);\nfor(let i=0;i<n;i++)counts[keys[i]]++;\nlet sum=0;\nfor(let k=0;k<=radix;k++){\nconst c=counts[k];\ncounts[k]=sum;\nsum+=c;\n}\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];\nreturn out;\n}\nfunction sortUint32Keys(idx,keys,n,radix){\nif(n<2)return idx;\nif(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);\nreturn radixLsd32(idx,keys,n);\n}\nfunction exact(buffer,n){\nif(buffer.length===n&&buffer.byteOffset===0)return buffer;\nreturn Uint32Array.prototype.slice.call(buffer,0,n);\n}\nfunction radixSortFloat64(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=new Uint32Array(n);\nconst lo=new Uint32Array(n);\nconst hi=new Uint32Array(n);\nconst nans=new Uint32Array(n);\nconst pair=new Uint32Array(2);\nlet m=0;\nlet nanCount=0;\nfor(let i=0;i<n;i++){\nconst row=src[i];\nconst v=values[row];\nif(Number.isNaN(v)){nans[nanCount++]=row;continue;}\ntransformDouble(v,pair);\nif(descending){\nlo[m]=~pair[0]>>>0;\nhi[m]=~pair[1]>>>0;\n}else{\nlo[m]=pair[0];\nhi[m]=pair[1];\n}\nidx[m++]=row;\n}\nconst sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);\nif(nanCount===0)return exact(sorted,m);\nconst out=new Uint32Array(n);\nout.set(sorted.subarray(0,m),0);\nout.set(nans.subarray(0,nanCount),m);\nreturn out;\n}\nfunction radixSortInt32(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst k=(values[idx[i]]^0x80000000)>>>0;\nkeys[i]=descending?(~k>>>0):k;\n}\nreturn exact(radixLsd32(idx,keys,n),n);\n}\nfunction rankSortDictionary(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst ranks=dictRanks(handle.dict,opts.locale);\nconst codes=handle.values;\nconst present=presenceReader(handle);\nconst size=Math.max(dictSize(handle.dict),ranks.length);\nconst absentRank=size;\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nconst descending=!!opts.descending;\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nlet rank=present&&present(row)===0?absentRank:ranks[codes[row]];\nif(rank===undefined)rank=absentRank;\nkeys[i]=descending?absentRank-rank:rank;\n}\nreturn exact(sortUint32Keys(idx,keys,n,size+1),n);\n}\nfunction mergeSortComparator(values,order,compare){\nconst n=order.length;\nlet src=Uint32Array.from(order);\nif(n<2)return src;\nlet dst=new Uint32Array(n);\nfor(let width=1;width<n;width<<=1){\nfor(let start=0;start<n;start+=width<<1){\nconst mid=Math.min(start+width,n);\nconst end=Math.min(start+(width<<1),n);\nlet i=start;\nlet j=mid;\nlet k=start;\nwhile(i<mid&&j<end){\ndst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];\n}\nwhile(i<mid)dst[k++]=src[i++];\nwhile(j<end)dst[k++]=src[j++];\n}\nconst t=src;src=dst;dst=t;\n}\nreturn src;\n}\nfunction sortBitsetColumn(handle,idx,descending){\nconst bit=bitReader(handle.values);\nconst n=idx.length;\nconst out=new Uint32Array(n);\nconst first=descending?1:0;\nlet k=0;\nfor(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];\nfor(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];\nreturn out;\n}\nfunction indexableValues(handle,idx){\nconst values=handle.values;\nconst kind=handle.kind;\nconst direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));\nif(direct&&!handle.presence)return values;\nconst reader=valueReader(handle);\nconst materialised=new Array(rowCount(handle)||0);\nfor(let i=0;i<idx.length;i++){\nconst row=idx[i];\nmaterialised[row]=reader(row);\n}\nreturn materialised;\n}\nfunction allStrings(values,idx){\nfor(let i=0;i<idx.length;i++){\nif(typeof values[idx[i]]!=='string')return false;\n}\nreturn true;\n}\nfunction keyedSortStrings(values,idx,opts){\nconst n=idx.length;\nconst codeOf=new Map();\nconst table=[];\nconst codes=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst v=values[idx[i]];\nlet c=codeOf.get(v);\nif(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}\ncodes[i]=c;\n}\nconst d=table.length;\nconst compare=valueComparator(opts.locale);\nconst order=new Array(d);\nfor(let i=0;i<d;i++)order[i]=i;\norder.sort((a,b)=>compare(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(d);\nfor(let r=0;r<d;r++)ranks[order[r]]=r;\nconst descending=!!opts.descending;\nconst idxOut=Uint32Array.from(idx);\nconst keys=new Uint32Array(n);\nconst top=d-1;\nfor(let i=0;i<n;i++){\nconst rank=ranks[codes[i]];\nkeys[i]=descending?top-rank:rank;\n}\nreturn exact(sortUint32Keys(idxOut,keys,n,d),n);\n}\nfunction sortByComparator(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nif(idx.length>=2&&allStrings(values,idx))return keyedSortStrings(values,idx,opts);\nconst base=valueComparator(opts.locale);\nconst compare=opts.descending?(a,b)=>base(b,a):base;\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction sortByCompare(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nconst user=opts.compare;\nconst descending=!!opts.descending;\nconst compare=descending\n?(a,b)=>-user(a,b,undefined,undefined,true)\n:(a,b)=>user(a,b,undefined,undefined,false);\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction partitionPresent(handle,idx){\nconst n=idx.length;\nconst present=presenceReader(handle);\nconst values=handle.values;\nconst checkNaN=handle.kind==='float64'&&!!values;\nconst looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;\nif(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};\nconst keep=new Uint32Array(n);\nconst drop=new Uint32Array(n);\nlet p=0;\nlet a=0;\nif(present&&checkNaN){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(checkNaN&&!present){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(present&&!looseKind){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1)keep[p++]=row;else drop[a++]=row;\n}\n}else{\nconst reader=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;\n}\n}\nif(a===0)return{present:idx,absent:EMPTY_INDICES};\nreturn{present:keep.subarray(0,p),absent:drop.subarray(0,a)};\n}\nfunction joinRuns(sorted,absent,nullsFirst){\nif(absent.length===0)return sorted;\nconst out=new Uint32Array(sorted.length+absent.length);\nif(nullsFirst){\nout.set(absent,0);\nout.set(sorted,absent.length);\n}else{\nout.set(sorted,0);\nout.set(absent,sorted.length);\n}\nreturn out;\n}\nfunction sortColumn(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nif(!handle||src.length<2)return Uint32Array.from(src);\nconst{present,absent}=partitionPresent(handle,src);\nif(present.length===0)return Uint32Array.from(src);\nconst descending=!!opts.descending;\nlet sorted;\nif(typeof opts.compare==='function'){\nsorted=sortByCompare(handle,present,opts);\n}else{\nswitch(handle.kind){\ncase'float64':\nsorted=radixSortFloat64(handle.values,present,descending);\nbreak;\ncase'int32':\nsorted=radixSortInt32(handle.values,present,descending);\nbreak;\ncase'dictionary':\nsorted=rankSortDictionary(handle,present,opts);\nbreak;\ncase'bitset':\nsorted=sortBitsetColumn(handle,present,descending);\nbreak;\ndefault:\nsorted=sortByComparator(handle,present,opts);\nbreak;\n}\n}\nreturn joinRuns(sorted,absent,!!opts.nullsFirst);\n}\nfunction sortMulti(handles,entries,order,opts={}){\nconst list=entries||[];\nconst first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);\nlet current=order||identity(rowCount(first,opts));\nfor(let i=list.length-1;i>=0;i--){\nconst entry=list[i];\nconst handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);\nif(!handle)continue;\ncurrent=sortColumn(handle,current,{\ndescending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',\nnullsFirst:!!entry.nullsFirst,\nlocale:entry.locale!==undefined?entry.locale:opts.locale,\ncompare:entry.compare,\n});\n}\nreturn current instanceof Uint32Array?current:Uint32Array.from(current);\n}\nfunction byId(handles,id){\nif(!handles||id===undefined)return undefined;\nfor(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];\nreturn undefined;\n}\n});\n__def(\"packages/core/src/format/date.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"scanPattern\",{enumerable:true,get:function(){return scanPattern;}});\nObject.defineProperty(__exports,\"toDate\",{enumerable:true,get:function(){return toDate;}});\nObject.defineProperty(__exports,\"compilePattern\",{enumerable:true,get:function(){return compilePattern;}});\nObject.defineProperty(__exports,\"compileDate\",{enumerable:true,get:function(){return compileDate;}});\nObject.defineProperty(__exports,\"toIsoDate\",{enumerable:true,get:function(){return toIsoDate;}});\nObject.defineProperty(__exports,\"toIsoDateTime\",{enumerable:true,get:function(){return toIsoDateTime;}});\nObject.defineProperty(__exports,\"compareIso\",{enumerable:true,get:function(){return compareIso;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isNil=__m0[\"isNil\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst TOKENS=[\n'yyyy','yy','MMMM','MMM','MM','M','dd','d',\n'EEEE','EEE','HH','H','hh','h','mm','m','ss','s','SSS','a',\n];\nfunction scanPattern(pattern){\nconst out=[];\nlet i=0;\nlet literal='';\nconst flush=()=>{if(literal){out.push({token:null,text:literal});literal='';}};\nwhile(i<pattern.length){\nconst ch=pattern[i];\nif(ch===\"'\"){\nif(pattern[i+1]===\"'\"){literal+=\"'\";i+=2;continue;}\nconst end=pattern.indexOf(\"'\",i+1);\nif(end===-1){literal+=pattern.slice(i+1);i=pattern.length;continue;}\nliteral+=pattern.slice(i+1,end);\ni=end+1;\ncontinue;\n}\nconst token=TOKENS.find((t)=>pattern.startsWith(t,i));\nif(token){flush();out.push({token,text:token});i+=token.length;continue;}\nif(/[A-Za-z]/.test(ch)){\nwarnOnce(\n`date.pattern.token:${ch}`,\n`the date pattern \"${pattern}\" contains '${ch}', which is not a supported token, `\n+'so it is rendered as text. Quote it as a literal to silence this. '\n+`Supported: ${TOKENS.join(' ')}.`,\n);\n}\nliteral+=ch;\ni+=1;\n}\nflush();\nreturn out;\n}\nconst WALL_CLOCK=/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?(?:\\.\\d+)?)?$/;\nfunction toDate(value){\nif(isNil(value)||value==='')return null;\nif(value instanceof Date)return Number.isNaN(value.getTime())?null:value;\nif(typeof value==='number')return Number.isNaN(value)?null:new Date(value);\nif(typeof value==='string'){\nconst wall=WALL_CLOCK.exec(value.trim());\nif(wall){\nconst[,y,mo,d,h='0',mi='0',sec='0']=wall;\nreturn new Date(+y,+mo-1,+d,+h,+mi,+sec);\n}\nconst d=new Date(value);\nreturn Number.isNaN(d.getTime())?null:d;\n}\nreturn null;\n}\nfunction pad(n,w){return String(n).padStart(w,'0');}\nfunction fieldReader(timeZone){\nif(!timeZone){\nreturn(d)=>({\nyear:d.getFullYear(),month:d.getMonth()+1,day:d.getDate(),\nhour:d.getHours(),minute:d.getMinutes(),second:d.getSeconds(),\nms:d.getMilliseconds(),weekday:d.getDay(),\n});\n}\nconst zoned=new Intl.DateTimeFormat('en-US',{\ntimeZone,year:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',hour12:false,weekday:'short',\n});\nconst days={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};\nreturn(d)=>{\nconst f={year:0,month:1,day:1,hour:0,minute:0,second:0,ms:d.getMilliseconds(),weekday:0};\nfor(const part of zoned.formatToParts(d)){\nswitch(part.type){\ncase'year':f.year=Number(part.value);break;\ncase'month':f.month=Number(part.value);break;\ncase'day':f.day=Number(part.value);break;\ncase'hour':f.hour=Number(part.value)%24;break;\ncase'minute':f.minute=Number(part.value);break;\ncase'second':f.second=Number(part.value);break;\ncase'weekday':f.weekday=days[part.value]??0;break;\ndefault:break;\n}\n}\nreturn f;\n};\n}\nfunction compilePattern(pattern,locale,timeZone){\nconst segments=scanPattern(pattern);\nconst read=fieldReader(timeZone);\nconst used=new Set(segments.filter((s)=>s.token).map((s)=>s.token));\nconst monthShort=used.has('MMM')?new Intl.DateTimeFormat(locale,{month:'short',timeZone}):null;\nconst monthLong=used.has('MMMM')?new Intl.DateTimeFormat(locale,{month:'long',timeZone}):null;\nconst dayShort=used.has('EEE')?new Intl.DateTimeFormat(locale,{weekday:'short',timeZone}):null;\nconst dayLong=used.has('EEEE')?new Intl.DateTimeFormat(locale,{weekday:'long',timeZone}):null;\nreturn(d)=>{\nconst f=read(d);\nlet out='';\nfor(const seg of segments){\nif(!seg.token){out+=seg.text;continue;}\nswitch(seg.token){\ncase'yyyy':out+=pad(f.year,4);break;\ncase'yy':out+=pad(f.year%100,2);break;\ncase'MMMM':out+=monthLong.format(d);break;\ncase'MMM':out+=monthShort.format(d);break;\ncase'MM':out+=pad(f.month,2);break;\ncase'M':out+=String(f.month);break;\ncase'dd':out+=pad(f.day,2);break;\ncase'd':out+=String(f.day);break;\ncase'EEEE':out+=dayLong.format(d);break;\ncase'EEE':out+=dayShort.format(d);break;\ncase'HH':out+=pad(f.hour,2);break;\ncase'H':out+=String(f.hour);break;\ncase'hh':out+=pad(f.hour%12===0?12:f.hour%12,2);break;\ncase'h':out+=String(f.hour%12===0?12:f.hour%12);break;\ncase'mm':out+=pad(f.minute,2);break;\ncase'm':out+=String(f.minute);break;\ncase'ss':out+=pad(f.second,2);break;\ncase's':out+=String(f.second);break;\ncase'SSS':out+=pad(f.ms,3);break;\ncase'a':out+=f.hour<12?'AM':'PM';break;\ndefault:out+=seg.text;break;\n}\n}\nreturn out;\n};\n}\nconst UNITS=[\n['year',365*24*3600e3],\n['month',30*24*3600e3],\n['week',7*24*3600e3],\n['day',24*3600e3],\n['hour',3600e3],\n['minute',60e3],\n['second',1e3],\n];\nfunction compileDate(spec,locale){\nconst s=spec||{};\nconst loc=s.locale||locale||undefined;\nconst nullDisplay=s.nullDisplay??'';\nconst timeZone=s.timeZone;\nlet absolute;\nif(s.pattern){\nabsolute=compilePattern(s.pattern,loc,timeZone);\n}else if(s.dateStyle||s.timeStyle){\nconst opts={timeZone};\nif(s.dateStyle)opts.dateStyle=s.dateStyle;\nif(s.timeStyle)opts.timeStyle=s.timeStyle;\nconst dtf=new Intl.DateTimeFormat(loc,opts);\nabsolute=(d)=>dtf.format(d);\n}else{\nconst dtf=new Intl.DateTimeFormat(loc,{dateStyle:'medium',timeZone});\nabsolute=(d)=>dtf.format(d);\n}\nconst relative=s.relative?new Intl.RelativeTimeFormat(loc,{numeric:'auto'}):null;\nconst thresholdDays=typeof s.relative==='object'&&s.relative\n?(s.relative.threshold??7)\n:7;\nconst thresholdMs=thresholdDays*24*3600e3;\nconst format=(value,params)=>{\nconst d=toDate(value);\nif(!d)return nullDisplay;\nif(relative){\nconst now=params&&typeof params.now==='number'?params.now:Date.now();\nconst delta=d.getTime()-now;\nif(Math.abs(delta)<thresholdMs){\nfor(const[unit,ms]of UNITS){\nif(Math.abs(delta)>=ms||unit==='second'){\nreturn relative.format(Math.round(delta/ms),unit);\n}\n}\n}\n}\nreturn absolute(d);\n};\nformat.spec=s;\nreturn format;\n}\nfunction toIsoDate(value){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst match=/^(\\d{4}-\\d{2}-\\d{2})/.exec(value.trim());\nif(match)return match[1];\nconst parsed=toDate(value);\nreturn parsed?toIsoDate(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nconst pad=(n)=>String(n).padStart(2,'0');\nreturn`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\n}\nfunction toIsoDateTime(value,timeZone){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst text=value.trim();\nif(ZONE_SUFFIX.test(text)){\nconst instant=toDate(text);\nreturn instant?wallClockIn(instant,timeZone):null;\n}\nconst match=/^(\\d{4}-\\d{2}-\\d{2})[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?/.exec(text);\nif(match){\nconst[,day,hour,minute,second]=match;\nreturn`${day}T${hour}:${minute}${second&&second!=='00'?`:${second}`:''}`;\n}\nif(/^\\d{4}-\\d{2}-\\d{2}$/.test(text))return`${text}T00:00`;\nconst parsed=toDate(text);\nreturn parsed?toIsoDateTime(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nreturn wallClockIn(date,timeZone);\n}\nconst ZONE_SUFFIX=/(?:Z|[+-]\\d{2}:?\\d{2})$/i;\nfunction wallClockIn(date,timeZone){\nconst pad=(n)=>String(n).padStart(2,'0');\nif(timeZone){\ntry{\nconst parts=new Intl.DateTimeFormat('en-CA',{\ntimeZone,\nyear:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',\nhour12:false,\n}).formatToParts(date).reduce((out,part)=>{\nif(part.type!=='literal')out[part.type]=part.value;\nreturn out;\n},{});\nconst hour=parts.hour==='24'?'00':parts.hour;\nconst seconds=Number(parts.second);\nreturn`${parts.year}-${parts.month}-${parts.day}T${hour}:${parts.minute}`\n+(seconds?`:${parts.second}`:'');\n}catch{\n}\n}\nconst day=`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\nconst seconds=date.getSeconds();\nconst clock=`${pad(date.getHours())}:${pad(date.getMinutes())}${seconds?`:${pad(seconds)}`:''}`;\nreturn`${day}T${clock}`;\n}\nfunction compareIso(a,b){\nconst left=isNil(a)||a===''?null:String(a);\nconst right=isNil(b)||b===''?null:String(b);\nif(left===null)return right===null?0:1;\nif(right===null)return-1;\nreturn left<right?-1:left>right?1:0;\n}\n});\n__def(\"packages/core/src/compute/filter.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return releaseMask;}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return compilePredicate;}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return testValue;}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return evaluateCondition;}});\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return evaluateFilters;}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return pruneColumn;}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return mentionsColumn;}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return compact;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isBlank=__m0[\"isBlank\"];\nconst toArray=__m0[\"toArray\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/format/date.js\");\nconst toIsoDate=__m1[\"toIsoDate\"];\nconst __m2=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m2[\"bitReader\"];\nconst dictSize=__m2[\"dictSize\"];\nconst dictValue=__m2[\"dictValue\"];\nconst presenceReader=__m2[\"presenceReader\"];\nconst valueComparator=__m2[\"valueComparator\"];\nconst valueReader=__m2[\"valueReader\"];\nconst ISO_DAY=/^\\d{4}-\\d{2}-\\d{2}$/;\nconst NULL_KEY='\\u0000null\\u0000';\nfunction acquireMask(ctx,n){\nconst pool=ctx&&ctx.pool;\nif(pool){\nconst take=pool.mask||pool.acquireMask||pool.acquire||pool.take;\nif(typeof take==='function'){\nconst mask=take.call(pool,n);\nif(mask&&mask.length>=n)return mask;\n}\n}\nreturn new Uint8Array(n);\n}\nfunction releaseMask(ctx,mask){\nconst pool=ctx&&ctx.pool;\nif(!pool||!mask)return;\nconst give=pool.release||pool.releaseMask||pool.free||pool.recycle;\nif(typeof give==='function')give.call(pool,mask);\n}\nfunction fillMask(mask,n,value){\nmask.fill(value,0,n);\nreturn mask;\n}\nfunction unorderable(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\nfunction coerceTarget(value,type){\nif(value===null||value===undefined)return value;\nif(type==='number')return typeof value==='number'?value:Number(value);\nif(type==='date'||type==='dateString'){\nconst iso=toIsoDate(value);\nreturn iso===null?toMillis(value):iso;\n}\nif(type==='boolean'){\nif(typeof value==='boolean')return value;\nif(value==='true'||value===1)return true;\nif(value==='false'||value===0)return false;\nreturn!!value;\n}\nreturn value;\n}\nfunction toMillis(value){\nif(value instanceof Date)return value.getTime();\nif(typeof value==='number')return value;\nreturn Date.parse(String(value));\n}\nfunction toNumber(value){\nif(typeof value==='number')return value;\nif(value instanceof Date)return value.getTime();\nif(value===null||value===undefined||value==='')return NaN;\nreturn Number(value);\n}\nfunction textOf(v,caseSensitive){\nconst s=typeof v==='string'?v:String(v);\nreturn caseSensitive?s:s.toLowerCase();\n}\nfunction setKey(v,caseSensitive){\nif(v===null||v===undefined)return NULL_KEY;\nif(typeof v==='string')return caseSensitive?v:v.toLowerCase();\nif(v instanceof Date)return v.getTime();\nreturn v;\n}\nfunction buildSet(value,caseSensitive,type){\nconst set=new Set();\nfor(const raw of toArray(value)){\nconst entry=coerceTarget(raw,type);\nset.add(setKey(entry,caseSensitive));\nif(typeof entry==='string'&&entry!==''&&Number.isFinite(Number(entry)))set.add(Number(entry));\nelse if(typeof entry==='number'&&Number.isFinite(entry))set.add(setKey(String(entry),caseSensitive));\n}\nreturn set;\n}\nfunction valueEquals(a,b,caseSensitive){\nif(a===null||a===undefined||b===null||b===undefined){\nreturn(a===null||a===undefined)&&(b===null||b===undefined);\n}\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return caseSensitive?a===b:a.toLowerCase()===b.toLowerCase();\nif(a instanceof Date||b instanceof Date)return toMillis(a)===toMillis(b);\nif(ta==='number'&&tb==='number')return a===b||(Number.isNaN(a)&&Number.isNaN(b));\nif(ta==='number'&&tb==='string')return a===Number(b);\nif(ta==='string'&&tb==='number')return Number(a)===b;\nif(ta==='boolean'||tb==='boolean')return a===b;\nif(Array.isArray(a)&&Array.isArray(b)){\nreturn a.length===b.length&&a.every((x,i)=>valueEquals(x,b[i],caseSensitive));\n}\nreturn a===b;\n}\nfunction compileRegExp(value,caseSensitive){\ntry{\nif(value instanceof RegExp){\nconst flags=value.flags.replace(/[gy]/g,'');\nreturn new RegExp(value.source,caseSensitive?flags:flags.includes('i')?flags:`${flags}i`);\n}\nreturn new RegExp(String(value),caseSensitive?'':'i');\n}catch(err){\nwarnOnce(`regex:${String(value)}`,`filter operator \"matches\" received an invalid pattern: ${String(value)}`,err);\nreturn null;\n}\n}\nfunction compilePredicate(condition,locale){\nconst predicate=compileValuePredicate(condition,locale);\nconst type=condition&&condition.type;\nif(type!=='date'&&type!=='dateString')return predicate;\nreturn(v)=>predicate(typeof v==='string'&&ISO_DAY.test(v)?v:(toIsoDate(v)??v));\n}\nfunction compileValuePredicate(condition,locale){\nconst op=condition&&condition.op;\nconst caseSensitive=!!(condition&&condition.caseSensitive);\nconst type=condition&&condition.type;\nconst cmp=valueComparator(locale);\nconst not=(p)=>(v)=>!p(v);\nswitch(op){\ncase'eq':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>valueEquals(v,target,caseSensitive);\n}\ncase'ne':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>!valueEquals(v,target,caseSensitive);\n}\ncase'lt':case'lte':case'gt':case'gte':{\nconst target=coerceTarget(condition.value,type);\nif(unorderable(target))return()=>false;\nconst want=op==='lt'?-1:op==='lte'?0:op==='gt'?1:2;\nreturn(v)=>{\nif(unorderable(v))return false;\nconst c=cmp(v,target);\nreturn want===-1?c<0:want===0?c<=0:want===1?c>0:c>=0;\n};\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=coerceTarget(pair[0],type);\nconst hi=coerceTarget(pair[1],type);\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nif(unorderable(lo)||unorderable(hi))return op==='between'?()=>false:()=>true;\nconst inRange=(v)=>{\nif(unorderable(v))return false;\nconst a=cmp(v,lo);\nconst b=cmp(v,hi);\nreturn(loInclusive?a>=0:a>0)&&(hiInclusive?b<=0:b<0);\n};\nreturn op==='between'?inRange:not(inRange);\n}\ncase'in':case'notIn':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst member=(v)=>set.has(setKey(v,caseSensitive));\nreturn op==='in'?member:not(member);\n}\ncase'contains':case'notContains':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nconst has=(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).includes(needle));\nreturn op==='contains'?has:not(has);\n}\ncase'startsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).startsWith(needle));\n}\ncase'endsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).endsWith(needle));\n}\ncase'matches':{\nconst re=compileRegExp(condition.value,caseSensitive);\nif(!re)return()=>false;\nreturn(v)=>(v===null||v===undefined?false:re.test(String(v)));\n}\ncase'blank':\nreturn(v)=>isBlank(v)||(Array.isArray(v)&&v.length===0);\ncase'notBlank':\nreturn(v)=>!(isBlank(v)||(Array.isArray(v)&&v.length===0));\ncase'containsAny':case'containsNone':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst any=(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nfor(let i=0;i<list.length;i++)if(set.has(setKey(list[i],caseSensitive)))return true;\nreturn false;\n};\nreturn op==='containsAny'?any:not(any);\n}\ncase'containsAll':{\nconst wanted=toArray(condition.value).map((x)=>setKey(coerceTarget(x,type),caseSensitive));\nreturn(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nif(wanted.length===0)return true;\nconst have=new Set(list.map((x)=>setKey(x,caseSensitive)));\nfor(let i=0;i<wanted.length;i++)if(!have.has(wanted[i]))return false;\nreturn true;\n};\n}\ndefault:\nwarnOnce(`op:${String(op)}`,`unknown filter operator \"${String(op)}\"; the condition passes every row`);\nreturn()=>true;\n}\n}\nfunction testValue(value,condition,locale){\nreturn compilePredicate(condition,locale)(value);\n}\nfunction presenceCondition(handle,wantPresent,mask,count){\nconst present=presenceReader(handle);\nif(present){\nconst target=wantPresent?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===target?1:0;\nreturn mask;\n}\nconst kind=handle.kind;\nif(kind==='float64'||kind==='int32'||kind==='bitset'){\nreturn fillMask(mask,count,wantPresent?1:0);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++){\nconst v=read(i);\nconst blank=isBlank(v)||(Array.isArray(v)&&v.length===0);\nmask[i]=blank===wantPresent?0:1;\n}\nreturn mask;\n}\nfunction dictionaryCondition(handle,pred,mask,count){\nconst dict=handle.dict;\nconst size=dictSize(dict);\nconst allowed=new Uint8Array(size);\nfor(let code=0;code<size;code++)allowed[code]=pred(dictValue(dict,code))?1:0;\nconst codes=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=allowed[codes[i]];\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===1?allowed[codes[i]]:absentAnswer;\nreturn mask;\n}\nfunction booleanCondition(handle,pred,mask,count){\nconst bit=bitReader(handle.values);\nconst whenTrue=pred(true)?1:0;\nconst whenFalse=pred(false)?1:0;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=bit(i)===1?whenTrue:whenFalse;\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++){\nmask[i]=present(i)===0?absentAnswer:(bit(i)===1?whenTrue:whenFalse);\n}\nreturn mask;\n}\nfunction numericCondition(handle,condition,pred,mask,count){\nconst values=handle.values;\nconst type=condition.type;\nconst op=condition.op;\nlet handled=true;\nswitch(op){\ncase'eq':case'ne':{\nconst target=toNumber(coerceTarget(condition.value,type));\nconst wantNaN=typeof condition.value==='number'&&Number.isNaN(condition.value);\nconst invert=op==='ne'?1:0;\nif(wantNaN){\nfor(let i=0;i<count;i++)mask[i]=(Number.isNaN(values[i])?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=((values[i]===target)?1:0)^invert;\n}\nbreak;\n}\ncase'lt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<t?1:0;\nbreak;\n}\ncase'lte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<=t?1:0;\nbreak;\n}\ncase'gt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>t?1:0;\nbreak;\n}\ncase'gte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>=t?1:0;\nbreak;\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=toNumber(coerceTarget(pair[0],type));\nconst hi=toNumber(coerceTarget(pair[1],type));\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nconst invert=op==='notBetween'?1:0;\nif(loInclusive&&hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<=hi))?1:0)^invert;\n}else if(loInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<hi))?1:0)^invert;\n}else if(hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<=hi))?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<hi))?1:0)^invert;\n}\nbreak;\n}\ncase'in':case'notIn':{\nconst set=new Set();\nfor(const raw of toArray(condition.value)){\nconst n=toNumber(coerceTarget(raw,type));\nif(!Number.isNaN(n))set.add(n);\n}\nconst invert=op==='notIn'?1:0;\nfor(let i=0;i<count;i++)mask[i]=(set.has(values[i])?1:0)^invert;\nbreak;\n}\ndefault:\nhandled=false;\nbreak;\n}\nif(!handled)return false;\nconst present=presenceReader(handle);\nif(present){\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)if(present(i)===0)mask[i]=absentAnswer;\n}\nreturn true;\n}\nfunction genericCondition(handle,pred,mask,count){\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++)mask[i]=pred(read(i))?1:0;\nreturn mask;\n}\nfunction evaluateCondition(condition,ctx,out){\nconst count=ctx.count|0;\nconst mask=out||acquireMask(ctx,count);\nif(!condition)return fillMask(mask,count,1);\nconst handle=typeof ctx.handle==='function'?ctx.handle(condition.col):undefined;\nconst custom=typeof ctx.custom==='function'?ctx.custom:null;\nif(!handle){\nif(custom){\nfor(let i=0;i<count;i++)mask[i]=custom(condition,i)?1:0;\nreturn mask;\n}\nwarnOnce(`filter:col:${String(condition.col)}`,\n`filter references unknown column \"${String(condition.col)}\"; the condition passes every row`);\nreturn fillMask(mask,count,1);\n}\nconst op=condition.op;\nif(op==='blank'||op==='notBlank')return presenceCondition(handle,op==='notBlank',mask,count);\nconst pred=compilePredicate(condition,ctx.locale);\nswitch(handle.kind){\ncase'dictionary':\nreturn dictionaryCondition(handle,pred,mask,count);\ncase'bitset':\nreturn booleanCondition(handle,pred,mask,count);\ncase'float64':case'int32':\nif(numericCondition(handle,condition,pred,mask,count))return mask;\nreturn genericCondition(handle,pred,mask,count);\ndefault:\nreturn genericCondition(handle,pred,mask,count);\n}\n}\nfunction evaluateNode(node,ctx,count){\nif(!node)return fillMask(acquireMask(ctx,count),count,1);\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(children.length===0)return fillMask(acquireMask(ctx,count),count,1);\nconst acc=evaluateNode(children[0],ctx,count);\nfor(let k=1;k<children.length;k++){\nconst rhs=evaluateNode(children[k],ctx,count);\nif(op==='or')for(let i=0;i<count;i++)acc[i]|=rhs[i];\nelse for(let i=0;i<count;i++)acc[i]&=rhs[i];\nreleaseMask(ctx,rhs);\n}\nif(op==='not')for(let i=0;i<count;i++)acc[i]^=1;\nreturn acc;\n}\nreturn evaluateCondition(node,ctx,acquireMask(ctx,count));\n}\nfunction evaluateFilters(filters,ctx){\nreturn evaluateNode(filters,ctx,ctx.count|0);\n}\nfunction pruneColumn(filters,colId){\nif(!filters||!colId)return filters||null;\nconst node=(filters);\nif(Array.isArray(node.conditions)){\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(op!=='and'){\nreturn mentionsColumn(node,colId)?null:filters;\n}\nconst kept=[];\nfor(const child of node.conditions){\nconst pruned=pruneColumn(child,colId);\nif(pruned)kept.push(pruned);\n}\nif(!kept.length)return null;\nreturn{...node,op:'and',conditions:kept};\n}\nreturn node.col===colId?null:filters;\n}\nfunction mentionsColumn(filters,colId){\nif(!filters||typeof filters!=='object')return false;\nconst node=(filters);\nif(node.col===colId)return true;\nif(Array.isArray(node.conditions)){\nfor(const child of node.conditions)if(mentionsColumn(child,colId))return true;\n}\nreturn false;\n}\nfunction compact(mask,count,out){\nif(out&&out.length>=count){\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])out[k++]=i;\nreturn out.subarray(0,k);\n}\nlet survivors=0;\nfor(let i=0;i<count;i++)survivors+=mask[i]?1:0;\nconst result=new Uint32Array(survivors);\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])result[k++]=i;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/group.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return packKeys;}});\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return groupByColumns;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueReader=__m0[\"valueReader\"];\nconst KEY_SEPARATOR='\\u001F';\nconst NULL_MARKER='\\u0000';\nconst MAX_DIRECT_COUNTS=1<<20;\nfunction packKeys(handles,idx,n){\nconst k=handles.length;\nconst readers=handles.map((h)=>valueReader(h));\nconst allDictionary=k>0&&handles.every((h)=>h&&h.kind==='dictionary'&&h.dict);\nif(allDictionary){\nconst cards=handles.map((h)=>dictSize(h.dict)+1);\nlet product=1;\nfor(let j=0;j<k;j++)product*=cards[j];\nif(product<=Number.MAX_SAFE_INTEGER){\nconst codes=handles.map((h)=>h.values);\nconst presence=handles.map((h)=>presenceReader(h));\nconst keyOf=(row)=>{\nlet key=0;\nfor(let j=0;j<k;j++){\nconst present=presence[j];\nconst code=present&&present(row)===0?cards[j]-1:codes[j][row];\nkey=key*cards[j]+code;\n}\nreturn key;\n};\nconst packed=new Float64Array(n);\nfor(let i=0;i<n;i++)packed[i]=keyOf(idx[i]);\nreturn{packed,strings:null,product,readers,keyOf};\n}\n}\nconst keyOf=(row)=>{\nlet key='';\nfor(let j=0;j<k;j++){\nconst v=readers[j](row);\nkey+=(j===0?'':KEY_SEPARATOR)+(v===null||v===undefined?NULL_MARKER:String(v));\n}\nreturn key;\n};\nconst strings=new Array(n);\nfor(let i=0;i<n;i++)strings[i]=keyOf(idx[i]);\nreturn{packed:null,strings,product:Infinity,readers,keyOf};\n}\nfunction scatterBuckets(idx,ids,n,groups){\nconst offsets=new Uint32Array(groups+1);\nfor(let i=0;i<n;i++)offsets[ids[i]+1]++;\nfor(let g=0;g<groups;g++)offsets[g+1]+=offsets[g];\nconst scattered=new Uint32Array(n);\nconst cursor=offsets.slice(0,groups);\nfor(let i=0;i<n;i++)scattered[cursor[ids[i]]++]=idx[i];\nconst buckets=new Array(groups);\nfor(let g=0;g<groups;g++)buckets[g]=scattered.subarray(offsets[g],offsets[g+1]);\nreturn buckets;\n}\nfunction groupByColumns(handles,order,opts={}){\nconst list=handles||[];\nconst idx=order||identity(rowCount(list[0],opts));\nconst n=idx.length;\nif(list.length===0||n===0)return{keys:[],buckets:[]};\nconst{packed,strings,product,readers}=packKeys(list,idx,n);\nconst ids=new Uint32Array(n);\nlet groups=0;\nlet packedKeys=null;\nif(packed&&product<=Math.max(1024,Math.min(MAX_DIRECT_COUNTS,n*4))){\nconst size=product;\nconst seen=new Int32Array(size).fill(-1);\nfor(let i=0;i<n;i++)seen[packed[i]]=0;\nfor(let key=0;key<size;key++)if(seen[key]===0)seen[key]=groups++;\nfor(let i=0;i<n;i++)ids[i]=seen[packed[i]];\npackedKeys=new Float64Array(groups);\nfor(let key=0;key<size;key++)if(seen[key]>=0)packedKeys[seen[key]]=key;\n}else if(packed){\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=packed[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\npackedKeys=new Float64Array(groups);\nfor(const[key,id]of seen)packedKeys[id]=key;\n}else{\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=strings[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\n}\nconst buckets=scatterBuckets(idx,ids,n,groups);\nconst keys=new Array(groups);\nfor(let g=0;g<groups;g++){\nconst row=buckets[g][0];\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\nkeys[g]=tuple;\n}\nconst result={keys,buckets};\nif(packedKeys)result.packed=packedKeys;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/facet.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return STRATEGIES;}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return GRANULARITIES;}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return DEFAULT_BUCKETS;}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return DEFAULT_CARDINALITY_LIMIT;}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return QUANTILE_SAMPLE;}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return facetKind;}});\nObject.defineProperty(__exports,\"orderedReader\",{enumerable:true,get:function(){return orderedReader;}});\nObject.defineProperty(__exports,\"toNumeric\",{enumerable:true,get:function(){return toNumeric;}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return cardinalityOf;}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return pickGranularity;}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return floorTo;}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return advance;}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return computeBounds;}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return countInto;}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return bucketOf;}});\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return facet;}});\nObject.defineProperty(__exports,\"default\",{enumerable:true,get:function(){return __default;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst dictSize=__m0[\"dictSize\"];\nconst dictValue=__m0[\"dictValue\"];\nconst STRATEGIES=Object.freeze(['equal','quantile','log']);\nconst GRANULARITIES=Object.freeze(['hour','day','week','month','quarter','year']);\nconst DEFAULT_BUCKETS=20;\nconst DEFAULT_CARDINALITY_LIMIT=50;\nconst QUANTILE_SAMPLE=10_000;\nfunction facetKind(handle,type){\nif(!handle)return'none';\nconst base=type&&type.base;\nif(base==='date'||base==='datetime'||base==='time'||base==='dateString')return'date';\nswitch(handle.kind){\ncase'bitset':return'boolean';\ncase'float64':case'int32':return'numeric';\ncase'dictionary':return'category';\ncase'multi':return'category';\ndefault:\nif(base==='number')return'numeric';\nif(base==='boolean')return'boolean';\nif(base==='text')return'category';\nreturn'none';\n}\n}\nfunction orderedReader(handle){\nconst values=handle.values;\nconst kind=handle.kind;\nif((kind==='float64'||kind==='int32')&&values)return(i)=>values[i];\nconst read=valueReader(handle);\nreturn(i)=>toNumeric(read(i));\n}\nfunction toNumeric(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(v===null||v===undefined||v==='')return NaN;\nif(typeof v==='boolean')return v?1:0;\nif(typeof v==='string'){\nconst n=Number(v);\nif(Number.isFinite(n))return n;\nconst t=Date.parse(v);\nreturn Number.isFinite(t)?t:NaN;\n}\nreturn NaN;\n}\nfunction cardinalityOf(handle,indices,count,limit=DEFAULT_CARDINALITY_LIMIT){\nif(!handle)return{cardinality:0,exact:true};\nif(handle.dict)return{cardinality:dictSize(handle.dict),exact:true};\nif(handle.kind==='bitset')return{cardinality:2,exact:true};\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst seen=new Set();\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined)continue;\nseen.add(v);\nif(seen.size>limit)return{cardinality:seen.size,exact:false};\n}\nreturn{cardinality:seen.size,exact:true};\n}\nconst HOUR_MS=3600_000;\nconst DAY_MS=86_400_000;\nfunction pickGranularity(span,target=DEFAULT_BUCKETS){\nconst ms=Number.isFinite(span)&&span>0?span:0;\nconst wide=Math.max(1,target)*2;\nif(ms/HOUR_MS<=wide)return'hour';\nif(ms/DAY_MS<=wide)return'day';\nif(ms/(7*DAY_MS)<=wide)return'week';\nif(ms/(30*DAY_MS)<=wide)return'month';\nif(ms/(91*DAY_MS)<=wide)return'quarter';\nreturn'year';\n}\nfunction floorTo(ms,granularity){\nif(!Number.isFinite(ms))return NaN;\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setMinutes(0,0,0);return d.getTime();\ncase'day':d.setHours(0,0,0,0);return d.getTime();\ncase'week':{\nd.setHours(0,0,0,0);\nconst back=(d.getDay()+6)%7;\nd.setDate(d.getDate()-back);\nreturn d.getTime();\n}\ncase'month':d.setDate(1);d.setHours(0,0,0,0);return d.getTime();\ncase'quarter':\nd.setMonth(Math.floor(d.getMonth()/3)*3,1);\nd.setHours(0,0,0,0);\nreturn d.getTime();\ndefault:d.setMonth(0,1);d.setHours(0,0,0,0);return d.getTime();\n}\n}\nfunction advance(ms,granularity){\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setHours(d.getHours()+1);break;\ncase'day':d.setDate(d.getDate()+1);break;\ncase'week':d.setDate(d.getDate()+7);break;\ncase'month':d.setMonth(d.getMonth()+1);break;\ncase'quarter':d.setMonth(d.getMonth()+3);break;\ndefault:d.setFullYear(d.getFullYear()+1);break;\n}\nreturn d.getTime();\n}\nfunction numericExtent(handle,indices,count){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nlet min=Infinity;\nlet max=-Infinity;\nlet nulls=0;\nlet finite=0;\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){nulls++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){nulls++;continue;}\nif(v<min)min=v;\nif(v>max)max=v;\nfinite++;\n}\nreturn{min,max,nulls,finite};\n}\nfunction sortedSample(handle,indices,count,cap){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nconst step=n>cap?n/cap:1;\nconst out=[];\nfor(let s=0;s<n;s+=step){\nconst i=indices?indices[Math.floor(s)]:Math.floor(s);\nif(present&&!present(i))continue;\nconst v=read(i);\nif(Number.isFinite(v))out.push(v);\n}\nconst arr=Float64Array.from(out);\narr.sort();\nreturn arr;\n}\nfunction computeBounds(handle,indices,count,opts={}){\nconst kind=opts.kind||facetKind(handle,opts.type);\nif(kind==='none'||!handle)return{kind:'none',buckets:[],suppressed:'type'};\nif(kind==='boolean')return boundsForBoolean(handle,indices,count);\nif(kind==='category')return boundsForCategory(handle,indices,count,opts);\nreturn boundsForOrdered(handle,indices,count,kind,opts);\n}\nfunction boundsForBoolean(handle,indices,count){\nconst present=presenceReader(handle);\nlet nulls=0;\nif(present){\nconst n=indices?indices.length:count;\nfor(let k=0;k<n;k++)if(!present(indices?indices[k]:k))nulls++;\n}\nconst buckets=[{value:false,label:'false'},{value:true,label:'true'}];\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'boolean',buckets};\n}\nfunction boundsForCategory(handle,indices,count,opts){\nconst limit=opts.cardinalityLimit??DEFAULT_CARDINALITY_LIMIT;\nconst{cardinality}=cardinalityOf(handle,indices,count,limit);\nif(cardinality>limit&&(opts.aboveLimit||'suppress')==='suppress'){\nreturn{kind:'category',buckets:[],suppressed:'cardinality',cardinality};\n}\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst tally=new Map();\nlet nulls=0;\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){nulls++;continue;}\nif(Array.isArray(v)){\nif(!v.length){nulls++;continue;}\nfor(const m of v)tally.set(m,(tally.get(m)||0)+1);\ncontinue;\n}\ntally.set(v,(tally.get(v)||0)+1);\n}\nlet entries=[...tally.entries()];\nif(opts.order==='alpha'){\nentries.sort((a,b)=>String(a[0]).localeCompare(String(b[0])));\n}else{\nentries.sort((a,b)=>b[1]-a[1]);\n}\nlet remainder=0;\nlet dropped=0;\nif(entries.length>limit){\ndropped=entries.length-limit;\nfor(let i=limit;i<entries.length;i++)remainder+=entries[i][1];\nentries=entries.slice(0,limit);\n}\nconst buckets=entries.map(([value])=>({value,label:String(value)}));\nif(remainder>0)buckets.push({remainder:true,label:`Other (${dropped} values)`});\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'category',buckets,cardinality};\n}\nfunction boundsForOrdered(handle,indices,count,kind,opts){\nconst{min,max,nulls,finite}=numericExtent(handle,indices,count);\nif(!finite){\nreturn{kind,buckets:nulls?[{null:true,label:'Empty'}]:[],empty:true};\n}\nconst wanted=Math.max(1,Math.floor(opts.buckets||DEFAULT_BUCKETS));\nlet buckets=[];\nif(kind==='date'){\nconst granularity=GRANULARITIES.includes(opts.granularity)\n?opts.granularity:pickGranularity(max-min,wanted);\nlet edge=floorTo(min,granularity);\nwhile(edge<=max&&buckets.length<4096){\nconst next=advance(edge,granularity);\nif(!(next>edge))break;\nbuckets.push({from:edge,to:next});\nedge=next;\n}\nreturn{kind,buckets:withNull(buckets,nulls),granularity};\n}\nconst strategy=STRATEGIES.includes(opts.strategy)?opts.strategy:'equal';\nif(strategy==='quantile'){\nconst sample=sortedSample(handle,indices,count,QUANTILE_SAMPLE);\nif(sample.length){\nconst edges=[sample[0]];\nfor(let b=1;b<wanted;b++){\nconst v=sample[Math.min(sample.length-1,Math.floor((b/wanted)*sample.length))];\nif(v>edges[edges.length-1])edges.push(v);\n}\nedges.push(max);\nfor(let b=0;b<edges.length-1;b++)buckets.push({from:edges[b],to:edges[b+1]});\n}\n}else if(strategy==='log'&&min>0){\nconst lo=Math.log10(min);\nconst hi=Math.log10(max);\nconst step=(hi-lo)/wanted||1;\nfor(let b=0;b<wanted;b++){\nbuckets.push({from:10**(lo+b*step),to:10**(lo+(b+1)*step)});\n}\n}\nif(!buckets.length){\nconst width=(max-min)/wanted||1;\nfor(let b=0;b<wanted;b++)buckets.push({from:min+b*width,to:min+(b+1)*width});\n}\nbuckets[buckets.length-1].to=max;\nreturn{kind,buckets:withNull(buckets,nulls),strategy,min,max};\n}\nfunction withNull(buckets,nulls){\nreturn nulls>0?[...buckets,{null:true,label:'Empty'}]:buckets;\n}\nfunction countInto(handle,indices,count,bounds,out){\nconst buckets=(bounds&&bounds.buckets)||[];\nconst counts=out&&out.length>=buckets.length?out.subarray(0,buckets.length)\n:new Uint32Array(buckets.length);\ncounts.fill(0);\nif(!handle||!buckets.length)return counts;\nconst nullBucket=buckets.length-1;\nconst hasNull=!!buckets[nullBucket]&&buckets[nullBucket].null===true;\nconst n=indices?indices.length:count;\nif(bounds.kind==='boolean'){\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined){if(hasNull)counts[nullBucket]++;continue;}\ncounts[v?1:0]++;\n}\nreturn counts;\n}\nif(bounds.kind==='category'){\nconst slot=new Map();\nfor(let b=0;b<buckets.length;b++){\nif(!buckets[b].null&&!buckets[b].remainder)slot.set(buckets[b].value,b);\n}\nconst remainderAt=buckets.findIndex((b)=>b.remainder);\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){if(hasNull)counts[nullBucket]++;continue;}\nif(Array.isArray(v)){\nif(!v.length){if(hasNull)counts[nullBucket]++;continue;}\nfor(const m of v){\nconst at=slot.get(m);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\ncontinue;\n}\nconst at=slot.get(v);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\nreturn counts;\n}\nconst ordered=hasNull?buckets.length-1:buckets.length;\nconst edges=new Float64Array(ordered+1);\nfor(let b=0;b<ordered;b++)edges[b]=buckets[b].from;\nedges[ordered]=ordered?buckets[ordered-1].to:0;\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){if(hasNull)counts[nullBucket]++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){if(hasNull)counts[nullBucket]++;continue;}\nconst at=bucketOf(edges,ordered,v);\nif(at>=0)counts[at]++;\n}\nreturn counts;\n}\nfunction bucketOf(edges,ordered,v){\nif(!ordered)return-1;\nif(v<edges[0])return-1;\nif(v>=edges[ordered])return v===edges[ordered]?ordered-1:-1;\nlet lo=0;\nlet hi=ordered-1;\nwhile(lo<hi){\nconst mid=(lo+hi+1)>>>1;\nif(v>=edges[mid])lo=mid;else hi=mid-1;\n}\nreturn lo;\n}\nfunction facet(handle,indices,count,opts={}){\nconst bounds=opts.bounds||computeBounds(handle,opts.boundsIndices??indices,count,opts);\nreturn{bounds,counts:countInto(handle,indices,count,bounds)};\n}\nconst __default=facet;\n});\n__def(\"packages/core/src/compute/special.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"logGamma\",{enumerable:true,get:function(){return logGamma;}});\nObject.defineProperty(__exports,\"incompleteBeta\",{enumerable:true,get:function(){return incompleteBeta;}});\nObject.defineProperty(__exports,\"normalQuantile\",{enumerable:true,get:function(){return normalQuantile;}});\nObject.defineProperty(__exports,\"studentT\",{enumerable:true,get:function(){return studentT;}});\nObject.defineProperty(__exports,\"studentTQuantile\",{enumerable:true,get:function(){return studentTQuantile;}});\nconst LANCZOS=Object.freeze([\n676.5203681218851,-1259.1392167224028,771.32342877765313,\n-176.61502916214059,12.507343278686905,-0.13857109526572012,\n9.9843695780195716e-6,1.5056327351493116e-7,\n]);\nconst EPS=3e-12;\nconst TINY=1e-300;\nfunction logGamma(x){\nif(x<0.5)return Math.log(Math.PI/Math.sin(Math.PI*x))-logGamma(1-x);\nconst z=x-1;\nlet a=0.99999999999980993;\nconst t=z+7.5;\nfor(let i=0;i<LANCZOS.length;i++)a+=LANCZOS[i]/(z+i+1);\nreturn 0.5*Math.log(2*Math.PI)+(z+0.5)*Math.log(t)-t+Math.log(a);\n}\nfunction betaContinuedFraction(a,b,x){\nconst qab=a+b;\nconst qap=a+1;\nconst qam=a-1;\nlet c=1;\nlet d=1-(qab*x)/qap;\nif(Math.abs(d)<TINY)d=TINY;\nd=1/d;\nlet h=d;\nfor(let m=1;m<=300;m++){\nconst m2=2*m;\nlet aa=(m*(b-m)*x)/((qam+m2)*(a+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nh*=d*c;\naa=(-(a+m)*(qab+m)*x)/((a+m2)*(qap+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nconst step=d*c;\nh*=step;\nif(Math.abs(step-1)<EPS)break;\n}\nreturn h;\n}\nfunction incompleteBeta(a,b,x){\nif(!(a>0)||!(b>0)||!Number.isFinite(x))return Number.NaN;\nif(x<=0)return 0;\nif(x>=1)return 1;\nconst front=Math.exp(\nlogGamma(a+b)-logGamma(a)-logGamma(b)+a*Math.log(x)+b*Math.log(1-x),\n);\nreturn x<(a+1)/(a+b+2)\n?(front*betaContinuedFraction(a,b,x))/a\n:1-(front*betaContinuedFraction(b,a,1-x))/b;\n}\nfunction normalQuantile(p){\nif(!(p>0)||!(p<1))return p===0?-Infinity:(p===1?Infinity:Number.NaN);\nconst a=[-3.969683028665376e+1,2.209460984245205e+2,-2.759285104469687e+2,\n1.383577518672690e+2,-3.066479806614716e+1,2.506628277459239];\nconst b=[-5.447609879822406e+1,1.615858368580409e+2,-1.556989798598866e+2,\n6.680131188771972e+1,-1.328068155288572e+1];\nconst c=[-7.784894002430293e-3,-3.223964580411365e-1,-2.400758277161838,\n-2.549732539343734,4.374664141464968,2.938163982698783];\nconst d=[7.784695709041462e-3,3.224671290700398e-1,2.445134137142996,\n3.754408661907416];\nconst low=0.02425;\nlet q;\nlet r;\nlet x;\nif(p<low){\nq=Math.sqrt(-2*Math.log(p));\nx=(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}else if(p<=1-low){\nq=p-0.5;\nr=q*q;\nx=((((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q)\n/ (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);\n}else{\nq=Math.sqrt(-2*Math.log(1-p));\nx=-(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}\nconst e=0.5*erfc(-x/Math.SQRT2)-p;\nconst u=e*Math.sqrt(2*Math.PI)*Math.exp((x*x)/2);\nreturn x-u/(1+(x*u)/2);\n}\nfunction erfc(x){\nconst z=Math.abs(x);\nconst t=2/(2+z);\nconst ty=4*t-2;\nconst cof=[-1.3026537197817094,6.4196979235649026e-1,1.9476473204185836e-2,\n-9.561514786808631e-3,-9.46595344482036e-4,3.66839497852761e-4,\n4.2523324806907e-5,-2.0278578112534e-5,-1.624290004647e-6,\n1.303655835580e-6,1.5626441722e-8,-8.5238095915e-8,6.529054439e-9,\n5.059343495e-9,-9.91364156e-10,-2.27365122e-10,9.6467911e-11,\n2.394038e-12,-6.886027e-12,8.94487e-13,3.13092e-13,-1.12708e-13,\n3.81e-16,7.106e-15];\nlet dd=0;\nlet dv=0;\nlet tmp;\nfor(let j=cof.length-1;j>0;j--){\ntmp=dv;\ndv=ty*dv-dd+cof[j];\ndd=tmp;\n}\nconst ans=t*Math.exp(-z*z+0.5*(cof[0]+ty*dv)-dd);\nreturn x>=0?ans:2-ans;\n}\nfunction studentT(t,df){\nif(!(df>0)||!Number.isFinite(t))return Number.NaN;\nconst tail=0.5*incompleteBeta(df/2,0.5,df/(df+t*t));\nreturn t>0?1-tail:tail;\n}\nfunction studentTQuantile(p,df){\nif(!(p>0)||!(p<1)||!(df>0))return Number.NaN;\nif(df>1e7)return normalQuantile(p);\nlet lo=-1e4;\nlet hi=1e4;\nlet x=normalQuantile(p);\nconst logBeta=logGamma(df/2)+logGamma(0.5)-logGamma((df+1)/2);\nfor(let i=0;i<60;i++){\nconst cdf=studentT(x,df);\nif(cdf<p)lo=x;else hi=x;\nconst pdf=Math.exp(-((df+1)/2)*Math.log(1+(x*x)/df)-logBeta)\n/ Math.sqrt(df);\nconst step=pdf>0?(cdf-p)/pdf:0;\nif(Math.abs(step)<1e-12)break;\nconst next=x-step;\nx=next>lo&&next<hi&&Number.isFinite(next)?next:(lo+hi)/2;\nif(hi-lo<1e-12)break;\n}\nreturn x;\n}\n});\n__def(\"packages/core/src/compute/statistics.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KENDALL_LIMIT\",{enumerable:true,get:function(){return KENDALL_LIMIT;}});\nObject.defineProperty(__exports,\"MAINTENANCE\",{enumerable:true,get:function(){return MAINTENANCE;}});\nObject.defineProperty(__exports,\"numbers\",{enumerable:true,get:function(){return numbers;}});\nObject.defineProperty(__exports,\"frequencies\",{enumerable:true,get:function(){return frequencies;}});\nObject.defineProperty(__exports,\"herfindahl\",{enumerable:true,get:function(){return herfindahl;}});\nObject.defineProperty(__exports,\"entropy\",{enumerable:true,get:function(){return entropy;}});\nObject.defineProperty(__exports,\"evenness\",{enumerable:true,get:function(){return evenness;}});\nObject.defineProperty(__exports,\"topShare\",{enumerable:true,get:function(){return topShare;}});\nObject.defineProperty(__exports,\"gini\",{enumerable:true,get:function(){return gini;}});\nObject.defineProperty(__exports,\"moments\",{enumerable:true,get:function(){return moments;}});\nObject.defineProperty(__exports,\"quantileSorted\",{enumerable:true,get:function(){return quantileSorted;}});\nObject.defineProperty(__exports,\"quantile\",{enumerable:true,get:function(){return quantile;}});\nObject.defineProperty(__exports,\"STAT_FNS\",{enumerable:true,get:function(){return STAT_FNS;}});\nObject.defineProperty(__exports,\"STAT_LABELS\",{enumerable:true,get:function(){return STAT_LABELS;}});\nObject.defineProperty(__exports,\"weightedAverage\",{enumerable:true,get:function(){return weightedAverage;}});\nObject.defineProperty(__exports,\"extremeRow\",{enumerable:true,get:function(){return extremeRow;}});\nObject.defineProperty(__exports,\"correlation\",{enumerable:true,get:function(){return correlation;}});\nObject.defineProperty(__exports,\"trimmedMean\",{enumerable:true,get:function(){return trimmedMean;}});\nObject.defineProperty(__exports,\"winsorizedMean\",{enumerable:true,get:function(){return winsorizedMean;}});\nObject.defineProperty(__exports,\"modifiedZOutliers\",{enumerable:true,get:function(){return modifiedZOutliers;}});\nObject.defineProperty(__exports,\"jarqueBera\",{enumerable:true,get:function(){return jarqueBera;}});\nObject.defineProperty(__exports,\"weightedQuantile\",{enumerable:true,get:function(){return weightedQuantile;}});\nObject.defineProperty(__exports,\"pairs\",{enumerable:true,get:function(){return pairs;}});\nObject.defineProperty(__exports,\"covariance\",{enumerable:true,get:function(){return covariance;}});\nObject.defineProperty(__exports,\"regression\",{enumerable:true,get:function(){return regression;}});\nObject.defineProperty(__exports,\"spearman\",{enumerable:true,get:function(){return spearman;}});\nObject.defineProperty(__exports,\"kendall\",{enumerable:true,get:function(){return kendall;}});\nObject.defineProperty(__exports,\"seriesStats\",{enumerable:true,get:function(){return seriesStats;}});\nObject.defineProperty(__exports,\"D2_N2\",{enumerable:true,get:function(){return D2_N2;}});\nObject.defineProperty(__exports,\"D4_N2\",{enumerable:true,get:function(){return D4_N2;}});\nObject.defineProperty(__exports,\"movingRanges\",{enumerable:true,get:function(){return movingRanges;}});\nObject.defineProperty(__exports,\"withinSigma\",{enumerable:true,get:function(){return withinSigma;}});\nObject.defineProperty(__exports,\"capability\",{enumerable:true,get:function(){return capability;}});\nObject.defineProperty(__exports,\"controlLimits\",{enumerable:true,get:function(){return controlLimits;}});\nObject.defineProperty(__exports,\"westernElectricViolations\",{enumerable:true,get:function(){return westernElectricViolations;}});\nObject.defineProperty(__exports,\"nelsonViolations\",{enumerable:true,get:function(){return nelsonViolations;}});\nObject.defineProperty(__exports,\"CONTROL_RULE_SETS\",{enumerable:true,get:function(){return CONTROL_RULE_SETS;}});\nObject.defineProperty(__exports,\"controlViolations\",{enumerable:true,get:function(){return controlViolations;}});\nObject.defineProperty(__exports,\"countOutside\",{enumerable:true,get:function(){return countOutside;}});\nObject.defineProperty(__exports,\"histogram\",{enumerable:true,get:function(){return histogram;}});\nObject.defineProperty(__exports,\"DEFAULT_CONFIDENCE\",{enumerable:true,get:function(){return DEFAULT_CONFIDENCE;}});\nObject.defineProperty(__exports,\"meanInterval\",{enumerable:true,get:function(){return meanInterval;}});\nObject.defineProperty(__exports,\"proportionInterval\",{enumerable:true,get:function(){return proportionInterval;}});\nObject.defineProperty(__exports,\"slopeInterval\",{enumerable:true,get:function(){return slopeInterval;}});\nObject.defineProperty(__exports,\"capabilityInterval\",{enumerable:true,get:function(){return capabilityInterval;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst __m1=__req(\"packages/core/src/compute/special.js\");\nconst studentTQuantile=__m1[\"studentTQuantile\"];\nconst normalQuantile=__m1[\"normalQuantile\"];\nconst KENDALL_LIMIT=5000;\nconst MAINTENANCE=Object.freeze({\nvariance:'rescan',\nvarianceP:'rescan',\nstddev:'rescan',\nstddevP:'rescan',\nsumSquares:'rescan',\nweightedAvg:'maintained',\nmedian:'rescan',\np25:'rescan',\np75:'rescan',\np90:'rescan',\np95:'rescan',\np99:'rescan',\niqr:'rescan',\nmode:'rescan',\ndistinct:'rescan',\nrange:'rescan',\nskewness:'rescan',\nkurtosis:'rescan',\ngeomean:'rescan',\nharmean:'rescan',\nmad:'rescan',\nargmin:'rescan',\nargmax:'rescan',\nhhi:'rescan',\nentropy:'rescan',\nevenness:'rescan',\ntop3Share:'rescan',\ntop10Share:'rescan',\ngini:'rescan',\ntrimmedMean:'rescan',\nwinsorizedMean:'rescan',\nrobustOutliers:'rescan',\njarqueBera:'rescan',\n});\nfunction numbers(handle,indices){\nconst n=indices.length;\nconst out=new Float64Array(n);\nlet count=0;\nconst numeric=handle&&(handle.kind==='float64'||handle.kind==='int32');\nif(numeric){\nconst values=handle.values;\nconst present=presenceReader(handle);\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present&&present(row)!==1)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nconst v=typeof raw==='number'?raw:Number(raw);\nif(!Number.isFinite(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nfunction frequencies(handle,indices){\nconst seen=new Map();\nconst read=valueReader(handle);\nlet total=0;\nfor(let i=0;i<indices.length;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nif(typeof raw==='number'&&Number.isNaN(raw))continue;\nconst key=typeof raw==='object'?String(raw):raw;\nseen.set(key,(seen.get(key)||0)+1);\ntotal++;\n}\nconst counts=[...seen.values()].sort((a,b)=>b-a);\nreturn{counts,total,distinct:counts.length};\n}\nfunction sharesOf(freq){\nreturn freq.total>0?freq.counts.map((c)=>c/freq.total):[];\n}\nfunction herfindahl(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))sum+=share*share;\nreturn sum;\n}\nfunction entropy(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum;\n}\nfunction evenness(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total||freq.distinct<2)return freq.total?1:null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum/Math.log2(freq.distinct);\n}\nfunction topShare(handle,indices,n=3){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nconst take=Math.max(1,Math.floor(n));\nlet held=0;\nfor(let i=0;i<Math.min(take,freq.counts.length);i++)held+=freq.counts[i];\nreturn held/freq.total;\n}\nfunction gini(handle,indices){\nconst values=numbers(handle,indices);\nconst n=values.length;\nif(!n)return null;\nconst sorted=values.slice().sort();\nif(sorted[0]<0)return null;\nlet total=0;\nlet weighted=0;\nfor(let i=0;i<n;i++){\ntotal+=sorted[i];\nweighted+=(i+1)*sorted[i];\n}\nif(total===0)return 0;\nreturn(2*weighted)/(n*total)-(n+1)/n;\n}\nfunction moments(values){\nlet n=0;\nlet mean=0;\nlet m2=0;\nfor(let i=0;i<values.length;i++){\nconst x=values[i];\nn++;\nconst delta=x-mean;\nmean+=delta/n;\nm2+=delta*(x-mean);\n}\nreturn{n,mean,m2};\n}\nfunction quantileSorted(sorted,p){\nconst n=sorted.length;\nif(!n)return NaN;\nif(n===1)return sorted[0];\nconst h=(n-1)*Math.min(1,Math.max(0,p));\nconst lo=Math.floor(h);\nconst hi=Math.ceil(h);\nif(lo===hi)return sorted[lo];\nreturn sorted[lo]+(h-lo)*(sorted[hi]-sorted[lo]);\n}\nfunction quantile(values,p){\nif(!values.length)return NaN;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,p);\n}\nconst STAT_FNS=Object.freeze({\nhhi:(h,i)=>herfindahl(h,i),\nentropy:(h,i)=>entropy(h,i),\nevenness:(h,i)=>evenness(h,i),\ntop3Share:(h,i)=>topShare(h,i,3),\ntop10Share:(h,i)=>topShare(h,i,10),\ngini:(h,i)=>gini(h,i),\ntrimmedMean:(h,i)=>trimmedMean(numbers(h,i),0.1),\nwinsorizedMean:(h,i)=>winsorizedMean(numbers(h,i),0.1),\nrobustOutliers:(h,i)=>modifiedZOutliers(numbers(h,i),3.5),\njarqueBera:(h,i)=>jarqueBera(numbers(h,i)),\nvariance:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?m2/(n-1):null;\n},\nvarianceP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?m2/n:null;\n},\nstddev:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?Math.sqrt(m2/(n-1)):null;\n},\nstddevP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?Math.sqrt(m2/n):null;\n},\nmedian:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.5):null;\n},\np25:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.25):null;\n},\np75:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.75):null;\n},\np90:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.9):null;\n},\np95:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.95):null;\n},\np99:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.99):null;\n},\niqr:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,0.75)-quantileSorted(sorted,0.25);\n},\nmad:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst middle=quantile(values,0.5);\nconst deviations=new Float64Array(values.length);\nfor(let k=0;k<values.length;k++)deviations[k]=Math.abs(values[k]-middle);\nreturn quantile(deviations,0.5);\n},\nrange:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet lo=Infinity;\nlet hi=-Infinity;\nfor(let k=0;k<values.length;k++){\nif(values[k]<lo)lo=values[k];\nif(values[k]>hi)hi=values[k];\n}\nreturn hi-lo;\n},\ndistinct:(h,i)=>{\nconst read=valueReader(h);\nconst seen=new Set();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nseen.add(v instanceof Date?v.getTime():v);\n}\nreturn seen.size;\n},\nmode:(h,i)=>{\nconst read=valueReader(h);\nconst counts=new Map();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nconst id=v instanceof Date?v.getTime():v;\ncounts.set(id,(counts.get(id)||0)+1);\n}\nlet best=null;\nlet most=1;\nfor(const[value,times]of counts){\nif(times>most){\nmost=times;\nbest=value;\n}\n}\nreturn best;\n},\nskewness:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<3||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**3;\nreturn(n/((n-1)*(n-2)))*sum;\n},\nkurtosis:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<4||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**4;\nconst a=(n*(n+1))/((n-1)*(n-2)*(n-3));\nconst b=(3*(n-1)**2)/((n-2)*(n-3));\nreturn a*sum-b;\n},\ngeomean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]<=0)return null;\nsum+=Math.log(values[k]);\n}\nreturn Math.exp(sum/values.length);\n},\nharmean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]===0)return null;\nsum+=1/values[k];\n}\nreturn values.length/sum;\n},\nsumSquares:(h,i)=>{\nconst values=numbers(h,i);\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=values[k]*values[k];\nreturn sum;\n},\n});\nconst STAT_LABELS=Object.freeze({\nhhi:'Concentration (HHI)',\nentropy:'Entropy',\nevenness:'Evenness',\ntop3Share:'Top 3 share',\ntop10Share:'Top 10 share',\ngini:'Gini coefficient',\ntrimmedMean:'Trimmed mean',\nwinsorizedMean:'Winsorized mean',\nrobustOutliers:'Outliers (robust)',\njarqueBera:'Jarque–Bera',\nmedian:'Median',\np25:'25th percentile',\np75:'75th percentile',\np90:'90th percentile',\np95:'95th percentile',\np99:'99th percentile',\niqr:'Interquartile range',\nmad:'Median absolute deviation',\nvariance:'Variance',\nvarianceP:'Variance (population)',\nstddev:'Standard deviation',\nstddevP:'Standard deviation (population)',\nrange:'Range',\ndistinct:'Distinct',\nmode:'Mode',\nskewness:'Skewness',\nkurtosis:'Kurtosis',\ngeomean:'Geometric mean',\nharmean:'Harmonic mean',\nsumSquares:'Sum of squares',\nweightedAvg:'Weighted average',\nargmin:'Lowest by',\nargmax:'Highest by',\n});\nfunction weightedAverage(handle,weights,indices){\nconst readValue=valueReader(handle);\nconst readWeight=valueReader(weights);\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(readValue(row));\nconst weight=Number(readWeight(row));\nif(!Number.isFinite(value)||!Number.isFinite(weight))continue;\ntop+=value*weight;\nbottom+=weight;\n}\nreturn bottom===0?null:top/bottom;\n}\nfunction extremeRow(handle,indices,largest){\nconst read=valueReader(handle);\nlet best=null;\nlet bestValue=largest?-Infinity:Infinity;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(read(row));\nif(!Number.isFinite(value))continue;\nif(largest?value>bestValue:value<bestValue){\nbestValue=value;\nbest=row;\n}\n}\nreturn best;\n}\nfunction correlation(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nlet n=0;\nlet sx=0;\nlet sy=0;\nlet sxx=0;\nlet syy=0;\nlet sxy=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nn++;\nsx+=x;\nsy+=y;\nsxx+=x*x;\nsyy+=y*y;\nsxy+=x*y;\n}\nif(n<2)return null;\nconst top=n*sxy-sx*sy;\nconst bottom=Math.sqrt((n*sxx-sx*sx)*(n*syy-sy*sy));\nif(bottom===0)return null;\nconst r=top/bottom;\nreturn Math.max(-1,Math.min(1,r));\n}\nfunction trimmedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst kept=sorted.slice(cut,n-cut);\nif(!kept.length)return quantileSorted(sorted,0.5);\nlet sum=0;\nfor(const v of kept)sum+=v;\nreturn sum/kept.length;\n}\nfunction winsorizedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst low=sorted[cut];\nconst high=sorted[n-1-cut];\nlet sum=0;\nfor(const v of sorted)sum+=Math.min(high,Math.max(low,v));\nreturn sum/n;\n}\nfunction modifiedZOutliers(values,threshold=3.5){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst middle=quantileSorted(sorted,0.5);\nconst deviations=sorted.map((v)=>Math.abs(v-middle)).sort((a,b)=>a-b);\nconst mad=quantileSorted(deviations,0.5);\nif(mad===0)return null;\nlet count=0;\nfor(const v of sorted)if(Math.abs((0.6745*(v-middle))/mad)>threshold)count++;\nreturn count;\n}\nfunction jarqueBera(values){\nconst n=values.length;\nif(n<8)return null;\nlet mean=0;\nfor(const v of values)mean+=v;\nmean/=n;\nlet m2=0;\nlet m3=0;\nlet m4=0;\nfor(const v of values){\nconst d=v-mean;\nm2+=d*d;\nm3+=d*d*d;\nm4+=d*d*d*d;\n}\nm2/=n;\nm3/=n;\nm4/=n;\nif(m2===0)return null;\nconst skew=m3/m2**1.5;\nconst excess=m4/(m2*m2)-3;\nreturn(n/6)*(skew*skew+(excess*excess)/4);\n}\nfunction weightedQuantile(values,weights,p){\nconst paired=[];\nlet total=0;\nfor(let i=0;i<values.length;i++){\nconst v=Number(values[i]);\nconst w=Number(weights[i]);\nif(!Number.isFinite(v)||!Number.isFinite(w)||w<=0)continue;\npaired.push([v,w]);\ntotal+=w;\n}\nif(!paired.length||total<=0)return null;\npaired.sort((a,b)=>a[0]-b[0]);\nif(paired.length===1)return paired[0][0];\nconst at=[];\nlet seen=0;\nfor(const[,w]of paired){\nat.push((seen+w/2)/total);\nseen+=w;\n}\nconst target=Math.max(0,Math.min(1,p));\nif(target<=at[0])return paired[0][0];\nif(target>=at[at.length-1])return paired[paired.length-1][0];\nfor(let i=1;i<at.length;i++){\nif(target>at[i])continue;\nconst span=at[i]-at[i-1];\nconst within=span>0?(target-at[i-1])/span:0;\nreturn paired[i-1][0]+(paired[i][0]-paired[i-1][0])*within;\n}\nreturn paired[paired.length-1][0];\n}\nfunction pairs(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nconst xs=new Float64Array(indices.length);\nconst ys=new Float64Array(indices.length);\nlet n=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nxs[n]=x;\nys[n]=y;\nn++;\n}\nreturn{xs:xs.subarray(0,n),ys:ys.subarray(0,n),n};\n}\nfunction covariance(a,b,indices,population=false){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=(xs[i]-mx)*(ys[i]-my);\nreturn sum/(population?n:n-1);\n}\nfunction regression(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sxx=0;\nlet sxy=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=xs[i]-mx;\nconst dy=ys[i]-my;\nsxx+=dx*dx;\nsxy+=dx*dy;\nsyy+=dy*dy;\n}\nif(sxx===0)return null;\nconst slope=sxy/sxx;\nconst intercept=my-slope*mx;\nconst r2=syy===0?1:Math.max(0,Math.min(1,(sxy*sxy)/(sxx*syy)));\nconst residual=Math.max(0,syy-slope*sxy);\nconst stdError=n>2?Math.sqrt(residual/(n-2)/sxx):0;\nreturn{slope,intercept,r2,stdError,n};\n}\nfunction ranksOf(values){\nconst n=values.length;\nconst order=Array.from({length:n},(unused,i)=>i)\n.sort((i,j)=>values[i]-values[j]);\nconst ranks=new Float64Array(n);\nlet i=0;\nwhile(i<n){\nlet j=i;\nwhile(j+1<n&&values[order[j+1]]===values[order[i]])j++;\nconst shared=(i+j)/2+1;\nfor(let k=i;k<=j;k++)ranks[order[k]]=shared;\ni=j+1;\n}\nreturn ranks;\n}\nfunction spearman(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nconst rx=ranksOf(xs);\nconst ry=ranksOf(ys);\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=rx[i];my+=ry[i];}\nmx/=n;\nmy/=n;\nlet sxy=0;\nlet sxx=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=rx[i]-mx;\nconst dy=ry[i]-my;\nsxy+=dx*dy;\nsxx+=dx*dx;\nsyy+=dy*dy;\n}\nif(sxx===0||syy===0)return null;\nreturn Math.max(-1,Math.min(1,sxy/Math.sqrt(sxx*syy)));\n}\nfunction kendall(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2||n>KENDALL_LIMIT)return null;\nlet concordant=0;\nlet discordant=0;\nlet tiedXOnly=0;\nlet tiedYOnly=0;\nfor(let i=0;i<n;i++){\nfor(let j=i+1;j<n;j++){\nconst dx=Math.sign(xs[i]-xs[j]);\nconst dy=Math.sign(ys[i]-ys[j]);\nconst product=dx*dy;\nif(product>0)concordant++;\nelse if(product<0)discordant++;\nelse if(dx===0&&dy===0){}\nelse if(dx===0)tiedXOnly++;\nelse tiedYOnly++;\n}\n}\nconst orderedByX=concordant+discordant+tiedYOnly;\nconst orderedByY=concordant+discordant+tiedXOnly;\nif(orderedByX===0||orderedByY===0)return null;\nreturn(concordant-discordant)/Math.sqrt(orderedByX*orderedByY);\n}\nfunction seriesStats(ordered,opts={}){\nconst n=ordered.length;\nif(n<2)return null;\nconst first=ordered[0];\nconst last=ordered[n-1];\nconst returns=[];\nfor(let i=1;i<n;i++){\nconst previous=ordered[i-1];\nif(previous===0)continue;\nreturns.push((ordered[i]-previous)/Math.abs(previous));\n}\nlet volatility=null;\nif(returns.length>1){\nlet mean=0;\nfor(const r of returns)mean+=r;\nmean/=returns.length;\nlet m2=0;\nfor(const r of returns)m2+=(r-mean)**2;\nvolatility=Math.sqrt(m2/(returns.length-1));\n}\nconst periods=Number(opts.periodsPerYear)>0?Number(opts.periodsPerYear):null;\nlet peak=ordered[0];\nlet peakAt=0;\nlet worst=0;\nlet worstFrom=0;\nlet worstTo=0;\nfor(let i=1;i<n;i++){\nif(ordered[i]>peak){peak=ordered[i];peakAt=i;continue;}\nif(peak<=0)continue;\nconst fall=(peak-ordered[i])/peak;\nif(fall>worst){worst=fall;worstFrom=peakAt;worstTo=i;}\n}\nlet autocorrelation=null;\nif(n>2){\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<n;i++){\nconst d=ordered[i]-mean;\nbottom+=d*d;\nif(i>0)top+=d*(ordered[i-1]-mean);\n}\nautocorrelation=bottom>0?top/bottom:null;\n}\nlet up=0;\nlet down=0;\nfor(const r of returns){if(r>0)up++;else if(r<0)down++;}\nlet growth=null;\nif(first>0&&last>0){\nconst perPeriod=(last/first)**(1/(n-1))-1;\ngrowth=periods?(1+perPeriod)**periods-1:perPeriod;\n}\nreturn{\nn,\nfirst,\nlast,\nchange:last-first,\nchangePercent:first===0?null:((last-first)/Math.abs(first))*100,\nvolatility,\nannualisedVolatility:volatility!==null&&periods?volatility*Math.sqrt(periods):null,\ngrowth,\nmaxDrawdown:worst,\nmaxDrawdownFrom:worstFrom,\nmaxDrawdownTo:worstTo,\nautocorrelation,\nupDays:up,\ndownDays:down,\n};\n}\nconst D2_N2=1.128;\nconst D4_N2=3.267;\nfunction movingRanges(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst ranges=[];\nfor(let i=1;i<n;i++)ranges.push(Math.abs(ordered[i]-ordered[i-1]));\nconst centre=ranges.reduce((t,r)=>t+r,0)/ranges.length;\nreturn{ranges,centre,upper:D4_N2*centre,lower:0};\n}\nfunction withinSigma(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nlet total=0;\nfor(let i=1;i<n;i++)total+=Math.abs(ordered[i]-ordered[i-1]);\nconst meanRange=total/(n-1);\nreturn{sigma:meanRange/D2_N2,meanRange};\n}\nfunction capability(ordered,spec){\nconst n=ordered.length;\nif(n<2||!spec)return null;\nconst lower=Number.isFinite(Number(spec.lower))?Number(spec.lower):null;\nconst upper=Number.isFinite(Number(spec.upper))?Number(spec.upper):null;\nif(lower===null&&upper===null)return null;\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet m2=0;\nfor(let i=0;i<n;i++)m2+=(ordered[i]-mean)**2;\nconst overall=Math.sqrt(m2/(n-1));\nconst within=withinSigma(ordered);\nconst sigmaWithin=within?within.sigma:null;\nconst indices=(sigma)=>{\nif(!sigma||sigma<=0)return{index:null,k:null};\nconst both=lower!==null&&upper!==null;\nconst index=both?(upper-lower)/(6*sigma):null;\nconst upperSide=upper!==null?(upper-mean)/(3*sigma):Infinity;\nconst lowerSide=lower!==null?(mean-lower)/(3*sigma):Infinity;\nreturn{index,k:Math.min(upperSide,lowerSide)};\n};\nconst short=indices(sigmaWithin);\nconst long=indices(overall);\nlet outOfSpec=0;\nfor(let i=0;i<n;i++){\nif(lower!==null&&ordered[i]<lower){outOfSpec++;continue;}\nif(upper!==null&&ordered[i]>upper)outOfSpec++;\n}\nreturn{\nn,\nmean,\nlower,\nupper,\ntarget:Number.isFinite(Number(spec.target))?Number(spec.target):null,\nsigmaWithin,\nsigmaOverall:overall,\ncp:short.index,\ncpk:short.k,\npp:long.index,\nppk:long.k,\noutOfSpec,\ndefectRate:n?outOfSpec/n:null,\n};\n}\nfunction controlLimits(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst within=withinSigma(ordered);\nif(!within||!(within.sigma>0))return null;\nlet centre=0;\nfor(let i=0;i<n;i++)centre+=ordered[i];\ncentre/=n;\nreturn{\ncentre,\nsigma:within.sigma,\nupper:centre+3*within.sigma,\nlower:centre-3*within.sigma,\n};\n}\nfunction westernElectricViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3){\nout.push({index:i,rule:1,description:'beyond three sigma'});\n}\nif(i>=2){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-2;k<=i;k++)if(z(k)*side>2)hits++;\nif(hits>=2){\nout.push({index:i,rule:2,description:'two of three past two sigma'});\nbreak;\n}\n}\n}\nif(i>=4){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-4;k<=i;k++)if(z(k)*side>1)hits++;\nif(hits>=4){\nout.push({index:i,rule:3,description:'four of five past one sigma'});\nbreak;\n}\n}\n}\nif(i>=7){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-7;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){\nout.push({index:i,rule:4,description:'eight in a row on one side'});\nbreak;\n}\n}\n}\n}\nreturn out;\n}\nfunction nelsonViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst oneSide=(from,to,past,need)=>{\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=from;k<=to;k++)if(z(k)*side>past)hits++;\nif(hits>=need)return true;\n}\nreturn false;\n};\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3)out.push({index:i,rule:1,description:'beyond three sigma'});\nif(i>=8){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-8;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){out.push({index:i,rule:2,description:'nine in a row on one side'});break;}\n}\n}\nif(i>=5){\nfor(const dir of[1,-1]){\nlet all=true;\nfor(let k=i-4;k<=i;k++){\nif((ordered[k]-ordered[k-1])*dir<=0){all=false;break;}\n}\nif(all){\nout.push({index:i,rule:3,description:dir>0?'six rising':'six falling'});\nbreak;\n}\n}\n}\nif(i>=13){\nlet alternating=true;\nfor(let k=i-12;k<=i;k++){\nconst a=ordered[k]-ordered[k-1];\nconst b=ordered[k+1<=i?k+1:k]-ordered[k];\nif(k+1>i)break;\nif(a===0||b===0||(a>0)===(b>0)){alternating=false;break;}\n}\nif(alternating)out.push({index:i,rule:4,description:'fourteen alternating'});\n}\nif(i>=2&&oneSide(i-2,i,2,2)){\nout.push({index:i,rule:5,description:'two of three past two sigma'});\n}\nif(i>=4&&oneSide(i-4,i,1,4)){\nout.push({index:i,rule:6,description:'four of five past one sigma'});\n}\nif(i>=14){\nlet inside=true;\nfor(let k=i-14;k<=i;k++)if(Math.abs(z(k))>=1){inside=false;break;}\nif(inside)out.push({index:i,rule:7,description:'fifteen within one sigma'});\n}\nif(i>=7){\nlet outside=true;\nfor(let k=i-7;k<=i;k++)if(Math.abs(z(k))<=1){outside=false;break;}\nif(outside)out.push({index:i,rule:8,description:'eight beyond one sigma'});\n}\n}\nreturn out;\n}\nconst CONTROL_RULE_SETS=Object.freeze(['westernElectric','nelson']);\nfunction controlViolations(ordered,limits,ruleSet='westernElectric'){\nreturn String(ruleSet)==='nelson'\n?nelsonViolations(ordered,limits)\n:westernElectricViolations(ordered,limits);\n}\nfunction countOutside(values,low,high){\nlet count=0;\nfor(let i=0;i<values.length;i++){\nif(values[i]<low||values[i]>high)count++;\n}\nreturn count;\n}\nfunction histogram(sorted,q1,q3,cap=20){\nconst n=sorted.length;\nif(!n)return[];\nconst min=sorted[0];\nconst max=sorted[n-1];\nif(max===min)return[{from:min,to:max,count:n}];\nconst iqr=q3-q1;\nconst fence=1.5*iqr;\nlet lo=iqr>0?Math.max(min,q1-fence):min;\nlet hi=iqr>0?Math.min(max,q3+fence):max;\nif(!(hi>lo)){lo=min;hi=max;}\nconst width=iqr>0?(2*iqr)/Math.cbrt(n):(hi-lo)/(Math.ceil(Math.log2(n))+1);\nconst count=width>0\n?Math.min(cap,Math.max(1,Math.ceil((hi-lo)/width)))\n:1;\nconst step=(hi-lo)/count;\nconst bins=[];\nfor(let i=0;i<count;i++){\nbins.push({from:lo+i*step,to:lo+(i+1)*step,count:0});\n}\nfor(let i=0;i<n;i++){\nconst at=Math.min(count-1,Math.max(0,Math.floor((sorted[i]-lo)/step)));\nbins[at].count++;\n}\nbins[0].from=min;\nbins[count-1].to=max;\nreturn bins;\n}\nconst DEFAULT_CONFIDENCE=0.95;\nfunction level(conf){\nconst c=Number(conf);\nreturn Number.isFinite(c)&&c>0&&c<1?c:DEFAULT_CONFIDENCE;\n}\nfunction meanInterval(values,conf=DEFAULT_CONFIDENCE){\nconst n=values.length;\nif(n<2)return null;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=values[i];\nconst mean=sum/n;\nlet ss=0;\nfor(let i=0;i<n;i++){const d=values[i]-mean;ss+=d*d;}\nconst sd=Math.sqrt(ss/(n-1));\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,n-1);\nconst margin=(t*sd)/Math.sqrt(n);\nreturn{mean,lower:mean-margin,upper:mean+margin,margin,n,confidence:c};\n}\nfunction proportionInterval(successes,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(successes);\nconst total=Number(n);\nif(!(total>0)||!(k>=0)||k>total)return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst p=k/total;\nconst z2=z*z;\nconst denominator=1+z2/total;\nconst centre=(p+z2/(2*total))/denominator;\nconst half=(z/denominator)\n*Math.sqrt((p*(1-p))/total+z2/(4*total*total));\nreturn{\nproportion:p,\nlower:Math.max(0,centre-half),\nupper:Math.min(1,centre+half),\nn:total,\nconfidence:c,\n};\n}\nfunction slopeInterval(fit,conf=DEFAULT_CONFIDENCE){\nif(!fit||!(fit.n>2)||!Number.isFinite(fit.stdError))return null;\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,fit.n-2);\nconst margin=t*fit.stdError;\nreturn{\nslope:fit.slope,\nlower:fit.slope-margin,\nupper:fit.slope+margin,\nmargin,\nconfidence:c,\n};\n}\nfunction capabilityInterval(index,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(index);\nconst count=Number(n);\nif(!Number.isFinite(k)||!(count>1))return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst margin=z*Math.sqrt(1/(9*count)+(k*k)/(2*(count-1)));\nreturn{index:k,lower:k-margin,upper:k+margin,margin,n:count,confidence:c};\n}\n});\n__def(\"packages/core/src/compute/total.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return TOTAL_FNS;}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return TOTAL_LABELS;}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return totalLabel;}});\nObject.defineProperty(__exports,\"aggregatesFor\",{enumerable:true,get:function(){return aggregatesFor;}});\nObject.defineProperty(__exports,\"aggregateAllowed\",{enumerable:true,get:function(){return aggregateAllowed;}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return collectValues;}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return total;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isFunction=__m0[\"isFunction\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m1[\"presenceReader\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst valueReader=__m1[\"valueReader\"];\nconst __m2=__req(\"packages/core/src/compute/statistics.js\");\nconst STAT_FNS=__m2[\"STAT_FNS\"];\nconst STAT_LABELS=__m2[\"STAT_LABELS\"];\nfunction isNumericBacking(handle){\nreturn!!handle&&(handle.kind==='float64'||handle.kind==='int32');\n}\nfunction sum(handle,indices){\nconst n=indices.length;\nlet acc=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(!Number.isNaN(v))acc+=v;\n}\nreturn acc;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1){\nconst v=values[row];\nif(!Number.isNaN(v))acc+=v;\n}\n}\nreturn acc;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=numberOf(read(indices[i]));\nif(v!==null)acc+=v;\n}\nreturn acc;\n}\nsum.kernel=true;\nfunction countValues(handle,indices){\nconst n=indices.length;\nlet count=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++)if(!Number.isNaN(values[indices[i]]))count++;\nreturn count;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1&&!Number.isNaN(values[row]))count++;\n}\nreturn count;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v!==null&&v!==undefined&&!(typeof v==='number'&&Number.isNaN(v)))count++;\n}\nreturn count;\n}\ncountValues.kernel=true;\nfunction count(handle,indices){\nreturn indices.length;\n}\ncount.kernel=true;\nfunction avg(handle,indices){\nconst values=countValues(handle,indices);\nif(values===0)return null;\nreturn sum(handle,indices)/values;\n}\navg.kernel=true;\nfunction extreme(handle,indices,direction,locale){\nconst n=indices.length;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nlet best=null;\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===0)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nconst read=valueReader(handle);\nconst cmp=valueComparator(locale);\nlet best=null;\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v)))continue;\nif(best===null||(direction<0?cmp(v,best)<0:cmp(v,best)>0))best=v;\n}\nreturn best;\n}\nfunction min(handle,indices,ctx){\nreturn extreme(handle,indices,-1,ctx&&ctx.locale);\n}\nmin.kernel=true;\nfunction max(handle,indices,ctx){\nreturn extreme(handle,indices,1,ctx&&ctx.locale);\n}\nmax.kernel=true;\nfunction first(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[0]);\n}\nfirst.kernel=true;\nfunction last(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[indices.length-1]);\n}\nlast.kernel=true;\nfunction numberOf(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nconst TOTAL_FNS={\nsum,min,max,avg,count,first,last,countValues,\n...STAT_FNS,\n};\nconst TOTAL_LABELS=Object.freeze({\n...STAT_LABELS,\nsum:'Sum',\navg:'Average',\nmin:'Min',\nmax:'Max',\ncount:'Count',\ncountValues:'Count of values',\nfirst:'First',\nlast:'Last',\n});\nfunction totalLabel(fn){\nif(!fn)return'';\nif(typeof fn==='string')return TOTAL_LABELS[fn]||fn;\nreturn'Total';\n}\nconst CHOOSER_ORDER=Object.freeze([\n'sum','avg','min','max','count','countValues','first','last',\n]);\nfunction aggregatesFor(column){\nconst supported=column&&column.dataType\n&&column.dataType.totals&&column.dataType.totals.supported;\nif(Array.isArray(supported))return supported.slice();\nconst named=CHOOSER_ORDER.filter((name)=>name in TOTAL_FNS);\nfor(const name of Object.keys(TOTAL_FNS))if(!named.includes(name))named.push(name);\nreturn named;\n}\nfunction aggregateAllowed(column,name){\nif(typeof name!=='string')return true;\nreturn aggregatesFor(column).includes(name);\n}\nfunction collectValues(handle,indices){\nconst read=valueReader(handle);\nconst out=[];\nfor(let i=0;i<indices.length;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined)continue;\nout.push(v);\n}\nreturn out;\n}\nfunction total(handle,indices,fn,ctx){\nconst list=indices||[];\nif(typeof fn==='string'){\nconst kernel=TOTAL_FNS[fn];\nif(!kernel){\nwarnOnce(`total:${fn}`,`unknown total function \"${fn}\"; register it in config.totalFns`);\nreturn null;\n}\nreturn kernel(handle,list,ctx);\n}\nif(isFunction(fn)){\nif(fn.kernel===true)return fn(handle,list,ctx);\nreturn fn(collectValues(handle,list),ctx||{});\n}\nreturn null;\n}\n});\n__def(\"packages/core/src/compute/pivot.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return KEY_DELIMITER;}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return DEFAULT_PATH_SEPARATOR;}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return DEFAULT_MAX_COLUMNS;}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return pivotKey;}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return joinPath;}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return resolvePivotKeys;}});\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return pivot;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nconst packKeys=__m2[\"packKeys\"];\nconst __m3=__req(\"packages/core/src/compute/total.js\");\nconst total=__m3[\"total\"];\nconst KEY_DELIMITER='|';\nconst DEFAULT_PATH_SEPARATOR='/';\nconst DEFAULT_MAX_COLUMNS=2000;\nfunction pivotKey(groupPath,pivotPath,colId){\nreturn`${groupPath}${KEY_DELIMITER}${pivotPath}${KEY_DELIMITER}${colId}`;\n}\nfunction joinPath(parts,separator){\nlet out='';\nfor(let i=0;i<parts.length;i++){\nconst v=parts[i];\nout+=(i===0?'':separator)+(v===null||v===undefined?'':String(v));\n}\nreturn out;\n}\nfunction resolvePivotKeys(handles,order,opts={}){\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst n=order.length;\nconst{keyOf,readers}=packKeys(handles,order,0);\nconst seen=new Map();\nconst tuples=[];\nconst rawKeys=[];\nfor(let i=0;i<n;i++){\nconst row=order[i];\nconst key=keyOf(row);\nif(seen.has(key))continue;\nseen.set(key,tuples.length);\nrawKeys.push(key);\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\ntuples.push(tuple);\n}\nconst cmp=valueComparator(opts.locale);\nconst rank=tuples.map((_,i)=>i);\nrank.sort((a,b)=>{\nconst ta=tuples[a];\nconst tb=tuples[b];\nfor(let j=0;j<ta.length;j++){\nconst c=compareNullable(ta[j],tb[j],cmp);\nif(c!==0)return c;\n}\nreturn a-b;\n});\nconst keys=new Array(rank.length);\nconst paths=new Array(rank.length);\nconst idByKey=new Map();\nfor(let position=0;position<rank.length;position++){\nconst from=rank[position];\nkeys[position]=tuples[from];\npaths[position]=joinPath(tuples[from],separator);\nidByKey.set(rawKeys[from],position);\n}\nconst idOf=(row)=>{\nconst id=idByKey.get(keyOf(row));\nreturn id===undefined?-1:id;\n};\nreturn{keys,paths,idOf};\n}\nfunction compareNullable(a,b,cmp){\nconst na=a===null||a===undefined;\nconst nb=b===null||b===undefined;\nif(na||nb)return na&&nb?0:na?1:-1;\nreturn cmp(a,b);\n}\nfunction resolveValueColumns(opts){\nconst declared=opts.values||opts.totals||[];\nif(declared.length&&typeof declared[0]==='object'&&declared[0]!==null){\nreturn declared.filter((entry)=>entry&&entry.handle);\n}\nconst resolve=typeof opts.handle==='function'?opts.handle:null;\nif(!resolve){\nif(declared.length){\nwarnOnce('pivot:handles',\n'pivot was given total column ids but no handle(colId) resolver, so no cell values were reduced. Pass values: [{ colId, handle, fn }] or opts.handle.');\n}\nreturn[];\n}\nconst totalOf=typeof opts.totalOf==='function'?opts.totalOf:null;\nconst out=[];\nfor(const colId of declared){\nconst handle=resolve(colId);\nif(!handle)continue;\nout.push({colId,handle,fn:totalOf?totalOf(colId):'sum'});\n}\nreturn out;\n}\nfunction normaliseArgs(a,b,c){\nif(Array.isArray(a)){\nconst opts=c||{};\nreturn{...opts,pivotHandles:a,order:b||null,groups:opts.groups||null};\n}\nreturn a||{};\n}\nfunction pivot(input,orderArg,optsArg){\nconst opts=normaliseArgs(input,orderArg,optsArg);\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst valueColumns=resolveValueColumns(opts);\nconst maxColumns=opts.maxColumns===undefined?DEFAULT_MAX_COLUMNS:opts.maxColumns;\nconst groups=opts.groups&&opts.groups.buckets?opts.groups:null;\nconst buckets=groups?groups.buckets:[opts.order||new Uint32Array(0)];\nconst groupPaths=opts.groupPaths\n||(groups?groups.keys.map((tuple)=>joinPath(tuple,separator)):['']);\nconst scope=concatIndices(buckets);\nconst{keys,paths,idOf}=resolvePivotKeys(opts.pivotHandles||[],scope,opts);\nconst columns=paths.length*Math.max(1,valueColumns.length);\nconst fields=derivedFields(paths,valueColumns,separator);\nif(maxColumns&&columns>maxColumns){\nconst empty=new Map();\nreturn{\nkeys,\npaths,\nfields,\ngroupPaths,\ncolumns,\nvalues:empty,\ncells:empty,\nerror:{\ncode:'pivot-max-columns',\nmessage:`[lattice] pivot would generate ${columns} columns, above pivot.maxColumns of ${maxColumns}. Narrow the pivot columns or raise the limit.`,\ncolumns,\nmaxColumns,\n},\n};\n}\nconst cells=new Map();\nconst keyCount=paths.length;\nfor(let g=0;g<buckets.length;g++){\nconst bucket=buckets[g];\nconst groupPath=groupPaths[g]===undefined?'':groupPaths[g];\nconst n=bucket.length;\nif(n===0)continue;\nconst ids=new Int32Array(n);\nconst counts=new Uint32Array(keyCount+1);\nfor(let i=0;i<n;i++){\nconst id=idOf(bucket[i]);\nids[i]=id;\nif(id>=0)counts[id+1]++;\n}\nfor(let k=0;k<keyCount;k++)counts[k+1]+=counts[k];\nconst scattered=new Uint32Array(n);\nconst cursor=counts.slice(0,keyCount);\nfor(let i=0;i<n;i++){\nconst id=ids[i];\nif(id>=0)scattered[cursor[id]++]=bucket[i];\n}\nfor(let k=0;k<keyCount;k++){\nconst from=counts[k];\nconst to=counts[k+1];\nif(to===from)continue;\nconst slice=scattered.subarray(from,to);\nfor(let c=0;c<valueColumns.length;c++){\nconst column=valueColumns[c];\nconst result=total(column.handle,slice,column.fn,opts.totalContext||{locale:opts.locale});\ncells.set(pivotKey(groupPath,paths[k],column.colId),result);\n}\n}\n}\nreturn{keys,paths,fields,groupPaths,columns,values:cells,cells,error:null};\n}\nfunction derivedFields(paths,valueColumns,separator){\nif(valueColumns.length===0)return paths.slice();\nconst out=[];\nfor(const path of paths){\nfor(const column of valueColumns)out.push(`${path}${separator}${column.colId}`);\n}\nreturn out;\n}\nfunction concatIndices(buckets){\nif(buckets.length===1)return buckets[0]||new Uint32Array(0);\nlet n=0;\nfor(const b of buckets)n+=b?b.length:0;\nconst out=new Uint32Array(n);\nlet at=0;\nfor(const b of buckets){\nif(!b||b.length===0)continue;\nout.set(b,at);\nat+=b.length;\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/compute/reference.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return referenceValue;}});\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return referenceSort;}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return referenceFilter;}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return referencePasses;}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return referenceGroup;}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return referenceTotal;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst getPath=__m0[\"getPath\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst isMissing=__m1[\"isMissing\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/filter.js\");\nconst testValue=__m2[\"testValue\"];\nconst KEY_SEPARATOR=String.fromCharCode(0x1f);\nconst NULL_MARKER=String.fromCharCode(0x00);\nfunction referenceValue(row,col){\nconst v=col.includes('.')?getPath(row,col):(row==null?undefined:row[col]);\nreturn v===undefined?null:v;\n}\nfunction referenceSort(rows,entries,opts={}){\nconst list=entries||[];\nlet order=rows.map((_,i)=>i);\nif(list.length===0)return order;\nfor(let e=list.length-1;e>=0;e--){\norder=referenceSortOne(rows,order,list[e],opts);\n}\nreturn order;\n}\nfunction referenceSortOne(rows,order,entry,opts){\nconst locale=entry.locale!==undefined?entry.locale:opts.locale;\nconst base=valueComparator(locale);\nconst descending=entry.descending!==undefined?!!entry.descending:entry.dir==='desc';\nconst present=[];\nconst absent=[];\nfor(const i of order){\nconst v=referenceValue(rows[i],entry.col);\nif(isMissing(v))absent.push(i);else present.push(i);\n}\nconst position=new Map();\nfor(let p=0;p<present.length;p++)position.set(present[p],p);\nconst compare=(a,b)=>{\nconst va=referenceValue(rows[a],entry.col);\nconst vb=referenceValue(rows[b],entry.col);\nlet c;\nif(typeof entry.compare==='function'){\nc=entry.compare(va,vb,rows[a],rows[b],descending);\nif(descending)c=-c;\n}else{\nc=descending?base(vb,va):base(va,vb);\n}\nreturn c!==0?c:position.get(a)-position.get(b);\n};\npresent.sort(compare);\nreturn entry.nullsFirst?absent.concat(present):present.concat(absent);\n}\nfunction referenceFilter(rows,filters,opts={}){\nconst out=[];\nfor(let i=0;i<rows.length;i++){\nif(referencePasses(rows[i],filters,opts,i))out.push(i);\n}\nreturn out;\n}\nfunction referencePasses(row,node,opts,index){\nif(!node)return true;\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nif(children.length===0)return true;\nif(node.op==='or')return children.some((c)=>referencePasses(row,c,opts,index));\nconst all=children.every((c)=>referencePasses(row,c,opts,index));\nreturn node.op==='not'?!all:all;\n}\nif(node.col===undefined&&typeof opts.custom==='function')return!!opts.custom(node,row,index);\nreturn testValue(referenceValue(row,node.col),node,opts.locale);\n}\nfunction referenceGroup(rows,cols,order){\nconst source=order||rows.map((_,i)=>i);\nconst seen=new Map();\nconst keys=[];\nconst buckets=[];\nfor(const i of source){\nconst tuple=cols.map((col)=>referenceValue(rows[i],col));\nconst key=tuple\n.map((v)=>(v===null||v===undefined?NULL_MARKER:String(v)))\n.join(KEY_SEPARATOR);\nlet at=seen.get(key);\nif(at===undefined){\nat=keys.length;\nseen.set(key,at);\nkeys.push(tuple);\nbuckets.push([]);\n}\nbuckets[at].push(i);\n}\nreturn{keys,buckets};\n}\nfunction referenceTotal(values,fn,opts={}){\nconst cmp=valueComparator(opts.locale);\nconst live=values.filter((v)=>!isMissing(v));\nconst numbers=live.map(toNumberOrNull).filter((v)=>v!==null);\nswitch(fn){\ncase'count':return values.length;\ncase'countValues':return live.length;\ncase'sum':return numbers.reduce((a,b)=>a+b,0);\ncase'avg':return live.length===0?null:numbers.reduce((a,b)=>a+b,0)/live.length;\ncase'min':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)<0?b:a));\ncase'max':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)>0?b:a));\ncase'first':return values.length===0?null:normaliseNull(values[0]);\ncase'last':return values.length===0?null:normaliseNull(values[values.length-1]);\ndefault:return null;\n}\n}\nfunction toNumberOrNull(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nfunction normaliseNull(v){\nreturn v===undefined?null:v;\n}\n});\n__def(\"packages/core/src/compute/index.js\",function(__exports,__req){\n'use strict';\nconst __m0=__req(\"packages/core/src/compute/sort.js\");\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return __m0[\"sortColumn\"];}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return __m0[\"sortMulti\"];}});\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return __m0[\"radixSortFloat64\"];}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return __m0[\"radixSortInt32\"];}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return __m0[\"rankSortDictionary\"];}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return __m0[\"mergeSortComparator\"];}});\nconst __m1=__req(\"packages/core/src/compute/filter.js\");\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return __m1[\"evaluateFilters\"];}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return __m1[\"evaluateCondition\"];}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return __m1[\"compact\"];}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return __m1[\"testValue\"];}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return __m1[\"compilePredicate\"];}});\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return __m1[\"releaseMask\"];}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return __m1[\"pruneColumn\"];}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return __m1[\"mentionsColumn\"];}});\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return __m2[\"groupByColumns\"];}});\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return __m2[\"packKeys\"];}});\nconst __m3=__req(\"packages/core/src/compute/facet.js\");\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return __m3[\"facet\"];}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return __m3[\"computeBounds\"];}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return __m3[\"countInto\"];}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return __m3[\"bucketOf\"];}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return __m3[\"facetKind\"];}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return __m3[\"cardinalityOf\"];}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return __m3[\"pickGranularity\"];}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return __m3[\"floorTo\"];}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return __m3[\"advance\"];}});\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return __m3[\"STRATEGIES\"];}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return __m3[\"GRANULARITIES\"];}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return __m3[\"DEFAULT_BUCKETS\"];}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return __m3[\"DEFAULT_CARDINALITY_LIMIT\"];}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return __m3[\"QUANTILE_SAMPLE\"];}});\nconst __m4=__req(\"packages/core/src/compute/total.js\");\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return __m4[\"TOTAL_FNS\"];}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return __m4[\"TOTAL_LABELS\"];}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return __m4[\"totalLabel\"];}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return __m4[\"total\"];}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return __m4[\"collectValues\"];}});\nconst __m5=__req(\"packages/core/src/compute/pivot.js\");\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return __m5[\"pivot\"];}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return __m5[\"resolvePivotKeys\"];}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return __m5[\"pivotKey\"];}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return __m5[\"joinPath\"];}});\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return __m5[\"KEY_DELIMITER\"];}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return __m5[\"DEFAULT_PATH_SEPARATOR\"];}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return __m5[\"DEFAULT_MAX_COLUMNS\"];}});\nconst __m6=__req(\"packages/core/src/compute/reference.js\");\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return __m6[\"referenceSort\"];}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return __m6[\"referenceFilter\"];}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return __m6[\"referenceGroup\"];}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return __m6[\"referenceTotal\"];}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return __m6[\"referencePasses\"];}});\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return __m6[\"referenceValue\"];}});\nconst __m7=__req(\"packages/core/src/compute/handle.js\");\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return __m7[\"identity\"];}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return __m7[\"rowCount\"];}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return __m7[\"presenceReader\"];}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return __m7[\"bitReader\"];}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return __m7[\"valueReader\"];}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return __m7[\"valueComparator\"];}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return __m7[\"numericTotalOrder\"];}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return __m7[\"dictRanks\"];}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return __m7[\"dictSize\"];}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return __m7[\"dictValue\"];}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return __m7[\"multiValue\"];}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return __m7[\"isMissing\"];}});\n});\n__def(\"packages/worker/src/kernel.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"loadCompute\",{enumerable:true,get:function(){return loadCompute;}});\nObject.defineProperty(__exports,\"setCompute\",{enumerable:true,get:function(){return setCompute;}});\nObject.defineProperty(__exports,\"dispatch\",{enumerable:true,get:function(){return dispatch;}});\nObject.defineProperty(__exports,\"handleMessage\",{enumerable:true,get:function(){return handleMessage;}});\nObject.defineProperty(__exports,\"installKernel\",{enumerable:true,get:function(){return installKernel;}});\nconst __m0=__req(\"packages/worker/src/transport.js\");\nconst PROTOCOL=__m0[\"PROTOCOL\"];\nconst OPS=__m0[\"OPS\"];\nconst CONTROL=__m0[\"CONTROL\"];\nconst ERRORS=__m0[\"ERRORS\"];\nconst unpackHandle=__m0[\"unpackHandle\"];\nconst unpackHandles=__m0[\"unpackHandles\"];\nconst createMaskPool=__m0[\"createMaskPool\"];\nconst collectTransfers=__m0[\"collectTransfers\"];\nconst __m1=__req(\"packages/core/src/store/columnpack.js\");\nconst packChunk=__m1[\"packChunk\"];\nconst packedTransfers=__m1[\"packedTransfers\"];\nlet computeModule=null;\nlet computePromise=null;\nlet computeError=null;\nasync function loadCompute(loader){\nif(computeModule)return computeModule;\nif(!computePromise){\nconst load=loader||(()=>Promise.resolve(__req(\"packages/core/src/compute/index.js\")));\ncomputePromise=Promise.resolve()\n.then(load)\n.then((mod)=>{computeModule=mod;return mod;})\n.catch((err)=>{\ncomputeError=err;\ncomputeModule=null;\nreturn null;\n});\n}\nreturn computePromise;\n}\nfunction setCompute(mod){\ncomputeModule=mod;\ncomputePromise=mod?Promise.resolve(mod):null;\ncomputeError=mod?null:computeError;\n}\nfunction filterContext(handles,count,locale){\nconst byId=new Map();\nfor(const h of handles)if(h)byId.set(h.id,h);\nreturn{\nhandle(colId){return byId.get(colId);},\ncount,\npool:createMaskPool(),\nlocale,\n};\n}\nfunction dispatch(request,compute){\nconst{op,args}=request;\nif(op===OPS.COLUMNIZE){\nreturn packChunk(args.schema||[],args.rows||[],args.opts||{});\n}\nconst fn=compute[op];\nif(typeof fn!=='function'){\nconst err=new Error(`[lattice] compute kernel '${op}' is not exported`);\n(err).code=ERRORS.NO_KERNEL;\nthrow err;\n}\nswitch(op){\ncase OPS.SORT_COLUMN:\nreturn fn(unpackHandle(args.handle),args.order??null,args.opts||{});\ncase OPS.SORT_MULTI:{\nconst handles=unpackHandles(args.handles||[]);\nconst entries=(args.entries||[]).map((e)=>({\n...e,\nhandle:handles[e.index],\n}));\nreturn fn(handles,entries,args.order??null);\n}\ncase OPS.EVALUATE_FILTERS:\nreturn fn(args.filters,filterContext(unpackHandles(args.handles||[]),args.count,args.locale));\ncase OPS.COMPACT:\nreturn fn(args.mask,args.count,undefined);\ncase OPS.GROUP_BY_COLUMNS:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.TOTAL:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.fn);\ncase OPS.PIVOT:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.FACET:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.count,args.opts||{});\ndefault:{\nconst err=new Error(`[lattice] unknown worker op '${op}'`);\n(err).code=ERRORS.PROTOCOL;\nthrow err;\n}\n}\n}\nasync function handleMessage(message,opts={}){\nif(!message||message.lattice!==PROTOCOL)return null;\nconst{id,op}=message;\nif(op===CONTROL.CANCEL){\nopts.cancelled?.add(message.target);\nreturn null;\n}\nif(op===CONTROL.PING){\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result:'pong'},transfer:[]};\n}\nif(op===OPS.COLUMNIZE){\nif(opts.cancelled?.has(id)){opts.cancelled.delete(id);return null;}\ntry{\nconst result=packChunk(message.args.schema||[],message.args.rows||[],message.args.opts||{});\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:packedTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{lattice:PROTOCOL,id,ok:false,error:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack}},\ntransfer:[],\n};\n}\n}\nconst compute=await loadCompute(opts.loader);\nif(!compute){\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{\ncode:ERRORS.NO_COMPUTE,\nmessage:`[lattice] compute kernels unavailable in worker: ${computeError?computeError.message:'module not found'}`,\n},\n},\ntransfer:[],\n};\n}\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\ntry{\nconst result=dispatch(message,compute);\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:collectTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack},\n},\ntransfer:[],\n};\n}\n}\nfunction installKernel(scope,opts={}){\nconst cancelled=new Set();\nconst onMessage=async(event)=>{\nconst outcome=await handleMessage(event.data,{loader:opts.loader,cancelled});\nif(!outcome)return;\nscope.postMessage(outcome.reply,outcome.transfer);\n};\nscope.addEventListener('message',onMessage);\nloadCompute(opts.loader).then((mod)=>{\nscope.postMessage({lattice:PROTOCOL,id:0,op:CONTROL.READY,compute:!!mod});\n});\nreturn()=>scope.removeEventListener('message',onMessage);\n}\n});\nvar __entry=__req(\"packages/worker/src/kernel.js\");\nroot[\"__latticeKernel\"]=__entry;\n})(typeof globalThis!=='undefined'?globalThis:this);\n__latticeKernel.installKernel(self);\n",{type:'classic'});
|
|
69196
|
+
__req("packages/worker/src/inline.js").setWorkerSource("(function(root){\n'use strict';\nvar __mods=Object.create(null);\nvar __cache=Object.create(null);\nfunction __def(id,fn){__mods[id]=fn;}\nfunction __req(id){\nvar hit=__cache[id];\nif(hit)return hit;\nvar exports=Object.create(null);\n__cache[id]=exports;\nvar fn=__mods[id];\nif(!fn)throw new Error('[lattice] missing module: '+id);\nfn(exports,__req);\nreturn exports;\n}\n__def(\"packages/core/src/internal/util.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"VERSION\",{enumerable:true,get:function(){return VERSION;}});\nObject.defineProperty(__exports,\"reportedWarnings\",{enumerable:true,get:function(){return reportedWarnings;}});\nObject.defineProperty(__exports,\"warnOnce\",{enumerable:true,get:function(){return warnOnce;}});\nObject.defineProperty(__exports,\"infoOnce\",{enumerable:true,get:function(){return infoOnce;}});\nObject.defineProperty(__exports,\"resetWarnings\",{enumerable:true,get:function(){return resetWarnings;}});\nObject.defineProperty(__exports,\"fail\",{enumerable:true,get:function(){return fail;}});\nObject.defineProperty(__exports,\"invariant\",{enumerable:true,get:function(){return invariant;}});\nObject.defineProperty(__exports,\"DEV\",{enumerable:true,get:function(){return DEV;}});\nObject.defineProperty(__exports,\"isObject\",{enumerable:true,get:function(){return isObject;}});\nObject.defineProperty(__exports,\"isFunction\",{enumerable:true,get:function(){return isFunction;}});\nObject.defineProperty(__exports,\"isNil\",{enumerable:true,get:function(){return isNil;}});\nObject.defineProperty(__exports,\"isBlank\",{enumerable:true,get:function(){return isBlank;}});\nObject.defineProperty(__exports,\"isCtor\",{enumerable:true,get:function(){return isCtor;}});\nObject.defineProperty(__exports,\"pathGetter\",{enumerable:true,get:function(){return pathGetter;}});\nObject.defineProperty(__exports,\"pathSetter\",{enumerable:true,get:function(){return pathSetter;}});\nObject.defineProperty(__exports,\"getPath\",{enumerable:true,get:function(){return getPath;}});\nObject.defineProperty(__exports,\"setPath\",{enumerable:true,get:function(){return setPath;}});\nObject.defineProperty(__exports,\"humanise\",{enumerable:true,get:function(){return humanise;}});\nObject.defineProperty(__exports,\"escapeHtml\",{enumerable:true,get:function(){return escapeHtml;}});\nObject.defineProperty(__exports,\"titleCase\",{enumerable:true,get:function(){return titleCase;}});\nObject.defineProperty(__exports,\"expand\",{enumerable:true,get:function(){return expand;}});\nObject.defineProperty(__exports,\"toArray\",{enumerable:true,get:function(){return toArray;}});\nObject.defineProperty(__exports,\"merge\",{enumerable:true,get:function(){return merge;}});\nObject.defineProperty(__exports,\"mergeRow\",{enumerable:true,get:function(){return mergeRow;}});\nObject.defineProperty(__exports,\"Lru\",{enumerable:true,get:function(){return Lru;}});\nObject.defineProperty(__exports,\"collator\",{enumerable:true,get:function(){return collator;}});\nObject.defineProperty(__exports,\"defaultCompare\",{enumerable:true,get:function(){return defaultCompare;}});\nObject.defineProperty(__exports,\"now\",{enumerable:true,get:function(){return now;}});\nObject.defineProperty(__exports,\"nextFrame\",{enumerable:true,get:function(){return nextFrame;}});\nObject.defineProperty(__exports,\"cancelFrame\",{enumerable:true,get:function(){return cancelFrame;}});\nObject.defineProperty(__exports,\"frameBatched\",{enumerable:true,get:function(){return frameBatched;}});\nObject.defineProperty(__exports,\"settleDebounce\",{enumerable:true,get:function(){return settleDebounce;}});\nObject.defineProperty(__exports,\"whenIdle\",{enumerable:true,get:function(){return whenIdle;}});\nObject.defineProperty(__exports,\"uid\",{enumerable:true,get:function(){return uid;}});\nconst STAMPED_VERSION=\"1.18.0\";\nasync function resolveVersion(){\nif(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;\ntry{\nif(typeof process==='undefined'||!process.versions||!process.versions.node){\nreturn STAMPED_VERSION;\n}\nconst mod=await import('node:'+'module');\nconst req=mod.createRequire((typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst fs=req('node:'+'fs');\nconst url=new URL('../../../../package.json',(typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst text=fs.readFileSync(url,'utf8');\nreturn JSON.parse(text).version||STAMPED_VERSION;\n}catch{\nreturn STAMPED_VERSION;\n}\n}\nconst VERSION=\"1.18.0\";\nconst warned=new Set();\nconst reported=[];\nconst REPORT_LIMIT=500;\nfunction record(key,level,message){\nreported.push({\nkey,\nlevel,\nmessage:message.map((m)=>(typeof m==='string'?m:safeString(m))).join(' '),\nat:Date.now(),\n});\nif(reported.length>REPORT_LIMIT)reported.shift();\n}\nfunction safeString(value){\nif(value instanceof Error)return value.message;\ntry{return JSON.stringify(value);}catch{return String(value);}\n}\nfunction reportedWarnings(){return reported.map((r)=>({...r}));}\nfunction warnOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'warn',message);\nconsole.warn('[lattice]',...message);\n}\nfunction infoOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'info',message);\nconsole.info('[lattice]',...message);\n}\nfunction resetWarnings(){\nwarned.clear();\nreported.length=0;\n}\nfunction fail(message,extra){\nconst err=new Error(`[lattice] ${message}`);\nif(extra!==undefined)err.cause=extra;\nthrow err;\n}\nfunction invariant(condition,message){\nif(!condition)fail(message);\n}\nconst DEV=(()=>{\ntry{\nreturn!(typeof process!=='undefined'&&process.env\n&&process.env.NODE_ENV==='production');\n}catch{\nreturn true;\n}\n})();\nfunction isObject(v){\nreturn v!==null&&typeof v==='object'&&!Array.isArray(v);\n}\nfunction isFunction(v){\nreturn typeof v==='function';\n}\nfunction isNil(v){\nreturn v===null||v===undefined;\n}\nfunction isBlank(v){\nreturn v===null||v===undefined||v==='';\n}\nfunction isCtor(v){\nif(typeof v!=='function')return false;\nif(/^class[\\s{]/.test(Function.prototype.toString.call(v)))return true;\nreturn!!(v.prototype&&Object.getOwnPropertyNames(v.prototype).length>1);\n}\nconst pathCache=new Map();\nfunction pathGetter(path){\nlet fn=pathCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o)=>(o==null?undefined:o[path]);\n}else{\nconst parts=path.split('.');\nconst n=parts.length;\nfn=(o)=>{\nlet cur=o;\nfor(let i=0;i<n;i++){\nif(cur==null)return undefined;\ncur=cur[parts[i]];\n}\nreturn cur;\n};\n}\npathCache.set(path,fn);\nreturn fn;\n}\nconst setterCache=new Map();\nfunction pathSetter(path){\nlet fn=setterCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o,v)=>{if(o!=null)o[path]=v;};\n}else{\nconst parts=path.split('.');\nconst last=parts.length-1;\nfn=(o,v)=>{\nlet cur=o;\nfor(let i=0;i<last;i++){\nif(cur==null)return;\nconst k=parts[i];\nif(cur[k]==null)cur[k]={};\ncur=cur[k];\n}\nif(cur!=null)cur[parts[last]]=v;\n};\n}\nsetterCache.set(path,fn);\nreturn fn;\n}\nfunction getPath(obj,path){\nreturn pathGetter(path)(obj);\n}\nfunction setPath(obj,path,value){\npathSetter(path)(obj,value);\n}\nfunction humanise(field){\nif(!field)return'';\nconst leaf=field.includes('.')?field.slice(field.lastIndexOf('.')+1):field;\nreturn leaf\n.replace(/[_-]+/g,' ')\n.replace(/([a-z0-9])([A-Z])/g,'$1 $2')\n.replace(/([A-Z]+)([A-Z][a-z])/g,'$1 $2')\n.replace(/\\s+/g,' ')\n.trim()\n.replace(/^./,(c)=>c.toUpperCase());\n}\nconst ESCAPES={'&':'&','<':'<','>':'>','\"':'"',\"'\":'''};\nfunction escapeHtml(s){\nconst str=s==null?'':String(s);\nreturn/[&<>\"']/.test(str)?str.replace(/[&<>\"']/g,(c)=>ESCAPES[c]):str;\n}\nfunction titleCase(s){\nreturn String(s).replace(/\\w\\S*/g,(t)=>t[0].toUpperCase()+t.slice(1).toLowerCase());\n}\nfunction expand(value,key,whenTrue){\nif(value===undefined)return undefined;\nif(value===true)return{enabled:true,...whenTrue};\nif(value===false)return{enabled:false};\nif(isObject(value))return value;\nreturn{[key]:value,enabled:true};\n}\nfunction toArray(v){\nif(v===undefined||v===null)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction merge(a,b){\nif(!isObject(a))return isObject(b)?{...b}:b;\nif(!isObject(b))return b===undefined?a:b;\nconst out={...a};\nfor(const k of Object.keys(b)){\nconst bv=b[k];\nif(bv===undefined)continue;\nout[k]=isObject(bv)&&isObject(out[k])?merge(out[k],bv):bv;\n}\nreturn out;\n}\nfunction mergeRow(previous,patch){\nif(!isObject(previous)||!isObject(patch)||previous===patch)return patch;\nconst out=Object.create(Object.getPrototypeOf(previous));\nObject.assign(out,previous,patch);\nreturn out;\n}\nclass Lru{\n#max;\n#map=new Map();\n#onEvict;\nconstructor(max=256,onEvict=null){\nthis.#max=max;\nthis.#onEvict=onEvict;\n}\nget size(){\nreturn this.#map.size;\n}\nget max(){\nreturn this.#max;\n}\nset max(v){\nthis.#max=v;\nthis.#trim();\n}\nhas(k){\nreturn this.#map.has(k);\n}\nget(k){\nconst m=this.#map;\nif(!m.has(k))return undefined;\nconst v=m.get(k);\nm.delete(k);\nm.set(k,v);\nreturn v;\n}\npeek(k){\nreturn this.#map.get(k);\n}\nset(k,v){\nconst m=this.#map;\nif(m.has(k))m.delete(k);\nm.set(k,v);\nthis.#trim();\nreturn v;\n}\ndelete(k){\nconst v=this.#map.get(k);\nif(this.#map.delete(k)&&this.#onEvict)this.#onEvict(v,k);\nreturn v;\n}\nclear(){\nif(this.#onEvict)for(const[k,v]of this.#map)this.#onEvict(v,k);\nthis.#map.clear();\n}\nkeys(){\nreturn this.#map.keys();\n}\nvalues(){\nreturn this.#map.values();\n}\n#trim(){\nconst m=this.#map;\nwhile(m.size>this.#max){\nconst oldest=m.keys().next().value;\nconst v=m.get(oldest);\nm.delete(oldest);\nif(this.#onEvict)this.#onEvict(v,oldest);\n}\n}\n}\nconst collators=new Map();\nfunction collator(locale,opts){\nconst key=`${locale||''}|${opts?JSON.stringify(opts):''}`;\nlet c=collators.get(key);\nif(!c){\nc=new Intl.Collator(locale||undefined,{\nnumeric:true,sensitivity:'variant',...opts,\n});\ncollators.set(key,c);\n}\nreturn c;\n}\nfunction defaultCompare(a,b){\nif(a===b)return 0;\nif(a===null||a===undefined)return 1;\nif(b===null||b===undefined)return-1;\nif(typeof a==='number'&&typeof b==='number'){\nif(Number.isNaN(a))return Number.isNaN(b)?0:1;\nif(Number.isNaN(b))return-1;\nreturn a<b?-1:a>b?1:0;\n}\nconst sa=String(a);\nconst sb=String(b);\nreturn sa<sb?-1:sa>sb?1:0;\n}\nfunction now(){\nreturn typeof performance!=='undefined'&&performance.now\n?performance.now()\n:Date.now();\n}\nconst hasRaf=typeof requestAnimationFrame==='function';\nfunction nextFrame(fn){\nif(hasRaf)return requestAnimationFrame(fn);\nreturn setTimeout(()=>fn(now()),16);\n}\nfunction cancelFrame(handle){\nif(handle==null)return;\nif(hasRaf)cancelAnimationFrame(handle);\nelse clearTimeout(handle);\n}\nfunction frameBatched(fn){\nlet handle=null;\nlet lastArgs=null;\nconst run=()=>{\nhandle=null;\nconst a=lastArgs;\nlastArgs=null;\nfn(...(a||[]));\n};\nconst wrapped=(...args)=>{\nlastArgs=args;\nif(handle===null)handle=nextFrame(run);\n};\nwrapped.cancel=()=>{\ncancelFrame(handle);\nhandle=null;\nlastArgs=null;\n};\nwrapped.flush=()=>{\nif(handle!==null){\ncancelFrame(handle);\nrun();\n}\n};\nreturn wrapped;\n}\nfunction settleDebounce(fn,waitMs){\nlet timer=null;\nlet held=null;\nconst trailing=()=>{\ntimer=null;\nif(held===null)return;\nconst args=held;\nheld=null;\nfn(...args);\narm();\n};\nconst arm=()=>{\ntimer=setTimeout(trailing,waitMs);\nif(typeof timer?.unref==='function')timer.unref();\n};\nconst wrapped=(...args)=>{\nif(timer===null){\nfn(...args);\narm();\n}else{\nheld=args;\nclearTimeout(timer);\narm();\n}\n};\nwrapped.flush=()=>{\nif(timer!==null)clearTimeout(timer);\ntimer=null;\nif(held===null)return;\nconst args=held;\nheld=null;\nfn(...args);\n};\nwrapped.cancel=()=>{\nif(timer!==null)clearTimeout(timer);\ntimer=null;\nheld=null;\n};\nwrapped.pending=()=>timer!==null||held!==null;\nreturn wrapped;\n}\nfunction whenIdle(fn,timeout=50){\nif(typeof requestIdleCallback==='function'){\nreturn requestIdleCallback(fn,{timeout});\n}\nreturn setTimeout(()=>fn({timeRemaining:()=>0,didTimeout:true}),1);\n}\nlet idSeq=0;\nfunction uid(prefix='l'){\nreturn`${prefix}${(++idSeq).toString(36)}`;\n}\n});\n__def(\"packages/worker/src/transport.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"PROTOCOL\",{enumerable:true,get:function(){return PROTOCOL;}});\nObject.defineProperty(__exports,\"OPS\",{enumerable:true,get:function(){return OPS;}});\nObject.defineProperty(__exports,\"CONTROL\",{enumerable:true,get:function(){return CONTROL;}});\nObject.defineProperty(__exports,\"ERRORS\",{enumerable:true,get:function(){return ERRORS;}});\nObject.defineProperty(__exports,\"packHandle\",{enumerable:true,get:function(){return packHandle;}});\nObject.defineProperty(__exports,\"packHandles\",{enumerable:true,get:function(){return packHandles;}});\nObject.defineProperty(__exports,\"TransportedDictionary\",{enumerable:true,get:function(){return TransportedDictionary;}});\nObject.defineProperty(__exports,\"unpackHandle\",{enumerable:true,get:function(){return unpackHandle;}});\nObject.defineProperty(__exports,\"unpackHandles\",{enumerable:true,get:function(){return unpackHandles;}});\nObject.defineProperty(__exports,\"createMaskPool\",{enumerable:true,get:function(){return createMaskPool;}});\nObject.defineProperty(__exports,\"isTransferable\",{enumerable:true,get:function(){return isTransferable;}});\nObject.defineProperty(__exports,\"collectTransfers\",{enumerable:true,get:function(){return collectTransfers;}});\nObject.defineProperty(__exports,\"isPortable\",{enumerable:true,get:function(){return isPortable;}});\nObject.defineProperty(__exports,\"filterColumnIds\",{enumerable:true,get:function(){return filterColumnIds;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst isFunction=__m0[\"isFunction\"];\nconst PROTOCOL=1;\nconst OPS=Object.freeze({\nSORT_COLUMN:'sortColumn',\nSORT_MULTI:'sortMulti',\nEVALUATE_FILTERS:'evaluateFilters',\nCOMPACT:'compact',\nGROUP_BY_COLUMNS:'groupByColumns',\nTOTAL:'total',\nPIVOT:'pivot',\nFACET:'facet',\nCOLUMNIZE:'columnize',\n});\nconst CONTROL=Object.freeze({\nREADY:'ready',\nCANCEL:'cancel',\nPING:'ping',\n});\nconst ERRORS=Object.freeze({\nNO_COMPUTE:'E_NO_COMPUTE',\nNO_KERNEL:'E_NO_KERNEL',\nABORTED:'E_ABORTED',\nKERNEL:'E_KERNEL',\nPROTOCOL:'E_PROTOCOL',\n});\nfunction packHandle(handle){\nif(handle==null)return null;\nconst presence=handle.presence;\nreturn{\nid:handle.id,\nkind:handle.kind,\nnullable:!!handle.nullable,\nvalues:handle.values??null,\npresence:presence?(presence.words??presence):null,\npresenceBits:presence?(presence.size??(presence.words??presence).length*8):0,\ndict:handle.dict?sliceDictionary(handle.dict):null,\noffsets:handle.offsets??null,\nversion:handle.version??0,\n};\n}\nfunction sliceDictionary(dict){\nif(Array.isArray(dict))return dict;\nif(isFunction(dict.values))return dict.values();\nreturn[];\n}\nfunction packHandles(handles){\nconst out=new Array(handles.length);\nfor(let i=0;i<handles.length;i++)out[i]=packHandle(handles[i]);\nreturn out;\n}\nclass TransportedBitset{\n#words;\n#bits;\nconstructor(words,bits){\nthis.#words=words;\nthis.#bits=bits;\n}\nget words(){return this.#words;}\nget size(){return this.#bits;}\nget(i){return(this.#words[i>>>3]&(1<<(i&7)))!==0;}\ncount(){\nconst w=this.#words;\nlet n=0;\nfor(let i=0;i<w.length;i++){\nlet v=w[i];\nwhile(v){v&=v-1;n++;}\n}\nreturn n;\n}\n}\nclass TransportedDictionary{\n#values;\n#index=null;\n#version=0;\n#ranks=new Map();\nconstructor(values){\nthis.#values=values||[];\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\ncodeOf(value){\nif(this.#index===null){\nthis.#index=new Map();\nfor(let i=0;i<this.#values.length;i++)this.#index.set(this.#values[i],i);\n}\nconst found=this.#index.get(value);\nif(found!==undefined)return found;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#index.set(value,code);\nthis.#version++;\nreturn code;\n}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nconst cached=this.#ranks.get(key);\nif(cached&&cached.version===this.#version)return cached.ranks;\nconst n=this.#values.length;\nconst order=new Uint32Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst vals=this.#values;\nconst sorted=Array.from(order).sort((a,b)=>{\nconst av=vals[a];\nconst bv=vals[b];\nif(av===bv)return 0;\nif(av===null||av===undefined)return 1;\nif(bv===null||bv===undefined)return-1;\nreturn cmp(String(av),String(bv));\n});\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<sorted.length;r++)ranks[sorted[r]]=r;\nthis.#ranks.set(key,{version:this.#version,ranks});\nreturn ranks;\n}\n}\nfunction unpackHandle(packed){\nif(packed==null)return null;\nconst presence=packed.presence\n?new TransportedBitset(packed.presence,packed.presenceBits||packed.presence.length*8)\n:null;\nconst dict=packed.dict?new TransportedDictionary(packed.dict):null;\nconst values=packed.values;\nconst offsets=packed.offsets??null;\nconst kind=packed.kind;\nconst get=(physical)=>{\nif(presence&&!presence.get(physical))return null;\nswitch(kind){\ncase'dictionary':\nreturn dict?dict.valueOf(values[physical]):values[physical];\ncase'bitset':\nreturn(values[physical>>>3]&(1<<(physical&7)))!==0;\ncase'multi':{\nif(!offsets)return null;\nconst from=offsets[physical];\nconst to=offsets[physical+1];\nconst out=new Array(to-from);\nfor(let i=from;i<to;i++)out[i-from]=dict?dict.valueOf(values[i]):values[i];\nreturn out;\n}\ndefault:\nreturn values[physical];\n}\n};\nreturn{\nid:packed.id,\nkind,\nnullable:packed.nullable,\nvalues,\npresence,\ndict,\noffsets,\nget,\nversion:packed.version,\n};\n}\nfunction unpackHandles(packed){\nconst out=new Array(packed.length);\nfor(let i=0;i<packed.length;i++)out[i]=unpackHandle(packed[i]);\nreturn out;\n}\nfunction createMaskPool(){\nconst masks=[];\nconst indices=[];\nreturn{\nmask(n){\nfor(let i=0;i<masks.length;i++){\nif(masks[i].length>=n){\nconst buf=masks.splice(i,1)[0].subarray(0,n);\nbuf.fill(0);\nreturn buf;\n}\n}\nreturn new Uint8Array(n);\n},\nindices(n){\nfor(let i=0;i<indices.length;i++){\nif(indices[i].length>=n)return indices.splice(i,1)[0].subarray(0,n);\n}\nreturn new Uint32Array(n);\n},\nrelease(buf){\nif(!buf)return;\nif(buf instanceof Uint8Array)masks.push(buf);\nelse if(buf instanceof Uint32Array)indices.push(buf);\n},\nclear(){masks.length=0;indices.length=0;},\n};\n}\nfunction isTransferable(v){\nif(!ArrayBuffer.isView(v))return false;\nconst buf=(v).buffer;\nif(!buf)return false;\nreturn typeof SharedArrayBuffer==='undefined'||!(buf instanceof SharedArrayBuffer);\n}\nfunction collectTransfers(value,out=[]){\nconst add=(v)=>{\nif(!isTransferable(v))return;\nconst buf=(v).buffer;\nif(!out.includes(buf))out.push(buf);\n};\nif(value==null)return out;\nif(ArrayBuffer.isView(value)){add(value);return out;}\nif(Array.isArray(value)){\nfor(const item of value)add(item);\nreturn out;\n}\nif(typeof value==='object'){\nfor(const key of Object.keys(value)){\nconst item=(value)[key];\nif(Array.isArray(item))for(const sub of item)add(sub);\nelse add(item);\n}\n}\nreturn out;\n}\nfunction isPortable(value,depth=0){\nif(value==null)return true;\nconst t=typeof value;\nif(t==='function'||t==='symbol')return false;\nif(t!=='object')return true;\nif(depth>4)return true;\nif(ArrayBuffer.isView(value)||value instanceof ArrayBuffer||value instanceof Date)return true;\nif(Array.isArray(value)){\nfor(const item of value)if(!isPortable(item,depth+1))return false;\nreturn true;\n}\nfor(const key of Object.keys(value)){\nif(!isPortable((value)[key],depth+1))return false;\n}\nreturn true;\n}\nfunction filterColumnIds(filters,out=new Set()){\nif(!filters||typeof filters!=='object')return out;\nconst node=(filters);\nif(typeof node.col==='string')out.add(node.col);\nconst conditions=node.conditions;\nif(Array.isArray(conditions))for(const child of conditions)filterColumnIds(child,out);\nreturn out;\n}\n});\n__def(\"packages/core/src/store/bitset.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Bitset\",{enumerable:true,get:function(){return Bitset;}});\nconst WORD_BITS=8;\nclass Bitset{\nstatic#POP=new Uint8Array(256);\nstatic{\nfor(let i=1;i<256;i++)Bitset.#POP[i]=Bitset.#POP[i>>1]+(i&1);\n}\n#words;\n#bits;\nconstructor(bits=0){\nconst n=Math.max(0,bits|0);\nthis.#bits=n;\nthis.#words=new Uint8Array(Math.ceil(n/WORD_BITS));\n}\nget size(){return this.#bits;}\nget words(){return this.#words;}\nget bytes(){return this.#words?this.#words.byteLength:0;}\nget(i){\nif(i<0||i>=this.#bits)return 0;\nreturn(this.#words[i>>3]>>(i&7))&1;\n}\nset(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]|=1<<(i&7);\nreturn this;\n}\nclear(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]&=~(1<<(i&7));\nreturn this;\n}\nassign(i,bit){return bit?this.set(i):this.clear(i);}\nfill(bit=false){\nthis.#words.fill(bit?0xff:0);\nif(bit)this.#maskTail();\nreturn this;\n}\ngrow(bits){\nconst n=Math.max(0,bits|0);\nif(n<=this.#bits)return this;\nconst need=Math.ceil(n/WORD_BITS);\nif(need>this.#words.length){\nconst next=new Uint8Array(need);\nnext.set(this.#words);\nthis.#words=next;\n}\nthis.#bits=n;\nreturn this;\n}\ncount(){\nconst w=this.#words;\nconst pop=Bitset.#POP;\nlet total=0;\nfor(let i=0;i<w.length;i++)total+=pop[w[i]];\nreturn total;\n}\nand(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]&=b[i];\nfor(let i=shared;i<w.length;i++)w[i]=0;\nreturn this;\n}\nor(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]|=b[i];\nreturn this;\n}\nnot(){\nconst w=this.#words;\nfor(let i=0;i<w.length;i++)w[i]=~w[i]&0xff;\nthis.#maskTail();\nreturn this;\n}\nclone(){\nconst out=new Bitset(this.#bits);\nout.words.set(this.#words.subarray(0,out.words.length));\nreturn out;\n}\nrelease(){\nthis.#words=new Uint8Array(0);\nthis.#bits=0;\n}\n#maskTail(){\nconst used=this.#bits&7;\nif(used===0)return;\nconst last=(this.#bits>>3);\nif(last<this.#words.length)this.#words[last]&=(1<<used)-1;\n}\nstatic from(bools){\nconst arr=Array.isArray(bools)?bools:Array.from(bools);\nconst out=new Bitset(arr.length);\nfor(let i=0;i<arr.length;i++)if(arr[i])out.set(i);\nreturn out;\n}\n}\n});\n__def(\"packages/core/src/store/dictionary.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Dictionary\",{enumerable:true,get:function(){return Dictionary;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nclass Dictionary{\n#values;\n#codes=new Map();\n#version=0;\n#ranks=null;\n#ranksVersion=-1;\n#ranksLocale='\\u0000';\nconstructor(values=[]){\nthis.#values=[];\nfor(let i=0;i<values.length;i++){\nconst v=values[i];\nif(this.#codes.has(v))continue;\nthis.#codes.set(v,this.#values.length);\nthis.#values.push(v);\n}\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\nget bytes(){\nlet total=this.#values.length*8;\nfor(let i=0;i<this.#values.length;i++){\nconst v=this.#values[i];\nif(typeof v==='string')total+=v.length*2;\ntotal+=16;\n}\nreturn total;\n}\ncodeOf(value){\nconst existing=this.#codes.get(value);\nif(existing!==undefined)return existing;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#codes.set(value,code);\nthis.#version++;\nreturn code;\n}\nlookup(value){\nconst code=this.#codes.get(value);\nreturn code===undefined?-1:code;\n}\nhas(value){return this.#codes.has(value);}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nif(this.#ranks&&this.#ranksVersion===this.#version&&this.#ranksLocale===key){\nreturn this.#ranks;\n}\nconst n=this.#values.length;\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst values=this.#values;\norder.sort((a,b)=>this.#compare(values[a],values[b],cmp));\nconst ranks=new Uint32Array(n);\nfor(let rank=0;rank<n;rank++)ranks[order[rank]]=rank;\nthis.#ranks=ranks;\nthis.#ranksVersion=this.#version;\nthis.#ranksLocale=key;\nreturn ranks;\n}\n#compare(a,b,compare){\nif(typeof a==='string'&&typeof b==='string')return compare(a,b);\nreturn defaultCompare(a,b);\n}\n}\n});\n__def(\"packages/core/src/store/multivalue.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"MultiValue\",{enumerable:true,get:function(){return MultiValue;}});\nclass MultiValue{\n#values;\n#offsets;\n#rows=0;\n#fill=0;\nconstructor(capacity={}){\nconst rows=Math.max(1,capacity.rows??16);\nconst values=Math.max(1,capacity.values??rows);\nthis.#values=new Int32Array(values);\nthis.#offsets=new Uint32Array(rows+1);\n}\nget values(){return this.#values;}\nget offsets(){return this.#offsets;}\nget rows(){return this.#rows;}\nget length(){return this.#fill;}\nget bytes(){return this.#values.byteLength+this.#offsets.byteLength;}\ncount(r){\nif(r<0||r>=this.#rows)return 0;\nreturn this.#offsets[r+1]-this.#offsets[r];\n}\nat(r){\nif(r<0||r>=this.#rows)return this.#values.subarray(0,0);\nreturn this.#values.subarray(this.#offsets[r],this.#offsets[r+1]);\n}\nhas(r,code){\nif(r<0||r>=this.#rows)return false;\nconst v=this.#values;\nconst end=this.#offsets[r+1];\nfor(let i=this.#offsets[r];i<end;i++)if(v[i]===code)return true;\nreturn false;\n}\nhasAny(r,codes){\nfor(let i=0;i<codes.length;i++)if(this.has(r,codes[i]))return true;\nreturn false;\n}\nhasAll(r,codes){\nfor(let i=0;i<codes.length;i++)if(!this.has(r,codes[i]))return false;\nreturn true;\n}\nhasNone(r,codes){return!this.hasAny(r,codes);}\npush(codes){\nconst r=this.#rows;\nconst n=codes.length;\nthis.#ensureRows(r+1);\nthis.#ensureValues(this.#fill+n);\nconst start=this.#fill;\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nthis.#fill+=n;\nthis.#rows=r+1;\nthis.#offsets[r]=start;\nthis.#offsets[r+1]=this.#fill;\nreturn r;\n}\nwrite(r,codes){\nif(r===this.#rows){this.push(codes);return;}\nif(r<0||r>this.#rows)return;\nconst start=this.#offsets[r];\nconst end=this.#offsets[r+1];\nconst n=codes.length;\nif(end-start===n){\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nreturn;\n}\nthis.#rebuild(r,codes);\n}\ncompact(remap,liveCount,dead){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst oldRows=this.#rows;\nconst values=new Int32Array(Math.max(1,this.#fill));\nconst offsets=new Uint32Array(liveCount+1);\nlet w=0;\nfor(let p=0;p<oldRows;p++){\nif(remap[p]===dead)continue;\nconst start=oldOffsets[p];\nconst end=oldOffsets[p+1];\noffsets[remap[p]]=w;\nfor(let i=start;i<end;i++)values[w++]=oldValues[i];\noffsets[remap[p]+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#rows=liveCount;\nthis.#fill=w;\n}\nrelease(){\nthis.#values=new Int32Array(0);\nthis.#offsets=new Uint32Array(1);\nthis.#rows=0;\nthis.#fill=0;\n}\n#ensureRows(rows){\nif(rows+1<=this.#offsets.length)return;\nlet cap=this.#offsets.length-1;\nwhile(cap<rows)cap=cap*2||16;\nconst next=new Uint32Array(cap+1);\nnext.set(this.#offsets);\nthis.#offsets=next;\n}\n#ensureValues(n){\nif(n<=this.#values.length)return;\nlet cap=this.#values.length;\nwhile(cap<n)cap=cap*2||16;\nconst next=new Int32Array(cap);\nnext.set(this.#values);\nthis.#values=next;\n}\n#rebuild(r,codes){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst rows=this.#rows;\nconst delta=codes.length-(oldOffsets[r+1]-oldOffsets[r]);\nconst values=new Int32Array(Math.max(1,this.#fill+delta));\nconst offsets=new Uint32Array(oldOffsets.length);\nlet w=0;\nfor(let p=0;p<rows;p++){\noffsets[p]=w;\nif(p===r){\nfor(let i=0;i<codes.length;i++)values[w++]=codes[i]|0;\n}else{\nfor(let i=oldOffsets[p];i<oldOffsets[p+1];i++)values[w++]=oldValues[i];\n}\noffsets[p+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#fill=w;\n}\n}\n});\n__def(\"packages/core/src/compute/handle.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return identity;}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return rowCount;}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return bitReader;}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return presenceReader;}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return dictSize;}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return dictValue;}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return multiValue;}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return valueReader;}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return numericTotalOrder;}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return valueComparator;}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return dictRanks;}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return isMissing;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nconst warnOnce=__m0[\"warnOnce\"];\nfunction identity(n){\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[i]=i;\nreturn out;\n}\nfunction rowCount(handle,opts){\nif(opts&&typeof opts.count==='number')return opts.count;\nif(!handle)return 0;\nif(typeof handle.count==='number')return handle.count;\nif(typeof handle.length==='number')return handle.length;\nconst values=handle.values;\nif(handle.kind==='multi'&&handle.offsets)return Math.max(0,handle.offsets.length-1);\nif(!values)return handle.presence&&typeof handle.presence.size==='number'?handle.presence.size:0;\nif(handle.kind==='bitset'){\nif(typeof values.size==='number')return values.size;\nif(handle.presence&&typeof handle.presence.size==='number')return handle.presence.size;\nwarnOnce(`count:${handle.id}`,`column \"${handle.id}\" is bitset-backed with no declared row count; assuming ${values.length*8}`);\nreturn values.length*8;\n}\nreturn values.length;\n}\nconst bitOrders=new WeakMap();\nfunction bitOrderOf(bitset){\nconst ctor=bitset.constructor;\nif(!ctor)return'unknown';\nconst cached=bitOrders.get(ctor);\nif(cached)return cached;\nlet order='unknown';\ntry{\nlet probe=null;\nif(typeof ctor.from==='function')probe=ctor.from([false,true]);\nelse{\nprobe=new ctor(8);\nprobe.set(1);\n}\nconst words=probe&&probe.words;\nif(words&&words.length){\nif(words[0]===0x02)order='lsb';\nelse if(words[0]===0x40)order='msb';\n}\n}catch{\norder='unknown';\n}\nbitOrders.set(ctor,order);\nreturn order;\n}\nfunction bitReader(bits){\nif(!bits)return()=>0;\nconst raw=bits instanceof Uint8Array?bits:bits.words;\nif(raw instanceof Uint8Array){\nconst order=bits instanceof Uint8Array?'lsb':bitOrderOf(bits);\nif(order==='lsb')return(i)=>(raw[i>>>3]>>>(i&7))&1;\nif(order==='msb')return(i)=>(raw[i>>>3]>>>(7-(i&7)))&1;\n}\nif(typeof bits.get==='function')return(i)=>(bits.get(i)?1:0);\nreturn()=>0;\n}\nfunction presenceReader(handle){\nif(!handle||!handle.presence)return null;\nreturn bitReader(handle.presence);\n}\nfunction dictSize(dict){\nif(!dict)return 0;\nif(typeof dict.size==='number')return dict.size;\nif(typeof dict.values==='function')return dict.values().length;\nreturn 0;\n}\nfunction dictValue(dict,code){\nif(!dict)return null;\nif(typeof dict.valueOf==='function')return dict.valueOf(code);\nif(typeof dict.values==='function')return dict.values()[code];\nreturn null;\n}\nfunction multiValue(handle,i){\nconst offsets=handle.offsets;\nconst values=handle.values;\nif(!offsets||!values)return[];\nconst from=offsets[i];\nconst to=offsets[i+1];\nif(!(to>from))return[];\nconst dict=handle.dict;\nconst out=new Array(to-from);\nfor(let k=from;k<to;k++)out[k-from]=dict?dictValue(dict,values[k]):values[k];\nreturn out;\n}\nfunction valueReader(handle){\nif(!handle)return()=>undefined;\nconst values=handle.values;\nconst present=presenceReader(handle);\nconst kind=handle.kind;\nif(kind==='dictionary'){\nconst dict=handle.dict;\nif(present)return(i)=>(present(i)?dictValue(dict,values[i]):null);\nreturn(i)=>dictValue(dict,values[i]);\n}\nif(kind==='bitset'){\nconst bit=bitReader(values);\nif(present)return(i)=>(present(i)?bit(i)===1:null);\nreturn(i)=>bit(i)===1;\n}\nif(kind==='multi'){\nif(present)return(i)=>(present(i)?multiValue(handle,i):null);\nreturn(i)=>multiValue(handle,i);\n}\nif(!values&&typeof handle.get==='function'){\nconst get=handle.get.bind(handle);\nreturn(i)=>{\nconst v=get(i);\nreturn v===undefined?null:v;\n};\n}\nif(present){\nreturn(i)=>{\nif(!present(i))return null;\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nreturn(i)=>{\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nfunction numericTotalOrder(a,b){\nif(a<b)return-1;\nif(a>b)return 1;\nif(a===b){\nconst na=Object.is(a,-0);\nconst nb=Object.is(b,-0);\nif(na===nb)return 0;\nreturn na?-1:1;\n}\nconst an=Number.isNaN(a);\nconst bn=Number.isNaN(b);\nif(an&&bn)return 0;\nreturn an?1:-1;\n}\nfunction valueComparator(locale){\nconst coll=collator(locale);\nreturn(a,b)=>{\nif(a===b)return 0;\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return coll.compare(a,b);\nif(ta==='number'&&tb==='number')return numericTotalOrder(a,b);\nif(ta==='boolean'&&tb==='boolean')return a===b?0:a?1:-1;\nif(a instanceof Date||b instanceof Date){\nconst na=a instanceof Date?a.getTime():Number(a);\nconst nb=b instanceof Date?b.getTime():Number(b);\nreturn numericTotalOrder(na,nb);\n}\nreturn defaultCompare(a,b);\n};\n}\nfunction dictRanks(dict,locale){\nif(dict&&typeof dict.ranks==='function')return dict.ranks(locale);\nconst table=dict&&typeof dict.values==='function'?dict.values():[];\nconst n=table.length;\nconst cmp=valueComparator(locale);\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\norder.sort((a,b)=>cmp(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<n;r++)ranks[order[r]]=r;\nreturn ranks;\n}\nfunction isMissing(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\n});\n__def(\"packages/core/src/compute/sort.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return radixSortFloat64;}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return radixSortInt32;}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return rankSortDictionary;}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return mergeSortComparator;}});\nObject.defineProperty(__exports,\"rankSortStrings\",{enumerable:true,get:function(){return rankSortStrings;}});\nObject.defineProperty(__exports,\"collateStringRanks\",{enumerable:true,get:function(){return collateStringRanks;}});\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return sortColumn;}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return sortMulti;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m0[\"bitReader\"];\nconst dictRanks=__m0[\"dictRanks\"];\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst isMissing=__m0[\"isMissing\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueComparator=__m0[\"valueComparator\"];\nconst valueReader=__m0[\"valueReader\"];\nconst EMPTY_INDICES=new Uint32Array(0);\nconst SCRATCH=new ArrayBuffer(8);\nconst SCRATCH_F64=new Float64Array(SCRATCH);\nconst SCRATCH_U32=new Uint32Array(SCRATCH);\nconst HI=(()=>{\nSCRATCH_F64[0]=-1;\nreturn(SCRATCH_U32[1]&0x80000000)!==0?1:0;\n})();\nconst LO=HI===1?0:1;\nfunction transformDouble(value,out){\nSCRATCH_F64[0]=value;\nlet hi=SCRATCH_U32[HI];\nlet lo=SCRATCH_U32[LO];\nif((hi&0x80000000)!==0){\nhi=~hi>>>0;\nlo=~lo>>>0;\n}else{\nhi=(hi^0x80000000)>>>0;\n}\nout[0]=lo;\nout[1]=hi;\n}\nfunction radixLsd64(idx,lo,hi,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*8);\nfor(let i=0;i<n;i++){\nconst l=lo[i];\nconst h=hi[i];\nhist[l&0xff]++;\nhist[256+((l>>>8)&0xff)]++;\nhist[512+((l>>>16)&0xff)]++;\nhist[768+((l>>>24)&0xff)]++;\nhist[1024+(h&0xff)]++;\nhist[1280+((h>>>8)&0xff)]++;\nhist[1536+((h>>>16)&0xff)]++;\nhist[1792+((h>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcLo=lo;\nlet srcHi=hi;\nlet dstIdx=new Uint32Array(n);\nlet dstLo=new Uint32Array(n);\nlet dstHi=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<8;pass++){\nconst base=pass<<8;\nconst shift=(pass&3)<<3;\nconst useHi=pass>=4;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst l=srcLo[i];\nconst h=srcHi[i];\nconst digit=((useHi?h:l)>>>shift)&0xff;\nconst p=offset[digit]++;\ndstIdx[p]=srcIdx[i];\ndstLo[p]=l;\ndstHi[p]=h;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcLo;srcLo=dstLo;dstLo=t;\nt=srcHi;srcHi=dstHi;dstHi=t;\n}\nreturn srcIdx;\n}\nfunction radixLsd32(idx,keys,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*4);\nfor(let i=0;i<n;i++){\nconst k=keys[i];\nhist[k&0xff]++;\nhist[256+((k>>>8)&0xff)]++;\nhist[512+((k>>>16)&0xff)]++;\nhist[768+((k>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcKeys=keys;\nlet dstIdx=new Uint32Array(n);\nlet dstKeys=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<4;pass++){\nconst base=pass<<8;\nconst shift=pass<<3;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst k=srcKeys[i];\nconst p=offset[(k>>>shift)&0xff]++;\ndstIdx[p]=srcIdx[i];\ndstKeys[p]=k;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcKeys;srcKeys=dstKeys;dstKeys=t;\n}\nreturn srcIdx;\n}\nfunction countingSort(idx,keys,n,radix){\nconst counts=new Uint32Array(radix+1);\nfor(let i=0;i<n;i++)counts[keys[i]]++;\nlet sum=0;\nfor(let k=0;k<=radix;k++){\nconst c=counts[k];\ncounts[k]=sum;\nsum+=c;\n}\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];\nreturn out;\n}\nfunction sortUint32Keys(idx,keys,n,radix){\nif(n<2)return idx;\nif(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);\nreturn radixLsd32(idx,keys,n);\n}\nfunction exact(buffer,n){\nif(buffer.length===n&&buffer.byteOffset===0)return buffer;\nreturn Uint32Array.prototype.slice.call(buffer,0,n);\n}\nfunction radixSortFloat64(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=new Uint32Array(n);\nconst lo=new Uint32Array(n);\nconst hi=new Uint32Array(n);\nconst nans=new Uint32Array(n);\nconst pair=new Uint32Array(2);\nlet m=0;\nlet nanCount=0;\nfor(let i=0;i<n;i++){\nconst row=src[i];\nconst v=values[row];\nif(Number.isNaN(v)){nans[nanCount++]=row;continue;}\ntransformDouble(v,pair);\nif(descending){\nlo[m]=~pair[0]>>>0;\nhi[m]=~pair[1]>>>0;\n}else{\nlo[m]=pair[0];\nhi[m]=pair[1];\n}\nidx[m++]=row;\n}\nconst sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);\nif(nanCount===0)return exact(sorted,m);\nconst out=new Uint32Array(n);\nout.set(sorted.subarray(0,m),0);\nout.set(nans.subarray(0,nanCount),m);\nreturn out;\n}\nfunction radixSortInt32(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst k=(values[idx[i]]^0x80000000)>>>0;\nkeys[i]=descending?(~k>>>0):k;\n}\nreturn exact(radixLsd32(idx,keys,n),n);\n}\nfunction rankSortDictionary(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst ranks=dictRanks(handle.dict,opts.locale);\nconst codes=handle.values;\nconst present=presenceReader(handle);\nconst size=Math.max(dictSize(handle.dict),ranks.length);\nconst absentRank=size;\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nconst descending=!!opts.descending;\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nlet rank=present&&present(row)===0?absentRank:ranks[codes[row]];\nif(rank===undefined)rank=absentRank;\nkeys[i]=descending?absentRank-rank:rank;\n}\nreturn exact(sortUint32Keys(idx,keys,n,size+1),n);\n}\nfunction mergeSortComparator(values,order,compare){\nconst n=order.length;\nlet src=Uint32Array.from(order);\nif(n<2)return src;\nlet dst=new Uint32Array(n);\nfor(let width=1;width<n;width<<=1){\nfor(let start=0;start<n;start+=width<<1){\nconst mid=Math.min(start+width,n);\nconst end=Math.min(start+(width<<1),n);\nlet i=start;\nlet j=mid;\nlet k=start;\nwhile(i<mid&&j<end){\ndst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];\n}\nwhile(i<mid)dst[k++]=src[i++];\nwhile(j<end)dst[k++]=src[j++];\n}\nconst t=src;src=dst;dst=t;\n}\nreturn src;\n}\nfunction sortBitsetColumn(handle,idx,descending){\nconst bit=bitReader(handle.values);\nconst n=idx.length;\nconst out=new Uint32Array(n);\nconst first=descending?1:0;\nlet k=0;\nfor(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];\nfor(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];\nreturn out;\n}\nfunction indexableValues(handle,idx){\nconst values=handle.values;\nconst kind=handle.kind;\nconst direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));\nif(direct&&!handle.presence)return values;\nconst reader=valueReader(handle);\nconst materialised=new Array(rowCount(handle)||0);\nfor(let i=0;i<idx.length;i++){\nconst row=idx[i];\nmaterialised[row]=reader(row);\n}\nreturn materialised;\n}\nfunction allStrings(values,idx){\nfor(let i=0;i<idx.length;i++){\nif(typeof values[idx[i]]!=='string')return false;\n}\nreturn true;\n}\nfunction rankSortStrings(idx,codes,ranks,d,descending){\nconst n=idx.length;\nconst idxOut=Uint32Array.from(idx);\nif(n<2||d<1)return idxOut;\nconst keys=new Uint32Array(n);\nconst top=d-1;\nfor(let i=0;i<n;i++){\nconst rank=ranks[codes[i]];\nkeys[i]=descending?top-rank:rank;\n}\nreturn exact(sortUint32Keys(idxOut,keys,n,d),n);\n}\nfunction collateStringRanks(table,d,locale){\nconst compare=valueComparator(locale);\nconst order=new Array(d);\nfor(let i=0;i<d;i++)order[i]=i;\norder.sort((a,b)=>compare(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(d);\nfor(let r=0;r<d;r++)ranks[order[r]]=r;\nreturn ranks;\n}\nfunction keyedSortStrings(values,idx,opts){\nconst n=idx.length;\nconst codeOf=new Map();\nconst table=[];\nconst codes=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst v=values[idx[i]];\nlet c=codeOf.get(v);\nif(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}\ncodes[i]=c;\n}\nconst d=table.length;\nconst ranks=collateStringRanks(table,d,opts.locale);\nreturn rankSortStrings(idx,codes,ranks,d,!!opts.descending);\n}\nfunction sortByComparator(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nif(idx.length>=2&&allStrings(values,idx)){\nconst index=handle.stringRank;\nif(index&&index.version===handle.version&&index.usable(idx,values,opts.locale)){\nreturn index.sort(idx,opts);\n}\nreturn keyedSortStrings(values,idx,opts);\n}\nconst base=valueComparator(opts.locale);\nconst compare=opts.descending?(a,b)=>base(b,a):base;\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction sortByCompare(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nconst user=opts.compare;\nconst descending=!!opts.descending;\nconst compare=descending\n?(a,b)=>-user(a,b,undefined,undefined,true)\n:(a,b)=>user(a,b,undefined,undefined,false);\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction partitionPresent(handle,idx){\nconst n=idx.length;\nconst present=presenceReader(handle);\nconst values=handle.values;\nconst checkNaN=handle.kind==='float64'&&!!values;\nconst looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;\nif(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};\nconst keep=new Uint32Array(n);\nconst drop=new Uint32Array(n);\nlet p=0;\nlet a=0;\nif(present&&checkNaN){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(checkNaN&&!present){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(present&&!looseKind){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1)keep[p++]=row;else drop[a++]=row;\n}\n}else{\nconst reader=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;\n}\n}\nif(a===0)return{present:idx,absent:EMPTY_INDICES};\nreturn{present:keep.subarray(0,p),absent:drop.subarray(0,a)};\n}\nfunction joinRuns(sorted,absent,nullsFirst){\nif(absent.length===0)return sorted;\nconst out=new Uint32Array(sorted.length+absent.length);\nif(nullsFirst){\nout.set(absent,0);\nout.set(sorted,absent.length);\n}else{\nout.set(sorted,0);\nout.set(absent,sorted.length);\n}\nreturn out;\n}\nfunction sortColumn(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nif(!handle||src.length<2)return Uint32Array.from(src);\nconst{present,absent}=partitionPresent(handle,src);\nif(present.length===0)return Uint32Array.from(src);\nconst descending=!!opts.descending;\nlet sorted;\nif(typeof opts.compare==='function'){\nsorted=sortByCompare(handle,present,opts);\n}else{\nswitch(handle.kind){\ncase'float64':\nsorted=radixSortFloat64(handle.values,present,descending);\nbreak;\ncase'int32':\nsorted=radixSortInt32(handle.values,present,descending);\nbreak;\ncase'dictionary':\nsorted=rankSortDictionary(handle,present,opts);\nbreak;\ncase'bitset':\nsorted=sortBitsetColumn(handle,present,descending);\nbreak;\ndefault:\nsorted=sortByComparator(handle,present,opts);\nbreak;\n}\n}\nreturn joinRuns(sorted,absent,!!opts.nullsFirst);\n}\nfunction sortMulti(handles,entries,order,opts={}){\nconst list=entries||[];\nconst first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);\nlet current=order||identity(rowCount(first,opts));\nfor(let i=list.length-1;i>=0;i--){\nconst entry=list[i];\nconst handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);\nif(!handle)continue;\ncurrent=sortColumn(handle,current,{\ndescending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',\nnullsFirst:!!entry.nullsFirst,\nlocale:entry.locale!==undefined?entry.locale:opts.locale,\ncompare:entry.compare,\n});\n}\nreturn current instanceof Uint32Array?current:Uint32Array.from(current);\n}\nfunction byId(handles,id){\nif(!handles||id===undefined)return undefined;\nfor(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];\nreturn undefined;\n}\n});\n__def(\"packages/core/src/store/stringrank.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"DEFAULT_MAX_DISTINCT\",{enumerable:true,get:function(){return DEFAULT_MAX_DISTINCT;}});\nObject.defineProperty(__exports,\"StringRankIndex\",{enumerable:true,get:function(){return StringRankIndex;}});\nconst __m0=__req(\"packages/core/src/compute/sort.js\");\nconst collateStringRanks=__m0[\"collateStringRanks\"];\nconst rankSortStrings=__m0[\"rankSortStrings\"];\nconst DEFAULT_MAX_DISTINCT=100000;\nclass StringRankIndex{\n#table=[];\n#codeOf=new Map();\n#codeByRow;\n#length=0;\n#generation=0;\n#stamp=-1;\n#maxDistinct;\n#capped=false;\n#ranks=null;\n#ranksGeneration=-1;\n#ranksLocale='\\u0000';\nconstructor(maxDistinct=DEFAULT_MAX_DISTINCT){\nthis.#maxDistinct=maxDistinct>0?maxDistinct:DEFAULT_MAX_DISTINCT;\nthis.#codeByRow=new Uint32Array(0);\n}\nget version(){return this.#stamp;}\nset version(version){this.#stamp=version;}\nget generation(){return this.#generation;}\nget size(){return this.#table.length;}\nget capped(){return this.#capped;}\nget length(){return this.#length;}\nget bytes(){\nlet total=this.#codeByRow.byteLength;\nconst table=this.#table;\nfor(let i=0;i<table.length;i++)total+=table[i].length*2+24;\nreturn total;\n}\n#intern(value,capOnGrowth){\nconst existing=this.#codeOf.get(value);\nif(existing!==undefined)return existing;\nif(this.#capped)return-1;\nif(capOnGrowth&&this.#table.length>=this.#maxDistinct){\nthis.#capped=true;\nreturn-1;\n}\nconst code=this.#table.length;\nthis.#table.push(value);\nthis.#codeOf.set(value,code);\nthis.#generation++;\nreturn code;\n}\nbuild(values,count){\nconst n=count|0;\nthis.#table=[];\nthis.#codeOf=new Map();\nthis.#generation=0;\nthis.#capped=false;\nthis.#ranks=null;\nthis.#ranksGeneration=-1;\nthis.#codeByRow=new Uint32Array(n);\nfor(let row=0;row<n;row++){\nconst v=values[row];\nconst code=typeof v==='string'?this.#intern(v,false):-1;\nthis.#codeByRow[row]=code<0?0:code;\n}\nthis.#length=n;\n}\nappend(values,from,count){\nconst to=(from|0)+(count|0);\nif(to>this.#codeByRow.length){\nconst next=new Uint32Array(to);\nnext.set(this.#codeByRow.subarray(0,this.#length));\nthis.#codeByRow=next;\n}\nfor(let row=from|0;row<to;row++){\nconst v=values[row];\nconst code=typeof v==='string'?this.#intern(v,true):-1;\nthis.#codeByRow[row]=code<0?0:code;\n}\nthis.#length=Math.max(this.#length,to);\n}\nranks(locale){\nconst key=locale||'';\nif(this.#ranks&&this.#ranksGeneration===this.#generation&&this.#ranksLocale===key){\nreturn this.#ranks;\n}\nconst ranks=collateStringRanks(this.#table,this.#table.length,locale);\nthis.#ranks=ranks;\nthis.#ranksGeneration=this.#generation;\nthis.#ranksLocale=key;\nreturn ranks;\n}\nusable(idx,values,locale){\nif(this.#capped||this.#table.length===0)return false;\nconst codeByRow=this.#codeByRow;\nconst table=this.#table;\nconst covered=this.#length;\nfor(let i=0;i<idx.length;i++){\nconst row=idx[i];\nif(row>=covered)return false;\nif(table[codeByRow[row]]!==values[row])return false;\n}\nreturn true;\n}\nsort(idx,opts){\nconst ranks=this.ranks(opts.locale);\nconst d=this.#table.length;\nconst n=idx.length;\nconst codes=new Uint32Array(n);\nconst codeByRow=this.#codeByRow;\nfor(let i=0;i<n;i++)codes[i]=codeByRow[idx[i]];\nreturn rankSortStrings(idx,codes,ranks,d,!!opts.descending);\n}\n}\n});\n__def(\"packages/core/src/store/columnstore.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"REMOVED\",{enumerable:true,get:function(){return REMOVED;}});\nObject.defineProperty(__exports,\"toFloat\",{enumerable:true,get:function(){return toFloat;}});\nObject.defineProperty(__exports,\"ColumnHandle\",{enumerable:true,get:function(){return ColumnHandle;}});\nObject.defineProperty(__exports,\"ColumnStore\",{enumerable:true,get:function(){return ColumnStore;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/bitset.js\");\nconst Bitset=__m1[\"Bitset\"];\nconst __m2=__req(\"packages/core/src/store/dictionary.js\");\nconst Dictionary=__m2[\"Dictionary\"];\nconst __m3=__req(\"packages/core/src/store/multivalue.js\");\nconst MultiValue=__m3[\"MultiValue\"];\nconst __m4=__req(\"packages/core/src/store/stringrank.js\");\nconst StringRankIndex=__m4[\"StringRankIndex\"];\nconst REMOVED=0xFFFFFFFF;\nconst DEFAULT_CAPACITY=1024;\nconst DEFAULT_COLUMNAR_BELOW=5000;\nconst DEFAULT_COMPACT_RATIO=0.2;\nconst KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction absent(v){return v===null||v===undefined;}\nfunction toFloat(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(typeof v==='boolean')return v?1:0;\nconst n=Number(v);\nreturn Number.isNaN(n)&&typeof v==='string'?Date.parse(v):n;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(absent(v))return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction decodeFrom(old,p){\nswitch(old.kind){\ncase'float64':\ncase'int32':return old.buf[p];\ncase'bitset':return old.bits.get(p)===1;\ncase'dictionary':return old.dict.valueOf(old.buf[p]);\ncase'multi':{\nconst codes=old.mv.at(p);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=old.dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return old.buf[p];\n}\n}\nfunction decodePacked(frag,i){\nswitch(frag.kind){\ncase'float64':\ncase'int32':return frag.values[i];\ncase'bitset':return(frag.values[i>>3]&(1<<(i&7)))!==0;\ncase'dictionary':return(frag.table||[])[frag.values[i]];\ncase'multi':{\nconst start=frag.offsets[i];\nconst end=frag.offsets[i+1];\nconst table=frag.table||[];\nconst out=new Array(end-start);\nfor(let k=start;k<end;k++)out[k-start]=table[frag.values[k]];\nreturn out;\n}\ndefault:return frag.values[i];\n}\n}\nclass ColumnHandle{\n#id;\n#kind;\n#target;\n#nullable;\n#read;\n#host;\n#seed;\n#columnar=false;\n#buf=null;\n#bits=null;\n#mv=null;\n#dict=null;\n#stringRank=null;\n#stringRankOn;\n#stringRankMax;\n#stringRankVersion=-1;\n#presence=null;\n#capacity=0;\n#version=0;\n#overlay=null;\n#cache=null;\n#released=false;\nconstructor(schema,host){\nthis.#id=schema.id;\nconst kind=KINDS.has(schema.kind)?schema.kind:'object';\nif(schema.kind&&!KINDS.has(schema.kind)){\nwarnOnce(`store.kind.${schema.id}`,\n`column \"${schema.id}\" declares unknown storage kind \"${schema.kind}\"; falling back to object`);\n}\nthis.#target=kind;\nthis.#kind=kind;\nthis.#nullable=schema.nullable!==false;\nthis.#seed=schema.dictionary??null;\nthis.#host=host;\nthis.#read=isFunction(schema.read)\n?schema.read\n:pathGetter(schema.field||schema.id);\nthis.#stringRankOn=schema.stringRankIndex!=='off';\nthis.#stringRankMax=typeof schema.stringRankMaxDistinct==='number'\n?schema.stringRankMaxDistinct\n:0;\nthis.#overlay=new Map();\n}\nget id(){return this.#id;}\nget kind(){return this.#columnar?this.#kind:'object';}\nget target(){return this.#target;}\nget nullable(){return this.#nullable;}\nget values(){\nif(this.#released)return null;\nif(!this.#columnar)return this.#lazy().values;\nif(this.#kind==='bitset')return this.#bits.words;\nif(this.#kind==='multi')return this.#mv.values;\nreturn this.#buf;\n}\nget presence(){\nif(this.#released||!this.#nullable)return null;\nreturn this.#columnar?this.#presence:this.#lazy().presence;\n}\nget dict(){\nif(this.#released||!this.#columnar)return null;\nreturn this.#kind==='dictionary'||this.#kind==='multi'?this.#dict:null;\n}\nget stringRank(){\nif(this.#released||!this.#stringRankOn)return null;\nif(this.kind!=='object')return null;\nconst values=this.values;\nconst n=this.#host.physical();\nif(!values||n===0)return null;\nif(this.#stringRank===null){\nif(typeof values[0]!=='string')return null;\nconst index=new StringRankIndex(this.#resolveStringRankMax());\nindex.build(values,n);\nindex.version=this.#version;\nthis.#stringRank=index;\nthis.#stringRankVersion=this.#version;\nreturn index.capped?null:index;\n}\nif(this.#stringRank.length<n){\nthis.#stringRank.append(values,this.#stringRank.length,n-this.#stringRank.length);\n}\nthis.#stringRank.version=this.#version;\nthis.#stringRankVersion=this.#version;\nreturn this.#stringRank.capped?null:this.#stringRank;\n}\n#resolveStringRankMax(){return this.#stringRankMax;}\n#dropStringRank(){\nthis.#stringRank=null;\nthis.#stringRankVersion=-1;\n}\nget offsets(){\nif(this.#released||!this.#columnar||this.#kind!=='multi')return null;\nreturn this.#mv.offsets;\n}\nget version(){return this.#version;}\nget bytes(){\nlet total=0;\nif(this.#buf)total+=this.#buf.byteLength??this.#buf.length*8;\nif(this.#bits)total+=this.#bits.bytes;\nif(this.#mv)total+=this.#mv.bytes;\nif(this.#presence)total+=this.#presence.bytes;\nif(this.#dict)total+=this.#dict.bytes;\nif(this.#overlay)total+=this.#overlay.size*24;\nreturn total;\n}\nget(physical){\nif(this.#released)return undefined;\nif(physical<0||physical>=this.#host.physical())return undefined;\nif(!this.#columnar)return this.#rowValue(physical);\nif(this.#nullable&&this.#presence.get(physical)===0)return null;\nswitch(this.#kind){\ncase'float64':\ncase'int32':return this.#buf[physical];\ncase'bitset':return this.#bits.get(physical)===1;\ncase'dictionary':return this.#dict.valueOf(this.#buf[physical]);\ncase'multi':{\nconst codes=this.#mv.at(physical);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=this.#dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return this.#buf[physical];\n}\n}\nset(physical,value){\nif(this.#released)return;\nif(this.#columnar)this.#writeValue(physical,value);\nelse this.#overlay.set(physical,value===undefined?null:value);\nif(this.#stringRank)this.#dropStringRank();\nthis.#version++;\n}\nread(row){return this.#read(row);}\nappendColumn(objects,from,n){\nif(this.#released||n<=0)return;\nif(!this.#columnar){this.#version++;return;}\nconst read=this.#read;\nconst nullable=this.#nullable;\nconst presence=this.#presence;\nlet sawAbsent=false;\nswitch(this.#kind){\ncase'float64':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nif(typeof v==='number'){\nif(nullable)presence.set(from+i);\nbuf[from+i]=v;\ncontinue;\n}\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?NaN:toFloat(v);\n}\nbreak;\n}\ncase'int32':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:toInt(v);\n}\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbits.assign(from+i,!gone&&!!v);\n}\nbreak;\n}\ncase'dictionary':{\nconst buf=this.#buf;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:dict.codeOf(v);\n}\nbreak;\n}\ncase'multi':{\nconst mv=this.#mv;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nconst members=toMembers(v);\nconst codes=new Array(members.length);\nfor(let k=0;k<members.length;k++)codes[k]=dict.codeOf(members[k]);\nmv.write(from+i,codes);\n}\nbreak;\n}\ndefault:{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?null:v;\n}\nbreak;\n}\n}\nif(sawAbsent){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nif(this.#stringRank&&this.#kind==='object'){\nthis.#stringRank.append(this.#buf,from,n);\nthis.#stringRank.version=this.#version+1;\nthis.#stringRankVersion=this.#version+1;\n}\nthis.#version++;\n}\nappendPacked(frag,from,n){\nif(this.#released||n<=0||!frag)return;\nif(!this.#columnar){this.#version++;return;}\nconst presence=this.#presence;\nconst fragPresence=frag.presence;\nif(presence){\nif(fragPresence){\nfor(let i=0;i<n;i++)presence.assign(from+i,(fragPresence[i>>3]&(1<<(i&7)))!==0);\n}else{\nfor(let i=0;i<n;i++)presence.set(from+i);\n}\n}\nconst kindsAgree=frag.kind===this.#kind;\nif(kindsAgree&&(this.#kind==='float64'||this.#kind==='int32')){\nthis.#buf.set(frag.values,from);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='bitset'){\nconst words=frag.values;\nfor(let i=0;i<n;i++)this.#bits.assign(from+i,(words[i>>3]&(1<<(i&7)))!==0);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='dictionary'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst codes=frag.values;\nconst buf=this.#buf;\nconst pres=presence;\nfor(let i=0;i<n;i++){\nif(pres&&(fragPresence?(fragPresence[i>>3]&(1<<(i&7)))===0:false)){buf[from+i]=0;continue;}\nbuf[from+i]=remap[codes[i]]??0;\n}\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='multi'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst flat=frag.values;\nconst offsets=frag.offsets;\nfor(let i=0;i<n;i++){\nconst start=offsets[i];\nconst end=offsets[i+1];\nconst codes=new Array(end-start);\nfor(let k=start;k<end;k++)codes[k-start]=remap[flat[k]]??0;\nthis.#mv.write(from+i,codes);\n}\nthis.#version++;\nreturn;\n}\nfor(let i=0;i<n;i++){\nconst gone=fragPresence\n?(fragPresence[i>>3]&(1<<(i&7)))===0\n:(frag.kind==='object'?frag.values[i]===null:false);\nthis.#writeValue(from+i,gone?null:decodePacked(frag,i));\n}\nthis.#version++;\n}\ntouch(){this.#version++;}\ncolumnarise(capacity,fill){\nif(this.#columnar||this.#released)return;\nconst values=new Array(fill);\nfor(let p=0;p<fill;p++)values[p]=this.#rowValue(p);\nthis.#kind=this.#target;\nthis.#columnar=true;\nthis.#alloc(capacity);\nfor(let p=0;p<fill;p++)this.#writeValue(p,values[p]);\nthis.#overlay.clear();\nthis.#cache=null;\nthis.#dropStringRank();\nthis.#version++;\n}\ngrow(capacity){\nif(!this.#columnar||this.#released||capacity<=this.#capacity)return;\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':{\nconst next=new this.#buf.constructor(capacity);\nnext.set(this.#buf);\nthis.#buf=next;\nbreak;\n}\ncase'bitset':this.#bits.grow(capacity);break;\ncase'multi':break;\ndefault:this.#buf.length=capacity;break;\n}\nif(this.#presence)this.#presence.grow(capacity);\nthis.#capacity=capacity;\nthis.#version++;\n}\nconvert(kind){\nif(this.#released||!KINDS.has(kind))return false;\nthis.#target=kind;\nif(!this.#columnar||kind===this.#kind)return false;\nconst old={kind:this.#kind,buf:this.#buf,bits:this.#bits,mv:this.#mv,dict:this.#dict};\nconst n=this.#host.physical();\nconst presence=this.#presence;\nthis.#kind=kind;\nthis.#alloc(this.#capacity);\nfor(let p=0;p<n;p++){\nconst gone=presence!==null&&presence.get(p)===0;\nif(gone&&kind!=='multi')continue;\nthis.#writeValue(p,gone?null:decodeFrom(old,p));\n}\nthis.#dropStringRank();\nthis.#version++;\nreturn true;\n}\ncompact(remap,oldFill,liveCount){\nif(this.#released)return;\nthis.#dropStringRank();\nif(!this.#columnar){\nconst overlay=this.#overlay;\nif(overlay.size){\nconst next=new Map();\nfor(const[p,v]of overlay)if(remap[p]!==REMOVED)next.set(remap[p],v);\nthis.#overlay=next;\n}\nthis.#cache=null;\nthis.#version++;\nreturn;\n}\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':case'object':{\nconst buf=this.#buf;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)buf[remap[p]]=buf[p];\nif(this.#kind==='object')for(let p=liveCount;p<oldFill;p++)buf[p]=undefined;\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)bits.assign(remap[p],bits.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)bits.clear(p);\nbreak;\n}\ncase'multi':this.#mv.compact(remap,liveCount,REMOVED);break;\ndefault:break;\n}\nif(this.#presence){\nconst pres=this.#presence;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)pres.assign(remap[p],pres.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)pres.clear(p);\n}\nthis.#version++;\n}\nrelease(){\nif(this.#released)return;\nthis.#released=true;\nthis.#buf=null;\nif(this.#bits)this.#bits.release();\nthis.#bits=null;\nif(this.#mv)this.#mv.release();\nthis.#mv=null;\nif(this.#presence)this.#presence.release();\nthis.#presence=null;\nthis.#dict=null;\nthis.#stringRank=null;\nthis.#overlay=new Map();\nthis.#cache=null;\nthis.#capacity=0;\nthis.#version++;\n}\n#alloc(capacity){\nconst cap=Math.max(1,capacity);\nthis.#buf=null;\nthis.#bits=null;\nthis.#mv=null;\nswitch(this.#kind){\ncase'float64':this.#buf=new Float64Array(cap);break;\ncase'int32':this.#buf=new Int32Array(cap);break;\ncase'bitset':this.#bits=new Bitset(cap);break;\ncase'dictionary':\nthis.#buf=new Uint32Array(cap);\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ncase'multi':\nthis.#mv=new MultiValue({rows:cap,values:cap});\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ndefault:this.#buf=new Array(cap);break;\n}\nif(this.#kind!=='dictionary'&&this.#kind!=='multi')this.#dict=null;\nif(this.#nullable){\nif(this.#presence)this.#presence.grow(cap);\nelse this.#presence=new Bitset(cap);\n}\nthis.#capacity=cap;\n}\n#writeValue(p,value){\nconst gone=absent(value);\nif(this.#nullable)this.#presence.assign(p,!gone);\nelse if(gone){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nswitch(this.#kind){\ncase'float64':this.#buf[p]=gone?NaN:toFloat(value);break;\ncase'int32':this.#buf[p]=gone?0:toInt(value);break;\ncase'bitset':this.#bits.assign(p,!gone&&!!value);break;\ncase'dictionary':this.#buf[p]=gone?0:this.#dict.codeOf(value);break;\ncase'multi':{\nconst members=toMembers(value);\nconst codes=new Array(members.length);\nfor(let i=0;i<members.length;i++)codes[i]=this.#dict.codeOf(members[i]);\nthis.#mv.write(p,codes);\nbreak;\n}\ndefault:this.#buf[p]=gone?null:value;break;\n}\n}\n#rowValue(p){\nif(this.#overlay.has(p))return this.#overlay.get(p);\nconst v=this.#read(this.#host.rowAt(p));\nreturn v===undefined?null:v;\n}\n#lazy(){\nif(this.#cache&&this.#cache.version===this.#version)return this.#cache;\nconst n=this.#host.physical();\nconst values=new Array(n);\nconst presence=this.#nullable?new Bitset(n):null;\nfor(let p=0;p<n;p++){\nconst v=this.#rowValue(p);\nvalues[p]=v;\nif(presence&&!absent(v))presence.set(p);\n}\nthis.#cache={version:this.#version,values,presence};\nreturn this.#cache;\n}\n}\nclass ColumnStore{\n#schema;\n#handles=new Map();\n#list=[];\n#rows=[];\n#fill=0;\n#capacity=0;\n#live=0;\n#dead=0;\n#tombs=new Bitset(0);\n#columnar=false;\n#retainSource=true;\n#columnarBelow;\n#initial;\n#ratio;\n#destroyed=false;\nconstructor(schema,opts={}){\nthis.#schema=Array.isArray(schema)?schema:[];\nthis.#initial=Math.max(1,opts.initialCapacity??DEFAULT_CAPACITY);\nthis.#retainSource=opts.retainSource!==false;\nthis.#columnarBelow=this.#retainSource?(opts.columnarBelow??DEFAULT_COLUMNAR_BELOW):0;\nthis.#ratio=opts.compactRatio??DEFAULT_COMPACT_RATIO;\nconst host={\nrowAt:(p)=>this.#rows[p],\nphysical:()=>this.#fill,\n};\nfor(const entry of this.#schema){\nif(!entry||!entry.id)continue;\nif(this.#handles.has(entry.id)){\nwarnOnce(`store.dup.${entry.id}`,`duplicate column id \"${entry.id}\" in the store schema; ignoring the second`);\ncontinue;\n}\nconst handle=new ColumnHandle(entry,host);\nthis.#handles.set(entry.id,handle);\nthis.#list.push(handle);\n}\nif(this.#columnarBelow<=0)this.#columnarise();\n}\nget count(){return this.#live;}\nget physical(){return this.#fill;}\nget capacity(){return this.#columnar?this.#capacity:this.#rows.length;}\nget tombstones(){return this.#dead;}\nget columnar(){return this.#columnar;}\nget destroyed(){return this.#destroyed;}\nget bytes(){\nlet total=this.#tombs.bytes+this.#rows.length*8;\nfor(const h of this.#list)total+=h.bytes;\nreturn total;\n}\nappend(objects){\nconst from=this.#fill;\nif(this.#destroyed||!objects)return{from,to:from};\nconst n=objects.length|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource)for(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar){\nif(this.#fill>=this.#columnarBelow)this.#columnarise();\nelse for(const h of this.#list)h.touch();\nreturn{from,to:this.#fill};\n}\nthis.#ensure(this.#fill);\nconst cols=this.#list;\nfor(let c=0;c<cols.length;c++)cols[c].appendColumn(objects,from,n);\nreturn{from,to:this.#fill};\n}\nappendPacked(chunk,objects){\nconst from=this.#fill;\nif(this.#destroyed||!chunk)return{from,to:from};\nconst n=chunk.count|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource&&objects){\nfor(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\n}\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar)this.#columnarise();\nthis.#ensure(this.#fill);\nconst byId=new Map();\nfor(const col of chunk.columns)byId.set(col.id,col);\nfor(const h of this.#list){\nconst frag=byId.get(h.id);\nif(frag)h.appendPacked(frag,from,n);\nelse{\nh.grow(this.#capacity);\n}\n}\nreturn{from,to:this.#fill};\n}\nsource(physical){\nif(this.#retainSource)return this.#rows[physical];\nif(physical<0||physical>=this.#fill)return undefined;\nreturn this.#reconstruct(physical);\n}\nsetSource(physical,object){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nif(!this.#retainSource)return;\nthis.#rows[physical]=object;\n}\nget(colId,physical){\nconst h=this.#handles.get(colId);\nreturn h?h.get(physical):undefined;\n}\nset(colId,physical,value){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nconst h=this.#handles.get(colId);\nif(!h){\nwarnOnce(`store.set.${colId}`,`set() on unknown column \"${colId}\"`);\nreturn;\n}\nh.set(physical,value);\n}\nremove(physical){\nif(this.#destroyed||physical<0||physical>=this.#fill)return false;\nif(this.#tombs.get(physical)===1)return false;\nthis.#tombs.set(physical);\nthis.#dead++;\nthis.#live--;\nreturn true;\n}\nlive(physical){\nif(physical<0||physical>=this.#fill)return false;\nreturn this.#tombs.get(physical)===0;\n}\ncompact(opts={}){\nif(this.#destroyed||this.#dead===0)return null;\nif(!opts.force&&this.#dead/this.#fill<this.#ratio)return null;\nconst oldFill=this.#fill;\nconst remap=new Uint32Array(oldFill);\nlet w=0;\nfor(let p=0;p<oldFill;p++)remap[p]=this.#tombs.get(p)===1?REMOVED:w++;\nfor(const h of this.#list)h.compact(remap,oldFill,w);\nif(this.#retainSource){\nconst rows=this.#rows;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)rows[remap[p]]=rows[p];\nrows.length=w;\n}\nthis.#fill=w;\nthis.#live=w;\nthis.#dead=0;\nthis.#tombs=new Bitset(Math.max(this.#capacity,w));\nreturn remap;\n}\ncolumn(colId){return this.#handles.get(colId);}\ncolumns(){return this.#list.slice();}\nliveIndices(){\nconst out=new Uint32Array(this.#live);\nif(this.#dead===0){\nfor(let p=0;p<this.#fill;p++)out[p]=p;\nreturn out;\n}\nlet k=0;\nfor(let p=0;p<this.#fill;p++)if(this.#tombs.get(p)===0)out[k++]=p;\nreturn out;\n}\nconvert(colId,kind){\nconst h=this.#handles.get(colId);\nreturn h?h.convert(kind):false;\n}\ndestroy(){\nif(this.#destroyed)return;\nthis.#destroyed=true;\nfor(const h of this.#list)h.release();\nthis.#handles.clear();\nthis.#list.length=0;\nthis.#rows.length=0;\nthis.#tombs.release();\nthis.#fill=0;\nthis.#live=0;\nthis.#dead=0;\nthis.#capacity=0;\n}\n#ensure(n){\nif(n<=this.#capacity)return;\nlet cap=this.#capacity||this.#initial;\nwhile(cap<n)cap*=2;\nfor(const h of this.#list)h.grow(cap);\nthis.#tombs.grow(cap);\nthis.#capacity=cap;\n}\n#reconstruct(physical){\nconst out={};\nfor(const h of this.#list)out[h.id]=h.get(physical);\nreturn out;\n}\n#columnarise(){\nif(this.#columnar)return;\nlet cap=this.#initial;\nwhile(cap<this.#fill)cap*=2;\nthis.#columnar=true;\nthis.#capacity=cap;\nthis.#tombs.grow(cap);\nfor(const h of this.#list)h.columnarise(cap,this.#fill);\n}\n}\n});\n__def(\"packages/core/src/store/ingest.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"INGEST_DEFAULTS\",{enumerable:true,get:function(){return INGEST_DEFAULTS;}});\nObject.defineProperty(__exports,\"inferKind\",{enumerable:true,get:function(){return inferKind;}});\nObject.defineProperty(__exports,\"decideText\",{enumerable:true,get:function(){return decideText;}});\nObject.defineProperty(__exports,\"createReaders\",{enumerable:true,get:function(){return createReaders;}});\nObject.defineProperty(__exports,\"Ingest\",{enumerable:true,get:function(){return Ingest;}});\nObject.defineProperty(__exports,\"ingest\",{enumerable:true,get:function(){return ingest;}});\nObject.defineProperty(__exports,\"ingestSync\",{enumerable:true,get:function(){return ingestSync;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst now=__m0[\"now\"];\nconst nextFrame=__m0[\"nextFrame\"];\nconst infoOnce=__m0[\"infoOnce\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/columnstore.js\");\nconst ColumnStore=__m1[\"ColumnStore\"];\nconst INGEST_DEFAULTS=Object.freeze({\nchunkMs:8,\nchunkRows:512,\nsampleSize:100,\ndictionaryRatio:0.1,\ncolumnarBelow:5000,\ninitialCapacity:1024,\n});\nfunction inferKind(samples,hints={}){\nif(hints.multi)return'multi';\nif(samples.length===0)return'object';\nlet numbers=0;let booleans=0;let strings=0;let dates=0;let arrays=0;\nfor(let i=0;i<samples.length;i++){\nconst v=samples[i];\nif(typeof v==='number')numbers++;\nelse if(typeof v==='boolean')booleans++;\nelse if(typeof v==='string')strings++;\nelse if(v instanceof Date)dates++;\nelse if(Array.isArray(v))arrays++;\n}\nconst n=samples.length;\nif(numbers===n)return'float64';\nif(booleans===n)return'bitset';\nif(dates===n)return'float64';\nif(strings===n)return'text';\nif(arrays===n)return'multi';\nreturn'object';\n}\nfunction decideText(distinct,rows,ratio){\nif(rows<=0)return'dictionary';\nreturn distinct<ratio*rows?'dictionary':'object';\n}\nfunction createReaders(columns,computed,context){\nconst readers=new Map();\nconst base=new Map();\nfor(const col of columns){\nif(col.computed)continue;\nconst read=isFunction(col.read)?col.read:pathGetter(col.field||col.id);\nbase.set(col.id,read);\nreaders.set(col.id,read);\n}\nconst order=computed?.order??[];\nconst fns=computed?.fns??{};\nconst deps=computed?.deps??{};\nconst wrapDeps=computed?.wrapDeps??null;\nconst active=order.filter((id)=>isFunction(fns[id]));\nconst wildcard=active.some((id)=>deps[id]==='*');\nlet memo=new WeakMap();\nconst resolve=(data)=>{\nconst values={};\nif(wildcard)for(const[id,read]of base)values[id]=read(data);\nfor(const id of active){\nconst declared=deps[id];\nlet bag;\nif(declared==='*'){\nbag=values;\n}else{\nbag={};\nconst list=declared||[];\nfor(let i=0;i<list.length;i++){\nconst d=list[i];\nbag[d]=d in values?values[d]:base.get(d)?.(data);\n}\n}\nvalues[id]=fns[id](wrapDeps?wrapDeps(bag,id):bag,{\ndata,row:null,column:null,grid:null,context,\n});\n}\nreturn values;\n};\nconst valuesFor=(data)=>{\nif(data===null||(typeof data!=='object'&&typeof data!=='function'))return resolve(data);\nlet v=memo.get(data);\nif(v===undefined){v=resolve(data);memo.set(data,v);}\nreturn v;\n};\nfor(const id of active){\nreaders.set(id,\n(data)=>valuesFor(data)[id]);\n}\nreturn{\nreaders,\nreset(){memo=new WeakMap();},\n};\n}\nclass ColumnPlan{\nspec;\nread;\nkind;\ninferred;\nnullable;\ncandidate=false;\ndistinct=null;\nchange=null;\nreason='';\nconstructor(spec,read){\nthis.spec=spec;\nthis.read=read;\nthis.kind='object';\nthis.inferred=false;\nthis.nullable=spec.nullable!==false;\n}\n}\nclass Ingest{\n#rows;\n#plans=[];\n#store=null;\n#readers;\n#cursor=0;\n#opts;\n#done=false;\n#cancelled=false;\n#elapsed=0;\n#columnar;\nconstructor(rows,plan={},opts={}){\nthis.#rows=Array.isArray(rows)?rows:Array.from(rows||[]);\nthis.#opts={...INGEST_DEFAULTS,...opts};\nconst columns=plan.columns??[];\nthis.#readers=createReaders(columns,plan.computed??null,plan.context);\nthis.#columnar=this.#rows.length>=this.#opts.columnarBelow;\nthis.#planColumns(columns,plan.computed??null);\nthis.#store=new ColumnStore(this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\nread:p.read,\ndictionary:p.spec.dictionary,\n})),{\ninitialCapacity:this.#opts.initialCapacity,\ncolumnarBelow:this.#opts.columnarBelow,\n});\n}\nget store(){return this.#store;}\nget done(){return this.#done||this.#cancelled;}\nget progress(){return this.#cursor;}\nslice(){\nif(this.done)return false;\nif(this.#opts.signal?.aborted){this.#cancelled=true;return false;}\nconst started=now();\nconst{chunkMs,chunkRows}=this.#opts;\nconst total=this.#rows.length;\ndo{\nconst end=Math.min(this.#cursor+chunkRows,total);\nthis.#store.append(this.#rows.slice(this.#cursor,end));\nthis.#measure(this.#cursor,end);\nthis.#cursor=end;\nthis.#readers.reset();\nthis.#reviewCardinality(false);\n}while(this.#cursor<total&&now()-started<chunkMs);\nthis.#elapsed+=now()-started;\nthis.#opts.onProgress?.({loaded:this.#cursor,total});\nif(this.#cursor>=total){\nthis.#reviewCardinality(true);\nthis.#done=true;\nreturn false;\n}\nreturn true;\n}\ncancel(){this.#cancelled=true;}\nresult(){\nreturn{\nstore:this.#store,\nschema:this.#plans.map((p)=>({\nid:p.spec.id,kind:p.kind,nullable:p.nullable,read:p.read,\ndictionary:p.spec.dictionary,\n})),\ndecisions:this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\ninferred:p.inferred,\ndistinct:p.candidate||p.change?this.#distinctOf(p):null,\nchange:p.change,\nreason:p.reason,\n})),\ncount:this.#store.count,\nelapsed:this.#elapsed,\ncancelled:this.#cancelled,\n};\n}\n#planColumns(columns,computed){\nconst rows=this.#rows;\nconst sampleN=Math.min(this.#opts.sampleSize,rows.length);\nconst ratio=this.#opts.dictionaryRatio;\nconst pure=computed?.pure instanceof Set\n?computed.pure\n:new Set(computed?.pure??computed?.order??[]);\nfor(const spec of columns){\nif(!spec||!spec.id)continue;\nif(spec.computed&&(spec.pure===false||(computed&&!pure.has(spec.id)))){\nwarnOnce(`ingest.impure.${spec.id}`,\n`column \"${spec.id}\" is an impure computed column and is not materialised into the store`);\ncontinue;\n}\nconst read=this.#readers.readers.get(spec.id)\n??(isFunction(spec.read)?spec.read:pathGetter(spec.field||spec.id));\nconst plan=new ColumnPlan(spec,read);\nif(spec.kind){\nplan.kind=spec.kind;\nplan.reason='declared by the caller';\n}else if(spec.dictionary){\nplan.kind=spec.multi?'multi':'dictionary';\nplan.reason='value table supplied (lookup column)';\n}else{\nconst samples=[];\nfor(let i=0;i<sampleN&&samples.length<this.#opts.sampleSize;i++){\nconst v=read(rows[i]);\nif(v!==null&&v!==undefined)samples.push(v);\n}\nplan.inferred=true;\nconst kind=inferKind(samples,{multi:spec.multi});\nif(kind==='text'){\nconst distinct=new Set(samples).size;\nplan.kind=decideText(distinct,samples.length,ratio);\nplan.candidate=this.#columnar;\nplan.reason=`sampled ${distinct} distinct in ${samples.length}`;\n}else{\nplan.kind=kind;\nplan.reason=`inferred from ${samples.length} sampled values`;\nif(kind==='object'&&samples.length){\ninfoOnce(`ingest.mixed.${spec.id}`,\n`column \"${spec.id}\" holds mixed or unrecognised value types; storing as an object array. Declare a type to avoid this.`);\n}\n}\nif(plan.kind==='object'&&plan.candidate)plan.distinct=new Set(samples);\n}\nthis.#plans.push(plan);\n}\n}\n#measure(from,to){\nconst rows=this.#rows;\nfor(const plan of this.#plans){\nif(!plan.candidate||!plan.distinct)continue;\nconst set=plan.distinct;\nfor(let i=from;i<to;i++){\nconst v=plan.read(rows[i]);\nif(v!==null&&v!==undefined)set.add(v);\n}\n}\n}\n#distinctOf(plan){\nif(plan.distinct)return plan.distinct.size;\nconst handle=this.#store.column(plan.spec.id);\nreturn handle?.dict?handle.dict.size:0;\n}\n#reviewCardinality(final){\nconst ratio=this.#opts.dictionaryRatio;\nconst total=this.#rows.length;\nfor(const plan of this.#plans){\nif(!plan.candidate)continue;\nconst distinct=this.#distinctOf(plan);\nif(plan.kind==='dictionary'&&distinct>=ratio*total){\nconst handle=this.#store.column(plan.spec.id);\nplan.distinct=new Set(handle?.dict?handle.dict.values():[]);\nthis.#store.convert(plan.spec.id,'object');\nplan.kind='object';\nplan.change='demoted';\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(plan.kind==='object'&&distinct>=ratio*total){\nplan.candidate=false;\nplan.distinct=null;\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(final&&plan.kind==='object'&&distinct<ratio*total){\nthis.#store.convert(plan.spec.id,'dictionary');\nplan.kind='dictionary';\nplan.change=plan.change==='demoted'?null:'promoted';\nplan.reason=`${distinct} distinct values is below ${ratio*100}% of ${total} rows`;\nplan.distinct=null;\n}\nif(final)plan.candidate=false;\n}\n}\n}\nasync function ingest(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,opts);\nconst frame=opts.scheduler?.frame??nextFrame;\nwhile(run.slice()){\nawait new Promise((resolve)=>{frame(resolve);});\n}\nreturn run.result();\n}\nfunction ingestSync(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,{...opts,chunkMs:Infinity});\nwhile(run.slice());\nreturn run.result();\n}\n});\n__def(\"packages/core/src/store/columnpack.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"isPortableSchema\",{enumerable:true,get:function(){return isPortableSchema;}});\nObject.defineProperty(__exports,\"packChunk\",{enumerable:true,get:function(){return packChunk;}});\nObject.defineProperty(__exports,\"packedTransfers\",{enumerable:true,get:function(){return packedTransfers;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/ingest.js\");\nconst inferKind=__m1[\"inferKind\"];\nconst decideText=__m1[\"decideText\"];\nconst INGEST_DEFAULTS=__m1[\"INGEST_DEFAULTS\"];\nconst __m2=__req(\"packages/core/src/store/columnstore.js\");\nconst toFloat=__m2[\"toFloat\"];\nconst PORTABLE_KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction isPortableSchema(schema){\nif(!Array.isArray(schema)||schema.length===0)return false;\nfor(const col of schema){\nif(!col||typeof col.id!=='string')return false;\nif(typeof col.field!=='string'||col.field==='')return false;\nif(col.kind&&!PORTABLE_KINDS.has(col.kind))return false;\n}\nreturn true;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(v===null||v===undefined)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction resolveKind(col,values,rows,ratio){\nif(col.kind)return col.kind;\nconst samples=[];\nfor(let i=0;i<values.length&&samples.length<INGEST_DEFAULTS.sampleSize;i++){\nconst v=values[i];\nif(v!==null&&v!==undefined)samples.push(v);\n}\nconst kind=inferKind(samples,{multi:col.multi});\nif(kind!=='text')return kind;\nconst distinct=new Set(samples).size;\nreturn decideText(distinct,samples.length,ratio);\n}\nfunction packChunk(schema,rows,opts={}){\nconst n=rows.length|0;\nconst ratio=opts.dictionaryRatio??INGEST_DEFAULTS.dictionaryRatio;\nconst columns=[];\nfor(const col of schema){\nconst read=pathGetter(col.field||col.id);\nconst nullable=col.nullable!==false;\nconst raw=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=read(rows[i]);\nraw[i]=v===undefined?null:v;\n}\nconst kind=resolveKind(col,raw,n,ratio);\nconst presence=nullable?new Uint8Array((n+7)>>3):null;\nconst present=(i)=>{if(presence)presence[i>>3]|=1<<(i&7);};\nlet packed;\nswitch(kind){\ncase'float64':{\nconst values=new Float64Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?NaN:toFloat(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'int32':{\nconst values=new Int32Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?0:toInt(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'bitset':{\nconst words=new Uint8Array((n+7)>>3);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nif(!gone&&!!v)words[i>>3]|=1<<(i&7);\n}\npacked={id:col.id,kind,nullable,values:words,presence,offsets:null,table:null};\nbreak;\n}\ncase'dictionary':{\nconst codes=new Uint32Array(n);\nconst table=[];\nconst index=new Map();\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v===null){codes[i]=0;continue;}\npresent(i);\nlet code=index.get(v);\nif(code===undefined){code=table.length;table.push(v);index.set(v,code);}\ncodes[i]=code;\n}\npacked={id:col.id,kind,nullable,values:codes,presence,offsets:null,table};\nbreak;\n}\ncase'multi':{\nconst table=[];\nconst index=new Map();\nconst offsets=new Uint32Array(n+1);\nconst flat=[];\nfor(let i=0;i<n;i++){\nconst v=raw[i];\noffsets[i]=flat.length;\nconst gone=v===null;\nif(!gone)present(i);\nconst members=toMembers(v);\nfor(let k=0;k<members.length;k++){\nconst m=members[k];\nlet code=index.get(m);\nif(code===undefined){code=table.length;table.push(m);index.set(m,code);}\nflat.push(code);\n}\n}\noffsets[n]=flat.length;\npacked={id:col.id,kind,nullable,values:Int32Array.from(flat),presence,offsets,table};\nbreak;\n}\ndefault:{\nconst values=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v!==null)present(i);\nvalues[i]=v;\n}\npacked={id:col.id,kind:'object',nullable,values,presence,offsets:null,table:null};\nbreak;\n}\n}\ncolumns.push(packed);\n}\nreturn{count:n,columns};\n}\nfunction packedTransfers(chunk){\nconst out=[];\nif(!chunk||!Array.isArray(chunk.columns))return out;\nconst add=(v)=>{\nif(ArrayBuffer.isView(v)&&v.buffer&&!out.includes(v.buffer))out.push(v.buffer);\n};\nfor(const col of chunk.columns){\nadd(col.values);\nadd(col.presence);\nadd(col.offsets);\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/format/date.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"scanPattern\",{enumerable:true,get:function(){return scanPattern;}});\nObject.defineProperty(__exports,\"toDate\",{enumerable:true,get:function(){return toDate;}});\nObject.defineProperty(__exports,\"compilePattern\",{enumerable:true,get:function(){return compilePattern;}});\nObject.defineProperty(__exports,\"compileDate\",{enumerable:true,get:function(){return compileDate;}});\nObject.defineProperty(__exports,\"toIsoDate\",{enumerable:true,get:function(){return toIsoDate;}});\nObject.defineProperty(__exports,\"toIsoDateTime\",{enumerable:true,get:function(){return toIsoDateTime;}});\nObject.defineProperty(__exports,\"compareIso\",{enumerable:true,get:function(){return compareIso;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isNil=__m0[\"isNil\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst TOKENS=[\n'yyyy','yy','MMMM','MMM','MM','M','dd','d',\n'EEEE','EEE','HH','H','hh','h','mm','m','ss','s','SSS','a',\n];\nfunction scanPattern(pattern){\nconst out=[];\nlet i=0;\nlet literal='';\nconst flush=()=>{if(literal){out.push({token:null,text:literal});literal='';}};\nwhile(i<pattern.length){\nconst ch=pattern[i];\nif(ch===\"'\"){\nif(pattern[i+1]===\"'\"){literal+=\"'\";i+=2;continue;}\nconst end=pattern.indexOf(\"'\",i+1);\nif(end===-1){literal+=pattern.slice(i+1);i=pattern.length;continue;}\nliteral+=pattern.slice(i+1,end);\ni=end+1;\ncontinue;\n}\nconst token=TOKENS.find((t)=>pattern.startsWith(t,i));\nif(token){flush();out.push({token,text:token});i+=token.length;continue;}\nif(/[A-Za-z]/.test(ch)){\nwarnOnce(\n`date.pattern.token:${ch}`,\n`the date pattern \"${pattern}\" contains '${ch}', which is not a supported token, `\n+'so it is rendered as text. Quote it as a literal to silence this. '\n+`Supported: ${TOKENS.join(' ')}.`,\n);\n}\nliteral+=ch;\ni+=1;\n}\nflush();\nreturn out;\n}\nconst WALL_CLOCK=/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?(?:\\.\\d+)?)?$/;\nfunction toDate(value){\nif(isNil(value)||value==='')return null;\nif(value instanceof Date)return Number.isNaN(value.getTime())?null:value;\nif(typeof value==='number')return Number.isNaN(value)?null:new Date(value);\nif(typeof value==='string'){\nconst wall=WALL_CLOCK.exec(value.trim());\nif(wall){\nconst[,y,mo,d,h='0',mi='0',sec='0']=wall;\nreturn new Date(+y,+mo-1,+d,+h,+mi,+sec);\n}\nconst d=new Date(value);\nreturn Number.isNaN(d.getTime())?null:d;\n}\nreturn null;\n}\nfunction pad(n,w){return String(n).padStart(w,'0');}\nfunction fieldReader(timeZone){\nif(!timeZone){\nreturn(d)=>({\nyear:d.getFullYear(),month:d.getMonth()+1,day:d.getDate(),\nhour:d.getHours(),minute:d.getMinutes(),second:d.getSeconds(),\nms:d.getMilliseconds(),weekday:d.getDay(),\n});\n}\nconst zoned=new Intl.DateTimeFormat('en-US',{\ntimeZone,year:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',hour12:false,weekday:'short',\n});\nconst days={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};\nreturn(d)=>{\nconst f={year:0,month:1,day:1,hour:0,minute:0,second:0,ms:d.getMilliseconds(),weekday:0};\nfor(const part of zoned.formatToParts(d)){\nswitch(part.type){\ncase'year':f.year=Number(part.value);break;\ncase'month':f.month=Number(part.value);break;\ncase'day':f.day=Number(part.value);break;\ncase'hour':f.hour=Number(part.value)%24;break;\ncase'minute':f.minute=Number(part.value);break;\ncase'second':f.second=Number(part.value);break;\ncase'weekday':f.weekday=days[part.value]??0;break;\ndefault:break;\n}\n}\nreturn f;\n};\n}\nfunction compilePattern(pattern,locale,timeZone){\nconst segments=scanPattern(pattern);\nconst read=fieldReader(timeZone);\nconst used=new Set(segments.filter((s)=>s.token).map((s)=>s.token));\nconst monthShort=used.has('MMM')?new Intl.DateTimeFormat(locale,{month:'short',timeZone}):null;\nconst monthLong=used.has('MMMM')?new Intl.DateTimeFormat(locale,{month:'long',timeZone}):null;\nconst dayShort=used.has('EEE')?new Intl.DateTimeFormat(locale,{weekday:'short',timeZone}):null;\nconst dayLong=used.has('EEEE')?new Intl.DateTimeFormat(locale,{weekday:'long',timeZone}):null;\nreturn(d)=>{\nconst f=read(d);\nlet out='';\nfor(const seg of segments){\nif(!seg.token){out+=seg.text;continue;}\nswitch(seg.token){\ncase'yyyy':out+=pad(f.year,4);break;\ncase'yy':out+=pad(f.year%100,2);break;\ncase'MMMM':out+=monthLong.format(d);break;\ncase'MMM':out+=monthShort.format(d);break;\ncase'MM':out+=pad(f.month,2);break;\ncase'M':out+=String(f.month);break;\ncase'dd':out+=pad(f.day,2);break;\ncase'd':out+=String(f.day);break;\ncase'EEEE':out+=dayLong.format(d);break;\ncase'EEE':out+=dayShort.format(d);break;\ncase'HH':out+=pad(f.hour,2);break;\ncase'H':out+=String(f.hour);break;\ncase'hh':out+=pad(f.hour%12===0?12:f.hour%12,2);break;\ncase'h':out+=String(f.hour%12===0?12:f.hour%12);break;\ncase'mm':out+=pad(f.minute,2);break;\ncase'm':out+=String(f.minute);break;\ncase'ss':out+=pad(f.second,2);break;\ncase's':out+=String(f.second);break;\ncase'SSS':out+=pad(f.ms,3);break;\ncase'a':out+=f.hour<12?'AM':'PM';break;\ndefault:out+=seg.text;break;\n}\n}\nreturn out;\n};\n}\nconst UNITS=[\n['year',365*24*3600e3],\n['month',30*24*3600e3],\n['week',7*24*3600e3],\n['day',24*3600e3],\n['hour',3600e3],\n['minute',60e3],\n['second',1e3],\n];\nfunction compileDate(spec,locale){\nconst s=spec||{};\nconst loc=s.locale||locale||undefined;\nconst nullDisplay=s.nullDisplay??'';\nconst timeZone=s.timeZone;\nlet absolute;\nif(s.pattern){\nabsolute=compilePattern(s.pattern,loc,timeZone);\n}else if(s.dateStyle||s.timeStyle){\nconst opts={timeZone};\nif(s.dateStyle)opts.dateStyle=s.dateStyle;\nif(s.timeStyle)opts.timeStyle=s.timeStyle;\nconst dtf=new Intl.DateTimeFormat(loc,opts);\nabsolute=(d)=>dtf.format(d);\n}else{\nconst dtf=new Intl.DateTimeFormat(loc,{dateStyle:'medium',timeZone});\nabsolute=(d)=>dtf.format(d);\n}\nconst relative=s.relative?new Intl.RelativeTimeFormat(loc,{numeric:'auto'}):null;\nconst thresholdDays=typeof s.relative==='object'&&s.relative\n?(s.relative.threshold??7)\n:7;\nconst thresholdMs=thresholdDays*24*3600e3;\nconst format=(value,params)=>{\nconst d=toDate(value);\nif(!d)return nullDisplay;\nif(relative){\nconst now=params&&typeof params.now==='number'?params.now:Date.now();\nconst delta=d.getTime()-now;\nif(Math.abs(delta)<thresholdMs){\nfor(const[unit,ms]of UNITS){\nif(Math.abs(delta)>=ms||unit==='second'){\nreturn relative.format(Math.round(delta/ms),unit);\n}\n}\n}\n}\nreturn absolute(d);\n};\nformat.spec=s;\nreturn format;\n}\nfunction toIsoDate(value){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst match=/^(\\d{4}-\\d{2}-\\d{2})/.exec(value.trim());\nif(match)return match[1];\nconst parsed=toDate(value);\nreturn parsed?toIsoDate(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nconst pad=(n)=>String(n).padStart(2,'0');\nreturn`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\n}\nfunction toIsoDateTime(value,timeZone){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst text=value.trim();\nif(ZONE_SUFFIX.test(text)){\nconst instant=toDate(text);\nreturn instant?wallClockIn(instant,timeZone):null;\n}\nconst match=/^(\\d{4}-\\d{2}-\\d{2})[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?/.exec(text);\nif(match){\nconst[,day,hour,minute,second]=match;\nreturn`${day}T${hour}:${minute}${second&&second!=='00'?`:${second}`:''}`;\n}\nif(/^\\d{4}-\\d{2}-\\d{2}$/.test(text))return`${text}T00:00`;\nconst parsed=toDate(text);\nreturn parsed?toIsoDateTime(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nreturn wallClockIn(date,timeZone);\n}\nconst ZONE_SUFFIX=/(?:Z|[+-]\\d{2}:?\\d{2})$/i;\nfunction wallClockIn(date,timeZone){\nconst pad=(n)=>String(n).padStart(2,'0');\nif(timeZone){\ntry{\nconst parts=new Intl.DateTimeFormat('en-CA',{\ntimeZone,\nyear:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',\nhour12:false,\n}).formatToParts(date).reduce((out,part)=>{\nif(part.type!=='literal')out[part.type]=part.value;\nreturn out;\n},{});\nconst hour=parts.hour==='24'?'00':parts.hour;\nconst seconds=Number(parts.second);\nreturn`${parts.year}-${parts.month}-${parts.day}T${hour}:${parts.minute}`\n+(seconds?`:${parts.second}`:'');\n}catch{\n}\n}\nconst day=`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\nconst seconds=date.getSeconds();\nconst clock=`${pad(date.getHours())}:${pad(date.getMinutes())}${seconds?`:${pad(seconds)}`:''}`;\nreturn`${day}T${clock}`;\n}\nfunction compareIso(a,b){\nconst left=isNil(a)||a===''?null:String(a);\nconst right=isNil(b)||b===''?null:String(b);\nif(left===null)return right===null?0:1;\nif(right===null)return-1;\nreturn left<right?-1:left>right?1:0;\n}\n});\n__def(\"packages/core/src/compute/filter.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return releaseMask;}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return compilePredicate;}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return testValue;}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return evaluateCondition;}});\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return evaluateFilters;}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return pruneColumn;}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return mentionsColumn;}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return compact;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isBlank=__m0[\"isBlank\"];\nconst toArray=__m0[\"toArray\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/format/date.js\");\nconst toIsoDate=__m1[\"toIsoDate\"];\nconst __m2=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m2[\"bitReader\"];\nconst dictSize=__m2[\"dictSize\"];\nconst dictValue=__m2[\"dictValue\"];\nconst presenceReader=__m2[\"presenceReader\"];\nconst valueComparator=__m2[\"valueComparator\"];\nconst valueReader=__m2[\"valueReader\"];\nconst ISO_DAY=/^\\d{4}-\\d{2}-\\d{2}$/;\nconst NULL_KEY='\\u0000null\\u0000';\nfunction acquireMask(ctx,n){\nconst pool=ctx&&ctx.pool;\nif(pool){\nconst take=pool.mask||pool.acquireMask||pool.acquire||pool.take;\nif(typeof take==='function'){\nconst mask=take.call(pool,n);\nif(mask&&mask.length>=n)return mask;\n}\n}\nreturn new Uint8Array(n);\n}\nfunction releaseMask(ctx,mask){\nconst pool=ctx&&ctx.pool;\nif(!pool||!mask)return;\nconst give=pool.release||pool.releaseMask||pool.free||pool.recycle;\nif(typeof give==='function')give.call(pool,mask);\n}\nfunction fillMask(mask,n,value){\nmask.fill(value,0,n);\nreturn mask;\n}\nfunction unorderable(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\nfunction coerceTarget(value,type){\nif(value===null||value===undefined)return value;\nif(type==='number')return typeof value==='number'?value:Number(value);\nif(type==='date'||type==='dateString'){\nconst iso=toIsoDate(value);\nreturn iso===null?toMillis(value):iso;\n}\nif(type==='boolean'){\nif(typeof value==='boolean')return value;\nif(value==='true'||value===1)return true;\nif(value==='false'||value===0)return false;\nreturn!!value;\n}\nreturn value;\n}\nfunction toMillis(value){\nif(value instanceof Date)return value.getTime();\nif(typeof value==='number')return value;\nreturn Date.parse(String(value));\n}\nfunction toNumber(value){\nif(typeof value==='number')return value;\nif(value instanceof Date)return value.getTime();\nif(value===null||value===undefined||value==='')return NaN;\nreturn Number(value);\n}\nfunction textOf(v,caseSensitive){\nconst s=typeof v==='string'?v:String(v);\nreturn caseSensitive?s:s.toLowerCase();\n}\nfunction setKey(v,caseSensitive){\nif(v===null||v===undefined)return NULL_KEY;\nif(typeof v==='string')return caseSensitive?v:v.toLowerCase();\nif(v instanceof Date)return v.getTime();\nreturn v;\n}\nfunction buildSet(value,caseSensitive,type){\nconst set=new Set();\nfor(const raw of toArray(value)){\nconst entry=coerceTarget(raw,type);\nset.add(setKey(entry,caseSensitive));\nif(typeof entry==='string'&&entry!==''&&Number.isFinite(Number(entry)))set.add(Number(entry));\nelse if(typeof entry==='number'&&Number.isFinite(entry))set.add(setKey(String(entry),caseSensitive));\n}\nreturn set;\n}\nfunction valueEquals(a,b,caseSensitive){\nif(a===null||a===undefined||b===null||b===undefined){\nreturn(a===null||a===undefined)&&(b===null||b===undefined);\n}\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return caseSensitive?a===b:a.toLowerCase()===b.toLowerCase();\nif(a instanceof Date||b instanceof Date)return toMillis(a)===toMillis(b);\nif(ta==='number'&&tb==='number')return a===b||(Number.isNaN(a)&&Number.isNaN(b));\nif(ta==='number'&&tb==='string')return a===Number(b);\nif(ta==='string'&&tb==='number')return Number(a)===b;\nif(ta==='boolean'||tb==='boolean')return a===b;\nif(Array.isArray(a)&&Array.isArray(b)){\nreturn a.length===b.length&&a.every((x,i)=>valueEquals(x,b[i],caseSensitive));\n}\nreturn a===b;\n}\nfunction compileRegExp(value,caseSensitive){\ntry{\nif(value instanceof RegExp){\nconst flags=value.flags.replace(/[gy]/g,'');\nreturn new RegExp(value.source,caseSensitive?flags:flags.includes('i')?flags:`${flags}i`);\n}\nreturn new RegExp(String(value),caseSensitive?'':'i');\n}catch(err){\nwarnOnce(`regex:${String(value)}`,`filter operator \"matches\" received an invalid pattern: ${String(value)}`,err);\nreturn null;\n}\n}\nfunction compilePredicate(condition,locale){\nconst predicate=compileValuePredicate(condition,locale);\nconst type=condition&&condition.type;\nif(type!=='date'&&type!=='dateString')return predicate;\nreturn(v)=>predicate(typeof v==='string'&&ISO_DAY.test(v)?v:(toIsoDate(v)??v));\n}\nfunction compileValuePredicate(condition,locale){\nconst op=condition&&condition.op;\nconst caseSensitive=!!(condition&&condition.caseSensitive);\nconst type=condition&&condition.type;\nconst cmp=valueComparator(locale);\nconst not=(p)=>(v)=>!p(v);\nswitch(op){\ncase'eq':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>valueEquals(v,target,caseSensitive);\n}\ncase'ne':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>!valueEquals(v,target,caseSensitive);\n}\ncase'lt':case'lte':case'gt':case'gte':{\nconst target=coerceTarget(condition.value,type);\nif(unorderable(target))return()=>false;\nconst want=op==='lt'?-1:op==='lte'?0:op==='gt'?1:2;\nreturn(v)=>{\nif(unorderable(v))return false;\nconst c=cmp(v,target);\nreturn want===-1?c<0:want===0?c<=0:want===1?c>0:c>=0;\n};\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=coerceTarget(pair[0],type);\nconst hi=coerceTarget(pair[1],type);\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nif(unorderable(lo)||unorderable(hi))return op==='between'?()=>false:()=>true;\nconst inRange=(v)=>{\nif(unorderable(v))return false;\nconst a=cmp(v,lo);\nconst b=cmp(v,hi);\nreturn(loInclusive?a>=0:a>0)&&(hiInclusive?b<=0:b<0);\n};\nreturn op==='between'?inRange:not(inRange);\n}\ncase'in':case'notIn':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst member=(v)=>set.has(setKey(v,caseSensitive));\nreturn op==='in'?member:not(member);\n}\ncase'contains':case'notContains':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nconst has=(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).includes(needle));\nreturn op==='contains'?has:not(has);\n}\ncase'startsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).startsWith(needle));\n}\ncase'endsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).endsWith(needle));\n}\ncase'matches':{\nconst re=compileRegExp(condition.value,caseSensitive);\nif(!re)return()=>false;\nreturn(v)=>(v===null||v===undefined?false:re.test(String(v)));\n}\ncase'blank':\nreturn(v)=>isBlank(v)||(Array.isArray(v)&&v.length===0);\ncase'notBlank':\nreturn(v)=>!(isBlank(v)||(Array.isArray(v)&&v.length===0));\ncase'containsAny':case'containsNone':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst any=(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nfor(let i=0;i<list.length;i++)if(set.has(setKey(list[i],caseSensitive)))return true;\nreturn false;\n};\nreturn op==='containsAny'?any:not(any);\n}\ncase'containsAll':{\nconst wanted=toArray(condition.value).map((x)=>setKey(coerceTarget(x,type),caseSensitive));\nreturn(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nif(wanted.length===0)return true;\nconst have=new Set(list.map((x)=>setKey(x,caseSensitive)));\nfor(let i=0;i<wanted.length;i++)if(!have.has(wanted[i]))return false;\nreturn true;\n};\n}\ndefault:\nwarnOnce(`op:${String(op)}`,`unknown filter operator \"${String(op)}\"; the condition passes every row`);\nreturn()=>true;\n}\n}\nfunction testValue(value,condition,locale){\nreturn compilePredicate(condition,locale)(value);\n}\nfunction presenceCondition(handle,wantPresent,mask,count){\nconst present=presenceReader(handle);\nif(present){\nconst target=wantPresent?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===target?1:0;\nreturn mask;\n}\nconst kind=handle.kind;\nif(kind==='float64'||kind==='int32'||kind==='bitset'){\nreturn fillMask(mask,count,wantPresent?1:0);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++){\nconst v=read(i);\nconst blank=isBlank(v)||(Array.isArray(v)&&v.length===0);\nmask[i]=blank===wantPresent?0:1;\n}\nreturn mask;\n}\nfunction dictionaryCondition(handle,pred,mask,count){\nconst dict=handle.dict;\nconst size=dictSize(dict);\nconst allowed=new Uint8Array(size);\nfor(let code=0;code<size;code++)allowed[code]=pred(dictValue(dict,code))?1:0;\nconst codes=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=allowed[codes[i]];\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===1?allowed[codes[i]]:absentAnswer;\nreturn mask;\n}\nfunction booleanCondition(handle,pred,mask,count){\nconst bit=bitReader(handle.values);\nconst whenTrue=pred(true)?1:0;\nconst whenFalse=pred(false)?1:0;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=bit(i)===1?whenTrue:whenFalse;\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++){\nmask[i]=present(i)===0?absentAnswer:(bit(i)===1?whenTrue:whenFalse);\n}\nreturn mask;\n}\nfunction numericCondition(handle,condition,pred,mask,count){\nconst values=handle.values;\nconst type=condition.type;\nconst op=condition.op;\nlet handled=true;\nswitch(op){\ncase'eq':case'ne':{\nconst target=toNumber(coerceTarget(condition.value,type));\nconst wantNaN=typeof condition.value==='number'&&Number.isNaN(condition.value);\nconst invert=op==='ne'?1:0;\nif(wantNaN){\nfor(let i=0;i<count;i++)mask[i]=(Number.isNaN(values[i])?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=((values[i]===target)?1:0)^invert;\n}\nbreak;\n}\ncase'lt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<t?1:0;\nbreak;\n}\ncase'lte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<=t?1:0;\nbreak;\n}\ncase'gt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>t?1:0;\nbreak;\n}\ncase'gte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>=t?1:0;\nbreak;\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=toNumber(coerceTarget(pair[0],type));\nconst hi=toNumber(coerceTarget(pair[1],type));\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nconst invert=op==='notBetween'?1:0;\nif(loInclusive&&hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<=hi))?1:0)^invert;\n}else if(loInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<hi))?1:0)^invert;\n}else if(hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<=hi))?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<hi))?1:0)^invert;\n}\nbreak;\n}\ncase'in':case'notIn':{\nconst set=new Set();\nfor(const raw of toArray(condition.value)){\nconst n=toNumber(coerceTarget(raw,type));\nif(!Number.isNaN(n))set.add(n);\n}\nconst invert=op==='notIn'?1:0;\nfor(let i=0;i<count;i++)mask[i]=(set.has(values[i])?1:0)^invert;\nbreak;\n}\ndefault:\nhandled=false;\nbreak;\n}\nif(!handled)return false;\nconst present=presenceReader(handle);\nif(present){\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)if(present(i)===0)mask[i]=absentAnswer;\n}\nreturn true;\n}\nfunction genericCondition(handle,pred,mask,count){\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++)mask[i]=pred(read(i))?1:0;\nreturn mask;\n}\nfunction evaluateCondition(condition,ctx,out){\nconst count=ctx.count|0;\nconst mask=out||acquireMask(ctx,count);\nif(!condition)return fillMask(mask,count,1);\nconst handle=typeof ctx.handle==='function'?ctx.handle(condition.col):undefined;\nconst custom=typeof ctx.custom==='function'?ctx.custom:null;\nif(!handle){\nif(custom){\nfor(let i=0;i<count;i++)mask[i]=custom(condition,i)?1:0;\nreturn mask;\n}\nwarnOnce(`filter:col:${String(condition.col)}`,\n`filter references unknown column \"${String(condition.col)}\"; the condition passes every row`);\nreturn fillMask(mask,count,1);\n}\nconst op=condition.op;\nif(op==='blank'||op==='notBlank')return presenceCondition(handle,op==='notBlank',mask,count);\nconst pred=compilePredicate(condition,ctx.locale);\nswitch(handle.kind){\ncase'dictionary':\nreturn dictionaryCondition(handle,pred,mask,count);\ncase'bitset':\nreturn booleanCondition(handle,pred,mask,count);\ncase'float64':case'int32':\nif(numericCondition(handle,condition,pred,mask,count))return mask;\nreturn genericCondition(handle,pred,mask,count);\ndefault:\nreturn genericCondition(handle,pred,mask,count);\n}\n}\nfunction evaluateNode(node,ctx,count){\nif(!node)return fillMask(acquireMask(ctx,count),count,1);\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(children.length===0)return fillMask(acquireMask(ctx,count),count,1);\nconst acc=evaluateNode(children[0],ctx,count);\nfor(let k=1;k<children.length;k++){\nconst rhs=evaluateNode(children[k],ctx,count);\nif(op==='or')for(let i=0;i<count;i++)acc[i]|=rhs[i];\nelse for(let i=0;i<count;i++)acc[i]&=rhs[i];\nreleaseMask(ctx,rhs);\n}\nif(op==='not')for(let i=0;i<count;i++)acc[i]^=1;\nreturn acc;\n}\nreturn evaluateCondition(node,ctx,acquireMask(ctx,count));\n}\nfunction evaluateFilters(filters,ctx){\nreturn evaluateNode(filters,ctx,ctx.count|0);\n}\nfunction pruneColumn(filters,colId){\nif(!filters||!colId)return filters||null;\nconst node=(filters);\nif(Array.isArray(node.conditions)){\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(op!=='and'){\nreturn mentionsColumn(node,colId)?null:filters;\n}\nconst kept=[];\nfor(const child of node.conditions){\nconst pruned=pruneColumn(child,colId);\nif(pruned)kept.push(pruned);\n}\nif(!kept.length)return null;\nreturn{...node,op:'and',conditions:kept};\n}\nreturn node.col===colId?null:filters;\n}\nfunction mentionsColumn(filters,colId){\nif(!filters||typeof filters!=='object')return false;\nconst node=(filters);\nif(node.col===colId)return true;\nif(Array.isArray(node.conditions)){\nfor(const child of node.conditions)if(mentionsColumn(child,colId))return true;\n}\nreturn false;\n}\nfunction compact(mask,count,out){\nif(out&&out.length>=count){\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])out[k++]=i;\nreturn out.subarray(0,k);\n}\nlet survivors=0;\nfor(let i=0;i<count;i++)survivors+=mask[i]?1:0;\nconst result=new Uint32Array(survivors);\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])result[k++]=i;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/group.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return packKeys;}});\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return groupByColumns;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueReader=__m0[\"valueReader\"];\nconst KEY_SEPARATOR='\\u001F';\nconst NULL_MARKER='\\u0000';\nconst MAX_DIRECT_COUNTS=1<<20;\nfunction packKeys(handles,idx,n){\nconst k=handles.length;\nconst readers=handles.map((h)=>valueReader(h));\nconst allDictionary=k>0&&handles.every((h)=>h&&h.kind==='dictionary'&&h.dict);\nif(allDictionary){\nconst cards=handles.map((h)=>dictSize(h.dict)+1);\nlet product=1;\nfor(let j=0;j<k;j++)product*=cards[j];\nif(product<=Number.MAX_SAFE_INTEGER){\nconst codes=handles.map((h)=>h.values);\nconst presence=handles.map((h)=>presenceReader(h));\nconst keyOf=(row)=>{\nlet key=0;\nfor(let j=0;j<k;j++){\nconst present=presence[j];\nconst code=present&&present(row)===0?cards[j]-1:codes[j][row];\nkey=key*cards[j]+code;\n}\nreturn key;\n};\nconst packed=new Float64Array(n);\nfor(let i=0;i<n;i++)packed[i]=keyOf(idx[i]);\nreturn{packed,strings:null,product,readers,keyOf};\n}\n}\nconst keyOf=(row)=>{\nlet key='';\nfor(let j=0;j<k;j++){\nconst v=readers[j](row);\nkey+=(j===0?'':KEY_SEPARATOR)+(v===null||v===undefined?NULL_MARKER:String(v));\n}\nreturn key;\n};\nconst strings=new Array(n);\nfor(let i=0;i<n;i++)strings[i]=keyOf(idx[i]);\nreturn{packed:null,strings,product:Infinity,readers,keyOf};\n}\nfunction scatterBuckets(idx,ids,n,groups){\nconst offsets=new Uint32Array(groups+1);\nfor(let i=0;i<n;i++)offsets[ids[i]+1]++;\nfor(let g=0;g<groups;g++)offsets[g+1]+=offsets[g];\nconst scattered=new Uint32Array(n);\nconst cursor=offsets.slice(0,groups);\nfor(let i=0;i<n;i++)scattered[cursor[ids[i]]++]=idx[i];\nconst buckets=new Array(groups);\nfor(let g=0;g<groups;g++)buckets[g]=scattered.subarray(offsets[g],offsets[g+1]);\nreturn buckets;\n}\nfunction groupByColumns(handles,order,opts={}){\nconst list=handles||[];\nconst idx=order||identity(rowCount(list[0],opts));\nconst n=idx.length;\nif(list.length===0||n===0)return{keys:[],buckets:[]};\nconst{packed,strings,product,readers}=packKeys(list,idx,n);\nconst ids=new Uint32Array(n);\nlet groups=0;\nlet packedKeys=null;\nif(packed&&product<=Math.max(1024,Math.min(MAX_DIRECT_COUNTS,n*4))){\nconst size=product;\nconst seen=new Int32Array(size).fill(-1);\nfor(let i=0;i<n;i++)seen[packed[i]]=0;\nfor(let key=0;key<size;key++)if(seen[key]===0)seen[key]=groups++;\nfor(let i=0;i<n;i++)ids[i]=seen[packed[i]];\npackedKeys=new Float64Array(groups);\nfor(let key=0;key<size;key++)if(seen[key]>=0)packedKeys[seen[key]]=key;\n}else if(packed){\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=packed[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\npackedKeys=new Float64Array(groups);\nfor(const[key,id]of seen)packedKeys[id]=key;\n}else{\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=strings[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\n}\nconst buckets=scatterBuckets(idx,ids,n,groups);\nconst keys=new Array(groups);\nfor(let g=0;g<groups;g++){\nconst row=buckets[g][0];\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\nkeys[g]=tuple;\n}\nconst result={keys,buckets};\nif(packedKeys)result.packed=packedKeys;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/facet.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return STRATEGIES;}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return GRANULARITIES;}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return DEFAULT_BUCKETS;}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return DEFAULT_CARDINALITY_LIMIT;}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return QUANTILE_SAMPLE;}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return facetKind;}});\nObject.defineProperty(__exports,\"orderedReader\",{enumerable:true,get:function(){return orderedReader;}});\nObject.defineProperty(__exports,\"toNumeric\",{enumerable:true,get:function(){return toNumeric;}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return cardinalityOf;}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return pickGranularity;}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return floorTo;}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return advance;}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return computeBounds;}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return countInto;}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return bucketOf;}});\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return facet;}});\nObject.defineProperty(__exports,\"default\",{enumerable:true,get:function(){return __default;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst dictSize=__m0[\"dictSize\"];\nconst dictValue=__m0[\"dictValue\"];\nconst STRATEGIES=Object.freeze(['equal','quantile','log']);\nconst GRANULARITIES=Object.freeze(['hour','day','week','month','quarter','year']);\nconst DEFAULT_BUCKETS=20;\nconst DEFAULT_CARDINALITY_LIMIT=50;\nconst QUANTILE_SAMPLE=10_000;\nfunction facetKind(handle,type){\nif(!handle)return'none';\nconst base=type&&type.base;\nif(base==='date'||base==='datetime'||base==='time'||base==='dateString')return'date';\nswitch(handle.kind){\ncase'bitset':return'boolean';\ncase'float64':case'int32':return'numeric';\ncase'dictionary':return'category';\ncase'multi':return'category';\ndefault:\nif(base==='number')return'numeric';\nif(base==='boolean')return'boolean';\nif(base==='text')return'category';\nreturn'none';\n}\n}\nfunction orderedReader(handle){\nconst values=handle.values;\nconst kind=handle.kind;\nif((kind==='float64'||kind==='int32')&&values)return(i)=>values[i];\nconst read=valueReader(handle);\nreturn(i)=>toNumeric(read(i));\n}\nfunction toNumeric(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(v===null||v===undefined||v==='')return NaN;\nif(typeof v==='boolean')return v?1:0;\nif(typeof v==='string'){\nconst n=Number(v);\nif(Number.isFinite(n))return n;\nconst t=Date.parse(v);\nreturn Number.isFinite(t)?t:NaN;\n}\nreturn NaN;\n}\nfunction cardinalityOf(handle,indices,count,limit=DEFAULT_CARDINALITY_LIMIT){\nif(!handle)return{cardinality:0,exact:true};\nif(handle.dict)return{cardinality:dictSize(handle.dict),exact:true};\nif(handle.kind==='bitset')return{cardinality:2,exact:true};\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst seen=new Set();\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined)continue;\nseen.add(v);\nif(seen.size>limit)return{cardinality:seen.size,exact:false};\n}\nreturn{cardinality:seen.size,exact:true};\n}\nconst HOUR_MS=3600_000;\nconst DAY_MS=86_400_000;\nfunction pickGranularity(span,target=DEFAULT_BUCKETS){\nconst ms=Number.isFinite(span)&&span>0?span:0;\nconst wide=Math.max(1,target)*2;\nif(ms/HOUR_MS<=wide)return'hour';\nif(ms/DAY_MS<=wide)return'day';\nif(ms/(7*DAY_MS)<=wide)return'week';\nif(ms/(30*DAY_MS)<=wide)return'month';\nif(ms/(91*DAY_MS)<=wide)return'quarter';\nreturn'year';\n}\nfunction floorTo(ms,granularity){\nif(!Number.isFinite(ms))return NaN;\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setMinutes(0,0,0);return d.getTime();\ncase'day':d.setHours(0,0,0,0);return d.getTime();\ncase'week':{\nd.setHours(0,0,0,0);\nconst back=(d.getDay()+6)%7;\nd.setDate(d.getDate()-back);\nreturn d.getTime();\n}\ncase'month':d.setDate(1);d.setHours(0,0,0,0);return d.getTime();\ncase'quarter':\nd.setMonth(Math.floor(d.getMonth()/3)*3,1);\nd.setHours(0,0,0,0);\nreturn d.getTime();\ndefault:d.setMonth(0,1);d.setHours(0,0,0,0);return d.getTime();\n}\n}\nfunction advance(ms,granularity){\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setHours(d.getHours()+1);break;\ncase'day':d.setDate(d.getDate()+1);break;\ncase'week':d.setDate(d.getDate()+7);break;\ncase'month':d.setMonth(d.getMonth()+1);break;\ncase'quarter':d.setMonth(d.getMonth()+3);break;\ndefault:d.setFullYear(d.getFullYear()+1);break;\n}\nreturn d.getTime();\n}\nfunction numericExtent(handle,indices,count){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nlet min=Infinity;\nlet max=-Infinity;\nlet nulls=0;\nlet finite=0;\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){nulls++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){nulls++;continue;}\nif(v<min)min=v;\nif(v>max)max=v;\nfinite++;\n}\nreturn{min,max,nulls,finite};\n}\nfunction sortedSample(handle,indices,count,cap){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nconst step=n>cap?n/cap:1;\nconst out=[];\nfor(let s=0;s<n;s+=step){\nconst i=indices?indices[Math.floor(s)]:Math.floor(s);\nif(present&&!present(i))continue;\nconst v=read(i);\nif(Number.isFinite(v))out.push(v);\n}\nconst arr=Float64Array.from(out);\narr.sort();\nreturn arr;\n}\nfunction computeBounds(handle,indices,count,opts={}){\nconst kind=opts.kind||facetKind(handle,opts.type);\nif(kind==='none'||!handle)return{kind:'none',buckets:[],suppressed:'type'};\nif(kind==='boolean')return boundsForBoolean(handle,indices,count);\nif(kind==='category')return boundsForCategory(handle,indices,count,opts);\nreturn boundsForOrdered(handle,indices,count,kind,opts);\n}\nfunction boundsForBoolean(handle,indices,count){\nconst present=presenceReader(handle);\nlet nulls=0;\nif(present){\nconst n=indices?indices.length:count;\nfor(let k=0;k<n;k++)if(!present(indices?indices[k]:k))nulls++;\n}\nconst buckets=[{value:false,label:'false'},{value:true,label:'true'}];\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'boolean',buckets};\n}\nfunction boundsForCategory(handle,indices,count,opts){\nconst limit=opts.cardinalityLimit??DEFAULT_CARDINALITY_LIMIT;\nconst{cardinality}=cardinalityOf(handle,indices,count,limit);\nif(cardinality>limit&&(opts.aboveLimit||'suppress')==='suppress'){\nreturn{kind:'category',buckets:[],suppressed:'cardinality',cardinality};\n}\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst tally=new Map();\nlet nulls=0;\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){nulls++;continue;}\nif(Array.isArray(v)){\nif(!v.length){nulls++;continue;}\nfor(const m of v)tally.set(m,(tally.get(m)||0)+1);\ncontinue;\n}\ntally.set(v,(tally.get(v)||0)+1);\n}\nlet entries=[...tally.entries()];\nif(opts.order==='alpha'){\nentries.sort((a,b)=>String(a[0]).localeCompare(String(b[0])));\n}else{\nentries.sort((a,b)=>b[1]-a[1]);\n}\nlet remainder=0;\nlet dropped=0;\nif(entries.length>limit){\ndropped=entries.length-limit;\nfor(let i=limit;i<entries.length;i++)remainder+=entries[i][1];\nentries=entries.slice(0,limit);\n}\nconst buckets=entries.map(([value])=>({value,label:String(value)}));\nif(remainder>0)buckets.push({remainder:true,label:`Other (${dropped} values)`});\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'category',buckets,cardinality};\n}\nfunction boundsForOrdered(handle,indices,count,kind,opts){\nconst{min,max,nulls,finite}=numericExtent(handle,indices,count);\nif(!finite){\nreturn{kind,buckets:nulls?[{null:true,label:'Empty'}]:[],empty:true};\n}\nconst wanted=Math.max(1,Math.floor(opts.buckets||DEFAULT_BUCKETS));\nlet buckets=[];\nif(kind==='date'){\nconst granularity=GRANULARITIES.includes(opts.granularity)\n?opts.granularity:pickGranularity(max-min,wanted);\nlet edge=floorTo(min,granularity);\nwhile(edge<=max&&buckets.length<4096){\nconst next=advance(edge,granularity);\nif(!(next>edge))break;\nbuckets.push({from:edge,to:next});\nedge=next;\n}\nreturn{kind,buckets:withNull(buckets,nulls),granularity};\n}\nconst strategy=STRATEGIES.includes(opts.strategy)?opts.strategy:'equal';\nif(strategy==='quantile'){\nconst sample=sortedSample(handle,indices,count,QUANTILE_SAMPLE);\nif(sample.length){\nconst edges=[sample[0]];\nfor(let b=1;b<wanted;b++){\nconst v=sample[Math.min(sample.length-1,Math.floor((b/wanted)*sample.length))];\nif(v>edges[edges.length-1])edges.push(v);\n}\nedges.push(max);\nfor(let b=0;b<edges.length-1;b++)buckets.push({from:edges[b],to:edges[b+1]});\n}\n}else if(strategy==='log'&&min>0){\nconst lo=Math.log10(min);\nconst hi=Math.log10(max);\nconst step=(hi-lo)/wanted||1;\nfor(let b=0;b<wanted;b++){\nbuckets.push({from:10**(lo+b*step),to:10**(lo+(b+1)*step)});\n}\n}\nif(!buckets.length){\nconst width=(max-min)/wanted||1;\nfor(let b=0;b<wanted;b++)buckets.push({from:min+b*width,to:min+(b+1)*width});\n}\nbuckets[buckets.length-1].to=max;\nreturn{kind,buckets:withNull(buckets,nulls),strategy,min,max};\n}\nfunction withNull(buckets,nulls){\nreturn nulls>0?[...buckets,{null:true,label:'Empty'}]:buckets;\n}\nfunction countInto(handle,indices,count,bounds,out){\nconst buckets=(bounds&&bounds.buckets)||[];\nconst counts=out&&out.length>=buckets.length?out.subarray(0,buckets.length)\n:new Uint32Array(buckets.length);\ncounts.fill(0);\nif(!handle||!buckets.length)return counts;\nconst nullBucket=buckets.length-1;\nconst hasNull=!!buckets[nullBucket]&&buckets[nullBucket].null===true;\nconst n=indices?indices.length:count;\nif(bounds.kind==='boolean'){\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined){if(hasNull)counts[nullBucket]++;continue;}\ncounts[v?1:0]++;\n}\nreturn counts;\n}\nif(bounds.kind==='category'){\nconst slot=new Map();\nfor(let b=0;b<buckets.length;b++){\nif(!buckets[b].null&&!buckets[b].remainder)slot.set(buckets[b].value,b);\n}\nconst remainderAt=buckets.findIndex((b)=>b.remainder);\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){if(hasNull)counts[nullBucket]++;continue;}\nif(Array.isArray(v)){\nif(!v.length){if(hasNull)counts[nullBucket]++;continue;}\nfor(const m of v){\nconst at=slot.get(m);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\ncontinue;\n}\nconst at=slot.get(v);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\nreturn counts;\n}\nconst ordered=hasNull?buckets.length-1:buckets.length;\nconst edges=new Float64Array(ordered+1);\nfor(let b=0;b<ordered;b++)edges[b]=buckets[b].from;\nedges[ordered]=ordered?buckets[ordered-1].to:0;\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){if(hasNull)counts[nullBucket]++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){if(hasNull)counts[nullBucket]++;continue;}\nconst at=bucketOf(edges,ordered,v);\nif(at>=0)counts[at]++;\n}\nreturn counts;\n}\nfunction bucketOf(edges,ordered,v){\nif(!ordered)return-1;\nif(v<edges[0])return-1;\nif(v>=edges[ordered])return v===edges[ordered]?ordered-1:-1;\nlet lo=0;\nlet hi=ordered-1;\nwhile(lo<hi){\nconst mid=(lo+hi+1)>>>1;\nif(v>=edges[mid])lo=mid;else hi=mid-1;\n}\nreturn lo;\n}\nfunction facet(handle,indices,count,opts={}){\nconst bounds=opts.bounds||computeBounds(handle,opts.boundsIndices??indices,count,opts);\nreturn{bounds,counts:countInto(handle,indices,count,bounds)};\n}\nconst __default=facet;\n});\n__def(\"packages/core/src/compute/special.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"logGamma\",{enumerable:true,get:function(){return logGamma;}});\nObject.defineProperty(__exports,\"incompleteBeta\",{enumerable:true,get:function(){return incompleteBeta;}});\nObject.defineProperty(__exports,\"normalQuantile\",{enumerable:true,get:function(){return normalQuantile;}});\nObject.defineProperty(__exports,\"studentT\",{enumerable:true,get:function(){return studentT;}});\nObject.defineProperty(__exports,\"studentTQuantile\",{enumerable:true,get:function(){return studentTQuantile;}});\nconst LANCZOS=Object.freeze([\n676.5203681218851,-1259.1392167224028,771.32342877765313,\n-176.61502916214059,12.507343278686905,-0.13857109526572012,\n9.9843695780195716e-6,1.5056327351493116e-7,\n]);\nconst EPS=3e-12;\nconst TINY=1e-300;\nfunction logGamma(x){\nif(x<0.5)return Math.log(Math.PI/Math.sin(Math.PI*x))-logGamma(1-x);\nconst z=x-1;\nlet a=0.99999999999980993;\nconst t=z+7.5;\nfor(let i=0;i<LANCZOS.length;i++)a+=LANCZOS[i]/(z+i+1);\nreturn 0.5*Math.log(2*Math.PI)+(z+0.5)*Math.log(t)-t+Math.log(a);\n}\nfunction betaContinuedFraction(a,b,x){\nconst qab=a+b;\nconst qap=a+1;\nconst qam=a-1;\nlet c=1;\nlet d=1-(qab*x)/qap;\nif(Math.abs(d)<TINY)d=TINY;\nd=1/d;\nlet h=d;\nfor(let m=1;m<=300;m++){\nconst m2=2*m;\nlet aa=(m*(b-m)*x)/((qam+m2)*(a+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nh*=d*c;\naa=(-(a+m)*(qab+m)*x)/((a+m2)*(qap+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nconst step=d*c;\nh*=step;\nif(Math.abs(step-1)<EPS)break;\n}\nreturn h;\n}\nfunction incompleteBeta(a,b,x){\nif(!(a>0)||!(b>0)||!Number.isFinite(x))return Number.NaN;\nif(x<=0)return 0;\nif(x>=1)return 1;\nconst front=Math.exp(\nlogGamma(a+b)-logGamma(a)-logGamma(b)+a*Math.log(x)+b*Math.log(1-x),\n);\nreturn x<(a+1)/(a+b+2)\n?(front*betaContinuedFraction(a,b,x))/a\n:1-(front*betaContinuedFraction(b,a,1-x))/b;\n}\nfunction normalQuantile(p){\nif(!(p>0)||!(p<1))return p===0?-Infinity:(p===1?Infinity:Number.NaN);\nconst a=[-3.969683028665376e+1,2.209460984245205e+2,-2.759285104469687e+2,\n1.383577518672690e+2,-3.066479806614716e+1,2.506628277459239];\nconst b=[-5.447609879822406e+1,1.615858368580409e+2,-1.556989798598866e+2,\n6.680131188771972e+1,-1.328068155288572e+1];\nconst c=[-7.784894002430293e-3,-3.223964580411365e-1,-2.400758277161838,\n-2.549732539343734,4.374664141464968,2.938163982698783];\nconst d=[7.784695709041462e-3,3.224671290700398e-1,2.445134137142996,\n3.754408661907416];\nconst low=0.02425;\nlet q;\nlet r;\nlet x;\nif(p<low){\nq=Math.sqrt(-2*Math.log(p));\nx=(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}else if(p<=1-low){\nq=p-0.5;\nr=q*q;\nx=((((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q)\n/ (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);\n}else{\nq=Math.sqrt(-2*Math.log(1-p));\nx=-(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}\nconst e=0.5*erfc(-x/Math.SQRT2)-p;\nconst u=e*Math.sqrt(2*Math.PI)*Math.exp((x*x)/2);\nreturn x-u/(1+(x*u)/2);\n}\nfunction erfc(x){\nconst z=Math.abs(x);\nconst t=2/(2+z);\nconst ty=4*t-2;\nconst cof=[-1.3026537197817094,6.4196979235649026e-1,1.9476473204185836e-2,\n-9.561514786808631e-3,-9.46595344482036e-4,3.66839497852761e-4,\n4.2523324806907e-5,-2.0278578112534e-5,-1.624290004647e-6,\n1.303655835580e-6,1.5626441722e-8,-8.5238095915e-8,6.529054439e-9,\n5.059343495e-9,-9.91364156e-10,-2.27365122e-10,9.6467911e-11,\n2.394038e-12,-6.886027e-12,8.94487e-13,3.13092e-13,-1.12708e-13,\n3.81e-16,7.106e-15];\nlet dd=0;\nlet dv=0;\nlet tmp;\nfor(let j=cof.length-1;j>0;j--){\ntmp=dv;\ndv=ty*dv-dd+cof[j];\ndd=tmp;\n}\nconst ans=t*Math.exp(-z*z+0.5*(cof[0]+ty*dv)-dd);\nreturn x>=0?ans:2-ans;\n}\nfunction studentT(t,df){\nif(!(df>0)||!Number.isFinite(t))return Number.NaN;\nconst tail=0.5*incompleteBeta(df/2,0.5,df/(df+t*t));\nreturn t>0?1-tail:tail;\n}\nfunction studentTQuantile(p,df){\nif(!(p>0)||!(p<1)||!(df>0))return Number.NaN;\nif(df>1e7)return normalQuantile(p);\nlet lo=-1e4;\nlet hi=1e4;\nlet x=normalQuantile(p);\nconst logBeta=logGamma(df/2)+logGamma(0.5)-logGamma((df+1)/2);\nfor(let i=0;i<60;i++){\nconst cdf=studentT(x,df);\nif(cdf<p)lo=x;else hi=x;\nconst pdf=Math.exp(-((df+1)/2)*Math.log(1+(x*x)/df)-logBeta)\n/ Math.sqrt(df);\nconst step=pdf>0?(cdf-p)/pdf:0;\nif(Math.abs(step)<1e-12)break;\nconst next=x-step;\nx=next>lo&&next<hi&&Number.isFinite(next)?next:(lo+hi)/2;\nif(hi-lo<1e-12)break;\n}\nreturn x;\n}\n});\n__def(\"packages/core/src/compute/statistics.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KENDALL_LIMIT\",{enumerable:true,get:function(){return KENDALL_LIMIT;}});\nObject.defineProperty(__exports,\"MAINTENANCE\",{enumerable:true,get:function(){return MAINTENANCE;}});\nObject.defineProperty(__exports,\"numbers\",{enumerable:true,get:function(){return numbers;}});\nObject.defineProperty(__exports,\"frequencies\",{enumerable:true,get:function(){return frequencies;}});\nObject.defineProperty(__exports,\"herfindahl\",{enumerable:true,get:function(){return herfindahl;}});\nObject.defineProperty(__exports,\"entropy\",{enumerable:true,get:function(){return entropy;}});\nObject.defineProperty(__exports,\"evenness\",{enumerable:true,get:function(){return evenness;}});\nObject.defineProperty(__exports,\"topShare\",{enumerable:true,get:function(){return topShare;}});\nObject.defineProperty(__exports,\"gini\",{enumerable:true,get:function(){return gini;}});\nObject.defineProperty(__exports,\"moments\",{enumerable:true,get:function(){return moments;}});\nObject.defineProperty(__exports,\"quantileSorted\",{enumerable:true,get:function(){return quantileSorted;}});\nObject.defineProperty(__exports,\"quantile\",{enumerable:true,get:function(){return quantile;}});\nObject.defineProperty(__exports,\"STAT_FNS\",{enumerable:true,get:function(){return STAT_FNS;}});\nObject.defineProperty(__exports,\"STAT_LABELS\",{enumerable:true,get:function(){return STAT_LABELS;}});\nObject.defineProperty(__exports,\"weightedAverage\",{enumerable:true,get:function(){return weightedAverage;}});\nObject.defineProperty(__exports,\"extremeRow\",{enumerable:true,get:function(){return extremeRow;}});\nObject.defineProperty(__exports,\"correlation\",{enumerable:true,get:function(){return correlation;}});\nObject.defineProperty(__exports,\"trimmedMean\",{enumerable:true,get:function(){return trimmedMean;}});\nObject.defineProperty(__exports,\"winsorizedMean\",{enumerable:true,get:function(){return winsorizedMean;}});\nObject.defineProperty(__exports,\"modifiedZOutliers\",{enumerable:true,get:function(){return modifiedZOutliers;}});\nObject.defineProperty(__exports,\"jarqueBera\",{enumerable:true,get:function(){return jarqueBera;}});\nObject.defineProperty(__exports,\"weightedQuantile\",{enumerable:true,get:function(){return weightedQuantile;}});\nObject.defineProperty(__exports,\"pairs\",{enumerable:true,get:function(){return pairs;}});\nObject.defineProperty(__exports,\"covariance\",{enumerable:true,get:function(){return covariance;}});\nObject.defineProperty(__exports,\"regression\",{enumerable:true,get:function(){return regression;}});\nObject.defineProperty(__exports,\"spearman\",{enumerable:true,get:function(){return spearman;}});\nObject.defineProperty(__exports,\"kendall\",{enumerable:true,get:function(){return kendall;}});\nObject.defineProperty(__exports,\"seriesStats\",{enumerable:true,get:function(){return seriesStats;}});\nObject.defineProperty(__exports,\"D2_N2\",{enumerable:true,get:function(){return D2_N2;}});\nObject.defineProperty(__exports,\"D4_N2\",{enumerable:true,get:function(){return D4_N2;}});\nObject.defineProperty(__exports,\"movingRanges\",{enumerable:true,get:function(){return movingRanges;}});\nObject.defineProperty(__exports,\"withinSigma\",{enumerable:true,get:function(){return withinSigma;}});\nObject.defineProperty(__exports,\"capability\",{enumerable:true,get:function(){return capability;}});\nObject.defineProperty(__exports,\"controlLimits\",{enumerable:true,get:function(){return controlLimits;}});\nObject.defineProperty(__exports,\"westernElectricViolations\",{enumerable:true,get:function(){return westernElectricViolations;}});\nObject.defineProperty(__exports,\"nelsonViolations\",{enumerable:true,get:function(){return nelsonViolations;}});\nObject.defineProperty(__exports,\"CONTROL_RULE_SETS\",{enumerable:true,get:function(){return CONTROL_RULE_SETS;}});\nObject.defineProperty(__exports,\"controlViolations\",{enumerable:true,get:function(){return controlViolations;}});\nObject.defineProperty(__exports,\"countOutside\",{enumerable:true,get:function(){return countOutside;}});\nObject.defineProperty(__exports,\"histogram\",{enumerable:true,get:function(){return histogram;}});\nObject.defineProperty(__exports,\"DEFAULT_CONFIDENCE\",{enumerable:true,get:function(){return DEFAULT_CONFIDENCE;}});\nObject.defineProperty(__exports,\"meanInterval\",{enumerable:true,get:function(){return meanInterval;}});\nObject.defineProperty(__exports,\"proportionInterval\",{enumerable:true,get:function(){return proportionInterval;}});\nObject.defineProperty(__exports,\"slopeInterval\",{enumerable:true,get:function(){return slopeInterval;}});\nObject.defineProperty(__exports,\"capabilityInterval\",{enumerable:true,get:function(){return capabilityInterval;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst __m1=__req(\"packages/core/src/compute/special.js\");\nconst studentTQuantile=__m1[\"studentTQuantile\"];\nconst normalQuantile=__m1[\"normalQuantile\"];\nconst KENDALL_LIMIT=5000;\nconst MAINTENANCE=Object.freeze({\nvariance:'rescan',\nvarianceP:'rescan',\nstddev:'rescan',\nstddevP:'rescan',\nsumSquares:'rescan',\nweightedAvg:'rescan',\nmedian:'rescan',\np25:'rescan',\np75:'rescan',\np90:'rescan',\np95:'rescan',\np99:'rescan',\niqr:'rescan',\nmode:'rescan',\ndistinct:'rescan',\nrange:'rescan',\nskewness:'rescan',\nkurtosis:'rescan',\ngeomean:'rescan',\nharmean:'rescan',\nmad:'rescan',\nargmin:'rescan',\nargmax:'rescan',\nhhi:'rescan',\nentropy:'rescan',\nevenness:'rescan',\ntop3Share:'rescan',\ntop10Share:'rescan',\ngini:'rescan',\ntrimmedMean:'rescan',\nwinsorizedMean:'rescan',\nrobustOutliers:'rescan',\njarqueBera:'rescan',\n});\nfunction numbers(handle,indices){\nconst n=indices.length;\nconst out=new Float64Array(n);\nlet count=0;\nconst numeric=handle&&(handle.kind==='float64'||handle.kind==='int32');\nif(numeric){\nconst values=handle.values;\nconst present=presenceReader(handle);\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present&&present(row)!==1)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nconst v=typeof raw==='number'?raw:Number(raw);\nif(!Number.isFinite(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nfunction frequencies(handle,indices){\nconst seen=new Map();\nconst read=valueReader(handle);\nlet total=0;\nfor(let i=0;i<indices.length;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nif(typeof raw==='number'&&Number.isNaN(raw))continue;\nconst key=typeof raw==='object'?String(raw):raw;\nseen.set(key,(seen.get(key)||0)+1);\ntotal++;\n}\nconst counts=[...seen.values()].sort((a,b)=>b-a);\nreturn{counts,total,distinct:counts.length};\n}\nfunction sharesOf(freq){\nreturn freq.total>0?freq.counts.map((c)=>c/freq.total):[];\n}\nfunction herfindahl(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))sum+=share*share;\nreturn sum;\n}\nfunction entropy(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum;\n}\nfunction evenness(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total||freq.distinct<2)return freq.total?1:null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum/Math.log2(freq.distinct);\n}\nfunction topShare(handle,indices,n=3){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nconst take=Math.max(1,Math.floor(n));\nlet held=0;\nfor(let i=0;i<Math.min(take,freq.counts.length);i++)held+=freq.counts[i];\nreturn held/freq.total;\n}\nfunction gini(handle,indices){\nconst values=numbers(handle,indices);\nconst n=values.length;\nif(!n)return null;\nconst sorted=values.slice().sort();\nif(sorted[0]<0)return null;\nlet total=0;\nlet weighted=0;\nfor(let i=0;i<n;i++){\ntotal+=sorted[i];\nweighted+=(i+1)*sorted[i];\n}\nif(total===0)return 0;\nreturn(2*weighted)/(n*total)-(n+1)/n;\n}\nfunction moments(values){\nlet n=0;\nlet mean=0;\nlet m2=0;\nfor(let i=0;i<values.length;i++){\nconst x=values[i];\nn++;\nconst delta=x-mean;\nmean+=delta/n;\nm2+=delta*(x-mean);\n}\nreturn{n,mean,m2};\n}\nfunction quantileSorted(sorted,p){\nconst n=sorted.length;\nif(!n)return NaN;\nif(n===1)return sorted[0];\nconst h=(n-1)*Math.min(1,Math.max(0,p));\nconst lo=Math.floor(h);\nconst hi=Math.ceil(h);\nif(lo===hi)return sorted[lo];\nreturn sorted[lo]+(h-lo)*(sorted[hi]-sorted[lo]);\n}\nfunction quantile(values,p){\nif(!values.length)return NaN;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,p);\n}\nconst STAT_FNS=Object.freeze({\nhhi:(h,i)=>herfindahl(h,i),\nentropy:(h,i)=>entropy(h,i),\nevenness:(h,i)=>evenness(h,i),\ntop3Share:(h,i)=>topShare(h,i,3),\ntop10Share:(h,i)=>topShare(h,i,10),\ngini:(h,i)=>gini(h,i),\ntrimmedMean:(h,i)=>trimmedMean(numbers(h,i),0.1),\nwinsorizedMean:(h,i)=>winsorizedMean(numbers(h,i),0.1),\nrobustOutliers:(h,i)=>modifiedZOutliers(numbers(h,i),3.5),\njarqueBera:(h,i)=>jarqueBera(numbers(h,i)),\nvariance:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?m2/(n-1):null;\n},\nvarianceP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?m2/n:null;\n},\nstddev:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?Math.sqrt(m2/(n-1)):null;\n},\nstddevP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?Math.sqrt(m2/n):null;\n},\nmedian:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.5):null;\n},\np25:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.25):null;\n},\np75:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.75):null;\n},\np90:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.9):null;\n},\np95:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.95):null;\n},\np99:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.99):null;\n},\niqr:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,0.75)-quantileSorted(sorted,0.25);\n},\nmad:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst middle=quantile(values,0.5);\nconst deviations=new Float64Array(values.length);\nfor(let k=0;k<values.length;k++)deviations[k]=Math.abs(values[k]-middle);\nreturn quantile(deviations,0.5);\n},\nrange:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet lo=Infinity;\nlet hi=-Infinity;\nfor(let k=0;k<values.length;k++){\nif(values[k]<lo)lo=values[k];\nif(values[k]>hi)hi=values[k];\n}\nreturn hi-lo;\n},\ndistinct:(h,i)=>{\nconst read=valueReader(h);\nconst seen=new Set();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nseen.add(v instanceof Date?v.getTime():v);\n}\nreturn seen.size;\n},\nmode:(h,i)=>{\nconst read=valueReader(h);\nconst counts=new Map();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nconst id=v instanceof Date?v.getTime():v;\ncounts.set(id,(counts.get(id)||0)+1);\n}\nlet best=null;\nlet most=1;\nfor(const[value,times]of counts){\nif(times>most){\nmost=times;\nbest=value;\n}\n}\nreturn best;\n},\nskewness:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<3||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**3;\nreturn(n/((n-1)*(n-2)))*sum;\n},\nkurtosis:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<4||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**4;\nconst a=(n*(n+1))/((n-1)*(n-2)*(n-3));\nconst b=(3*(n-1)**2)/((n-2)*(n-3));\nreturn a*sum-b;\n},\ngeomean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]<=0)return null;\nsum+=Math.log(values[k]);\n}\nreturn Math.exp(sum/values.length);\n},\nharmean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]===0)return null;\nsum+=1/values[k];\n}\nreturn values.length/sum;\n},\nsumSquares:(h,i)=>{\nconst values=numbers(h,i);\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=values[k]*values[k];\nreturn sum;\n},\n});\nconst STAT_LABELS=Object.freeze({\nhhi:'Concentration (HHI)',\nentropy:'Entropy',\nevenness:'Evenness',\ntop3Share:'Top 3 share',\ntop10Share:'Top 10 share',\ngini:'Gini coefficient',\ntrimmedMean:'Trimmed mean',\nwinsorizedMean:'Winsorized mean',\nrobustOutliers:'Outliers (robust)',\njarqueBera:'Jarque–Bera',\nmedian:'Median',\np25:'25th percentile',\np75:'75th percentile',\np90:'90th percentile',\np95:'95th percentile',\np99:'99th percentile',\niqr:'Interquartile range',\nmad:'Median absolute deviation',\nvariance:'Variance',\nvarianceP:'Variance (population)',\nstddev:'Standard deviation',\nstddevP:'Standard deviation (population)',\nrange:'Range',\ndistinct:'Distinct',\nmode:'Mode',\nskewness:'Skewness',\nkurtosis:'Kurtosis',\ngeomean:'Geometric mean',\nharmean:'Harmonic mean',\nsumSquares:'Sum of squares',\nweightedAvg:'Weighted average',\nargmin:'Lowest by',\nargmax:'Highest by',\n});\nfunction weightedAverage(handle,weights,indices){\nconst readValue=valueReader(handle);\nconst readWeight=valueReader(weights);\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(readValue(row));\nconst weight=Number(readWeight(row));\nif(!Number.isFinite(value)||!Number.isFinite(weight))continue;\ntop+=value*weight;\nbottom+=weight;\n}\nreturn bottom===0?null:top/bottom;\n}\nfunction extremeRow(handle,indices,largest){\nconst read=valueReader(handle);\nlet best=null;\nlet bestValue=largest?-Infinity:Infinity;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(read(row));\nif(!Number.isFinite(value))continue;\nif(largest?value>bestValue:value<bestValue){\nbestValue=value;\nbest=row;\n}\n}\nreturn best;\n}\nfunction correlation(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nlet n=0;\nlet sx=0;\nlet sy=0;\nlet sxx=0;\nlet syy=0;\nlet sxy=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nn++;\nsx+=x;\nsy+=y;\nsxx+=x*x;\nsyy+=y*y;\nsxy+=x*y;\n}\nif(n<2)return null;\nconst top=n*sxy-sx*sy;\nconst bottom=Math.sqrt((n*sxx-sx*sx)*(n*syy-sy*sy));\nif(bottom===0)return null;\nconst r=top/bottom;\nreturn Math.max(-1,Math.min(1,r));\n}\nfunction trimmedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst kept=sorted.slice(cut,n-cut);\nif(!kept.length)return quantileSorted(sorted,0.5);\nlet sum=0;\nfor(const v of kept)sum+=v;\nreturn sum/kept.length;\n}\nfunction winsorizedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst low=sorted[cut];\nconst high=sorted[n-1-cut];\nlet sum=0;\nfor(const v of sorted)sum+=Math.min(high,Math.max(low,v));\nreturn sum/n;\n}\nfunction modifiedZOutliers(values,threshold=3.5){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst middle=quantileSorted(sorted,0.5);\nconst deviations=sorted.map((v)=>Math.abs(v-middle)).sort((a,b)=>a-b);\nconst mad=quantileSorted(deviations,0.5);\nif(mad===0)return null;\nlet count=0;\nfor(const v of sorted)if(Math.abs((0.6745*(v-middle))/mad)>threshold)count++;\nreturn count;\n}\nfunction jarqueBera(values){\nconst n=values.length;\nif(n<8)return null;\nlet mean=0;\nfor(const v of values)mean+=v;\nmean/=n;\nlet m2=0;\nlet m3=0;\nlet m4=0;\nfor(const v of values){\nconst d=v-mean;\nm2+=d*d;\nm3+=d*d*d;\nm4+=d*d*d*d;\n}\nm2/=n;\nm3/=n;\nm4/=n;\nif(m2===0)return null;\nconst skew=m3/m2**1.5;\nconst excess=m4/(m2*m2)-3;\nreturn(n/6)*(skew*skew+(excess*excess)/4);\n}\nfunction weightedQuantile(values,weights,p){\nconst paired=[];\nlet total=0;\nfor(let i=0;i<values.length;i++){\nconst v=Number(values[i]);\nconst w=Number(weights[i]);\nif(!Number.isFinite(v)||!Number.isFinite(w)||w<=0)continue;\npaired.push([v,w]);\ntotal+=w;\n}\nif(!paired.length||total<=0)return null;\npaired.sort((a,b)=>a[0]-b[0]);\nif(paired.length===1)return paired[0][0];\nconst at=[];\nlet seen=0;\nfor(const[,w]of paired){\nat.push((seen+w/2)/total);\nseen+=w;\n}\nconst target=Math.max(0,Math.min(1,p));\nif(target<=at[0])return paired[0][0];\nif(target>=at[at.length-1])return paired[paired.length-1][0];\nfor(let i=1;i<at.length;i++){\nif(target>at[i])continue;\nconst span=at[i]-at[i-1];\nconst within=span>0?(target-at[i-1])/span:0;\nreturn paired[i-1][0]+(paired[i][0]-paired[i-1][0])*within;\n}\nreturn paired[paired.length-1][0];\n}\nfunction pairs(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nconst xs=new Float64Array(indices.length);\nconst ys=new Float64Array(indices.length);\nlet n=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nxs[n]=x;\nys[n]=y;\nn++;\n}\nreturn{xs:xs.subarray(0,n),ys:ys.subarray(0,n),n};\n}\nfunction covariance(a,b,indices,population=false){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=(xs[i]-mx)*(ys[i]-my);\nreturn sum/(population?n:n-1);\n}\nfunction regression(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sxx=0;\nlet sxy=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=xs[i]-mx;\nconst dy=ys[i]-my;\nsxx+=dx*dx;\nsxy+=dx*dy;\nsyy+=dy*dy;\n}\nif(sxx===0)return null;\nconst slope=sxy/sxx;\nconst intercept=my-slope*mx;\nconst r2=syy===0?1:Math.max(0,Math.min(1,(sxy*sxy)/(sxx*syy)));\nconst residual=Math.max(0,syy-slope*sxy);\nconst stdError=n>2?Math.sqrt(residual/(n-2)/sxx):0;\nreturn{slope,intercept,r2,stdError,n};\n}\nfunction ranksOf(values){\nconst n=values.length;\nconst order=Array.from({length:n},(unused,i)=>i)\n.sort((i,j)=>values[i]-values[j]);\nconst ranks=new Float64Array(n);\nlet i=0;\nwhile(i<n){\nlet j=i;\nwhile(j+1<n&&values[order[j+1]]===values[order[i]])j++;\nconst shared=(i+j)/2+1;\nfor(let k=i;k<=j;k++)ranks[order[k]]=shared;\ni=j+1;\n}\nreturn ranks;\n}\nfunction spearman(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nconst rx=ranksOf(xs);\nconst ry=ranksOf(ys);\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=rx[i];my+=ry[i];}\nmx/=n;\nmy/=n;\nlet sxy=0;\nlet sxx=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=rx[i]-mx;\nconst dy=ry[i]-my;\nsxy+=dx*dy;\nsxx+=dx*dx;\nsyy+=dy*dy;\n}\nif(sxx===0||syy===0)return null;\nreturn Math.max(-1,Math.min(1,sxy/Math.sqrt(sxx*syy)));\n}\nfunction kendall(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2||n>KENDALL_LIMIT)return null;\nlet concordant=0;\nlet discordant=0;\nlet tiedXOnly=0;\nlet tiedYOnly=0;\nfor(let i=0;i<n;i++){\nfor(let j=i+1;j<n;j++){\nconst dx=Math.sign(xs[i]-xs[j]);\nconst dy=Math.sign(ys[i]-ys[j]);\nconst product=dx*dy;\nif(product>0)concordant++;\nelse if(product<0)discordant++;\nelse if(dx===0&&dy===0){}\nelse if(dx===0)tiedXOnly++;\nelse tiedYOnly++;\n}\n}\nconst orderedByX=concordant+discordant+tiedYOnly;\nconst orderedByY=concordant+discordant+tiedXOnly;\nif(orderedByX===0||orderedByY===0)return null;\nreturn(concordant-discordant)/Math.sqrt(orderedByX*orderedByY);\n}\nfunction seriesStats(ordered,opts={}){\nconst n=ordered.length;\nif(n<2)return null;\nconst first=ordered[0];\nconst last=ordered[n-1];\nconst returns=[];\nfor(let i=1;i<n;i++){\nconst previous=ordered[i-1];\nif(previous===0)continue;\nreturns.push((ordered[i]-previous)/Math.abs(previous));\n}\nlet volatility=null;\nif(returns.length>1){\nlet mean=0;\nfor(const r of returns)mean+=r;\nmean/=returns.length;\nlet m2=0;\nfor(const r of returns)m2+=(r-mean)**2;\nvolatility=Math.sqrt(m2/(returns.length-1));\n}\nconst periods=Number(opts.periodsPerYear)>0?Number(opts.periodsPerYear):null;\nlet peak=ordered[0];\nlet peakAt=0;\nlet worst=0;\nlet worstFrom=0;\nlet worstTo=0;\nfor(let i=1;i<n;i++){\nif(ordered[i]>peak){peak=ordered[i];peakAt=i;continue;}\nif(peak<=0)continue;\nconst fall=(peak-ordered[i])/peak;\nif(fall>worst){worst=fall;worstFrom=peakAt;worstTo=i;}\n}\nlet autocorrelation=null;\nif(n>2){\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<n;i++){\nconst d=ordered[i]-mean;\nbottom+=d*d;\nif(i>0)top+=d*(ordered[i-1]-mean);\n}\nautocorrelation=bottom>0?top/bottom:null;\n}\nlet up=0;\nlet down=0;\nfor(const r of returns){if(r>0)up++;else if(r<0)down++;}\nlet growth=null;\nif(first>0&&last>0){\nconst perPeriod=(last/first)**(1/(n-1))-1;\ngrowth=periods?(1+perPeriod)**periods-1:perPeriod;\n}\nreturn{\nn,\nfirst,\nlast,\nchange:last-first,\nchangePercent:first===0?null:((last-first)/Math.abs(first))*100,\nvolatility,\nannualisedVolatility:volatility!==null&&periods?volatility*Math.sqrt(periods):null,\ngrowth,\nmaxDrawdown:worst,\nmaxDrawdownFrom:worstFrom,\nmaxDrawdownTo:worstTo,\nautocorrelation,\nupDays:up,\ndownDays:down,\n};\n}\nconst D2_N2=1.128;\nconst D4_N2=3.267;\nfunction movingRanges(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst ranges=[];\nfor(let i=1;i<n;i++)ranges.push(Math.abs(ordered[i]-ordered[i-1]));\nconst centre=ranges.reduce((t,r)=>t+r,0)/ranges.length;\nreturn{ranges,centre,upper:D4_N2*centre,lower:0};\n}\nfunction withinSigma(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nlet total=0;\nfor(let i=1;i<n;i++)total+=Math.abs(ordered[i]-ordered[i-1]);\nconst meanRange=total/(n-1);\nreturn{sigma:meanRange/D2_N2,meanRange};\n}\nfunction capability(ordered,spec){\nconst n=ordered.length;\nif(n<2||!spec)return null;\nconst lower=Number.isFinite(Number(spec.lower))?Number(spec.lower):null;\nconst upper=Number.isFinite(Number(spec.upper))?Number(spec.upper):null;\nif(lower===null&&upper===null)return null;\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet m2=0;\nfor(let i=0;i<n;i++)m2+=(ordered[i]-mean)**2;\nconst overall=Math.sqrt(m2/(n-1));\nconst within=withinSigma(ordered);\nconst sigmaWithin=within?within.sigma:null;\nconst indices=(sigma)=>{\nif(!sigma||sigma<=0)return{index:null,k:null};\nconst both=lower!==null&&upper!==null;\nconst index=both?(upper-lower)/(6*sigma):null;\nconst upperSide=upper!==null?(upper-mean)/(3*sigma):Infinity;\nconst lowerSide=lower!==null?(mean-lower)/(3*sigma):Infinity;\nreturn{index,k:Math.min(upperSide,lowerSide)};\n};\nconst short=indices(sigmaWithin);\nconst long=indices(overall);\nlet outOfSpec=0;\nfor(let i=0;i<n;i++){\nif(lower!==null&&ordered[i]<lower){outOfSpec++;continue;}\nif(upper!==null&&ordered[i]>upper)outOfSpec++;\n}\nreturn{\nn,\nmean,\nlower,\nupper,\ntarget:Number.isFinite(Number(spec.target))?Number(spec.target):null,\nsigmaWithin,\nsigmaOverall:overall,\ncp:short.index,\ncpk:short.k,\npp:long.index,\nppk:long.k,\noutOfSpec,\ndefectRate:n?outOfSpec/n:null,\n};\n}\nfunction controlLimits(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst within=withinSigma(ordered);\nif(!within||!(within.sigma>0))return null;\nlet centre=0;\nfor(let i=0;i<n;i++)centre+=ordered[i];\ncentre/=n;\nreturn{\ncentre,\nsigma:within.sigma,\nupper:centre+3*within.sigma,\nlower:centre-3*within.sigma,\n};\n}\nfunction westernElectricViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3){\nout.push({index:i,rule:1,description:'beyond three sigma'});\n}\nif(i>=2){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-2;k<=i;k++)if(z(k)*side>2)hits++;\nif(hits>=2){\nout.push({index:i,rule:2,description:'two of three past two sigma'});\nbreak;\n}\n}\n}\nif(i>=4){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-4;k<=i;k++)if(z(k)*side>1)hits++;\nif(hits>=4){\nout.push({index:i,rule:3,description:'four of five past one sigma'});\nbreak;\n}\n}\n}\nif(i>=7){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-7;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){\nout.push({index:i,rule:4,description:'eight in a row on one side'});\nbreak;\n}\n}\n}\n}\nreturn out;\n}\nfunction nelsonViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst oneSide=(from,to,past,need)=>{\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=from;k<=to;k++)if(z(k)*side>past)hits++;\nif(hits>=need)return true;\n}\nreturn false;\n};\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3)out.push({index:i,rule:1,description:'beyond three sigma'});\nif(i>=8){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-8;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){out.push({index:i,rule:2,description:'nine in a row on one side'});break;}\n}\n}\nif(i>=5){\nfor(const dir of[1,-1]){\nlet all=true;\nfor(let k=i-4;k<=i;k++){\nif((ordered[k]-ordered[k-1])*dir<=0){all=false;break;}\n}\nif(all){\nout.push({index:i,rule:3,description:dir>0?'six rising':'six falling'});\nbreak;\n}\n}\n}\nif(i>=13){\nlet alternating=true;\nfor(let k=i-12;k<=i;k++){\nconst a=ordered[k]-ordered[k-1];\nconst b=ordered[k+1<=i?k+1:k]-ordered[k];\nif(k+1>i)break;\nif(a===0||b===0||(a>0)===(b>0)){alternating=false;break;}\n}\nif(alternating)out.push({index:i,rule:4,description:'fourteen alternating'});\n}\nif(i>=2&&oneSide(i-2,i,2,2)){\nout.push({index:i,rule:5,description:'two of three past two sigma'});\n}\nif(i>=4&&oneSide(i-4,i,1,4)){\nout.push({index:i,rule:6,description:'four of five past one sigma'});\n}\nif(i>=14){\nlet inside=true;\nfor(let k=i-14;k<=i;k++)if(Math.abs(z(k))>=1){inside=false;break;}\nif(inside)out.push({index:i,rule:7,description:'fifteen within one sigma'});\n}\nif(i>=7){\nlet outside=true;\nfor(let k=i-7;k<=i;k++)if(Math.abs(z(k))<=1){outside=false;break;}\nif(outside)out.push({index:i,rule:8,description:'eight beyond one sigma'});\n}\n}\nreturn out;\n}\nconst CONTROL_RULE_SETS=Object.freeze(['westernElectric','nelson']);\nfunction controlViolations(ordered,limits,ruleSet='westernElectric'){\nreturn String(ruleSet)==='nelson'\n?nelsonViolations(ordered,limits)\n:westernElectricViolations(ordered,limits);\n}\nfunction countOutside(values,low,high){\nlet count=0;\nfor(let i=0;i<values.length;i++){\nif(values[i]<low||values[i]>high)count++;\n}\nreturn count;\n}\nfunction histogram(sorted,q1,q3,cap=20){\nconst n=sorted.length;\nif(!n)return[];\nconst min=sorted[0];\nconst max=sorted[n-1];\nif(max===min)return[{from:min,to:max,count:n}];\nconst iqr=q3-q1;\nconst fence=1.5*iqr;\nlet lo=iqr>0?Math.max(min,q1-fence):min;\nlet hi=iqr>0?Math.min(max,q3+fence):max;\nif(!(hi>lo)){lo=min;hi=max;}\nconst width=iqr>0?(2*iqr)/Math.cbrt(n):(hi-lo)/(Math.ceil(Math.log2(n))+1);\nconst count=width>0\n?Math.min(cap,Math.max(1,Math.ceil((hi-lo)/width)))\n:1;\nconst step=(hi-lo)/count;\nconst bins=[];\nfor(let i=0;i<count;i++){\nbins.push({from:lo+i*step,to:lo+(i+1)*step,count:0});\n}\nfor(let i=0;i<n;i++){\nconst at=Math.min(count-1,Math.max(0,Math.floor((sorted[i]-lo)/step)));\nbins[at].count++;\n}\nbins[0].from=min;\nbins[count-1].to=max;\nreturn bins;\n}\nconst DEFAULT_CONFIDENCE=0.95;\nfunction level(conf){\nconst c=Number(conf);\nreturn Number.isFinite(c)&&c>0&&c<1?c:DEFAULT_CONFIDENCE;\n}\nfunction meanInterval(values,conf=DEFAULT_CONFIDENCE){\nconst n=values.length;\nif(n<2)return null;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=values[i];\nconst mean=sum/n;\nlet ss=0;\nfor(let i=0;i<n;i++){const d=values[i]-mean;ss+=d*d;}\nconst sd=Math.sqrt(ss/(n-1));\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,n-1);\nconst margin=(t*sd)/Math.sqrt(n);\nreturn{mean,lower:mean-margin,upper:mean+margin,margin,n,confidence:c};\n}\nfunction proportionInterval(successes,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(successes);\nconst total=Number(n);\nif(!(total>0)||!(k>=0)||k>total)return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst p=k/total;\nconst z2=z*z;\nconst denominator=1+z2/total;\nconst centre=(p+z2/(2*total))/denominator;\nconst half=(z/denominator)\n*Math.sqrt((p*(1-p))/total+z2/(4*total*total));\nreturn{\nproportion:p,\nlower:Math.max(0,centre-half),\nupper:Math.min(1,centre+half),\nn:total,\nconfidence:c,\n};\n}\nfunction slopeInterval(fit,conf=DEFAULT_CONFIDENCE){\nif(!fit||!(fit.n>2)||!Number.isFinite(fit.stdError))return null;\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,fit.n-2);\nconst margin=t*fit.stdError;\nreturn{\nslope:fit.slope,\nlower:fit.slope-margin,\nupper:fit.slope+margin,\nmargin,\nconfidence:c,\n};\n}\nfunction capabilityInterval(index,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(index);\nconst count=Number(n);\nif(!Number.isFinite(k)||!(count>1))return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst margin=z*Math.sqrt(1/(9*count)+(k*k)/(2*(count-1)));\nreturn{index:k,lower:k-margin,upper:k+margin,margin,n:count,confidence:c};\n}\n});\n__def(\"packages/core/src/compute/total.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return TOTAL_FNS;}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return TOTAL_LABELS;}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return totalLabel;}});\nObject.defineProperty(__exports,\"aggregatesFor\",{enumerable:true,get:function(){return aggregatesFor;}});\nObject.defineProperty(__exports,\"aggregateAllowed\",{enumerable:true,get:function(){return aggregateAllowed;}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return collectValues;}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return total;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isFunction=__m0[\"isFunction\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m1[\"presenceReader\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst valueReader=__m1[\"valueReader\"];\nconst __m2=__req(\"packages/core/src/compute/statistics.js\");\nconst STAT_FNS=__m2[\"STAT_FNS\"];\nconst STAT_LABELS=__m2[\"STAT_LABELS\"];\nfunction isNumericBacking(handle){\nreturn!!handle&&(handle.kind==='float64'||handle.kind==='int32');\n}\nfunction sum(handle,indices){\nconst n=indices.length;\nlet acc=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(!Number.isNaN(v))acc+=v;\n}\nreturn acc;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1){\nconst v=values[row];\nif(!Number.isNaN(v))acc+=v;\n}\n}\nreturn acc;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=numberOf(read(indices[i]));\nif(v!==null)acc+=v;\n}\nreturn acc;\n}\nsum.kernel=true;\nfunction countValues(handle,indices){\nconst n=indices.length;\nlet count=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++)if(!Number.isNaN(values[indices[i]]))count++;\nreturn count;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1&&!Number.isNaN(values[row]))count++;\n}\nreturn count;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v!==null&&v!==undefined&&!(typeof v==='number'&&Number.isNaN(v)))count++;\n}\nreturn count;\n}\ncountValues.kernel=true;\nfunction count(handle,indices){\nreturn indices.length;\n}\ncount.kernel=true;\nfunction avg(handle,indices){\nconst values=countValues(handle,indices);\nif(values===0)return null;\nreturn sum(handle,indices)/values;\n}\navg.kernel=true;\nfunction extreme(handle,indices,direction,locale){\nconst n=indices.length;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nlet best=null;\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===0)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nconst read=valueReader(handle);\nconst cmp=valueComparator(locale);\nlet best=null;\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v)))continue;\nif(best===null||(direction<0?cmp(v,best)<0:cmp(v,best)>0))best=v;\n}\nreturn best;\n}\nfunction min(handle,indices,ctx){\nreturn extreme(handle,indices,-1,ctx&&ctx.locale);\n}\nmin.kernel=true;\nfunction max(handle,indices,ctx){\nreturn extreme(handle,indices,1,ctx&&ctx.locale);\n}\nmax.kernel=true;\nfunction first(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[0]);\n}\nfirst.kernel=true;\nfunction last(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[indices.length-1]);\n}\nlast.kernel=true;\nfunction numberOf(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nconst TOTAL_FNS={\nsum,min,max,avg,count,first,last,countValues,\n...STAT_FNS,\n};\nconst TOTAL_LABELS=Object.freeze({\n...STAT_LABELS,\nsum:'Sum',\navg:'Average',\nmin:'Min',\nmax:'Max',\ncount:'Count',\ncountValues:'Count of values',\nfirst:'First',\nlast:'Last',\n});\nfunction totalLabel(fn){\nif(!fn)return'';\nif(typeof fn==='string')return TOTAL_LABELS[fn]||fn;\nreturn'Total';\n}\nconst CHOOSER_ORDER=Object.freeze([\n'sum','avg','min','max','count','countValues','first','last',\n]);\nfunction aggregatesFor(column){\nconst supported=column&&column.dataType\n&&column.dataType.totals&&column.dataType.totals.supported;\nif(Array.isArray(supported))return supported.slice();\nconst named=CHOOSER_ORDER.filter((name)=>name in TOTAL_FNS);\nfor(const name of Object.keys(TOTAL_FNS))if(!named.includes(name))named.push(name);\nreturn named;\n}\nfunction aggregateAllowed(column,name){\nif(typeof name!=='string')return true;\nreturn aggregatesFor(column).includes(name);\n}\nfunction collectValues(handle,indices){\nconst read=valueReader(handle);\nconst out=[];\nfor(let i=0;i<indices.length;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined)continue;\nout.push(v);\n}\nreturn out;\n}\nfunction total(handle,indices,fn,ctx){\nconst list=indices||[];\nif(typeof fn==='string'){\nconst kernel=TOTAL_FNS[fn];\nif(!kernel){\nwarnOnce(`total:${fn}`,`unknown total function \"${fn}\"; register it in config.totalFns`);\nreturn null;\n}\nreturn kernel(handle,list,ctx);\n}\nif(isFunction(fn)){\nif(fn.kernel===true)return fn(handle,list,ctx);\nreturn fn(collectValues(handle,list),ctx||{});\n}\nreturn null;\n}\n});\n__def(\"packages/core/src/compute/pivot.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return KEY_DELIMITER;}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return DEFAULT_PATH_SEPARATOR;}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return DEFAULT_MAX_COLUMNS;}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return pivotKey;}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return joinPath;}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return resolvePivotKeys;}});\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return pivot;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nconst packKeys=__m2[\"packKeys\"];\nconst __m3=__req(\"packages/core/src/compute/total.js\");\nconst total=__m3[\"total\"];\nconst KEY_DELIMITER='|';\nconst DEFAULT_PATH_SEPARATOR='/';\nconst DEFAULT_MAX_COLUMNS=2000;\nfunction pivotKey(groupPath,pivotPath,colId){\nreturn`${groupPath}${KEY_DELIMITER}${pivotPath}${KEY_DELIMITER}${colId}`;\n}\nfunction joinPath(parts,separator){\nlet out='';\nfor(let i=0;i<parts.length;i++){\nconst v=parts[i];\nout+=(i===0?'':separator)+(v===null||v===undefined?'':String(v));\n}\nreturn out;\n}\nfunction resolvePivotKeys(handles,order,opts={}){\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst n=order.length;\nconst{keyOf,readers}=packKeys(handles,order,0);\nconst seen=new Map();\nconst tuples=[];\nconst rawKeys=[];\nfor(let i=0;i<n;i++){\nconst row=order[i];\nconst key=keyOf(row);\nif(seen.has(key))continue;\nseen.set(key,tuples.length);\nrawKeys.push(key);\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\ntuples.push(tuple);\n}\nconst cmp=valueComparator(opts.locale);\nconst rank=tuples.map((_,i)=>i);\nrank.sort((a,b)=>{\nconst ta=tuples[a];\nconst tb=tuples[b];\nfor(let j=0;j<ta.length;j++){\nconst c=compareNullable(ta[j],tb[j],cmp);\nif(c!==0)return c;\n}\nreturn a-b;\n});\nconst keys=new Array(rank.length);\nconst paths=new Array(rank.length);\nconst idByKey=new Map();\nfor(let position=0;position<rank.length;position++){\nconst from=rank[position];\nkeys[position]=tuples[from];\npaths[position]=joinPath(tuples[from],separator);\nidByKey.set(rawKeys[from],position);\n}\nconst idOf=(row)=>{\nconst id=idByKey.get(keyOf(row));\nreturn id===undefined?-1:id;\n};\nreturn{keys,paths,idOf};\n}\nfunction compareNullable(a,b,cmp){\nconst na=a===null||a===undefined;\nconst nb=b===null||b===undefined;\nif(na||nb)return na&&nb?0:na?1:-1;\nreturn cmp(a,b);\n}\nfunction resolveValueColumns(opts){\nconst declared=opts.values||opts.totals||[];\nif(declared.length&&typeof declared[0]==='object'&&declared[0]!==null){\nreturn declared.filter((entry)=>entry&&entry.handle);\n}\nconst resolve=typeof opts.handle==='function'?opts.handle:null;\nif(!resolve){\nif(declared.length){\nwarnOnce('pivot:handles',\n'pivot was given total column ids but no handle(colId) resolver, so no cell values were reduced. Pass values: [{ colId, handle, fn }] or opts.handle.');\n}\nreturn[];\n}\nconst totalOf=typeof opts.totalOf==='function'?opts.totalOf:null;\nconst out=[];\nfor(const colId of declared){\nconst handle=resolve(colId);\nif(!handle)continue;\nout.push({colId,handle,fn:totalOf?totalOf(colId):'sum'});\n}\nreturn out;\n}\nfunction normaliseArgs(a,b,c){\nif(Array.isArray(a)){\nconst opts=c||{};\nreturn{...opts,pivotHandles:a,order:b||null,groups:opts.groups||null};\n}\nreturn a||{};\n}\nfunction pivot(input,orderArg,optsArg){\nconst opts=normaliseArgs(input,orderArg,optsArg);\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst valueColumns=resolveValueColumns(opts);\nconst maxColumns=opts.maxColumns===undefined?DEFAULT_MAX_COLUMNS:opts.maxColumns;\nconst groups=opts.groups&&opts.groups.buckets?opts.groups:null;\nconst buckets=groups?groups.buckets:[opts.order||new Uint32Array(0)];\nconst groupPaths=opts.groupPaths\n||(groups?groups.keys.map((tuple)=>joinPath(tuple,separator)):['']);\nconst scope=concatIndices(buckets);\nconst{keys,paths,idOf}=resolvePivotKeys(opts.pivotHandles||[],scope,opts);\nconst columns=paths.length*Math.max(1,valueColumns.length);\nconst fields=derivedFields(paths,valueColumns,separator);\nif(maxColumns&&columns>maxColumns){\nconst empty=new Map();\nreturn{\nkeys,\npaths,\nfields,\ngroupPaths,\ncolumns,\nvalues:empty,\ncells:empty,\nerror:{\ncode:'pivot-max-columns',\nmessage:`[lattice] pivot would generate ${columns} columns, above pivot.maxColumns of ${maxColumns}. Narrow the pivot columns or raise the limit.`,\ncolumns,\nmaxColumns,\n},\n};\n}\nconst cells=new Map();\nconst keyCount=paths.length;\nfor(let g=0;g<buckets.length;g++){\nconst bucket=buckets[g];\nconst groupPath=groupPaths[g]===undefined?'':groupPaths[g];\nconst n=bucket.length;\nif(n===0)continue;\nconst ids=new Int32Array(n);\nconst counts=new Uint32Array(keyCount+1);\nfor(let i=0;i<n;i++){\nconst id=idOf(bucket[i]);\nids[i]=id;\nif(id>=0)counts[id+1]++;\n}\nfor(let k=0;k<keyCount;k++)counts[k+1]+=counts[k];\nconst scattered=new Uint32Array(n);\nconst cursor=counts.slice(0,keyCount);\nfor(let i=0;i<n;i++){\nconst id=ids[i];\nif(id>=0)scattered[cursor[id]++]=bucket[i];\n}\nfor(let k=0;k<keyCount;k++){\nconst from=counts[k];\nconst to=counts[k+1];\nif(to===from)continue;\nconst slice=scattered.subarray(from,to);\nfor(let c=0;c<valueColumns.length;c++){\nconst column=valueColumns[c];\nconst result=total(column.handle,slice,column.fn,opts.totalContext||{locale:opts.locale});\ncells.set(pivotKey(groupPath,paths[k],column.colId),result);\n}\n}\n}\nreturn{keys,paths,fields,groupPaths,columns,values:cells,cells,error:null};\n}\nfunction derivedFields(paths,valueColumns,separator){\nif(valueColumns.length===0)return paths.slice();\nconst out=[];\nfor(const path of paths){\nfor(const column of valueColumns)out.push(`${path}${separator}${column.colId}`);\n}\nreturn out;\n}\nfunction concatIndices(buckets){\nif(buckets.length===1)return buckets[0]||new Uint32Array(0);\nlet n=0;\nfor(const b of buckets)n+=b?b.length:0;\nconst out=new Uint32Array(n);\nlet at=0;\nfor(const b of buckets){\nif(!b||b.length===0)continue;\nout.set(b,at);\nat+=b.length;\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/compute/reference.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return referenceValue;}});\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return referenceSort;}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return referenceFilter;}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return referencePasses;}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return referenceGroup;}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return referenceTotal;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst getPath=__m0[\"getPath\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst isMissing=__m1[\"isMissing\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/filter.js\");\nconst testValue=__m2[\"testValue\"];\nconst KEY_SEPARATOR=String.fromCharCode(0x1f);\nconst NULL_MARKER=String.fromCharCode(0x00);\nfunction referenceValue(row,col){\nconst v=col.includes('.')?getPath(row,col):(row==null?undefined:row[col]);\nreturn v===undefined?null:v;\n}\nfunction referenceSort(rows,entries,opts={}){\nconst list=entries||[];\nlet order=rows.map((_,i)=>i);\nif(list.length===0)return order;\nfor(let e=list.length-1;e>=0;e--){\norder=referenceSortOne(rows,order,list[e],opts);\n}\nreturn order;\n}\nfunction referenceSortOne(rows,order,entry,opts){\nconst locale=entry.locale!==undefined?entry.locale:opts.locale;\nconst base=valueComparator(locale);\nconst descending=entry.descending!==undefined?!!entry.descending:entry.dir==='desc';\nconst present=[];\nconst absent=[];\nfor(const i of order){\nconst v=referenceValue(rows[i],entry.col);\nif(isMissing(v))absent.push(i);else present.push(i);\n}\nconst position=new Map();\nfor(let p=0;p<present.length;p++)position.set(present[p],p);\nconst compare=(a,b)=>{\nconst va=referenceValue(rows[a],entry.col);\nconst vb=referenceValue(rows[b],entry.col);\nlet c;\nif(typeof entry.compare==='function'){\nc=entry.compare(va,vb,rows[a],rows[b],descending);\nif(descending)c=-c;\n}else{\nc=descending?base(vb,va):base(va,vb);\n}\nreturn c!==0?c:position.get(a)-position.get(b);\n};\npresent.sort(compare);\nreturn entry.nullsFirst?absent.concat(present):present.concat(absent);\n}\nfunction referenceFilter(rows,filters,opts={}){\nconst out=[];\nfor(let i=0;i<rows.length;i++){\nif(referencePasses(rows[i],filters,opts,i))out.push(i);\n}\nreturn out;\n}\nfunction referencePasses(row,node,opts,index){\nif(!node)return true;\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nif(children.length===0)return true;\nif(node.op==='or')return children.some((c)=>referencePasses(row,c,opts,index));\nconst all=children.every((c)=>referencePasses(row,c,opts,index));\nreturn node.op==='not'?!all:all;\n}\nif(node.col===undefined&&typeof opts.custom==='function')return!!opts.custom(node,row,index);\nreturn testValue(referenceValue(row,node.col),node,opts.locale);\n}\nfunction referenceGroup(rows,cols,order){\nconst source=order||rows.map((_,i)=>i);\nconst seen=new Map();\nconst keys=[];\nconst buckets=[];\nfor(const i of source){\nconst tuple=cols.map((col)=>referenceValue(rows[i],col));\nconst key=tuple\n.map((v)=>(v===null||v===undefined?NULL_MARKER:String(v)))\n.join(KEY_SEPARATOR);\nlet at=seen.get(key);\nif(at===undefined){\nat=keys.length;\nseen.set(key,at);\nkeys.push(tuple);\nbuckets.push([]);\n}\nbuckets[at].push(i);\n}\nreturn{keys,buckets};\n}\nfunction referenceTotal(values,fn,opts={}){\nconst cmp=valueComparator(opts.locale);\nconst live=values.filter((v)=>!isMissing(v));\nconst numbers=live.map(toNumberOrNull).filter((v)=>v!==null);\nswitch(fn){\ncase'count':return values.length;\ncase'countValues':return live.length;\ncase'sum':return numbers.reduce((a,b)=>a+b,0);\ncase'avg':return live.length===0?null:numbers.reduce((a,b)=>a+b,0)/live.length;\ncase'min':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)<0?b:a));\ncase'max':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)>0?b:a));\ncase'first':return values.length===0?null:normaliseNull(values[0]);\ncase'last':return values.length===0?null:normaliseNull(values[values.length-1]);\ndefault:return null;\n}\n}\nfunction toNumberOrNull(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nfunction normaliseNull(v){\nreturn v===undefined?null:v;\n}\n});\n__def(\"packages/core/src/compute/index.js\",function(__exports,__req){\n'use strict';\nconst __m0=__req(\"packages/core/src/compute/sort.js\");\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return __m0[\"sortColumn\"];}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return __m0[\"sortMulti\"];}});\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return __m0[\"radixSortFloat64\"];}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return __m0[\"radixSortInt32\"];}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return __m0[\"rankSortDictionary\"];}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return __m0[\"mergeSortComparator\"];}});\nconst __m1=__req(\"packages/core/src/compute/filter.js\");\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return __m1[\"evaluateFilters\"];}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return __m1[\"evaluateCondition\"];}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return __m1[\"compact\"];}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return __m1[\"testValue\"];}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return __m1[\"compilePredicate\"];}});\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return __m1[\"releaseMask\"];}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return __m1[\"pruneColumn\"];}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return __m1[\"mentionsColumn\"];}});\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return __m2[\"groupByColumns\"];}});\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return __m2[\"packKeys\"];}});\nconst __m3=__req(\"packages/core/src/compute/facet.js\");\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return __m3[\"facet\"];}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return __m3[\"computeBounds\"];}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return __m3[\"countInto\"];}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return __m3[\"bucketOf\"];}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return __m3[\"facetKind\"];}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return __m3[\"cardinalityOf\"];}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return __m3[\"pickGranularity\"];}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return __m3[\"floorTo\"];}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return __m3[\"advance\"];}});\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return __m3[\"STRATEGIES\"];}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return __m3[\"GRANULARITIES\"];}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return __m3[\"DEFAULT_BUCKETS\"];}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return __m3[\"DEFAULT_CARDINALITY_LIMIT\"];}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return __m3[\"QUANTILE_SAMPLE\"];}});\nconst __m4=__req(\"packages/core/src/compute/total.js\");\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return __m4[\"TOTAL_FNS\"];}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return __m4[\"TOTAL_LABELS\"];}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return __m4[\"totalLabel\"];}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return __m4[\"total\"];}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return __m4[\"collectValues\"];}});\nconst __m5=__req(\"packages/core/src/compute/pivot.js\");\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return __m5[\"pivot\"];}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return __m5[\"resolvePivotKeys\"];}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return __m5[\"pivotKey\"];}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return __m5[\"joinPath\"];}});\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return __m5[\"KEY_DELIMITER\"];}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return __m5[\"DEFAULT_PATH_SEPARATOR\"];}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return __m5[\"DEFAULT_MAX_COLUMNS\"];}});\nconst __m6=__req(\"packages/core/src/compute/reference.js\");\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return __m6[\"referenceSort\"];}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return __m6[\"referenceFilter\"];}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return __m6[\"referenceGroup\"];}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return __m6[\"referenceTotal\"];}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return __m6[\"referencePasses\"];}});\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return __m6[\"referenceValue\"];}});\nconst __m7=__req(\"packages/core/src/compute/handle.js\");\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return __m7[\"identity\"];}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return __m7[\"rowCount\"];}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return __m7[\"presenceReader\"];}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return __m7[\"bitReader\"];}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return __m7[\"valueReader\"];}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return __m7[\"valueComparator\"];}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return __m7[\"numericTotalOrder\"];}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return __m7[\"dictRanks\"];}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return __m7[\"dictSize\"];}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return __m7[\"dictValue\"];}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return __m7[\"multiValue\"];}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return __m7[\"isMissing\"];}});\n});\n__def(\"packages/worker/src/kernel.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"loadCompute\",{enumerable:true,get:function(){return loadCompute;}});\nObject.defineProperty(__exports,\"setCompute\",{enumerable:true,get:function(){return setCompute;}});\nObject.defineProperty(__exports,\"dispatch\",{enumerable:true,get:function(){return dispatch;}});\nObject.defineProperty(__exports,\"handleMessage\",{enumerable:true,get:function(){return handleMessage;}});\nObject.defineProperty(__exports,\"installKernel\",{enumerable:true,get:function(){return installKernel;}});\nconst __m0=__req(\"packages/worker/src/transport.js\");\nconst PROTOCOL=__m0[\"PROTOCOL\"];\nconst OPS=__m0[\"OPS\"];\nconst CONTROL=__m0[\"CONTROL\"];\nconst ERRORS=__m0[\"ERRORS\"];\nconst unpackHandle=__m0[\"unpackHandle\"];\nconst unpackHandles=__m0[\"unpackHandles\"];\nconst createMaskPool=__m0[\"createMaskPool\"];\nconst collectTransfers=__m0[\"collectTransfers\"];\nconst __m1=__req(\"packages/core/src/store/columnpack.js\");\nconst packChunk=__m1[\"packChunk\"];\nconst packedTransfers=__m1[\"packedTransfers\"];\nlet computeModule=null;\nlet computePromise=null;\nlet computeError=null;\nasync function loadCompute(loader){\nif(computeModule)return computeModule;\nif(!computePromise){\nconst load=loader||(()=>Promise.resolve(__req(\"packages/core/src/compute/index.js\")));\ncomputePromise=Promise.resolve()\n.then(load)\n.then((mod)=>{computeModule=mod;return mod;})\n.catch((err)=>{\ncomputeError=err;\ncomputeModule=null;\nreturn null;\n});\n}\nreturn computePromise;\n}\nfunction setCompute(mod){\ncomputeModule=mod;\ncomputePromise=mod?Promise.resolve(mod):null;\ncomputeError=mod?null:computeError;\n}\nfunction filterContext(handles,count,locale){\nconst byId=new Map();\nfor(const h of handles)if(h)byId.set(h.id,h);\nreturn{\nhandle(colId){return byId.get(colId);},\ncount,\npool:createMaskPool(),\nlocale,\n};\n}\nfunction dispatch(request,compute){\nconst{op,args}=request;\nif(op===OPS.COLUMNIZE){\nreturn packChunk(args.schema||[],args.rows||[],args.opts||{});\n}\nconst fn=compute[op];\nif(typeof fn!=='function'){\nconst err=new Error(`[lattice] compute kernel '${op}' is not exported`);\n(err).code=ERRORS.NO_KERNEL;\nthrow err;\n}\nswitch(op){\ncase OPS.SORT_COLUMN:\nreturn fn(unpackHandle(args.handle),args.order??null,args.opts||{});\ncase OPS.SORT_MULTI:{\nconst handles=unpackHandles(args.handles||[]);\nconst entries=(args.entries||[]).map((e)=>({\n...e,\nhandle:handles[e.index],\n}));\nreturn fn(handles,entries,args.order??null);\n}\ncase OPS.EVALUATE_FILTERS:\nreturn fn(args.filters,filterContext(unpackHandles(args.handles||[]),args.count,args.locale));\ncase OPS.COMPACT:\nreturn fn(args.mask,args.count,undefined);\ncase OPS.GROUP_BY_COLUMNS:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.TOTAL:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.fn);\ncase OPS.PIVOT:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.FACET:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.count,args.opts||{});\ndefault:{\nconst err=new Error(`[lattice] unknown worker op '${op}'`);\n(err).code=ERRORS.PROTOCOL;\nthrow err;\n}\n}\n}\nasync function handleMessage(message,opts={}){\nif(!message||message.lattice!==PROTOCOL)return null;\nconst{id,op}=message;\nif(op===CONTROL.CANCEL){\nopts.cancelled?.add(message.target);\nreturn null;\n}\nif(op===CONTROL.PING){\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result:'pong'},transfer:[]};\n}\nif(op===OPS.COLUMNIZE){\nif(opts.cancelled?.has(id)){opts.cancelled.delete(id);return null;}\ntry{\nconst result=packChunk(message.args.schema||[],message.args.rows||[],message.args.opts||{});\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:packedTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{lattice:PROTOCOL,id,ok:false,error:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack}},\ntransfer:[],\n};\n}\n}\nconst compute=await loadCompute(opts.loader);\nif(!compute){\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{\ncode:ERRORS.NO_COMPUTE,\nmessage:`[lattice] compute kernels unavailable in worker: ${computeError?computeError.message:'module not found'}`,\n},\n},\ntransfer:[],\n};\n}\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\ntry{\nconst result=dispatch(message,compute);\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:collectTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack},\n},\ntransfer:[],\n};\n}\n}\nfunction installKernel(scope,opts={}){\nconst cancelled=new Set();\nconst onMessage=async(event)=>{\nconst outcome=await handleMessage(event.data,{loader:opts.loader,cancelled});\nif(!outcome)return;\nscope.postMessage(outcome.reply,outcome.transfer);\n};\nscope.addEventListener('message',onMessage);\nloadCompute(opts.loader).then((mod)=>{\nscope.postMessage({lattice:PROTOCOL,id:0,op:CONTROL.READY,compute:!!mod});\n});\nreturn()=>scope.removeEventListener('message',onMessage);\n}\n});\nvar __entry=__req(\"packages/worker/src/kernel.js\");\nroot[\"__latticeKernel\"]=__entry;\n})(typeof globalThis!=='undefined'?globalThis:this);\n__latticeKernel.installKernel(self);\n",{type:'classic'});
|
|
67870
69197
|
}catch(err){}
|
|
67871
69198
|
const __entry=__req("packages/dom/src/index.js");
|
|
67872
69199
|
export const
|