@marktiderman/genesis-forms 0.4.0 → 0.4.1

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.d.cts CHANGED
@@ -553,6 +553,8 @@ declare const CALCULATED_TYPE = "calculated";
553
553
  */
554
554
  declare const COMPUTED_FIELD_TYPES: readonly ["calculated"];
555
555
  type CalculatedFormat = "number" | "percent" | "text";
556
+ /** Longest the formulas of one form may be, all together (`parseForm` checks it). */
557
+ declare const MAX_FORM_FORMULA_LENGTH = 20000;
556
558
  /** Most decimal places a calculated value may keep. */
557
559
  declare const MAX_CALCULATED_DECIMALS = 10;
558
560
  interface CalculatedProps {
@@ -577,10 +579,18 @@ declare function formatCalculated(value: Json | undefined, field: FieldBlock): s
577
579
  * server can't make every formula over it slow.
578
580
  */
579
581
  declare const MAX_FORMULA_ITEMS = 10000;
582
+ /**
583
+ * Most list items and table rows all of a form's formulas read in one go
584
+ * (each answer and column counted once, in form order). A formula that reads
585
+ * an answer past the limit, or one over `MAX_FORMULA_ITEMS`, has no value
586
+ * (blank, never a partial total), so many big answers can't make working
587
+ * the values out slow either.
588
+ */
589
+ declare const MAX_SETTLE_ITEMS = 50000;
580
590
  /**
581
591
  * The value a formula reads for an answer: numbers and text as they are, a
582
592
  * list's items, one table column's cells. A list or table of more than
583
- * `MAX_FORMULA_ITEMS` reads as blank.
593
+ * `MAX_FORMULA_ITEMS` reads as blank. Each call builds a new list.
584
594
  */
585
595
  declare function formulaInput(value: Json | undefined, column?: string): FormulaValue;
586
596
 
@@ -666,4 +676,4 @@ declare function explain(source: FormEngine | ExplainInput, blockId: string, opt
666
676
  /** A condition as a plain-English clause: `contact_me is not Yes`. */
667
677
  declare function describeCondition(condition: Condition, def: FormDefinition, fields?: Map<string, FieldBlock>): string;
668
678
 
669
- export { type AnswersOf, Block, CALCULATED_TYPE, COMPUTED_FIELD_TYPES, type CalculatedFormat, type CalculatedProps, type ChoiceFieldOptions, type ChoiceOption, type CoerceHiddenOptions, type CoercedHidden, Condition, ContentBlock, Ending, type ExplainInput, type ExplainOptions, type Explanation, FORMULA_FUNCTIONS, FieldBlock, type FieldOptions, type FieldSpec, type FieldTypeManifest, type FieldValidation, FieldValidator, type Form, FormDefinition, FormEngine, type FormInput, type FormIssue, FormLayout, FormSettings, type FormulaFunction, type FormulaNode, type FormulaParseResult, type FormulaReader, type FormulaRef, type FormulaValue, HIGHLIGHT_NOTE_MESSAGE, HiddenInput, type Highlight, Json, type JumpTrace, type KeyResolver, LogicRule, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, type MediaNote, Operator, PageBreakBlock, type ParseResult, type PathResult, type RuleSpec, type RuleTrace, STRUCTURED_FIELD_TYPES, type TableColumn, calculatedProps, calculatedValue, canonicalJson, choiceOptions, coerceHidden, coerceHiddenValue, computePath, dateLimits, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, getFieldType, isEmptyValue, isIsoDate, isSensitive, listFieldTypes, listLimits, normalizeValue, numberLimits, parseForm, parseFormula, parseTimestamp, ratingDisplay, recall, registerFieldType, renameFormulaKey, ruleVisible, scaleLabels, steps, summarizeValue, tableColumns, tableLimits, when };
679
+ export { type AnswersOf, Block, CALCULATED_TYPE, COMPUTED_FIELD_TYPES, type CalculatedFormat, type CalculatedProps, type ChoiceFieldOptions, type ChoiceOption, type CoerceHiddenOptions, type CoercedHidden, Condition, ContentBlock, Ending, type ExplainInput, type ExplainOptions, type Explanation, FORMULA_FUNCTIONS, FieldBlock, type FieldOptions, type FieldSpec, type FieldTypeManifest, type FieldValidation, FieldValidator, type Form, FormDefinition, FormEngine, type FormInput, type FormIssue, FormLayout, FormSettings, type FormulaFunction, type FormulaNode, type FormulaParseResult, type FormulaReader, type FormulaRef, type FormulaValue, HIGHLIGHT_NOTE_MESSAGE, HiddenInput, type Highlight, Json, type JumpTrace, type KeyResolver, LogicRule, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_FORM_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_SETTLE_ITEMS, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, type MediaNote, Operator, PageBreakBlock, type ParseResult, type PathResult, type RuleSpec, type RuleTrace, STRUCTURED_FIELD_TYPES, type TableColumn, calculatedProps, calculatedValue, canonicalJson, choiceOptions, coerceHidden, coerceHiddenValue, computePath, dateLimits, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, getFieldType, isEmptyValue, isIsoDate, isSensitive, listFieldTypes, listLimits, normalizeValue, numberLimits, parseForm, parseFormula, parseTimestamp, ratingDisplay, recall, registerFieldType, renameFormulaKey, ruleVisible, scaleLabels, steps, summarizeValue, tableColumns, tableLimits, when };
package/dist/index.d.ts CHANGED
@@ -553,6 +553,8 @@ declare const CALCULATED_TYPE = "calculated";
553
553
  */
554
554
  declare const COMPUTED_FIELD_TYPES: readonly ["calculated"];
555
555
  type CalculatedFormat = "number" | "percent" | "text";
556
+ /** Longest the formulas of one form may be, all together (`parseForm` checks it). */
557
+ declare const MAX_FORM_FORMULA_LENGTH = 20000;
556
558
  /** Most decimal places a calculated value may keep. */
557
559
  declare const MAX_CALCULATED_DECIMALS = 10;
558
560
  interface CalculatedProps {
@@ -577,10 +579,18 @@ declare function formatCalculated(value: Json | undefined, field: FieldBlock): s
577
579
  * server can't make every formula over it slow.
578
580
  */
579
581
  declare const MAX_FORMULA_ITEMS = 10000;
582
+ /**
583
+ * Most list items and table rows all of a form's formulas read in one go
584
+ * (each answer and column counted once, in form order). A formula that reads
585
+ * an answer past the limit, or one over `MAX_FORMULA_ITEMS`, has no value
586
+ * (blank, never a partial total), so many big answers can't make working
587
+ * the values out slow either.
588
+ */
589
+ declare const MAX_SETTLE_ITEMS = 50000;
580
590
  /**
581
591
  * The value a formula reads for an answer: numbers and text as they are, a
582
592
  * list's items, one table column's cells. A list or table of more than
583
- * `MAX_FORMULA_ITEMS` reads as blank.
593
+ * `MAX_FORMULA_ITEMS` reads as blank. Each call builds a new list.
584
594
  */
585
595
  declare function formulaInput(value: Json | undefined, column?: string): FormulaValue;
586
596
 
@@ -666,4 +676,4 @@ declare function explain(source: FormEngine | ExplainInput, blockId: string, opt
666
676
  /** A condition as a plain-English clause: `contact_me is not Yes`. */
667
677
  declare function describeCondition(condition: Condition, def: FormDefinition, fields?: Map<string, FieldBlock>): string;
668
678
 
669
- export { type AnswersOf, Block, CALCULATED_TYPE, COMPUTED_FIELD_TYPES, type CalculatedFormat, type CalculatedProps, type ChoiceFieldOptions, type ChoiceOption, type CoerceHiddenOptions, type CoercedHidden, Condition, ContentBlock, Ending, type ExplainInput, type ExplainOptions, type Explanation, FORMULA_FUNCTIONS, FieldBlock, type FieldOptions, type FieldSpec, type FieldTypeManifest, type FieldValidation, FieldValidator, type Form, FormDefinition, FormEngine, type FormInput, type FormIssue, FormLayout, FormSettings, type FormulaFunction, type FormulaNode, type FormulaParseResult, type FormulaReader, type FormulaRef, type FormulaValue, HIGHLIGHT_NOTE_MESSAGE, HiddenInput, type Highlight, Json, type JumpTrace, type KeyResolver, LogicRule, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, type MediaNote, Operator, PageBreakBlock, type ParseResult, type PathResult, type RuleSpec, type RuleTrace, STRUCTURED_FIELD_TYPES, type TableColumn, calculatedProps, calculatedValue, canonicalJson, choiceOptions, coerceHidden, coerceHiddenValue, computePath, dateLimits, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, getFieldType, isEmptyValue, isIsoDate, isSensitive, listFieldTypes, listLimits, normalizeValue, numberLimits, parseForm, parseFormula, parseTimestamp, ratingDisplay, recall, registerFieldType, renameFormulaKey, ruleVisible, scaleLabels, steps, summarizeValue, tableColumns, tableLimits, when };
679
+ export { type AnswersOf, Block, CALCULATED_TYPE, COMPUTED_FIELD_TYPES, type CalculatedFormat, type CalculatedProps, type ChoiceFieldOptions, type ChoiceOption, type CoerceHiddenOptions, type CoercedHidden, Condition, ContentBlock, Ending, type ExplainInput, type ExplainOptions, type Explanation, FORMULA_FUNCTIONS, FieldBlock, type FieldOptions, type FieldSpec, type FieldTypeManifest, type FieldValidation, FieldValidator, type Form, FormDefinition, FormEngine, type FormInput, type FormIssue, FormLayout, FormSettings, type FormulaFunction, type FormulaNode, type FormulaParseResult, type FormulaReader, type FormulaRef, type FormulaValue, HIGHLIGHT_NOTE_MESSAGE, HiddenInput, type Highlight, Json, type JumpTrace, type KeyResolver, LogicRule, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_FORM_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_SETTLE_ITEMS, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, type MediaNote, Operator, PageBreakBlock, type ParseResult, type PathResult, type RuleSpec, type RuleTrace, STRUCTURED_FIELD_TYPES, type TableColumn, calculatedProps, calculatedValue, canonicalJson, choiceOptions, coerceHidden, coerceHiddenValue, computePath, dateLimits, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, getFieldType, isEmptyValue, isIsoDate, isSensitive, listFieldTypes, listLimits, normalizeValue, numberLimits, parseForm, parseFormula, parseTimestamp, ratingDisplay, recall, registerFieldType, renameFormulaKey, ruleVisible, scaleLabels, steps, summarizeValue, tableColumns, tableLimits, when };
package/dist/index.js CHANGED
@@ -62,6 +62,7 @@ function tokenize(source) {
62
62
  i++;
63
63
  while (isDigit(source[i] ?? "")) i++;
64
64
  }
65
+ if (isIdStart(source[i] ?? "")) throw new FormulaError("Write a number in digits only, like 1000000.", at);
65
66
  const v = Number(source.slice(at, i));
66
67
  if (!Number.isFinite(v)) throw new FormulaError("This number is too large.", at);
67
68
  tokens.push({ t: "num", v, at });
@@ -291,6 +292,27 @@ function numbersIn(values, out = []) {
291
292
  }
292
293
  return out;
293
294
  }
295
+ var listTotals = /* @__PURE__ */ new WeakMap();
296
+ var ownLists = /* @__PURE__ */ new WeakSet();
297
+ function ownFormulaList(list) {
298
+ Object.freeze(list);
299
+ ownLists.add(list);
300
+ return list;
301
+ }
302
+ function totalsOf(list) {
303
+ const own2 = ownLists.has(list);
304
+ let t = own2 ? listTotals.get(list) : void 0;
305
+ if (t) return t;
306
+ const nums = numbersIn(list);
307
+ t = { sum: 0, count: nums.length, min: Infinity, max: -Infinity };
308
+ for (const n of nums) {
309
+ t.sum += n;
310
+ if (n < t.min) t.min = n;
311
+ if (n > t.max) t.max = n;
312
+ }
313
+ if (own2) listTotals.set(list, t);
314
+ return t;
315
+ }
294
316
  function compare(op, a, b) {
295
317
  const blank2 = (v) => v === null || Array.isArray(v) || typeof v === "string" && v.trim() === "";
296
318
  if (blank2(a) || blank2(b)) return op === "!=";
@@ -315,7 +337,7 @@ function evaluateFormula(ast, read) {
315
337
  case "text":
316
338
  return node.value;
317
339
  case "ref":
318
- return read(node.column !== void 0 ? { key: node.key, column: node.column } : { key: node.key });
340
+ return read(node);
319
341
  case "unary": {
320
342
  const n = formulaNumber(scalar(run(node.arg)));
321
343
  return n === null ? null : -n;
@@ -323,12 +345,31 @@ function evaluateFormula(ast, read) {
323
345
  case "if":
324
346
  return truthy(run(node.test)) ? run(node.then) : run(node.else);
325
347
  case "call": {
326
- const nums = numbersIn(node.args.map(run));
327
- const total = nums.reduce((a, b) => a + b, 0);
348
+ let total = 0;
349
+ let count = 0;
350
+ let min = Infinity;
351
+ let max = -Infinity;
352
+ for (const arg of node.args) {
353
+ const v = run(arg);
354
+ if (Array.isArray(v)) {
355
+ const t = totalsOf(v);
356
+ total += t.sum;
357
+ count += t.count;
358
+ if (t.min < min) min = t.min;
359
+ if (t.max > max) max = t.max;
360
+ continue;
361
+ }
362
+ const n = formulaNumber(v);
363
+ if (n === null) continue;
364
+ total += n;
365
+ count++;
366
+ if (n < min) min = n;
367
+ if (n > max) max = n;
368
+ }
328
369
  if (node.fn === "sum") return finite(total);
329
- if (!nums.length) return null;
330
- if (node.fn === "avg") return finite(total / nums.length);
331
- return nums.reduce((a, b) => node.fn === "min" ? Math.min(a, b) : Math.max(a, b));
370
+ if (!count) return null;
371
+ if (node.fn === "avg") return finite(total / count);
372
+ return node.fn === "min" ? min : max;
332
373
  }
333
374
  case "binary": {
334
375
  const a = run(node.left);
@@ -356,6 +397,7 @@ function evaluateFormula(ast, read) {
356
397
  // src/calculated.ts
357
398
  var CALCULATED_TYPE = "calculated";
358
399
  var COMPUTED_FIELD_TYPES = [CALCULATED_TYPE];
400
+ var MAX_FORM_FORMULA_LENGTH = 2e4;
359
401
  var MAX_CALCULATED_DECIMALS = 10;
360
402
  function calculatedProps(field2) {
361
403
  const p = field2.props ?? {};
@@ -394,23 +436,45 @@ function formatCalculated(value, field2) {
394
436
  return typeof value === "string" ? value : "";
395
437
  }
396
438
  var MAX_FORMULA_ITEMS = 1e4;
439
+ var MAX_SETTLE_ITEMS = 5e4;
440
+ var extract = (value, column) => column !== void 0 ? value.flatMap((row) => {
441
+ if (!row || typeof row !== "object" || Array.isArray(row)) return [];
442
+ const cell = row[column];
443
+ return typeof cell === "string" || typeof cell === "number" ? [cell] : [];
444
+ }) : value.flatMap((v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean" ? [v] : []);
445
+ var extracted = /* @__PURE__ */ new WeakMap();
446
+ function cachedList(value, column) {
447
+ let byColumn = extracted.get(value);
448
+ if (!byColumn) extracted.set(value, byColumn = /* @__PURE__ */ new Map());
449
+ const key = column ?? "";
450
+ let list = byColumn.get(key);
451
+ if (!list) byColumn.set(key, list = ownFormulaList(extract(value, column)));
452
+ return list;
453
+ }
454
+ function readAnswer(value, column) {
455
+ if (Array.isArray(value)) return cachedList(value, column);
456
+ return column !== void 0 ? null : formulaInput(value);
457
+ }
397
458
  function formulaInput(value, column) {
398
459
  if (value === void 0 || value === null) return null;
399
460
  if (Array.isArray(value) && value.length > MAX_FORMULA_ITEMS) return null;
400
461
  if (column !== void 0) {
401
462
  if (!Array.isArray(value)) return null;
402
- return value.flatMap((row) => {
403
- if (!row || typeof row !== "object" || Array.isArray(row)) return [];
404
- const cell = row[column];
405
- return typeof cell === "string" || typeof cell === "number" ? [cell] : [];
406
- });
407
- }
408
- if (Array.isArray(value)) {
409
- return value.flatMap((v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean" ? [v] : []);
463
+ return extract(value, column);
410
464
  }
465
+ if (Array.isArray(value)) return extract(value, void 0);
411
466
  return typeof value === "object" ? null : value;
412
467
  }
468
+ function refNodes(node, out = []) {
469
+ if (node.kind === "ref") out.push(node);
470
+ else if (node.kind === "unary") refNodes(node.arg, out);
471
+ else if (node.kind === "binary") refNodes(node.left, out), refNodes(node.right, out);
472
+ else if (node.kind === "if") refNodes(node.test, out), refNodes(node.then, out), refNodes(node.else, out);
473
+ else if (node.kind === "call") for (const a of node.args) refNodes(a, out);
474
+ return out;
475
+ }
413
476
  var UNREAD = /* @__PURE__ */ Symbol("unread");
477
+ var OVER = /* @__PURE__ */ Symbol("over");
414
478
  function calculator(definition) {
415
479
  const compiled = [];
416
480
  const idByKey = /* @__PURE__ */ new Map();
@@ -421,14 +485,39 @@ function calculator(definition) {
421
485
  for (const block of definition.blocks) {
422
486
  if (block.kind !== "field" || !isCalculated(block)) continue;
423
487
  const parsed = parseFormula(calculatedProps(block).formula);
424
- const reads = parsed.ok ? parsed.refs.map((r) => idByKey.get(r.key)) : [];
425
- compiled.push({ field: block, ast: parsed.ok ? parsed.ast : null, reads, last: null });
488
+ const reads = [];
489
+ const slots = /* @__PURE__ */ new Map();
490
+ const byKey = /* @__PURE__ */ new Map();
491
+ for (const ref of parsed.ok ? refNodes(parsed.ast) : []) {
492
+ const id = idByKey.get(ref.key);
493
+ const key = `${id ?? ""}\0${ref.column ?? ""}`;
494
+ let slot = byKey.get(key);
495
+ if (slot === void 0) {
496
+ slot = reads.push({ id, column: ref.column, key }) - 1;
497
+ byKey.set(key, slot);
498
+ }
499
+ slots.set(ref, slot);
500
+ }
501
+ compiled.push({ field: block, ast: parsed.ok ? parsed.ast : null, reads, slots, last: null });
426
502
  }
427
503
  const withCalculated = (values, path) => {
428
504
  if (!compiled.length) return values;
429
505
  const visible = new Set(path);
430
506
  let next = values;
431
- const input = (id) => id === void 0 || !visible.has(id) || !Object.prototype.hasOwnProperty.call(next, id) ? UNREAD : next[id];
507
+ let budget = MAX_SETTLE_ITEMS;
508
+ const within = /* @__PURE__ */ new Map();
509
+ const input = ({ id, key }) => {
510
+ if (id === void 0 || !visible.has(id) || !Object.prototype.hasOwnProperty.call(next, id)) return UNREAD;
511
+ const value = next[id];
512
+ if (!Array.isArray(value)) return value;
513
+ let ok = within.get(key);
514
+ if (ok === void 0) {
515
+ ok = value.length <= MAX_FORMULA_ITEMS && value.length <= budget;
516
+ if (ok) budget -= value.length;
517
+ within.set(key, ok);
518
+ }
519
+ return ok ? value : OVER;
520
+ };
432
521
  for (const entry of compiled) {
433
522
  const { field: field2, ast } = entry;
434
523
  const inputs = entry.reads.map(input);
@@ -436,11 +525,18 @@ function calculator(definition) {
436
525
  if (entry.last && entry.last.inputs.length === inputs.length && entry.last.inputs.every((v, i) => v === inputs[i])) {
437
526
  value = entry.last.value;
438
527
  } else {
528
+ const resolved = new Array(inputs.length);
439
529
  const read = (ref) => {
440
- const raw = input(idByKey.get(ref.key));
441
- return raw === UNREAD ? null : formulaInput(raw, ref.column);
530
+ const slot = entry.slots.get(ref);
531
+ if (slot === void 0) return null;
532
+ let v = resolved[slot];
533
+ if (v === void 0) {
534
+ const raw = inputs[slot];
535
+ v = resolved[slot] = raw === UNREAD ? null : readAnswer(raw, entry.reads[slot].column);
536
+ }
537
+ return v;
442
538
  };
443
- value = ast ? calculatedValue(evaluateFormula(ast, read), field2) : void 0;
539
+ value = ast && !inputs.includes(OVER) ? calculatedValue(evaluateFormula(ast, read), field2) : void 0;
444
540
  entry.last = { inputs, value };
445
541
  }
446
542
  const current = Object.prototype.hasOwnProperty.call(next, field2.id) ? next[field2.id] : void 0;
@@ -1421,9 +1517,15 @@ function parseForm(input) {
1421
1517
  issue(`${path}.kind`, "Unknown block kind.");
1422
1518
  }
1423
1519
  });
1520
+ let formulaChars = 0;
1424
1521
  input.blocks.forEach((block, i) => {
1425
1522
  if (!isObject2(block) || block.kind !== "field" || block.type !== CALCULATED_TYPE) return;
1426
1523
  const path = `blocks[${i}].props.formula`;
1524
+ const source = isObject2(block.props) && typeof block.props.formula === "string" ? block.props.formula : "";
1525
+ formulaChars += source.length;
1526
+ if (formulaChars > MAX_FORM_FORMULA_LENGTH && formulaChars - source.length <= MAX_FORM_FORMULA_LENGTH) {
1527
+ issue(path, `The form's formulas together are over ${MAX_FORM_FORMULA_LENGTH} characters; shorten some, or work part out once in an earlier calculated field.`);
1528
+ }
1427
1529
  if (block.required === true) {
1428
1530
  warnings.push({ path: `blocks[${i}].required`, message: "A calculated field is worked out, not answered, so it is never required." });
1429
1531
  }
@@ -2258,6 +2360,6 @@ function describeCondition(condition, def, fields = fieldMap(def)) {
2258
2360
  return `${left} ${op} ${right}`;
2259
2361
  }
2260
2362
 
2261
- export { CALCULATED_TYPE, COMPUTED_FIELD_TYPES, FORMULA_FUNCTIONS, HIGHLIGHT_NOTE_MESSAGE, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, REQUIRED_MESSAGE, STRUCTURED_FIELD_TYPES, calculatedProps, calculatedValue, canonicalJson, choiceOptions, coerceHidden, coerceHiddenValue, computePath, createForm, dateLimits, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, getFieldType, isEmptyValue, isFormEvent, isIsoDate, isJson, isSensitive, listFieldTypes, listLimits, normalizeValue, numberLimits, parseForm, parseFormula, parseTimestamp, ratingDisplay, recall, registerFieldType, renameFormulaKey, replay, ruleVisible, scaleLabels, steps, summarizeValue, tableColumns, tableLimits, validateField, when };
2363
+ export { CALCULATED_TYPE, COMPUTED_FIELD_TYPES, FORMULA_FUNCTIONS, HIGHLIGHT_NOTE_MESSAGE, MAX_CALCULATED_DECIMALS, MAX_FORMULA_ITEMS, MAX_FORMULA_LENGTH, MAX_FORM_FORMULA_LENGTH, MAX_HIDDEN_STRING_LENGTH, MAX_HIGHLIGHT_NOTE_LENGTH, MAX_HIGHLIGHT_QUOTE_LENGTH, MAX_SETTLE_ITEMS, MAX_TABLE_CELL_LENGTH, MAX_TABLE_COLUMNS, MAX_TIMESTAMP_SECONDS, REQUIRED_MESSAGE, STRUCTURED_FIELD_TYPES, calculatedProps, calculatedValue, canonicalJson, choiceOptions, coerceHidden, coerceHiddenValue, computePath, createForm, dateLimits, defineForm, describeCondition, evaluate, evaluateFormula, explain, f, fingerprint, formatCalculated, formatTimestamp, formulaInput, formulaNumber, formulaRefs, getFieldType, isEmptyValue, isFormEvent, isIsoDate, isJson, isSensitive, listFieldTypes, listLimits, normalizeValue, numberLimits, parseForm, parseFormula, parseTimestamp, ratingDisplay, recall, registerFieldType, renameFormulaKey, replay, ruleVisible, scaleLabels, steps, summarizeValue, tableColumns, tableLimits, validateField, when };
2262
2364
  //# sourceMappingURL=index.js.map
2263
2365
  //# sourceMappingURL=index.js.map