@platforma-open/platforma-open.titeseq-analysis 2.4.0 → 2.5.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/dist/index.js CHANGED
@@ -1,4 +1,23 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
2
+ //#region ../model/dist/fitSettings.js
3
+ /** The read coverage both equations require, at the values each fit used on its own. */
4
+ const READ_COVERAGE_DEFAULTS = {
5
+ minReadsPerConcentration: 3,
6
+ minConcentrationPoints: 5
7
+ };
8
+ /** The settings only `hill_gate_index` reads, at the values the block shipped through 2.4.0. */
9
+ const HILL_GATE_INDEX_DEFAULTS = {
10
+ r2ThresholdGood: .8,
11
+ r2ThresholdFailed: .5,
12
+ nMin: .5,
13
+ nMax: 2,
14
+ hookEffectThresholdBin: .2,
15
+ hookEffectThresholdNoBin: .02,
16
+ hookEffectMinReads: 20
17
+ };
18
+ /** Adams 2016's floor, two thirds of the gate range, to three decimals. */
19
+ const DEFAULT_PLATEAU_FLOOR = .667;
20
+ //#endregion
2
21
  //#region ../model/dist/templateParams.js
3
22
  /**
4
23
  * What a project template carries out of a configured block — the mirror image of
@@ -16,7 +35,18 @@ function deriveTemplateParams(data) {
16
35
  binColumnRef: data.binColumnRef,
17
36
  antigenColumnRef: data.antigenColumnRef,
18
37
  sortFractionColumnRef: data.sortFractionColumnRef,
38
+ binFluorescenceColumnRef: data.binFluorescenceColumnRef,
19
39
  targetAntigen: data.targetAntigen,
40
+ equation: data.equation,
41
+ plateauFloor: data.plateauFloor,
42
+ r2GateMin: data.r2GateMin,
43
+ kdSeGateMax: data.kdSeGateMax,
44
+ requireAllConcentrations: data.requireAllConcentrations,
45
+ replicateColumnRef: data.replicateColumnRef,
46
+ replicateErrorModel: data.replicateErrorModel,
47
+ replicateFitErrorCutoff: data.replicateFitErrorCutoff,
48
+ replicateR2Floor: data.replicateR2Floor,
49
+ replicateCensoredMajority: data.replicateCensoredMajority,
20
50
  minReadsPerConcentration: data.minReadsPerConcentration,
21
51
  minConcentrationPoints: data.minConcentrationPoints,
22
52
  r2ThresholdGood: data.r2ThresholdGood,
@@ -32,7 +62,7 @@ function deriveTemplateParams(data) {
32
62
  //#endregion
33
63
  //#region ../kind/dist/package.js
34
64
  var name = "@platforma-open/platforma-open.titeseq-analysis.kind";
35
- var version$1 = "1.1.0";
65
+ var version$1 = "1.2.0";
36
66
  //#endregion
37
67
  //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/params.js
38
68
  /**
@@ -124,14 +154,14 @@ function defineBlockKind(meta) {
124
154
  });
125
155
  }
126
156
  //#endregion
127
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/plugin_handle.js
157
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/plugin_handle.js
128
158
  const PLUGIN_OUTPUT_PREFIX = "plugin-output#";
129
159
  /** Construct the output key for a plugin output in the block outputs map. */
130
160
  function pluginOutputKey(handle, outputKey) {
131
161
  return `${PLUGIN_OUTPUT_PREFIX}${handle}#${outputKey}`;
132
162
  }
133
163
  //#endregion
