@ai-matrx/records-ui 0.113.31 → 0.113.32

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.cjs CHANGED
@@ -148,8 +148,8 @@ __export(src_exports, {
148
148
  KERNEL_REASON: () => KERNEL_REASON,
149
149
  LANE_EMPTY: () => LANE_EMPTY,
150
150
  LANE_TITLE: () => LANE_TITLE,
151
- LAYOUT_FIELD_KIND: () => LAYOUT_FIELD_KIND,
152
- LAYOUT_LABEL: () => LAYOUT_LABEL,
151
+ LAYOUT_FIELD_KIND: () => import_views2.LAYOUT_FIELD_KIND,
152
+ LAYOUT_LABEL: () => import_views2.LAYOUT_LABEL,
153
153
  LEVEL_WORD: () => LEVEL_WORD,
154
154
  LOOK_WORDS: () => LOOK_WORDS,
155
155
  MACHINE_IDENTITY: () => MACHINE_IDENTITY,
@@ -182,8 +182,8 @@ __export(src_exports, {
182
182
  PAGE_BLOCK_KINDS: () => PAGE_BLOCK_KINDS,
183
183
  PAGE_BLOCK_LABEL: () => PAGE_BLOCK_LABEL,
184
184
  PAGE_KIND: () => PAGE_KIND,
185
- PAGE_VIEWS: () => PAGE_VIEWS,
186
- PAGE_VIEW_LABEL: () => PAGE_VIEW_LABEL,
185
+ PAGE_VIEWS: () => import_views2.PAGE_VIEWS,
186
+ PAGE_VIEW_LABEL: () => import_views2.PAGE_VIEW_LABEL,
187
187
  PARITY_LABEL: () => PARITY_LABEL,
188
188
  PARITY_MADE_OF: () => PARITY_MADE_OF,
189
189
  PERSON_KERNEL_TABLE: () => PERSON_KERNEL_TABLE,
@@ -204,8 +204,8 @@ __export(src_exports, {
204
204
  ProvenanceBadge: () => ProvenanceBadge,
205
205
  PublicPicturePicker: () => PublicPicturePicker,
206
206
  PublicViewPage: () => PublicViewPage,
207
- QUESTION_OPS: () => QUESTION_OPS,
208
- QUESTION_SURFACE: () => QUESTION_SURFACE,
207
+ QUESTION_OPS: () => question_exports.QUESTION_OPS,
208
+ QUESTION_SURFACE: () => question_exports.QUESTION_SURFACE,
209
209
  QuestionAnswerView: () => QuestionAnswerView,
210
210
  QuestionPanel: () => QuestionPanel,
211
211
  RECORDS_GRID_ROW_PX: () => RECORDS_GRID_ROW_PX,
@@ -243,8 +243,8 @@ __export(src_exports, {
243
243
  STANDARD_VERBS: () => STANDARD_VERBS,
244
244
  STORE_ANSWERS_THESE: () => STORE_ANSWERS_THESE,
245
245
  STORE_DECIDES_REASON: () => STORE_DECIDES_REASON,
246
- STORE_KEEPS_TIMELINE: () => STORE_KEEPS_TIMELINE,
247
- STORE_KEPT_LAYOUTS: () => STORE_KEPT_LAYOUTS,
246
+ STORE_KEEPS_TIMELINE: () => import_views2.STORE_KEEPS_TIMELINE,
247
+ STORE_KEPT_LAYOUTS: () => import_views2.STORE_KEPT_LAYOUTS,
248
248
  STRIP_FEATURE_ROWS: () => STRIP_FEATURE_ROWS,
249
249
  SUBSCRIPTION_CADENCES: () => SUBSCRIPTION_CADENCES,
250
250
  SUBSCRIPTION_CADENCE_LABEL: () => SUBSCRIPTION_CADENCE_LABEL,
@@ -287,9 +287,9 @@ __export(src_exports, {
287
287
  TimelineView: () => TimelineView,
288
288
  UNREAD_RECORD_LABEL: () => UNREAD_RECORD_LABEL,
289
289
  VIEW_ADDRESS_KEYS: () => VIEW_ADDRESS_KEYS,
290
- VIEW_KEYS: () => VIEW_KEYS,
291
- VIEW_LAYOUTS: () => VIEW_LAYOUTS,
292
- VIEW_NEEDS: () => VIEW_NEEDS,
290
+ VIEW_KEYS: () => import_views.VIEW_KEYS,
291
+ VIEW_LAYOUTS: () => import_views2.VIEW_LAYOUTS,
292
+ VIEW_NEEDS: () => import_views2.VIEW_NEEDS,
293
293
  VIEW_NOT_SAVED_YET: () => VIEW_NOT_SAVED_YET,
294
294
  VISIBILITY_LANES: () => VISIBILITY_LANES,
295
295
  VISIBILITY_LANE_TITLE: () => VISIBILITY_LANE_TITLE,
@@ -313,12 +313,12 @@ __export(src_exports, {
313
313
  addDays: () => addDays,
314
314
  addFields: () => import_core2.addFields,
315
315
  announceTableArchived: () => announceTableArchived,
316
- applyLook: () => applyLook,
316
+ applyLook: () => import_views3.applyLook,
317
317
  archiveConfirmSentence: () => archiveConfirmSentence,
318
318
  archivedRowLine: () => archivedRowLine,
319
319
  asRefusal: () => refusals_exports.asRefusal,
320
320
  askExampleFor: () => askExampleFor,
321
- askQuestion: () => askQuestion,
321
+ askQuestion: () => question_exports.askQuestion,
322
322
  askableFields: () => askableFields,
323
323
  bindingPlaceholdersFor: () => bindingPlaceholdersFor,
324
324
  blockFromSpec: () => blockFromSpec,
@@ -366,7 +366,7 @@ __export(src_exports, {
366
366
  declareTable: () => import_core2.declareTable,
367
367
  declareView: () => declareView,
368
368
  defaultBindingTemplate: () => defaultBindingTemplate,
369
- defaultViewOf: () => defaultViewOf,
369
+ defaultViewOf: () => import_views2.defaultViewOf,
370
370
  descriptionPatch: () => descriptionPatch,
371
371
  drawnBelowOnPage: () => drawnBelowOnPage,
372
372
  drawnSignatureOf: () => drawnSignatureOf,
@@ -384,13 +384,13 @@ __export(src_exports, {
384
384
  endingsFromDocument: () => import_forms8.endingsFromDocument,
385
385
  ensurePlatformTable: () => ensurePlatformTable,
386
386
  entityCellValue: () => entityCellValue,
387
- entityChartQuestion: () => entityChartQuestion,
387
+ entityChartQuestion: () => import_first_page7.entityChartQuestion,
388
388
  entityChoiceColumns: () => entityChoiceColumns,
389
389
  entityNameColumn: () => entityNameColumn,
390
390
  entityReferenceSpec: () => entityReferenceSpec,
391
391
  entityShownColumns: () => entityShownColumns,
392
392
  entityTableColumns: () => entityTableColumns,
393
- entityTableQuery: () => entityTableQuery,
393
+ entityTableQuery: () => import_first_page7.entityTableQuery,
394
394
  entityTitleColumn: () => entityTitleColumn,
395
395
  entityValueText: () => entityValueText,
396
396
  envelopeFor: () => envelopeFor,
@@ -402,7 +402,7 @@ __export(src_exports, {
402
402
  fieldTypeLabel: () => fieldTypeLabel,
403
403
  fieldsForNewColumns: () => fieldsForNewColumns,
404
404
  filterTargets: () => filterTargets,
405
- flatWhere: () => flatWhere,
405
+ flatWhere: () => question_exports.flatWhere,
406
406
  footerOf: () => footerOf,
407
407
  formDeclareArgs: () => import_forms8.formDeclareArgs,
408
408
  formEmbedSnippet: () => import_forms8.formEmbedSnippet,
@@ -413,7 +413,7 @@ __export(src_exports, {
413
413
  formPresentation: () => import_forms8.formPresentation,
414
414
  formRoutes: () => import_forms8.formRoutes,
415
415
  formatForField: () => formatForField,
416
- freeColumnName: () => freeColumnName,
416
+ freeColumnName: () => import_views2.freeColumnName,
417
417
  freshFormName: () => freshFormName,
418
418
  getPersonTimeZone: () => getPersonTimeZone,
419
419
  gridContextKey: () => gridContextKey,
@@ -454,17 +454,17 @@ __export(src_exports, {
454
454
  laneFor: () => laneFor,
455
455
  lastChangeSentence: () => lastChangeSentence,
456
456
  levelNeededFor: () => levelNeededFor,
457
- lookDiffers: () => lookDiffers,
457
+ lookDiffers: () => import_views3.lookDiffers,
458
458
  lookDocument: () => lookDocument,
459
459
  lookFromDocument: () => lookFromDocument,
460
- lookPart: () => lookPart,
460
+ lookPart: () => import_views3.lookPart,
461
461
  looksLikeId: () => looksLikeId,
462
462
  machineIdentityIn: () => machineIdentityIn,
463
463
  mayNotRestoreLine: () => mayNotRestoreLine,
464
- measurableFields: () => measurableFields,
464
+ measurableFields: () => question_exports.measurableFields,
465
465
  memberName: () => memberName,
466
466
  moveRecordValue: () => moveRecordValue,
467
- newQuestion: () => newQuestion,
467
+ newQuestion: () => question_exports.newQuestion,
468
468
  nextInWords: () => nextInWords,
469
469
  nextSummaryAt: () => nextSummaryAt,
470
470
  notAChoiceSentence: () => notAChoiceSentence,
@@ -474,7 +474,7 @@ __export(src_exports, {
474
474
  packOverlaps: () => packOverlaps,
475
475
  pageBlocksOf: () => pageBlocksOf,
476
476
  pagePresentation: () => pagePresentation,
477
- pageViewFromParam: () => pageViewFromParam,
477
+ pageViewFromParam: () => import_views2.pageViewFromParam,
478
478
  parityTypesWithNoExplanation: () => parityTypesWithNoExplanation,
479
479
  parseDelimited: () => parseDelimited,
480
480
  parseGridPresentation: () => parseGridPresentation,
@@ -490,11 +490,11 @@ __export(src_exports, {
490
490
  previewLine: () => previewLine,
491
491
  previewWords: () => previewWords,
492
492
  publiclyAnswerable: () => publiclyAnswerable,
493
- questionArchive: () => questionArchive,
494
- questionFromDefinition: () => questionFromDefinition,
493
+ questionArchive: () => question_exports.questionArchive,
494
+ questionFromDefinition: () => question_exports.questionFromDefinition,
495
495
  questionFromWords: () => questionFromWords,
496
- questionSave: () => questionSave,
497
- questionsOf: () => questionsOf,
496
+ questionSave: () => question_exports.questionSave,
497
+ questionsOf: () => question_exports.questionsOf,
498
498
  railFromParam: () => railFromParam,
499
499
  readLooks: () => readLooks,
500
500
  readTableShape: () => readTableShape,
@@ -524,7 +524,7 @@ __export(src_exports, {
524
524
  sameRecordLikely: () => sameRecordLikely,
525
525
  sameViewAddress: () => sameViewAddress,
526
526
  saveTableDescription: () => saveTableDescription,
527
- saveToViewPlan: () => saveToViewPlan,
527
+ saveToViewPlan: () => import_views3.saveToViewPlan,
528
528
  saveViewPatch: () => saveViewPatch,
529
529
  scalarText: () => scalarText,
530
530
  seedIsSatisfied: () => seedIsSatisfied,
@@ -545,7 +545,7 @@ __export(src_exports, {
545
545
  starterPageBlocks: () => starterPageBlocks,
546
546
  stepFromAgent: () => stepFromAgent,
547
547
  storeDecidesRights: () => storeDecidesRights,
548
- storeKeepsLayout: () => storeKeepsLayout,
548
+ storeKeepsLayout: () => import_views2.storeKeepsLayout,
549
549
  storePublishesKind: () => storePublishesKind,
550
550
  styleFromDecorations: () => styleFromDecorations,
551
551
  submissionStamp: () => import_forms8.submissionStamp,
@@ -563,8 +563,8 @@ __export(src_exports, {
563
563
  toStripAndRows: () => toStripAndRows,
564
564
  tokenFor: () => import_core2.tokenFor,
565
565
  unknownRailLine: () => unknownRailLine,
566
- unknownViewLine: () => unknownViewLine,
567
- unreadableKeys: () => unreadableKeys,
566
+ unknownViewLine: () => import_views2.unknownViewLine,
567
+ unreadableKeys: () => question_exports.unreadableKeys,
568
568
  useAddressDrill: () => useAddressDrill,
569
569
  useCanShare: () => useCanShare,
570
570
  useChoiceNudge: () => useChoiceNudge,
@@ -599,11 +599,11 @@ __export(src_exports, {
599
599
  viewAddressToParams: () => viewAddressToParams,
600
600
  viewDocument: () => viewDocument,
601
601
  viewFromRow: () => viewFromRow,
602
- viewKeysFor: () => viewKeysFor,
602
+ viewKeysFor: () => import_views.viewKeysFor,
603
603
  viewNeedFor: () => viewNeedFor,
604
604
  viewPatchDocument: () => viewPatchDocument,
605
605
  viewSettings: () => viewSettings,
606
- viewSettingsFor: () => viewSettingsFor,
606
+ viewSettingsFor: () => import_views.viewSettingsFor,
607
607
  viewSettingsPatch: () => viewSettingsPatch,
608
608
  visibilityLaneFor: () => visibilityLaneFor,
609
609
  welcomeFromDocument: () => import_forms8.welcomeFromDocument,
@@ -618,7 +618,7 @@ __export(src_exports, {
618
618
  withheldNoticeOf: () => withheldNoticeOf,
619
619
  withheldSentence: () => withheldSentence,
620
620
  withoutAddition: () => withoutAddition,
621
- wordsList: () => wordsList
621
+ wordsList: () => import_views2.wordsList
622
622
  });
623
623
  module.exports = __toCommonJS(src_exports);
624
624
 
@@ -690,12 +690,12 @@ function whatYouMayDo(level, known = true) {
690
690
  var NOT_ANSWERED_YET = whatYouMayDo(null, false);
691
691
  var KERNEL_REASON = "This is one of the tables the platform ships, so its columns are not changed from a screen. Make your own table to change columns.";
692
692
  function whatYouMayDoWithTable(table, level, known) {
693
- const base = whatYouMayDo(level, known);
694
- if (!table?.is_kernel) return base;
693
+ const base2 = whatYouMayDo(level, known);
694
+ if (!table?.is_kernel) return base2;
695
695
  return {
696
- ...base,
696
+ ...base2,
697
697
  structure: false,
698
- why: (what) => what === "structure" ? KERNEL_REASON : base.why(what)
698
+ why: (what) => what === "structure" ? KERNEL_REASON : base2.why(what)
699
699
  };
700
700
  }
701
701
 
@@ -824,8 +824,8 @@ var UNREAD_RECORD_LABEL = "Couldn't load this name";
824
824
  function realPlural(table) {
825
825
  const plural4 = (table.label_plural ?? "").trim();
826
826
  if (plural4 === "") return null;
827
- for (const base of [table.name, table.label_singular]) {
828
- const b = (base ?? "").trim();
827
+ for (const base2 of [table.name, table.label_singular]) {
828
+ const b = (base2 ?? "").trim();
829
829
  if (b !== "" && plural4 === `${b}s`) return null;
830
830
  }
831
831
  return plural4;
@@ -1125,7 +1125,7 @@ async function rowActionFromAgent(input, fields, check) {
1125
1125
  const name = input["name"];
1126
1126
  if (typeof name !== "string" || !name.trim()) throw new Error(`editing_row_action.name must be the button's label \u2014 received ${describeValue(name)}.`);
1127
1127
  const kind = input["kind"];
1128
- const base = {
1128
+ const base2 = {
1129
1129
  name: name.trim(),
1130
1130
  kind: kind === "agent" ? "agent" : "update",
1131
1131
  confirm: input["confirm"] === true,
@@ -1135,14 +1135,14 @@ async function rowActionFromAgent(input, fields, check) {
1135
1135
  if (kind === "agent") {
1136
1136
  const prompt = input["prompt"];
1137
1137
  if (typeof prompt !== "string" || !prompt.trim()) throw new Error(`An agent action needs \`prompt\`: what the agent does with the row \u2014 received ${describeValue(prompt)}.`);
1138
- return { ...base, prompt: prompt.trim() };
1138
+ return { ...base2, prompt: prompt.trim() };
1139
1139
  }
1140
1140
  if (kind !== "update") throw new Error(`editing_row_action.kind must be "update" or "agent" \u2014 received ${describeValue(kind)}.`);
1141
1141
  const steps = input["steps"];
1142
1142
  if (!Array.isArray(steps) || steps.length === 0) throw new Error(`An update action needs \`steps\`: a non-empty array \u2014 received ${describeValue(steps)}.`);
1143
1143
  const made = [];
1144
1144
  for (let i = 0; i < steps.length; i += 1) made.push(await stepFromAgent(steps[i], i, fields, check));
1145
- return { ...base, steps: made };
1145
+ return { ...base2, steps: made };
1146
1146
  }
1147
1147
  function actionForAgent(action3, fields) {
1148
1148
  const key = (id) => fields.find((f) => f.id === id)?.key ?? id;
@@ -1549,6 +1549,8 @@ function fieldTypeLabel(field2) {
1549
1549
  }
1550
1550
 
1551
1551
  // src/gridPage.ts
1552
+ var import_first_page = require("@ai-matrx/records/first-page");
1553
+ var import_first_page2 = require("@ai-matrx/records/first-page");
1552
1554
  function sortRefusal(f) {
1553
1555
  if (!computedOnRead(f)) return null;
1554
1556
  return `${fieldName(f)} is worked out each time it is read, so the store keeps no value to sort the whole table by. Sort by a column it is worked out from.`;
@@ -1561,23 +1563,6 @@ function computedOnRead(f) {
1561
1563
  const kind = String(editorKindFor(f));
1562
1564
  return (f.type === "formula" || kind === "formula" || kind === "lookup" || kind === "rollup") && String(f.compute_on ?? "read") === "read";
1563
1565
  }
1564
- function holdsNumbers(field2) {
1565
- const kind = String(editorKindFor(field2));
1566
- if (kind === "number" || kind === "currency" || kind === "percent") return true;
1567
- return String((field2.config ?? {})["system"] ?? "") === "autonumber";
1568
- }
1569
- function sortAsFor(field2) {
1570
- const kind = String(editorKindFor(field2));
1571
- if (holdsNumbers(field2)) return "number";
1572
- if (kind === "datetime") return "date";
1573
- return "text";
1574
- }
1575
- function pageSortFor(fields, sort) {
1576
- if (!sort) return [];
1577
- const field2 = fields.find((f) => f.key === sort.id);
1578
- if (!field2) return [];
1579
- return [{ field: field2.key, direction: sort.direction === "desc" ? "desc" : "asc", as: sortAsFor(field2) }];
1580
- }
1581
1566
  function containsPattern(text) {
1582
1567
  return `(?i)${text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`;
1583
1568
  }
@@ -1621,7 +1606,7 @@ function clauseFor(f, value, now = /* @__PURE__ */ new Date()) {
1621
1606
  if (!value.negated) return { rule: blank ? op("or", not(present), anyDay) : anyDay };
1622
1607
  return { rule: blank ? op("and", present, not(anyDay)) : not(anyDay) };
1623
1608
  }
1624
- const asStored = (w) => holdsNumbers(f) || kind === "rating" ? Number.isFinite(Number(w)) ? Number(w) : w : kind === "checkbox" && (w === "true" || w === "false") ? w === "true" : w;
1609
+ const asStored = (w) => (0, import_first_page.holdsNumbers)(f) || kind === "rating" ? Number.isFinite(Number(w)) ? Number(w) : w : kind === "checkbox" && (w === "true" || w === "false") ? w === "true" : w;
1625
1610
  const stored = words2.map(asStored);
1626
1611
  const anyWord = stored.length === 0 ? null : stored.length === 1 ? op("eq", field(f), constant(stored[0])) : op("or", ...stored.map((w) => op("eq", field(f), constant(w))));
1627
1612
  if (!value.negated) {
@@ -1676,12 +1661,12 @@ function dayWindow(day, holdsDays) {
1676
1661
  const ymd = (t) => `${t.getUTCFullYear()}-${String(t.getUTCMonth() + 1).padStart(2, "0")}-${String(t.getUTCDate()).padStart(2, "0")}`;
1677
1662
  return { from: ymd(new Date(Date.UTC(y, (m ?? 1) - 1, d ?? 1))), to: ymd(new Date(Date.UTC(y, (m ?? 1) - 1, (d ?? 1) + 1))) };
1678
1663
  }
1679
- function storeQuestion(fields, base, columnFilters, now = /* @__PURE__ */ new Date()) {
1664
+ function storeQuestion(fields, base2, columnFilters, now = /* @__PURE__ */ new Date()) {
1680
1665
  const refused = [];
1681
1666
  const flat = {};
1682
1667
  const rules = [];
1683
- if (base && (0, import_records6.isRuleFilter)(base)) rules.push(base);
1684
- else if (base) Object.assign(flat, base);
1668
+ if (base2 && (0, import_records6.isRuleFilter)(base2)) rules.push(base2);
1669
+ else if (base2) Object.assign(flat, base2);
1685
1670
  for (const [key, value] of Object.entries(columnFilters)) {
1686
1671
  if (!value) continue;
1687
1672
  const f = fields.find((candidate) => candidate.key === key);
@@ -2221,32 +2206,7 @@ function useLabelWait(field2) {
2221
2206
  }
2222
2207
 
2223
2208
  // src/gridLook.ts
2224
- function defaultSortOf(table, fields) {
2225
- const raw = table?.default_sort ?? null;
2226
- const first = Array.isArray(raw) ? raw[0] : raw;
2227
- let name = null;
2228
- let direction = "asc";
2229
- if (typeof first === "string") {
2230
- const trimmed = first.trim();
2231
- if (trimmed === "") return null;
2232
- if (trimmed.startsWith("-")) {
2233
- name = trimmed.slice(1).trim();
2234
- direction = "desc";
2235
- } else {
2236
- const [head, tail] = trimmed.split(/\s+/);
2237
- name = head ?? null;
2238
- if (tail && tail.toLowerCase() === "desc") direction = "desc";
2239
- }
2240
- } else if (first && typeof first === "object") {
2241
- const entry = first;
2242
- const named = entry["field"] ?? entry["key"] ?? entry["id"];
2243
- name = typeof named === "string" ? named : null;
2244
- if (String(entry["direction"] ?? "").toLowerCase() === "desc") direction = "desc";
2245
- }
2246
- if (!name) return null;
2247
- const field2 = fields.find((f) => f.key === name) ?? fields.find((f) => f.id === name);
2248
- return field2 ? { id: field2.key, direction } : null;
2249
- }
2209
+ var import_first_page3 = require("@ai-matrx/records/first-page");
2250
2210
  var ROW_HEIGHT_PX = {
2251
2211
  compact: 28,
2252
2212
  normal: void 0,
@@ -2604,7 +2564,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
2604
2564
  const [to, setTo] = (0, import_react10.useState)(null);
2605
2565
  const [preview, setPreview] = (0, import_react10.useState)(null);
2606
2566
  const [asking, setAsking] = (0, import_react10.useState)(false);
2607
- const [refusal4, setRefusal] = (0, import_react10.useState)(null);
2567
+ const [refusal3, setRefusal] = (0, import_react10.useState)(null);
2608
2568
  const [busy, setBusy] = (0, import_react10.useState)(false);
2609
2569
  const [said2, setSaid] = (0, import_react10.useState)(null);
2610
2570
  const name = fieldName(field2);
@@ -2702,7 +2662,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
2702
2662
  preview.keptAside > 0 ? `; ${preview.keptAside} ${preview.keptAside === 1 ? "value does" : "values do"} not fit and will be kept aside with ${preview.keptAside === 1 ? "its record" : "their records"}, with the reason \u2014 nothing is deleted` + (preview.examples.length > 0 ? ` (for example ${preview.examples.map((e) => `\u201C${e}\u201D`).join(", ")})` : "") : "",
2703
2663
  preview.partial ? ". Counted over the first 1,000 different values." : "."
2704
2664
  ] }) : null,
2705
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RefusalNotice, { error: refusal4 }) : null,
2665
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RefusalNotice, { error: refusal3 }) : null,
2706
2666
  said2 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "status", className: "text-[11px] text-muted-foreground", "data-records-retype-done": "", children: said2 }) : null
2707
2667
  ] });
2708
2668
  }
@@ -3476,10 +3436,10 @@ function TableDetails({
3476
3436
  if (slots.details.current === slot) slots.details.current = null;
3477
3437
  };
3478
3438
  }, [slots]);
3479
- const write = async (patch, base) => {
3439
+ const write = async (patch, base2) => {
3480
3440
  setBusy(true);
3481
3441
  setRefused(null);
3482
- const written = await (0, writeOnTheWinningVersion_exports.updateOnTheWinningVersion)(client, tableId, patch, await (0, recordVersions_exports.readTableVersionNow)(client, tableId), base);
3442
+ const written = await (0, writeOnTheWinningVersion_exports.updateOnTheWinningVersion)(client, tableId, patch, await (0, recordVersions_exports.readTableVersionNow)(client, tableId), base2);
3483
3443
  setBusy(false);
3484
3444
  if (!written.ok) {
3485
3445
  setRefused(refusalSentence(written.error));
@@ -4168,7 +4128,7 @@ function PersonPicker({ field: field2, value, onChange, disabled, id, className,
4168
4128
  // src/gridEditing.tsx
4169
4129
  var import_react64 = require("react");
4170
4130
  var import_records31 = require("@ai-matrx/records");
4171
- var import_core8 = require("@ai-matrx/records/core");
4131
+ var import_core7 = require("@ai-matrx/records/core");
4172
4132
  var import_react65 = require("@ai-matrx/records/react");
4173
4133
  var import_design_system37 = require("@ai-matrx/design-system");
4174
4134
 
@@ -4558,13 +4518,13 @@ function styleFromDecorations(decorations, fields) {
4558
4518
  return style;
4559
4519
  }
4560
4520
  function resolveTableStyle(decorations, fields, viewStyle) {
4561
- const base = styleFromDecorations(decorations, fields);
4562
- if (!viewStyle) return base;
4563
- const colorBy = viewStyle.colorBy ?? base.colorBy;
4564
- const rules = viewStyle.rules ?? base.rules;
4565
- const rows = viewStyle.rows ?? base.rows;
4566
- const columns = viewStyle.columns ?? base.columns;
4567
- const cells = viewStyle.cells ?? base.cells;
4521
+ const base2 = styleFromDecorations(decorations, fields);
4522
+ if (!viewStyle) return base2;
4523
+ const colorBy = viewStyle.colorBy ?? base2.colorBy;
4524
+ const rules = viewStyle.rules ?? base2.rules;
4525
+ const rows = viewStyle.rows ?? base2.rows;
4526
+ const columns = viewStyle.columns ?? base2.columns;
4527
+ const cells = viewStyle.cells ?? base2.cells;
4568
4528
  return {
4569
4529
  version: 1,
4570
4530
  ...colorBy !== void 0 ? { colorBy } : {},
@@ -4956,7 +4916,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
4956
4916
  const client = (0, import_react24.useOptionalRecordsClient)();
4957
4917
  const [rows, setRows] = (0, import_react23.useState)(null);
4958
4918
  const [words2, setWords] = (0, import_react23.useState)({});
4959
- const [refusal4, setRefusal] = (0, import_react23.useState)(null);
4919
+ const [refusal3, setRefusal] = (0, import_react23.useState)(null);
4960
4920
  const [search, setSearch] = (0, import_react23.useState)("");
4961
4921
  const [open, setOpenState] = (0, import_react23.useState)(autoOpen === true);
4962
4922
  const onCloseRef = (0, import_react23.useRef)(onClose);
@@ -5136,8 +5096,8 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
5136
5096
  })),
5137
5097
  onPick: toggle,
5138
5098
  notice: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5139
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RefusalLine, { error: refusal4, className: "p-2" }) : null,
5140
- !rows && !refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading\u2026" }) : null,
5099
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RefusalLine, { error: refusal3, className: "p-2" }) : null,
5100
+ !rows && !refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading\u2026" }) : null,
5141
5101
  full ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "p-2 text-xs text-muted-foreground", children: [
5142
5102
  fieldName(field2),
5143
5103
  " can point at ",
@@ -5236,7 +5196,7 @@ function columnNameTakenLine(taken, noun = "column") {
5236
5196
  // src/FieldEditor.tsx
5237
5197
  var import_react50 = require("react");
5238
5198
  var import_react51 = require("@ai-matrx/records/react");
5239
- var import_core7 = require("@ai-matrx/records/core");
5199
+ var import_core6 = require("@ai-matrx/records/core");
5240
5200
  var import_design_system32 = require("@ai-matrx/design-system");
5241
5201
 
5242
5202
  // src/FormulaTextEditor.tsx
@@ -5550,500 +5510,22 @@ var import_design_system24 = require("@ai-matrx/design-system");
5550
5510
  var import_react29 = require("react");
5551
5511
 
5552
5512
  // src/firstPage.ts
5553
- var import_core4 = require("@ai-matrx/records/core");
5554
- var import_uuid3 = require("@ai-matrx/kit/uuid");
5555
-
5556
- // src/groupReads.ts
5557
- function groupedPageSort(fields, groupKey, sort) {
5558
- if (!groupKey) return sort;
5559
- const field2 = fields.find((f) => f.key === groupKey);
5560
- if (!field2) return sort;
5561
- return [{ field: groupKey, direction: "asc", as: sortAsFor(field2) }, ...sort.filter((s) => s.field !== groupKey)];
5562
- }
5563
- function chosenEntries(chosen) {
5564
- return JSON.parse(JSON.stringify(Object.entries(chosen).sort())).filter(([, op2]) => op2 in MEASURE_LABEL);
5565
- }
5566
- function groupFactMeasures(chosen) {
5567
- return [{ op: "count" }, ...chosenEntries(chosen).filter(([, op2]) => op2 !== "count").map(([key, op2]) => ({ op: op2, key }))];
5568
- }
5569
- var REVERSE_CELL_CHIPS = 3;
5513
+ var import_first_page4 = require("@ai-matrx/records/first-page");
5570
5514
 
5571
5515
  // src/viewKeys.ts
5572
- var STORE_KEEPS_TIMELINE = true;
5573
- var ALL = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
5574
- var HIDES = ["grid", "gallery", "kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
5575
- var GRIDS = ["grid"];
5576
- var VIEW_KEYS = [
5577
- { path: "layout", shape: "kind", layouts: ALL, writer: "caller" },
5578
- { path: "filters", shape: "filter", layouts: ALL, writer: "caller" },
5579
- { path: "where", shape: "rule", layouts: ALL, writer: "caller" },
5580
- { path: "group_field", shape: "field", layouts: ["kanban", ...STORE_KEEPS_TIMELINE ? ["timeline"] : []], writer: "caller" },
5581
- { path: "swimlane_field", shape: "field:lane", layouts: ["kanban"], writer: "caller" },
5582
- { path: "collapsed_columns", shape: "values", layouts: ["kanban"], writer: "caller" },
5583
- { path: "measure", shape: "field:number", layouts: ["kanban"], writer: "caller" },
5584
- { path: "date_field", shape: "field:date", layouts: ["calendar"], writer: "caller" },
5585
- ...STORE_KEEPS_TIMELINE ? [
5586
- { path: "start_field", shape: "field:date", layouts: ["timeline"], writer: "caller" },
5587
- { path: "end_field", shape: "field:date", layouts: ["calendar", "timeline"], writer: "caller" }
5588
- ] : [],
5589
- { path: "image_field", shape: "field", layouts: ["gallery"], writer: "caller" },
5590
- { path: "sorts", shape: "sorts", layouts: ALL, writer: "caller" },
5591
- { path: "rule_id", shape: "uuid", layouts: ALL, writer: "caller" },
5592
- { path: "is_default", shape: "boolean", layouts: ALL, writer: "caller" },
5593
- { path: "presentation", shape: "presentation", layouts: ALL, writer: "caller" },
5594
- { path: "presentation.style", shape: "style", layouts: ALL, writer: "caller" },
5595
- { path: "presentation.formats", shape: "object", layouts: GRIDS, writer: "caller" },
5596
- { path: "presentation.frozen", shape: "fields", layouts: GRIDS, writer: "caller" },
5597
- { path: "presentation.grouping", shape: "grouping", layouts: ["grid", "gallery", "list"], writer: "caller" },
5598
- { path: "presentation.widths", shape: "widths", layouts: GRIDS, writer: "caller" },
5599
- { path: "presentation.rowHeight", shape: "row_height", layouts: GRIDS, writer: "caller" },
5600
- { path: "presentation.hiddenFields", shape: "fields", layouts: HIDES, writer: "caller" },
5601
- { path: "presentation.cardHidden", shape: "fields", layouts: ["kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list", "gallery"], writer: "caller" },
5602
- { path: "presentation.columnOrder", shape: "fields", layouts: GRIDS, writer: "caller" },
5603
- { path: "presentation.gallerySize", shape: "gallery_size", layouts: ["gallery"], writer: "caller" },
5604
- { path: "presentation.wrap", shape: "boolean", layouts: GRIDS, writer: "caller" },
5605
- { path: "presentation.wrapColumns", shape: "fields", layouts: GRIDS, writer: "caller" },
5606
- { path: "presentation.fit", shape: "fit", layouts: GRIDS, writer: "caller" },
5607
- { path: "presentation.freezeFirst", shape: "boolean", layouts: GRIDS, writer: "caller" },
5608
- { path: "presentation.footer", shape: "footer", layouts: GRIDS, writer: "caller" },
5609
- { path: "presentation.summaries", shape: "summaries", layouts: GRIDS, writer: "caller" },
5610
- { path: "grid", shape: "grid", layouts: GRIDS, writer: "caller" },
5611
- { path: "hidden_fields", shape: "input", layouts: HIDES, writer: "input" },
5612
- { path: "table_id", shape: "server", layouts: ALL, writer: "server" },
5613
- { path: "order", shape: "server", layouts: GRIDS, writer: "server" },
5614
- { path: "moved_from", shape: "server", layouts: ALL, writer: "server" }
5615
- ];
5616
- var STORE_KEPT_LAYOUTS = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
5617
- function storeKeepsLayout(layout) {
5618
- return STORE_KEPT_LAYOUTS.includes(layout);
5619
- }
5620
- function viewKeysFor(layout) {
5621
- return VIEW_KEYS.filter((k) => k.layouts.includes(layout)).map((k) => k.path);
5622
- }
5623
- var KINDS = STORE_KEPT_LAYOUTS;
5624
- function viewSettings(definition, rowFilters) {
5625
- const data = definition ?? {};
5626
- const text = (key) => {
5627
- const v = data[key];
5628
- return typeof v === "string" && v !== "" ? v : null;
5629
- };
5630
- const layout = String(data["layout"] ?? "grid");
5631
- const flat = rowFilters ?? (isObject2(data["filters"]) ? data["filters"] : null);
5632
- const moved = data["moved_from"];
5633
- return {
5634
- layout: KINDS.includes(layout) ? layout : "grid",
5635
- filters: flat && Object.keys(flat).length > 0 ? flat : null,
5636
- where: isRule(data["where"]) ? data["where"] : null,
5637
- groupField: text("group_field"),
5638
- swimlaneField: text("swimlane_field"),
5639
- collapsedColumns: Array.isArray(data["collapsed_columns"]) ? data["collapsed_columns"].filter((v) => ["string", "number", "boolean"].includes(typeof v)).map(String) : [],
5640
- measure: text("measure"),
5641
- dateField: text("date_field"),
5642
- startField: text("start_field"),
5643
- endField: text("end_field"),
5644
- imageField: text("image_field"),
5645
- sorts: parseSorts(data["sorts"]),
5646
- ruleId: text("rule_id"),
5647
- isDefault: data["is_default"] === true || data["is_default"] === "true",
5648
- presentation: parseGridPresentation(data["presentation"]),
5649
- movedFrom: isObject2(moved) ? moved : null
5650
- };
5651
- }
5652
- function viewSettingsFor(settings, layout) {
5653
- const reads = new Set(viewKeysFor(layout));
5654
- const out = { layout: settings.layout };
5655
- const take = (key, path) => {
5656
- if (reads.has(path)) out[key] = settings[key];
5657
- };
5658
- take("filters", "filters");
5659
- take("where", "where");
5660
- take("groupField", "group_field");
5661
- take("swimlaneField", "swimlane_field");
5662
- take("collapsedColumns", "collapsed_columns");
5663
- take("measure", "measure");
5664
- take("dateField", "date_field");
5665
- take("startField", "start_field");
5666
- take("endField", "end_field");
5667
- take("imageField", "image_field");
5668
- take("sorts", "sorts");
5669
- take("ruleId", "rule_id");
5670
- take("isDefault", "is_default");
5671
- const p = settings.presentation;
5672
- const look = {};
5673
- for (const [key, value] of Object.entries(p)) {
5674
- if (reads.has(`presentation.${key}`)) look[key] = value;
5675
- }
5676
- out.presentation = look;
5677
- return out;
5678
- }
5679
- function viewSettingsPatch(patch) {
5680
- const out = {};
5681
- const field2 = (key, path) => {
5682
- if (patch[key] !== void 0) out[path] = patch[key] || null;
5683
- };
5684
- if (patch.layout !== void 0 && storeKeepsLayout(patch.layout)) out["layout"] = patch.layout;
5685
- field2("groupField", "group_field");
5686
- field2("swimlaneField", "swimlane_field");
5687
- field2("measure", "measure");
5688
- field2("dateField", "date_field");
5689
- if (STORE_KEEPS_TIMELINE) {
5690
- field2("startField", "start_field");
5691
- field2("endField", "end_field");
5692
- }
5693
- field2("imageField", "image_field");
5694
- field2("ruleId", "rule_id");
5695
- if (patch.collapsedColumns !== void 0) out["collapsed_columns"] = patch.collapsedColumns ?? [];
5696
- if (patch.sorts !== void 0) out["sorts"] = patch.sorts ?? [];
5697
- if (patch.where !== void 0) out["where"] = patch.where ?? null;
5698
- if (patch.isDefault !== void 0) out["is_default"] = patch.isDefault === true;
5699
- if (patch.presentation !== void 0) {
5700
- out["presentation"] = !patch.presentation || presentationIsEmpty(patch.presentation) ? null : JSON.parse(presentationDocument(patch.presentation));
5701
- }
5702
- return out;
5703
- }
5704
- function isObject2(raw) {
5705
- return Boolean(raw) && typeof raw === "object" && !Array.isArray(raw);
5706
- }
5707
- function isRule(raw) {
5708
- if (!isObject2(raw)) return false;
5709
- const node = raw;
5710
- return typeof node.op === "string" && Array.isArray(node.args);
5711
- }
5712
- function parseSorts(raw) {
5713
- let list = raw;
5714
- if (typeof raw === "string") {
5715
- try {
5716
- list = raw.trim() === "" ? [] : JSON.parse(raw);
5717
- } catch {
5718
- return [];
5719
- }
5720
- }
5721
- if (!Array.isArray(list)) return [];
5722
- return list.filter((s) => isObject2(s) && typeof s.field === "string").map((s) => ({ field: s.field, direction: s.direction === "desc" ? "desc" : "asc" }));
5723
- }
5724
-
5725
- // src/views.ts
5726
- var VIEW_LAYOUTS = ["grid", "kanban", "calendar", "gallery", "timeline", "list"];
5727
- var LAYOUT_LABEL = {
5728
- grid: "Grid",
5729
- kanban: "Kanban",
5730
- calendar: "Calendar",
5731
- gallery: "Gallery",
5732
- timeline: "Timeline",
5733
- list: "List"
5734
- };
5735
- function wordsList(words2) {
5736
- const clean = words2.map((w) => w.trim()).filter((w) => w !== "");
5737
- if (clean.length <= 1) return clean.join("");
5738
- return `${clean.slice(0, -1).join(", ")} and ${clean[clean.length - 1]}`;
5739
- }
5740
- var VIEW_NEEDS = {
5741
- grid: null,
5742
- // A list reads nothing a table can lack: rows, titled, grouped only when the person chooses.
5743
- list: null,
5744
- kanban: {
5745
- kind: "choice",
5746
- viewKey: "groupField",
5747
- blocking: true,
5748
- starter: { label: "Status", type: "select", options: ["To do", "In progress", "Done"] },
5749
- pick: "Pick the choice column the board's columns come from.",
5750
- missing: "This table has no choice column to make the board's columns from.",
5751
- does: (label) => `Make it work adds a ${label} column with the choices below and groups the board by it.`,
5752
- ask: (label, options) => `Add a choice column called ${label} to this table${options.length > 0 ? ` with the choices ${wordsList(options)}` : ""}, then group the Kanban board by it.`
5753
- },
5754
- calendar: {
5755
- kind: "date",
5756
- viewKey: "dateField",
5757
- blocking: true,
5758
- starter: { label: "Date", type: "datetime" },
5759
- pick: "Pick the date column the calendar places records by.",
5760
- missing: "This table has no date column to place records on.",
5761
- does: (label) => `Make it work adds a ${label} column and lays the calendar out by it.`,
5762
- ask: (label) => `Add a date column called ${label} to this table, then lay the Calendar out by it.`
5763
- },
5764
- gallery: {
5765
- kind: "file",
5766
- viewKey: "imageField",
5767
- blocking: false,
5768
- starter: { label: "Photo", type: "attachment" },
5769
- pick: "Pick the file column each card shows as its picture.",
5770
- missing: "The cards have no picture because this table has no file column.",
5771
- does: (label) => `Make it work adds a ${label} column and shows it on each card.`,
5772
- ask: (label) => `Add a file column called ${label} to this table, then show it as the picture on each Gallery card.`
5773
- },
5774
- timeline: {
5775
- kind: "date",
5776
- viewKey: "dateField",
5777
- blocking: true,
5778
- starter: { label: "Start", type: "datetime" },
5779
- pick: "Pick the date column each bar starts on.",
5780
- missing: "This table has no date column to place records on.",
5781
- does: (label) => `Make it work adds a ${label} column and lays the timeline out by it.`,
5782
- ask: (label) => `Add a date column called ${label} to this table, then lay the Timeline out by it.`
5783
- }
5784
- };
5785
- function freeColumnName(wanted, taken) {
5786
- const held = new Set(taken.map((t) => t.trim().toLowerCase()));
5787
- const base = wanted.trim() === "" ? "Column" : wanted.trim();
5788
- if (!held.has(base.toLowerCase())) return base;
5789
- for (let n = 2; n < 100; n += 1) {
5790
- const next = `${base} ${n}`;
5791
- if (!held.has(next.toLowerCase())) return next;
5792
- }
5793
- return base;
5794
- }
5795
- function viewOrderOf(definition) {
5796
- const raw = definition?.["order"];
5797
- return raw === "manual" ? "manual" : raw === "sorted" ? "sorted" : null;
5798
- }
5799
- function defaultViewOf(views) {
5800
- return views.find((v) => v.isDefault);
5801
- }
5802
- var LAYOUT_FIELD_KIND = {
5803
- grid: null,
5804
- kanban: "choice",
5805
- calendar: "date",
5806
- gallery: "file",
5807
- timeline: "date",
5808
- list: null
5809
- };
5810
- var PAGE_VIEWS = [...VIEW_LAYOUTS, "dashboards", "archived"];
5811
- var PAGE_VIEW_LABEL = {
5812
- ...LAYOUT_LABEL,
5813
- dashboards: "Dashboards",
5814
- archived: "Archived"
5815
- };
5816
- var PAGE_VIEW_SPELLINGS = {
5817
- grid: "grid",
5818
- table: "grid",
5819
- rows: "grid",
5820
- list: "list",
5821
- kanban: "kanban",
5822
- board: "kanban",
5823
- pipeline: "kanban",
5824
- calendar: "calendar",
5825
- month: "calendar",
5826
- schedule: "calendar",
5827
- gallery: "gallery",
5828
- cards: "gallery",
5829
- timeline: "timeline",
5830
- gantt: "timeline",
5831
- dashboards: "dashboards",
5832
- dashboard: "dashboards",
5833
- charts: "dashboards",
5834
- archived: "archived",
5835
- archive: "archived",
5836
- // The grid's row action says "Delete" and the store soft-deletes, so the word
5837
- // a person types is as likely to be the one the button used as the one this
5838
- // view is called. Both land in the same place; neither dies.
5839
- deleted: "archived",
5840
- trash: "archived",
5841
- removed: "archived"
5516
+ var base = __toESM(require("@ai-matrx/records/views"), 1);
5517
+ var import_views = require("@ai-matrx/records/views");
5518
+ var gridPresentationCodec = {
5519
+ parse: parseGridPresentation,
5520
+ isEmpty: presentationIsEmpty,
5521
+ toDocument: (presentation) => JSON.parse(presentationDocument(presentation))
5842
5522
  };
5843
- function pageViewFromParam(raw) {
5844
- if (typeof raw !== "string") return null;
5845
- const token2 = raw.trim().toLowerCase();
5846
- if (token2 === "") return null;
5847
- return PAGE_VIEW_SPELLINGS[token2] ?? null;
5848
- }
5849
- function unknownViewLine(raw) {
5850
- return `The link asked for a view called \u201C${raw}\u201D, which this table has no view for, so you are looking at ${PAGE_VIEW_LABEL.grid}. The views this table has are ${PAGE_VIEWS.map((v) => PAGE_VIEW_LABEL[v]).join(", ")} \u2014 pick one above and the address follows it.`;
5851
- }
5852
- function viewDocument(spec) {
5853
- const out = {
5854
- // A layout the store does not keep yet is not sent: the view is saved as a grid (`STORE_KEPT_LAYOUTS`).
5855
- layout: storeKeepsLayout(spec.layout) ? spec.layout : "grid",
5856
- sorts: spec.sorts ?? [],
5857
- is_default: spec.isDefault === true
5858
- };
5859
- if (spec.groupField) out["group_field"] = spec.groupField;
5860
- if (spec.swimlaneField) out["swimlane_field"] = spec.swimlaneField;
5861
- if (spec.collapsedColumns && spec.collapsedColumns.length > 0) out["collapsed_columns"] = spec.collapsedColumns;
5862
- if (spec.measure) out["measure"] = spec.measure;
5863
- if (spec.dateField) out["date_field"] = spec.dateField;
5864
- if (STORE_KEEPS_TIMELINE && spec.startField) out["start_field"] = spec.startField;
5865
- if (STORE_KEEPS_TIMELINE && spec.endField) out["end_field"] = spec.endField;
5866
- if (spec.imageField) out["image_field"] = spec.imageField;
5867
- if (spec.ruleId) out["rule_id"] = spec.ruleId;
5868
- if (spec.where) out["where"] = spec.where;
5869
- if (spec.presentation && !presentationIsEmpty(spec.presentation)) {
5870
- out["presentation"] = JSON.parse(presentationDocument(spec.presentation));
5871
- }
5872
- return out;
5873
- }
5874
- function viewFromRow(row) {
5875
- const data = row.definition ?? {};
5876
- const k = viewSettings(data, row.filters && Object.keys(row.filters).length > 0 ? row.filters : null);
5877
- const tableFromDefinition = typeof data["table_id"] === "string" && data["table_id"] !== "" ? data["table_id"] : null;
5878
- return {
5879
- id: row.view_id,
5880
- name: row.name || "Untitled view",
5881
- subject: row.table_id ?? tableFromDefinition ?? "",
5882
- layout: k.layout,
5883
- groupField: k.groupField,
5884
- swimlaneField: k.swimlaneField,
5885
- collapsedColumns: k.collapsedColumns,
5886
- measure: k.measure,
5887
- dateField: k.dateField,
5888
- startField: k.startField,
5889
- endField: k.endField,
5890
- imageField: k.imageField,
5891
- sorts: k.sorts,
5892
- order: viewOrderOf(data),
5893
- ruleId: k.ruleId,
5894
- ...k.filters ? { filters: k.filters } : {},
5895
- where: k.where,
5896
- // The older table's own default view, carried in by the mover, IS this table's default —
5897
- // the mover wrote the row's column, which `custom.views` does not return. Read as anything
5898
- // else, the page would seed a second "All records" beside it and open on that.
5899
- isDefault: k.isDefault || k.movedFrom?.["kind"] === "default_view",
5900
- presentation: k.presentation,
5901
- movedFrom: k.movedFrom
5902
- };
5903
- }
5904
- async function declareView(client, spec) {
5905
- return client.viewDeclare({
5906
- table_id: spec.subject,
5907
- spec: {
5908
- name: spec.name,
5909
- ...spec.filters ? { filters: spec.filters } : {},
5910
- definition: viewDocument(spec)
5911
- }
5912
- });
5913
- }
5914
- async function saveViewPatch(client, tableId, viewId, patch) {
5915
- const definition = viewPatchDocument(patch);
5916
- const renamed = patch.name !== void 0 && patch.name.trim() !== "";
5917
- const refiltered = patch.filters !== void 0;
5918
- return client.viewDeclare({
5919
- table_id: tableId,
5920
- spec: {
5921
- view_id: viewId,
5922
- ...renamed ? { name: patch.name.trim() } : {},
5923
- ...refiltered ? { filters: patch.filters ?? null } : {},
5924
- definition
5925
- }
5926
- });
5927
- }
5928
- function viewPatchDocument(patch) {
5929
- const { name: _name, subject: _subject, filters: _filters, ...keys } = patch;
5930
- return viewSettingsPatch(keys);
5931
- }
5932
- function viewPatchFor(view, patch) {
5933
- if (!view.isDefault) return patch;
5934
- const { layout: _layout, isDefault: _isDefault, ...kept } = patch;
5935
- return kept;
5936
- }
5937
- async function designateView(client, tableId, viewId, layout) {
5938
- return client.viewDesignate({ table_id: tableId, view_id: viewId, layout });
5939
- }
5940
-
5941
- // src/viewLook.ts
5942
- var LOOK_KEYS = [
5943
- "layout",
5944
- "groupField",
5945
- "swimlaneField",
5946
- "collapsedColumns",
5947
- "measure",
5948
- "dateField",
5949
- "startField",
5950
- "endField",
5951
- "imageField",
5952
- "sorts",
5953
- "where",
5954
- "presentation"
5955
- ];
5956
- function lookPart(patch) {
5957
- const out = {};
5958
- for (const key of LOOK_KEYS) {
5959
- if (patch[key] !== void 0) out[key] = patch[key];
5960
- }
5961
- return out;
5962
- }
5963
- function lookDocument(look) {
5964
- return viewSettingsPatch(look);
5965
- }
5966
- function lookFromDocument(doc) {
5967
- const data = doc ?? {};
5968
- const read = viewSettings(data);
5969
- const out = {};
5970
- const has = (key) => Object.prototype.hasOwnProperty.call(data, key);
5971
- if (has("layout") && VIEW_LAYOUTS.includes(String(data["layout"]))) {
5972
- out.layout = data["layout"];
5973
- }
5974
- if (has("group_field")) out.groupField = read.groupField;
5975
- if (has("swimlane_field")) out.swimlaneField = read.swimlaneField;
5976
- if (has("collapsed_columns")) out.collapsedColumns = read.collapsedColumns;
5977
- if (has("measure")) out.measure = read.measure;
5978
- if (has("date_field")) out.dateField = read.dateField;
5979
- if (has("start_field")) out.startField = read.startField;
5980
- if (has("end_field")) out.endField = read.endField;
5981
- if (has("image_field")) out.imageField = read.imageField;
5982
- if (has("sorts")) out.sorts = read.sorts;
5983
- if (has("where")) out.where = read.where;
5984
- if (has("presentation")) out.presentation = parseGridPresentation(data["presentation"]);
5985
- return out;
5986
- }
5987
- function applyLook(view, look) {
5988
- if (!look) return view;
5989
- return { ...view, ...look };
5990
- }
5991
- function lookDiffers(view, look) {
5992
- if (!look) return false;
5993
- const shown4 = applyLook(view, look);
5994
- return LOOK_KEYS.some(
5995
- (key) => look[key] !== void 0 && JSON.stringify(shown4[key] ?? null) !== JSON.stringify(view[key] ?? null)
5996
- );
5997
- }
5998
- function saveToViewPlan(view, look) {
5999
- const patch = viewPatchFor(view, look);
6000
- const left = {};
6001
- if (look.layout !== void 0 && patch.layout === void 0 && look.layout !== view.layout) left.layout = look.layout;
6002
- return { patch, left: Object.keys(left).length > 0 ? left : null };
6003
- }
6004
- async function readLooks(client, tableId) {
6005
- const answered = await client.viewLookRead({ table_id: tableId });
6006
- if (!answered.ok) return answered;
6007
- const out = {};
6008
- for (const [viewId, row] of Object.entries(answered.data ?? {})) {
6009
- out[viewId] = lookFromDocument(row?.look ?? null);
6010
- }
6011
- return { ok: true, data: out };
6012
- }
6013
- async function keepLook(client, tableId, viewId, look) {
6014
- const doc = look ? lookDocument(look) : null;
6015
- return client.viewLookSet({ table_id: tableId, view_id: viewId, look: doc && Object.keys(doc).length > 0 ? doc : null });
6016
- }
6017
- var LOOK_WORDS = {
6018
- /** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
6019
- yours: "You changed how this view looks. Only you see it.",
6020
- /** The visible label for the same fact. */
6021
- yoursLabel: "Only you see this",
6022
- saveToView: "Save to view",
6023
- saveAsNew: "Save as new view",
6024
- reset: "Reset to view",
6025
- /** The one button your look's doors fold into when the toolbar row has no room for three. */
6026
- folded: "Your look",
6027
- newName: "Name for the new view"
6028
- };
6029
-
6030
- // src/entityQuery.ts
6031
- function entityTableQuery(options = {}) {
6032
- const search = (options.search ?? "").trim();
6033
- return { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} };
6034
- }
6035
- function entityChartQuestion(input) {
6036
- const m = input.measure ?? { op: "count" };
6037
- return {
6038
- ...input.by ? { by: [input.by] } : {},
6039
- show: [m.op === "count" ? "count" : { op: m.op, of: m.of }],
6040
- ...input.where ? { where: input.where } : {},
6041
- ...input.organization ? { organization: input.organization } : {}
6042
- };
6043
- }
5523
+ var boundViews = base.bindViewCodec(gridPresentationCodec);
5524
+ var { viewSettings, viewSettingsPatch } = boundViews;
6044
5525
 
6045
5526
  // src/firstPage.ts
6046
- var EMBEDDED_PAGE_SIZE = 50;
5527
+ var import_first_page5 = require("@ai-matrx/records/first-page");
5528
+ var { firstGridPageRequest, askTablePageSeed } = (0, import_first_page4.bindFirstPageCodec)(gridPresentationCodec);
6047
5529
 
6048
5530
  // src/embeddedLook.tsx
6049
5531
  var EMBEDDED_LOOK = { blankEmpty: true, choiceDot: true, plainRelation: true };
@@ -6366,16 +5848,16 @@ function Chips({
6366
5848
  }
6367
5849
 
6368
5850
  // src/values.tsx
6369
- var import_core6 = require("@ai-matrx/records/core");
5851
+ var import_core5 = require("@ai-matrx/records/core");
6370
5852
 
6371
5853
  // src/WholeValue.tsx
6372
5854
  var import_react32 = require("react");
6373
- var import_core5 = require("@ai-matrx/records/core");
5855
+ var import_core4 = require("@ai-matrx/records/core");
6374
5856
  var import_design_system17 = require("@ai-matrx/design-system");
6375
5857
  var import_jsx_runtime20 = require("react/jsx-runtime");
6376
5858
  var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
6377
5859
  function wholeValueLine(pointer) {
6378
- return `Open the whole text (${(0, import_core5.wholeValueSize)(pointer)})`;
5860
+ return `Open the whole text (${(0, import_core4.wholeValueSize)(pointer)})`;
6379
5861
  }
6380
5862
  function WholeValueCell({ words: words2, pointer }) {
6381
5863
  const host = useRecordsUi();
@@ -6386,12 +5868,12 @@ function WholeValueCell({ words: words2, pointer }) {
6386
5868
  words2,
6387
5869
  "\u2026"
6388
5870
  ] }),
6389
- href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core5.wholeValueSize)(pointer)} in a file` })
5871
+ href ? host.Link ? host.Link({ href, children: line, className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "shrink-0 text-xs text-primary underline-offset-2 hover:underline", href, target: "_blank", rel: "noreferrer", children: line }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs italic text-muted-foreground", title: WHOLE_VALUE_UNBOUND, children: `${(0, import_core4.wholeValueSize)(pointer)} in a file` })
6390
5872
  ] });
6391
5873
  }
6392
5874
  var WHOLE_VALUE_NOT_EDITABLE_HERE = "The whole text is kept as a file. Open it to read it; this screen cannot load it to edit.";
6393
5875
  function wholeValueOpening(pointer) {
6394
- return `Opening the whole text (${(0, import_core5.wholeValueSize)(pointer)})\u2026`;
5876
+ return `Opening the whole text (${(0, import_core4.wholeValueSize)(pointer)})\u2026`;
6395
5877
  }
6396
5878
  function useWholeText(pointer) {
6397
5879
  const host = useRecordsUi();
@@ -7298,7 +6780,7 @@ function RetiredValues({
7298
6780
  }) {
7299
6781
  const client = (0, import_react39.useRecordsClient)();
7300
6782
  const [busy, setBusy] = (0, import_react38.useState)(null);
7301
- const [refusal4, setRefusal] = (0, import_react38.useState)(null);
6783
+ const [refusal3, setRefusal] = (0, import_react38.useState)(null);
7302
6784
  const [said2, setSaid] = (0, import_react38.useState)(null);
7303
6785
  const [missing, setMissing] = (0, import_react38.useState)(null);
7304
6786
  const kept = retiredValuesOf(document2);
@@ -7347,7 +6829,7 @@ function RetiredValues({
7347
6829
  mayWrite ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_design_system23.Button, { size: "sm", variant: "outline", className: "h-6 px-2 text-xs", disabled: busy !== null, onClick: () => void restore(entry, index), "data-records-retired-restore": "", children: busy === id ? "Restoring\u2026" : "Restore" }) : null
7348
6830
  ] }),
7349
6831
  entry.reason ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "text-[11px] text-muted-foreground", children: entry.reason }) : null,
7350
- refusal4?.key === id ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RefusalNotice, { error: refusal4.error }) : null,
6832
+ refusal3?.key === id ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RefusalNotice, { error: refusal3.error }) : null,
7351
6833
  missing === id ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
7352
6834
  "No earlier version of ",
7353
6835
  name,
@@ -7509,7 +6991,7 @@ function renderValue(field2, value, document2, labels, stillWaitingFor, look) {
7509
6991
  if ((0, import_records19.isButtonField)(field2)) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ButtonValue, { field: field2 });
7510
6992
  const newer = newerKindValue(field2, value);
7511
6993
  if (newer !== void 0) return newer;
7512
- const whole = typeof value === "string" ? (0, import_core6.wholeValueOf)(document2, field2.key) : null;
6994
+ const whole = typeof value === "string" ? (0, import_core5.wholeValueOf)(document2, field2.key) : null;
7513
6995
  if (whole) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(WholeValueCell, { words: value, pointer: whole });
7514
6996
  const kind = editorKindFor(field2);
7515
6997
  if (kind === "relation" || kind === "entity_reference") {
@@ -7633,7 +7115,7 @@ function scalarText(field2, value, labels, stillWaitingFor) {
7633
7115
  function ProvenanceBadge({ document: document2, fieldKey }) {
7634
7116
  const envelope = envelopeFor(document2, fieldKey);
7635
7117
  if (!envelope?.src) return null;
7636
- if ((0, import_core6.wholeValueOf)(document2, fieldKey)) return null;
7118
+ if ((0, import_core5.wholeValueOf)(document2, fieldKey)) return null;
7637
7119
  const sources = document2?._sources;
7638
7120
  const source = sources?.[envelope.src];
7639
7121
  const label = source ? Object.values(source).map(String).join(" \xB7 ") : envelope.src;
@@ -7669,7 +7151,7 @@ function RecordValue({
7669
7151
  const newer = newerKindValue(field2, value, { inCell });
7670
7152
  if (newer !== void 0) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children: newer });
7671
7153
  }
7672
- if (inCell && ui.grid === "merged" && ui.renderText && typeof value === "string" && value.trim() !== "" && editorKindFor(field2) === "long_text" && !shownAsOf(field2) && !(0, import_core6.wholeValueOf)(document2, field2.key) && !envelopeFor(document2, field2.key)?.absent && // A long-text cell holding a kind is drawn by the kind system below, not as markdown.
7154
+ if (inCell && ui.grid === "merged" && ui.renderText && typeof value === "string" && value.trim() !== "" && editorKindFor(field2) === "long_text" && !shownAsOf(field2) && !(0, import_core5.wholeValueOf)(document2, field2.key) && !envelopeFor(document2, field2.key)?.absent && // A long-text cell holding a kind is drawn by the kind system below, not as markdown.
7673
7155
  !kindValueOf(value)) {
7674
7156
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "block h-[1.5em] min-w-0 overflow-hidden whitespace-normal", "data-records-cell-text": "", children: ui.renderText(value, "cell") });
7675
7157
  }
@@ -8202,7 +7684,7 @@ function ruleWords(rules) {
8202
7684
  function rulesChanged(was, now) {
8203
7685
  return ruleWords(was) !== ruleWords(now);
8204
7686
  }
8205
- function holdsNumbers2(field2) {
7687
+ function holdsNumbers3(field2) {
8206
7688
  return field2.type === "range";
8207
7689
  }
8208
7690
  function groupValue(value, numbers) {
@@ -8213,7 +7695,7 @@ function groupValue(value, numbers) {
8213
7695
  function FieldRulePreview({ field: field2, tableId, rules }) {
8214
7696
  const client = (0, import_react45.useRecordsClient)();
8215
7697
  const [preview, setPreview] = (0, import_react44.useState)(null);
8216
- const [refusal4, setRefusal] = (0, import_react44.useState)(null);
7698
+ const [refusal3, setRefusal] = (0, import_react44.useState)(null);
8217
7699
  const key = (0, import_react44.useMemo)(() => ruleWords(rules), [rules]);
8218
7700
  const latest = (0, import_react44.useRef)(rules);
8219
7701
  latest.current = rules;
@@ -8229,7 +7711,7 @@ function FieldRulePreview({ field: field2, tableId, rules }) {
8229
7711
  setRefusal(answer.error);
8230
7712
  return;
8231
7713
  }
8232
- const numbers = holdsNumbers2(field2);
7714
+ const numbers = holdsNumbers3(field2);
8233
7715
  const groups = answer.data.map((row) => ({ value: groupValue(row.groups[field2.key] ?? null, numbers), count: row.row_count }));
8234
7716
  setPreview((0, import_records21.previewRuleChange)(latest.current, groups, answer.data.length >= PREVIEW_GROUPS2));
8235
7717
  });
@@ -8239,7 +7721,7 @@ function FieldRulePreview({ field: field2, tableId, rules }) {
8239
7721
  clearTimeout(timer);
8240
7722
  };
8241
7723
  }, [client, tableId, field2.key, key]);
8242
- if (refusal4) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(RefusalNotice, { error: refusal4 });
7724
+ if (refusal3) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(RefusalNotice, { error: refusal3 });
8243
7725
  if (!preview) {
8244
7726
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { className: "text-[11px] text-muted-foreground", "data-records-rule-preview": "counting", children: [
8245
7727
  "Counting ",
@@ -8300,9 +7782,9 @@ function choiceDisplayPatch(field2, rows) {
8300
7782
  }
8301
7783
  function lookFollowsRenames(field2, look, renames) {
8302
7784
  if (renames.size === 0) return look;
8303
- const base = look ?? displayFormatOf(field2);
8304
- const choices = base && Array.isArray(base.options["choices"]) ? base.options["choices"] : null;
8305
- if (!base || !choices) return look;
7785
+ const base2 = look ?? displayFormatOf(field2);
7786
+ const choices = base2 && Array.isArray(base2.options["choices"]) ? base2.options["choices"] : null;
7787
+ if (!base2 || !choices) return look;
8306
7788
  let moved = false;
8307
7789
  const next = choices.map((c) => {
8308
7790
  const was = typeof c["value"] === "string" ? c["value"] : null;
@@ -8312,11 +7794,11 @@ function lookFollowsRenames(field2, look, renames) {
8312
7794
  return { ...c, value: now };
8313
7795
  });
8314
7796
  if (!moved) return look;
8315
- return { id: base.id, options: { ...base.options, choices: next } };
7797
+ return { id: base2.id, options: { ...base2.options, choices: next } };
8316
7798
  }
8317
7799
  function choiceLookFromList(field2, start, rows) {
8318
- const base = startingChoiceColors(field2, start.map((r) => r.words.trim()).filter((w) => w !== ""));
8319
- const colorRows = base.map((row) => {
7800
+ const base2 = startingChoiceColors(field2, start.map((r) => r.words.trim()).filter((w) => w !== ""));
7801
+ const colorRows = base2.map((row) => {
8320
7802
  const was = start.find((r) => choiceWord(r.words) === choiceWord(row.value));
8321
7803
  const now = was?.id ? rows.find((r) => r.id === was.id) : void 0;
8322
7804
  return now ? { value: row.value, color: now.color ?? null } : row;
@@ -8747,9 +8229,9 @@ function storageOf(field2) {
8747
8229
  }
8748
8230
  }
8749
8231
  function formatMenu(field2) {
8750
- const base = storageOf(field2);
8751
- if (base === null) return { groups: [], otherKinds: [] };
8752
- if (base === "formula") {
8232
+ const base2 = storageOf(field2);
8233
+ if (base2 === null) return { groups: [], otherKinds: [] };
8234
+ if (base2 === "formula") {
8753
8235
  const groups2 = [];
8754
8236
  for (const def of import_field_formats6.FIELD_FORMAT_LIST) {
8755
8237
  if (neverALook(def) || KIND_WORD[def.id] || def.id === "boolean") continue;
@@ -8759,7 +8241,7 @@ function formatMenu(field2) {
8759
8241
  }
8760
8242
  return { groups: groups2, otherKinds: [] };
8761
8243
  }
8762
- const groups = (0, import_field_formats6.groupedFormatsForBase)(base).map((g) => ({ group: g.group, formats: g.formats.filter((d) => !neverALook(d) && !KIND_WORD[d.id]) })).filter((g) => g.formats.length > 0);
8244
+ const groups = (0, import_field_formats6.groupedFormatsForBase)(base2).map((g) => ({ group: g.group, formats: g.formats.filter((d) => !neverALook(d) && !KIND_WORD[d.id]) })).filter((g) => g.formats.length > 0);
8763
8245
  const own3 = new Set(groups.flatMap((g) => g.formats.map((d) => d.id)));
8764
8246
  const otherKinds = [];
8765
8247
  for (const def of import_field_formats6.FIELD_FORMAT_LIST) {
@@ -9597,7 +9079,7 @@ function FieldEditor(props) {
9597
9079
  return;
9598
9080
  }
9599
9081
  (0, import_react51.tableShapeChanged)(tableId);
9600
- for (const c of done.data.undo.cells_back) (0, import_core7.announceRecordChanged)(c.record_id);
9082
+ for (const c of done.data.undo.cells_back) (0, import_core6.announceRecordChanged)(c.record_id);
9601
9083
  const n = done.data.rehomed.reduce((sum, r) => sum + r.records, 0);
9602
9084
  setRehome({});
9603
9085
  setRehomed({ said: `Saved. ${n} ${n === 1 ? "record was" : "records were"} changed with the choices.`, undo: done.data.undo });
@@ -10079,7 +9561,7 @@ function FieldEditor(props) {
10079
9561
  return;
10080
9562
  }
10081
9563
  (0, import_react51.tableShapeChanged)(tableId);
10082
- for (const c of undo.cells_back) (0, import_core7.announceRecordChanged)(c.record_id);
9564
+ for (const c of undo.cells_back) (0, import_core6.announceRecordChanged)(c.record_id);
10083
9565
  setChoiceList(null);
10084
9566
  setChoiceListStart(null);
10085
9567
  setRehomed({ said: "Undone. The choices and the records that held them are back as they were.", undo: null });
@@ -11331,7 +10813,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
11331
10813
  }
11332
10814
  function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
11333
10815
  const [text, setText] = (0, import_react59.useState)(() => openingText(field2, value));
11334
- const [refusal4, setRefusal] = (0, import_react59.useState)(null);
10816
+ const [refusal3, setRefusal] = (0, import_react59.useState)(null);
11335
10817
  const [why, setWhy] = (0, import_react59.useState)(void 0);
11336
10818
  const sent = (0, import_react59.useRef)(value);
11337
10819
  (0, import_react59.useEffect)(() => {
@@ -11362,11 +10844,11 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
11362
10844
  value: text,
11363
10845
  disabled,
11364
10846
  autoComplete: "off",
11365
- "aria-invalid": refusal4 ? true : void 0,
10847
+ "aria-invalid": refusal3 ? true : void 0,
11366
10848
  placeholder: helper ? typedDatePlaceholder(helper) : void 0,
11367
10849
  onChange: (e) => retype(e.target.value),
11368
10850
  onBlur: () => {
11369
- if (!refusal4) return;
10851
+ if (!refusal3) return;
11370
10852
  setText(openingText(field2, sent.current));
11371
10853
  setRefusal(null);
11372
10854
  }
@@ -11374,7 +10856,7 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
11374
10856
  ),
11375
10857
  helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field2) }) : null
11376
10858
  ] }),
11377
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(FloatingRefusal, { text: refusal4, why }) : null
10859
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(FloatingRefusal, { text: refusal3, why }) : null
11378
10860
  ] });
11379
10861
  }
11380
10862
  function typedDatePlaceholder(helper) {
@@ -11478,7 +10960,7 @@ function inTheStoresOrder(options) {
11478
10960
  function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCancel, addsChoices, initialSearch, asForm, onChosen }) {
11479
10961
  const client = (0, import_react60.useOptionalRecordsClient)();
11480
10962
  const [options, setOptions] = (0, import_react59.useState)(null);
11481
- const [refusal4, setRefusal] = (0, import_react59.useState)(null);
10963
+ const [refusal3, setRefusal] = (0, import_react59.useState)(null);
11482
10964
  const [reread, setReread] = (0, import_react59.useState)(0);
11483
10965
  (0, import_react59.useEffect)(() => {
11484
10966
  if (!client) return;
@@ -11510,8 +10992,8 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
11510
10992
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-xs text-muted-foreground", children: "This is normally picked from a list. A page answered without an account cannot read that list, so type your answer and whoever receives it will match it up." })
11511
10993
  ] });
11512
10994
  }
11513
- if (refusal4)
11514
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(RefusalLine, { error: refusal4 }) });
10995
+ if (refusal3)
10996
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(RefusalLine, { error: refusal3 }) });
11515
10997
  if (!options) return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { id, className: "text-xs text-muted-foreground", children: "Reading this field's choices\u2026" });
11516
10998
  if (asForm && options.length > 0) {
11517
10999
  const titled = (option) => recordName(option.data, null, "Unnamed choice");
@@ -12199,7 +11681,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12199
11681
  }
12200
11682
  const held = optimistic[cellKey(address.rowId, address.key)];
12201
11683
  const document2 = rows.find((r) => r.id === address.rowId)?.document;
12202
- const pointer = held === void 0 && typeof current === "string" ? (0, import_core8.wholeValueOf)(document2, address.key) : null;
11684
+ const pointer = held === void 0 && typeof current === "string" ? (0, import_core7.wholeValueOf)(document2, address.key) : null;
12203
11685
  if (pointer) {
12204
11686
  const read = host.readFileText;
12205
11687
  if (!read) return;
@@ -12250,7 +11732,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12250
11732
  startedFrom.current = null;
12251
11733
  }, []);
12252
11734
  const writeCellNow = (0, import_react64.useCallback)(
12253
- async (rowId, key, value, base, resent = false) => {
11735
+ async (rowId, key, value, base2, resent = false) => {
12254
11736
  const id = cellKey(rowId, key);
12255
11737
  const adding = isChoiceAddition(value) ? value : null;
12256
11738
  const shown4 = adding ? adding.value : value;
@@ -12267,7 +11749,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12267
11749
  let version = await versionOf(source, versions.current, versionReads.current, rowId);
12268
11750
  const drawnNow = await source.seen(rowId);
12269
11751
  const storedNow = rowsNow.current.find((r) => r.id === rowId)?.document?.[key];
12270
- if (drawnNow !== null && (version === null || drawnNow > version) && sameValue(storedNow, base)) {
11752
+ if (drawnNow !== null && (version === null || drawnNow > version) && sameValue(storedNow, base2)) {
12271
11753
  version = drawnNow;
12272
11754
  rememberVersion(versions.current, rowId, drawnNow);
12273
11755
  }
@@ -12296,13 +11778,13 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12296
11778
  if (written.ok) {
12297
11779
  rememberVersion(versions.current, rowId, written.data);
12298
11780
  source.wrote(rowId, written.data);
12299
- settling.current.set(id, base);
12300
- writtenRef.current?.({ rowId, key, before: base, after: shown4, version: written.data });
11781
+ settling.current.set(id, base2);
11782
+ writtenRef.current?.({ rowId, key, before: base2, after: shown4, version: written.data });
12301
11783
  afterWrite();
12302
11784
  return;
12303
11785
  }
12304
11786
  if (isUnsentWrite(written.error)) {
12305
- setRefusals((held) => ({ ...held, [id]: { error: written.error, conflict: null, attempted: value, unsent: true, base } }));
11787
+ setRefusals((held) => ({ ...held, [id]: { error: written.error, conflict: null, attempted: value, unsent: true, base: base2 } }));
12306
11788
  return;
12307
11789
  }
12308
11790
  setOptimistic((held) => {
@@ -12310,12 +11792,12 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12310
11792
  delete next[id];
12311
11793
  return next;
12312
11794
  });
12313
- const conflict = (0, import_core8.asWriteConflict)(written.error, rowId);
11795
+ const conflict = (0, import_core7.asWriteConflict)(written.error, rowId);
12314
11796
  if (written.error.code === "stale_write") {
12315
11797
  if (conflict) rememberVersion(versions.current, rowId, conflict.current_version);
12316
11798
  else versions.current.delete(rowId);
12317
- if (conflict && !resent && sameValue(conflict.contested_fields[key], base)) {
12318
- await writeCellNow(rowId, key, value, base, true);
11799
+ if (conflict && !resent && sameValue(conflict.contested_fields[key], base2)) {
11800
+ await writeCellNow(rowId, key, value, base2, true);
12319
11801
  return;
12320
11802
  }
12321
11803
  }
@@ -12332,9 +11814,9 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12332
11814
  [client, reload, afterWrite, source]
12333
11815
  );
12334
11816
  const writeCell = (0, import_react64.useCallback)(
12335
- (rowId, key, value, base) => {
11817
+ (rowId, key, value, base2) => {
12336
11818
  const behind = queues.current.get(rowId) ?? Promise.resolve();
12337
- const next = behind.then(() => writeCellNow(rowId, key, value, base));
11819
+ const next = behind.then(() => writeCellNow(rowId, key, value, base2));
12338
11820
  queues.current.set(
12339
11821
  rowId,
12340
11822
  next.then(
@@ -12398,7 +11880,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12398
11880
  }
12399
11881
  const starting = shownValue2(next.rowId, next.key);
12400
11882
  const nextDocument = rows.find((r) => r.id === next.rowId)?.document;
12401
- if (typeof starting === "string" && optimistic[cellKey(next.rowId, next.key)] === void 0 && (0, import_core8.wholeValueOf)(nextDocument, next.key)) {
11883
+ if (typeof starting === "string" && optimistic[cellKey(next.rowId, next.key)] === void 0 && (0, import_core7.wholeValueOf)(nextDocument, next.key)) {
12402
11884
  setEditing(null);
12403
11885
  setDraft(null);
12404
11886
  typed2.current = null;
@@ -12687,7 +12169,7 @@ function GridCell({
12687
12169
  };
12688
12170
  const value = editing ? editing.valueFor(row, field2) : row.document?.[field2.key];
12689
12171
  const state = editing ? editing.stateOf(row.id, field2.key) : null;
12690
- const refusal4 = editing ? editing.refusalOf(row.id, field2.key) : null;
12172
+ const refusal3 = editing ? editing.refusalOf(row.id, field2.key) : null;
12691
12173
  const editable = Boolean(editing) && canWrite && fieldIsEditable(field2);
12692
12174
  if (open && editing) {
12693
12175
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { "data-records-open-cell": "", className: "relative block w-full min-w-0", children: [
@@ -12724,10 +12206,10 @@ function GridCell({
12724
12206
  // state they are in, so only Discard is offered. It is INSIDE the open
12725
12207
  // cell, so pressing Discard is not "focus left the cell" — which would
12726
12208
  // commit the refused value one more time on its way out.
12727
- refusal4 && !refusal4.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12209
+ refusal3 && !refusal3.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12728
12210
  RefusalNotice,
12729
12211
  {
12730
- error: refusal4.error,
12212
+ error: refusal3.error,
12731
12213
  className: "py-1.5 text-left",
12732
12214
  onDiscard: () => editing.discard(row.id, field2.key)
12733
12215
  }
@@ -12752,14 +12234,14 @@ function GridCell({
12752
12234
  }
12753
12235
  ),
12754
12236
  answered ? null : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-xs text-muted-foreground", title: "nobody has answered this yet", children: "\u2014" }),
12755
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal4, field: field2, row, editing, typed: false }) : null
12237
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: false }) : null
12756
12238
  ] });
12757
12239
  }
12758
12240
  if (editable && format?.id === "rating") {
12759
12241
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { "data-matrx-cell-control": "", className: "relative flex h-full w-full flex-wrap items-center gap-1.5", children: [
12760
12242
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(FormattedValue, { value, format, onRate: (next) => editing?.setCell(row.id, field2.key, next), selectFirst: true }),
12761
12243
  state === "saving" ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { "data-records-cell-saving": "", className: "pointer-events-none absolute right-1 top-1/2 z-10 -translate-y-1/2 rounded bg-card/90 px-1 text-[10px] text-muted-foreground", children: "Saving\u2026" }) : null,
12762
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal4, field: field2, row, editing, typed: false }) : null
12244
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: false }) : null
12763
12245
  ] });
12764
12246
  }
12765
12247
  const openThisCell = (event) => {
@@ -12881,40 +12363,40 @@ function GridCell({
12881
12363
  ) : null
12882
12364
  ] }),
12883
12365
  state === "saving" ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { "data-records-cell-saving": "", className: "pointer-events-none absolute right-1 top-1/2 z-10 -translate-y-1/2 rounded bg-card/90 px-1 text-[10px] text-muted-foreground", children: "Saving\u2026" }) : null,
12884
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal4, field: field2, row, editing, typed: true }) : null
12366
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: true }) : null
12885
12367
  ]
12886
12368
  }
12887
12369
  )
12888
12370
  );
12889
12371
  }
12890
12372
  function CellRefusalNotice({
12891
- refusal: refusal4,
12373
+ refusal: refusal3,
12892
12374
  field: field2,
12893
12375
  row,
12894
12376
  editing,
12895
12377
  typed: typed2
12896
12378
  }) {
12897
12379
  const [open, setOpen] = (0, import_react64.useState)(true);
12898
- const line = refusal4.unsent ? UNSENT_LINE : refusalLineForAPerson(refusal4.error);
12899
- const notice = refusal4.unsent ? (
12380
+ const line = refusal3.unsent ? UNSENT_LINE : refusalLineForAPerson(refusal3.error);
12381
+ const notice = refusal3.unsent ? (
12900
12382
  // NOT SENT, NOT REFUSED: what was typed is still in the cell; it goes again once online.
12901
12383
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col gap-1.5 px-3 py-2 text-xs", "data-records-cell-unsent": "", children: [
12902
12384
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "font-medium", children: UNSENT_LINE }),
12903
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "max-w-[16rem] truncate text-muted-foreground", title: valueInALine(refusal4.attempted), children: valueInALine(refusal4.attempted) }),
12385
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "max-w-[16rem] truncate text-muted-foreground", title: valueInALine(refusal3.attempted), children: valueInALine(refusal3.attempted) }),
12904
12386
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "flex flex-wrap gap-1", children: [
12905
12387
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_design_system37.Button, { size: "sm", variant: "outline", className: "h-6", "data-records-cell-try-now": "", onClick: () => editing?.tryNow(row.id, field2.key), children: "Try now" }),
12906
12388
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_design_system37.Button, { size: "sm", variant: "ghost", className: "h-6", "data-records-cell-discard": "", onClick: () => editing?.discard(row.id, field2.key), children: "Discard" })
12907
12389
  ] })
12908
12390
  ] })
12909
- ) : refusal4.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12391
+ ) : refusal3.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12910
12392
  RefusalNotice,
12911
12393
  {
12912
- error: refusal4.error,
12394
+ error: refusal3.error,
12913
12395
  className: "py-1.5 text-left",
12914
12396
  actions: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "flex flex-col gap-1", "data-refusal-conflict": "", children: [
12915
12397
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-[11px]", children: [
12916
12398
  "Theirs: ",
12917
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("strong", { children: formatTheirs(refusal4.conflict, field2.key) })
12399
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("strong", { children: formatTheirs(refusal3.conflict, field2.key) })
12918
12400
  ] }),
12919
12401
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "flex flex-wrap gap-1", children: [
12920
12402
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_design_system37.Button, { size: "sm", variant: "outline", onClick: () => editing?.retry(row.id, field2.key), children: "Try again" }),
@@ -12925,7 +12407,7 @@ function CellRefusalNotice({
12925
12407
  ) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12926
12408
  RefusalNotice,
12927
12409
  {
12928
- error: refusal4.error,
12410
+ error: refusal3.error,
12929
12411
  className: "py-1.5 text-left",
12930
12412
  ...typed2 ? { onKeepEditing: () => editing?.keepEditing(row.id, field2.key) } : {},
12931
12413
  onDiscard: () => editing?.discard(row.id, field2.key)
@@ -12939,8 +12421,8 @@ function CellRefusalNotice({
12939
12421
  "data-records-cell-refusal-line": "",
12940
12422
  title: line,
12941
12423
  "aria-label": line,
12942
- "data-records-cell-unsent-mark": refusal4.unsent ? "" : void 0,
12943
- className: `absolute right-1 top-1/2 z-10 flex h-4 w-4 -translate-y-1/2 items-center justify-center rounded-full text-[10px] font-bold leading-none ${refusal4.unsent ? "bg-amber-500 text-white" : "bg-destructive text-destructive-foreground"}`,
12424
+ "data-records-cell-unsent-mark": refusal3.unsent ? "" : void 0,
12425
+ className: `absolute right-1 top-1/2 z-10 flex h-4 w-4 -translate-y-1/2 items-center justify-center rounded-full text-[10px] font-bold leading-none ${refusal3.unsent ? "bg-amber-500 text-white" : "bg-destructive text-destructive-foreground"}`,
12944
12426
  children: "!"
12945
12427
  }
12946
12428
  ) }),
@@ -13439,7 +12921,7 @@ var import_react128 = require("@ai-matrx/records/react");
13439
12921
  var import_records44 = require("@ai-matrx/records");
13440
12922
  var import_records45 = require("@ai-matrx/records");
13441
12923
  var import_data_table16 = require("@ai-matrx/design-system/data-table");
13442
- var import_core18 = require("@ai-matrx/records/core");
12924
+ var import_core17 = require("@ai-matrx/records/core");
13443
12925
 
13444
12926
  // src/tableDecorations.ts
13445
12927
  var import_react69 = require("react");
@@ -13541,7 +13023,7 @@ function EmptyRecords({ words: words2 }) {
13541
13023
 
13542
13024
  // src/gridControls.tsx
13543
13025
  var import_clipboard = require("@ai-matrx/kit/clipboard");
13544
- var import_core10 = require("@ai-matrx/records/core");
13026
+ var import_core9 = require("@ai-matrx/records/core");
13545
13027
  var import_react90 = require("react");
13546
13028
  var import_react91 = require("@ai-matrx/records/react");
13547
13029
  var import_design_system51 = require("@ai-matrx/design-system");
@@ -13563,7 +13045,7 @@ function MergeRecordDialog({ tableId, record, open, onOpenChange, onMerged }) {
13563
13045
  const records = (0, import_react72.useRecords)(tableId, { pageSize: 200 });
13564
13046
  const [other, setOther] = (0, import_react71.useState)(null);
13565
13047
  const [busy, setBusy] = (0, import_react71.useState)(false);
13566
- const [refusal4, setRefusal] = (0, import_react71.useState)(null);
13048
+ const [refusal3, setRefusal] = (0, import_react71.useState)(null);
13567
13049
  const options = (0, import_react71.useMemo)(
13568
13050
  () => (records.data?.rows ?? []).filter((row) => row.id !== record.id).map((row) => ({ value: row.id, label: rowNameIn(table.data ?? null, row) })),
13569
13051
  [records.data, record.id, table.data]
@@ -13633,7 +13115,7 @@ function MergeRecordDialog({ tableId, record, open, onOpenChange, onMerged }) {
13633
13115
  ariaLabel: "Record to merge"
13634
13116
  }
13635
13117
  ),
13636
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(RefusalNotice, { error: refusal4 }) : null,
13118
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(RefusalNotice, { error: refusal3 }) : null,
13637
13119
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_design_system40.DialogFooter, { children: [
13638
13120
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_design_system40.Button, { variant: "ghost", size: "sm", onClick: () => close(false), disabled: busy, children: "Cancel" }),
13639
13121
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_design_system40.Button, { size: "sm", onClick: () => void merge(), disabled: !other || busy, "data-records-merge-go": "", children: busy ? "Merging\u2026" : "Merge" })
@@ -13803,7 +13285,7 @@ function useGridColours(args) {
13803
13285
  [client, tableId, decorations, notify]
13804
13286
  );
13805
13287
  const idOf = (0, import_react73.useCallback)((key) => fields.find((f) => f.key === key), [fields]);
13806
- const refusal4 = mayColour ? void 0 : whyNot;
13288
+ const refusal3 = mayColour ? void 0 : whyNot;
13807
13289
  const headerItem = (0, import_react73.useCallback)(
13808
13290
  (columnKey) => {
13809
13291
  if (!enabled) return null;
@@ -13818,7 +13300,7 @@ function useGridColours(args) {
13818
13300
  id: "col-colour",
13819
13301
  label: "Colour by\u2026",
13820
13302
  icon: "palette",
13821
- disabledReason: refusal4,
13303
+ disabledReason: refusal3,
13822
13304
  submenu: [
13823
13305
  byThis ? {
13824
13306
  id: "col-colour-off",
@@ -13854,7 +13336,7 @@ function useGridColours(args) {
13854
13336
  ]
13855
13337
  };
13856
13338
  },
13857
- [enabled, idOf, decorations.data, refusal4, write]
13339
+ [enabled, idOf, decorations.data, refusal3, write]
13858
13340
  );
13859
13341
  const cellItem = (0, import_react73.useCallback)(
13860
13342
  (rowId, columnKey) => {
@@ -13866,7 +13348,7 @@ function useGridColours(args) {
13866
13348
  id: "cell-highlight",
13867
13349
  label: "Highlight cell",
13868
13350
  icon: "palette",
13869
- disabledReason: refusal4,
13351
+ disabledReason: refusal3,
13870
13352
  submenu: swatches(
13871
13353
  "cell-highlight",
13872
13354
  current,
@@ -13874,7 +13356,7 @@ function useGridColours(args) {
13874
13356
  )
13875
13357
  };
13876
13358
  },
13877
- [enabled, idOf, decorations.data, refusal4, write]
13359
+ [enabled, idOf, decorations.data, refusal3, write]
13878
13360
  );
13879
13361
  const cellsItem = (0, import_react73.useCallback)(
13880
13362
  (cells) => {
@@ -13884,7 +13366,7 @@ function useGridColours(args) {
13884
13366
  id: "sel-highlight",
13885
13367
  label: `Highlight ${n} cells`,
13886
13368
  icon: "palette",
13887
- disabledReason: refusal4,
13369
+ disabledReason: refusal3,
13888
13370
  submenu: swatches("sel-highlight", void 0, (color) => {
13889
13371
  void (async () => {
13890
13372
  let kept = 0;
@@ -13904,7 +13386,7 @@ function useGridColours(args) {
13904
13386
  })
13905
13387
  };
13906
13388
  },
13907
- [enabled, idOf, refusal4, client, tableId, decorations, notify]
13389
+ [enabled, idOf, refusal3, client, tableId, decorations, notify]
13908
13390
  );
13909
13391
  const rowItem = (0, import_react73.useCallback)(
13910
13392
  (rowId) => {
@@ -13914,7 +13396,7 @@ function useGridColours(args) {
13914
13396
  id: "row-highlight",
13915
13397
  label: "Highlight row",
13916
13398
  icon: "palette",
13917
- disabledReason: refusal4,
13399
+ disabledReason: refusal3,
13918
13400
  submenu: swatches(
13919
13401
  "row-highlight",
13920
13402
  current,
@@ -13922,7 +13404,7 @@ function useGridColours(args) {
13922
13404
  )
13923
13405
  };
13924
13406
  },
13925
- [enabled, decorations.data, refusal4, write]
13407
+ [enabled, decorations.data, refusal3, write]
13926
13408
  );
13927
13409
  const dialogs = enabled ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
13928
13410
  ColourRulesDialog,
@@ -14673,7 +14155,7 @@ function stepOf(step2, original) {
14673
14155
  return { field: field2, set: "value", value: step2.value };
14674
14156
  }
14675
14157
  function actionOf(draft, original) {
14676
- const base = {
14158
+ const base2 = {
14677
14159
  ...draft.id ? { id: draft.id } : {},
14678
14160
  name: draft.name.trim(),
14679
14161
  kind: draft.kind,
@@ -14681,9 +14163,9 @@ function actionOf(draft, original) {
14681
14163
  ...draft.color ? { color: draft.color } : {},
14682
14164
  ...draft.icon ? { icon: draft.icon } : {}
14683
14165
  };
14684
- if (draft.kind === "agent") return { ...base, prompt: draft.prompt };
14166
+ if (draft.kind === "agent") return { ...base2, prompt: draft.prompt };
14685
14167
  return {
14686
- ...base,
14168
+ ...base2,
14687
14169
  steps: draft.steps.map((s, i) => stepOf(s, original?.steps?.[i]))
14688
14170
  };
14689
14171
  }
@@ -15829,7 +15311,7 @@ function WholeTextDialog({
15829
15311
  }
15830
15312
 
15831
15313
  // src/pasteValues.ts
15832
- var import_core9 = require("@ai-matrx/records/core");
15314
+ var import_core8 = require("@ai-matrx/records/core");
15833
15315
  var import_records36 = require("@ai-matrx/records");
15834
15316
  function wordForStoredChoice(options, value) {
15835
15317
  if (options === void 0 || typeof value !== "string" || value === "") return null;
@@ -15908,20 +15390,20 @@ function planPastedBlock(args) {
15908
15390
  });
15909
15391
  accepted[key] = judged.value;
15910
15392
  }
15911
- const predicted = (0, import_core9.predictValueRefusals)(args.fields, accepted);
15912
- for (const refusal4 of predicted) {
15913
- const key = refusal4.field_key;
15393
+ const predicted = (0, import_core8.predictValueRefusals)(args.fields, accepted);
15394
+ for (const refusal3 of predicted) {
15395
+ const key = refusal3.field_key;
15914
15396
  if (key === void 0) continue;
15915
15397
  const cell2 = built.find((b) => b.key === key && b.refusal === null);
15916
15398
  if (!cell2) continue;
15917
- cell2.refusal = refusal4.message;
15399
+ cell2.refusal = refusal3.message;
15918
15400
  cell2.value = null;
15919
15401
  delete accepted[key];
15920
15402
  refusals.push({
15921
15403
  fromLine,
15922
15404
  column: fieldName(byKey.get(key) ?? { key }),
15923
15405
  raw: cell2.raw,
15924
- why: refusal4.message
15406
+ why: refusal3.message
15925
15407
  });
15926
15408
  }
15927
15409
  cells += Object.keys(accepted).length;
@@ -16125,8 +15607,8 @@ function useMergedGridControls(args) {
16125
15607
  setHeld(null);
16126
15608
  }, [keptKey]);
16127
15609
  const order = (0, import_react90.useMemo)(() => {
16128
- const base = held?.order ?? columnsInKeptOrder(fieldKeys, keptOrder);
16129
- const known = columnsInKeptOrder(fieldKeys, base);
15610
+ const base2 = held?.order ?? columnsInKeptOrder(fieldKeys, keptOrder);
15611
+ const known = columnsInKeptOrder(fieldKeys, base2);
16130
15612
  if (frozenKeys.size === 0) return known;
16131
15613
  return [...known.filter((k) => frozenKeys.has(k)), ...known.filter((k) => !frozenKeys.has(k))];
16132
15614
  }, [held, fieldKeys, keptOrder, frozenKeys]);
@@ -16175,17 +15657,17 @@ function useMergedGridControls(args) {
16175
15657
  const fieldsRef = (0, import_react90.useRef)(fields);
16176
15658
  fieldsRef.current = fields;
16177
15659
  const [choiceCounts, setChoiceCounts] = (0, import_react90.useState)({});
16178
- (0, import_react90.useEffect)(() => (0, import_core10.onRecordChanged)(() => (0, askOnce_exports.forgetAsked)(client, `value_counts:${tableId}:`)), [client, tableId]);
15660
+ (0, import_react90.useEffect)(() => (0, import_core9.onRecordChanged)(() => (0, askOnce_exports.forgetAsked)(client, `value_counts:${tableId}:`)), [client, tableId]);
16179
15661
  (0, import_react90.useEffect)(() => {
16180
15662
  if (!enabled || choiceKeys.length === 0) {
16181
15663
  setChoiceCounts({});
16182
15664
  return;
16183
15665
  }
16184
15666
  let cancelled = false;
16185
- const [keys, filters, base, searched] = JSON.parse(countQuestionKey);
15667
+ const [keys, filters, base2, searched] = JSON.parse(countQuestionKey);
16186
15668
  for (const key of keys) {
16187
15669
  const { [key]: _own, ...others } = filters;
16188
- const asked2 = storeQuestion(fieldsRef.current, base ?? void 0, others);
15670
+ const asked2 = storeQuestion(fieldsRef.current, base2 ?? void 0, others);
16189
15671
  void (0, askOnce_exports.askOnce)(
16190
15672
  client,
16191
15673
  `value_counts:${tableId}:${key}:${searched}:${JSON.stringify(asked2.filter ?? null)}`,
@@ -16801,9 +16283,9 @@ function readersThrough(fields, key) {
16801
16283
  });
16802
16284
  }
16803
16285
  function backLinkSentence(column, readers = [], tableName2 = null) {
16804
- const base = `It goes when ${column.source_field_label} is archived on ${column.source_table_name}. Archiving it removes the links it holds there too; it can be brought back from Archived.`;
16805
- if (readers.length === 0) return base;
16806
- return `${readersSentence(readers.length, tableName2)} ${base}`;
16286
+ const base2 = `It goes when ${column.source_field_label} is archived on ${column.source_table_name}. Archiving it removes the links it holds there too; it can be brought back from Archived.`;
16287
+ if (readers.length === 0) return base2;
16288
+ return `${readersSentence(readers.length, tableName2)} ${base2}`;
16807
16289
  }
16808
16290
  function afterMenuLayerCloses(next) {
16809
16291
  if (typeof window === "undefined") return next();
@@ -16832,7 +16314,7 @@ var import_design_system55 = require("@ai-matrx/design-system");
16832
16314
  // src/RecordForm.tsx
16833
16315
  var import_react96 = require("react");
16834
16316
  var import_react97 = require("@ai-matrx/records/react");
16835
- var import_core12 = require("@ai-matrx/records/core");
16317
+ var import_core11 = require("@ai-matrx/records/core");
16836
16318
  var import_design_system54 = require("@ai-matrx/design-system");
16837
16319
  var import_text_case6 = require("@ai-matrx/kit/text-case");
16838
16320
 
@@ -16845,7 +16327,7 @@ var import_design_system53 = require("@ai-matrx/design-system");
16845
16327
  var import_react92 = require("react");
16846
16328
  var import_react93 = require("@ai-matrx/records/react");
16847
16329
  var import_design_system52 = require("@ai-matrx/design-system");
16848
- var import_core11 = require("@ai-matrx/records/core");
16330
+ var import_core10 = require("@ai-matrx/records/core");
16849
16331
  var import_jsx_runtime59 = require("react/jsx-runtime");
16850
16332
  function isEmptyValue(value) {
16851
16333
  return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
@@ -16917,7 +16399,7 @@ async function writeStandardRowValues(client, args) {
16917
16399
  { schema: config.schema ?? "custom" }
16918
16400
  );
16919
16401
  if (!old.error) return { ok: true };
16920
- const error = (0, import_core11.mapPgError)(old.error, "entityValueWrite");
16402
+ const error = (0, import_core10.mapPgError)(old.error, "entityValueWrite");
16921
16403
  return { ok: false, error: doorIsAbsent(error) && first && first.error.code !== "door_absent" ? first.error : error };
16922
16404
  }
16923
16405
  function doorIsAbsent(error) {
@@ -17498,7 +16980,7 @@ function CustomRecordForm({
17498
16980
  return out;
17499
16981
  }, [draft]);
17500
16982
  const predicted = (0, import_react96.useMemo)(
17501
- () => fields.data ? (0, import_core12.predictWriteRefusals)({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
16983
+ () => fields.data ? (0, import_core11.predictWriteRefusals)({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
17502
16984
  [fields.data, document2, recordType]
17503
16985
  );
17504
16986
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(RefusalNotice, { error: fields.error, className });
@@ -17548,7 +17030,7 @@ function CustomRecordForm({
17548
17030
  setEdit({
17549
17031
  saving: false,
17550
17032
  error: answered2.ok ? null : answered2.error,
17551
- conflict: answered2.ok ? null : (0, import_core12.asWriteConflict)(answered2.error, recordId)
17033
+ conflict: answered2.ok ? null : (0, import_core11.asWriteConflict)(answered2.error, recordId)
17552
17034
  });
17553
17035
  const moved = answered2.ok ? answered2.data : null;
17554
17036
  if (moved !== null) {
@@ -17659,7 +17141,7 @@ function FieldRow({
17659
17141
  }) {
17660
17142
  const id = `field-${field2.id}`;
17661
17143
  const storedWords = document2?.[field2.key];
17662
- const whole = typeof storedWords === "string" ? (0, import_core12.wholeValueOf)(document2, field2.key) : null;
17144
+ const whole = typeof storedWords === "string" ? (0, import_core11.wholeValueOf)(document2, field2.key) : null;
17663
17145
  return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: (0, import_design_system54.cn)("flex min-w-0 flex-col gap-1", whole && "sm:col-span-2"), children: [
17664
17146
  /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(FieldLabel, { field: field2, htmlFor: id, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(ProvenanceBadge, { document: document2, fieldKey: field2.key }) }),
17665
17147
  whole ? (
@@ -18110,8 +17592,8 @@ function useDrillDefinition(source) {
18110
17592
  }, [client, key]);
18111
17593
  return state.key === key ? { def: state.def, error: state.error } : { def: null, error: null };
18112
17594
  }
18113
- function drillWhere(base, trail, booleans) {
18114
- const where = { ...base ?? {} };
17595
+ function drillWhere(base2, trail, booleans) {
17596
+ const where = { ...base2 ?? {} };
18115
17597
  for (const w of trail) {
18116
17598
  const { key, grain } = (0, import_data_table14.parseDimensionRef)(w.dim);
18117
17599
  if (grain) where[w.dim] = w.value;
@@ -18290,10 +17772,10 @@ function useDrill(args) {
18290
17772
  const booleans = (0, import_react102.useMemo)(() => new Set((def?.dimensions ?? []).filter((d) => d.kind === "boolean").map((d) => d.key)), [def]);
18291
17773
  const baseKey = JSON.stringify(args.base ?? []);
18292
17774
  const filter = (0, import_react102.useMemo)(() => {
18293
- const base = JSON.parse(baseKey);
18294
- if (base.length === 0) return args.filter;
17775
+ const base2 = JSON.parse(baseKey);
17776
+ if (base2.length === 0) return args.filter;
18295
17777
  const out = { ...args.filter ?? {} };
18296
- for (const b of base) out[b.key] = b.value;
17778
+ for (const b of base2) out[b.key] = b.value;
18297
17779
  return out;
18298
17780
  }, [args.filter, baseKey]);
18299
17781
  const where = (0, import_react102.useMemo)(() => drillWhere(filter, question.where, booleans), [filter, question.where, booleans]);
@@ -18422,17 +17904,17 @@ function trailClause(fields, w) {
18422
17904
  }
18423
17905
  return { key, value: w.value, field: field2 };
18424
17906
  }
18425
- function filterWithTrail(fields, base, trail) {
18426
- if (trail.length === 0) return base;
18427
- if (!base || !(0, import_records37.isRuleFilter)(base)) {
18428
- const flat = { ...base ?? {} };
17907
+ function filterWithTrail(fields, base2, trail) {
17908
+ if (trail.length === 0) return base2;
17909
+ if (!base2 || !(0, import_records37.isRuleFilter)(base2)) {
17910
+ const flat = { ...base2 ?? {} };
18429
17911
  for (const w of trail) {
18430
17912
  const clause = trailClause(fields, w);
18431
17913
  flat[clause.key] = clause.value;
18432
17914
  }
18433
17915
  return flat;
18434
17916
  }
18435
- const args = [base];
17917
+ const args = [base2];
18436
17918
  for (const w of trail) {
18437
17919
  const clause = trailClause(fields, w);
18438
17920
  if (!clause.field) continue;
@@ -18446,14 +17928,14 @@ function filterWithTrail(fields, base, trail) {
18446
17928
  }
18447
17929
  return { op: "and", args };
18448
17930
  }
18449
- function filterWithWindow(fields, base, key, range) {
18450
- if (!base || !(0, import_records37.isRuleFilter)(base)) return { ...base ?? {}, [key]: { from: range.from, to: range.to } };
17931
+ function filterWithWindow(fields, base2, key, range) {
17932
+ if (!base2 || !(0, import_records37.isRuleFilter)(base2)) return { ...base2 ?? {}, [key]: { from: range.from, to: range.to } };
18451
17933
  const field2 = fields.find((f) => f.key === key);
18452
- if (!field2) return base;
17934
+ if (!field2) return base2;
18453
17935
  const ref = { field: field2.id };
18454
17936
  return {
18455
17937
  op: "and",
18456
- args: [base, { op: "gte", args: [ref, { const: range.from }] }, { op: "lt", args: [ref, { const: range.to }] }]
17938
+ args: [base2, { op: "gte", args: [ref, { const: range.from }] }, { op: "lt", args: [ref, { const: range.to }] }]
18457
17939
  };
18458
17940
  }
18459
17941
  function useGridDrillQuestion(args) {
@@ -19120,7 +18602,7 @@ function columnForField(field2, editing, mayWriteRow, whyNotRow, look, onAskWhoC
19120
18602
  ...look?.frozen ? { frozen: true, width: Math.max(FROZEN_COLUMN_WIDTH, defaultColumnWidth(field2)) } : { width: defaultColumnWidth(field2) },
19121
18603
  // A column that holds numbers filters as numbers (=, <, >, between) — the record number too,
19122
18604
  // which is worked out but kept (review 2: the autonumber header offered "Contains").
19123
- filter: filterRefusal(field2) !== null ? false : editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? "select" : holdsNumbers(field2) ? "number" : "auto",
18605
+ filter: filterRefusal(field2) !== null ? false : editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? "select" : (0, import_first_page2.holdsNumbers)(field2) ? "number" : "auto",
19124
18606
  // THE MENU'S VALUE LIST WEARS THE CHOICES' COLOURS (lane CELL-EDITORS, night walk 2026-10-06): the
19125
18607
  // same chip the cell draws, never bare words beside a coloured column.
19126
18608
  ...editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? { filterValueClass: (value, label) => choiceChipLookOf(field2, value, label).className } : {},
@@ -19247,6 +18729,11 @@ function withTypeMark(field2, header) {
19247
18729
  // src/ReverseColumns.tsx
19248
18730
  var import_react106 = require("react");
19249
18731
  var import_records38 = require("@ai-matrx/records");
18732
+
18733
+ // src/groupReads.ts
18734
+ var import_first_page6 = require("@ai-matrx/records/first-page");
18735
+
18736
+ // src/ReverseColumns.tsx
19250
18737
  var import_react107 = require("@ai-matrx/records/react");
19251
18738
  var import_design_system58 = require("@ai-matrx/design-system");
19252
18739
  var import_jsx_runtime65 = require("react/jsx-runtime");
@@ -19320,7 +18807,7 @@ function useReverseGridColumns(tableId, rowIds) {
19320
18807
  const reverse = (0, import_react107.useReverseColumns)(tableId);
19321
18808
  const columns = useStableColumns(reverse.data);
19322
18809
  const ids = (0, import_react106.useMemo)(() => rowIds.filter((id) => id !== SUMMARY_ROW_ID && id !== ADD_ROW_ID), [rowIds]);
19323
- const links = (0, import_react107.useReverseLinks)(tableId, columns, ids, REVERSE_CELL_CHIPS);
18810
+ const links = (0, import_react107.useReverseLinks)(tableId, columns, ids, import_first_page6.REVERSE_CELL_CHIPS);
19324
18811
  const held = useLinksStore(links.data, links.loading);
19325
18812
  return (0, import_react106.useMemo)(
19326
18813
  () => columns.length === 0 ? NO_GRID_COLUMNS : columns.map((column) => ({
@@ -19707,10 +19194,10 @@ function PastePreview({
19707
19194
  /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(PlanTable, { plan }),
19708
19195
  plan.refusals.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { "data-matrx-paste-refusals": true, className: "flex flex-col gap-1", children: [
19709
19196
  /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { className: "text-xs font-medium", children: plan.refusals.length === 1 ? "One cell will be left alone:" : `${plan.refusals.length} cells will be left alone:` }),
19710
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("ul", { className: "flex flex-col gap-1", children: plan.refusals.slice(0, 12).map((refusal4, index) => /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("li", { className: "text-xs text-muted-foreground", children: [
19711
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "font-medium", children: refusal4.fromLine > 0 ? `Row ${refusal4.fromLine}, ${refusal4.column}` : refusal4.column }),
19197
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("ul", { className: "flex flex-col gap-1", children: plan.refusals.slice(0, 12).map((refusal3, index) => /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("li", { className: "text-xs text-muted-foreground", children: [
19198
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "font-medium", children: refusal3.fromLine > 0 ? `Row ${refusal3.fromLine}, ${refusal3.column}` : refusal3.column }),
19712
19199
  " \u2014 ",
19713
- refusal4.why
19200
+ refusal3.why
19714
19201
  ] }, index)) }),
19715
19202
  plan.refusals.length > 12 ? /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
19716
19203
  plan.refusals.length - 12,
@@ -19936,12 +19423,12 @@ function withOpenRecord(columns, onOpen, nameOf2, place = "end", hrefOf) {
19936
19423
  // src/ImportWizard.tsx
19937
19424
  var import_react109 = require("react");
19938
19425
  var import_react110 = require("@ai-matrx/records/react");
19939
- var import_core14 = require("@ai-matrx/records/core");
19426
+ var import_core13 = require("@ai-matrx/records/core");
19940
19427
  var import_design_system60 = require("@ai-matrx/design-system");
19941
19428
  var import_records41 = require("@ai-matrx/records");
19942
19429
 
19943
19430
  // src/importRuleCheck.ts
19944
- var import_core13 = require("@ai-matrx/records/core");
19431
+ var import_core12 = require("@ai-matrx/records/core");
19945
19432
  function checkImportRules(fields, rows, mapping, choiceOptions, relationNames) {
19946
19433
  const byKey = new Map(fields.map((f) => [f.key, f]));
19947
19434
  const verdicts = [];
@@ -19967,7 +19454,7 @@ function checkImportRules(fields, rows, mapping, choiceOptions, relationNames) {
19967
19454
  if ("unmatchedNames" in meant) return;
19968
19455
  if ("refusal" in meant) why = meant.refusal;
19969
19456
  else {
19970
- const predicted = (0, import_core13.predictValueRefusals)([field2], { [key]: meant.value }).filter(
19457
+ const predicted = (0, import_core12.predictValueRefusals)([field2], { [key]: meant.value }).filter(
19971
19458
  (p) => p.field_key === void 0 || p.field_key === key
19972
19459
  );
19973
19460
  if (predicted.length > 0) why = predicted[0].message;
@@ -20174,8 +19661,8 @@ function offerDownload(name, text, type = "text/csv") {
20174
19661
  return true;
20175
19662
  }
20176
19663
  function refusedFileName(sourceName) {
20177
- const base = (sourceName ?? "import").replace(/\.(csv|xlsx)$/i, "");
20178
- return `${base} \u2014 rows not added.csv`;
19664
+ const base2 = (sourceName ?? "import").replace(/\.(csv|xlsx)$/i, "");
19665
+ return `${base2} \u2014 rows not added.csv`;
20179
19666
  }
20180
19667
 
20181
19668
  // src/ImportWizard.tsx
@@ -20471,7 +19958,7 @@ function ImportWizard({ tableId, source, onDone, onWrote, className }) {
20471
19958
  try {
20472
19959
  const xlsx = file.name.toLowerCase().endsWith(".xlsx");
20473
19960
  const bytes = await file.arrayBuffer();
20474
- const result = xlsx ? await (0, import_core14.importXlsx)(bytes) : (0, import_core14.importCsv)(new TextDecoder().decode(bytes));
19961
+ const result = xlsx ? await (0, import_core13.importXlsx)(bytes) : (0, import_core13.importCsv)(new TextDecoder().decode(bytes));
20475
19962
  await planFrom(result, { name: file.name, bytes: file.size, hash: await sha256(bytes), format: xlsx ? "xlsx" : "csv" });
20476
19963
  } catch (thrown) {
20477
19964
  setProblem(
@@ -21629,11 +21116,11 @@ function cellWords(raw) {
21629
21116
  function uniqueLabels(raw) {
21630
21117
  const seen = /* @__PURE__ */ new Map();
21631
21118
  return raw.map((label, index) => {
21632
- const base = label.trim() || `Column ${index + 1}`;
21633
- const key = base.toLowerCase();
21119
+ const base2 = label.trim() || `Column ${index + 1}`;
21120
+ const key = base2.toLowerCase();
21634
21121
  const count = (seen.get(key) ?? 0) + 1;
21635
21122
  seen.set(key, count);
21636
- return count === 1 ? base : `${base} ${count}`;
21123
+ return count === 1 ? base2 : `${base2} ${count}`;
21637
21124
  });
21638
21125
  }
21639
21126
  function rowsOf(headers, matrix) {
@@ -21694,7 +21181,7 @@ function recordsFromPairs(pairs) {
21694
21181
  if (current.size > 0) records.push(current);
21695
21182
  return records;
21696
21183
  }
21697
- function shapeFromRecords(records, base, from) {
21184
+ function shapeFromRecords(records, base2, from) {
21698
21185
  const order = [];
21699
21186
  for (const r of records) for (const k of r.keys()) if (!order.some((o) => o.toLowerCase() === k.toLowerCase())) order.push(k);
21700
21187
  const headers = uniqueLabels(order);
@@ -21707,7 +21194,7 @@ function shapeFromRecords(records, base, from) {
21707
21194
  return row;
21708
21195
  });
21709
21196
  return {
21710
- ...base,
21197
+ ...base2,
21711
21198
  kind: "key_value",
21712
21199
  headers,
21713
21200
  rows,
@@ -22275,7 +21762,7 @@ function valueListKind(field2) {
22275
21762
  if (kind === "text" || kind === "long_text" || kind === "email" || kind === "phone" || kind === "url") return "words";
22276
21763
  if (kind === "datetime" || kind === "date") return "days";
22277
21764
  if (kind === "checkbox") return "yesno";
22278
- if (holdsNumbers(field2) || kind === "rating") return "numbers";
21765
+ if ((0, import_first_page2.holdsNumbers)(field2) || kind === "rating") return "numbers";
22279
21766
  return "loaded";
22280
21767
  }
22281
21768
  function noValueList(columnId2) {
@@ -22407,7 +21894,7 @@ function useGroupFacts(args) {
22407
21894
  const entries = JSON.parse(chosenKey);
22408
21895
  const asked2 = JSON.parse(filterKey);
22409
21896
  const filter = Object.keys(asked2).length > 0 ? asked2 : void 0;
22410
- const measures = groupFactMeasures(Object.fromEntries(entries));
21897
+ const measures = (0, import_first_page6.groupFactMeasures)(Object.fromEntries(entries));
22411
21898
  let cancelled = false;
22412
21899
  void client.recordAggregate({ table_id: tableId, groupBy: [groupKey], measures, limit: 1e3, ...filter ? { filter } : {} }).then((answered) => {
22413
21900
  if (cancelled) return;
@@ -22480,7 +21967,7 @@ function useGroupLabel(fields, groupKey) {
22480
21967
  // src/gridUndo.tsx
22481
21968
  var import_react117 = require("react");
22482
21969
  var import_react118 = require("@ai-matrx/records/react");
22483
- var import_core15 = require("@ai-matrx/records/core");
21970
+ var import_core14 = require("@ai-matrx/records/core");
22484
21971
  var import_design_system62 = require("@ai-matrx/design-system");
22485
21972
  var import_data_table15 = require("@ai-matrx/design-system/data-table");
22486
21973
  var import_jsx_runtime73 = require("react/jsx-runtime");
@@ -22541,40 +22028,40 @@ function useGridUndo(args) {
22541
22028
  if (!step2) return;
22542
22029
  setBusy(true);
22543
22030
  const changes = changesFor(step2, direction, known.current);
22544
- let refusal4 = null;
22031
+ let refusal3 = null;
22545
22032
  if (direction === "redo" && (step2.created?.length ?? 0) > 0) {
22546
22033
  const answers = await Promise.all((step2.created ?? []).map((id) => client.recordRestore({ record_id: id })));
22547
22034
  const failed = answers.find((a) => !a.ok);
22548
- if (failed && !failed.ok) refusal4 = failed.error;
22035
+ if (failed && !failed.ok) refusal3 = failed.error;
22549
22036
  }
22550
- if (!refusal4 && step2.retiredField) {
22037
+ if (!refusal3 && step2.retiredField) {
22551
22038
  const fieldId = step2.retiredField.fieldId;
22552
22039
  const done = direction === "undo" ? await client.fieldRestore({ field_id: fieldId }) : await client.fieldRetire({ field_id: fieldId });
22553
- if (!done.ok) refusal4 = done.error;
22040
+ if (!done.ok) refusal3 = done.error;
22554
22041
  else (0, import_react118.tableShapeChanged)(tableId);
22555
22042
  }
22556
- if (!refusal4 && changes.length > 0) {
22043
+ if (!refusal3 && changes.length > 0) {
22557
22044
  const done = await (0, recordVersions_exports.changeRecordsAt)(client, { table_id: tableId, changes });
22558
- if (!done.ok) refusal4 = done.error;
22045
+ if (!done.ok) refusal3 = done.error;
22559
22046
  else {
22560
22047
  for (const result of done.data ?? []) if (result.op === "update") known.current.set(result.id, result.version);
22561
22048
  onVersions?.((done.data ?? []).flatMap((r) => r.op === "update" ? [{ id: r.id, version: r.version }] : []));
22562
22049
  }
22563
22050
  }
22564
- if (!refusal4 && direction === "undo" && (step2.archived?.length ?? 0) > 0) {
22051
+ if (!refusal3 && direction === "undo" && (step2.archived?.length ?? 0) > 0) {
22565
22052
  const answers = await Promise.all((step2.archived ?? []).map((id) => client.recordRestore({ record_id: id })));
22566
22053
  const failed = answers.find((a) => !a.ok);
22567
- if (failed && !failed.ok) refusal4 = failed.error;
22054
+ if (failed && !failed.ok) refusal3 = failed.error;
22568
22055
  }
22569
22056
  setBusy(false);
22570
- if (refusal4) {
22571
- setNotice({ says: `${direction === "undo" ? "Undo" : "Redo"} changed nothing: ${refusalSentence(refusal4)}`, refusal: refusal4, canUndo: false });
22572
- if ((0, recordVersions_exports.isChangedElsewhere)(refusal4)) reload();
22057
+ if (refusal3) {
22058
+ setNotice({ says: `${direction === "undo" ? "Undo" : "Redo"} changed nothing: ${refusalSentence(refusal3)}`, refusal: refusal3, canUndo: false });
22059
+ if ((0, recordVersions_exports.isChangedElsewhere)(refusal3)) reload();
22573
22060
  return;
22574
22061
  }
22575
22062
  forget(step2.cells.map((c) => ({ rowId: c.rowId, key: c.key })));
22576
22063
  for (const id of /* @__PURE__ */ new Set([...step2.cells.map((c) => c.rowId), ...step2.created ?? [], ...step2.archived ?? []])) {
22577
- (0, import_core15.announceRecordChanged)(id);
22064
+ (0, import_core14.announceRecordChanged)(id);
22578
22065
  }
22579
22066
  setHeld(() => {
22580
22067
  let stack = taken.stack;
@@ -22962,7 +22449,7 @@ function holdKeys() {
22962
22449
  // src/gridAssist.tsx
22963
22450
  var import_clipboard2 = require("@ai-matrx/kit/clipboard");
22964
22451
  var import_react121 = require("react");
22965
- var import_core16 = require("@ai-matrx/records/core");
22452
+ var import_core15 = require("@ai-matrx/records/core");
22966
22453
  var import_workspace = require("@ai-matrx/alchemy/react/workspace");
22967
22454
 
22968
22455
  // src/gridAgentContext.ts
@@ -23092,7 +22579,7 @@ function useGridAssist(args) {
23092
22579
  const copyRecordReference = (0, import_react121.useCallback)(
23093
22580
  (rowId) => {
23094
22581
  void (async () => {
23095
- const text = JSON.stringify({ __kind: (0, import_core16.tableKindSlug)(tableId), _record_id: rowId });
22582
+ const text = JSON.stringify({ __kind: (0, import_core15.tableKindSlug)(tableId), _record_id: rowId });
23096
22583
  if (!await (0, import_clipboard2.copyText)(text)) {
23097
22584
  say2(false, "This browser did not let the page write to the clipboard.");
23098
22585
  return;
@@ -23148,7 +22635,7 @@ function useGridAssist(args) {
23148
22635
  if (!row) return;
23149
22636
  const document2 = row.document ?? {};
23150
22637
  const value = editing.valueFor(row, fieldOf2(key));
23151
- const pointer = typeof document2[key] === "string" ? (0, import_core16.wholeValueOf)(document2, key) : null;
22638
+ const pointer = typeof document2[key] === "string" ? (0, import_core15.wholeValueOf)(document2, key) : null;
23152
22639
  setWhole({ rowId, key, rowTitle: titleOf(row), value, pointer });
23153
22640
  },
23154
22641
  [rowOf, fieldOf2, titleOf, editing]
@@ -23244,7 +22731,7 @@ function useGridAssist(args) {
23244
22731
  // src/gridBulk.tsx
23245
22732
  var import_react122 = require("react");
23246
22733
  var import_react123 = require("@ai-matrx/records/react");
23247
- var import_core17 = require("@ai-matrx/records/core");
22734
+ var import_core16 = require("@ai-matrx/records/core");
23248
22735
  var import_design_system63 = require("@ai-matrx/design-system");
23249
22736
  var import_jsx_runtime75 = require("react/jsx-runtime");
23250
22737
  function countOf(n, one, many) {
@@ -23290,7 +22777,7 @@ function useGridBulk(args) {
23290
22777
  const client = (0, import_react123.useRecordsClient)();
23291
22778
  const { tableId, rows, fields, noun, nounPlural, reload, forget, pushUndo: pushUndo2, versions } = args;
23292
22779
  const [busy, setBusy] = (0, import_react122.useState)(false);
23293
- const [refusal4, setRefusal] = (0, import_react122.useState)(null);
22780
+ const [refusal3, setRefusal] = (0, import_react122.useState)(null);
23294
22781
  const send = (0, import_react122.useCallback)(
23295
22782
  async (changes) => {
23296
22783
  setBusy(true);
@@ -23310,7 +22797,7 @@ function useGridBulk(args) {
23310
22797
  return null;
23311
22798
  }
23312
22799
  for (const result of done.data ?? []) if (result.op === "update") versions.wrote(result.id, result.version);
23313
- for (const change of changes) if ("record_id" in change && change.record_id) (0, import_core17.announceRecordChanged)(change.record_id);
22800
+ for (const change of changes) if ("record_id" in change && change.record_id) (0, import_core16.announceRecordChanged)(change.record_id);
23314
22801
  return done.data;
23315
22802
  },
23316
22803
  [client, tableId, versions, reload]
@@ -23354,7 +22841,7 @@ function useGridBulk(args) {
23354
22841
  },
23355
22842
  [send, rows, pushUndo2, reload, noun, nounPlural]
23356
22843
  );
23357
- return { busy, refusal: refusal4, clearRefusal: () => setRefusal(null), apply, duplicate, archive };
22844
+ return { busy, refusal: refusal3, clearRefusal: () => setRefusal(null), apply, duplicate, archive };
23358
22845
  }
23359
22846
  function BulkActions({
23360
22847
  ids,
@@ -23475,6 +22962,12 @@ var import_react124 = require("react");
23475
22962
  var import_react125 = require("@ai-matrx/records/react");
23476
22963
  var import_records43 = require("@ai-matrx/records");
23477
22964
  var import_design_system64 = require("@ai-matrx/design-system");
22965
+
22966
+ // src/views.ts
22967
+ var import_views2 = require("@ai-matrx/records/views");
22968
+ var { viewDocument, viewFromRow, declareView, saveViewPatch, viewPatchDocument } = boundViews;
22969
+
22970
+ // src/handOrder.tsx
23478
22971
  var import_jsx_runtime76 = require("react/jsx-runtime");
23479
22972
  function sortArrow(direction) {
23480
22973
  return direction === "asc" ? "\u2191" : "\u2193";
@@ -23842,7 +23335,7 @@ function GridBody({
23842
23335
  const viewSorts = heldOrder?.sorts ?? viewOrder?.sorts ?? [];
23843
23336
  const manual = order === "manual" && viewId !== null;
23844
23337
  const storePaged = merged || tableCard === null && !manual;
23845
- const defaultSort = (0, import_react127.useMemo)(() => defaultSortOf(table.data, fields.data ?? []), [table.data, fields.data]);
23338
+ const defaultSort = (0, import_react127.useMemo)(() => (0, import_first_page3.defaultSortOf)(table.data, fields.data ?? []), [table.data, fields.data]);
23846
23339
  const viewSort = (0, import_react127.useMemo)(() => {
23847
23340
  const first = viewSorts[0];
23848
23341
  if (!first) return null;
@@ -23959,7 +23452,7 @@ function GridBody({
23959
23452
  const seatedSort = seatedOn === openingKey ? query.sort : addressSort.current ?? openingSort;
23960
23453
  const rowGroupKey = merged && !drillState.enabled ? presentation.grouping?.field ?? null : null;
23961
23454
  const pageSort = (0, import_react127.useMemo)(
23962
- () => storePaged ? groupedPageSort(fields.data ?? [], rowGroupKey, pageSortFor(fields.data ?? [], seatedSort)) : [],
23455
+ () => storePaged ? (0, import_first_page6.groupedPageSort)(fields.data ?? [], rowGroupKey, (0, import_first_page2.pageSortFor)(fields.data ?? [], seatedSort)) : [],
23963
23456
  [storePaged, fields.data, seatedSort, rowGroupKey]
23964
23457
  );
23965
23458
  const classicInCard = !merged && tableCard !== null;
@@ -24011,7 +23504,7 @@ function GridBody({
24011
23504
  const seen = new Set(storeRows.map((row) => row.id));
24012
23505
  return [...storeRows, ...appendedRows.filter((row) => !seen.has(row.id))];
24013
23506
  }, [manual, storePaged, hand.rows, storeRows, embeddedMore, appendedRows]);
24014
- const nextEmbeddedPhysicalOffset = query.pageSize + appendedPhysicalPages * EMBEDDED_PAGE_SIZE;
23507
+ const nextEmbeddedPhysicalOffset = query.pageSize + appendedPhysicalPages * import_first_page5.EMBEDDED_PAGE_SIZE;
24015
23508
  const showMoreRows = (0, import_react127.useCallback)(async () => {
24016
23509
  if (appending || !embeddedMore) return;
24017
23510
  const requestAskKey = askKey2;
@@ -24022,7 +23515,7 @@ function GridBody({
24022
23515
  search: pageSearch.trim() === "" ? null : pageSearch.trim(),
24023
23516
  sort: pageSort,
24024
23517
  view_id: pageDoorViewId,
24025
- limit: EMBEDDED_PAGE_SIZE,
23518
+ limit: import_first_page5.EMBEDDED_PAGE_SIZE,
24026
23519
  offset: nextEmbeddedPhysicalOffset
24027
23520
  });
24028
23521
  if (embeddedAskKey.current !== requestAskKey) return;
@@ -24498,7 +23991,7 @@ function GridBody({
24498
23991
  }))
24499
23992
  );
24500
23993
  editing.forget(cells);
24501
- for (const u of updates) (0, import_core18.announceRecordChanged)(u.row.recordId);
23994
+ for (const u of updates) (0, import_core17.announceRecordChanged)(u.row.recordId);
24502
23995
  const lines = updates.length + creates.length;
24503
23996
  undo.push({ label: `Pasted ${lines} ${lines === 1 ? "row" : "rows"}`, cells, created });
24504
23997
  const expected = [
@@ -24778,7 +24271,7 @@ function GridBody({
24778
24271
  const addRowHere = (0, import_react127.useCallback)(async (values) => {
24779
24272
  setAddRefused(null);
24780
24273
  if (formHosted && fields.data) {
24781
- const wouldRefuse = (0, import_core18.predictWriteRefusals)({ fields: fields.data, document: values ?? {} });
24274
+ const wouldRefuse = (0, import_core17.predictWriteRefusals)({ fields: fields.data, document: values ?? {} });
24782
24275
  if (wouldRefuse.length > 0) {
24783
24276
  setFormAsk((held) => ({ n: (held?.n ?? 0) + 1, initial: { ...values ?? {} } }));
24784
24277
  return;
@@ -26026,6 +25519,11 @@ var import_react129 = require("react");
26026
25519
  var import_data_table17 = require("@ai-matrx/design-system/data-table");
26027
25520
  var import_react130 = require("@ai-matrx/records/react");
26028
25521
  var import_react131 = require("@ai-matrx/records/entity/react");
25522
+
25523
+ // src/entityQuery.ts
25524
+ var import_first_page7 = require("@ai-matrx/records/first-page");
25525
+
25526
+ // src/entityTable.tsx
26029
25527
  var import_jsx_runtime78 = require("react/jsx-runtime");
26030
25528
  function EntityDataScope({ children }) {
26031
25529
  const above = (0, import_react131.useOptionalEntityScope)();
@@ -26077,7 +25575,7 @@ function editTypeOf(column) {
26077
25575
  function useEntityTable(token2, options = {}) {
26078
25576
  const type = (0, import_react131.useEntityType)(token2);
26079
25577
  const columns = (0, import_react131.useEntityColumns)(token2);
26080
- const list = (0, import_react131.useEntityList)(token2, entityTableQuery(options));
25578
+ const list = (0, import_react131.useEntityList)(token2, (0, import_first_page7.entityTableQuery)(options));
26081
25579
  const write = (0, import_react131.useEntityWrite)(token2);
26082
25580
  const shown4 = (0, import_react129.useMemo)(() => entityShownColumns(columns.data ?? []), [columns.data]);
26083
25581
  const refused = list.error ?? columns.error ?? type.error;
@@ -26276,7 +25774,7 @@ function ConnectedRecordsTableCard({
26276
25774
  var import_download2 = require("@ai-matrx/kit/download");
26277
25775
  var import_react133 = require("react");
26278
25776
  var import_react134 = require("@ai-matrx/records/react");
26279
- var import_core19 = require("@ai-matrx/records/core");
25777
+ var import_core18 = require("@ai-matrx/records/core");
26280
25778
 
26281
25779
  // src/viewExport.ts
26282
25780
  var import_format6 = require("@ai-matrx/kit/format");
@@ -26293,7 +25791,7 @@ function viewColumns(fields, presentation) {
26293
25791
  function viewPageSorts(fields, sorts) {
26294
25792
  return (sorts ?? []).flatMap((s) => {
26295
25793
  const field2 = fields.find((f) => f.key === s.field);
26296
- return field2 ? [{ field: field2.key, direction: s.direction, as: sortAsFor(field2) }] : [];
25794
+ return field2 ? [{ field: field2.key, direction: s.direction, as: (0, import_first_page2.sortAsFor)(field2) }] : [];
26297
25795
  });
26298
25796
  }
26299
25797
  async function readViewRows(client, tableId, fields, view, ceiling = VIEW_EXPORT_CEILING) {
@@ -26349,7 +25847,7 @@ function toRows(fields, records, labels) {
26349
25847
  absent_reason: envelope?.absent ?? null,
26350
25848
  // A VALUE KEPT AS A FILE carries its pointer, so the export writes the whole text
26351
25849
  // (`withWholeValues`), never the first words passed off as the value.
26352
- source: (0, import_core19.wholeValueOf)(document2, field2.key)
25850
+ source: (0, import_core18.wholeValueOf)(document2, field2.key)
26353
25851
  };
26354
25852
  }
26355
25853
  return row;
@@ -26380,7 +25878,7 @@ async function rowsForFile(args) {
26380
25878
  );
26381
25879
  const lookup = ((field2, id) => labels(field2, id) ?? learned.get(`${field2.id}:${id}`) ?? null);
26382
25880
  const read = host.readFileText;
26383
- return (0, import_core19.withWholeValues)(toRows(all, records, lookup), read ? (fileId) => read({ fileId }) : null);
25881
+ return (0, import_core18.withWholeValues)(toRows(all, records, lookup), read ? (fileId) => read({ fileId }) : null);
26384
25882
  }
26385
25883
  function ExportMenu({ tableId, rows, label, className, view }) {
26386
25884
  const client = (0, import_react134.useRecordsClient)();
@@ -26419,7 +25917,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26419
25917
  {
26420
25918
  size: "sm",
26421
25919
  variant: "outline",
26422
- onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core19.exportCsv)(columns, rows2))).catch(
25920
+ onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core18.exportCsv)(columns, rows2))).catch(
26423
25921
  (thrown) => setFailure((0, refusals_exports.refusalFromThrown)(thrown, "The CSV could not be written.", "Try again in a moment."))
26424
25922
  ),
26425
25923
  children: "CSV"
@@ -26440,7 +25938,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26440
25938
  );
26441
25939
  setFailure(null);
26442
25940
  try {
26443
- exported().then((rows2) => (0, import_core19.exportXlsx)(columns, rows2, name)).then(
25941
+ exported().then((rows2) => (0, import_core18.exportXlsx)(columns, rows2, name)).then(
26444
25942
  (bytes) => download(
26445
25943
  `${name}.xlsx`,
26446
25944
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@@ -26461,7 +25959,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26461
25959
  sourceId: `records:${tableId}`,
26462
25960
  size: "xs",
26463
25961
  json: () => records.map((r) => r.document),
26464
- human: () => (0, import_core19.exportCsv)(columns, toRows(columns, records, labels))
25962
+ human: () => (0, import_core18.exportCsv)(columns, toRows(columns, records, labels))
26465
25963
  }
26466
25964
  ),
26467
25965
  viewHeld && "rows" in viewHeld && viewHeld.cut ? /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "text-xs text-muted-foreground", children: cutWords(viewHeld.rows.length) }) : null,
@@ -26581,7 +26079,7 @@ var import_design_system78 = require("@ai-matrx/design-system");
26581
26079
  // src/TablesHome.tsx
26582
26080
  var import_react147 = require("react");
26583
26081
  var import_react148 = require("@ai-matrx/records/react");
26584
- var import_core20 = require("@ai-matrx/records/core");
26082
+ var import_core19 = require("@ai-matrx/records/core");
26585
26083
  var import_records50 = require("@ai-matrx/records");
26586
26084
  var import_design_system77 = require("@ai-matrx/design-system");
26587
26085
 
@@ -26745,19 +26243,19 @@ function fieldsForNewColumns(columns) {
26745
26243
  let key = (0, import_core2.tokenFor)(column.label) || `column_${i + 1}`;
26746
26244
  while (keys.has(key)) key = `${key}_${i + 1}`;
26747
26245
  keys.add(key);
26748
- const base = { key, label: column.label, sort: (i + 1) * 10, required: false };
26246
+ const base2 = { key, label: column.label, sort: (i + 1) * 10, required: false };
26749
26247
  switch (column.type) {
26750
26248
  case "date":
26751
- return { ...base, type: "datetime", kind: "date" };
26249
+ return { ...base2, type: "datetime", kind: "date" };
26752
26250
  case "datetime":
26753
- return { ...base, type: "datetime", kind: "datetime" };
26251
+ return { ...base2, type: "datetime", kind: "datetime" };
26754
26252
  case "currency":
26755
- return { ...base, type: "currency", unit: "$" };
26253
+ return { ...base2, type: "currency", unit: "$" };
26756
26254
  case "select":
26757
26255
  case "multi_select":
26758
- return { ...base, type: column.type, multi: column.type === "multi_select", options: column.options ?? [] };
26256
+ return { ...base2, type: column.type, multi: column.type === "multi_select", options: column.options ?? [] };
26759
26257
  default:
26760
- return { ...base, type: column.type };
26258
+ return { ...base2, type: column.type };
26761
26259
  }
26762
26260
  });
26763
26261
  }
@@ -27406,15 +26904,15 @@ function objectActionForKey(actions, event) {
27406
26904
  const id = Object.keys(TABLE_ACTION_KEYS).find((k) => TABLE_ACTION_KEYS[k].code === event.code);
27407
26905
  return id ? actions.find((a) => a.id === id) ?? null : null;
27408
26906
  }
27409
- function action(base, needs, input, perform) {
27410
- const chord = TABLE_ACTION_KEYS[base.id];
27411
- if (chord && base.shortcut === void 0) base = { ...base, shortcut: chord.label };
26907
+ function action(base2, needs, input, perform) {
26908
+ const chord = TABLE_ACTION_KEYS[base2.id];
26909
+ if (chord && base2.shortcut === void 0) base2 = { ...base2, shortcut: chord.label };
27412
26910
  const refused = rightsReason(input.rights, needs, input.table);
27413
- if (refused !== null) return { ...base, disabledReason: refused, run: NOOP };
26911
+ if (refused !== null) return { ...base2, disabledReason: refused, run: NOOP };
27414
26912
  if (perform === void 0) {
27415
- return { ...base, disabledReason: input.host.unavailableReasons?.[base.id] ?? ACTION_NOT_HERE_REASON, run: NOOP };
26913
+ return { ...base2, disabledReason: input.host.unavailableReasons?.[base2.id] ?? ACTION_NOT_HERE_REASON, run: NOOP };
27416
26914
  }
27417
- return { ...base, run: perform };
26915
+ return { ...base2, run: perform };
27418
26916
  }
27419
26917
  function bind(handler, table) {
27420
26918
  return handler ? () => handler(table) : void 0;
@@ -27485,9 +26983,9 @@ function tableActions(input) {
27485
26983
  ];
27486
26984
  return withExtensions(built, host.extend ? host.extend(table, input.rights) : []);
27487
26985
  }
27488
- function withExtensions(base, extra) {
27489
- if (extra.length === 0) return [...base];
27490
- const seen = new Set(base.map((a) => a.id));
26986
+ function withExtensions(base2, extra) {
26987
+ if (extra.length === 0) return [...base2];
26988
+ const seen = new Set(base2.map((a) => a.id));
27491
26989
  for (const entry of extra) {
27492
26990
  if (entry.group === "danger") {
27493
26991
  throw new Error(`Object action "${entry.id}": the danger group is closed to extensions.`);
@@ -27502,7 +27000,7 @@ function withExtensions(base, extra) {
27502
27000
  }
27503
27001
  const out = [];
27504
27002
  for (const group of OBJECT_ACTION_GROUPS) {
27505
- out.push(...base.filter((a) => a.group === group.id), ...extra.filter((a) => a.group === group.id));
27003
+ out.push(...base2.filter((a) => a.group === group.id), ...extra.filter((a) => a.group === group.id));
27506
27004
  }
27507
27005
  return out;
27508
27006
  }
@@ -27708,7 +27206,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
27708
27206
  const [things, setThings] = (0, import_react141.useState)(null);
27709
27207
  const [error, setError] = (0, import_react141.useState)(null);
27710
27208
  const [restoring, setRestoring] = (0, import_react141.useState)(null);
27711
- const [refusal4, setRefusal] = (0, import_react141.useState)(null);
27209
+ const [refusal3, setRefusal] = (0, import_react141.useState)(null);
27712
27210
  const [said2, setSaid] = (0, import_react141.useState)(null);
27713
27211
  const read = (0, import_react141.useCallback)(async () => {
27714
27212
  const [forms, checklists] = await Promise.all([
@@ -27761,7 +27259,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
27761
27259
  " \xB7 archived ",
27762
27260
  (0, import_records47.archivedWhen)(thing.archivedAt)
27763
27261
  ] }),
27764
- refusal4 && refusal4.id === thing.id ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(RefusalNotice, { error: refusal4.error, className: "mt-2" }) : null
27262
+ refusal3 && refusal3.id === thing.id ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
27765
27263
  ] }),
27766
27264
  thing.whyNot ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { className: "text-xs text-muted-foreground", children: thing.whyNot }) : /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
27767
27265
  import_design_system74.Button,
@@ -28318,7 +27816,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
28318
27816
  };
28319
27817
  }, [client]);
28320
27818
  const listed = facts.phase === "read" ? (0, import_records50.withTablePlacement)(
28321
- (0, import_core20.withTableFacts)(tables.data ?? [], facts.rows, me),
27819
+ (0, import_core19.withTableFacts)(tables.data ?? [], facts.rows, me),
28322
27820
  facts.rows
28323
27821
  ) : tables.data ?? [];
28324
27822
  const [showEverything, setShowEverything] = (0, import_react147.useState)(false);
@@ -28605,20 +28103,20 @@ function draftsFor(headers, rows) {
28605
28103
  function keysFor(labels) {
28606
28104
  const used = /* @__PURE__ */ new Set();
28607
28105
  return labels.map((label, i) => {
28608
- const base = (0, import_core2.tokenFor)(label) === "table" && !/table/i.test(label) ? `column_${i + 1}` : (0, import_core2.tokenFor)(label);
28609
- let key = base;
28106
+ const base2 = (0, import_core2.tokenFor)(label) === "table" && !/table/i.test(label) ? `column_${i + 1}` : (0, import_core2.tokenFor)(label);
28107
+ let key = base2;
28610
28108
  let n = 2;
28611
- while (used.has(key)) key = `${base}_${n++}`;
28109
+ while (used.has(key)) key = `${base2}_${n++}`;
28612
28110
  used.add(key);
28613
28111
  return key;
28614
28112
  });
28615
28113
  }
28616
28114
  function freeName(name, taken) {
28617
28115
  const lower = new Set(taken.map((t) => t.trim().toLowerCase()));
28618
- const base = name.trim() || "Saved table";
28619
- if (!lower.has(base.toLowerCase())) return base;
28620
- for (let n = 2; n < 100; n += 1) if (!lower.has(`${base} ${n}`.toLowerCase())) return `${base} ${n}`;
28621
- return `${base} ${Date.now()}`;
28116
+ const base2 = name.trim() || "Saved table";
28117
+ if (!lower.has(base2.toLowerCase())) return base2;
28118
+ for (let n = 2; n < 100; n += 1) if (!lower.has(`${base2} ${n}`.toLowerCase())) return `${base2} ${n}`;
28119
+ return `${base2} ${Date.now()}`;
28622
28120
  }
28623
28121
  async function sha256Text(text) {
28624
28122
  const subtle = globalThis.crypto?.subtle;
@@ -29522,11 +29020,11 @@ var import_design_system86 = require("@ai-matrx/design-system");
29522
29020
  var TableRestoreRefused = class extends Error {
29523
29021
  refusal;
29524
29022
  sentence;
29525
- constructor(refusal4) {
29526
- const sentence2 = refusalSentence(refusal4);
29023
+ constructor(refusal3) {
29024
+ const sentence2 = refusalSentence(refusal3);
29527
29025
  super(sentence2);
29528
29026
  this.name = "TableRestoreRefused";
29529
- this.refusal = refusal4;
29027
+ this.refusal = refusal3;
29530
29028
  this.sentence = sentence2;
29531
29029
  }
29532
29030
  };
@@ -31032,6 +30530,22 @@ function usePlatformTable(spec) {
31032
30530
  return state;
31033
30531
  }
31034
30532
 
30533
+ // src/viewLook.ts
30534
+ var import_views3 = require("@ai-matrx/records/views");
30535
+ var { lookDocument, lookFromDocument, readLooks, keepLook } = boundViews;
30536
+ var LOOK_WORDS = {
30537
+ /** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
30538
+ yours: "You changed how this view looks. Only you see it.",
30539
+ /** The visible label for the same fact. */
30540
+ yoursLabel: "Only you see this",
30541
+ saveToView: "Save to view",
30542
+ saveAsNew: "Save as new view",
30543
+ reset: "Reset to view",
30544
+ /** The one button your look's doors fold into when the toolbar row has no room for three. */
30545
+ folded: "Your look",
30546
+ newName: "Name for the new view"
30547
+ };
30548
+
31035
30549
  // src/ViewSwitcher.tsx
31036
30550
  var import_react196 = require("react");
31037
30551
  var import_react197 = require("@ai-matrx/records/react");
@@ -31290,13 +30804,13 @@ function recordLink(tableId, recordId, origin = DEFAULT_ACTION_ORIGIN) {
31290
30804
  }
31291
30805
  var NOOP2 = () => {
31292
30806
  };
31293
- function action2(base, needs, input, perform) {
30807
+ function action2(base2, needs, input, perform) {
31294
30808
  const refused = rightsReason(input.rights, needs);
31295
- if (refused !== null) return { ...base, disabledReason: refused, run: NOOP2 };
30809
+ if (refused !== null) return { ...base2, disabledReason: refused, run: NOOP2 };
31296
30810
  if (perform === void 0) {
31297
- return { ...base, disabledReason: input.host.unavailableReasons?.[base.id] ?? ACTION_NOT_HERE_REASON, run: NOOP2 };
30811
+ return { ...base2, disabledReason: input.host.unavailableReasons?.[base2.id] ?? ACTION_NOT_HERE_REASON, run: NOOP2 };
31298
30812
  }
31299
- return { ...base, run: perform };
30813
+ return { ...base2, run: perform };
31300
30814
  }
31301
30815
  function bind2(handler, record) {
31302
30816
  return handler ? () => handler(record) : void 0;
@@ -33885,7 +33399,7 @@ function TimelineView({
33885
33399
  ] });
33886
33400
  if (!startField) {
33887
33401
  return /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: (0, import_design_system95.cn)("flex min-w-0 flex-col gap-2", className), "data-timeline-needs": "", children: /* @__PURE__ */ (0, import_jsx_runtime111.jsxs)("div", { className: "flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground", children: [
33888
- /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("p", { children: dates.length > 0 ? VIEW_NEEDS.timeline?.pick : VIEW_NEEDS.timeline?.missing }),
33402
+ /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("p", { children: dates.length > 0 ? import_views2.VIEW_NEEDS.timeline?.pick : import_views2.VIEW_NEEDS.timeline?.missing }),
33889
33403
  dates.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "flex flex-wrap gap-2", children: settings }) : null
33890
33404
  ] }) });
33891
33405
  }
@@ -34060,15 +33574,15 @@ var import_react192 = require("@ai-matrx/records/react");
34060
33574
  var import_design_system96 = require("@ai-matrx/design-system");
34061
33575
  var import_jsx_runtime112 = require("react/jsx-runtime");
34062
33576
  function viewNeedFor(layout) {
34063
- return VIEW_NEEDS[layout];
33577
+ return import_views2.VIEW_NEEDS[layout];
34064
33578
  }
34065
33579
  function columnDeclarationFor(need, label, options, fields) {
34066
- const base = { label: label.trim(), sort: nextFieldSort(fields) };
33580
+ const base2 = { label: label.trim(), sort: nextFieldSort(fields) };
34067
33581
  if (need.starter.type === "select") {
34068
- return { ...base, parity_type: "select", options: options.map((o) => o.trim()).filter((o) => o !== "") };
33582
+ return { ...base2, parity_type: "select", options: options.map((o) => o.trim()).filter((o) => o !== "") };
34069
33583
  }
34070
- if (need.starter.type === "datetime") return { ...base, parity_type: "datetime", kind: "date" };
34071
- return { ...base, parity_type: "attachment" };
33584
+ if (need.starter.type === "datetime") return { ...base2, parity_type: "datetime", kind: "date" };
33585
+ return { ...base2, parity_type: "attachment" };
34072
33586
  }
34073
33587
  var askedFor = /* @__PURE__ */ new Map();
34074
33588
  var askKey = (tableId, layout) => `${tableId}:${layout}`;
@@ -34091,7 +33605,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
34091
33605
  const mutation = (0, import_react192.useFieldMutation)();
34092
33606
  const client = (0, import_react192.useRecordsClient)();
34093
33607
  const taken = fields.map((f) => fieldName(f));
34094
- const [label, setLabel] = (0, import_react191.useState)(() => freeColumnName(need?.starter.label ?? "", taken));
33608
+ const [label, setLabel] = (0, import_react191.useState)(() => (0, import_views2.freeColumnName)(need?.starter.label ?? "", taken));
34095
33609
  const [options, setOptions] = (0, import_react191.useState)(() => [...need?.starter.options ?? []]);
34096
33610
  const [refused, setRefused] = (0, import_react191.useState)(null);
34097
33611
  const [pendingId, setPendingId] = (0, import_react191.useState)(null);
@@ -34558,7 +34072,7 @@ function ViewSwitcher({
34558
34072
  newRowLabel,
34559
34073
  className
34560
34074
  }) {
34561
- const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 200);
34075
+ const pageSize = pageSizeAsked ?? (embedded ? import_first_page5.EMBEDDED_PAGE_SIZE : 200);
34562
34076
  const [layout, setLayout] = (0, import_react196.useState)(view.layout);
34563
34077
  const [local, setLocal] = (0, import_react196.useState)({});
34564
34078
  (0, import_react196.useEffect)(() => {
@@ -34577,14 +34091,14 @@ function ViewSwitcher({
34577
34091
  return /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("div", { className: (0, import_design_system98.cn)("flex min-h-0 flex-col gap-2", footer === "sticky" && "flex-1", className), children: [
34578
34092
  chooser && !embedded ? /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("div", { className: "flex items-center gap-2", children: [
34579
34093
  /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("span", { className: "truncate text-sm font-medium", children: view.name }),
34580
- /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("div", { className: "ml-auto flex items-center gap-0.5", role: "group", "aria-label": "Layout", children: VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
34094
+ /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("div", { className: "ml-auto flex items-center gap-0.5", role: "group", "aria-label": "Layout", children: import_views2.VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime115.jsx)(
34581
34095
  import_design_system98.Button,
34582
34096
  {
34583
34097
  size: "sm",
34584
34098
  variant: option === layout ? "secondary" : "ghost",
34585
34099
  "aria-pressed": option === layout,
34586
34100
  onClick: () => pick(option),
34587
- children: LAYOUT_LABEL[option]
34101
+ children: import_views2.LAYOUT_LABEL[option]
34588
34102
  },
34589
34103
  option
34590
34104
  )) })
@@ -34948,10 +34462,10 @@ function Board({
34948
34462
  ...view.endField ? { endKey: view.endField } : {},
34949
34463
  groupKey: view.groupField ?? null,
34950
34464
  ...view.presentation?.style?.colorBy !== void 0 ? { colorKey: view.presentation.style.colorBy?.field ?? null } : {},
34951
- layoutKept: remembered && STORE_KEEPS_TIMELINE,
34465
+ layoutKept: remembered && import_views2.STORE_KEEPS_TIMELINE,
34952
34466
  onSettingsChange: (patch) => {
34953
34467
  if (patch.startKey !== void 0) {
34954
- onChange({ startField: patch.startKey, ...STORE_KEEPS_TIMELINE ? {} : { dateField: patch.startKey } });
34468
+ onChange({ startField: patch.startKey, ...import_views2.STORE_KEEPS_TIMELINE ? {} : { dateField: patch.startKey } });
34955
34469
  }
34956
34470
  if (patch.endKey !== void 0) onChange({ endField: patch.endKey });
34957
34471
  if (patch.groupKey !== void 0) onChange({ groupField: patch.groupKey });
@@ -35052,7 +34566,7 @@ function FieldPicker({
35052
34566
  onPick,
35053
34567
  placing
35054
34568
  }) {
35055
- const want = LAYOUT_FIELD_KIND[layout];
34569
+ const want = import_views2.LAYOUT_FIELD_KIND[layout];
35056
34570
  const offerable = want ? offerableFields(all, want, placing) : [];
35057
34571
  const chosenField = chosen ? all.find((field2) => field2.key === chosen) : void 0;
35058
34572
  const unusual = chosenField && !offerable.some((field2) => field2.key === chosenField.key) ? chosenField : void 0;
@@ -35081,7 +34595,7 @@ function FieldPicker({
35081
34595
  }
35082
34596
  function Pick({ layout, picker }) {
35083
34597
  return /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("div", { className: "flex flex-col gap-2 rounded border border-dashed p-4 text-xs text-muted-foreground", children: [
35084
- /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("p", { children: VIEW_NEEDS[layout]?.pick }),
34598
+ /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("p", { children: import_views2.VIEW_NEEDS[layout]?.pick }),
35085
34599
  picker
35086
34600
  ] });
35087
34601
  }
@@ -35544,7 +35058,7 @@ function ArchivedView({
35544
35058
  const [loading, setLoading] = (0, import_react198.useState)(true);
35545
35059
  const [error, setError] = (0, import_react198.useState)(null);
35546
35060
  const [restoring, setRestoring] = (0, import_react198.useState)(null);
35547
- const [refusal4, setRefusal] = (0, import_react198.useState)(null);
35061
+ const [refusal3, setRefusal] = (0, import_react198.useState)(null);
35548
35062
  (0, import_react198.useEffect)(() => {
35549
35063
  if (laneFromHost) setLane(laneFromHost);
35550
35064
  }, [laneFromHost]);
@@ -35621,7 +35135,7 @@ function ArchivedView({
35621
35135
  /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
35622
35136
  /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("span", { className: "truncate text-sm", children: recordName(row.document, titleKey) }),
35623
35137
  /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("span", { className: "truncate text-xs text-muted-foreground", "data-testid": "archived-who", children: (0, import_records57.archivedByLine)(row) }),
35624
- refusal4 && refusal4.recordId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(RefusalNotice, { error: refusal4.error, className: "mt-2" }) : null
35138
+ refusal3 && refusal3.recordId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
35625
35139
  ] }),
35626
35140
  mayRestore ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
35627
35141
  import_design_system99.Button,
@@ -35650,7 +35164,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35650
35164
  const [rows, setRows] = (0, import_react198.useState)(null);
35651
35165
  const [error, setError] = (0, import_react198.useState)(null);
35652
35166
  const [restoring, setRestoring] = (0, import_react198.useState)(null);
35653
- const [refusal4, setRefusal] = (0, import_react198.useState)(null);
35167
+ const [refusal3, setRefusal] = (0, import_react198.useState)(null);
35654
35168
  const read = (0, import_react198.useCallback)(async () => {
35655
35169
  const answer = await client.fieldsRetired({ table_id: tableId });
35656
35170
  if (answer.ok) {
@@ -35694,7 +35208,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35694
35208
  /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
35695
35209
  /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("span", { className: "truncate text-sm", children: name }),
35696
35210
  /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: retiredColumnLine(row) }),
35697
- refusal4 && refusal4.fieldId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(RefusalNotice, { error: refusal4.error, className: "mt-2" }) : null
35211
+ refusal3 && refusal3.fieldId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
35698
35212
  ] }),
35699
35213
  mayRestore ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(import_design_system99.Button, { size: "sm", variant: "outline", disabled: restoring === row.id, onClick: () => void restore(row.id), children: restoring === row.id ? "Bringing it back\u2026" : "Restore" }) : null
35700
35214
  ]
@@ -35759,7 +35273,7 @@ function ArchivedPortals({
35759
35273
  const [confirming, setConfirming] = (0, import_react200.useState)(null);
35760
35274
  const [typed2, setTyped] = (0, import_react200.useState)("");
35761
35275
  const [restoring, setRestoring] = (0, import_react200.useState)(null);
35762
- const [refusal4, setRefusal] = (0, import_react200.useState)(null);
35276
+ const [refusal3, setRefusal] = (0, import_react200.useState)(null);
35763
35277
  const [said2, setSaid] = (0, import_react200.useState)(null);
35764
35278
  const read = (0, import_react200.useCallback)(async () => {
35765
35279
  const answered = await client.listPortals({ archived: "archived" });
@@ -35875,7 +35389,7 @@ function ArchivedPortals({
35875
35389
  )
35876
35390
  ] })
35877
35391
  ] }) : null,
35878
- refusal4 && refusal4.portalId === portal.portal_id ? /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(RefusalNotice, { error: refusal4.error }) : null
35392
+ refusal3 && refusal3.portalId === portal.portal_id ? /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(RefusalNotice, { error: refusal3.error }) : null
35879
35393
  ]
35880
35394
  },
35881
35395
  portal.portal_id
@@ -35909,10 +35423,10 @@ var import_react205 = require("@ai-matrx/records/react");
35909
35423
  var NOOP3 = () => {
35910
35424
  };
35911
35425
  function viewActions(whyNot, host) {
35912
- const one = (base, run) => {
35913
- if (whyNot !== null) return { ...base, disabledReason: whyNot, run: NOOP3 };
35914
- if (!run) return { ...base, disabledReason: ACTION_NOT_HERE_REASON, run: NOOP3 };
35915
- return { ...base, run };
35426
+ const one = (base2, run) => {
35427
+ if (whyNot !== null) return { ...base2, disabledReason: whyNot, run: NOOP3 };
35428
+ if (!run) return { ...base2, disabledReason: ACTION_NOT_HERE_REASON, run: NOOP3 };
35429
+ return { ...base2, run };
35916
35430
  };
35917
35431
  return [
35918
35432
  one({ id: "rename", label: "Rename view\u2026", icon: "pencil", group: "organize", verb: "rename" }, host.rename),
@@ -35924,8 +35438,8 @@ function viewActions(whyNot, host) {
35924
35438
  ];
35925
35439
  }
35926
35440
  function copyName(name, taken) {
35927
- const base = `${name} (copy)`;
35928
- if (!taken.includes(base)) return base;
35441
+ const base2 = `${name} (copy)`;
35442
+ if (!taken.includes(base2)) return base2;
35929
35443
  for (let n = 2; ; n += 1) {
35930
35444
  const next = `${name} (copy ${n})`;
35931
35445
  if (!taken.includes(next)) return next;
@@ -35951,7 +35465,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
35951
35465
  const [unavailable, setUnavailable] = (0, import_react203.useState)(false);
35952
35466
  const [active, setActive] = (0, import_react203.useState)(() => {
35953
35467
  if (!initialViews || initialViews.length === 0) return activeViewId ?? null;
35954
- return (initialViews.find((v) => v.id === activeViewId) ?? defaultViewOf(initialViews) ?? initialViews[0]).id;
35468
+ return (initialViews.find((v) => v.id === activeViewId) ?? (0, import_views2.defaultViewOf)(initialViews) ?? initialViews[0]).id;
35955
35469
  });
35956
35470
  const readOnMount = (0, import_react203.useRef)(initialViews === void 0);
35957
35471
  const [naming, setNaming] = (0, import_react203.useState)(false);
@@ -36008,7 +35522,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
36008
35522
  }, [load]);
36009
35523
  (0, import_react203.useEffect)(() => {
36010
35524
  if (!views || views.length === 0) return;
36011
- const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? defaultViewOf(views) ?? views[0];
35525
+ const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? (0, import_views2.defaultViewOf)(views) ?? views[0];
36012
35526
  if (chosen.id !== active) setActive(chosen.id);
36013
35527
  onActiveView?.(chosen);
36014
35528
  }, [views, activeViewId]);
@@ -36697,7 +36211,7 @@ function MyChecklistSteps({
36697
36211
  }, [held, onSteps]);
36698
36212
  const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
36699
36213
  const [busy, setBusy] = (0, import_react208.useState)(null);
36700
- const [refusal4, setRefusal] = (0, import_react208.useState)(null);
36214
+ const [refusal3, setRefusal] = (0, import_react208.useState)(null);
36701
36215
  const complete = (0, import_react208.useCallback)(
36702
36216
  async (step2, evidence) => {
36703
36217
  setBusy(step2.step_id);
@@ -36720,7 +36234,7 @@ function MyChecklistSteps({
36720
36234
  /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("span", { className: "tabular-nums", children: steps.length })
36721
36235
  ] }),
36722
36236
  error ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(RefusalNotice, { error }) : null,
36723
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(RefusalNotice, { error: refusal4 }) : null,
36237
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(RefusalNotice, { error: refusal3 }) : null,
36724
36238
  /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("ol", { className: "flex flex-col gap-1.5", children: steps.map(
36725
36239
  (step2) => actions ? /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("div", { className: "flex flex-col gap-0.5", "data-step-row": step2.step_id, children: [
36726
36240
  /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(StepRow, { step: step2, busy: busy === step2.step_id, onComplete: (evidence) => void complete(step2, evidence) }),
@@ -36920,7 +36434,7 @@ function ChecklistTemplateEditor({
36920
36434
  const [saved, setSaved] = (0, import_react208.useState)(false);
36921
36435
  const [name, setName] = (0, import_react208.useState)("");
36922
36436
  const [rows, setRows] = (0, import_react208.useState)([{ ...EMPTY_ROW }]);
36923
- const [refusal4, setRefusal] = (0, import_react208.useState)(null);
36437
+ const [refusal3, setRefusal] = (0, import_react208.useState)(null);
36924
36438
  const [error, setError] = (0, import_react208.useState)(null);
36925
36439
  const [busy, setBusy] = (0, import_react208.useState)(false);
36926
36440
  const [loading, setLoading] = (0, import_react208.useState)(Boolean(templateId));
@@ -37096,10 +36610,10 @@ function ChecklistTemplateEditor({
37096
36610
  ] }, index)) }),
37097
36611
  /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("div", { className: "flex items-center gap-1.5", children: [
37098
36612
  /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(import_design_system103.Button, { size: "sm", variant: "outline", onClick: () => setRows((held) => [...held, { ...EMPTY_ROW }]), children: "Add a step" }),
37099
- /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(import_design_system103.Button, { size: "sm", disabled: busy || refusal4 !== null || spec.steps.length === 0, onClick: () => void save(), children: busy ? "\u2026" : "Save" }),
36613
+ /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(import_design_system103.Button, { size: "sm", disabled: busy || refusal3 !== null || spec.steps.length === 0, onClick: () => void save(), children: busy ? "\u2026" : "Save" }),
37100
36614
  saved && !busy ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("span", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-saved", role: "status", children: "Saved" }) : null
37101
36615
  ] }),
37102
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-refusal", children: refusal4 }) : null
36616
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-refusal", children: refusal3 }) : null
37103
36617
  ] });
37104
36618
  }
37105
36619
  function toStepSpec(row, index) {
@@ -38682,7 +38196,7 @@ var import_design_system110 = require("@ai-matrx/design-system");
38682
38196
  var import_react223 = require("react");
38683
38197
  var import_recharts = require("recharts");
38684
38198
  var import_records59 = require("@ai-matrx/records");
38685
- var import_core21 = require("@ai-matrx/records/core");
38199
+ var import_core20 = require("@ai-matrx/records/core");
38686
38200
  var import_design_system109 = require("@ai-matrx/design-system");
38687
38201
  var import_format11 = require("@ai-matrx/kit/format");
38688
38202
 
@@ -39144,7 +38658,7 @@ function pretty(n) {
39144
38658
  return Number.isInteger(n) ? n.toLocaleString() : n.toLocaleString(void 0, { maximumFractionDigits: 2 });
39145
38659
  }
39146
38660
  function asRefusal2(block) {
39147
- return (0, import_core21.mapPgError)(
38661
+ return (0, import_core20.mapPgError)(
39148
38662
  {
39149
38663
  message: block.refused ?? "",
39150
38664
  ...block.sqlstate ? { code: block.sqlstate } : {}
@@ -42015,7 +41529,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
42015
41529
  var import_clipboard9 = require("@ai-matrx/kit/clipboard");
42016
41530
  var import_design_system121 = require("@ai-matrx/design-system");
42017
41531
  var import_react241 = require("react");
42018
- var import_core22 = require("@dnd-kit/core");
41532
+ var import_core21 = require("@dnd-kit/core");
42019
41533
  var import_sortable = require("@dnd-kit/sortable");
42020
41534
  var import_utilities = require("@dnd-kit/utilities");
42021
41535
  var import_react242 = require("@ai-matrx/records/react");
@@ -42376,7 +41890,7 @@ function FormStage({
42376
41890
  const [answers, setAnswers] = (0, import_react239.useState)(() => ({ ...initialAnswers ?? {} }));
42377
41891
  const [at, setAt] = (0, import_react239.useState)(0);
42378
41892
  const [error, setError] = (0, import_react239.useState)(null);
42379
- const [refusal4, setRefusal] = (0, import_react239.useState)(null);
41893
+ const [refusal3, setRefusal] = (0, import_react239.useState)(null);
42380
41894
  const [writing, setWriting] = (0, import_react239.useState)(false);
42381
41895
  const [done, setDone] = (0, import_react239.useState)(null);
42382
41896
  const [hidden, setHidden] = (0, import_react239.useState)({});
@@ -42749,10 +42263,10 @@ function FormStage({
42749
42263
  ) : null,
42750
42264
  form.intro && index === 0 ? /* @__PURE__ */ (0, import_jsx_runtime137.jsx)("p", { className: "text-base text-muted-foreground", children: authored(host, form.intro, "form-intro") }) : null,
42751
42265
  error ? /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(RefusalNotice, { error, className: "text-left" }) : null,
42752
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(
42266
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(
42753
42267
  RefusalNotice,
42754
42268
  {
42755
- error: refusal4,
42269
+ error: refusal3,
42756
42270
  className: "text-left",
42757
42271
  onKeepEditing: () => {
42758
42272
  setRefusal(null);
@@ -42941,11 +42455,11 @@ function Question({
42941
42455
  // src/FormBuilder.tsx
42942
42456
  var import_forms3 = require("@ai-matrx/records/forms");
42943
42457
  var import_jsx_runtime138 = require("react/jsx-runtime");
42944
- function freshFormName(base, taken) {
42458
+ function freshFormName(base2, taken) {
42945
42459
  const names = new Set(taken.map((n) => n.trim().toLowerCase()));
42946
- if (!names.has(base.toLowerCase())) return base;
42460
+ if (!names.has(base2.toLowerCase())) return base2;
42947
42461
  for (let n = 2; ; n += 1) {
42948
- const next = `${base} ${n}`;
42462
+ const next = `${base2} ${n}`;
42949
42463
  if (!names.has(next.toLowerCase())) return next;
42950
42464
  }
42951
42465
  }
@@ -43242,8 +42756,8 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
43242
42756
  return;
43243
42757
  }
43244
42758
  setMakeOnMount("making");
43245
- const base = table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form";
43246
- void create(freshFormName(base, forms.map((f) => f.name))).then(
42759
+ const base2 = table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form";
42760
+ void create(freshFormName(base2, forms.map((f) => f.name))).then(
43247
42761
  (made) => setMakeOnMount(made ? "made" : "not-made")
43248
42762
  );
43249
42763
  }, [createOnMount, makeOnMount, forms, fields.data, create, table.data, table.error]);
@@ -43648,9 +43162,9 @@ function QuestionList({
43648
43162
  onQuestions,
43649
43163
  onQuestion
43650
43164
  }) {
43651
- const sensors = (0, import_core22.useSensors)(
43652
- (0, import_core22.useSensor)(import_core22.PointerSensor, { activationConstraint: { distance: 4 } }),
43653
- (0, import_core22.useSensor)(import_core22.KeyboardSensor, { coordinateGetter: import_sortable.sortableKeyboardCoordinates })
43165
+ const sensors = (0, import_core21.useSensors)(
43166
+ (0, import_core21.useSensor)(import_core21.PointerSensor, { activationConstraint: { distance: 4 } }),
43167
+ (0, import_core21.useSensor)(import_core21.KeyboardSensor, { coordinateGetter: import_sortable.sortableKeyboardCoordinates })
43654
43168
  );
43655
43169
  const askable = askableFields([...fields]);
43656
43170
  const unasked = askable.filter((f) => !draft.questions.some((q) => q.field === f.key));
@@ -43672,7 +43186,7 @@ function QuestionList({
43672
43186
  /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("span", { className: "font-medium text-foreground", children: "Questions" }),
43673
43187
  /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("span", { className: "tabular-nums", children: draft.questions.length })
43674
43188
  ] }),
43675
- /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_core22.DndContext, { sensors, collisionDetection: import_core22.closestCenter, onDragEnd: dragEnd, children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_sortable.SortableContext, { items: draft.questions.map((q) => q.field), strategy: import_sortable.verticalListSortingStrategy, children: draft.questions.map((question, index) => /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(
43189
+ /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_core21.DndContext, { sensors, collisionDetection: import_core21.closestCenter, onDragEnd: dragEnd, children: /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_sortable.SortableContext, { items: draft.questions.map((q) => q.field), strategy: import_sortable.verticalListSortingStrategy, children: draft.questions.map((question, index) => /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(
43676
43190
  QuestionRow,
43677
43191
  {
43678
43192
  index,
@@ -44668,7 +44182,7 @@ var import_react259 = require("@ai-matrx/records/react");
44668
44182
  var import_design_system130 = require("@ai-matrx/design-system");
44669
44183
 
44670
44184
  // src/DashboardGrid.tsx
44671
- var import_core23 = require("@dnd-kit/core");
44185
+ var import_core22 = require("@dnd-kit/core");
44672
44186
  var import_sortable2 = require("@dnd-kit/sortable");
44673
44187
  var import_utilities2 = require("@dnd-kit/utilities");
44674
44188
  var import_design_system127 = require("@ai-matrx/design-system");
@@ -44724,7 +44238,7 @@ function withBlockIds(blocks) {
44724
44238
  // src/DashboardGrid.tsx
44725
44239
  var import_jsx_runtime143 = require("react/jsx-runtime");
44726
44240
  var dashboardCollision = (args) => {
44727
- const under = (0, import_core23.pointerWithin)(args);
44241
+ const under = (0, import_core22.pointerWithin)(args);
44728
44242
  if (under.length > 0) return under;
44729
44243
  const at = args.collisionRect;
44730
44244
  return args.droppableContainers.flatMap((container) => {
@@ -44734,9 +44248,9 @@ var dashboardCollision = (args) => {
44734
44248
  }).sort((a, b) => a.data.value - b.data.value);
44735
44249
  };
44736
44250
  function DashboardGrid({ items, arranging, onMove, onSpan }) {
44737
- const sensors = (0, import_core23.useSensors)(
44738
- (0, import_core23.useSensor)(import_core23.PointerSensor, { activationConstraint: { distance: 4 } }),
44739
- (0, import_core23.useSensor)(import_core23.KeyboardSensor, { coordinateGetter: import_sortable2.sortableKeyboardCoordinates })
44251
+ const sensors = (0, import_core22.useSensors)(
44252
+ (0, import_core22.useSensor)(import_core22.PointerSensor, { activationConstraint: { distance: 4 } }),
44253
+ (0, import_core22.useSensor)(import_core22.KeyboardSensor, { coordinateGetter: import_sortable2.sortableKeyboardCoordinates })
44740
44254
  );
44741
44255
  const ids = items.map((item) => item.id);
44742
44256
  function dragEnd(event) {
@@ -44746,7 +44260,7 @@ function DashboardGrid({ items, arranging, onMove, onSpan }) {
44746
44260
  }
44747
44261
  const grid = /* @__PURE__ */ (0, import_jsx_runtime143.jsx)("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-12", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(GridCell2, { item, index, arranging, onSpan }, item.id)) });
44748
44262
  if (!arranging) return grid;
44749
- return /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_core23.DndContext, { sensors, collisionDetection: dashboardCollision, onDragEnd: dragEnd, children: /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_sortable2.SortableContext, { items: ids, strategy: import_sortable2.rectSortingStrategy, children: grid }) });
44263
+ return /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_core22.DndContext, { sensors, collisionDetection: dashboardCollision, onDragEnd: dragEnd, children: /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_sortable2.SortableContext, { items: ids, strategy: import_sortable2.rectSortingStrategy, children: grid }) });
44750
44264
  }
44751
44265
  function GridCell2({
44752
44266
  item,
@@ -45173,7 +44687,7 @@ function AddChart({ subject, onAdd, onClose }) {
45173
44687
  const field2 = all.find((f) => f.key === key);
45174
44688
  return field2 ? scalarText(field2, value, labels) : String(value);
45175
44689
  };
45176
- const [measureKey5, setMeasureKey] = (0, import_react256.useState)("count");
44690
+ const [measureKey4, setMeasureKey] = (0, import_react256.useState)("count");
45177
44691
  const [splitKey, setSplitKey] = (0, import_react256.useState)("none");
45178
44692
  const [kind, setKind] = (0, import_react256.useState)("auto");
45179
44693
  const [filter, setFilter] = (0, import_react256.useState)({});
@@ -45181,7 +44695,7 @@ function AddChart({ subject, onAdd, onClose }) {
45181
44695
  const numbers = numberColumns(all);
45182
44696
  const choices = offerableFields(all, "choice");
45183
44697
  const dates = offerableFields(all, "date");
45184
- const measure = measureKey5 === "count" ? { op: "count" } : { op: measureKey5.split(":")[0], key: measureKey5.split(":")[1] };
44698
+ const measure = measureKey4 === "count" ? { op: "count" } : { op: measureKey4.split(":")[0], key: measureKey4.split(":")[1] };
45185
44699
  const split = splitKey === "none" ? { kind: "none" } : splitKey.startsWith("period:") ? { kind: "period", key: splitKey.split(":")[2], by: splitKey.split(":")[1] } : { kind: "column", key: splitKey.slice("column:".length) };
45186
44700
  const shape = kind !== "auto" ? kind : split.kind === "period" ? "line" : split.kind === "column" ? "column" : "number";
45187
44701
  function pickTable(next) {
@@ -45199,7 +44713,7 @@ function AddChart({ subject, onAdd, onClose }) {
45199
44713
  return /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)("div", { className: "flex flex-col gap-2 rounded border p-2 text-xs", role: "group", "aria-label": "Add chart", children: [
45200
44714
  /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
45201
44715
  /* @__PURE__ */ (0, import_jsx_runtime146.jsx)("div", { className: "min-w-[12rem]", children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(TablePicker, { dataSource: client.config.dataSource, value: tableId, onChange: pickTable }) }),
45202
- /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_design_system129.Select, { value: measureKey5, onValueChange: setMeasureKey, children: [
44716
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_design_system129.Select, { value: measureKey4, onValueChange: setMeasureKey, children: [
45203
44717
  /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(import_design_system129.SelectTrigger, { size: "sm", "aria-label": "What the chart counts", className: "h-7 min-w-[8rem] text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(import_design_system129.SelectValue, {}) }),
45204
44718
  /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_design_system129.SelectContent, { children: [
45205
44719
  /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(import_design_system129.SelectItem, { value: "count", children: "How many" }),
@@ -45295,14 +44809,14 @@ function filterTargets(filter, blocks) {
45295
44809
  if (filter.targets && filter.targets.length > 0) return filter.targets;
45296
44810
  return blocks.filter((b) => b.kind === "list" && b.table_id === filter.table_id).map((b) => b.id);
45297
44811
  }
45298
- function combineFilter(base, extra, fieldIdOf) {
44812
+ function combineFilter(base2, extra, fieldIdOf) {
45299
44813
  const extraKeys = Object.keys(extra);
45300
- if (!base || !(0, import_records65.isRuleFilter)(base) && Object.keys(base).length === 0) {
44814
+ if (!base2 || !(0, import_records65.isRuleFilter)(base2) && Object.keys(base2).length === 0) {
45301
44815
  return { filter: extraKeys.length > 0 ? { ...extra } : null, dropped: [] };
45302
44816
  }
45303
- if (!(0, import_records65.isRuleFilter)(base)) return { filter: { ...base, ...extra }, dropped: [] };
44817
+ if (!(0, import_records65.isRuleFilter)(base2)) return { filter: { ...base2, ...extra }, dropped: [] };
45304
44818
  const dropped = [];
45305
- let rule = base;
44819
+ let rule = base2;
45306
44820
  for (const key of extraKeys) {
45307
44821
  const id = fieldIdOf(key);
45308
44822
  if (!id) {
@@ -45958,372 +45472,8 @@ var import_design_system131 = require("@ai-matrx/design-system");
45958
45472
  var import_react261 = require("@ai-matrx/records/react");
45959
45473
 
45960
45474
  // src/question.ts
45961
- var import_records66 = require("@ai-matrx/records");
45962
- var import_core24 = require("@ai-matrx/records/core");
45963
- var QUESTION_OPS = ["count", "sum", "avg", "min", "max"];
45964
- var QUESTION_LIMIT_DEFAULT = 25;
45965
- var QUESTION_GROUP_CEILING = 200;
45966
- var QUESTION_THROUGH_GROUP_CAP = 60;
45967
- function newQuestion() {
45968
- return { v: 1, measures: [{ op: "count" }], where: null, through: [], group: null, asOf: null, order: null, limit: QUESTION_LIMIT_DEFAULT, show: "table" };
45969
- }
45970
- function questionFromDefinition(definition) {
45971
- const raw = definition && typeof definition === "object" ? definition.question : null;
45972
- const base = newQuestion();
45973
- if (!raw || typeof raw !== "object") return base;
45974
- const measures = Array.isArray(raw.measures) ? raw.measures.filter((m) => !!m && QUESTION_OPS.includes(m.op)) : [];
45975
- return {
45976
- v: 1,
45977
- measures: measures.length > 0 ? measures : base.measures,
45978
- where: raw.where && typeof raw.where === "object" ? raw.where : null,
45979
- through: Array.isArray(raw.through) ? raw.through.filter((t) => t && typeof t.relation === "string" && typeof t.key === "string") : [],
45980
- group: raw.group && typeof raw.group === "object" && "kind" in raw.group ? raw.group : null,
45981
- asOf: typeof raw.asOf === "string" && raw.asOf !== "" ? raw.asOf : null,
45982
- order: raw.order && (raw.order.by === "measure" || raw.order.by === "count") ? raw.order : null,
45983
- limit: typeof raw.limit === "number" && raw.limit > 0 ? Math.min(Math.floor(raw.limit), QUESTION_GROUP_CEILING) : base.limit,
45984
- show: ["table", "bar", "column", "line", "donut", "number"].includes(raw.show) ? raw.show : base.show
45985
- };
45986
- }
45987
- function refusal(message, hint) {
45988
- return { ok: false, error: { code: "invalid_argument", message, ...hint ? { hint } : {} } };
45989
- }
45990
- function fieldById(fields, id) {
45991
- return fields.find((f) => f.id === id);
45992
- }
45993
- function flatWhere(where, fields) {
45994
- if (!where) return {};
45995
- const node = where;
45996
- const clauses = node.op === "and" ? node.args ?? [] : [where];
45997
- const out = {};
45998
- for (const clause of clauses) {
45999
- const c = clause;
46000
- if (c.op !== "eq" || !c.args?.[0]?.field || !c.args[1] || !("const" in c.args[1])) return null;
46001
- const f = fieldById(fields, c.args[0].field);
46002
- if (!f) return null;
46003
- out[f.key] = c.args[1].const;
46004
- }
46005
- return out;
46006
- }
46007
- function isFormula(fields, key) {
46008
- if (!key) return false;
46009
- const f = fields.find((x) => x.key === key);
46010
- return !!f && (f.type === "formula" || editorKindFor(f) === "formula");
46011
- }
46012
- function rowsOf2(rows, groupKey, keys) {
46013
- return rows.map((r) => {
46014
- const values = {};
46015
- for (const k of keys) {
46016
- const v = (r.measures ?? {})[k];
46017
- values[k] = v === null || v === void 0 ? null : Number(v);
46018
- }
46019
- const withheld = {};
46020
- for (const [name, notice] of Object.entries(r.withheld ?? {})) if (keys.includes(name)) withheld[name] = notice;
46021
- const g = groupKey ? (r.groups ?? {})[groupKey] : null;
46022
- return { group: g === null || g === void 0 ? null : String(g), values, withheld, n: Number(r.row_count ?? 0) };
46023
- });
46024
- }
46025
- function sortAndCut(rows, spec, keys) {
46026
- const first = keys[0];
46027
- const by = spec.order?.by ?? "count";
46028
- const dir = spec.order?.direction ?? "desc";
46029
- const value = (r) => by === "count" ? r.n : first ? r.values[first] : null;
46030
- const present = rows.filter((r) => value(r) !== null && value(r) !== void 0);
46031
- const blank = rows.filter((r) => value(r) === null || value(r) === void 0);
46032
- present.sort((a, b) => dir === "desc" ? value(b) - value(a) : value(a) - value(b));
46033
- return [...present, ...blank];
46034
- }
46035
- async function askQuestion(client, tableId, spec, fields) {
46036
- const measures = spec.measures.length > 0 ? spec.measures : [{ op: "count" }];
46037
- for (const m of measures) {
46038
- if (m.op !== "count" && !m.key) return refusal(`Pick the column to ${m.op === "avg" ? "average" : m.op}.`);
46039
- }
46040
- const keys = measures.map((m) => (0, import_records66.measureKey)({ op: m.op, ...m.key ? { key: m.key } : {} }));
46041
- const group = spec.group;
46042
- if (spec.asOf) return askAsOf(client, tableId, spec, fields, measures, keys);
46043
- let filter = spec.where ?? {};
46044
- if (spec.through.length > 0) {
46045
- const flat = flatWhere(spec.where, fields);
46046
- if (flat === null) {
46047
- return refusal(
46048
- "A condition on a related table can only be joined with \u201Cis\u201D conditions, all of them true.",
46049
- "Simplify the other conditions, or move them to the related table."
46050
- );
46051
- }
46052
- for (const t of spec.through) flat[`${t.relation}.${t.key}`] = t.value;
46053
- filter = flat;
46054
- }
46055
- if (group?.kind === "through") return askThrough(client, tableId, spec, fields, measures, keys, filter);
46056
- const ordered = measures.map((m, i) => {
46057
- const one = { op: m.op, ...m.key ? { key: m.key } : {} };
46058
- if (i === 0 && spec.order?.by === "measure") one["order"] = spec.order.direction;
46059
- return one;
46060
- });
46061
- if (spec.order?.by === "count") {
46062
- const at = measures.findIndex((m) => m.op === "count");
46063
- if (at >= 0) ordered[at]["order"] = spec.order.direction;
46064
- else ordered.unshift({ op: "count", order: spec.order.direction });
46065
- }
46066
- const groupBy = group?.kind === "field" ? [group.key] : [];
46067
- const bucket = group?.kind === "bucket" ? { key: group.key, by: group.by } : null;
46068
- const groupKey = group?.kind === "field" ? group.key : group?.kind === "bucket" ? `${group.key}_${group.by}` : null;
46069
- const limit = group ? Math.max(1, Math.min(spec.limit, QUESTION_GROUP_CEILING)) : 1;
46070
- const asked2 = await client.recordAggregate({
46071
- table_id: tableId,
46072
- groupBy,
46073
- // `order` rides the measure into custom.agg_sql (VISION-REACH W2); the type predates it.
46074
- measures: ordered,
46075
- bucket,
46076
- filter,
46077
- limit
46078
- });
46079
- if (!asked2.ok) return asked2;
46080
- const rows = rowsOf2(asked2.data, groupKey, keys);
46081
- let groupsTotal = group ? rows.length : null;
46082
- let groupsExact = true;
46083
- if (group && rows.length >= limit && limit < QUESTION_GROUP_CEILING) {
46084
- const every = await client.recordAggregate({
46085
- table_id: tableId,
46086
- groupBy,
46087
- measures: [{ op: "count" }],
46088
- bucket,
46089
- filter,
46090
- limit: QUESTION_GROUP_CEILING
46091
- });
46092
- if (every.ok) {
46093
- groupsTotal = every.data.length;
46094
- groupsExact = every.data.length < QUESTION_GROUP_CEILING;
46095
- } else {
46096
- groupsExact = false;
46097
- }
46098
- } else if (group && rows.length >= QUESTION_GROUP_CEILING) {
46099
- groupsExact = false;
46100
- }
46101
- return {
46102
- ok: true,
46103
- data: {
46104
- rows,
46105
- measures: keys,
46106
- groupKey,
46107
- groupsTotal,
46108
- groupsExact,
46109
- truncated: groupsTotal !== null && (groupsTotal > rows.length || !groupsExact),
46110
- asOf: null
46111
- }
46112
- };
46113
- }
46114
- async function askThrough(client, tableId, spec, fields, measures, keys, filter) {
46115
- const group = spec.group;
46116
- const rel = fields.find((f) => f.key === group.relation);
46117
- if (!rel || !rel.relation_target) return refusal(`\u201C${group.relation}\u201D is not a relation of this table.`);
46118
- const flat = filter && !filter.op ? filter : flatWhere(filter, fields);
46119
- if (flat === null) {
46120
- return refusal(
46121
- "Summarizing by a related table's column can only be joined with \u201Cis\u201D conditions, all of them true.",
46122
- "Simplify the conditions, or summarize by a column of this table."
46123
- );
46124
- }
46125
- const values = await client.recordAggregate({
46126
- table_id: rel.relation_target,
46127
- groupBy: [group.key],
46128
- measures: [{ op: "count" }],
46129
- limit: QUESTION_THROUGH_GROUP_CAP + 1
46130
- });
46131
- if (!values.ok) return values;
46132
- const named = values.data.map((r) => (r.groups ?? {})[group.key] ?? null).filter((v) => v !== null && v !== "");
46133
- if (named.length > QUESTION_THROUGH_GROUP_CAP) {
46134
- return refusal(
46135
- `That column has more than ${QUESTION_THROUGH_GROUP_CAP} values, too many to summarize by.`,
46136
- "Add a condition that narrows it, or summarize by a column of this table."
46137
- );
46138
- }
46139
- const answered = [];
46140
- for (let i = 0; i < named.length; i += 8) {
46141
- const batch = await Promise.all(
46142
- named.slice(i, i + 8).map(async (value) => {
46143
- const one = await client.recordAggregate({
46144
- table_id: tableId,
46145
- groupBy: [],
46146
- measures: measures.map((m) => ({ op: m.op, ...m.key ? { key: m.key } : {} })),
46147
- filter: { ...flat, [`${group.relation}.${group.key}`]: value },
46148
- limit: 1
46149
- });
46150
- return { value, one };
46151
- })
46152
- );
46153
- for (const { value, one } of batch) {
46154
- if (!one.ok) return one;
46155
- const [row] = rowsOf2(one.data, null, keys);
46156
- if (row && row.n > 0) answered.push({ ...row, group: value });
46157
- }
46158
- }
46159
- const sorted = sortAndCut(answered, spec, keys);
46160
- const limit = Math.max(1, Math.min(spec.limit, QUESTION_GROUP_CEILING));
46161
- return {
46162
- ok: true,
46163
- data: {
46164
- rows: sorted.slice(0, limit),
46165
- measures: keys,
46166
- groupKey: `${group.relation}.${group.key}`,
46167
- groupsTotal: sorted.length,
46168
- groupsExact: true,
46169
- truncated: sorted.length > limit,
46170
- asOf: null
46171
- }
46172
- };
46173
- }
46174
- async function askAsOf(client, tableId, spec, fields, measures, keys) {
46175
- const group = spec.group;
46176
- if (spec.through.length > 0 || group?.kind === "through") {
46177
- return refusal("\u201CAs of\u201D cannot reach across a relation yet.", "Ask without the related table's column, or without \u201Cas of\u201D.");
46178
- }
46179
- if (group?.kind === "bucket") {
46180
- return refusal("\u201CAs of\u201D cannot cut dates into periods yet.", "Summarize by the date itself, or ask without \u201Cas of\u201D.");
46181
- }
46182
- const match = flatWhere(spec.where, fields);
46183
- if (match === null) {
46184
- return refusal("\u201CAs of\u201D can only be filtered with \u201Cis\u201D conditions, all of them true.", "Simplify the filter, or ask without \u201Cas of\u201D.");
46185
- }
46186
- const formula = [...measures.map((m) => m.key), group?.key, ...Object.keys(match)].find((k) => isFormula(fields, k));
46187
- if (formula) {
46188
- const f = fields.find((x) => x.key === formula);
46189
- return refusal(
46190
- `${f?.label || formula} is worked out when a record is read, so it cannot be measured as of a moment.`,
46191
- "Measure a stored column, or ask without \u201Cas of\u201D."
46192
- );
46193
- }
46194
- const moment = new Date(spec.asOf);
46195
- if (Number.isNaN(moment.getTime())) return refusal("\u201CAs of\u201D is not a date and time.");
46196
- const config = client.config;
46197
- const groupKey = group?.kind === "field" ? group.key : null;
46198
- const byGroup = /* @__PURE__ */ new Map();
46199
- for (let i = 0; i < measures.length; i++) {
46200
- const m = measures[i];
46201
- const response = await config.dataSource.rpc(
46202
- "record_aggregate_as_of",
46203
- {
46204
- p_organization_id: config.organizationId,
46205
- p_table_id: tableId,
46206
- p_recorded_at: moment.toISOString(),
46207
- p_measure: m.op,
46208
- p_field_key: m.key ?? null,
46209
- p_group_by: groupKey,
46210
- p_match: match
46211
- },
46212
- { schema: config.schema ?? "custom" }
46213
- );
46214
- if (response.error) return { ok: false, error: (0, import_core24.mapPgError)(response.error, "askQuestion.asOf") };
46215
- const rows2 = Array.isArray(response.data) ? response.data : [];
46216
- const bad = rows2.find((r) => Number(r.not_numbers ?? 0) > 0);
46217
- if (bad && m.op !== "count") {
46218
- return refusal(`${m.key} held \u201C${bad.a_non_number}\u201D then, which is not a number, so its ${m.op} cannot be worked out.`);
46219
- }
46220
- for (const r of rows2) {
46221
- const g = groupKey ? r.bucket ?? null : null;
46222
- const at = g ?? "\0all";
46223
- const row = byGroup.get(at) ?? { group: g, values: {}, withheld: {}, n: Number(r.row_count ?? 0) };
46224
- row.values[keys[i]] = m.op === "count" ? Number(r.row_count ?? 0) : r.result === null ? null : Number(r.result);
46225
- byGroup.set(at, row);
46226
- }
46227
- }
46228
- let rows = [...byGroup.values()];
46229
- if (!groupKey && rows.length === 0) {
46230
- rows = [{ group: null, values: Object.fromEntries(keys.map((k, i) => [k, measures[i].op === "count" ? 0 : null])), withheld: {}, n: 0 }];
46231
- }
46232
- for (const r of rows) for (const k of keys) if (!(k in r.values)) r.values[k] = null;
46233
- const sorted = groupKey ? sortAndCut(rows, spec, keys) : rows;
46234
- const limit = groupKey ? Math.max(1, Math.min(spec.limit, QUESTION_GROUP_CEILING)) : 1;
46235
- return {
46236
- ok: true,
46237
- data: {
46238
- rows: sorted.slice(0, limit),
46239
- measures: keys,
46240
- groupKey,
46241
- groupsTotal: groupKey ? sorted.length : null,
46242
- groupsExact: true,
46243
- truncated: groupKey ? sorted.length > limit : false,
46244
- asOf: moment.toISOString()
46245
- }
46246
- };
46247
- }
46248
- async function unreadableKeys(client, tableId, fields) {
46249
- const guarded = fields.filter((f) => f.sensitivity === "confidential" || f.sensitivity === "restricted");
46250
- const out = /* @__PURE__ */ new Set();
46251
- if (guarded.length === 0) return out;
46252
- const asked2 = await client.recordAggregate({
46253
- table_id: tableId,
46254
- groupBy: [],
46255
- measures: guarded.map((f) => ({ op: "filled", key: f.key })),
46256
- limit: 1
46257
- });
46258
- if (!asked2.ok) {
46259
- for (const f of guarded) {
46260
- const one = await client.recordAggregate({ table_id: tableId, groupBy: [], measures: [{ op: "filled", key: f.key }], limit: 1 });
46261
- if (!one.ok || Object.keys(one.data[0]?.withheld ?? {}).length > 0) out.add(f.key);
46262
- }
46263
- return out;
46264
- }
46265
- for (const f of guarded) if (asked2.data.some((r) => r.withheld && `filled_${f.key}` in r.withheld)) out.add(f.key);
46266
- return out;
46267
- }
46268
- function measurableFields(fields, op2) {
46269
- if (op2 === "count") return [];
46270
- return fields.filter((f) => isNumericField(f) || (op2 === "min" || op2 === "max") && editorKindFor(f) === "datetime");
46271
- }
46272
- var QUESTION_SURFACE = "custom/records/question";
46273
- function savedOf(row) {
46274
- return {
46275
- id: row["id"],
46276
- name: String(row["name"] ?? ""),
46277
- spec: questionFromDefinition(row["definition"]),
46278
- shared: row["visibility"] !== "personal",
46279
- version: Number(row["version"] ?? 1),
46280
- createdBy: row["created_by"] ?? null
46281
- };
46282
- }
46283
- async function questionsOf(client, tableId) {
46284
- const response = await client.config.dataSource.schema("platform").from("saved_view").select("id, name, definition, visibility, version, created_by").eq("surface_key", QUESTION_SURFACE).eq("subject_id", tableId).is("deleted_at", null).order("name", { ascending: true });
46285
- if (response.error) return { ok: false, error: (0, import_core24.mapPgError)(response.error, "questionsOf") };
46286
- const me = client.config.actor?.user_id ?? null;
46287
- return {
46288
- ok: true,
46289
- data: (response.data ?? []).map(savedOf).filter((q) => q.shared || me !== null && q.createdBy === me)
46290
- };
46291
- }
46292
- async function questionSave(client, args) {
46293
- const name = args.name.trim();
46294
- if (!name) return refusal("Name the question so the team can find it.");
46295
- const response = await client.config.dataSource.rpc(
46296
- "saved_view_save",
46297
- {
46298
- p_surface_key: QUESTION_SURFACE,
46299
- p_id: args.id ?? null,
46300
- p_subject_id: args.tableId,
46301
- p_organization_id: client.config.organizationId,
46302
- p_name: name,
46303
- p_definition: { question: args.spec },
46304
- p_visibility: args.shared ? "internal" : "personal",
46305
- p_touch: true,
46306
- ...args.expectedVersion !== void 0 ? { p_expected_version: args.expectedVersion } : {}
46307
- },
46308
- { schema: "public" }
46309
- );
46310
- if (response.error) {
46311
- if (response.error.code === "23505") {
46312
- return { ok: false, error: { code: "already_exists", message: `You already have a question called \u201C${name}\u201D.` } };
46313
- }
46314
- return { ok: false, error: (0, import_core24.mapPgError)(response.error, "questionSave") };
46315
- }
46316
- return { ok: true, data: response.data ? savedOf(response.data) : null };
46317
- }
46318
- async function questionArchive(client, id, version) {
46319
- const response = await client.config.dataSource.rpc(
46320
- "saved_view_archive",
46321
- { p_surface_key: QUESTION_SURFACE, p_id: id, ...version !== void 0 ? { p_expected_version: version } : {} },
46322
- { schema: "public" }
46323
- );
46324
- if (response.error) return { ok: false, error: (0, import_core24.mapPgError)(response.error, "questionArchive") };
46325
- return { ok: true, data: response.data !== null };
46326
- }
45475
+ var question_exports = {};
45476
+ __reExport(question_exports, require("@ai-matrx/records/questions"));
46327
45477
 
46328
45478
  // src/QuestionPanel.tsx
46329
45479
  var import_jsx_runtime148 = require("react/jsx-runtime");
@@ -46379,12 +45529,12 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46379
45529
  }
46380
45530
  let live = true;
46381
45531
  void (async () => {
46382
- const mine2 = await unreadableKeys(client, tableId, all);
45532
+ const mine2 = await (0, question_exports.unreadableKeys)(client, tableId, all);
46383
45533
  const out = {};
46384
45534
  for (const rel of all.filter((f) => editorKindFor(f) === "relation" && f.relation_target && !mine2.has(f.key))) {
46385
45535
  const target = await client.fields({ table_id: rel.relation_target });
46386
45536
  if (!target.ok) continue;
46387
- const theirs = await unreadableKeys(client, rel.relation_target, target.data);
45537
+ const theirs = await (0, question_exports.unreadableKeys)(client, rel.relation_target, target.data);
46388
45538
  out[rel.key] = { relation: rel, fields: target.data.filter((f) => !theirs.has(f.key) && editorKindFor(f) !== "relation") };
46389
45539
  }
46390
45540
  if (!live) return;
@@ -46399,7 +45549,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46399
45549
  const [saved, setSaved] = (0, import_react260.useState)(null);
46400
45550
  const [savedEpoch, setSavedEpoch] = (0, import_react260.useState)(0);
46401
45551
  const [current, setCurrent] = (0, import_react260.useState)(null);
46402
- const [spec, setSpec] = (0, import_react260.useState)(newQuestion);
45552
+ const [spec, setSpec] = (0, import_react260.useState)(question_exports.newQuestion);
46403
45553
  const [name, setName] = (0, import_react260.useState)("");
46404
45554
  const [shared, setShared] = (0, import_react260.useState)(true);
46405
45555
  const [saveError, setSaveError] = (0, import_react260.useState)(null);
@@ -46408,7 +45558,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46408
45558
  const openedFromLink = (0, import_react260.useRef)(false);
46409
45559
  (0, import_react260.useEffect)(() => {
46410
45560
  let live = true;
46411
- void questionsOf(client, tableId).then((answer2) => {
45561
+ void (0, question_exports.questionsOf)(client, tableId).then((answer2) => {
46412
45562
  if (!live) return;
46413
45563
  setSaved(answer2.ok ? answer2.data : []);
46414
45564
  if (answer2.ok && activeQuestionId && !openedFromLink.current) {
@@ -46424,7 +45574,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46424
45574
  }, [client, tableId, savedEpoch, activeQuestionId]);
46425
45575
  const open = (q) => {
46426
45576
  setCurrent(q);
46427
- setSpec(q ? q.spec : newQuestion());
45577
+ setSpec(q ? q.spec : (0, question_exports.newQuestion)());
46428
45578
  setName(q ? q.name : "");
46429
45579
  setShared(q ? q.shared : true);
46430
45580
  setSaveError(null);
@@ -46443,7 +45593,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46443
45593
  let live = true;
46444
45594
  setAsking(true);
46445
45595
  const t = setTimeout(() => {
46446
- void askQuestion(client, tableId, spec, all).then((a) => {
45596
+ void (0, question_exports.askQuestion)(client, tableId, spec, all).then((a) => {
46447
45597
  if (!live) return;
46448
45598
  setAnswer(a);
46449
45599
  setAsking(false);
@@ -46459,7 +45609,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46459
45609
  setSaving(true);
46460
45610
  setSaveError(null);
46461
45611
  const editing = !asNew && current && mine;
46462
- const kept = await questionSave(client, {
45612
+ const kept = await (0, question_exports.questionSave)(client, {
46463
45613
  ...editing ? { id: current.id, expectedVersion: current.version } : {},
46464
45614
  tableId,
46465
45615
  name: asNew && current && name.trim() === current.name ? `${name.trim()} (copy)` : name,
@@ -46477,7 +45627,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46477
45627
  };
46478
45628
  const archive = async () => {
46479
45629
  if (!current) return;
46480
- const gone = await questionArchive(client, current.id, current.version);
45630
+ const gone = await (0, question_exports.questionArchive)(client, current.id, current.version);
46481
45631
  if (!gone.ok) return setSaveError(gone.error);
46482
45632
  open(null);
46483
45633
  setSavedEpoch((n) => n + 1);
@@ -46632,17 +45782,17 @@ function Measures({ measures, fields, onChange }) {
46632
45782
  const set = (i, next) => onChange(measures.map((m, j) => j === i ? next : m));
46633
45783
  return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex flex-col gap-1", children: [
46634
45784
  measures.map((m, i) => {
46635
- const eligible = measurableFields(fields, m.op);
45785
+ const eligible = (0, question_exports.measurableFields)(fields, m.op);
46636
45786
  return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-center gap-1", "data-testid": "question-measure", children: [
46637
45787
  /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
46638
45788
  PickOne,
46639
45789
  {
46640
45790
  label: "Measure",
46641
45791
  value: m.op,
46642
- options: QUESTION_OPS.map((op2) => ({ value: op2, label: OP_LABEL[op2] })),
45792
+ options: question_exports.QUESTION_OPS.map((op2) => ({ value: op2, label: OP_LABEL[op2] })),
46643
45793
  onChange: (op2) => {
46644
45794
  const nextOp = op2;
46645
- const keep = nextOp !== "count" && measurableFields(fields, nextOp).some((f) => f.key === m.key);
45795
+ const keep = nextOp !== "count" && (0, question_exports.measurableFields)(fields, nextOp).some((f) => f.key === m.key);
46646
45796
  set(i, nextOp === "count" ? { op: "count" } : { op: nextOp, ...keep ? { key: m.key } : {} });
46647
45797
  },
46648
45798
  className: "w-28",
@@ -46882,7 +46032,7 @@ function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATE
46882
46032
  // src/TableAsk.tsx
46883
46033
  var import_react262 = require("react");
46884
46034
  var import_design_system132 = require("@ai-matrx/design-system");
46885
- var import_records67 = require("@ai-matrx/records");
46035
+ var import_records66 = require("@ai-matrx/records");
46886
46036
  var import_react263 = require("@ai-matrx/records/react");
46887
46037
 
46888
46038
  // src/askWords.ts
@@ -47074,14 +46224,14 @@ function questionFromWords(text, fields, choices = {}) {
47074
46224
  const measured = head === "" ? null : columnNamed2(head, names);
47075
46225
  if (op2 === null) {
47076
46226
  if (head === "") op2 = "count";
47077
- else if (measured && measurableFields([...fields], "sum").some((f) => f.key === measured.key)) op2 = "sum";
46227
+ else if (measured && (0, question_exports.measurableFields)([...fields], "sum").some((f) => f.key === measured.key)) op2 = "sum";
47078
46228
  else return { ok: false, why: "Start with count, sum, average, smallest or largest" };
47079
46229
  }
47080
- const spec = { ...newQuestion(), group };
46230
+ const spec = { ...(0, question_exports.newQuestion)(), group };
47081
46231
  let measureReads = "Count";
47082
46232
  if (op2 !== "count") {
47083
46233
  if (!measured) return { ok: false, why: head === "" ? `${OP_READS[op2]} which column?` : `No column named \u201C${head}\u201D` };
47084
- if (!measurableFields([...fields], op2).some((f) => f.key === measured.key)) {
46234
+ if (!(0, question_exports.measurableFields)([...fields], op2).some((f) => f.key === measured.key)) {
47085
46235
  return { ok: false, why: `${fieldName(measured)} is not a number column` };
47086
46236
  }
47087
46237
  spec.measures = [{ op: op2, key: measured.key }];
@@ -47112,13 +46262,13 @@ function TableAsk({ tableId, onOpenInQuestions }) {
47112
46262
  await Promise.all(
47113
46263
  all.filter(isChoiceField).map(async (field2) => {
47114
46264
  const got = await (0, askOnce_exports.fieldOptionsOnce)(client, field2.id);
47115
- if (got.ok) choices[field2.key] = (got.data ?? []).map((o) => (0, import_records67.optionLabel)(o)).filter((w) => Boolean(w));
46265
+ if (got.ok) choices[field2.key] = (got.data ?? []).map((o) => (0, import_records66.optionLabel)(o)).filter((w) => Boolean(w));
47116
46266
  })
47117
46267
  );
47118
46268
  const read = questionFromWords(words2, all, choices);
47119
46269
  if (!read.ok) return setSaid({ kind: "not-read", why: read.why });
47120
46270
  setSaid({ kind: "asking", reads: read.reads });
47121
- const answered = await askQuestion(client, tableId, read.spec, all);
46271
+ const answered = await (0, question_exports.askQuestion)(client, tableId, read.spec, all);
47122
46272
  setSaid(answered.ok ? { kind: "answer", reads: read.reads, spec: read.spec, answer: answered.data } : { kind: "refused", error: answered.error });
47123
46273
  };
47124
46274
  return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_design_system132.Popover, { open, onOpenChange: setOpen, children: [
@@ -47180,7 +46330,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
47180
46330
  // src/PageScreen.tsx
47181
46331
  var import_react264 = require("react");
47182
46332
  var import_react265 = require("@ai-matrx/records/react");
47183
- var import_core25 = require("@ai-matrx/records/core");
46333
+ var import_core23 = require("@ai-matrx/records/core");
47184
46334
  var import_design_system133 = require("@ai-matrx/design-system");
47185
46335
  var import_forms4 = require("@ai-matrx/records/forms");
47186
46336
  var import_jsx_runtime150 = require("react/jsx-runtime");
@@ -47597,7 +46747,7 @@ function ListBlockView({
47597
46747
  ...sort.length > 0 ? { sort } : {}
47598
46748
  });
47599
46749
  const reload = page.reload;
47600
- (0, import_react264.useEffect)(() => (0, import_core25.onRecordChanged)(() => reload()), [reload]);
46750
+ (0, import_react264.useEffect)(() => (0, import_core23.onRecordChanged)(() => reload()), [reload]);
47601
46751
  const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
47602
46752
  const columns = block.columns && block.columns.length > 0 ? block.columns.map((k) => all.find((f) => f.key === k)).filter((f) => !!f) : [...all].sort((a, b) => (a.sort ?? 100) - (b.sort ?? 100)).slice(0, DEFAULT_COLUMNS);
47603
46753
  const firstId = rows[0]?.id ?? null;
@@ -47963,7 +47113,7 @@ function onePerKey3(all) {
47963
47113
  var import_clipboard11 = require("@ai-matrx/kit/clipboard");
47964
47114
  var import_react266 = require("react");
47965
47115
  var import_react267 = require("@ai-matrx/records/react");
47966
- var import_records68 = require("@ai-matrx/records");
47116
+ var import_records67 = require("@ai-matrx/records");
47967
47117
  var import_design_system134 = require("@ai-matrx/design-system");
47968
47118
  var import_forms5 = require("@ai-matrx/records/forms");
47969
47119
  var import_jsx_runtime151 = require("react/jsx-runtime");
@@ -48069,7 +47219,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
48069
47219
  }
48070
47220
  ) : null,
48071
47221
  /* @__PURE__ */ (0, import_jsx_runtime151.jsx)("ul", { className: "flex flex-col gap-2", children: forms.map((form) => {
48072
- const url = `${origin}${(0, import_records68.publicFormPath)(form.form_id)}`;
47222
+ const url = `${origin}${(0, import_records67.publicFormPath)(form.form_id)}`;
48073
47223
  return /* @__PURE__ */ (0, import_jsx_runtime151.jsxs)(
48074
47224
  "li",
48075
47225
  {
@@ -48151,7 +47301,7 @@ var import_design_system136 = require("@ai-matrx/design-system");
48151
47301
 
48152
47302
  // src/CaptureRun.tsx
48153
47303
  var import_react268 = require("react");
48154
- var import_records69 = require("@ai-matrx/records");
47304
+ var import_records68 = require("@ai-matrx/records");
48155
47305
  var import_react269 = require("@ai-matrx/records/react");
48156
47306
  var import_design_system135 = require("@ai-matrx/design-system");
48157
47307
  var import_jsx_runtime152 = require("react/jsx-runtime");
@@ -48206,7 +47356,7 @@ function CaptureRun({ sheetId, face: given, className }) {
48206
47356
  const [sending, setSending] = (0, import_react268.useState)(false);
48207
47357
  const queueRef = (0, import_react268.useRef)(null);
48208
47358
  (0, import_react268.useEffect)(() => {
48209
- const q2 = (0, import_records69.openCaptureQueue)({
47359
+ const q2 = (0, import_records68.openCaptureQueue)({
48210
47360
  onChange: (c, all) => {
48211
47361
  setCounts(c);
48212
47362
  setItems(all);
@@ -48473,7 +47623,7 @@ function CaptureRun({ sheetId, face: given, className }) {
48473
47623
  value: String(answers[q.field] ?? ""),
48474
47624
  onChange: (e) => {
48475
47625
  const raw = e.target.value;
48476
- const answered2 = field2 ? (0, import_records69.coerceTypedAnswer)(field2, raw, { label: q.ask ?? (0, import_records69.coercionLabel)(field2) }) : { value: raw };
47626
+ const answered2 = field2 ? (0, import_records68.coerceTypedAnswer)(field2, raw, { label: q.ask ?? (0, import_records68.coercionLabel)(field2) }) : { value: raw };
48477
47627
  setAnswers((held) => ({
48478
47628
  ...held,
48479
47629
  [q.field]: raw === "" ? "" : "refusal" in answered2 ? raw : answered2.value
@@ -49116,13 +48266,13 @@ function useEmbedHandshake(args) {
49116
48266
  // src/TablePage.tsx
49117
48267
  var import_clipboard14 = require("@ai-matrx/kit/clipboard");
49118
48268
  var import_react288 = require("react");
49119
- var import_records70 = require("@ai-matrx/records");
48269
+ var import_records69 = require("@ai-matrx/records");
49120
48270
  var import_react289 = require("@ai-matrx/records/react");
49121
48271
  var import_design_system146 = require("@ai-matrx/design-system");
49122
48272
  var import_text_case19 = require("@ai-matrx/kit/text-case");
49123
48273
 
49124
48274
  // src/viewShare.ts
49125
- var import_core26 = require("@ai-matrx/records/core");
48275
+ var import_core24 = require("@ai-matrx/records/core");
49126
48276
  var NO_VIEW_REASON = "No saved view yet";
49127
48277
  function viewLink(tableId, viewId, origin) {
49128
48278
  return `${tableLink(tableId, origin)}?view=${encodeURIComponent(viewId)}`;
@@ -49158,7 +48308,7 @@ async function downloadViewCsv(args) {
49158
48308
  const columns = viewColumns(fields, view.presentation);
49159
48309
  const rows = await rowsForFile({ client, host, fields: columns, records: read.rows, labels });
49160
48310
  const name = fileNameOf(args.tableName) || "records";
49161
- download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core26.exportCsv)(columns, rows));
48311
+ download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core24.exportCsv)(columns, rows));
49162
48312
  host.notify?.success(read.cut ? cutWords(read.rows.length) : "CSV downloaded");
49163
48313
  }
49164
48314
 
@@ -49681,16 +48831,16 @@ function toolbarFold(input) {
49681
48831
  };
49682
48832
  const withGap = (width) => width > 0 ? width + gap : 0;
49683
48833
  const shareNow = input.share ? withGap(input.share.now) : 0;
49684
- const base = pieces.reduce((rest, p) => rest - withGap(p.piece.now), needsNow - shareNow);
48834
+ const base2 = pieces.reduce((rest, p) => rest - withGap(p.piece.now), needsNow - shareNow);
49685
48835
  const stages = input.tools ? [0, 1, 2, 3] : [0, 1, 2];
49686
48836
  const shareOn = input.share ? withGap(input.share.full ?? input.share.now) : 0;
49687
- const needs = stages.map((fold) => pieces.reduce((sum, p) => sum + withGap(widthAt(p, fold)), base + shareOn));
48837
+ const needs = stages.map((fold) => pieces.reduce((sum, p) => sum + withGap(widthAt(p, fold)), base2 + shareOn));
49688
48838
  const fits = needs.findIndex((need) => need <= available + 0.5);
49689
48839
  if (fits >= 0) return stages[fits];
49690
48840
  const least = Math.min(...needs);
49691
48841
  const most = stages[needs.findIndex((need) => need <= least + 0.5)];
49692
48842
  if (!input.tools || !input.share) return most;
49693
- const fixed = pieces.reduce((sum, p) => sum + withGap(p.stage === 3 ? SLOT_MIN : widthAt(p, 3)), base + shareOn);
48843
+ const fixed = pieces.reduce((sum, p) => sum + withGap(p.stage === 3 ? SLOT_MIN : widthAt(p, 3)), base2 + shareOn);
49694
48844
  return fixed > available + 0.5 ? 4 : most;
49695
48845
  }
49696
48846
  function naturalWidth(el) {
@@ -49847,7 +48997,7 @@ function useSlotScroll(slot) {
49847
48997
  }
49848
48998
 
49849
48999
  // src/TablePage.tsx
49850
- var import_uuid4 = require("@ai-matrx/kit/uuid");
49000
+ var import_uuid3 = require("@ai-matrx/kit/uuid");
49851
49001
  var import_jsx_runtime163 = require("react/jsx-runtime");
49852
49002
  var RAIL_TITLE = {
49853
49003
  settings: "Table settings",
@@ -49934,7 +49084,7 @@ function TableNotHere({
49934
49084
  const client = (0, import_react289.useRecordsClient)();
49935
49085
  const [archived, setArchived] = (0, import_react288.useState)({ phase: "asking" });
49936
49086
  const [restoring, setRestoring] = (0, import_react288.useState)(false);
49937
- const [refusal4, setRefusal] = (0, import_react288.useState)(null);
49087
+ const [refusal3, setRefusal] = (0, import_react288.useState)(null);
49938
49088
  (0, import_react288.useEffect)(() => {
49939
49089
  let alive = true;
49940
49090
  void client.tableArchived({ table_id: tableId }).then((answered) => {
@@ -49951,8 +49101,8 @@ function TableNotHere({
49951
49101
  return /* @__PURE__ */ (0, import_jsx_runtime163.jsxs)("div", { className: (0, import_design_system146.cn)("flex flex-col items-start gap-2 rounded-md border border-dashed p-6", className), children: [
49952
49102
  /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "text-sm font-medium", children: "This table is archived" }),
49953
49103
  /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "max-w-prose text-xs text-muted-foreground", children: TABLE_IS_ARCHIVED }),
49954
- /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records70.archivedByLine)(row) }),
49955
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(RefusalNotice, { error: refusal4 }) : null,
49104
+ /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records69.archivedByLine)(row) }),
49105
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(RefusalNotice, { error: refusal3 }) : null,
49956
49106
  /* @__PURE__ */ (0, import_jsx_runtime163.jsxs)("div", { className: "flex gap-2", children: [
49957
49107
  /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
49958
49108
  import_design_system146.Button,
@@ -50054,7 +49204,7 @@ function unknownRailLine(raw) {
50054
49204
  }
50055
49205
  var SHARE_NOT_YOURS_LINE = "The link asked to open this table's sharing, and only someone with Admin on this table can share it, so it did not open. Ask an admin of this table to share it or to give you Admin.";
50056
49206
  function openingView(activeView, activeDashboardId) {
50057
- const named = pageViewFromParam(activeView);
49207
+ const named = (0, import_views2.pageViewFromParam)(activeView);
50058
49208
  if (named === null) {
50059
49209
  const asked2 = typeof activeView === "string" ? activeView.trim() : "";
50060
49210
  return {
@@ -50069,7 +49219,7 @@ function openingView(activeView, activeDashboardId) {
50069
49219
  }
50070
49220
  function savedViewFromParam(activeView) {
50071
49221
  const word = typeof activeView === "string" ? activeView.trim() : "";
50072
- return (0, import_uuid4.isUuidShape)(word) ? word.toLowerCase() : null;
49222
+ return (0, import_uuid3.isUuidShape)(word) ? word.toLowerCase() : null;
50073
49223
  }
50074
49224
  function addressForView(view, layout) {
50075
49225
  return view && !view.isDefault ? view.id : layout;
@@ -50152,7 +49302,7 @@ function TablePage({
50152
49302
  const [view, setView] = (0, import_react288.useState)(() => {
50153
49303
  if (!seededViews || seededViews.length === 0) return null;
50154
49304
  const asked2 = savedViewFromParam(activeView);
50155
- return seededViews.find((v) => v.id === asked2) ?? defaultViewOf(seededViews) ?? seededViews[0];
49305
+ return seededViews.find((v) => v.id === asked2) ?? (0, import_views2.defaultViewOf)(seededViews) ?? seededViews[0];
50156
49306
  });
50157
49307
  const [looks, setLooks] = (0, import_react288.useState)(() => seededViews ? seededOpening?.looks : void 0);
50158
49308
  const looksSeededFor = (0, import_react288.useRef)(seededViews && seededOpening ? tableId : null);
@@ -50172,7 +49322,7 @@ function TablePage({
50172
49322
  };
50173
49323
  }, [client, tableId]);
50174
49324
  const look = view && looks ? looks[view.id] : void 0;
50175
- const shown4 = view ? applyLook(view, look) : null;
49325
+ const shown4 = view ? (0, import_views3.applyLook)(view, look) : null;
50176
49326
  const [viewsEpoch, setViewsEpoch] = (0, import_react288.useState)(0);
50177
49327
  const opening = openingRail(activeRecordId, activeRail);
50178
49328
  const recordsUi = useRecordsUi();
@@ -50245,7 +49395,7 @@ function TablePage({
50245
49395
  const toolbarFold2 = useToolbarFit(toolbarRow);
50246
49396
  const slotClipped = useSlotScroll(toolbarSlot);
50247
49397
  const embedded = pagePresentation2 === "embedded";
50248
- const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 100);
49398
+ const pageSize = pageSizeAsked ?? (embedded ? import_first_page5.EMBEDDED_PAGE_SIZE : 100);
50249
49399
  const chooserInline = !embedded && !phone && toolbarFold2 < 2;
50250
49400
  const chooserCompact = !embedded && !phone && toolbarFold2 >= 2;
50251
49401
  const controlsInSheet = phone;
@@ -50281,7 +49431,7 @@ function TablePage({
50281
49431
  (k) => look[k] !== void 0 && !(k === "groupField" && activeGroupField) && !(k === "layout" && layoutFromLink)
50282
49432
  ) : [],
50283
49433
  fromAddress: [...layoutFromLink ? ["layout"] : [], ...activeGroupField ? ["groupField"] : []],
50284
- lookDiffers: view ? lookDiffers(view, look) : false
49434
+ lookDiffers: view ? (0, import_views3.lookDiffers)(view, look) : false
50285
49435
  };
50286
49436
  const shownSignature = JSON.stringify(shownReport);
50287
49437
  const reportRef = (0, import_react288.useRef)(onShownViewChange);
@@ -50307,7 +49457,7 @@ function TablePage({
50307
49457
  setSurface((now) => ({ ...now, rail: named }));
50308
49458
  }, [activeRail, activeRecordId]);
50309
49459
  (0, import_react288.useEffect)(() => {
50310
- const named = pageViewFromParam(activeView);
49460
+ const named = (0, import_views2.pageViewFromParam)(activeView);
50311
49461
  if (named === null) return;
50312
49462
  const isLayout = named !== "dashboards" && named !== "archived";
50313
49463
  setLayoutFromLink(isLayout ? named : null);
@@ -50318,7 +49468,7 @@ function TablePage({
50318
49468
  async (asked2) => {
50319
49469
  const current = view;
50320
49470
  if (!current) return;
50321
- const part = lookPart(asked2);
49471
+ const part = (0, import_views3.lookPart)(asked2);
50322
49472
  if (Object.keys(part).length === 0) return;
50323
49473
  const before = looks?.[current.id];
50324
49474
  const next = { ...before ?? {}, ...part };
@@ -50376,7 +49526,7 @@ function TablePage({
50376
49526
  addressReportRef.current?.(isViewAddressEmpty(addressNow) ? null : addressNow);
50377
49527
  }, [addressReady, addressSignature]);
50378
49528
  const queryShowing = !isViewAddressEmpty({ ...gridQuery ?? {}, hidden: [] });
50379
- const lookShowing = Boolean(view && looks && (lookDiffers(view, looks[view.id]) || queryShowing));
49529
+ const lookShowing = Boolean(view && looks && ((0, import_views3.lookDiffers)(view, looks[view.id]) || queryShowing));
50380
49530
  const [lookRefused, setLookRefused] = (0, import_react288.useState)(null);
50381
49531
  const [namingLook, setNamingLook] = (0, import_react288.useState)(false);
50382
49532
  const [lookName, setLookName] = (0, import_react288.useState)("");
@@ -50402,7 +49552,7 @@ function TablePage({
50402
49552
  const mine = current && looks ? looks[current.id] : void 0;
50403
49553
  if (!current || !mine) return;
50404
49554
  setLookRefused(null);
50405
- const { patch, left } = saveToViewPlan(current, mine);
49555
+ const { patch, left } = (0, import_views3.saveToViewPlan)(current, mine);
50406
49556
  if (Object.keys(viewPatchDocument(patch)).length > 0) {
50407
49557
  const written = await saveViewPatch(client, tableId, current.id, patch);
50408
49558
  if (!written.ok) {
@@ -50441,14 +49591,14 @@ function TablePage({
50441
49591
  const [designateRefused, setDesignateRefused] = (0, import_react288.useState)(null);
50442
49592
  const opensAs = view?.isDefault ? view.layout : null;
50443
49593
  const canDesignate = Boolean(
50444
- rights.organise && view && layoutShowing && layoutShowing !== opensAs && storeKeepsLayout(layoutShowing)
49594
+ rights.organise && view && layoutShowing && layoutShowing !== opensAs && (0, import_views2.storeKeepsLayout)(layoutShowing)
50445
49595
  );
50446
- const layoutShowingLabel = layoutShowing ? LAYOUT_LABEL[layoutShowing] : "";
49596
+ const layoutShowingLabel = layoutShowing ? import_views2.LAYOUT_LABEL[layoutShowing] : "";
50447
49597
  const designate = async () => {
50448
49598
  const current = view;
50449
49599
  if (!current || !layoutShowing) return;
50450
49600
  setDesignateRefused(null);
50451
- const written = await designateView(client, tableId, current.id, layoutShowing);
49601
+ const written = await (0, import_views2.designateView)(client, tableId, current.id, layoutShowing);
50452
49602
  if (!written.ok) {
50453
49603
  setDesignateRefused(written.error);
50454
49604
  return;
@@ -50464,14 +49614,14 @@ function TablePage({
50464
49614
  {
50465
49615
  value: layoutShowing ?? "",
50466
49616
  onValueChange: (value) => {
50467
- if (VIEW_LAYOUTS.includes(value)) pickLayout(value);
49617
+ if (import_views2.VIEW_LAYOUTS.includes(value)) pickLayout(value);
50468
49618
  },
50469
- children: VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(import_design_system146.DropdownMenuRadioItem, { value: option, children: LAYOUT_LABEL[option] }, option))
49619
+ children: import_views2.VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(import_design_system146.DropdownMenuRadioItem, { value: option, children: import_views2.LAYOUT_LABEL[option] }, option))
50470
49620
  }
50471
49621
  );
50472
49622
  const sheetExtras = controlsInSheet && main === "records" && shownLayout === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime163.jsxs)(import_jsx_runtime163.Fragment, { children: [
50473
49623
  /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("div", { className: "flex items-center gap-2 text-xs", "data-table-sheet-filter": "", "data-matrx-table-tools-keep-open": "", children: /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(ViewFilter, { tableId, view: shown4, onApply: (where) => void patchView({ where }) }) }),
50474
- /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("div", { role: "group", "aria-label": "Layout", className: "flex flex-wrap gap-1 pt-1", "data-table-sheet-layout": "", children: VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
49624
+ /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("div", { role: "group", "aria-label": "Layout", className: "flex flex-wrap gap-1 pt-1", "data-table-sheet-layout": "", children: import_views2.VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
50475
49625
  import_design_system146.Button,
50476
49626
  {
50477
49627
  size: "sm",
@@ -50479,7 +49629,7 @@ function TablePage({
50479
49629
  "aria-pressed": layoutShowing === option,
50480
49630
  className: "h-8 !w-auto",
50481
49631
  onClick: () => pickLayout(option),
50482
- children: LAYOUT_LABEL[option]
49632
+ children: import_views2.LAYOUT_LABEL[option]
50483
49633
  },
50484
49634
  option
50485
49635
  )) }),
@@ -50736,7 +49886,7 @@ function TablePage({
50736
49886
  ] });
50737
49887
  }
50738
49888
  const lookSavable = Boolean(
50739
- rights.write && view && Object.keys(viewPatchDocument(saveToViewPlan(view, look ?? {}).patch)).length > 0
49889
+ rights.write && view && Object.keys(viewPatchDocument((0, import_views3.saveToViewPlan)(view, look ?? {}).patch)).length > 0
50740
49890
  );
50741
49891
  return /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(ViewAddressContext.Provider, { value: addressPort, children: /* @__PURE__ */ (0, import_jsx_runtime163.jsxs)("div", { className: (0, import_design_system146.cn)("flex h-full min-h-0 gap-4", className), "data-table-footer": footer, children: [
50742
49892
  headerNode,
@@ -50763,7 +49913,7 @@ function TablePage({
50763
49913
  if (before !== null && before !== next.id) {
50764
49914
  setViewLinkMissed(false);
50765
49915
  setPickedViewId(next.id);
50766
- onViewChanged?.(addressForView(next, applyLook(next, looks?.[next.id]).layout ?? "grid"));
49916
+ onViewChanged?.(addressForView(next, (0, import_views3.applyLook)(next, looks?.[next.id]).layout ?? "grid"));
50767
49917
  }
50768
49918
  },
50769
49919
  onViews: setViews,
@@ -50800,14 +49950,14 @@ function TablePage({
50800
49950
  },
50801
49951
  viewsEpoch
50802
49952
  ),
50803
- chooserInline ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("div", { className: "flex shrink-0 items-center gap-0.5", role: "group", "aria-label": "Layout", "data-toolbar-fit": "chooser", children: VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
49953
+ chooserInline ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("div", { className: "flex shrink-0 items-center gap-0.5", role: "group", "aria-label": "Layout", "data-toolbar-fit": "chooser", children: import_views2.VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
50804
49954
  import_design_system146.Button,
50805
49955
  {
50806
49956
  size: "sm",
50807
49957
  variant: layoutShowing === option ? "secondary" : "ghost",
50808
49958
  "aria-pressed": layoutShowing === option,
50809
49959
  onClick: () => pickLayout(option),
50810
- children: LAYOUT_LABEL[option]
49960
+ children: import_views2.LAYOUT_LABEL[option]
50811
49961
  },
50812
49962
  option
50813
49963
  )) }) : null,
@@ -50945,7 +50095,7 @@ function TablePage({
50945
50095
  QuestionPanel,
50946
50096
  {
50947
50097
  tableId,
50948
- activeQuestionId: questionsFromLink && activeItemId && (0, import_uuid4.isUuidShape)(activeItemId) ? activeItemId : null,
50098
+ activeQuestionId: questionsFromLink && activeItemId && (0, import_uuid3.isUuidShape)(activeItemId) ? activeItemId : null,
50949
50099
  draft: questionDraft
50950
50100
  }
50951
50101
  ) : main === "archived" ? (
@@ -50978,7 +50128,7 @@ function TablePage({
50978
50128
  children: [
50979
50129
  railUnknown ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "rounded-md border border-amber-600/40 bg-amber-500/5 px-3 py-2 text-xs leading-relaxed text-amber-700 dark:border-amber-400/40 dark:text-amber-300", children: unknownRailLine(railUnknown) }) : null,
50980
50130
  shareFromLink && rights.known && (!rights.share || !canShare) ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "rounded-md border border-amber-600/40 bg-amber-500/5 px-3 py-2 text-xs leading-relaxed text-amber-700 dark:border-amber-400/40 dark:text-amber-300", children: canShare ? SHARE_NOT_YOURS_LINE : shareUnavailableReason() }) : null,
50981
- opened.unknown ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "rounded-md border border-amber-600/40 bg-amber-500/5 px-3 py-2 text-xs leading-relaxed text-amber-700 dark:border-amber-400/40 dark:text-amber-300", children: unknownViewLine(opened.unknown) }) : null,
50131
+ opened.unknown ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "rounded-md border border-amber-600/40 bg-amber-500/5 px-3 py-2 text-xs leading-relaxed text-amber-700 dark:border-amber-400/40 dark:text-amber-300", children: (0, import_views2.unknownViewLine)(opened.unknown) }) : null,
50982
50132
  viewLinkMissed ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
50983
50133
  "p",
50984
50134
  {
@@ -51201,7 +50351,7 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51201
50351
  const writable = !column.readOnly && entity.canUpdate;
51202
50352
  const placed = (row) => entityValueText(column, entityCellValue(row, column)) || null;
51203
50353
  const lanes = [...words2.map((w) => ({ key: w, label: w })), { key: "", label: `No ${column.label.toLowerCase()}` }];
51204
- const rowsOf3 = (key) => entity.rows.filter((r) => (placed(r) ?? "") === key);
50354
+ const rowsOf2 = (key) => entity.rows.filter((r) => (placed(r) ?? "") === key);
51205
50355
  const drop = async (event, to) => {
51206
50356
  event.preventDefault();
51207
50357
  setOver(null);
@@ -51213,7 +50363,7 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51213
50363
  if (says) setRefused({ to, says });
51214
50364
  };
51215
50365
  return /* @__PURE__ */ (0, import_jsx_runtime164.jsx)("div", { className: (0, import_design_system148.cn)("flex min-h-40 gap-2 overflow-x-auto pb-1", className), "data-records-entity-board": column.key, children: lanes.map((lane) => {
51216
- const cards = rowsOf3(lane.key);
50366
+ const cards = rowsOf2(lane.key);
51217
50367
  if (lane.key === "" && cards.length === 0) return null;
51218
50368
  return /* @__PURE__ */ (0, import_jsx_runtime164.jsxs)(
51219
50369
  "section",
@@ -51255,9 +50405,9 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51255
50405
  );
51256
50406
  }) });
51257
50407
  }
51258
- function blockOfAnswer(answer, base, by) {
50408
+ function blockOfAnswer(answer, base2, by) {
51259
50409
  if (!answer.ok) {
51260
- return { ...base, refused: refusalSentence(answer.error) || "This chart could not be read.", ...answer.error.code ? { sqlstate: answer.error.code } : {} };
50410
+ return { ...base2, refused: refusalSentence(answer.error) || "This chart could not be read.", ...answer.error.code ? { sqlstate: answer.error.code } : {} };
51261
50411
  }
51262
50412
  const rows = answer.data.rows.filter((r) => by ? r.kind !== "total" : r.kind === "total").map((r) => {
51263
50413
  const groups = {};
@@ -51269,17 +50419,17 @@ function blockOfAnswer(answer, base, by) {
51269
50419
  for (const [k, v] of Object.entries(r.measures ?? {})) measuresOut[k] = typeof v === "number" ? v : v === null ? null : Number(v);
51270
50420
  return { groups, measures: measuresOut, row_count: Number(r.row_count) };
51271
50421
  });
51272
- return { ...base, rows };
50422
+ return { ...base2, rows };
51273
50423
  }
51274
50424
  function EntityChartBlock({ source, kind, by, measure, title, where, organization, centerValue, variant, className }) {
51275
50425
  const client = (0, import_react291.useRecordsClient)();
51276
50426
  const m = measure ?? { op: "count" };
51277
50427
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
51278
- const question = entityChartQuestion({ by, measure, where, organization });
50428
+ const question = (0, import_first_page7.entityChartQuestion)({ by, measure, where, organization });
51279
50429
  const measures = [m.op === "count" ? { op: "count" } : { op: m.op, key: m.of }];
51280
- const base = { title: title ?? "", kind, measures, group_by: by ? [by] : [] };
50430
+ const base2 = { title: title ?? "", kind, measures, group_by: by ? [by] : [] };
51281
50431
  const seeded = (0, import_react291.useSeededAnswerAt)(`entity-chart:${ask}`, (c) => c.drillAsk({ source, question }));
51282
- const [block, setBlock] = (0, import_react290.useState)(() => seeded ? blockOfAnswer({ ok: true, data: seeded.data }, base, by) : null);
50432
+ const [block, setBlock] = (0, import_react290.useState)(() => seeded ? blockOfAnswer({ ok: true, data: seeded.data }, base2, by) : null);
51283
50433
  const seededFor = (0, import_react290.useRef)(seeded ? { ask: `${ask}|${kind}|${title ?? ""}`, at: seeded.at } : null);
51284
50434
  (0, import_react290.useEffect)(() => {
51285
50435
  const held = seededFor.current;
@@ -51288,7 +50438,7 @@ function EntityChartBlock({ source, kind, by, measure, title, where, organizatio
51288
50438
  let cancelled = false;
51289
50439
  void client.drillAsk({ source, question }).then((answer) => {
51290
50440
  if (cancelled) return;
51291
- setBlock(blockOfAnswer(answer, base, by));
50441
+ setBlock(blockOfAnswer(answer, base2, by));
51292
50442
  });
51293
50443
  return () => {
51294
50444
  cancelled = true;
@@ -51318,7 +50468,7 @@ function EntityTablePageBody({
51318
50468
  searchOverride,
51319
50469
  onSearchChange,
51320
50470
  searchBox = true,
51321
- pageSize = presentation === "embedded" ? EMBEDDED_PAGE_SIZE : 100,
50471
+ pageSize = presentation === "embedded" ? import_first_page5.EMBEDDED_PAGE_SIZE : 100,
51322
50472
  layout: opened = "grid",
51323
50473
  onLayoutChange,
51324
50474
  groupBy,
@@ -51457,7 +50607,7 @@ function TablePage2(props) {
51457
50607
 
51458
50608
  // src/DataBindingPicker.tsx
51459
50609
  var import_react292 = require("react");
51460
- var import_records71 = require("@ai-matrx/records");
50610
+ var import_records70 = require("@ai-matrx/records");
51461
50611
  var import_react293 = require("@ai-matrx/records/react");
51462
50612
  var import_design_system149 = require("@ai-matrx/design-system");
51463
50613
  var import_jsx_runtime166 = require("react/jsx-runtime");
@@ -51491,7 +50641,7 @@ function isCompleteDataBinding(binding) {
51491
50641
  }
51492
50642
  function bindingPlaceholdersFor(field2) {
51493
50643
  const label = fieldName(field2);
51494
- if ((0, import_records71.isEntityReferenceConfig)(field2.config)) {
50644
+ if ((0, import_records70.isEntityReferenceConfig)(field2.config)) {
51495
50645
  return [
51496
50646
  { token: `{${field2.key}.name}`, label: `${label} \xB7 name` },
51497
50647
  { token: `{${field2.key}.id}`, label: `${label} \xB7 id` }
@@ -51566,7 +50716,7 @@ function BindingDetails({
51566
50716
  }, [disabled, shape, binding, fields.loading, fieldList, table.data, onChange]);
51567
50717
  const selectShape = (next) => {
51568
50718
  if (next === shape) return;
51569
- const base = {
50719
+ const base2 = {
51570
50720
  kind: "merge_field",
51571
50721
  source: "record",
51572
50722
  semantic_type: next,
@@ -51574,21 +50724,21 @@ function BindingDetails({
51574
50724
  missing: binding.missing,
51575
50725
  override_policy: "shown_locked"
51576
50726
  };
51577
- if (next !== "collection" && binding.record_id) base.record_id = binding.record_id;
51578
- if (next === "value" && binding.field_key) base.field_key = binding.field_key;
50727
+ if (next !== "collection" && binding.record_id) base2.record_id = binding.record_id;
50728
+ if (next === "value" && binding.field_key) base2.field_key = binding.field_key;
51579
50729
  if (next === "collection") {
51580
50730
  const limit = binding.limit ?? defaultRowLimit;
51581
- if (limit) base.limit = limit;
50731
+ if (limit) base2.limit = limit;
51582
50732
  }
51583
50733
  if (next !== "value" && binding.transform) {
51584
- base.transform = {
50734
+ base2.transform = {
51585
50735
  name: "list",
51586
50736
  template: binding.transform.template,
51587
50737
  ...binding.transform.join !== void 0 ? { join: binding.transform.join } : {},
51588
- ...next === "collection" && base.limit !== void 0 ? { max: base.limit } : {}
50738
+ ...next === "collection" && base2.limit !== void 0 ? { max: base2.limit } : {}
51589
50739
  };
51590
50740
  }
51591
- onChange(base);
50741
+ onChange(base2);
51592
50742
  };
51593
50743
  const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
51594
50744
  const template = binding.transform?.template ?? "";