134
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/block_storage.js
164
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/block_storage.js
135
165
  /**
136
166
  * Discriminator key for BlockStorage format detection.
137
167
  * This unique hash-based key identifies data as BlockStorage vs legacy formats.
@@ -3948,7 +3978,7 @@ objectType({
3948
3978
  content: stringType()
3949
3979
  });
3950
3980
  //#endregion
3951
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/bmodel/block_kind_ref.js
3981
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/bmodel/block_kind_ref.js
3952
3982
  /**
3953
3983
  * Compose a {@link BlockKindReference} from a kind's `name`/`version`.
3954
3984
  *
@@ -3964,7 +3994,7 @@ objectType({
3964
3994
  to: numberType().min(1)
3965
3995
  });
3966
3996
  //#endregion
3967
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/util.js
3997
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/util.js
3968
3998
  function assertNever(x) {
3969
3999
  throw new Error("Unexpected object: " + x);
3970
4000
  }
@@ -3976,7 +4006,7 @@ function uniqueBy(array, makeId) {
3976
4006
  return [...new Map(array.map((e) => [makeId(e), e])).values()];
3977
4007
  }
3978
4008
  //#endregion
3979
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
4009
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
3980
4010
  /**
3981
4011
  * Type guard function that checks if the given value is a valid DataInfo.
3982
4012
  *
@@ -4165,7 +4195,7 @@ function entriesToDataInfo(dataInfoEntries) {
4165
4195
  }
4166
4196
  }
4167
4197
  //#endregion
4168
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/errors.js
4198
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/errors.js
4169
4199
  var ServiceError = class extends Error {
4170
4200
  name = "ServiceError";
4171
4201
  };
@@ -4189,7 +4219,7 @@ function ensureError(value) {
4189
4219
  return new Error(stringifyValue(value));
4190
4220
  }
4191
4221
  //#endregion
4192
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/json.js
4222
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/json.js
4193
4223
  var import_canonicalize = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
4194
4224
  module.exports = function serialize(object) {
4195
4225
  if (typeof object === "number" && isNaN(object)) throw new Error("NaN is not allowed");
@@ -4222,7 +4252,7 @@ function parseJsonSafely(value, fallback) {
4222
4252
  }
4223
4253
  }
4224
4254
  //#endregion
4225
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4255
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4226
4256
  function readMetadata(metadata, key) {
4227
4257
  return metadata?.[key];
4228
4258
  }
@@ -4550,7 +4580,7 @@ function matchAxisId(query, target) {
4550
4580
  return query.name === target.name && matchDomain$1(query.domain, target.domain) && matchDomain$1(query.contextDomain, target.contextDomain);
4551
4581
  }
4552
4582
  //#endregion
4553
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
4583
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
4554
4584
  const BOOLEAN_TYPES = /* @__PURE__ */ new Set([
4555
4585
  "numericComparison",
4556
4586
  "stringEquals",
@@ -4655,7 +4685,7 @@ function collectSpecQueryColumns(query) {
4655
4685
  return result;
4656
4686
  }
4657
4687
  //#endregion
4658
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
4688
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
4659
4689
  function mapPTableDef(def, cb) {
4660
4690
  return {
4661
4691
  ...def,
@@ -4698,7 +4728,7 @@ function mapJoinEntry(entry, cb) {
4698
4728
  }
4699
4729
  }
4700
4730
  //#endregion
4701
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
4731
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
4702
4732
  function getPTableColumnId(spec) {
4703
4733
  switch (spec.type) {
4704
4734
  case "axis": return {
@@ -4712,7 +4742,7 @@ function getPTableColumnId(spec) {
4712
4742
  }
4713
4743
  }
4714
4744
  //#endregion
4715
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
4745
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
4716
4746
  function stringifyColumnFilteredId(key) {
4717
4747
  return canonicalizeJson(createColumnFilteredKey(key));
4718
4748
  }
@@ -4745,7 +4775,7 @@ function applyAxisFilters(spec, axisFilters) {
4745
4775
  };
4746
4776
  }
4747
4777
  //#endregion
4748
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
4778
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
4749
4779
  function isPObjectId(value) {
4750
4780
  if (typeof value !== "string") return false;
4751
4781
  return isPObjectKey(parseJsonSafely(value));
@@ -4832,7 +4862,7 @@ function extractAllColumns(entry) {
4832
4862
  return [...columns.values()];
4833
4863
  }
4834
4864
  //#endregion
4835
- //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.5/node_modules/@milaboratories/helpers/dist/utils.js
4865
+ //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.6/node_modules/@milaboratories/helpers/dist/utils.js
4836
4866
  function isNil$1(v) {
4837
4867
  return v === null || v === void 0;
4838
4868
  }
@@ -4865,13 +4895,13 @@ function isPlainObject$1(value) {
4865
4895
  return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
4866
4896
  }
4867
4897
  //#endregion
4868
- //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.5/node_modules/@milaboratories/helpers/dist/error.js
4898
+ //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.6/node_modules/@milaboratories/helpers/dist/error.js
4869
4899
  function throwError(v) {
4870
4900
  if (typeof v === "string") throw new Error(v);
4871
4901
  else throw v;
4872
4902
  }
4873
4903
  //#endregion
4874
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
4904
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
4875
4905
  function isColumnDiscoveredKey(obj) {
4876
4906
  return typeof obj === "object" && obj !== null && "__isDiscovered" in obj;
4877
4907
  }
@@ -4946,7 +4976,7 @@ function isString$1(value) {
4946
4976
  return typeof value === "string";
4947
4977
  }
4948
4978
  //#endregion
4949
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
4979
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
4950
4980
  /**
4951
4981
  * Canonically serializes a column key to a branded string id. Accepts both
4952
4982
  * the new {@link ColumnUniversalKey} and the deprecated {@link UniversalPColumnId}
@@ -5120,7 +5150,7 @@ function extractPObjectId(id) {
5120
5150
  throw new Error(`extractPObjectId: unrecognized column id structure: ${JSON.stringify(id)}`);
5121
5151
  }
5122
5152
  //#endregion
5123
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
5153
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
5124
5154
  function isColumnOverriddenKey(obj) {
5125
5155
  return typeof obj === "object" && obj !== null && "__isOverridden" in obj;
5126
5156
  }
@@ -5242,7 +5272,7 @@ function mergeRecord(a, b) {
5242
5272
  };
5243
5273
  }
5244
5274
  //#endregion
5245
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5275
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5246
5276
  function axisKey(axis) {
5247
5277
  return (0, import_canonicalize.default)(getAxisId(axis));
5248
5278
  }
@@ -5488,7 +5518,7 @@ function isAnchorAxisRef(value) {
5488
5518
  return typeof value === "object" && "anchor" in value;
5489
5519
  }
5490
5520
  //#endregion
5491
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5521
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5492
5522
  /**
5493
5523
  * Determines if an axis ID matches an axis selector.
5494
5524
  *
@@ -5614,7 +5644,7 @@ function multiColumnSelectorsToPredicate(selectors) {
5614
5644
  return (spec) => isPColumnSpec(spec) && arr.some((sel) => matchMultiColumnSelector(spec, sel));
5615
5645
  }
5616
5646
  //#endregion
5617
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5647
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5618
5648
  function deriveNativeId(spec) {
5619
5649
  const result = {
5620
5650
  kind: spec.kind,
@@ -5626,7 +5656,7 @@ function deriveNativeId(spec) {
5626
5656
  return (0, import_canonicalize.default)(result);
5627
5657
  }
5628
5658
  //#endregion
5629
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5659
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5630
5660
  var LinkerMap = class LinkerMap {
5631
5661
  /** Graph of linkers connected by axes (single or grouped by parents) */
5632
5662
  data;
@@ -5803,7 +5833,7 @@ var LinkerMap = class LinkerMap {
5803
5833
  }
5804
5834
  };
5805
5835
  //#endregion
5806
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
5836
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
5807
5837
  /**
5808
5838
  * Required PFrames version. Bump this in lockstep with the `@milaboratories/pframes-rs-*`
5809
5839
  * version in `pnpm-workspace.yaml` so blocks built against the new SDK refuse to load on
@@ -5859,7 +5889,7 @@ function plRefsEqual(ref1, ref2, ignoreEnrichments = false) {
5859
5889
  return ref1.blockId === ref2.blockId && ref1.name === ref2.name && (ignoreEnrichments || ref1.requireEnrichments === ref2.requireEnrichments);
5860
5890
  }
5861
5891
  //#endregion
5862
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
5892
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
5863
5893
  function mapValueInVOE(voe, cb) {
5864
5894
  return voe.ok ? {
5865
5895
  ok: true,
@@ -5867,7 +5897,7 @@ function mapValueInVOE(voe, cb) {
5867
5897
  } : voe;
5868
5898
  }
5869
5899
  //#endregion
5870
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
5900
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
5871
5901
  /** Well-known resource type names used across the platform. */
5872
5902
  const ResourceTypeName = {
5873
5903
  StreamManager: "StreamManager",
@@ -5916,7 +5946,7 @@ const ResourceTypeName = {
5916
5946
  SharedEnvelope: "SharedEnvelope"
5917
5947
  };
5918
5948
  //#endregion
5919
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
5949
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
5920
5950
  const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
5921
5951
  const { service, isNodeService, isWasmService, isMainService, getServiceKind, getServiceModelMethods, getServiceUiMethods } = (() => {
5922
5952
  const typeMap = /* @__PURE__ */ new Map();
@@ -5955,7 +5985,7 @@ const { service, isNodeService, isWasmService, isMainService, getServiceKind, ge
5955
5985
  };
5956
5986
  })();
5957
5987
  //#endregion
5958
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
5988
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
5959
5989
  const Services = {
5960
5990
  PFrameSpec: service()({
5961
5991
  type: "wasm",
@@ -6049,7 +6079,7 @@ function resolveRequiredServices(flags) {
6049
6079
  }
6050
6080
  Object.fromEntries(Object.keys(Services).map((key) => [`requires${key}`, true]));
6051
6081
  //#endregion
6052
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
6082
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
6053
6083
  function buildMethodMap(pick) {
6054
6084
  const result = {};
6055
6085
  for (const id of Object.values(Services)) result[id] = [...pick(id)];
@@ -6058,7 +6088,7 @@ function buildMethodMap(pick) {
6058
6088
  buildMethodMap(getServiceUiMethods);
6059
6089
  buildMethodMap(getServiceModelMethods);
6060
6090
  //#endregion
6061
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
6091
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
6062
6092
  /** Resource types that hold column collections — DFS stops here and collects. */
6063
6093
  const COLLECT_TYPES = [ResourceTypeName.PFrame];
6064
6094
  /** Resource types DFS descends through when looking for PFrames. */
@@ -6166,7 +6196,7 @@ function indexPoolBlock(block) {
6166
6196
  return result;
6167
6197
  }
6168
6198
  //#endregion
6169
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6199
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6170
6200
  /**
6171
6201
  * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
6172
6202
  * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
@@ -6203,7 +6233,7 @@ var ColumnRegistry = class {
6203
6233
  }
6204
6234
  };
6205
6235
  //#endregion
6206
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
6236
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
6207
6237
  /**
6208
6238
  * Two-track dedup over an item stream keyed by `ColumnUniversalId`:
6209
6239
  *
@@ -6244,7 +6274,7 @@ function dedupColumns(items, getId, getSpec) {
6244
6274
  return out;
6245
6275
  }
6246
6276
  //#endregion
6247
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6277
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6248
6278
  /**
6249
6279
  * Generic entries provider over a single accessor root. Walks `<root>` once
6250
6280
  * from the supplied `rootPath`, builds an id → {@link LeafEntry} map and
@@ -6301,7 +6331,7 @@ var ResultPoolEntriesProvider = class {
6301
6331
  }
6302
6332
  };
6303
6333
  //#endregion
6304
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/template/template_ref_form.js
6334
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/template/template_ref_form.js
6305
6335
  /**
6306
6336
  * Whether `value` is a reference in the readable spelling.
6307
6337
  *
@@ -6370,7 +6400,7 @@ function expandTemplatePlRef(ref) {
6370
6400
  };
6371
6401
  }
6372
6402
  //#endregion
6373
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/template/template_relocate.js
6403
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.54.1/node_modules/@milaboratories/pl-model-common/dist/template/template_relocate.js
6374
6404
  /**
6375
6405
  * Point every column identifier in a block's params at the blocks of the project being built.
6376
6406
  *
@@ -6430,7 +6460,7 @@ function relocateBlockIds(params, blockIds) {
6430
6460
  return walk(params);
6431
6461
  }
6432
6462
  //#endregion
6433
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/block_migrations.js
6463
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/block_migrations.js
6434
6464
  /** Create a DataVersioned wrapper with correct shape */
6435
6465
  function makeVersionedData(version, data) {
6436
6466
  return {
@@ -6742,9 +6772,10 @@ var DataModelInitialChain = class extends DataModelMigrationChain {
6742
6772
  if (data !== null && typeof data === "object" && "args" in data) return fn(data);
6743
6773
  return data;
6744
6774
  };
6775
+ const initialVersion = this.versionChain[0];
6745
6776
  const step = {
6746
6777
  fromVersion: DATA_MODEL_LEGACY_VERSION,
6747
- toVersion: this.versionChain[0],
6778
+ toVersion: initialVersion,
6748
6779
  migrate: wrappedFn
6749
6780
  };
6750
6781
  return new DataModelMigrationChainWithRecover({
@@ -7008,7 +7039,7 @@ var DataModel = class DataModel {
7008
7039
  }
7009
7040
  };
7010
7041
  //#endregion
7011
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/internal.js
7042
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/internal.js
7012
7043
  /** Utility code helping to identify whether the code is running in actual UI environment */
7013
7044
  function isInUI() {
7014
7045
  return typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined";
@@ -7078,7 +7109,7 @@ function registerFutureAwait(handle, onResolve) {
7078
7109
  futureResolves.get(handle).push(onResolve);
7079
7110
  }
7080
7111
  //#endregion
7081
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
7112
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
7082
7113
  /**
7083
7114
  * All facade callback names as constants.
7084
7115
  * These are the source of truth - the interface is derived from these.
@@ -7116,7 +7147,7 @@ function registerFacadeCallbacks(callbacks) {
7116
7147
  for (const key of Object.values(BlockStorageFacadeCallbacks)) tryRegisterCallback(key, callbacks[key]);
7117
7148
  }
7118
7149
  //#endregion
7119
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/services/block_services.js
7150
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/services/block_services.js
7120
7151
  /**
7121
7152
  * Services required by all V3 blocks by default.
7122
7153
  * Edit this when a new service should be available to all blocks.
@@ -7132,7 +7163,7 @@ const BLOCK_SERVICE_FLAGS = {
7132
7163
  };
7133
7164
  resolveRequiredServices(BLOCK_SERVICE_FLAGS);
7134
7165
  //#endregion
7135
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/future.js
7166
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/future.js
7136
7167
  var FutureRef = class FutureRef {
7137
7168
  handle;
7138
7169
  postProcess;
@@ -7160,7 +7191,7 @@ var FutureRef = class FutureRef {
7160
7191
  }
7161
7192
  };
7162
7193
  //#endregion
7163
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/accessor.js
7194
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/accessor.js
7164
7195
  function ifDef(value, cb) {
7165
7196
  return value === void 0 ? void 0 : cb(value);
7166
7197
  }
@@ -7410,11 +7441,11 @@ var TreeNodeAccessor = class TreeNodeAccessor {
7410
7441
  }
7411
7442
  };
7412
7443
  //#endregion
7413
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/internal.js
7444
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/internal.js
7414
7445
  const MainAccessorName = "main";
7415
7446
  const StagingAccessorName = "staging";
7416
7447
  //#endregion
7417
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7448
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7418
7449
  function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7419
7450
  const sortedFilters = [...axisFilters].sort((a, b) => b[0] - a[0]);
7420
7451
  const { type } = dataInfoEntries;
@@ -7478,7 +7509,7 @@ function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7478
7509
  }
7479
7510
  }
7480
7511
  //#endregion
7481
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7512
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7482
7513
  /**
7483
7514
  * Structural postfix derivation for linked columns (phase 2 of `deriveDistinctLabels`).
7484
7515
  *
@@ -7650,7 +7681,10 @@ function resolveGroup(entries, indices, format) {
7650
7681
  * linked columns by the difference between their sources.
7651
7682
  */
7652
7683
  function derivePostfixes(entries, format = defaultLinkerFormatter) {
7653
- const postfix = [...entries.reduce((acc, e, idx) => acc.set(e.stem, [...acc.get(e.stem) ?? [], idx]), /* @__PURE__ */ new Map()).values()].reduce((acc, idxs) => {
7684
+ const postfix = [...entries.reduce((acc, e, idx) => {
7685
+ const key = `${e.stem}\u0000${e.marker ?? ""}`;
7686
+ return acc.set(key, [...acc.get(key) ?? [], idx]);
7687
+ }, /* @__PURE__ */ new Map()).values()].reduce((acc, idxs) => {
7654
7688
  if (idxs.length < 2) return acc;
7655
7689
  const resolved = resolveGroup(idxs.map((i) => entries[i]), idxs, format);
7656
7690
  return idxs.reduce((m, i, k) => m.set(i, resolved[k]), acc);
@@ -7661,7 +7695,7 @@ function derivePostfixes(entries, format = defaultLinkerFormatter) {
7661
7695
  });
7662
7696
  }
7663
7697
  //#endregion
7664
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7698
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7665
7699
  const DISTANCE_PENALTY = .001;
7666
7700
  const LABEL_TYPE = "__LABEL__";
7667
7701
  const LABEL_TYPE_FULL = "__LABEL__@1";
@@ -7683,9 +7717,10 @@ function isSyntheticType(t) {
7683
7717
  function deriveDistinctLabels(values, options = {}) {
7684
7718
  const stems = deriveStems(values, options);
7685
7719
  return derivePostfixes(values.map((v, i) => {
7686
- const { spec, linkerPath } = extractEntryParts(v);
7720
+ const { spec, linkerPath, marker } = extractEntryParts(v);
7687
7721
  return {
7688
7722
  stem: stems[i],
7723
+ marker,
7689
7724
  hit: spec,
7690
7725
  linkers: (linkerPath ?? []).map((s) => s.spec)
7691
7726
  };
@@ -7737,13 +7772,15 @@ function extractEntryParts(entry) {
7737
7772
  spec: entry,
7738
7773
  extraTrace: void 0,
7739
7774
  linkerPath: void 0,
7740
- qualifications: void 0
7775
+ qualifications: void 0,
7776
+ marker: void 0
7741
7777
  };
7742
7778
  return {
7743
7779
  spec: entry.spec,
7744
7780
  extraTrace: entry.extraTrace,
7745
7781
  linkerPath: entry.linkerPath,
7746
- qualifications: entry.qualifications
7782
+ qualifications: entry.qualifications,
7783
+ marker: entry.marker
7747
7784
  };
7748
7785
  }
7749
7786
  function formatQualification(q) {
@@ -8090,7 +8127,7 @@ function repairBareLabels(labels, minimized, records, stats, forceTraceElements,
8090
8127
  return patched;
8091
8128
  }
8092
8129
  //#endregion
8093
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/util/label.js
8130
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/util/label.js
8094
8131
  /** @deprecated Use deriveDistinctLabels */
8095
8132
  function deriveLabels(values, getSpec, options = {}) {
8096
8133
  return deriveDistinctLabels(values.map(getSpec), options).map((label, i) => ({
@@ -8099,15 +8136,17 @@ function deriveLabels(values, getSpec, options = {}) {
8099
8136
  }));
8100
8137
  }
8101
8138
  //#endregion
8102
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
8103
- const RT_RESOURCE_MAP = "PColumnData/ResourceMap";
8104
- const RT_RESOURCE_MAP_PARTITIONED = "PColumnData/Partitioned/ResourceMap";
8105
- const RT_JSON_PARTITIONED = "PColumnData/JsonPartitioned";
8106
- const RT_BINARY_PARTITIONED = "PColumnData/BinaryPartitioned";
8107
- const RT_PARQUET_PARTITIONED = "PColumnData/ParquetPartitioned";
8108
- const RT_JSON_SUPER_PARTITIONED = "PColumnData/Partitioned/JsonPartitioned";
8109
- const RT_BINARY_SUPER_PARTITIONED = "PColumnData/Partitioned/BinaryPartitioned";
8110
- const RT_PARQUET_SUPER_PARTITIONED = "PColumnData/Partitioned/ParquetPartitioned";
8139
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
8140
+ const PCD_PREFIX = "PColumnData/";
8141
+ const RT_RESOURCE_MAP = PCD_PREFIX + "ResourceMap";
8142
+ const RT_RESOURCE_MAP_PARTITIONED = PCD_PREFIX + "Partitioned/ResourceMap";
8143
+ const RT_JSON_PARTITIONED = PCD_PREFIX + "JsonPartitioned";
8144
+ const RT_BINARY_PARTITIONED = PCD_PREFIX + "BinaryPartitioned";
8145
+ const RT_PARQUET_PARTITIONED = PCD_PREFIX + "ParquetPartitioned";
8146
+ const PCD_SUP_PREFIX = PCD_PREFIX + "Partitioned/";
8147
+ const RT_JSON_SUPER_PARTITIONED = PCD_SUP_PREFIX + "JsonPartitioned";
8148
+ const RT_BINARY_SUPER_PARTITIONED = PCD_SUP_PREFIX + "BinaryPartitioned";
8149
+ const RT_PARQUET_SUPER_PARTITIONED = PCD_SUP_PREFIX + "ParquetPartitioned";
8111
8150
  const removeIndexSuffix = (keyStr) => {
8112
8151
  if (keyStr.endsWith(".index")) return {
8113
8152
  baseKey: keyStr.substring(0, keyStr.length - 6),
@@ -8393,7 +8432,7 @@ function allPColumnsReady(columns) {
8393
8432
  return columns.every(isPColumnReady);
8394
8433
  }
8395
8434
  //#endregion
8396
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
8435
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
8397
8436
  function isPColumnValues(value) {
8398
8437
  if (!Array.isArray(value)) return false;
8399
8438
  if (value.length === 0) return true;
@@ -8427,9 +8466,10 @@ function splitFiltersToAxisFilter(splitFilters) {
8427
8466
  }
8428
8467
  function fallbackIdDeriver(originalId, axisFilters) {
8429
8468
  if (!axisFilters || axisFilters.length === 0) return originalId;
8469
+ const filtersToCanonicalize = [...axisFilters].sort((a, b) => a[0] - b[0]);
8430
8470
  return (0, import_canonicalize.default)({
8431
8471
  id: originalId,
8432
- axisFilters: [...axisFilters].sort((a, b) => a[0] - b[0])
8472
+ axisFilters: filtersToCanonicalize
8433
8473
  });
8434
8474
  }
8435
8475
  /** Checks if a selector object uses any anchor properties */
@@ -8671,7 +8711,7 @@ var PColumnCollection = class {
8671
8711
  }
8672
8712
  };
8673
8713
  //#endregion
8674
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8714
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8675
8715
  /**
8676
8716
  * Builds a ServiceProxy from a ServiceDispatch.
8677
8717
  * Each service method call is forwarded to dispatch.callServiceMethod.
@@ -8680,7 +8720,7 @@ function createServiceProxy(dispatch) {
8680
8720
  return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
8681
8721
  }
8682
8722
  //#endregion
8683
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/services/get_services.js
8723
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/services/get_services.js
8684
8724
  const cachedServices = /* @__PURE__ */ new WeakMap();
8685
8725
  function getService(name, deps) {
8686
8726
  const ctx = deps?.ctx ?? getCfgRenderCtx();
@@ -8694,7 +8734,7 @@ function getService(name, deps) {
8694
8734
  })();
8695
8735
  }
8696
8736
  //#endregion
8697
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8737
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8698
8738
  function patchInSetFilters(filters) {
8699
8739
  const inSetToOrEqual = (predicate) => {
8700
8740
  if (predicate.operator !== "InSet") return predicate;
@@ -8732,7 +8772,7 @@ function patchInSetFilters(filters) {
8732
8772
  return filters.map((filter) => mapFilter(filter, inSetToOrEqual));
8733
8773
  }
8734
8774
  //#endregion
8735
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/render/api.js
8775
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/render/api.js
8736
8776
  /**
8737
8777
  * Helper function to match domain objects
8738
8778
  * @param query Optional domain to match against
@@ -8783,11 +8823,13 @@ var ResultPool = class {
8783
8823
  let refsWithEnrichments = false;
8784
8824
  if (typeof opts !== "undefined") {
8785
8825
  if (typeof opts === "function") labelOps = opts;
8786
- else if (typeof opts === "object") if ("includeNativeLabel" in opts || "separator" in opts || "addLabelAsSuffix" in opts) labelOps = opts;
8787
- else {
8788
- opts = opts;
8789
- labelOps = opts.label ?? {};
8790
- refsWithEnrichments = opts.refsWithEnrichments ?? false;
8826
+ else if (typeof opts === "object") {
8827
+ if ("includeNativeLabel" in opts || "separator" in opts || "addLabelAsSuffix" in opts) labelOps = opts;
8828
+ else {
8829
+ opts = opts;
8830
+ labelOps = opts.label ?? {};
8831
+ refsWithEnrichments = opts.refsWithEnrichments ?? false;
8832
+ }
8791
8833
  }
8792
8834
  }
8793
8835
  if (typeof labelOps === "object") return deriveLabels(filtered, (o) => o.obj, labelOps ?? {}).map(({ value: { ref }, label }) => ({
@@ -9181,27 +9223,27 @@ var PluginRenderCtx = class extends RenderCtxBase {
9181
9223
  }
9182
9224
  };
9183
9225
  //#endregion
9184
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/plugin_model.js
9226
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/plugin_model.js
9185
9227
  /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
9186
9228
  * identical across multiple `@platforma-sdk/model` copies in one process. */
9187
9229
  const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
9188
9230
  //#endregion
9189
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/version.js
9190
- const PlatformaSDKVersion = "1.85.0";
9231
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/version.js
9232
+ const PlatformaSDKVersion = "1.86.3";
9191
9233
  //#endregion
9192
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/bconfig/types.js
9234
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/bconfig/types.js
9193
9235
  function isConfigLambda(cfgOrFh) {
9194
9236
  return cfgOrFh.__renderLambda === true;
9195
9237
  }
9196
9238
  //#endregion
9197
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
9239
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
9198
9240
  function downgradeCfgOrLambda(data) {
9199
9241
  if (data === void 0) return void 0;
9200
9242
  if (isConfigLambda(data)) return data.handle;
9201
9243
  return data;
9202
9244
  }
9203
9245
  //#endregion
9204
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
9246
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
9205
9247
  /**
9206
9248
  * BlockStorage Callback Implementations - wired to facade callbacks in BlockModelV3.done().
9207
9249
  *
@@ -9555,7 +9597,7 @@ function deriveTemplateParamsFromStorage(storageJson, deriveTemplateParams) {
9555
9597
  }
9556
9598
  }
9557
9599
  //#endregion
9558
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/block_model.js
9600
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/block_model.js
9559
9601
  /**
9560
9602
  * Merges two feature flag objects with type-aware logic:
9561
9603
  * - `supports*` (boolean): OR — `true` if either side is `true`
@@ -9921,7 +9963,7 @@ var BlockModelV3 = class BlockModelV3 {
9921
9963
  }
9922
9964
  };
9923
9965
  //#endregion
9924
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9966
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9925
9967
  /** Create id for column copy with added keys in axes domains */
9926
9968
  const colId = (id, domains, contextDomains) => {
9927
9969
  let wid = id.toString();
@@ -10027,7 +10069,7 @@ function getAdditionalColumnsForColumn(blockAxes, column) {
10027
10069
  })];
10028
10070
  }
10029
10071
  //#endregion
10030
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
10072
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
10031
10073
  /**
10032
10074
  * Replace every column leaf whose id equals `fromId` with `toId`, leaving
10033
10075
  * other column refs (linkers, sub-anchors) intact. Wrapper recipes
@@ -10045,1214 +10087,657 @@ function rebrandLeafId(node, fromId, toId) {
10045
10087
  return mapSpecQueryColumns(node, { column: (id) => id === fromId ? toId : id });
10046
10088
  }
10047
10089
  //#endregion
10048
- //#region ../node_modules/.pnpm/lru-cache@11.2.4/node_modules/lru-cache/dist/esm/index.js
10049
- /**
10050
- * @module LRUCache
10051
- */
10052
- const defaultPerf = typeof performance === "object" && performance && typeof performance.now === "function" ? performance : Date;
10053
- const warned = /* @__PURE__ */ new Set();
10054
- /* c8 ignore start */
10055
- const PROCESS = typeof process === "object" && !!process ? process : {};
10056
- /* c8 ignore start */
10057
- const emitWarning = (msg, type, code, fn) => {
10058
- typeof PROCESS.emitWarning === "function" ? PROCESS.emitWarning(msg, type, code, fn) : console.error(`[${code}] ${type}: ${msg}`);
10059
- };
10060
- let AC = globalThis.AbortController;
10061
- let AS = globalThis.AbortSignal;
10062
- /* c8 ignore start */
10063
- if (typeof AC === "undefined") {
10064
- AS = class AbortSignal {
10065
- onabort;
10066
- _onabort = [];
10067
- reason;
10068
- aborted = false;
10069
- addEventListener(_, fn) {
10070
- this._onabort.push(fn);
10071
- }
10072
- };
10073
- AC = class AbortController {
10074
- constructor() {
10075
- warnACPolyfill();
10076
- }
10077
- signal = new AS();
10078
- abort(reason) {
10079
- if (this.signal.aborted) return;
10080
- this.signal.reason = reason;
10081
- this.signal.aborted = true;
10082
- for (const fn of this.signal._onabort) fn(reason);
10083
- this.signal.onabort?.(reason);
10084
- }
10085
- };
10086
- let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== "1";
10087
- const warnACPolyfill = () => {
10088
- if (!printACPolyfillWarning) return;
10089
- printACPolyfillWarning = false;
10090
- emitWarning("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.", "NO_ABORT_CONTROLLER", "ENOTSUP", warnACPolyfill);
10091
- };
10092
- }
10093
- /* c8 ignore stop */
10094
- const shouldWarn = (code) => !warned.has(code);
10095
- const isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n);
10096
- /* c8 ignore start */
10097
- const getUintArray = (max) => !isPosInt(max) ? null : max <= Math.pow(2, 8) ? Uint8Array : max <= Math.pow(2, 16) ? Uint16Array : max <= Math.pow(2, 32) ? Uint32Array : max <= Number.MAX_SAFE_INTEGER ? ZeroArray : null;
10098
- /* c8 ignore stop */
10099
- var ZeroArray = class extends Array {
10100
- constructor(size) {
10101
- super(size);
10102
- this.fill(0);
10103
- }
10104
- };
10105
- var Stack = class Stack {
10090
+ //#region ../node_modules/.pnpm/lru-cache@11.5.3/node_modules/lru-cache/dist/esm/browser/index.min.js
10091
+ var L = { hasSubscribers: !1 };
10092
+ var S = L;
10093
+ var W = L;
10094
+ var M = typeof performance == "object" && performance && typeof performance.now == "function" ? performance : Date;
10095
+ var R = () => S.hasSubscribers || W.hasSubscribers;
10096
+ var j = /* @__PURE__ */ new Set();
10097
+ var I = typeof process == "object" && process ? process : {};
10098
+ var P = (d, e, t, i) => {
10099
+ typeof I.emitWarning == "function" ? I.emitWarning(d, e, t, i) : console.error(`[${t}] ${e}: ${d}`);
10100
+ };
10101
+ var k = (d) => !j.has(d);
10102
+ var T = (d) => !!d && d === Math.floor(d) && d > 0 && isFinite(d);
10103
+ var G = (d) => T(d) ? d <= Math.pow(2, 8) ? Uint8Array : d <= Math.pow(2, 16) ? Uint16Array : d <= Math.pow(2, 32) ? Uint32Array : d <= Number.MAX_SAFE_INTEGER ? O : null : null;
10104
+ var O = class extends Array {
10105
+ constructor(e) {
10106
+ super(e), this.fill(0);
10107
+ }
10108
+ };
10109
+ var x = class d {
10106
10110
  heap;
10107
10111
  length;
10108
- static #constructing = false;
10109
- static create(max) {
10110
- const HeapCls = getUintArray(max);
10111
- if (!HeapCls) return [];
10112
- Stack.#constructing = true;
10113
- const s = new Stack(max, HeapCls);
10114
- Stack.#constructing = false;
10115
- return s;
10116
- }
10117
- constructor(max, HeapCls) {
10118
- /* c8 ignore start */
10119
- if (!Stack.#constructing) throw new TypeError("instantiate Stack using Stack.create(n)");
10120
- /* c8 ignore stop */
10121
- this.heap = new HeapCls(max);
10122
- this.length = 0;
10123
- }
10124
- push(n) {
10125
- this.heap[this.length++] = n;
10112
+ static #o = !1;
10113
+ static create(e) {
10114
+ let t = G(e);
10115
+ if (!t) return [];
10116
+ d.#o = !0;
10117
+ let i = new d(e, t);
10118
+ return d.#o = !1, i;
10119
+ }
10120
+ constructor(e, t) {
10121
+ if (!d.#o) throw new TypeError("instantiate Stack using Stack.create(n)");
10122
+ this.heap = new t(e), this.length = 0;
10123
+ }
10124
+ push(e) {
10125
+ this.heap[this.length++] = e;
10126
10126
  }
10127
10127
  pop() {
10128
10128
  return this.heap[--this.length];
10129
10129
  }
10130
10130
  };
10131
- /**
10132
- * Default export, the thing you're using this module to get.
10133
- *
10134
- * The `K` and `V` types define the key and value types, respectively. The
10135
- * optional `FC` type defines the type of the `context` object passed to
10136
- * `cache.fetch()` and `cache.memo()`.
10137
- *
10138
- * Keys and values **must not** be `null` or `undefined`.
10139
- *
10140
- * All properties from the options object (with the exception of `max`,
10141
- * `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are
10142
- * added as normal public members. (The listed options are read-only getters.)
10143
- *
10144
- * Changing any of these will alter the defaults for subsequent method calls.
10145
- */
10146
- var LRUCache = class LRUCache {
10147
- #max;
10148
- #maxSize;
10149
- #dispose;
10150
- #onInsert;
10151
- #disposeAfter;
10152
- #fetchMethod;
10153
- #memoMethod;
10154
- #perf;
10155
- /**
10156
- * {@link LRUCache.OptionsBase.perf}
10157
- */
10131
+ var U = class d {
10132
+ #o;
10133
+ #c;
10134
+ #S;
10135
+ #O;
10136
+ #w;
10137
+ #M;
10138
+ #I;
10139
+ #m;
10158
10140
  get perf() {
10159
- return this.#perf;
10141
+ return this.#m;
10160
10142
  }
10161
- /**
10162
- * {@link LRUCache.OptionsBase.ttl}
10163
- */
10164
10143
  ttl;
10165
- /**
10166
- * {@link LRUCache.OptionsBase.ttlResolution}
10167
- */
10168
10144
  ttlResolution;
10169
- /**
10170
- * {@link LRUCache.OptionsBase.ttlAutopurge}
10171
- */
10172
10145
  ttlAutopurge;
10173
- /**
10174
- * {@link LRUCache.OptionsBase.updateAgeOnGet}
10175
- */
10176
10146
  updateAgeOnGet;
10177
- /**
10178
- * {@link LRUCache.OptionsBase.updateAgeOnHas}
10179
- */
10180
10147
  updateAgeOnHas;
10181
- /**
10182
- * {@link LRUCache.OptionsBase.allowStale}
10183
- */
10184
10148
  allowStale;
10185
- /**
10186
- * {@link LRUCache.OptionsBase.noDisposeOnSet}
10187
- */
10188
10149
  noDisposeOnSet;
10189
- /**
10190
- * {@link LRUCache.OptionsBase.noUpdateTTL}
10191
- */
10192
10150
  noUpdateTTL;
10193
- /**
10194
- * {@link LRUCache.OptionsBase.maxEntrySize}
10195
- */
10196
10151
  maxEntrySize;
10197
- /**
10198
- * {@link LRUCache.OptionsBase.sizeCalculation}
10199
- */
10200
10152
  sizeCalculation;
10201
- /**
10202
- * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection}
10203
- */
10204
10153
  noDeleteOnFetchRejection;
10205
- /**
10206
- * {@link LRUCache.OptionsBase.noDeleteOnStaleGet}
10207
- */
10208
10154
  noDeleteOnStaleGet;
10209
- /**
10210
- * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort}
10211
- */
10212
10155
  allowStaleOnFetchAbort;
10213
- /**
10214
- * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection}
10215
- */
10216
10156
  allowStaleOnFetchRejection;
10217
- /**
10218
- * {@link LRUCache.OptionsBase.ignoreFetchAbort}
10219
- */
10220
10157
  ignoreFetchAbort;
10221
- #size;
10222
- #calculatedSize;
10223
- #keyMap;
10224
- #keyList;
10225
- #valList;
10226
- #next;
10227
- #prev;
10228
- #head;
10229
- #tail;
10230
- #free;
10231
- #disposed;
10232
- #sizes;
10233
- #starts;
10234
- #ttls;
10235
- #autopurgeTimers;
10236
- #hasDispose;
10237
- #hasFetchMethod;
10238
- #hasDisposeAfter;
10239
- #hasOnInsert;
10240
- /**
10241
- * Do not call this method unless you need to inspect the
10242
- * inner workings of the cache. If anything returned by this
10243
- * object is modified in any way, strange breakage may occur.
10244
- *
10245
- * These fields are private for a reason!
10246
- *
10247
- * @internal
10248
- */
10249
- static unsafeExposeInternals(c) {
10158
+ backgroundFetchSize;
10159
+ #n;
10160
+ #b;
10161
+ #s;
10162
+ #i;
10163
+ #t;
10164
+ #l;
10165
+ #u;
10166
+ #a;
10167
+ #h;
10168
+ #y;
10169
+ #r;
10170
+ #_;
10171
+ #F;
10172
+ #d;
10173
+ #g;
10174
+ #T;
10175
+ #U;
10176
+ #f;
10177
+ #D;
10178
+ static unsafeExposeInternals(e) {
10250
10179
  return {
10251
- starts: c.#starts,
10252
- ttls: c.#ttls,
10253
- autopurgeTimers: c.#autopurgeTimers,
10254
- sizes: c.#sizes,
10255
- keyMap: c.#keyMap,
10256
- keyList: c.#keyList,
10257
- valList: c.#valList,
10258
- next: c.#next,
10259
- prev: c.#prev,
10180
+ starts: e.#F,
10181
+ ttls: e.#d,
10182
+ autopurgeTimers: e.#g,
10183
+ sizes: e.#_,
10184
+ keyMap: e.#s,
10185
+ keyList: e.#i,
10186
+ valList: e.#t,
10187
+ next: e.#l,
10188
+ prev: e.#u,
10260
10189
  get head() {
10261
- return c.#head;
10190
+ return e.#a;
10262
10191
  },
10263
10192
  get tail() {
10264
- return c.#tail;
10193
+ return e.#h;
10265
10194
  },
10266
- free: c.#free,
10267
- isBackgroundFetch: (p) => c.#isBackgroundFetch(p),
10268
- backgroundFetch: (k, index, options, context) => c.#backgroundFetch(k, index, options, context),
10269
- moveToTail: (index) => c.#moveToTail(index),
10270
- indexes: (options) => c.#indexes(options),
10271
- rindexes: (options) => c.#rindexes(options),
10272
- isStale: (index) => c.#isStale(index)
10195
+ free: e.#y,
10196
+ isBackgroundFetch: (t) => e.#e(t),
10197
+ backgroundFetch: (t, i, s, n) => e.#P(t, i, s, n),
10198
+ moveToTail: (t) => e.#L(t),
10199
+ indexes: (t) => e.#A(t),
10200
+ rindexes: (t) => e.#z(t),
10201
+ isStale: (t) => e.#p(t)
10273
10202
  };
10274
10203
  }
10275
- /**
10276
- * {@link LRUCache.OptionsBase.max} (read-only)
10277
- */
10278
10204
  get max() {
10279
- return this.#max;
10205
+ return this.#o;
10280
10206
  }
10281
- /**
10282
- * {@link LRUCache.OptionsBase.maxSize} (read-only)
10283
- */
10284
10207
  get maxSize() {
10285
- return this.#maxSize;
10208
+ return this.#c;
10286
10209
  }
10287
- /**
10288
- * The total computed size of items in the cache (read-only)
10289
- */
10290
10210
  get calculatedSize() {
10291
- return this.#calculatedSize;
10211
+ return this.#b;
10292
10212
  }
10293
- /**
10294
- * The number of items stored in the cache (read-only)
10295
- */
10296
10213
  get size() {
10297
- return this.#size;
10214
+ return this.#n;
10298
10215
  }
10299
- /**
10300
- * {@link LRUCache.OptionsBase.fetchMethod} (read-only)
10301
- */
10302
10216
  get fetchMethod() {
10303
- return this.#fetchMethod;
10217
+ return this.#M;
10304
10218
  }
10305
10219
  get memoMethod() {
10306
- return this.#memoMethod;
10220
+ return this.#I;
10307
10221
  }
10308
- /**
10309
- * {@link LRUCache.OptionsBase.dispose} (read-only)
10310
- */
10311
10222
  get dispose() {
10312
- return this.#dispose;
10223
+ return this.#S;
10313
10224
  }
10314
- /**
10315
- * {@link LRUCache.OptionsBase.onInsert} (read-only)
10316
- */
10317
10225
  get onInsert() {
10318
- return this.#onInsert;
10226
+ return this.#O;
10319
10227
  }
10320
- /**
10321
- * {@link LRUCache.OptionsBase.disposeAfter} (read-only)
10322
- */
10323
10228
  get disposeAfter() {
10324
- return this.#disposeAfter;
10325
- }
10326
- constructor(options) {
10327
- const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, onInsert, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort, perf } = options;
10328
- if (perf !== void 0) {
10329
- if (typeof perf?.now !== "function") throw new TypeError("perf option must have a now() method if specified");
10330
- }
10331
- this.#perf = perf ?? defaultPerf;
10332
- if (max !== 0 && !isPosInt(max)) throw new TypeError("max option must be a nonnegative integer");
10333
- const UintArray = max ? getUintArray(max) : Array;
10334
- if (!UintArray) throw new Error("invalid max value: " + max);
10335
- this.#max = max;
10336
- this.#maxSize = maxSize;
10337
- this.maxEntrySize = maxEntrySize || this.#maxSize;
10338
- this.sizeCalculation = sizeCalculation;
10339
- if (this.sizeCalculation) {
10340
- if (!this.#maxSize && !this.maxEntrySize) throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
10341
- if (typeof this.sizeCalculation !== "function") throw new TypeError("sizeCalculation set to non-function");
10342
- }
10343
- if (memoMethod !== void 0 && typeof memoMethod !== "function") throw new TypeError("memoMethod must be a function if defined");
10344
- this.#memoMethod = memoMethod;
10345
- if (fetchMethod !== void 0 && typeof fetchMethod !== "function") throw new TypeError("fetchMethod must be a function if specified");
10346
- this.#fetchMethod = fetchMethod;
10347
- this.#hasFetchMethod = !!fetchMethod;
10348
- this.#keyMap = /* @__PURE__ */ new Map();
10349
- this.#keyList = new Array(max).fill(void 0);
10350
- this.#valList = new Array(max).fill(void 0);
10351
- this.#next = new UintArray(max);
10352
- this.#prev = new UintArray(max);
10353
- this.#head = 0;
10354
- this.#tail = 0;
10355
- this.#free = Stack.create(max);
10356
- this.#size = 0;
10357
- this.#calculatedSize = 0;
10358
- if (typeof dispose === "function") this.#dispose = dispose;
10359
- if (typeof onInsert === "function") this.#onInsert = onInsert;
10360
- if (typeof disposeAfter === "function") {
10361
- this.#disposeAfter = disposeAfter;
10362
- this.#disposed = [];
10363
- } else {
10364
- this.#disposeAfter = void 0;
10365
- this.#disposed = void 0;
10366
- }
10367
- this.#hasDispose = !!this.#dispose;
10368
- this.#hasOnInsert = !!this.#onInsert;
10369
- this.#hasDisposeAfter = !!this.#disposeAfter;
10370
- this.noDisposeOnSet = !!noDisposeOnSet;
10371
- this.noUpdateTTL = !!noUpdateTTL;
10372
- this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection;
10373
- this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection;
10374
- this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort;
10375
- this.ignoreFetchAbort = !!ignoreFetchAbort;
10376
- if (this.maxEntrySize !== 0) {
10377
- if (this.#maxSize !== 0) {
10378
- if (!isPosInt(this.#maxSize)) throw new TypeError("maxSize must be a positive integer if specified");
10379
- }
10380
- if (!isPosInt(this.maxEntrySize)) throw new TypeError("maxEntrySize must be a positive integer if specified");
10381
- this.#initializeSizeTracking();
10382
- }
10383
- this.allowStale = !!allowStale;
10384
- this.noDeleteOnStaleGet = !!noDeleteOnStaleGet;
10385
- this.updateAgeOnGet = !!updateAgeOnGet;
10386
- this.updateAgeOnHas = !!updateAgeOnHas;
10387
- this.ttlResolution = isPosInt(ttlResolution) || ttlResolution === 0 ? ttlResolution : 1;
10388
- this.ttlAutopurge = !!ttlAutopurge;
10389
- this.ttl = ttl || 0;
10390
- if (this.ttl) {
10391
- if (!isPosInt(this.ttl)) throw new TypeError("ttl must be a positive integer if specified");
10392
- this.#initializeTTLTracking();
10393
- }
10394
- if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) throw new TypeError("At least one of max, maxSize, or ttl is required");
10395
- if (!this.ttlAutopurge && !this.#max && !this.#maxSize) {
10396
- const code = "LRU_CACHE_UNBOUNDED";
10397
- if (shouldWarn(code)) {
10398
- warned.add(code);
10399
- emitWarning("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.", "UnboundedCacheWarning", code, LRUCache);
10400
- }
10401
- }
10402
- }
10403
- /**
10404
- * Return the number of ms left in the item's TTL. If item is not in cache,
10405
- * returns `0`. Returns `Infinity` if item is in cache without a defined TTL.
10406
- */
10407
- getRemainingTTL(key) {
10408
- return this.#keyMap.has(key) ? Infinity : 0;
10409
- }
10410
- #initializeTTLTracking() {
10411
- const ttls = new ZeroArray(this.#max);
10412
- const starts = new ZeroArray(this.#max);
10413
- this.#ttls = ttls;
10414
- this.#starts = starts;
10415
- const purgeTimers = this.ttlAutopurge ? new Array(this.#max) : void 0;
10416
- this.#autopurgeTimers = purgeTimers;
10417
- this.#setItemTTL = (index, ttl, start = this.#perf.now()) => {
10418
- starts[index] = ttl !== 0 ? start : 0;
10419
- ttls[index] = ttl;
10420
- if (purgeTimers?.[index]) {
10421
- clearTimeout(purgeTimers[index]);
10422
- purgeTimers[index] = void 0;
10423
- }
10424
- if (ttl !== 0 && purgeTimers) {
10425
- const t = setTimeout(() => {
10426
- if (this.#isStale(index)) this.#delete(this.#keyList[index], "expire");
10427
- }, ttl + 1);
10428
- /* c8 ignore start */
10429
- if (t.unref) t.unref();
10430
- /* c8 ignore stop */
10431
- purgeTimers[index] = t;
10432
- }
10433
- };
10434
- this.#updateItemAge = (index) => {
10435
- starts[index] = ttls[index] !== 0 ? this.#perf.now() : 0;
10436
- };
10437
- this.#statusTTL = (status, index) => {
10438
- if (ttls[index]) {
10439
- const ttl = ttls[index];
10440
- const start = starts[index];
10441
- /* c8 ignore next */
10442
- if (!ttl || !start) return;
10443
- status.ttl = ttl;
10444
- status.start = start;
10445
- status.now = cachedNow || getNow();
10446
- status.remainingTTL = ttl - (status.now - start);
10447
- }
10448
- };
10449
- let cachedNow = 0;
10450
- const getNow = () => {
10451
- const n = this.#perf.now();
10229
+ return this.#w;
10230
+ }
10231
+ constructor(e) {
10232
+ let { max: t = 0, ttl: i, ttlResolution: s = 1, ttlAutopurge: n, updateAgeOnGet: o, updateAgeOnHas: l, allowStale: h, dispose: r, onInsert: c, disposeAfter: m, noDisposeOnSet: _, noUpdateTTL: u, maxSize: g = 0, maxEntrySize: f = 0, sizeCalculation: y, fetchMethod: a, memoMethod: w, noDeleteOnFetchRejection: F, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: p, allowStaleOnFetchAbort: A, ignoreFetchAbort: z, backgroundFetchSize: C = 1, perf: E } = e;
10233
+ if (this.backgroundFetchSize = C, E !== void 0 && typeof E?.now != "function") throw new TypeError("perf option must have a now() method if specified");
10234
+ if (this.#m = E ?? M, t !== 0 && !T(t)) throw new TypeError("max option must be a nonnegative integer");
10235
+ let v = t ? G(t) : Array;
10236
+ if (!v) throw new Error("invalid max value: " + t);
10237
+ if (this.#o = t, this.#c = g, this.maxEntrySize = f || this.#c, this.sizeCalculation = y, this.sizeCalculation) {
10238
+ if (!this.#c && !this.maxEntrySize) throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
10239
+ if (typeof this.sizeCalculation != "function") throw new TypeError("sizeCalculation set to non-function");
10240
+ }
10241
+ if (w !== void 0 && typeof w != "function") throw new TypeError("memoMethod must be a function if defined");
10242
+ if (this.#I = w, a !== void 0 && typeof a != "function") throw new TypeError("fetchMethod must be a function if specified");
10243
+ if (this.#M = a, this.#U = !!a, this.#s = /* @__PURE__ */ new Map(), this.#i = Array.from({ length: t }).fill(void 0), this.#t = Array.from({ length: t }).fill(void 0), this.#l = new v(t), this.#u = new v(t), this.#a = 0, this.#h = 0, this.#y = x.create(t), this.#n = 0, this.#b = 0, typeof r == "function" && (this.#S = r), typeof c == "function" && (this.#O = c), typeof m == "function" ? (this.#w = m, this.#r = []) : (this.#w = void 0, this.#r = void 0), this.#T = !!this.#S, this.#D = !!this.#O, this.#f = !!this.#w, this.noDisposeOnSet = !!_, this.noUpdateTTL = !!u, this.noDeleteOnFetchRejection = !!F, this.allowStaleOnFetchRejection = !!p, this.allowStaleOnFetchAbort = !!A, this.ignoreFetchAbort = !!z, this.maxEntrySize !== 0) {
10244
+ if (this.#c !== 0 && !T(this.#c)) throw new TypeError("maxSize must be a positive integer if specified");
10245
+ if (!T(this.maxEntrySize)) throw new TypeError("maxEntrySize must be a positive integer if specified");
10246
+ this.#X();
10247
+ }
10248
+ if (this.allowStale = !!h, this.noDeleteOnStaleGet = !!b, this.updateAgeOnGet = !!o, this.updateAgeOnHas = !!l, this.ttlResolution = T(s) || s === 0 ? s : 1, this.ttlAutopurge = !!n, this.ttl = i || 0, this.ttl) {
10249
+ if (!T(this.ttl)) throw new TypeError("ttl must be a positive integer if specified");
10250
+ this.#k();
10251
+ }
10252
+ if (this.#o === 0 && this.ttl === 0 && this.#c === 0) throw new TypeError("At least one of max, maxSize, or ttl is required");
10253
+ if (!this.ttlAutopurge && !this.#o && !this.#c) {
10254
+ let D = "LRU_CACHE_UNBOUNDED";
10255
+ k(D) && (j.add(D), P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.", "UnboundedCacheWarning", D, d));
10256
+ }
10257
+ }
10258
+ getRemainingTTL(e) {
10259
+ return this.#s.has(e) ? 1 / 0 : 0;
10260
+ }
10261
+ #k() {
10262
+ let e = new O(this.#o), t = new O(this.#o);
10263
+ this.#d = e, this.#F = t;
10264
+ let i = this.ttlAutopurge ? Array.from({ length: this.#o }) : void 0;
10265
+ this.#g = i, this.#H = (h, r, c = this.#m.now()) => {
10266
+ t[h] = r !== 0 ? c : 0, e[h] = r, s(h, r);
10267
+ }, this.#R = (h) => {
10268
+ t[h] = e[h] !== 0 ? this.#m.now() : 0, s(h, e[h]);
10269
+ };
10270
+ let s = this.ttlAutopurge ? (h, r) => {
10271
+ if (i?.[h] && (clearTimeout(i[h]), i[h] = void 0), r && r !== 0 && i) {
10272
+ let c = setTimeout(() => {
10273
+ this.#p(h) ? (this.#E(this.#i[h], "expire"), i[h] = void 0) : s(h, l(h));
10274
+ }, r + 1);
10275
+ c.unref && c.unref(), i[h] = c;
10276
+ }
10277
+ } : () => {};
10278
+ this.#v = (h, r) => {
10279
+ if (e[r]) {
10280
+ let c = e[r], m = t[r];
10281
+ if (!c || !m) return;
10282
+ h.ttl = c, h.start = m, h.now = n || o();
10283
+ h.remainingTTL = c - (h.now - m);
10284
+ }
10285
+ };
10286
+ let n = 0, o = () => {
10287
+ let h = this.#m.now();
10452
10288
  if (this.ttlResolution > 0) {
10453
- cachedNow = n;
10454
- const t = setTimeout(() => cachedNow = 0, this.ttlResolution);
10455
- /* c8 ignore start */
10456
- if (t.unref) t.unref();
10457
- }
10458
- return n;
10459
- };
10460
- this.getRemainingTTL = (key) => {
10461
- const index = this.#keyMap.get(key);
10462
- if (index === void 0) return 0;
10463
- const ttl = ttls[index];
10464
- const start = starts[index];
10465
- if (!ttl || !start) return Infinity;
10466
- return ttl - ((cachedNow || getNow()) - start);
10467
- };
10468
- this.#isStale = (index) => {
10469
- const s = starts[index];
10470
- const t = ttls[index];
10471
- return !!t && !!s && (cachedNow || getNow()) - s > t;
10472
- };
10473
- }
10474
- #updateItemAge = () => {};
10475
- #statusTTL = () => {};
10476
- #setItemTTL = () => {};
10477
- /* c8 ignore stop */
10478
- #isStale = () => false;
10479
- #initializeSizeTracking() {
10480
- const sizes = new ZeroArray(this.#max);
10481
- this.#calculatedSize = 0;
10482
- this.#sizes = sizes;
10483
- this.#removeItemSize = (index) => {
10484
- this.#calculatedSize -= sizes[index];
10485
- sizes[index] = 0;
10486
- };
10487
- this.#requireSize = (k, v, size, sizeCalculation) => {
10488
- if (this.#isBackgroundFetch(v)) return 0;
10489
- if (!isPosInt(size)) {
10490
- if (sizeCalculation) {
10491
- if (typeof sizeCalculation !== "function") throw new TypeError("sizeCalculation must be a function");
10492
- size = sizeCalculation(v, k);
10493
- if (!isPosInt(size)) throw new TypeError("sizeCalculation return invalid (expect positive integer)");
10289
+ n = h;
10290
+ let r = setTimeout(() => n = 0, this.ttlResolution);
10291
+ r.unref && r.unref();
10292
+ }
10293
+ return h;
10294
+ };
10295
+ this.getRemainingTTL = (h) => {
10296
+ let r = this.#s.get(h);
10297
+ return r === void 0 ? 0 : l(r);
10298
+ };
10299
+ let l = (h) => {
10300
+ let r = e[h], c = t[h];
10301
+ if (!r || !c) return 1 / 0;
10302
+ return r - ((n || o()) - c);
10303
+ };
10304
+ this.#p = (h) => {
10305
+ let r = t[h], c = e[h];
10306
+ return !!c && !!r && (n || o()) - r > c;
10307
+ };
10308
+ }
10309
+ #R = () => {};
10310
+ #v = () => {};
10311
+ #H = () => {};
10312
+ #p = () => !1;
10313
+ #X() {
10314
+ let e = new O(this.#o);
10315
+ this.#b = 0, this.#_ = e, this.#x = (t) => {
10316
+ this.#b -= e[t], e[t] = 0;
10317
+ }, this.#N = (t, i, s, n) => {
10318
+ if (!T(s)) {
10319
+ if (this.#e(i)) return this.backgroundFetchSize;
10320
+ if (n) {
10321
+ if (typeof n != "function") throw new TypeError("sizeCalculation must be a function");
10322
+ if (s = n(i, t), !T(s)) throw new TypeError("sizeCalculation return invalid (expect positive integer)");
10494
10323
  } else throw new TypeError("invalid size value (must be positive integer). When maxSize or maxEntrySize is used, sizeCalculation or size must be set.");
10495
10324
  }
10496
- return size;
10497
- };
10498
- this.#addItemSize = (index, size, status) => {
10499
- sizes[index] = size;
10500
- if (this.#maxSize) {
10501
- const maxSize = this.#maxSize - sizes[index];
10502
- while (this.#calculatedSize > maxSize) this.#evict(true);
10503
- }
10504
- this.#calculatedSize += sizes[index];
10505
- if (status) {
10506
- status.entrySize = size;
10507
- status.totalCalculatedSize = this.#calculatedSize;
10325
+ return s;
10326
+ }, this.#j = (t, i, s) => {
10327
+ if (e[t] = i, this.#c) {
10328
+ let n = this.#c - e[t];
10329
+ for (; this.#b > n;) this.#G(!0);
10508
10330
  }
10331
+ this.#b += e[t], s && (s.entrySize = i, s.totalCalculatedSize = this.#b);
10509
10332
  };
10510
10333
  }
10511
- #removeItemSize = (_i) => {};
10512
- #addItemSize = (_i, _s, _st) => {};
10513
- #requireSize = (_k, _v, size, sizeCalculation) => {
10514
- if (size || sizeCalculation) throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
10334
+ #x = (e) => {};
10335
+ #j = (e, t, i) => {};
10336
+ #N = (e, t, i, s) => {
10337
+ if (i || s) throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
10515
10338
  return 0;
10516
10339
  };
10517
- *#indexes({ allowStale = this.allowStale } = {}) {
10518
- if (this.#size) for (let i = this.#tail;;) {
10519
- if (!this.#isValidIndex(i)) break;
10520
- if (allowStale || !this.#isStale(i)) yield i;
10521
- if (i === this.#head) break;
10522
- else i = this.#prev[i];
10523
- }
10340
+ *#A({ allowStale: e = this.allowStale } = {}) {
10341
+ if (this.#n) for (let t = this.#h; this.#V(t) && ((e || !this.#p(t)) && (yield t), t !== this.#a);) t = this.#u[t];
10524
10342
  }
10525
- *#rindexes({ allowStale = this.allowStale } = {}) {
10526
- if (this.#size) for (let i = this.#head;;) {
10527
- if (!this.#isValidIndex(i)) break;
10528
- if (allowStale || !this.#isStale(i)) yield i;
10529
- if (i === this.#tail) break;
10530
- else i = this.#next[i];
10531
- }
10343
+ *#z({ allowStale: e = this.allowStale } = {}) {
10344
+ if (this.#n) for (let t = this.#a; this.#V(t) && ((e || !this.#p(t)) && (yield t), t !== this.#h);) t = this.#l[t];
10532
10345
  }
10533
- #isValidIndex(index) {
10534
- return index !== void 0 && this.#keyMap.get(this.#keyList[index]) === index;
10346
+ #V(e) {
10347
+ return e !== void 0 && this.#s.get(this.#i[e]) === e;
10535
10348
  }
10536
- /**
10537
- * Return a generator yielding `[key, value]` pairs,
10538
- * in order from most recently used to least recently used.
10539
- */
10540
10349
  *entries() {
10541
- for (const i of this.#indexes()) if (this.#valList[i] !== void 0 && this.#keyList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield [this.#keyList[i], this.#valList[i]];
10350
+ for (let e of this.#A()) this.#t[e] !== void 0 && this.#i[e] !== void 0 && !this.#e(this.#t[e]) && (yield [this.#i[e], this.#t[e]]);
10542
10351
  }
10543
- /**
10544
- * Inverse order version of {@link LRUCache.entries}
10545
- *
10546
- * Return a generator yielding `[key, value]` pairs,
10547
- * in order from least recently used to most recently used.
10548
- */
10549
10352
  *rentries() {
10550
- for (const i of this.#rindexes()) if (this.#valList[i] !== void 0 && this.#keyList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield [this.#keyList[i], this.#valList[i]];
10353
+ for (let e of this.#z()) this.#t[e] !== void 0 && this.#i[e] !== void 0 && !this.#e(this.#t[e]) && (yield [this.#i[e], this.#t[e]]);
10551
10354
  }
10552
- /**
10553
- * Return a generator yielding the keys in the cache,
10554
- * in order from most recently used to least recently used.
10555
- */
10556
10355
  *keys() {
10557
- for (const i of this.#indexes()) {
10558
- const k = this.#keyList[i];
10559
- if (k !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield k;
10356
+ for (let e of this.#A()) {
10357
+ let t = this.#i[e];
10358
+ t !== void 0 && !this.#e(this.#t[e]) && (yield t);
10560
10359
  }
10561
10360
  }
10562
- /**
10563
- * Inverse order version of {@link LRUCache.keys}
10564
- *
10565
- * Return a generator yielding the keys in the cache,
10566
- * in order from least recently used to most recently used.
10567
- */
10568
10361
  *rkeys() {
10569
- for (const i of this.#rindexes()) {
10570
- const k = this.#keyList[i];
10571
- if (k !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield k;
10362
+ for (let e of this.#z()) {
10363
+ let t = this.#i[e];
10364
+ t !== void 0 && !this.#e(this.#t[e]) && (yield t);
10572
10365
  }
10573
10366
  }
10574
- /**
10575
- * Return a generator yielding the values in the cache,
10576
- * in order from most recently used to least recently used.
10577
- */
10578
10367
  *values() {
10579
- for (const i of this.#indexes()) if (this.#valList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield this.#valList[i];
10368
+ for (let e of this.#A()) this.#t[e] !== void 0 && !this.#e(this.#t[e]) && (yield this.#t[e]);
10580
10369
  }
10581
- /**
10582
- * Inverse order version of {@link LRUCache.values}
10583
- *
10584
- * Return a generator yielding the values in the cache,
10585
- * in order from least recently used to most recently used.
10586
- */
10587
10370
  *rvalues() {
10588
- for (const i of this.#rindexes()) if (this.#valList[i] !== void 0 && !this.#isBackgroundFetch(this.#valList[i])) yield this.#valList[i];
10371
+ for (let e of this.#z()) this.#t[e] !== void 0 && !this.#e(this.#t[e]) && (yield this.#t[e]);
10589
10372
  }
10590
- /**
10591
- * Iterating over the cache itself yields the same results as
10592
- * {@link LRUCache.entries}
10593
- */
10594
10373
  [Symbol.iterator]() {
10595
10374
  return this.entries();
10596
10375
  }
10597
- /**
10598
- * A String value that is used in the creation of the default string
10599
- * description of an object. Called by the built-in method
10600
- * `Object.prototype.toString`.
10601
- */
10602
10376
  [Symbol.toStringTag] = "LRUCache";
10603
- /**
10604
- * Find a value for which the supplied fn method returns a truthy value,
10605
- * similar to `Array.find()`. fn is called as `fn(value, key, cache)`.
10606
- */
10607
- find(fn, getOptions = {}) {
10608
- for (const i of this.#indexes()) {
10609
- const v = this.#valList[i];
10610
- const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
10611
- if (value === void 0) continue;
10612
- if (fn(value, this.#keyList[i], this)) return this.get(this.#keyList[i], getOptions);
10377
+ find(e, t = {}) {
10378
+ for (let i of this.#A()) {
10379
+ let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
10380
+ if (n !== void 0 && e(n, this.#i[i], this)) return this.#C(this.#i[i], t);
10613
10381
  }
10614
10382
  }
10615
- /**
10616
- * Call the supplied function on each item in the cache, in order from most
10617
- * recently used to least recently used.
10618
- *
10619
- * `fn` is called as `fn(value, key, cache)`.
10620
- *
10621
- * If `thisp` is provided, function will be called in the `this`-context of
10622
- * the provided object, or the cache if no `thisp` object is provided.
10623
- *
10624
- * Does not update age or recenty of use, or iterate over stale values.
10625
- */
10626
- forEach(fn, thisp = this) {
10627
- for (const i of this.#indexes()) {
10628
- const v = this.#valList[i];
10629
- const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
10630
- if (value === void 0) continue;
10631
- fn.call(thisp, value, this.#keyList[i], this);
10383
+ forEach(e, t = this) {
10384
+ for (let i of this.#A()) {
10385
+ let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
10386
+ n !== void 0 && e.call(t, n, this.#i[i], this);
10632
10387
  }
10633
10388
  }
10634
- /**
10635
- * The same as {@link LRUCache.forEach} but items are iterated over in
10636
- * reverse order. (ie, less recently used items are iterated over first.)
10637
- */
10638
- rforEach(fn, thisp = this) {
10639
- for (const i of this.#rindexes()) {
10640
- const v = this.#valList[i];
10641
- const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
10642
- if (value === void 0) continue;
10643
- fn.call(thisp, value, this.#keyList[i], this);
10389
+ rforEach(e, t = this) {
10390
+ for (let i of this.#z()) {
10391
+ let s = this.#t[i], n = this.#e(s) ? s.__staleWhileFetching : s;
10392
+ n !== void 0 && e.call(t, n, this.#i[i], this);
10644
10393
  }
10645
10394
  }
10646
- /**
10647
- * Delete any stale entries. Returns true if anything was removed,
10648
- * false otherwise.
10649
- */
10650
10395
  purgeStale() {
10651
- let deleted = false;
10652
- for (const i of this.#rindexes({ allowStale: true })) if (this.#isStale(i)) {
10653
- this.#delete(this.#keyList[i], "expire");
10654
- deleted = true;
10655
- }
10656
- return deleted;
10657
- }
10658
- /**
10659
- * Get the extended info about a given entry, to get its value, size, and
10660
- * TTL info simultaneously. Returns `undefined` if the key is not present.
10661
- *
10662
- * Unlike {@link LRUCache#dump}, which is designed to be portable and survive
10663
- * serialization, the `start` value is always the current timestamp, and the
10664
- * `ttl` is a calculated remaining time to live (negative if expired).
10665
- *
10666
- * Always returns stale values, if their info is found in the cache, so be
10667
- * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl})
10668
- * if relevant.
10669
- */
10670
- info(key) {
10671
- const i = this.#keyMap.get(key);
10672
- if (i === void 0) return void 0;
10673
- const v = this.#valList[i];
10674
- /* c8 ignore start - this isn't tested for the info function,
10675
- * but it's the same logic as found in other places. */
10676
- const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
10677
- if (value === void 0) return void 0;
10678
- /* c8 ignore end */
10679
- const entry = { value };
10680
- if (this.#ttls && this.#starts) {
10681
- const ttl = this.#ttls[i];
10682
- const start = this.#starts[i];
10683
- if (ttl && start) {
10684
- entry.ttl = ttl - (this.#perf.now() - start);
10685
- entry.start = Date.now();
10686
- }
10687
- }
10688
- if (this.#sizes) entry.size = this.#sizes[i];
10689
- return entry;
10396
+ let e = !1;
10397
+ for (let t of this.#z({ allowStale: !0 })) this.#p(t) && (this.#E(this.#i[t], "expire"), e = !0);
10398
+ return e;
10399
+ }
10400
+ info(e) {
10401
+ let t = this.#s.get(e);
10402
+ if (t === void 0) return;
10403
+ let i = this.#t[t], s = this.#e(i) ? i.__staleWhileFetching : i;
10404
+ if (s === void 0) return;
10405
+ let n = { value: s };
10406
+ if (this.#d && this.#F) {
10407
+ let o = this.#d[t], l = this.#F[t];
10408
+ if (o && l) n.ttl = o - (this.#m.now() - l), n.start = Date.now();
10409
+ }
10410
+ return this.#_ && (n.size = this.#_[t]), n;
10690
10411
  }
10691
- /**
10692
- * Return an array of [key, {@link LRUCache.Entry}] tuples which can be
10693
- * passed to {@link LRUCache#load}.
10694
- *
10695
- * The `start` fields are calculated relative to a portable `Date.now()`
10696
- * timestamp, even if `performance.now()` is available.
10697
- *
10698
- * Stale entries are always included in the `dump`, even if
10699
- * {@link LRUCache.OptionsBase.allowStale} is false.
10700
- *
10701
- * Note: this returns an actual array, not a generator, so it can be more
10702
- * easily passed around.
10703
- */
10704
10412
  dump() {
10705
- const arr = [];
10706
- for (const i of this.#indexes({ allowStale: true })) {
10707
- const key = this.#keyList[i];
10708
- const v = this.#valList[i];
10709
- const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
10710
- if (value === void 0 || key === void 0) continue;
10711
- const entry = { value };
10712
- if (this.#ttls && this.#starts) {
10713
- entry.ttl = this.#ttls[i];
10714
- const age = this.#perf.now() - this.#starts[i];
10715
- entry.start = Math.floor(Date.now() - age);
10716
- }
10717
- if (this.#sizes) entry.size = this.#sizes[i];
10718
- arr.unshift([key, entry]);
10719
- }
10720
- return arr;
10721
- }
10722
- /**
10723
- * Reset the cache and load in the items in entries in the order listed.
10724
- *
10725
- * The shape of the resulting cache may be different if the same options are
10726
- * not used in both caches.
10727
- *
10728
- * The `start` fields are assumed to be calculated relative to a portable
10729
- * `Date.now()` timestamp, even if `performance.now()` is available.
10730
- */
10731
- load(arr) {
10732
- this.clear();
10733
- for (const [key, entry] of arr) {
10734
- if (entry.start) {
10735
- const age = Date.now() - entry.start;
10736
- entry.start = this.#perf.now() - age;
10413
+ let e = [];
10414
+ for (let t of this.#A({ allowStale: !0 })) {
10415
+ let i = this.#i[t], s = this.#t[t], n = this.#e(s) ? s.__staleWhileFetching : s;
10416
+ if (n === void 0 || i === void 0) continue;
10417
+ let o = { value: n };
10418
+ if (this.#d && this.#F) {
10419
+ o.ttl = this.#d[t];
10420
+ let l = this.#m.now() - this.#F[t];
10421
+ o.start = Math.floor(Date.now() - l);
10737
10422
  }
10738
- this.set(key, entry.value, entry);
10423
+ this.#_ && (o.size = this.#_[t]), e.unshift([i, o]);
10739
10424
  }
10425
+ return e;
10740
10426
  }
10741
- /**
10742
- * Add a value to the cache.
10743
- *
10744
- * Note: if `undefined` is specified as a value, this is an alias for
10745
- * {@link LRUCache#delete}
10746
- *
10747
- * Fields on the {@link LRUCache.SetOptions} options param will override
10748
- * their corresponding values in the constructor options for the scope
10749
- * of this single `set()` operation.
10750
- *
10751
- * If `start` is provided, then that will set the effective start
10752
- * time for the TTL calculation. Note that this must be a previous
10753
- * value of `performance.now()` if supported, or a previous value of
10754
- * `Date.now()` if not.
10755
- *
10756
- * Options object may also include `size`, which will prevent
10757
- * calling the `sizeCalculation` function and just use the specified
10758
- * number if it is a positive integer, and `noDisposeOnSet` which
10759
- * will prevent calling a `dispose` function in the case of
10760
- * overwrites.
10761
- *
10762
- * If the `size` (or return value of `sizeCalculation`) for a given
10763
- * entry is greater than `maxEntrySize`, then the item will not be
10764
- * added to the cache.
10765
- *
10766
- * Will update the recency of the entry.
10767
- *
10768
- * If the value is `undefined`, then this is an alias for
10769
- * `cache.delete(key)`. `undefined` is never stored in the cache.
10770
- */
10771
- set(k, v, setOptions = {}) {
10772
- if (v === void 0) {
10773
- this.delete(k);
10774
- return this;
10775
- }
10776
- const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status } = setOptions;
10777
- let { noUpdateTTL = this.noUpdateTTL } = setOptions;
10778
- const size = this.#requireSize(k, v, setOptions.size || 0, sizeCalculation);
10779
- if (this.maxEntrySize && size > this.maxEntrySize) {
10780
- if (status) {
10781
- status.set = "miss";
10782
- status.maxEntrySizeExceeded = true;
10783
- }
10784
- this.#delete(k, "set");
10785
- return this;
10786
- }
10787
- let index = this.#size === 0 ? void 0 : this.#keyMap.get(k);
10788
- if (index === void 0) {
10789
- index = this.#size === 0 ? this.#tail : this.#free.length !== 0 ? this.#free.pop() : this.#size === this.#max ? this.#evict(false) : this.#size;
10790
- this.#keyList[index] = k;
10791
- this.#valList[index] = v;
10792
- this.#keyMap.set(k, index);
10793
- this.#next[this.#tail] = index;
10794
- this.#prev[index] = this.#tail;
10795
- this.#tail = index;
10796
- this.#size++;
10797
- this.#addItemSize(index, size, status);
10798
- if (status) status.set = "add";
10799
- noUpdateTTL = false;
10800
- if (this.#hasOnInsert) this.#onInsert?.(v, k, "add");
10801
- } else {
10802
- this.#moveToTail(index);
10803
- const oldVal = this.#valList[index];
10804
- if (v !== oldVal) {
10805
- if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) {
10806
- oldVal.__abortController.abort(/* @__PURE__ */ new Error("replaced"));
10807
- const { __staleWhileFetching: s } = oldVal;
10808
- if (s !== void 0 && !noDisposeOnSet) {
10809
- if (this.#hasDispose) this.#dispose?.(s, k, "set");
10810
- if (this.#hasDisposeAfter) this.#disposed?.push([
10811
- s,
10812
- k,
10813
- "set"
10814
- ]);
10815
- }
10816
- } else if (!noDisposeOnSet) {
10817
- if (this.#hasDispose) this.#dispose?.(oldVal, k, "set");
10818
- if (this.#hasDisposeAfter) this.#disposed?.push([
10819
- oldVal,
10820
- k,
10427
+ load(e) {
10428
+ this.clear();
10429
+ for (let [t, i] of e) {
10430
+ if (i.start) {
10431
+ let s = Date.now() - i.start;
10432
+ i.start = this.#m.now() - s;
10433
+ }
10434
+ this.#W(t, i.value, i);
10435
+ }
10436
+ }
10437
+ set(e, t, i = {}) {
10438
+ let { status: s = S.hasSubscribers ? {} : void 0 } = i;
10439
+ i.status = s, s && (s.op = "set", s.key = e, t !== void 0 && (s.value = t), s.cache = this);
10440
+ let n = this.#W(e, t, i);
10441
+ return s && S.hasSubscribers && S.publish(s), n;
10442
+ }
10443
+ #W(e, t, i, s) {
10444
+ let { ttl: n = this.ttl, start: o, noDisposeOnSet: l = this.noDisposeOnSet, sizeCalculation: h = this.sizeCalculation, status: r } = i, c = this.#e(t);
10445
+ if (t === void 0) return r && (r.set = "deleted"), this.delete(e), this;
10446
+ let { noUpdateTTL: m = this.noUpdateTTL } = i;
10447
+ r && !c && (r.value = t);
10448
+ let _ = this.#N(e, t, i.size || 0, h, r);
10449
+ if (this.maxEntrySize && _ > this.maxEntrySize) return this.#E(e, "set"), r && (r.set = "miss", r.maxEntrySizeExceeded = !0), this;
10450
+ let u = this.#n === 0 ? void 0 : this.#s.get(e);
10451
+ if (u === void 0) u = this.#n === 0 ? this.#h : this.#y.length !== 0 ? this.#y.pop() : this.#n === this.#o ? this.#G(!1) : this.#n, this.#i[u] = e, this.#t[u] = t, this.#s.set(e, u), this.#l[this.#h] = u, this.#u[u] = this.#h, this.#h = u, this.#n++, this.#j(u, _, r), r && (r.set = "add"), m = !1, this.#D && !c && this.#O?.(t, e, "add");
10452
+ else {
10453
+ this.#L(u);
10454
+ let g = this.#t[u];
10455
+ if (t !== g) {
10456
+ if (!l) if (this.#e(g)) {
10457
+ g !== s && g.__abortController.abort(/* @__PURE__ */ new Error("replaced"));
10458
+ let { __staleWhileFetching: f } = g;
10459
+ f !== void 0 && f !== t && (this.#T && this.#S?.(f, e, "set"), this.#f && this.#r?.push([
10460
+ f,
10461
+ e,
10821
10462
  "set"
10822
- ]);
10823
- }
10824
- this.#removeItemSize(index);
10825
- this.#addItemSize(index, size, status);
10826
- this.#valList[index] = v;
10827
- if (status) {
10828
- status.set = "replace";
10829
- const oldValue = oldVal && this.#isBackgroundFetch(oldVal) ? oldVal.__staleWhileFetching : oldVal;
10830
- if (oldValue !== void 0) status.oldValue = oldValue;
10463
+ ]));
10464
+ } else this.#T && this.#S?.(g, e, "set"), this.#f && this.#r?.push([
10465
+ g,
10466
+ e,
10467
+ "set"
10468
+ ]);
10469
+ if (this.#x(u), this.#j(u, _, r), this.#t[u] = t, !c) {
10470
+ let f = g && this.#e(g) ? g.__staleWhileFetching : g, y = f === void 0 ? "add" : t !== f ? "replace" : "update";
10471
+ r && (r.set = y, f !== void 0 && (r.oldValue = f)), this.#D && this.onInsert?.(t, e, y);
10831
10472
  }
10832
- } else if (status) status.set = "update";
10833
- if (this.#hasOnInsert) this.onInsert?.(v, k, v === oldVal ? "update" : "replace");
10834
- }
10835
- if (ttl !== 0 && !this.#ttls) this.#initializeTTLTracking();
10836
- if (this.#ttls) {
10837
- if (!noUpdateTTL) this.#setItemTTL(index, ttl, start);
10838
- if (status) this.#statusTTL(status, index);
10473
+ } else c || (r && (r.set = "update"), this.#D && this.onInsert?.(t, e, "update"));
10839
10474
  }
10840
- if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) {
10841
- const dt = this.#disposed;
10842
- let task;
10843
- while (task = dt?.shift()) this.#disposeAfter?.(...task);
10475
+ if (n !== 0 && !this.#d && this.#k(), this.#d && (m || this.#H(u, n, o), r && this.#v(r, u)), !l && this.#f && this.#r) {
10476
+ let g = this.#r, f;
10477
+ for (; f = g?.shift();) this.#w?.(...f);
10844
10478
  }
10845
10479
  return this;
10846
10480
  }
10847
- /**
10848
- * Evict the least recently used item, returning its value or
10849
- * `undefined` if cache is empty.
10850
- */
10851
10481
  pop() {
10852
10482
  try {
10853
- while (this.#size) {
10854
- const val = this.#valList[this.#head];
10855
- this.#evict(true);
10856
- if (this.#isBackgroundFetch(val)) {
10857
- if (val.__staleWhileFetching) return val.__staleWhileFetching;
10858
- } else if (val !== void 0) return val;
10483
+ for (; this.#n;) {
10484
+ let e = this.#t[this.#a];
10485
+ if (this.#G(!0), this.#e(e)) {
10486
+ if (e.__staleWhileFetching) return e.__staleWhileFetching;
10487
+ } else if (e !== void 0) return e;
10859
10488
  }
10860
10489
  } finally {
10861
- if (this.#hasDisposeAfter && this.#disposed) {
10862
- const dt = this.#disposed;
10863
- let task;
10864
- while (task = dt?.shift()) this.#disposeAfter?.(...task);
10865
- }
10866
- }
10867
- }
10868
- #evict(free) {
10869
- const head = this.#head;
10870
- const k = this.#keyList[head];
10871
- const v = this.#valList[head];
10872
- if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) v.__abortController.abort(/* @__PURE__ */ new Error("evicted"));
10873
- else if (this.#hasDispose || this.#hasDisposeAfter) {
10874
- if (this.#hasDispose) this.#dispose?.(v, k, "evict");
10875
- if (this.#hasDisposeAfter) this.#disposed?.push([
10876
- v,
10877
- k,
10878
- "evict"
10879
- ]);
10880
- }
10881
- this.#removeItemSize(head);
10882
- if (this.#autopurgeTimers?.[head]) {
10883
- clearTimeout(this.#autopurgeTimers[head]);
10884
- this.#autopurgeTimers[head] = void 0;
10885
- }
10886
- if (free) {
10887
- this.#keyList[head] = void 0;
10888
- this.#valList[head] = void 0;
10889
- this.#free.push(head);
10890
- }
10891
- if (this.#size === 1) {
10892
- this.#head = this.#tail = 0;
10893
- this.#free.length = 0;
10894
- } else this.#head = this.#next[head];
10895
- this.#keyMap.delete(k);
10896
- this.#size--;
10897
- return head;
10898
- }
10899
- /**
10900
- * Check if a key is in the cache, without updating the recency of use.
10901
- * Will return false if the item is stale, even though it is technically
10902
- * in the cache.
10903
- *
10904
- * Check if a key is in the cache, without updating the recency of
10905
- * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set
10906
- * to `true` in either the options or the constructor.
10907
- *
10908
- * Will return `false` if the item is stale, even though it is technically in
10909
- * the cache. The difference can be determined (if it matters) by using a
10910
- * `status` argument, and inspecting the `has` field.
10911
- *
10912
- * Will not update item age unless
10913
- * {@link LRUCache.OptionsBase.updateAgeOnHas} is set.
10914
- */
10915
- has(k, hasOptions = {}) {
10916
- const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions;
10917
- const index = this.#keyMap.get(k);
10918
- if (index !== void 0) {
10919
- const v = this.#valList[index];
10920
- if (this.#isBackgroundFetch(v) && v.__staleWhileFetching === void 0) return false;
10921
- if (!this.#isStale(index)) {
10922
- if (updateAgeOnHas) this.#updateItemAge(index);
10923
- if (status) {
10924
- status.has = "hit";
10925
- this.#statusTTL(status, index);
10926
- }
10927
- return true;
10928
- } else if (status) {
10929
- status.has = "stale";
10930
- this.#statusTTL(status, index);
10931
- }
10932
- } else if (status) status.has = "miss";
10933
- return false;
10934
- }
10935
- /**
10936
- * Like {@link LRUCache#get} but doesn't update recency or delete stale
10937
- * items.
10938
- *
10939
- * Returns `undefined` if the item is stale, unless
10940
- * {@link LRUCache.OptionsBase.allowStale} is set.
10941
- */
10942
- peek(k, peekOptions = {}) {
10943
- const { allowStale = this.allowStale } = peekOptions;
10944
- const index = this.#keyMap.get(k);
10945
- if (index === void 0 || !allowStale && this.#isStale(index)) return;
10946
- const v = this.#valList[index];
10947
- return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
10948
- }
10949
- #backgroundFetch(k, index, options, context) {
10950
- const v = index === void 0 ? void 0 : this.#valList[index];
10951
- if (this.#isBackgroundFetch(v)) return v;
10952
- const ac = new AC();
10953
- const { signal } = options;
10954
- signal?.addEventListener("abort", () => ac.abort(signal.reason), { signal: ac.signal });
10955
- const fetchOpts = {
10956
- signal: ac.signal,
10957
- options,
10958
- context
10959
- };
10960
- const cb = (v, updateCache = false) => {
10961
- const { aborted } = ac.signal;
10962
- const ignoreAbort = options.ignoreFetchAbort && v !== void 0;
10963
- if (options.status) {
10964
- if (aborted && !updateCache) {
10965
- options.status.fetchAborted = true;
10966
- options.status.fetchError = ac.signal.reason;
10967
- if (ignoreAbort) options.status.fetchAbortIgnored = true;
10968
- } else options.status.fetchResolved = true;
10969
- }
10970
- if (aborted && !ignoreAbort && !updateCache) return fetchFail(ac.signal.reason);
10971
- const bf = p;
10972
- const vl = this.#valList[index];
10973
- if (vl === p || ignoreAbort && updateCache && vl === void 0) {
10974
- if (v === void 0) {
10975
- if (bf.__staleWhileFetching !== void 0) this.#valList[index] = bf.__staleWhileFetching;
10976
- else this.#delete(k, "fetch");
10977
- } else {
10978
- if (options.status) options.status.fetchUpdated = true;
10979
- this.set(k, v, fetchOpts.options);
10980
- }
10981
- }
10982
- return v;
10983
- };
10984
- const eb = (er) => {
10985
- if (options.status) {
10986
- options.status.fetchRejected = true;
10987
- options.status.fetchError = er;
10988
- }
10989
- return fetchFail(er);
10990
- };
10991
- const fetchFail = (er) => {
10992
- const { aborted } = ac.signal;
10993
- const allowStaleAborted = aborted && options.allowStaleOnFetchAbort;
10994
- const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection;
10995
- const noDelete = allowStale || options.noDeleteOnFetchRejection;
10996
- const bf = p;
10997
- if (this.#valList[index] === p) {
10998
- if (!noDelete || bf.__staleWhileFetching === void 0) this.#delete(k, "fetch");
10999
- else if (!allowStaleAborted) this.#valList[index] = bf.__staleWhileFetching;
11000
- }
11001
- if (allowStale) {
11002
- if (options.status && bf.__staleWhileFetching !== void 0) options.status.returnedStale = true;
11003
- return bf.__staleWhileFetching;
11004
- } else if (bf.__returned === bf) throw er;
11005
- };
11006
- const pcall = (res, rej) => {
11007
- const fmp = this.#fetchMethod?.(k, v, fetchOpts);
11008
- if (fmp && fmp instanceof Promise) fmp.then((v) => res(v === void 0 ? void 0 : v), rej);
11009
- ac.signal.addEventListener("abort", () => {
11010
- if (!options.ignoreFetchAbort || options.allowStaleOnFetchAbort) {
11011
- res(void 0);
11012
- if (options.allowStaleOnFetchAbort) res = (v) => cb(v, true);
11013
- }
11014
- });
11015
- };
11016
- if (options.status) options.status.fetchDispatched = true;
11017
- const p = new Promise(pcall).then(cb, eb);
11018
- const bf = Object.assign(p, {
11019
- __abortController: ac,
11020
- __staleWhileFetching: v,
10490
+ if (this.#f && this.#r) {
10491
+ let e = this.#r, t;
10492
+ for (; t = e?.shift();) this.#w?.(...t);
10493
+ }
10494
+ }
10495
+ }
10496
+ #G(e) {
10497
+ let t = this.#a, i = this.#i[t], s = this.#t[t], n = this.#e(s);
10498
+ n && s.__abortController.abort(/* @__PURE__ */ new Error("evicted"));
10499
+ let o = n ? s.__staleWhileFetching : s;
10500
+ return (this.#T || this.#f) && o !== void 0 && (this.#T && this.#S?.(o, i, "evict"), this.#f && this.#r?.push([
10501
+ o,
10502
+ i,
10503
+ "evict"
10504
+ ])), this.#x(t), this.#g?.[t] && (clearTimeout(this.#g[t]), this.#g[t] = void 0), e && (this.#i[t] = void 0, this.#t[t] = void 0, this.#y.push(t)), this.#n === 1 ? (this.#a = this.#h = 0, this.#y.length = 0) : this.#a = this.#l[t], this.#s.delete(i), this.#n--, t;
10505
+ }
10506
+ has(e, t = {}) {
10507
+ let { status: i = S.hasSubscribers ? {} : void 0 } = t;
10508
+ t.status = i, i && (i.op = "has", i.key = e, i.cache = this);
10509
+ let s = this.#Y(e, t);
10510
+ return S.hasSubscribers && S.publish(i), s;
10511
+ }
10512
+ #Y(e, t = {}) {
10513
+ let { updateAgeOnHas: i = this.updateAgeOnHas, status: s } = t, n = this.#s.get(e);
10514
+ if (n !== void 0) {
10515
+ let o = this.#t[n];
10516
+ if (this.#e(o) && o.__staleWhileFetching === void 0) return !1;
10517
+ if (this.#p(n)) s && (s.has = "stale", this.#v(s, n));
10518
+ else return i && this.#R(n), s && (s.has = "hit", this.#v(s, n)), !0;
10519
+ } else s && (s.has = "miss");
10520
+ return !1;
10521
+ }
10522
+ peek(e, t = {}) {
10523
+ let { status: i = R() ? {} : void 0 } = t;
10524
+ i && (i.op = "peek", i.key = e, i.cache = this), t.status = i;
10525
+ let s = this.#J(e, t);
10526
+ return S.hasSubscribers && S.publish(i), s;
10527
+ }
10528
+ #J(e, t) {
10529
+ let { status: i, allowStale: s = this.allowStale } = t, n = this.#s.get(e);
10530
+ if (n === void 0 || !s && this.#p(n)) {
10531
+ i && (i.peek = n === void 0 ? "miss" : "stale");
10532
+ return;
10533
+ }
10534
+ let o = this.#t[n], l = this.#e(o) ? o.__staleWhileFetching : o;
10535
+ return i && (l !== void 0 ? (i.peek = "hit", i.value = l) : i.peek = "miss"), l;
10536
+ }
10537
+ #P(e, t, i, s) {
10538
+ let n = t === void 0 ? void 0 : this.#t[t];
10539
+ if (this.#e(n)) return n;
10540
+ let o = new AbortController(), { signal: l } = i;
10541
+ l?.addEventListener("abort", () => o.abort(l.reason), { signal: o.signal });
10542
+ let h = {
10543
+ signal: o.signal,
10544
+ options: i,
10545
+ context: s
10546
+ }, r = (f, y = !1) => {
10547
+ let { aborted: a } = o.signal, w = i.ignoreFetchAbort && f !== void 0, F = i.ignoreFetchAbort || !!(i.allowStaleOnFetchAbort && f !== void 0);
10548
+ if (i.status && (a && !y ? (i.status.fetchAborted = !0, i.status.fetchError = o.signal.reason, w && (i.status.fetchAbortIgnored = !0)) : i.status.fetchResolved = !0), a && !w && !y) return m(o.signal.reason, F);
10549
+ let b = u, p = this.#t[t];
10550
+ return (p === u || p === void 0 && w && y) && (f === void 0 ? b.__staleWhileFetching !== void 0 ? this.#t[t] = b.__staleWhileFetching : this.#E(e, "fetch") : (i.status && (i.status.fetchUpdated = !0), this.#W(e, f, h.options, b))), f;
10551
+ }, c = (f) => (i.status && (i.status.fetchRejected = !0, i.status.fetchError = f), m(f, !1)), m = (f, y) => {
10552
+ let { aborted: a } = o.signal, w = a && i.allowStaleOnFetchAbort, F = w || i.allowStaleOnFetchRejection, b = F || i.noDeleteOnFetchRejection, p = u;
10553
+ if (this.#t[t] === u && (!b || !y && p.__staleWhileFetching === void 0 ? this.#E(e, "fetch") : w || (this.#t[t] = p.__staleWhileFetching)), F) return i.status && p.__staleWhileFetching !== void 0 && (i.status.returnedStale = !0), p.__staleWhileFetching;
10554
+ if (p.__returned === p) throw f;
10555
+ }, _ = (f, y) => {
10556
+ let a = this.#M?.(e, n, h);
10557
+ o.signal.addEventListener("abort", () => {
10558
+ (!i.ignoreFetchAbort || i.allowStaleOnFetchAbort) && (f(void 0), i.allowStaleOnFetchAbort && (f = (w) => r(w, !0)));
10559
+ }), a && a instanceof Promise ? a.then((w) => f(w === void 0 ? void 0 : w), y) : a !== void 0 && f(a);
10560
+ };
10561
+ i.status && (i.status.fetchDispatched = !0);
10562
+ let u = new Promise(_).then(r, c), g = Object.assign(u, {
10563
+ __abortController: o,
10564
+ __staleWhileFetching: n,
11021
10565
  __returned: void 0
11022
10566
  });
11023
- if (index === void 0) {
11024
- this.set(k, bf, {
11025
- ...fetchOpts.options,
11026
- status: void 0
11027
- });
11028
- index = this.#keyMap.get(k);
11029
- } else this.#valList[index] = bf;
11030
- return bf;
11031
- }
11032
- #isBackgroundFetch(p) {
11033
- if (!this.#hasFetchMethod) return false;
11034
- const b = p;
11035
- return !!b && b instanceof Promise && b.hasOwnProperty("__staleWhileFetching") && b.__abortController instanceof AC;
11036
- }
11037
- async fetch(k, fetchOptions = {}) {
11038
- const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, ttl = this.ttl, noDisposeOnSet = this.noDisposeOnSet, size = 0, sizeCalculation = this.sizeCalculation, noUpdateTTL = this.noUpdateTTL, noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection = this.allowStaleOnFetchRejection, ignoreFetchAbort = this.ignoreFetchAbort, allowStaleOnFetchAbort = this.allowStaleOnFetchAbort, context, forceRefresh = false, status, signal } = fetchOptions;
11039
- if (!this.#hasFetchMethod) {
11040
- if (status) status.fetch = "get";
11041
- return this.get(k, {
11042
- allowStale,
11043
- updateAgeOnGet,
11044
- noDeleteOnStaleGet,
11045
- status
11046
- });
11047
- }
11048
- const options = {
11049
- allowStale,
11050
- updateAgeOnGet,
11051
- noDeleteOnStaleGet,
11052
- ttl,
11053
- noDisposeOnSet,
11054
- size,
11055
- sizeCalculation,
11056
- noUpdateTTL,
11057
- noDeleteOnFetchRejection,
11058
- allowStaleOnFetchRejection,
11059
- allowStaleOnFetchAbort,
11060
- ignoreFetchAbort,
11061
- status,
11062
- signal
11063
- };
11064
- let index = this.#keyMap.get(k);
11065
- if (index === void 0) {
11066
- if (status) status.fetch = "miss";
11067
- const p = this.#backgroundFetch(k, index, options, context);
10567
+ return t === void 0 ? (this.#W(e, g, {
10568
+ ...h.options,
10569
+ status: void 0
10570
+ }), t = this.#s.get(e)) : this.#t[t] = g, g;
10571
+ }
10572
+ #e(e) {
10573
+ if (!this.#U) return !1;
10574
+ let t = e;
10575
+ return !!t && t instanceof Promise && t.hasOwnProperty("__staleWhileFetching") && t.__abortController instanceof AbortController;
10576
+ }
10577
+ fetch(e, t = {}) {
10578
+ let i = W.hasSubscribers, { status: s = R() ? {} : void 0 } = t;
10579
+ t.status = s, s && t.context && (s.context = t.context);
10580
+ let n = this.#B(e, t);
10581
+ return s && i && (s.trace = !0, W.tracePromise(() => n, s).catch(() => {})), n;
10582
+ }
10583
+ async #B(e, t = {}) {
10584
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, ttl: o = this.ttl, noDisposeOnSet: l = this.noDisposeOnSet, size: h = 0, sizeCalculation: r = this.sizeCalculation, noUpdateTTL: c = this.noUpdateTTL, noDeleteOnFetchRejection: m = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection: _ = this.allowStaleOnFetchRejection, ignoreFetchAbort: u = this.ignoreFetchAbort, allowStaleOnFetchAbort: g = this.allowStaleOnFetchAbort, context: f, forceRefresh: y = !1, status: a, signal: w } = t;
10585
+ if (a && (a.op = "fetch", a.key = e, y && (a.forceRefresh = !0), a.cache = this), !this.#U) return a && (a.fetch = "get"), this.#C(e, {
10586
+ allowStale: i,
10587
+ updateAgeOnGet: s,
10588
+ noDeleteOnStaleGet: n,
10589
+ status: a
10590
+ });
10591
+ let F = {
10592
+ allowStale: i,
10593
+ updateAgeOnGet: s,
10594
+ noDeleteOnStaleGet: n,
10595
+ ttl: o,
10596
+ noDisposeOnSet: l,
10597
+ size: h,
10598
+ sizeCalculation: r,
10599
+ noUpdateTTL: c,
10600
+ noDeleteOnFetchRejection: m,
10601
+ allowStaleOnFetchRejection: _,
10602
+ allowStaleOnFetchAbort: g,
10603
+ ignoreFetchAbort: u,
10604
+ status: a,
10605
+ signal: w
10606
+ }, b = this.#s.get(e);
10607
+ if (b === void 0) {
10608
+ a && (a.fetch = "miss");
10609
+ let p = this.#P(e, b, F, f);
11068
10610
  return p.__returned = p;
11069
10611
  } else {
11070
- const v = this.#valList[index];
11071
- if (this.#isBackgroundFetch(v)) {
11072
- const stale = allowStale && v.__staleWhileFetching !== void 0;
11073
- if (status) {
11074
- status.fetch = "inflight";
11075
- if (stale) status.returnedStale = true;
11076
- }
11077
- return stale ? v.__staleWhileFetching : v.__returned = v;
11078
- }
11079
- const isStale = this.#isStale(index);
11080
- if (!forceRefresh && !isStale) {
11081
- if (status) status.fetch = "hit";
11082
- this.#moveToTail(index);
11083
- if (updateAgeOnGet) this.#updateItemAge(index);
11084
- if (status) this.#statusTTL(status, index);
11085
- return v;
11086
- }
11087
- const p = this.#backgroundFetch(k, index, options, context);
11088
- const staleVal = p.__staleWhileFetching !== void 0 && allowStale;
11089
- if (status) {
11090
- status.fetch = isStale ? "stale" : "refresh";
11091
- if (staleVal && isStale) status.returnedStale = true;
11092
- }
11093
- return staleVal ? p.__staleWhileFetching : p.__returned = p;
11094
- }
11095
- }
11096
- async forceFetch(k, fetchOptions = {}) {
11097
- const v = await this.fetch(k, fetchOptions);
11098
- if (v === void 0) throw new Error("fetch() returned undefined");
11099
- return v;
11100
- }
11101
- memo(k, memoOptions = {}) {
11102
- const memoMethod = this.#memoMethod;
11103
- if (!memoMethod) throw new Error("no memoMethod provided to constructor");
11104
- const { context, forceRefresh, ...options } = memoOptions;
11105
- const v = this.get(k, options);
11106
- if (!forceRefresh && v !== void 0) return v;
11107
- const vv = memoMethod(k, v, {
11108
- options,
11109
- context
11110
- });
11111
- this.set(k, vv, options);
11112
- return vv;
10612
+ let p = this.#t[b];
10613
+ if (this.#e(p)) {
10614
+ let v = i && p.__staleWhileFetching !== void 0;
10615
+ return a && (a.fetch = "inflight", v && (a.returnedStale = !0)), v ? p.__staleWhileFetching : p.__returned = p;
10616
+ }
10617
+ let A = this.#p(b);
10618
+ if (!y && !A) return a && (a.fetch = "hit"), this.#L(b), s && this.#R(b), a && this.#v(a, b), p;
10619
+ let z = this.#P(e, b, F, f), E = z.__staleWhileFetching !== void 0 && i;
10620
+ return a && (a.fetch = A ? "stale" : "refresh", E && A && (a.returnedStale = !0)), E ? z.__staleWhileFetching : z.__returned = z;
10621
+ }
10622
+ }
10623
+ forceFetch(e, t = {}) {
10624
+ let i = W.hasSubscribers, { status: s = R() ? {} : void 0 } = t;
10625
+ t.status = s, s && t.context && (s.context = t.context);
10626
+ let n = this.#K(e, t);
10627
+ return s && i && (s.trace = !0, W.tracePromise(() => n, s).catch(() => {})), n;
10628
+ }
10629
+ async #K(e, t = {}) {
10630
+ let i = await this.#B(e, t);
10631
+ if (i === void 0) throw new Error("fetch() returned undefined");
10632
+ return i;
10633
+ }
10634
+ memo(e, t = {}) {
10635
+ let { status: i = S.hasSubscribers ? {} : void 0 } = t;
10636
+ t.status = i, i && (i.op = "memo", i.key = e, t.context && (i.context = t.context), i.cache = this);
10637
+ let s = this.#Q(e, t);
10638
+ return i && (i.value = s), S.hasSubscribers && S.publish(i), s;
10639
+ }
10640
+ #Q(e, t = {}) {
10641
+ let i = this.#I;
10642
+ if (!i) throw new Error("no memoMethod provided to constructor");
10643
+ let { context: s, status: n, forceRefresh: o, ...l } = t;
10644
+ n && o && (n.forceRefresh = !0);
10645
+ let h = this.#C(e, l), r = o || h === void 0;
10646
+ if (n && (n.memo = r ? "miss" : "hit", r || (n.value = h)), !r) return h;
10647
+ let c = i(e, h, {
10648
+ options: l,
10649
+ context: s
10650
+ });
10651
+ return n && (n.value = c), this.#W(e, c, l), c;
10652
+ }
10653
+ get(e, t = {}) {
10654
+ let { status: i = S.hasSubscribers ? {} : void 0 } = t;
10655
+ t.status = i, i && (i.op = "get", i.key = e, i.cache = this);
10656
+ let s = this.#C(e, t);
10657
+ return i && (s !== void 0 && (i.value = s), S.hasSubscribers && S.publish(i)), s;
10658
+ }
10659
+ #C(e, t = {}) {
10660
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, status: o } = t, l = this.#s.get(e);
10661
+ if (l === void 0) {
10662
+ o && (o.get = "miss");
10663
+ return;
10664
+ }
10665
+ let h = this.#t[l], r = this.#e(h);
10666
+ return o && this.#v(o, l), this.#p(l) ? r ? (o && (o.get = "stale-fetching"), i && h.__staleWhileFetching !== void 0 ? (o && (o.returnedStale = !0), h.__staleWhileFetching) : void 0) : (n || this.#E(e, "expire"), o && (o.get = "stale"), i ? (o && (o.returnedStale = !0), h) : void 0) : (o && (o.get = r ? "fetching" : "hit"), this.#L(l), s && this.#R(l), r ? h.__staleWhileFetching : h);
11113
10667
  }
11114
- /**
11115
- * Return a value from the cache. Will update the recency of the cache
11116
- * entry found.
11117
- *
11118
- * If the key is not found, get() will return `undefined`.
11119
- */
11120
- get(k, getOptions = {}) {
11121
- const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status } = getOptions;
11122
- const index = this.#keyMap.get(k);
11123
- if (index !== void 0) {
11124
- const value = this.#valList[index];
11125
- const fetching = this.#isBackgroundFetch(value);
11126
- if (status) this.#statusTTL(status, index);
11127
- if (this.#isStale(index)) {
11128
- if (status) status.get = "stale";
11129
- if (!fetching) {
11130
- if (!noDeleteOnStaleGet) this.#delete(k, "expire");
11131
- if (status && allowStale) status.returnedStale = true;
11132
- return allowStale ? value : void 0;
11133
- } else {
11134
- if (status && allowStale && value.__staleWhileFetching !== void 0) status.returnedStale = true;
11135
- return allowStale ? value.__staleWhileFetching : void 0;
11136
- }
11137
- } else {
11138
- if (status) status.get = "hit";
11139
- if (fetching) return value.__staleWhileFetching;
11140
- this.#moveToTail(index);
11141
- if (updateAgeOnGet) this.#updateItemAge(index);
11142
- return value;
11143
- }
11144
- } else if (status) status.get = "miss";
10668
+ #$(e, t) {
10669
+ this.#u[t] = e, this.#l[e] = t;
11145
10670
  }
11146
- #connect(p, n) {
11147
- this.#prev[n] = p;
11148
- this.#next[p] = n;
10671
+ #L(e) {
10672
+ e !== this.#h && (e === this.#a ? this.#a = this.#l[e] : this.#$(this.#u[e], this.#l[e]), this.#$(this.#h, e), this.#h = e);
11149
10673
  }
11150
- #moveToTail(index) {
11151
- if (index !== this.#tail) {
11152
- if (index === this.#head) this.#head = this.#next[index];
11153
- else this.#connect(this.#prev[index], this.#next[index]);
11154
- this.#connect(this.#tail, index);
11155
- this.#tail = index;
11156
- }
10674
+ delete(e) {
10675
+ return this.#E(e, "delete");
11157
10676
  }
11158
- /**
11159
- * Deletes a key out of the cache.
11160
- *
11161
- * Returns true if the key was deleted, false otherwise.
11162
- */
11163
- delete(k) {
11164
- return this.#delete(k, "delete");
11165
- }
11166
- #delete(k, reason) {
11167
- let deleted = false;
11168
- if (this.#size !== 0) {
11169
- const index = this.#keyMap.get(k);
11170
- if (index !== void 0) {
11171
- if (this.#autopurgeTimers?.[index]) {
11172
- clearTimeout(this.#autopurgeTimers?.[index]);
11173
- this.#autopurgeTimers[index] = void 0;
11174
- }
11175
- deleted = true;
11176
- if (this.#size === 1) this.#clear(reason);
10677
+ #E(e, t) {
10678
+ S.hasSubscribers && S.publish({
10679
+ op: "delete",
10680
+ delete: t,
10681
+ key: e,
10682
+ cache: this
10683
+ });
10684
+ let i = !1;
10685
+ if (this.#n !== 0) {
10686
+ let s = this.#s.get(e);
10687
+ if (s !== void 0) if (this.#g?.[s] && (clearTimeout(this.#g[s]), this.#g[s] = void 0), i = !0, this.#n === 1) this.#q(t);
10688
+ else {
10689
+ this.#x(s);
10690
+ let n = this.#t[s];
10691
+ if (this.#e(n) ? n.__abortController.abort(/* @__PURE__ */ new Error("deleted")) : (this.#T || this.#f) && (this.#T && this.#S?.(n, e, t), this.#f && this.#r?.push([
10692
+ n,
10693
+ e,
10694
+ t
10695
+ ])), this.#s.delete(e), this.#i[s] = void 0, this.#t[s] = void 0, s === this.#h) this.#h = this.#u[s];
10696
+ else if (s === this.#a) this.#a = this.#l[s];
11177
10697
  else {
11178
- this.#removeItemSize(index);
11179
- const v = this.#valList[index];
11180
- if (this.#isBackgroundFetch(v)) v.__abortController.abort(/* @__PURE__ */ new Error("deleted"));
11181
- else if (this.#hasDispose || this.#hasDisposeAfter) {
11182
- if (this.#hasDispose) this.#dispose?.(v, k, reason);
11183
- if (this.#hasDisposeAfter) this.#disposed?.push([
11184
- v,
11185
- k,
11186
- reason
11187
- ]);
11188
- }
11189
- this.#keyMap.delete(k);
11190
- this.#keyList[index] = void 0;
11191
- this.#valList[index] = void 0;
11192
- if (index === this.#tail) this.#tail = this.#prev[index];
11193
- else if (index === this.#head) this.#head = this.#next[index];
11194
- else {
11195
- const pi = this.#prev[index];
11196
- this.#next[pi] = this.#next[index];
11197
- const ni = this.#next[index];
11198
- this.#prev[ni] = this.#prev[index];
11199
- }
11200
- this.#size--;
11201
- this.#free.push(index);
10698
+ let o = this.#u[s];
10699
+ this.#l[o] = this.#l[s];
10700
+ let l = this.#l[s];
10701
+ this.#u[l] = this.#u[s];
11202
10702
  }
10703
+ this.#n--, this.#y.push(s);
11203
10704
  }
11204
10705
  }
11205
- if (this.#hasDisposeAfter && this.#disposed?.length) {
11206
- const dt = this.#disposed;
11207
- let task;
11208
- while (task = dt?.shift()) this.#disposeAfter?.(...task);
10706
+ if (this.#f && this.#r?.length) {
10707
+ let s = this.#r, n;
10708
+ for (; n = s?.shift();) this.#w?.(...n);
11209
10709
  }
11210
- return deleted;
10710
+ return i;
11211
10711
  }
11212
- /**
11213
- * Clear the cache entirely, throwing away all values.
11214
- */
11215
10712
  clear() {
11216
- return this.#clear("delete");
10713
+ return this.#q("delete");
11217
10714
  }
11218
- #clear(reason) {
11219
- for (const index of this.#rindexes({ allowStale: true })) {
11220
- const v = this.#valList[index];
11221
- if (this.#isBackgroundFetch(v)) v.__abortController.abort(/* @__PURE__ */ new Error("deleted"));
10715
+ #q(e) {
10716
+ for (let t of this.#z({ allowStale: !0 })) {
10717
+ let i = this.#t[t];
10718
+ if (this.#e(i)) i.__abortController.abort(/* @__PURE__ */ new Error("deleted"));
11222
10719
  else {
11223
- const k = this.#keyList[index];
11224
- if (this.#hasDispose) this.#dispose?.(v, k, reason);
11225
- if (this.#hasDisposeAfter) this.#disposed?.push([
11226
- v,
11227
- k,
11228
- reason
10720
+ let s = this.#i[t];
10721
+ this.#T && this.#S?.(i, s, e), this.#f && this.#r?.push([
10722
+ i,
10723
+ s,
10724
+ e
11229
10725
  ]);
11230
10726
  }
11231
10727
  }
11232
- this.#keyMap.clear();
11233
- this.#valList.fill(void 0);
11234
- this.#keyList.fill(void 0);
11235
- if (this.#ttls && this.#starts) {
11236
- this.#ttls.fill(0);
11237
- this.#starts.fill(0);
11238
- for (const t of this.#autopurgeTimers ?? []) if (t !== void 0) clearTimeout(t);
11239
- this.#autopurgeTimers?.fill(void 0);
10728
+ if (this.#s.clear(), this.#t.fill(void 0), this.#i.fill(void 0), this.#d && this.#F) {
10729
+ this.#d.fill(0), this.#F.fill(0);
10730
+ for (let t of this.#g ?? []) t !== void 0 && clearTimeout(t);
10731
+ this.#g?.fill(void 0);
11240
10732
  }
11241
- if (this.#sizes) this.#sizes.fill(0);
11242
- this.#head = 0;
11243
- this.#tail = 0;
11244
- this.#free.length = 0;
11245
- this.#calculatedSize = 0;
11246
- this.#size = 0;
11247
- if (this.#hasDisposeAfter && this.#disposed) {
11248
- const dt = this.#disposed;
11249
- let task;
11250
- while (task = dt?.shift()) this.#disposeAfter?.(...task);
10733
+ if (this.#_ && this.#_.fill(0), this.#a = 0, this.#h = 0, this.#y.length = 0, this.#b = 0, this.#n = 0, this.#f && this.#r) {
10734
+ let t = this.#r, i;
10735
+ for (; i = t?.shift();) this.#w?.(...i);
11251
10736
  }
11252
10737
  }
11253
10738
  };
11254
10739
  //#endregion
11255
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
10740
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
11256
10741
  /**
11257
10742
  * Unified memoised factory dispatching to the right provider flavour by the
11258
10743
  * source shape:
@@ -11275,7 +10760,7 @@ function ColumnsProvider(source) {
11275
10760
  * {@link AccessorColumnsProviderImpl}, so `indexAccessorRoot` runs once per
11276
10761
  * accessor root (within the LRU window).
11277
10762
  */
11278
- const _accessorProviderCache = new LRUCache({ max: 64 });
10763
+ const _accessorProviderCache = new U({ max: 64 });
11279
10764
  function AccessorColumnsProvider(root) {
11280
10765
  let provider = _accessorProviderCache.get(root.handle);
11281
10766
  if (provider === void 0) {
@@ -11289,7 +10774,7 @@ function AccessorColumnsProvider(root) {
11289
10774
  * {@link ResultPoolColumnsProviderImpl}, so `indexPoolBlock` runs once per
11290
10775
  * pool snapshot (within the LRU window).
11291
10776
  */
11292
- const _resultPoolProviderCache = new LRUCache({ max: 4 });
10777
+ const _resultPoolProviderCache = new U({ max: 4 });
11293
10778
  function ResultPoolColumnsProvider(rawPool = getCfgRenderCtx().getUpstreamBlockCtx()) {
11294
10779
  const key = hashRawPool(rawPool);
11295
10780
  let provider = _resultPoolProviderCache.get(key);
@@ -11341,7 +10826,7 @@ function hashRawPool(rawPool) {
11341
10826
  return rawPool.map((b) => `${b.blockId}\x1f${b.prodCtx ?? ""}\x1f${b.stagingCtx ?? ""}\x1f${b.prodIncomplete ? 1 : 0}\x1f${b.stagingIncomplete ? 1 : 0}`).join("");
11342
10827
  }
11343
10828
  //#endregion
11344
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
10829
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
11345
10830
  /**
11346
10831
  * Build the default set of ColumnsProviders for the ambient render ctx:
11347
10832
  * - `AccessorColumnsProvider` over `outputs` (if present)
@@ -11376,7 +10861,7 @@ function isColumnProvider(source) {
11376
10861
  return typeof p.getColumns === "function" && typeof p.isFinal === "function";
11377
10862
  }
11378
10863
  //#endregion
11379
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/data_column.js
10864
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/data_column.js
11380
10865
  /**
11381
10866
  * Thrown by leaf-recipe factories when the requested column is provably
11382
10867
  * absent in the active render ctx — i.e. every relevant accessor reports
@@ -11607,7 +11092,7 @@ const readDataStatus = memoizeByEntry(({ accessor, name }) => {
11607
11092
  return accessor.getInputsLocked() ? "absent" : "resolving";
11608
11093
  });
11609
11094
  function memoizeByEntry(fn) {
11610
- const cache = new LRUCache({ max: 1e3 });
11095
+ const cache = new U({ max: 1e3 });
11611
11096
  return (entry) => {
11612
11097
  const key = `${entry.accessor.handle}:${entry.name}`;
11613
11098
  let hit = cache.get(key);
@@ -11616,7 +11101,7 @@ function memoizeByEntry(fn) {
11616
11101
  };
11617
11102
  }
11618
11103
  //#endregion
11619
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
11104
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
11620
11105
  /**
11621
11106
  * Recipe wrapper that overlays {@link SpecOverrides} on top of any other
11622
11107
  * recipe. The id is `ColumnOverriddenKey { source: inner.id, specOverrides }`.
@@ -11754,7 +11239,7 @@ var DataColumnOverriddenRecipe = class extends ColumnOverriddenRecipe {
11754
11239
  }
11755
11240
  };
11756
11241
  //#endregion
11757
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
11242
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
11758
11243
  /**
11759
11244
  * Recipe wrapper that fixes the values of selected axes of an inner recipe
11760
11245
  * (axis slicing). The id is `FilteredPColumnId { source: inner.id,
@@ -11880,7 +11365,7 @@ function toAxisSelector(axis) {
11880
11365
  return selector;
11881
11366
  }
11882
11367
  //#endregion
11883
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
11368
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
11884
11369
  /**
11885
11370
  * Build a `ColumnRecipe` from a stringified id. Dispatches to the matching
11886
11371
  * concrete recipe variant based on the id's encoding and recurses on
@@ -11931,7 +11416,7 @@ function ColumnRecipeGetStatus(id, opts = {}) {
11931
11416
  }
11932
11417
  const ColumnRecipe = Object.assign(ColumnRecipeBuild, { getStatus: ColumnRecipeGetStatus });
11933
11418
  //#endregion
11934
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
11419
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
11935
11420
  /**
11936
11421
  * Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base
11937
11422
  * column + a `path` of linkers + qualifications.
@@ -12102,7 +11587,7 @@ function referencedUniIdsOf(key) {
12102
11587
  return /* @__PURE__ */ new Set([key.column, ...(key.path ?? []).map((item) => item.column)]);
12103
11588
  }
12104
11589
  //#endregion
12105
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/column.js
11590
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/column.js
12106
11591
  /**
12107
11592
  * Unified entry point — routes between the two top-level dispatchers:
12108
11593
  * - string id (`PObjectId` / `ColumnUniversalId`) → {@link ColumnRecipe}
@@ -12116,7 +11601,7 @@ function Column(source, opts) {
12116
11601
  return DataColumn(source, opts);
12117
11602
  }
12118
11603
  //#endregion
12119
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
11604
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
12120
11605
  /**
12121
11606
  * Build a {@link ColumnsCollection} from sandbox-side source descriptors.
12122
11607
  * Resolves the `columnsCollection` driver (either from `deps.driver` or via
@@ -12225,7 +11710,35 @@ function defaultCtxSources(ctx) {
12225
11710
  return [...currentBlockSources(ctx), { kind: "result_pool" }];
12226
11711
  }
12227
11712
  //#endregion
12228
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/columns/utils.js
11713
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/peer_links.js
11714
+ /** Main axes of the datasets: the second axis of every column marked `pl7.app/isAnchor`. */
11715
+ function collectDatasetAxes(specs) {
11716
+ return new Set(specs.flatMap((spec) => {
11717
+ const main = spec.axesSpec[1];
11718
+ return readAnnotation(spec, Annotation.IsAnchor) === "true" && main !== void 0 ? [canonicalizeAxisId(main)] : [];
11719
+ }));
11720
+ }
11721
+ /** {@link collectDatasetAxes} over the result pool. */
11722
+ function getResultPoolDatasetAxes() {
11723
+ return collectDatasetAxes(ResultPoolColumnsProvider().getColumns().map((c) => c.getSpec()));
11724
+ }
11725
+ /**
11726
+ * Labels of the peer links on a linker path. A peer link joins two datasets' main axes, e.g. one
11727
+ * clonotype to another, so the columns behind it describe a different clonotype than the row.
11728
+ */
11729
+ function findPeerLinks(linkers, datasetAxes) {
11730
+ return uniq(linkers.flatMap((l) => {
11731
+ const peer = l.axesSpec.every((a) => datasetAxes.has(canonicalizeAxisId(a)));
11732
+ const label = readAnnotation(l, Annotation.LinkLabel) ?? readAnnotation(l, Annotation.Label);
11733
+ return peer && label ? [label] : [];
11734
+ }));
11735
+ }
11736
+ /** Hover text for the link icon. */
11737
+ function describePeerLinks(links) {
11738
+ return `Reached via ${links.join(", then ")}`;
11739
+ }
11740
+ //#endregion
11741
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/columns/utils.js
12229
11742
  /**
12230
11743
  * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,
12231
11744
  * deduped in traversal order. The hit column is
@@ -12356,7 +11869,7 @@ function hasSingleDataColumn(recipe) {
12356
11869
  return recipe.getReferencedIds().length === 1;
12357
11870
  }
12358
11871
  //#endregion
12359
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
11872
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
12360
11873
  function getAllRelatedColumns(ctx, predicate) {
12361
11874
  const columns = new PColumnCollection();
12362
11875
  columns.addColumnProvider(ctx.resultPool);
@@ -12432,7 +11945,7 @@ function discoverIntegrableColumnIds(ctx, rootColumns) {
12432
11945
  }
12433
11946
  }
12434
11947
  //#endregion
12435
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
11948
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
12436
11949
  function isHiddenFromGraphColumn(column) {
12437
11950
  return !!readAnnotationJson(column, Annotation.HideDataFromGraphs);
12438
11951
  }
@@ -12461,7 +11974,7 @@ function createPFrameForGraphs(ctx, blockColumns) {
12461
11974
  }));
12462
11975
  }
12463
11976
  //#endregion
12464
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/filter_discovery.js
11977
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/filter_discovery.js
12465
11978
  /**
12466
11979
  * Matches columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
12467
11980
  *
@@ -12513,7 +12026,7 @@ function buildRefMap(entries) {
12513
12026
  return new Map(entries.map((e) => [(0, import_canonicalize.default)(e.ref), e.ref]));
12514
12027
  }
12515
12028
  //#endregion
12516
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/enrichment_discovery.js
12029
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/enrichment_discovery.js
12517
12030
  /**
12518
12031
  * Linker-reached hits attached to the anchor primary. Drops zero-hop variants
12519
12032
  * (filters / the primary itself) and structural hits (subset, linker, label
@@ -12573,7 +12086,7 @@ function enrichmentVariantsToRefs(variants, labelOptions) {
12573
12086
  });
12574
12087
  }
12575
12088
  //#endregion
12576
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/build_dataset_options.js
12089
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/build_dataset_options.js
12577
12090
  function toPredicate(opt) {
12578
12091
  if (opt === void 0) return () => true;
12579
12092
  return typeof opt === "function" ? opt : multiColumnSelectorsToPredicate(opt);
@@ -12623,7 +12136,7 @@ function buildDatasetOptions(ctx, opts) {
12623
12136
  });
12624
12137
  }
12625
12138
  //#endregion
12626
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/filters/traverse.js
12139
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/filters/traverse.js
12627
12140
  /**
12628
12141
  * Recursively traverses a FilterSpec tree bottom-up, applying visitor callbacks.
12629
12142
  *
@@ -12662,7 +12175,7 @@ function collectFilterSpecColumns(filter) {
12662
12175
  });
12663
12176
  }
12664
12177
  //#endregion
12665
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
12178
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
12666
12179
  /** Converts a QueryColumnId object into a SpecQueryExpression reference. */
12667
12180
  function resolveColumnRef(col) {
12668
12181
  return col.type === "axis" ? {
@@ -12974,7 +12487,7 @@ function isEmpty(value) {
12974
12487
  return true;
12975
12488
  }
12976
12489
  //#endregion
12977
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/filters/distill.js
12490
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/filters/distill.js
12978
12491
  /**
12979
12492
  * Strips non-FilterSpec metadata (whitelist approach) and removes
12980
12493
  * unfilled leaves (type is undefined or any required field is undefined).
@@ -13079,7 +12592,7 @@ const REQUIRED_KEYS_BY_TYPE = {
13079
12592
  greaterThanColumnOrEqual: ["column", "rhs"]
13080
12593
  };
13081
12594
  //#endregion
13082
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
12595
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
13083
12596
  /** Upgrade PlDataTableStateV2 to the latest version */
13084
12597
  function upgradePlDataTableStateV2(state) {
13085
12598
  if (!state) return createPlDataTableStateV2();
@@ -13437,7 +12950,7 @@ function parseLegacyLeafColumn(s) {
13437
12950
  return parsed;
13438
12951
  }
13439
12952
  //#endregion
13440
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
12953
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
13441
12954
  /** Adapt a {@link ColumnRecipe} to the plain {@link RuleColumn} shape. */
13442
12955
  function toRuleColumn(col) {
13443
12956
  return {
@@ -13531,11 +13044,12 @@ function deriveAllLabels(options) {
13531
13044
  return deriveDistinctLabels(columns.map((c) => ({
13532
13045
  spec: c.spec,
13533
13046
  linkerPath: c.linkerPath?.map((step) => ({ spec: step.linker.spec })),
13534
- qualifications: c.qualifications
13047
+ qualifications: c.qualifications,
13048
+ marker: c.marker
13535
13049
  })), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
13536
13050
  }
13537
13051
  //#endregion
13538
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
13052
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
13539
13053
  /**
13540
13054
  * Assemble a ptable def directly from recipes. Each secondary recipe is its own
13541
13055
  * outer-joined subtree: `getQuery()` encodes its linker chain, and its
@@ -13599,7 +13113,7 @@ function columnToJoinEntry(col, qualifications) {
13599
13113
  };
13600
13114
  }
13601
13115
  //#endregion
13602
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
13116
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
13603
13117
  function createColumnResolver(columns) {
13604
13118
  const axisIds = [];
13605
13119
  for (const c of columns) for (const ax of c.getSpec().axesSpec) axisIds.push(getAxisId(ax));
@@ -13621,7 +13135,7 @@ function createColumnResolver(columns) {
13621
13135
  };
13622
13136
  }
13623
13137
  //#endregion
13624
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
13138
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
13625
13139
  /**
13626
13140
  * Discover columns from sources/anchors and split them into primary
13627
13141
  * (direct anchor hits — zero-hop, query is a bare column) and secondary
@@ -13667,7 +13181,7 @@ function discoverLabelColumns(ctx, primary) {
13667
13181
  }).getColumns();
13668
13182
  }
13669
13183
  //#endregion
13670
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
13184
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.86.3/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
13671
13185
  function createPlDataTableV3(ctx, options) {
13672
13186
  const state = upgradePlDataTableStateV2(options.tableState);
13673
13187
  const primaryJoinType = options.primaryJoinType ?? "full";
@@ -13676,8 +13190,13 @@ function createPlDataTableV3(ctx, options) {
13676
13190
  const { primary, secondary } = resolved;
13677
13191
  if (primary.length === 0) return void 0;
13678
13192
  const { direct, linked } = splitByTopology(secondary);
13193
+ const labelable = [...primary, ...secondary].map(toLabelableColumn);
13194
+ const linkHints = collectLinkHints(labelable);
13679
13195
  const derivedLabels = deriveAllLabels({
13680
- columns: [...primary, ...secondary].filter((c) => !isColumnHidden(c.getSpec())).map(toLabelableColumn),
13196
+ columns: labelable.filter((c) => !isColumnHidden(c.spec)).map((c) => ({
13197
+ ...c,
13198
+ marker: linkHints.get(c.id)
13199
+ })),
13681
13200
  deriveLabelsOptions: {
13682
13201
  includeNativeLabel: true,
13683
13202
  ...options.labelsOptions
@@ -13750,6 +13269,7 @@ function createPlDataTableV3(ctx, options) {
13750
13269
  ],
13751
13270
  primaryColumns: primary,
13752
13271
  derivedLabels,
13272
+ linkHints,
13753
13273
  visibilityByColId,
13754
13274
  orderByColId
13755
13275
  });
@@ -13791,6 +13311,15 @@ function splitByTopology(columns) {
13791
13311
  function collectLinkerSnapshots(linked) {
13792
13312
  return uniqueBy(linked.flatMap((c) => collectLinkerColumns(c)), (c) => c.id);
13793
13313
  }
13314
+ /** Link icon hover text per column, for columns reached through at least one peer link. */
13315
+ function collectLinkHints(columns) {
13316
+ if (!columns.some((c) => c.linkerPath?.length)) return /* @__PURE__ */ new Map();
13317
+ const datasetAxes = getResultPoolDatasetAxes();
13318
+ return new Map(columns.flatMap((c) => {
13319
+ const links = findPeerLinks(c.linkerPath?.map((step) => step.linker.spec) ?? [], datasetAxes);
13320
+ return links.length > 0 ? [[c.id, describePeerLinks(links)]] : [];
13321
+ }));
13322
+ }
13794
13323
  function toLabelableColumn(col) {
13795
13324
  return {
13796
13325
  id: col.id,
@@ -13811,7 +13340,7 @@ function toLabelableColumn(col) {
13811
13340
  * The UI overlays this onto the engine-emitted specs at render time.
13812
13341
  */
13813
13342
  function buildColumnsMeta(params) {
13814
- const { fullColumns, visibleColumns, primaryColumns, derivedLabels } = params;
13343
+ const { fullColumns, visibleColumns, primaryColumns, derivedLabels, linkHints } = params;
13815
13344
  const { visibilityByColId, orderByColId } = params;
13816
13345
  const visibleStatus = buildDataStatusMap(visibleColumns);
13817
13346
  const columns = fullColumns.reduce((acc, c) => {
@@ -13820,7 +13349,8 @@ function buildColumnsMeta(params) {
13820
13349
  label: derivedLabels[c.id],
13821
13350
  visibility: getEffectiveVisibility(rc, visibilityByColId),
13822
13351
  order: getOrderPriority(rc, orderByColId),
13823
- status: visibleStatus[c.id]
13352
+ status: visibleStatus[c.id],
13353
+ linkHint: linkHints.get(c.id)
13824
13354
  };
13825
13355
  return acc;
13826
13356
  }, {});
@@ -14030,6 +13560,11 @@ const ErrorShape = objectType({
14030
13560
  errors: lazyType(() => ErrorShape.array()).optional()
14031
13561
  });
14032
13562
  //#endregion
13563
+ //#region ../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/predicate/isBoolean.mjs
13564
+ function isBoolean(x) {
13565
+ return typeof x === "boolean";
13566
+ }
13567
+ //#endregion
14033
13568
  //#region ../node_modules/.pnpm/es-toolkit@1.41.0/node_modules/es-toolkit/dist/predicate/isString.mjs
14034
13569
  function isString(value) {
14035
13570
  return typeof value === "string";
@@ -14042,6 +13577,30 @@ function isNumber(value) {
14042
13577
  //#endregion
14043
13578
  //#region ../kind/dist/index.js
14044
13579
  /**
13580
+ * The equations the block fits.
13581
+ *
13582
+ * `log_fluorescence` is a Hill fit on the log gate fluorescence with the exponent fixed at 1,
13583
+ * weighted least squares. `hill_gate_index` is the fit the block shipped through 2.4.0: a Hill
13584
+ * fit on the read-weighted mean gate index with a free exponent, graded on R² and the exponent.
13585
+ */
13586
+ const EQUATIONS = ["log_fluorescence", "hill_gate_index"];
13587
+ /**
13588
+ * How the error of a value combined over sample replicates is computed.
13589
+ *
13590
+ * `sd_over_sqrt_n` is the sample SD over the square root of the replicate count, falling back to
13591
+ * the single fit's own standard error for one replicate. `phillips` is the population SD over the
13592
+ * square root of the count plus one, which is 0 for one replicate; it reproduces the SEM published
13593
+ * with Phillips 2021.
13594
+ */
13595
+ const REPLICATE_ERROR_MODELS = ["sd_over_sqrt_n", "phillips"];
13596
+ const DEFAULT_REPLICATE_ERROR_MODEL = "sd_over_sqrt_n";
13597
+ /**
13598
+ * Share of the entered replicates one censoring side must hold, and exceed the other side by, for
13599
+ * the combined value to be reported as that side's bound. The block's own rule: no published
13600
+ * method defines one, and opposite bounds cannot be averaged into anything meaningful.
13601
+ */
13602
+ const DEFAULT_CENSORED_MAJORITY = .5;
13603
+ /**
14045
13604
  * The contract at runtime, for params arriving from a template file rather than typed code. An
14046
13605
  * absent field is always allowed — every param is optional and the block's own default takes
14047
13606
  * over — so each guard runs only on what is present. Keys the contract does not name are dropped
@@ -14083,6 +13642,14 @@ function isNumberFrom(min) {
14083
13642
  return (v) => isFiniteNumber(v) && v >= min;
14084
13643
  }
14085
13644
  const isFraction = (v) => isFiniteNumber(v) && v >= 0 && v <= 1;
13645
+ /** A fraction with zero excluded: a plateau floor of 0 asks for no rise at all. */
13646
+ const isPositiveFraction = (v) => isFiniteNumber(v) && v > 0 && v <= 1;
13647
+ const isEquation = (v) => isString(v) && EQUATIONS.includes(v);
13648
+ const isReplicateErrorModel = (v) => isString(v) && REPLICATE_ERROR_MODELS.includes(v);
13649
+ /** A positive number: a cutoff of 0 decades rejects every fit. */
13650
+ const isPositiveNumber = (v) => isFiniteNumber(v) && v > 0;
13651
+ /** A share from one half to the whole: below one half no side can be the majority. */
13652
+ const isMajority = (v) => isFiniteNumber(v) && v >= .5 && v <= 1;
14086
13653
  /**
14087
13654
  * The runtime half of the contract. The `satisfies` clause is what stops it drifting: every
14088
13655
  * field `BlockParams` declares must appear here, and each guard must narrow to that field's own
@@ -14100,7 +13667,13 @@ const CONTRACT = {
14100
13667
  binColumnRef: check(isPlRef, "a reference to a FACS bin column"),
14101
13668
  antigenColumnRef: check(isPlRef, "a reference to an antigen column"),
14102
13669
  sortFractionColumnRef: check(isPlRef, "a reference to a FACS sort fraction column"),
13670
+ binFluorescenceColumnRef: check(isPlRef, "a reference to a gate fluorescence column"),
14103
13671
  targetAntigen: check(isString, "a string"),
13672
+ equation: check(isEquation, `one of ${EQUATIONS.map((e) => `"${e}"`).join(" or ")}`),
13673
+ plateauFloor: check(isPositiveFraction, "a number above 0 and at most 1"),
13674
+ r2GateMin: check(isFraction, "a number between 0 and 1"),
13675
+ requireAllConcentrations: check(isBoolean, "true or false"),
13676
+ kdSeGateMax: check((v) => isFiniteNumber(v) && v > 0, "a number above 0"),
14104
13677
  minReadsPerConcentration: check(isNumberFrom(1), "a number of 1 or more"),
14105
13678
  minConcentrationPoints: check(isNumberFrom(3), "a number of 3 or more"),
14106
13679
  r2ThresholdGood: check(isFraction, "a number between 0 and 1"),
@@ -14110,10 +13683,27 @@ const CONTRACT = {
14110
13683
  hookEffectThresholdBin: check(isFiniteNumber, "a number"),
14111
13684
  hookEffectThresholdNoBin: check(isFiniteNumber, "a number"),
14112
13685
  hookEffectMinReads: check(isFiniteNumber, "a number"),
13686
+ replicateColumnRef: check(isPlRef, "a reference to a replicate column"),
13687
+ replicateErrorModel: check(isReplicateErrorModel, `one of ${REPLICATE_ERROR_MODELS.map((m) => `"${m}"`).join(" or ")}`),
13688
+ replicateFitErrorCutoff: check(isPositiveNumber, "a number above 0"),
13689
+ replicateR2Floor: check(isFraction, "a number between 0 and 1"),
13690
+ replicateCensoredMajority: check(isMajority, "a number between 0.5 and 1"),
14113
13691
  customBlockLabel: check(isString, "a string")
14114
13692
  };
13693
+ Object.keys(CONTRACT);
14115
13694
  //#endregion
14116
13695
  //#region ../model/dist/index.js
13696
+ /**
13697
+ * The per-replicate chart: one dot per replicate on a log Kd,app axis. The page binds the sources
13698
+ * from the columns the run produced.
13699
+ */
13700
+ const REPLICATES_DEFAULT_STATE = {
13701
+ title: "",
13702
+ template: "dots",
13703
+ currentTab: null,
13704
+ layersSettings: { dots: {} },
13705
+ axesSettings: { axisY: { scale: "log" } }
13706
+ };
14117
13707
  const summaryCol = (name, type) => `{"kind":"column","name":"{\\"name\\":\\"${name}\\",\\"resolvePath\\":[\\"main\\",\\"summaryPf\\"]}","type":"${type}"}`;
14118
13708
  const KD_PLOT_COL = summaryCol("kdPlotPosition", "Double");
14119
13709
  const HILL_PLOT_COL = summaryCol("hillPlotPosition", "Double");
@@ -14128,7 +13718,10 @@ const AFFINITY_VS_FIT_DEFAULT_STATE = {
14128
13718
  type: "grouping",
14129
13719
  value: FIT_FAILURE_REASON_COL
14130
13720
  } } },
14131
- axesSettings: { axisX: { scale: "log" } },
13721
+ axesSettings: {
13722
+ axisX: { scale: "log" },
13723
+ axisY: { scale: "log" }
13724
+ },
14132
13725
  optionsState: {
14133
13726
  type: "scatterplot",
14134
13727
  components: {
@@ -14199,18 +13792,31 @@ const initBlockData = (params) => ({
14199
13792
  filterRef: params?.filterRef,
14200
13793
  concentrationColumnRef: params?.concentrationColumnRef,
14201
13794
  binColumnRef: params?.binColumnRef,
13795
+ binFluorescenceColumnRef: params?.binFluorescenceColumnRef,
14202
13796
  antigenColumnRef: params?.antigenColumnRef,
14203
13797
  sortFractionColumnRef: params?.sortFractionColumnRef,
14204
13798
  targetAntigen: params?.targetAntigen,
14205
- minReadsPerConcentration: params?.minReadsPerConcentration ?? 3,
14206
- minConcentrationPoints: params?.minConcentrationPoints ?? 5,
14207
- r2ThresholdGood: params?.r2ThresholdGood ?? .8,
14208
- r2ThresholdFailed: params?.r2ThresholdFailed ?? .5,
14209
- nMin: params?.nMin ?? .5,
14210
- nMax: params?.nMax ?? 2,
14211
- hookEffectThresholdBin: params?.hookEffectThresholdBin ?? .2,
14212
- hookEffectThresholdNoBin: params?.hookEffectThresholdNoBin ?? .02,
14213
- hookEffectMinReads: params?.hookEffectMinReads ?? 20,
13799
+ equation: params?.equation ?? (params?.minReadsPerConcentration !== void 0 ? "hill_gate_index" : "log_fluorescence"),
13800
+ plateauFloor: params?.plateauFloor ?? .667,
13801
+ r2GateMin: params?.r2GateMin ?? .8,
13802
+ kdSeGateMax: params?.kdSeGateMax ?? 1,
13803
+ requireAllConcentrations: params?.requireAllConcentrations,
13804
+ replicateColumnRef: params?.replicateColumnRef,
13805
+ replicateErrorModel: params?.replicateErrorModel ?? "sd_over_sqrt_n",
13806
+ replicateFitErrorCutoff: params?.replicateFitErrorCutoff,
13807
+ replicateR2Floor: params?.replicateR2Floor,
13808
+ replicateCensoredMajority: params?.replicateCensoredMajority ?? .5,
13809
+ replicateTableState: createPlDataTableStateV2(),
13810
+ graphStateReplicates: REPLICATES_DEFAULT_STATE,
13811
+ minReadsPerConcentration: params?.minReadsPerConcentration ?? READ_COVERAGE_DEFAULTS.minReadsPerConcentration,
13812
+ minConcentrationPoints: params?.minConcentrationPoints ?? READ_COVERAGE_DEFAULTS.minConcentrationPoints,
13813
+ r2ThresholdGood: params?.r2ThresholdGood ?? HILL_GATE_INDEX_DEFAULTS.r2ThresholdGood,
13814
+ r2ThresholdFailed: params?.r2ThresholdFailed ?? HILL_GATE_INDEX_DEFAULTS.r2ThresholdFailed,
13815
+ nMin: params?.nMin ?? HILL_GATE_INDEX_DEFAULTS.nMin,
13816
+ nMax: params?.nMax ?? HILL_GATE_INDEX_DEFAULTS.nMax,
13817
+ hookEffectThresholdBin: params?.hookEffectThresholdBin ?? HILL_GATE_INDEX_DEFAULTS.hookEffectThresholdBin,
13818
+ hookEffectThresholdNoBin: params?.hookEffectThresholdNoBin ?? HILL_GATE_INDEX_DEFAULTS.hookEffectThresholdNoBin,
13819
+ hookEffectMinReads: params?.hookEffectMinReads ?? HILL_GATE_INDEX_DEFAULTS.hookEffectMinReads,
14214
13820
  defaultBlockLabel: "Tite-Seq Analysis",
14215
13821
  customBlockLabel: params?.customBlockLabel ?? "",
14216
13822
  tableState: createPlDataTableStateV2(),
@@ -14235,7 +13841,91 @@ const initBlockData = (params) => ({
14235
13841
  graphStateAffinityVsFit: AFFINITY_VS_FIT_DEFAULT_STATE,
14236
13842
  settingsOpen: false
14237
13843
  });
14238
- const dataModel = new DataModelBuilder({ kind }).from("v1").init(({ params }) => initBlockData(params));
13844
+ /**
13845
+ * v1 -> v2. A v1 project (v2.4.0 or earlier) ran the gate-index fit, so name it.
13846
+ *
13847
+ * Writing the field is the point. An absent `equation` reads as a new block's default,
13848
+ * `log_fluorescence`, and every released project would change the equation it fits.
13849
+ *
13850
+ * The plateau floor arrives at a new block's value and stays unread. `hill_gate_index` does
13851
+ * not read one. Nothing else moves: every setting, reference, label and piece of view state
13852
+ * crosses untouched, so a re-run reproduces the numbers the project already holds.
13853
+ */
13854
+ const migrateV1ToV2 = (v1) => ({
13855
+ ...v1,
13856
+ equation: "hill_gate_index",
13857
+ plateauFloor: DEFAULT_PLATEAU_FLOOR
13858
+ });
13859
+ /**
13860
+ * v2 -> v3. The R² gate arrives off, so a log-fluorescence project rates its fits as it did. v2
13861
+ * shipped only in development builds; the step repairs their stored projects.
13862
+ */
13863
+ const migrateV2ToV3 = (v2) => ({
13864
+ ...v2,
13865
+ r2GateEnabled: false,
13866
+ r2GateMin: .8
13867
+ });
13868
+ /**
13869
+ * v3 -> v4. Sample replicates arrive unset: no replicate column, both filters off, the default
13870
+ * error model and censoring majority, and empty per-replicate view state. The args a v3 project
13871
+ * sends do not move, so it does not re-run.
13872
+ */
13873
+ const migrateV3ToV4 = (v3) => ({
13874
+ ...v3,
13875
+ replicateErrorModel: DEFAULT_REPLICATE_ERROR_MODEL,
13876
+ replicateCensoredMajority: DEFAULT_CENSORED_MAJORITY,
13877
+ replicateTableState: createPlDataTableStateV2(),
13878
+ graphStateReplicates: REPLICATES_DEFAULT_STATE
13879
+ });
13880
+ /**
13881
+ * v4 -> v5. A stored point count below the minimum is raised to it. A cleared field stays cleared.
13882
+ * Raising it changes that project's args, so the block goes stale.
13883
+ */
13884
+ const migrateV4ToV5 = (v4) => ({
13885
+ ...v4,
13886
+ minConcentrationPoints: v4.minConcentrationPoints === void 0 ? void 0 : Math.max(v4.minConcentrationPoints, 5)
13887
+ });
13888
+ /**
13889
+ * v5 -> v6. The checkbox is gone: a limit applies when it is set. A project with the checkbox off
13890
+ * clears both limits, and one with it on keeps them, so the args do not move and it does not
13891
+ * re-run.
13892
+ */
13893
+ const migrateV5ToV6 = ({ r2GateEnabled, ...v5 }) => ({
13894
+ ...v5,
13895
+ r2GateMin: r2GateEnabled ? v5.r2GateMin : void 0,
13896
+ kdSeGateMax: r2GateEnabled ? v5.kdSeGateMax : void 0
13897
+ });
13898
+ const dataModel = new DataModelBuilder({ kind }).from("v1").migrate("v2", migrateV1ToV2).migrate("v3", migrateV2ToV3).migrate("v4", migrateV3ToV4).migrate("v5", migrateV4ToV5).migrate("v6", migrateV5ToV6).init(({ params }) => initBlockData(params));
13899
+ /** The per-replicate frame of the last run. Undefined when the run combined no replicates. */
13900
+ function replicateCols(ctx) {
13901
+ return ctx.outputs?.resolve({
13902
+ field: "replicatePf",
13903
+ allowPermanentAbsence: true
13904
+ })?.getPColumns();
13905
+ }
13906
+ const REPLICATE_AXIS = "pl7.app/vdj/replicate";
13907
+ /**
13908
+ * The filter that narrows the per-replicate frame to one variant. The variant axis is whichever
13909
+ * axis is not the replicate one, taken from the frame's own spec so the domain matches exactly.
13910
+ * Undefined when nothing is selected or the frame has no such axis.
13911
+ */
13912
+ function replicateDrilldownFilter(specs, key) {
13913
+ const value = key?.[0];
13914
+ if (value === void 0 || value === null) return void 0;
13915
+ const axis = specs.find((s) => s.name === "pl7.app/vdj/kd")?.axesSpec.find((a) => a.name !== REPLICATE_AXIS);
13916
+ if (axis === void 0) return void 0;
13917
+ return {
13918
+ type: "and",
13919
+ filters: [{
13920
+ type: "patternEquals",
13921
+ column: {
13922
+ type: "axis",
13923
+ id: getAxisId(axis)
13924
+ },
13925
+ value: String(value)
13926
+ }]
13927
+ };
13928
+ }
14239
13929
  function isIntegerValueType(vt) {
14240
13930
  return vt === "Int" || vt === "Long";
14241
13931
  }
@@ -14265,16 +13955,81 @@ const DATASET_KEY_AXES = /* @__PURE__ */ new Set([
14265
13955
  "pl7.app/vdj/scClonotypeKey",
14266
13956
  "pl7.app/variantKey"
14267
13957
  ]);
14268
- const platforma$1 = BlockModelV3.create({
14269
- dataModel,
14270
- kind
14271
- }).templateParams(deriveTemplateParams).args((data) => {
13958
+ /**
13959
+ * The block's workflow input, and the gate on whether it may run at all: a throw here marks the
13960
+ * args invalid and disables Run. Named rather than written inline so the staleness contract —
13961
+ * which bytes a given state projects — can be asserted in a test.
13962
+ */
13963
+ const deriveArgs = (data) => {
14272
13964
  if (data.abundanceRef === void 0) throw new Error("Abundance column is required");
14273
13965
  if (data.concentrationColumnRef === void 0) throw new Error("Concentration column is required");
14274
13966
  if (data.antigenColumnRef !== void 0 && !data.targetAntigen) throw new Error("Target antigen is required when an antigen column is selected");
14275
13967
  if (data.sortFractionColumnRef !== void 0 && data.binColumnRef === void 0) throw new Error("FACS sort fraction requires a FACS bin column — the correction only applies in bin mode");
13968
+ const inputs = {
13969
+ abundanceRef: data.abundanceRef,
13970
+ concentrationColumnRef: data.concentrationColumnRef,
13971
+ binColumnRef: data.binColumnRef,
13972
+ antigenColumnRef: data.antigenColumnRef,
13973
+ sortFractionColumnRef: data.sortFractionColumnRef,
13974
+ targetAntigen: data.targetAntigen
13975
+ };
13976
+ if (data.replicateColumnRef !== void 0) {
13977
+ if (data.replicateFitErrorCutoff !== void 0 && data.replicateFitErrorCutoff <= 0) throw new Error("Replicate fit-error cutoff must be above 0, or empty to turn it off");
13978
+ if (data.replicateR2Floor !== void 0 && (data.replicateR2Floor < 0 || data.replicateR2Floor > 1)) throw new Error("Replicate R² floor must be between 0 and 1, or empty to turn it off");
13979
+ if (data.replicateCensoredMajority === void 0) throw new Error("Replicate censoring majority is required");
13980
+ if (data.replicateCensoredMajority < .5 || data.replicateCensoredMajority > 1) throw new Error("Replicate censoring majority must be between 0.5 and 1");
13981
+ }
13982
+ const labels = {
13983
+ defaultBlockLabel: data.defaultBlockLabel ?? "Tite-Seq Analysis",
13984
+ customBlockLabel: data.customBlockLabel ?? "",
13985
+ ...data.filterRef !== void 0 && { inputFilter: createGlobalPObjectId(data.filterRef.blockId, data.filterRef.name) },
13986
+ ...data.replicateColumnRef !== void 0 && {
13987
+ replicateColumnRef: data.replicateColumnRef,
13988
+ replicateErrorModel: "sd_over_sqrt_n",
13989
+ ...data.equation === "log_fluorescence" && data.replicateFitErrorCutoff !== void 0 && { replicateFitErrorCutoff: data.replicateFitErrorCutoff },
13990
+ ...data.replicateR2Floor !== void 0 && { replicateR2Floor: data.replicateR2Floor },
13991
+ replicateCensoredMajority: data.replicateCensoredMajority
13992
+ }
13993
+ };
13994
+ switch (data.equation) {
13995
+ case "log_fluorescence": return logFluorescenceArgs(data, inputs, labels);
13996
+ case "hill_gate_index": return hillGateIndexArgs(data, inputs, labels);
13997
+ default: throw new Error(`Unknown equation: ${data.equation}`);
13998
+ }
13999
+ };
14000
+ /**
14001
+ * Read coverage, which both equations read: a point below the read floor is dropped, and a
14002
+ * clonotype left with fewer than the point count is refused before any fit. Narrowed here because
14003
+ * a check in the caller does not narrow `data` inside each equation's builder.
14004
+ */
14005
+ function readCoverage(data) {
14276
14006
  if (data.minReadsPerConcentration === void 0) throw new Error("Min reads per concentration is required");
14277
14007
  if (data.minConcentrationPoints === void 0) throw new Error("Min concentration points is required");
14008
+ if (data.minReadsPerConcentration < 1) throw new Error("Min reads per concentration must be ≥ 1");
14009
+ if (data.minConcentrationPoints < 5) throw new Error(`Min concentration points must be ≥ 5`);
14010
+ return {
14011
+ minReadsPerConcentration: data.minReadsPerConcentration,
14012
+ minConcentrationPoints: data.minConcentrationPoints
14013
+ };
14014
+ }
14015
+ function logFluorescenceArgs(data, inputs, labels) {
14016
+ if (data.plateauFloor === void 0) throw new Error("Plateau floor is required");
14017
+ if (data.plateauFloor <= 0 || data.plateauFloor > 1) throw new Error("Plateau floor must be above 0 and at most 1");
14018
+ if (data.binColumnRef === void 0) throw new Error("The log fluorescence fit requires a FACS bin column. For frequency-only data, choose the Mean bin fit in Fit method equation.");
14019
+ if (data.r2GateMin !== void 0 && !(data.r2GateMin >= 0 && data.r2GateMin <= 1)) throw new Error("Minimum R² must be between 0 and 1, or empty for no limit");
14020
+ if (data.kdSeGateMax !== void 0 && !(data.kdSeGateMax > 0)) throw new Error("Maximum Kd,app SE must be above 0, or empty for no limit");
14021
+ return {
14022
+ ...inputs,
14023
+ binFluorescenceColumnRef: data.binFluorescenceColumnRef,
14024
+ equation: "log_fluorescence",
14025
+ plateauFloor: data.plateauFloor,
14026
+ ...readCoverage(data),
14027
+ ...data.r2GateMin !== void 0 && { r2GateMin: data.r2GateMin },
14028
+ ...data.kdSeGateMax !== void 0 && { kdSeGateMax: data.kdSeGateMax },
14029
+ ...labels
14030
+ };
14031
+ }
14032
+ function hillGateIndexArgs(data, inputs, labels) {
14278
14033
  if (data.r2ThresholdGood === void 0) throw new Error("R² threshold (Good) is required");
14279
14034
  if (data.r2ThresholdFailed === void 0) throw new Error("R² threshold (Failed) is required");
14280
14035
  if (data.nMin === void 0) throw new Error("Hill coefficient nMin is required");
@@ -14287,36 +14042,62 @@ const platforma$1 = BlockModelV3.create({
14287
14042
  if (data.nMin >= data.nMax) throw new Error("Hill coefficient nMin must be < nMax");
14288
14043
  if (data.r2ThresholdGood < 0 || data.r2ThresholdGood > 1) throw new Error("R² threshold (Good) out of range");
14289
14044
  if (data.r2ThresholdFailed < 0 || data.r2ThresholdFailed > 1) throw new Error("R² threshold (Failed) out of range");
14290
- if (data.minReadsPerConcentration < 1) throw new Error("Min reads per concentration must be ≥ 1");
14291
- if (data.minConcentrationPoints < 3) throw new Error("Min concentration points must be ≥ 3");
14292
14045
  return {
14293
- abundanceRef: data.abundanceRef,
14294
- concentrationColumnRef: data.concentrationColumnRef,
14295
- binColumnRef: data.binColumnRef,
14296
- antigenColumnRef: data.antigenColumnRef,
14297
- sortFractionColumnRef: data.sortFractionColumnRef,
14298
- targetAntigen: data.targetAntigen,
14299
- minReadsPerConcentration: data.minReadsPerConcentration,
14300
- minConcentrationPoints: data.minConcentrationPoints,
14046
+ ...inputs,
14047
+ ...readCoverage(data),
14301
14048
  r2ThresholdGood: data.r2ThresholdGood,
14302
14049
  r2ThresholdFailed: data.r2ThresholdFailed,
14303
14050
  nMin: data.nMin,
14304
14051
  nMax: data.nMax,
14305
- hookEffectThresholdBin: data.hookEffectThresholdBin ?? .2,
14306
- hookEffectThresholdNoBin: data.hookEffectThresholdNoBin ?? .02,
14052
+ hookEffectThresholdBin: data.hookEffectThresholdBin ?? HILL_GATE_INDEX_DEFAULTS.hookEffectThresholdBin,
14053
+ hookEffectThresholdNoBin: data.hookEffectThresholdNoBin ?? HILL_GATE_INDEX_DEFAULTS.hookEffectThresholdNoBin,
14307
14054
  hookEffectMinReads: data.hookEffectMinReads,
14308
- defaultBlockLabel: data.defaultBlockLabel ?? "Tite-Seq Analysis",
14309
- customBlockLabel: data.customBlockLabel ?? "",
14310
- ...data.filterRef !== void 0 && { inputFilter: createGlobalPObjectId(data.filterRef.blockId, data.filterRef.name) }
14055
+ ...labels
14311
14056
  };
14312
- }).output("abundanceOptions", (ctx) => buildDatasetOptions(ctx, {
14057
+ }
14058
+ /** The block's pages. Per-replicate values are read by clicking a variant in the main table. */
14059
+ const sectionsFor = () => [
14060
+ {
14061
+ type: "link",
14062
+ href: "/",
14063
+ label: "Table"
14064
+ },
14065
+ {
14066
+ type: "link",
14067
+ href: "/titration-curves",
14068
+ label: "Titration Curves"
14069
+ },
14070
+ {
14071
+ type: "link",
14072
+ href: "/kd-distribution",
14073
+ label: "Kd Distribution"
14074
+ },
14075
+ {
14076
+ type: "link",
14077
+ href: "/affinity-vs-fit",
14078
+ label: "Affinity vs Fit Quality"
14079
+ }
14080
+ ];
14081
+ const platforma$1 = BlockModelV3.create({
14082
+ dataModel,
14083
+ kind
14084
+ }).templateParams(deriveTemplateParams).args(deriveArgs).output("abundanceOptions", (ctx) => buildDatasetOptions(ctx, {
14313
14085
  primary: (spec) => isPColumnSpec(spec) && spec.annotations?.["pl7.app/isAnchor"] === "true" && spec.axesSpec.length === 2 && spec.axesSpec[0].name === "pl7.app/sampleId" && DATASET_KEY_AXES.has(spec.axesSpec[1].name),
14314
14086
  filter: (spec) => isPColumnSpec(spec) && spec.axesSpec.length === 1 && DATASET_KEY_AXES.has(spec.axesSpec[0].name),
14315
14087
  requireEnrichments: false
14316
- }) ?? []).output("concentrationOptions", (ctx) => filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && isFloatValueType(spec.valueType) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId", { excludeRef: ctx.data.sortFractionColumnRef })).output("binOptions", (ctx) => filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && isIntegerValueType(spec.valueType) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId")).output("sortFractionOptions", (ctx) => filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && isFloatValueType(spec.valueType) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId", {
14088
+ }) ?? []).output("concentrationOptions", (ctx) => filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && isFloatValueType(spec.valueType) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId", { excludeRef: ctx.data.sortFractionColumnRef })).output("binOptions", (ctx) => filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && isIntegerValueType(spec.valueType) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId")).output("binFluorescenceOptions", (ctx) => filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && isFloatValueType(spec.valueType) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId", { excludeRef: ctx.data.concentrationColumnRef })).output("sortFractionOptions", (ctx) => filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && isFloatValueType(spec.valueType) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId", {
14317
14089
  excludeRef: ctx.data.concentrationColumnRef,
14318
14090
  valuePredicate: (finite) => finite.every((v) => v >= 0 && v <= 1)
14319
- })).output("antigenOptions", (ctx) => ctx.resultPool.getOptions((spec) => isPColumnSpec(spec) && spec.valueType === "String" && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId")).output("targetAntigenValues", (ctx) => {
14091
+ })).output("antigenOptions", (ctx) => ctx.resultPool.getOptions((spec) => isPColumnSpec(spec) && spec.valueType === "String" && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId")).output("replicateOptions", (ctx) => {
14092
+ const picked = [
14093
+ ctx.data.concentrationColumnRef,
14094
+ ctx.data.binColumnRef,
14095
+ ctx.data.sortFractionColumnRef,
14096
+ ctx.data.binFluorescenceColumnRef,
14097
+ ctx.data.antigenColumnRef
14098
+ ].filter((ref) => ref !== void 0);
14099
+ return filterPopulatedOptions(ctx, (spec) => isPColumnSpec(spec) && (spec.valueType === "String" || isIntegerValueType(spec.valueType)) && spec.axesSpec.length === 1 && spec.axesSpec[0].name === "pl7.app/sampleId").filter((opt) => !picked.some((ref) => plRefsEqual(opt.ref, ref)));
14100
+ }).output("targetAntigenValues", (ctx) => {
14320
14101
  if (!ctx.data.antigenColumnRef) return void 0;
14321
14102
  const values = (ctx.resultPool.getDataByRef(ctx.data.antigenColumnRef)?.data)?.getDataAsJson()?.["data"];
14322
14103
  if (!values) return void 0;
@@ -14330,9 +14111,13 @@ const platforma$1 = BlockModelV3.create({
14330
14111
  for (const key of [
14331
14112
  "summaryPf",
14332
14113
  "signalPf",
14333
- "logHandle"
14114
+ "logHandle",
14115
+ "replicatePf"
14334
14116
  ]) {
14335
- const errorAcc = ctx.outputs?.resolve(key)?.getError();
14117
+ const errorAcc = (key === "replicatePf" ? ctx.outputs?.resolve({
14118
+ field: key,
14119
+ allowPermanentAbsence: true
14120
+ }) : ctx.outputs?.resolve(key))?.getError();
14336
14121
  if (!errorAcc) continue;
14337
14122
  const typeName = errorAcc.resourceType.name;
14338
14123
  const detail = errorAcc.getDataAsJson()?.message ?? typeName;
@@ -14342,13 +14127,6 @@ const platforma$1 = BlockModelV3.create({
14342
14127
  message: isCidConflict ? `Transient result-hash conflict on "${key}": ${detail}. The platform retries automatically; usually self-recovers. If this persists across retries, the workflow likely has a non-deterministic step — report it.` : `Workflow output "${key}" failed: ${detail}`
14343
14128
  });
14344
14129
  }
14345
- if (data.concentrationColumnRef !== void 0) {
14346
- const unitLabel = ctx.resultPool.getPColumnSpecByRef(data.concentrationColumnRef)?.annotations?.["pl7.app/label"];
14347
- if (unitLabel && /\s/.test(unitLabel)) issues.push({
14348
- severity: "warning",
14349
- message: `Concentration column label "${unitLabel}" contains spaces. The full label becomes the Kd,app unit, so values render as "Kd,app (${unitLabel})". Use a bare unit like "nM" or "µM".`
14350
- });
14351
- }
14352
14130
  if (data.antigenColumnRef === void 0 && data.targetAntigen) issues.push({
14353
14131
  severity: "warning",
14354
14132
  message: "targetAntigen is set but no antigen column is selected — the value is ignored. Select an antigen column or clear the targetAntigen field."
@@ -14361,7 +14139,6 @@ const platforma$1 = BlockModelV3.create({
14361
14139
  }).output("logHandle", (ctx) => ctx.outputs?.resolve("logHandle")?.getLogHandle()).output("isRunning", (ctx) => ctx.outputs?.getIsReadyOrError() === false).outputWithStatus("summaryTable", (ctx) => {
14362
14140
  const summaryCols = ctx.outputs?.resolve("summaryPf")?.getPColumns();
14363
14141
  if (summaryCols === void 0) return void 0;
14364
- const signalCols = ctx.outputs?.resolve("signalPf")?.getPColumns() ?? [];
14365
14142
  const kdCol = summaryCols.find((c) => c.spec.name === "pl7.app/vdj/kd");
14366
14143
  if (!kdCol) return void 0;
14367
14144
  const resultPoolCols = ColumnsCollection(["result_pool"], { ctx: ctx.ctx }).filter({
@@ -14378,13 +14155,9 @@ const platforma$1 = BlockModelV3.create({
14378
14155
  return spec.valueType !== "File" && !spec.annotations?.["pl7.app/trace"]?.includes("milaboratories.titeseq-analysis");
14379
14156
  }).map((c) => c.withSpecs({ annotations: { "pl7.app/table/visibility": "optional" } }));
14380
14157
  return createPlDataTableV3(ctx, {
14381
- primaryColumns: [...summaryCols, ...signalCols].map((c) => DataColumn.fromColumn(c)),
14158
+ primaryColumns: summaryCols.map((c) => DataColumn.fromColumn(c)),
14382
14159
  columns: resultPoolCols,
14383
- tableState: ctx.data.tableState,
14384
- displayOptions: { visibility: [{
14385
- match: { name: [exactly("pl7.app/vdj/fitFailureReason"), ...signalCols.map((c) => exactly(c.spec.name))] },
14386
- visibility: "default"
14387
- }] }
14160
+ tableState: ctx.data.tableState
14388
14161
  });
14389
14162
  }).outputWithStatus("titrationCurvesPf", (ctx) => {
14390
14163
  const signalCols = ctx.outputs?.resolve("signalPf")?.getPColumns();
@@ -14414,28 +14187,52 @@ const platforma$1 = BlockModelV3.create({
14414
14187
  const pCols = ctx.outputs?.resolve("summaryPf")?.getPColumns();
14415
14188
  if (pCols === void 0) return void 0;
14416
14189
  return pCols.length === 0;
14417
- }).output("binMode", (ctx) => ctx.data.binColumnRef !== void 0).title(() => "Tite-Seq Analysis").subtitle((ctx) => ctx.data.customBlockLabel || ctx.data.defaultBlockLabel || "").sections((_ctx) => [
14418
- {
14419
- type: "link",
14420
- href: "/",
14421
- label: "Table"
14422
- },
14423
- {
14424
- type: "link",
14425
- href: "/titration-curves",
14426
- label: "Titration Curves"
14427
- },
14428
- {
14429
- type: "link",
14430
- href: "/kd-distribution",
14431
- label: "Kd Distribution"
14432
- },
14433
- {
14434
- type: "link",
14435
- href: "/affinity-vs-fit",
14436
- label: "Affinity vs Fit Quality"
14437
- }
14438
- ]).done();
14190
+ }).output("binMode", (ctx) => ctx.data.binColumnRef !== void 0).output("replicates", (ctx) => replicateCols(ctx) !== void 0).outputWithStatus("replicateTable", (ctx) => {
14191
+ const cols = replicateCols(ctx);
14192
+ if (cols === void 0) return void 0;
14193
+ return createPlDataTableV3(ctx, {
14194
+ primaryColumns: cols.map((c) => DataColumn.fromColumn(c)),
14195
+ columns: void 0,
14196
+ tableState: ctx.data.replicateTableState,
14197
+ displayOptions: { visibility: [{
14198
+ match: { name: cols.map((c) => exactly(c.spec.name)) },
14199
+ visibility: "default"
14200
+ }] }
14201
+ });
14202
+ }).output("summaryKeyAxisId", (ctx) => {
14203
+ const cols = ctx.outputs?.resolve("summaryPf")?.getPColumns();
14204
+ const axis = (cols?.find((c) => c.spec.name === "pl7.app/vdj/affinityClass") ?? cols?.find((c) => c.spec.name === "pl7.app/vdj/kd"))?.spec.axesSpec[0];
14205
+ return axis === void 0 ? void 0 : getAxisId(axis);
14206
+ }).outputWithStatus("replicateDrilldownTable", (ctx) => {
14207
+ const cols = replicateCols(ctx);
14208
+ if (cols === void 0) return void 0;
14209
+ const filters = replicateDrilldownFilter(cols.map((c) => c.spec), ctx.data.replicateDrilldownKey);
14210
+ if (filters === void 0) return void 0;
14211
+ return createPlDataTableV3(ctx, {
14212
+ primaryColumns: cols.map((c) => DataColumn.fromColumn(c)),
14213
+ columns: void 0,
14214
+ tableState: ctx.data.replicateDrilldownTableState,
14215
+ displayOptions: { visibility: [{
14216
+ match: { name: [exactly("pl7.app/label")] },
14217
+ visibility: "hidden"
14218
+ }, {
14219
+ match: { name: cols.map((c) => exactly(c.spec.name)) },
14220
+ visibility: "default"
14221
+ }] },
14222
+ filters
14223
+ });
14224
+ }).outputWithStatus("replicatePfHandle", (ctx) => {
14225
+ const cols = replicateCols(ctx);
14226
+ if (cols === void 0) return void 0;
14227
+ return createPFrameForGraphs(ctx, cols);
14228
+ }).output("replicatePfCols", (ctx) => {
14229
+ const cols = replicateCols(ctx);
14230
+ if (cols === void 0) return void 0;
14231
+ return cols.map((c) => ({
14232
+ columnId: c.id,
14233
+ spec: c.spec
14234
+ }));
14235
+ }).title(() => "Tite-Seq Analysis").subtitle((ctx) => ctx.data.customBlockLabel || ctx.data.defaultBlockLabel || "").sections(() => sectionsFor()).done();
14439
14236
  //#endregion
14440
14237
  //#region src/index.ts
14441
14238
  const selfUrl = import.meta.url;