@ai-matrx/records-ui 0.113.31 → 0.113.33

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,9 @@ 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");
1554
+ var import_data = require("@ai-matrx/records/data");
1552
1555
  function sortRefusal(f) {
1553
1556
  if (!computedOnRead(f)) return null;
1554
1557
  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,26 +1564,6 @@ function computedOnRead(f) {
1561
1564
  const kind = String(editorKindFor(f));
1562
1565
  return (f.type === "formula" || kind === "formula" || kind === "lookup" || kind === "rollup") && String(f.compute_on ?? "read") === "read";
1563
1566
  }
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
- function containsPattern(text) {
1582
- return `(?i)${text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`;
1583
- }
1584
1567
  var BLANK_VALUE = "__empty__";
1585
1568
  var field = (f) => ({ field: f.id });
1586
1569
  var constant = (value) => ({ const: value });
@@ -1602,7 +1585,7 @@ function clauseFor(f, value, now = /* @__PURE__ */ new Date()) {
1602
1585
  if (kind === "number" || kind === "currency" || kind === "percent" || kind === "checkbox") {
1603
1586
  return `${name} holds numbers, so it is filtered by a range, not by words.`;
1604
1587
  }
1605
- const matches2 = op("matches", field(f), constant(containsPattern(text)));
1588
+ const matches2 = op("matches", field(f), constant((0, import_data.containsPattern)(text)));
1606
1589
  return { rule: value.negated ? not(matches2) : matches2 };
1607
1590
  }
1608
1591
  case "select": {
@@ -1621,7 +1604,7 @@ function clauseFor(f, value, now = /* @__PURE__ */ new Date()) {
1621
1604
  if (!value.negated) return { rule: blank ? op("or", not(present), anyDay) : anyDay };
1622
1605
  return { rule: blank ? op("and", present, not(anyDay)) : not(anyDay) };
1623
1606
  }
1624
- const asStored = (w) => holdsNumbers(f) || kind === "rating" ? Number.isFinite(Number(w)) ? Number(w) : w : kind === "checkbox" && (w === "true" || w === "false") ? w === "true" : w;
1607
+ 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
1608
  const stored = words2.map(asStored);
1626
1609
  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
1610
  if (!value.negated) {
@@ -1676,12 +1659,12 @@ function dayWindow(day, holdsDays) {
1676
1659
  const ymd = (t) => `${t.getUTCFullYear()}-${String(t.getUTCMonth() + 1).padStart(2, "0")}-${String(t.getUTCDate()).padStart(2, "0")}`;
1677
1660
  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
1661
  }
1679
- function storeQuestion(fields, base, columnFilters, now = /* @__PURE__ */ new Date()) {
1662
+ function storeQuestion(fields, base2, columnFilters, now = /* @__PURE__ */ new Date()) {
1680
1663
  const refused = [];
1681
1664
  const flat = {};
1682
1665
  const rules = [];
1683
- if (base && (0, import_records6.isRuleFilter)(base)) rules.push(base);
1684
- else if (base) Object.assign(flat, base);
1666
+ if (base2 && (0, import_records6.isRuleFilter)(base2)) rules.push(base2);
1667
+ else if (base2) Object.assign(flat, base2);
1685
1668
  for (const [key, value] of Object.entries(columnFilters)) {
1686
1669
  if (!value) continue;
1687
1670
  const f = fields.find((candidate) => candidate.key === key);
@@ -2221,32 +2204,7 @@ function useLabelWait(field2) {
2221
2204
  }
2222
2205
 
2223
2206
  // 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
- }
2207
+ var import_first_page3 = require("@ai-matrx/records/first-page");
2250
2208
  var ROW_HEIGHT_PX = {
2251
2209
  compact: 28,
2252
2210
  normal: void 0,
@@ -2604,7 +2562,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
2604
2562
  const [to, setTo] = (0, import_react10.useState)(null);
2605
2563
  const [preview, setPreview] = (0, import_react10.useState)(null);
2606
2564
  const [asking, setAsking] = (0, import_react10.useState)(false);
2607
- const [refusal4, setRefusal] = (0, import_react10.useState)(null);
2565
+ const [refusal3, setRefusal] = (0, import_react10.useState)(null);
2608
2566
  const [busy, setBusy] = (0, import_react10.useState)(false);
2609
2567
  const [said2, setSaid] = (0, import_react10.useState)(null);
2610
2568
  const name = fieldName(field2);
@@ -2702,7 +2660,7 @@ function FieldRetype({ field: field2, tableId, onRetyped }) {
2702
2660
  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
2661
  preview.partial ? ". Counted over the first 1,000 different values." : "."
2704
2662
  ] }) : null,
2705
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RefusalNotice, { error: refusal4 }) : null,
2663
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RefusalNotice, { error: refusal3 }) : null,
2706
2664
  said2 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "status", className: "text-[11px] text-muted-foreground", "data-records-retype-done": "", children: said2 }) : null
2707
2665
  ] });
2708
2666
  }
@@ -3476,10 +3434,10 @@ function TableDetails({
3476
3434
  if (slots.details.current === slot) slots.details.current = null;
3477
3435
  };
3478
3436
  }, [slots]);
3479
- const write = async (patch, base) => {
3437
+ const write = async (patch, base2) => {
3480
3438
  setBusy(true);
3481
3439
  setRefused(null);
3482
- const written = await (0, writeOnTheWinningVersion_exports.updateOnTheWinningVersion)(client, tableId, patch, await (0, recordVersions_exports.readTableVersionNow)(client, tableId), base);
3440
+ const written = await (0, writeOnTheWinningVersion_exports.updateOnTheWinningVersion)(client, tableId, patch, await (0, recordVersions_exports.readTableVersionNow)(client, tableId), base2);
3483
3441
  setBusy(false);
3484
3442
  if (!written.ok) {
3485
3443
  setRefused(refusalSentence(written.error));
@@ -4168,7 +4126,7 @@ function PersonPicker({ field: field2, value, onChange, disabled, id, className,
4168
4126
  // src/gridEditing.tsx
4169
4127
  var import_react64 = require("react");
4170
4128
  var import_records31 = require("@ai-matrx/records");
4171
- var import_core8 = require("@ai-matrx/records/core");
4129
+ var import_core7 = require("@ai-matrx/records/core");
4172
4130
  var import_react65 = require("@ai-matrx/records/react");
4173
4131
  var import_design_system37 = require("@ai-matrx/design-system");
4174
4132
 
@@ -4558,13 +4516,13 @@ function styleFromDecorations(decorations, fields) {
4558
4516
  return style;
4559
4517
  }
4560
4518
  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;
4519
+ const base2 = styleFromDecorations(decorations, fields);
4520
+ if (!viewStyle) return base2;
4521
+ const colorBy = viewStyle.colorBy ?? base2.colorBy;
4522
+ const rules = viewStyle.rules ?? base2.rules;
4523
+ const rows = viewStyle.rows ?? base2.rows;
4524
+ const columns = viewStyle.columns ?? base2.columns;
4525
+ const cells = viewStyle.cells ?? base2.cells;
4568
4526
  return {
4569
4527
  version: 1,
4570
4528
  ...colorBy !== void 0 ? { colorBy } : {},
@@ -4956,7 +4914,7 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
4956
4914
  const client = (0, import_react24.useOptionalRecordsClient)();
4957
4915
  const [rows, setRows] = (0, import_react23.useState)(null);
4958
4916
  const [words2, setWords] = (0, import_react23.useState)({});
4959
- const [refusal4, setRefusal] = (0, import_react23.useState)(null);
4917
+ const [refusal3, setRefusal] = (0, import_react23.useState)(null);
4960
4918
  const [search, setSearch] = (0, import_react23.useState)("");
4961
4919
  const [open, setOpenState] = (0, import_react23.useState)(autoOpen === true);
4962
4920
  const onCloseRef = (0, import_react23.useRef)(onClose);
@@ -5136,8 +5094,8 @@ function RelationPicker({ field: field2, value, onChange, disabled, id, classNam
5136
5094
  })),
5137
5095
  onPick: toggle,
5138
5096
  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,
5097
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(RefusalLine, { error: refusal3, className: "p-2" }) : null,
5098
+ !rows && !refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "p-2 text-xs text-muted-foreground", children: "Reading\u2026" }) : null,
5141
5099
  full ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "p-2 text-xs text-muted-foreground", children: [
5142
5100
  fieldName(field2),
5143
5101
  " can point at ",
@@ -5236,7 +5194,7 @@ function columnNameTakenLine(taken, noun = "column") {
5236
5194
  // src/FieldEditor.tsx
5237
5195
  var import_react50 = require("react");
5238
5196
  var import_react51 = require("@ai-matrx/records/react");
5239
- var import_core7 = require("@ai-matrx/records/core");
5197
+ var import_core6 = require("@ai-matrx/records/core");
5240
5198
  var import_design_system32 = require("@ai-matrx/design-system");
5241
5199
 
5242
5200
  // src/FormulaTextEditor.tsx
@@ -5550,500 +5508,22 @@ var import_design_system24 = require("@ai-matrx/design-system");
5550
5508
  var import_react29 = require("react");
5551
5509
 
5552
5510
  // 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;
5511
+ var import_first_page4 = require("@ai-matrx/records/first-page");
5570
5512
 
5571
5513
  // 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"
5842
- };
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"
5514
+ var base = __toESM(require("@ai-matrx/records/views"), 1);
5515
+ var import_views = require("@ai-matrx/records/views");
5516
+ var gridPresentationCodec = {
5517
+ parse: parseGridPresentation,
5518
+ isEmpty: presentationIsEmpty,
5519
+ toDocument: (presentation) => JSON.parse(presentationDocument(presentation))
6028
5520
  };
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
- }
5521
+ var boundViews = base.bindViewCodec(gridPresentationCodec);
5522
+ var { viewSettings, viewSettingsPatch } = boundViews;
6044
5523
 
6045
5524
  // src/firstPage.ts
6046
- var EMBEDDED_PAGE_SIZE = 50;
5525
+ var import_first_page5 = require("@ai-matrx/records/first-page");
5526
+ var { firstGridPageRequest, askTablePageSeed } = (0, import_first_page4.bindFirstPageCodec)(gridPresentationCodec);
6047
5527
 
6048
5528
  // src/embeddedLook.tsx
6049
5529
  var EMBEDDED_LOOK = { blankEmpty: true, choiceDot: true, plainRelation: true };
@@ -6366,16 +5846,16 @@ function Chips({
6366
5846
  }
6367
5847
 
6368
5848
  // src/values.tsx
6369
- var import_core6 = require("@ai-matrx/records/core");
5849
+ var import_core5 = require("@ai-matrx/records/core");
6370
5850
 
6371
5851
  // src/WholeValue.tsx
6372
5852
  var import_react32 = require("react");
6373
- var import_core5 = require("@ai-matrx/records/core");
5853
+ var import_core4 = require("@ai-matrx/records/core");
6374
5854
  var import_design_system17 = require("@ai-matrx/design-system");
6375
5855
  var import_jsx_runtime20 = require("react/jsx-runtime");
6376
5856
  var WHOLE_VALUE_UNBOUND = "The whole text is kept as a file, and this screen has no way to open files yet.";
6377
5857
  function wholeValueLine(pointer) {
6378
- return `Open the whole text (${(0, import_core5.wholeValueSize)(pointer)})`;
5858
+ return `Open the whole text (${(0, import_core4.wholeValueSize)(pointer)})`;
6379
5859
  }
6380
5860
  function WholeValueCell({ words: words2, pointer }) {
6381
5861
  const host = useRecordsUi();
@@ -6386,12 +5866,12 @@ function WholeValueCell({ words: words2, pointer }) {
6386
5866
  words2,
6387
5867
  "\u2026"
6388
5868
  ] }),
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` })
5869
+ 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
5870
  ] });
6391
5871
  }
6392
5872
  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
5873
  function wholeValueOpening(pointer) {
6394
- return `Opening the whole text (${(0, import_core5.wholeValueSize)(pointer)})\u2026`;
5874
+ return `Opening the whole text (${(0, import_core4.wholeValueSize)(pointer)})\u2026`;
6395
5875
  }
6396
5876
  function useWholeText(pointer) {
6397
5877
  const host = useRecordsUi();
@@ -7298,7 +6778,7 @@ function RetiredValues({
7298
6778
  }) {
7299
6779
  const client = (0, import_react39.useRecordsClient)();
7300
6780
  const [busy, setBusy] = (0, import_react38.useState)(null);
7301
- const [refusal4, setRefusal] = (0, import_react38.useState)(null);
6781
+ const [refusal3, setRefusal] = (0, import_react38.useState)(null);
7302
6782
  const [said2, setSaid] = (0, import_react38.useState)(null);
7303
6783
  const [missing, setMissing] = (0, import_react38.useState)(null);
7304
6784
  const kept = retiredValuesOf(document2);
@@ -7347,7 +6827,7 @@ function RetiredValues({
7347
6827
  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
6828
  ] }),
7349
6829
  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,
6830
+ refusal3?.key === id ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(RefusalNotice, { error: refusal3.error }) : null,
7351
6831
  missing === id ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: "text-[11px] text-muted-foreground", children: [
7352
6832
  "No earlier version of ",
7353
6833
  name,
@@ -7509,7 +6989,7 @@ function renderValue(field2, value, document2, labels, stillWaitingFor, look) {
7509
6989
  if ((0, import_records19.isButtonField)(field2)) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ButtonValue, { field: field2 });
7510
6990
  const newer = newerKindValue(field2, value);
7511
6991
  if (newer !== void 0) return newer;
7512
- const whole = typeof value === "string" ? (0, import_core6.wholeValueOf)(document2, field2.key) : null;
6992
+ const whole = typeof value === "string" ? (0, import_core5.wholeValueOf)(document2, field2.key) : null;
7513
6993
  if (whole) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(WholeValueCell, { words: value, pointer: whole });
7514
6994
  const kind = editorKindFor(field2);
7515
6995
  if (kind === "relation" || kind === "entity_reference") {
@@ -7633,7 +7113,7 @@ function scalarText(field2, value, labels, stillWaitingFor) {
7633
7113
  function ProvenanceBadge({ document: document2, fieldKey }) {
7634
7114
  const envelope = envelopeFor(document2, fieldKey);
7635
7115
  if (!envelope?.src) return null;
7636
- if ((0, import_core6.wholeValueOf)(document2, fieldKey)) return null;
7116
+ if ((0, import_core5.wholeValueOf)(document2, fieldKey)) return null;
7637
7117
  const sources = document2?._sources;
7638
7118
  const source = sources?.[envelope.src];
7639
7119
  const label = source ? Object.values(source).map(String).join(" \xB7 ") : envelope.src;
@@ -7669,7 +7149,7 @@ function RecordValue({
7669
7149
  const newer = newerKindValue(field2, value, { inCell });
7670
7150
  if (newer !== void 0) return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children: newer });
7671
7151
  }
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.
7152
+ 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
7153
  !kindValueOf(value)) {
7674
7154
  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
7155
  }
@@ -8202,7 +7682,7 @@ function ruleWords(rules) {
8202
7682
  function rulesChanged(was, now) {
8203
7683
  return ruleWords(was) !== ruleWords(now);
8204
7684
  }
8205
- function holdsNumbers2(field2) {
7685
+ function holdsNumbers3(field2) {
8206
7686
  return field2.type === "range";
8207
7687
  }
8208
7688
  function groupValue(value, numbers) {
@@ -8213,7 +7693,7 @@ function groupValue(value, numbers) {
8213
7693
  function FieldRulePreview({ field: field2, tableId, rules }) {
8214
7694
  const client = (0, import_react45.useRecordsClient)();
8215
7695
  const [preview, setPreview] = (0, import_react44.useState)(null);
8216
- const [refusal4, setRefusal] = (0, import_react44.useState)(null);
7696
+ const [refusal3, setRefusal] = (0, import_react44.useState)(null);
8217
7697
  const key = (0, import_react44.useMemo)(() => ruleWords(rules), [rules]);
8218
7698
  const latest = (0, import_react44.useRef)(rules);
8219
7699
  latest.current = rules;
@@ -8229,7 +7709,7 @@ function FieldRulePreview({ field: field2, tableId, rules }) {
8229
7709
  setRefusal(answer.error);
8230
7710
  return;
8231
7711
  }
8232
- const numbers = holdsNumbers2(field2);
7712
+ const numbers = holdsNumbers3(field2);
8233
7713
  const groups = answer.data.map((row) => ({ value: groupValue(row.groups[field2.key] ?? null, numbers), count: row.row_count }));
8234
7714
  setPreview((0, import_records21.previewRuleChange)(latest.current, groups, answer.data.length >= PREVIEW_GROUPS2));
8235
7715
  });
@@ -8239,7 +7719,7 @@ function FieldRulePreview({ field: field2, tableId, rules }) {
8239
7719
  clearTimeout(timer);
8240
7720
  };
8241
7721
  }, [client, tableId, field2.key, key]);
8242
- if (refusal4) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(RefusalNotice, { error: refusal4 });
7722
+ if (refusal3) return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(RefusalNotice, { error: refusal3 });
8243
7723
  if (!preview) {
8244
7724
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { className: "text-[11px] text-muted-foreground", "data-records-rule-preview": "counting", children: [
8245
7725
  "Counting ",
@@ -8300,9 +7780,9 @@ function choiceDisplayPatch(field2, rows) {
8300
7780
  }
8301
7781
  function lookFollowsRenames(field2, look, renames) {
8302
7782
  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;
7783
+ const base2 = look ?? displayFormatOf(field2);
7784
+ const choices = base2 && Array.isArray(base2.options["choices"]) ? base2.options["choices"] : null;
7785
+ if (!base2 || !choices) return look;
8306
7786
  let moved = false;
8307
7787
  const next = choices.map((c) => {
8308
7788
  const was = typeof c["value"] === "string" ? c["value"] : null;
@@ -8312,11 +7792,11 @@ function lookFollowsRenames(field2, look, renames) {
8312
7792
  return { ...c, value: now };
8313
7793
  });
8314
7794
  if (!moved) return look;
8315
- return { id: base.id, options: { ...base.options, choices: next } };
7795
+ return { id: base2.id, options: { ...base2.options, choices: next } };
8316
7796
  }
8317
7797
  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) => {
7798
+ const base2 = startingChoiceColors(field2, start.map((r) => r.words.trim()).filter((w) => w !== ""));
7799
+ const colorRows = base2.map((row) => {
8320
7800
  const was = start.find((r) => choiceWord(r.words) === choiceWord(row.value));
8321
7801
  const now = was?.id ? rows.find((r) => r.id === was.id) : void 0;
8322
7802
  return now ? { value: row.value, color: now.color ?? null } : row;
@@ -8747,9 +8227,9 @@ function storageOf(field2) {
8747
8227
  }
8748
8228
  }
8749
8229
  function formatMenu(field2) {
8750
- const base = storageOf(field2);
8751
- if (base === null) return { groups: [], otherKinds: [] };
8752
- if (base === "formula") {
8230
+ const base2 = storageOf(field2);
8231
+ if (base2 === null) return { groups: [], otherKinds: [] };
8232
+ if (base2 === "formula") {
8753
8233
  const groups2 = [];
8754
8234
  for (const def of import_field_formats6.FIELD_FORMAT_LIST) {
8755
8235
  if (neverALook(def) || KIND_WORD[def.id] || def.id === "boolean") continue;
@@ -8759,7 +8239,7 @@ function formatMenu(field2) {
8759
8239
  }
8760
8240
  return { groups: groups2, otherKinds: [] };
8761
8241
  }
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);
8242
+ 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
8243
  const own3 = new Set(groups.flatMap((g) => g.formats.map((d) => d.id)));
8764
8244
  const otherKinds = [];
8765
8245
  for (const def of import_field_formats6.FIELD_FORMAT_LIST) {
@@ -9597,7 +9077,7 @@ function FieldEditor(props) {
9597
9077
  return;
9598
9078
  }
9599
9079
  (0, import_react51.tableShapeChanged)(tableId);
9600
- for (const c of done.data.undo.cells_back) (0, import_core7.announceRecordChanged)(c.record_id);
9080
+ for (const c of done.data.undo.cells_back) (0, import_core6.announceRecordChanged)(c.record_id);
9601
9081
  const n = done.data.rehomed.reduce((sum, r) => sum + r.records, 0);
9602
9082
  setRehome({});
9603
9083
  setRehomed({ said: `Saved. ${n} ${n === 1 ? "record was" : "records were"} changed with the choices.`, undo: done.data.undo });
@@ -10079,7 +9559,7 @@ function FieldEditor(props) {
10079
9559
  return;
10080
9560
  }
10081
9561
  (0, import_react51.tableShapeChanged)(tableId);
10082
- for (const c of undo.cells_back) (0, import_core7.announceRecordChanged)(c.record_id);
9562
+ for (const c of undo.cells_back) (0, import_core6.announceRecordChanged)(c.record_id);
10083
9563
  setChoiceList(null);
10084
9564
  setChoiceListStart(null);
10085
9565
  setRehomed({ said: "Undone. The choices and the records that held them are back as they were.", undo: null });
@@ -11331,7 +10811,7 @@ function FieldControl({ field: field2, value, onChange, disabled, id, autoOpen,
11331
10811
  }
11332
10812
  function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
11333
10813
  const [text, setText] = (0, import_react59.useState)(() => openingText(field2, value));
11334
- const [refusal4, setRefusal] = (0, import_react59.useState)(null);
10814
+ const [refusal3, setRefusal] = (0, import_react59.useState)(null);
11335
10815
  const [why, setWhy] = (0, import_react59.useState)(void 0);
11336
10816
  const sent = (0, import_react59.useRef)(value);
11337
10817
  (0, import_react59.useEffect)(() => {
@@ -11362,11 +10842,11 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
11362
10842
  value: text,
11363
10843
  disabled,
11364
10844
  autoComplete: "off",
11365
- "aria-invalid": refusal4 ? true : void 0,
10845
+ "aria-invalid": refusal3 ? true : void 0,
11366
10846
  placeholder: helper ? typedDatePlaceholder(helper) : void 0,
11367
10847
  onChange: (e) => retype(e.target.value),
11368
10848
  onBlur: () => {
11369
- if (!refusal4) return;
10849
+ if (!refusal3) return;
11370
10850
  setText(openingText(field2, sent.current));
11371
10851
  setRefusal(null);
11372
10852
  }
@@ -11374,7 +10854,7 @@ function TypedWordsControl({ field: field2, value, onChange, disabled, id }) {
11374
10854
  ),
11375
10855
  helper && !disabled ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(TypedDateHelper, { kind: helper, text, onText: retype, label: fieldName(field2) }) : null
11376
10856
  ] }),
11377
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(FloatingRefusal, { text: refusal4, why }) : null
10857
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(FloatingRefusal, { text: refusal3, why }) : null
11378
10858
  ] });
11379
10859
  }
11380
10860
  function typedDatePlaceholder(helper) {
@@ -11478,7 +10958,7 @@ function inTheStoresOrder(options) {
11478
10958
  function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen, onClose, onCancel, addsChoices, initialSearch, asForm, onChosen }) {
11479
10959
  const client = (0, import_react60.useOptionalRecordsClient)();
11480
10960
  const [options, setOptions] = (0, import_react59.useState)(null);
11481
- const [refusal4, setRefusal] = (0, import_react59.useState)(null);
10961
+ const [refusal3, setRefusal] = (0, import_react59.useState)(null);
11482
10962
  const [reread, setReread] = (0, import_react59.useState)(0);
11483
10963
  (0, import_react59.useEffect)(() => {
11484
10964
  if (!client) return;
@@ -11510,8 +10990,8 @@ function OptionControl({ field: field2, value, onChange, disabled, id, autoOpen,
11510
10990
  /* @__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
10991
  ] });
11512
10992
  }
11513
- if (refusal4)
11514
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(RefusalLine, { error: refusal4 }) });
10993
+ if (refusal3)
10994
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { id, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(RefusalLine, { error: refusal3 }) });
11515
10995
  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
10996
  if (asForm && options.length > 0) {
11517
10997
  const titled = (option) => recordName(option.data, null, "Unnamed choice");
@@ -12199,7 +11679,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12199
11679
  }
12200
11680
  const held = optimistic[cellKey(address.rowId, address.key)];
12201
11681
  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;
11682
+ const pointer = held === void 0 && typeof current === "string" ? (0, import_core7.wholeValueOf)(document2, address.key) : null;
12203
11683
  if (pointer) {
12204
11684
  const read = host.readFileText;
12205
11685
  if (!read) return;
@@ -12250,7 +11730,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12250
11730
  startedFrom.current = null;
12251
11731
  }, []);
12252
11732
  const writeCellNow = (0, import_react64.useCallback)(
12253
- async (rowId, key, value, base, resent = false) => {
11733
+ async (rowId, key, value, base2, resent = false) => {
12254
11734
  const id = cellKey(rowId, key);
12255
11735
  const adding = isChoiceAddition(value) ? value : null;
12256
11736
  const shown4 = adding ? adding.value : value;
@@ -12267,7 +11747,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12267
11747
  let version = await versionOf(source, versions.current, versionReads.current, rowId);
12268
11748
  const drawnNow = await source.seen(rowId);
12269
11749
  const storedNow = rowsNow.current.find((r) => r.id === rowId)?.document?.[key];
12270
- if (drawnNow !== null && (version === null || drawnNow > version) && sameValue(storedNow, base)) {
11750
+ if (drawnNow !== null && (version === null || drawnNow > version) && sameValue(storedNow, base2)) {
12271
11751
  version = drawnNow;
12272
11752
  rememberVersion(versions.current, rowId, drawnNow);
12273
11753
  }
@@ -12296,13 +11776,13 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12296
11776
  if (written.ok) {
12297
11777
  rememberVersion(versions.current, rowId, written.data);
12298
11778
  source.wrote(rowId, written.data);
12299
- settling.current.set(id, base);
12300
- writtenRef.current?.({ rowId, key, before: base, after: shown4, version: written.data });
11779
+ settling.current.set(id, base2);
11780
+ writtenRef.current?.({ rowId, key, before: base2, after: shown4, version: written.data });
12301
11781
  afterWrite();
12302
11782
  return;
12303
11783
  }
12304
11784
  if (isUnsentWrite(written.error)) {
12305
- setRefusals((held) => ({ ...held, [id]: { error: written.error, conflict: null, attempted: value, unsent: true, base } }));
11785
+ setRefusals((held) => ({ ...held, [id]: { error: written.error, conflict: null, attempted: value, unsent: true, base: base2 } }));
12306
11786
  return;
12307
11787
  }
12308
11788
  setOptimistic((held) => {
@@ -12310,12 +11790,12 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12310
11790
  delete next[id];
12311
11791
  return next;
12312
11792
  });
12313
- const conflict = (0, import_core8.asWriteConflict)(written.error, rowId);
11793
+ const conflict = (0, import_core7.asWriteConflict)(written.error, rowId);
12314
11794
  if (written.error.code === "stale_write") {
12315
11795
  if (conflict) rememberVersion(versions.current, rowId, conflict.current_version);
12316
11796
  else versions.current.delete(rowId);
12317
- if (conflict && !resent && sameValue(conflict.contested_fields[key], base)) {
12318
- await writeCellNow(rowId, key, value, base, true);
11797
+ if (conflict && !resent && sameValue(conflict.contested_fields[key], base2)) {
11798
+ await writeCellNow(rowId, key, value, base2, true);
12319
11799
  return;
12320
11800
  }
12321
11801
  }
@@ -12332,9 +11812,9 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12332
11812
  [client, reload, afterWrite, source]
12333
11813
  );
12334
11814
  const writeCell = (0, import_react64.useCallback)(
12335
- (rowId, key, value, base) => {
11815
+ (rowId, key, value, base2) => {
12336
11816
  const behind = queues.current.get(rowId) ?? Promise.resolve();
12337
- const next = behind.then(() => writeCellNow(rowId, key, value, base));
11817
+ const next = behind.then(() => writeCellNow(rowId, key, value, base2));
12338
11818
  queues.current.set(
12339
11819
  rowId,
12340
11820
  next.then(
@@ -12398,7 +11878,7 @@ function useGridEditing({ tableId, fields, rows, reload, reloadAfterWrite, canWr
12398
11878
  }
12399
11879
  const starting = shownValue2(next.rowId, next.key);
12400
11880
  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)) {
11881
+ if (typeof starting === "string" && optimistic[cellKey(next.rowId, next.key)] === void 0 && (0, import_core7.wholeValueOf)(nextDocument, next.key)) {
12402
11882
  setEditing(null);
12403
11883
  setDraft(null);
12404
11884
  typed2.current = null;
@@ -12687,7 +12167,7 @@ function GridCell({
12687
12167
  };
12688
12168
  const value = editing ? editing.valueFor(row, field2) : row.document?.[field2.key];
12689
12169
  const state = editing ? editing.stateOf(row.id, field2.key) : null;
12690
- const refusal4 = editing ? editing.refusalOf(row.id, field2.key) : null;
12170
+ const refusal3 = editing ? editing.refusalOf(row.id, field2.key) : null;
12691
12171
  const editable = Boolean(editing) && canWrite && fieldIsEditable(field2);
12692
12172
  if (open && editing) {
12693
12173
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { "data-records-open-cell": "", className: "relative block w-full min-w-0", children: [
@@ -12724,10 +12204,10 @@ function GridCell({
12724
12204
  // state they are in, so only Discard is offered. It is INSIDE the open
12725
12205
  // cell, so pressing Discard is not "focus left the cell" — which would
12726
12206
  // commit the refused value one more time on its way out.
12727
- refusal4 && !refusal4.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12207
+ refusal3 && !refusal3.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12728
12208
  RefusalNotice,
12729
12209
  {
12730
- error: refusal4.error,
12210
+ error: refusal3.error,
12731
12211
  className: "py-1.5 text-left",
12732
12212
  onDiscard: () => editing.discard(row.id, field2.key)
12733
12213
  }
@@ -12752,14 +12232,14 @@ function GridCell({
12752
12232
  }
12753
12233
  ),
12754
12234
  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
12235
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: false }) : null
12756
12236
  ] });
12757
12237
  }
12758
12238
  if (editable && format?.id === "rating") {
12759
12239
  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
12240
  /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(FormattedValue, { value, format, onRate: (next) => editing?.setCell(row.id, field2.key, next), selectFirst: true }),
12761
12241
  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
12242
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: false }) : null
12763
12243
  ] });
12764
12244
  }
12765
12245
  const openThisCell = (event) => {
@@ -12881,40 +12361,40 @@ function GridCell({
12881
12361
  ) : null
12882
12362
  ] }),
12883
12363
  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
12364
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(CellRefusalNotice, { refusal: refusal3, field: field2, row, editing, typed: true }) : null
12885
12365
  ]
12886
12366
  }
12887
12367
  )
12888
12368
  );
12889
12369
  }
12890
12370
  function CellRefusalNotice({
12891
- refusal: refusal4,
12371
+ refusal: refusal3,
12892
12372
  field: field2,
12893
12373
  row,
12894
12374
  editing,
12895
12375
  typed: typed2
12896
12376
  }) {
12897
12377
  const [open, setOpen] = (0, import_react64.useState)(true);
12898
- const line = refusal4.unsent ? UNSENT_LINE : refusalLineForAPerson(refusal4.error);
12899
- const notice = refusal4.unsent ? (
12378
+ const line = refusal3.unsent ? UNSENT_LINE : refusalLineForAPerson(refusal3.error);
12379
+ const notice = refusal3.unsent ? (
12900
12380
  // NOT SENT, NOT REFUSED: what was typed is still in the cell; it goes again once online.
12901
12381
  /* @__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
12382
  /* @__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) }),
12383
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "max-w-[16rem] truncate text-muted-foreground", title: valueInALine(refusal3.attempted), children: valueInALine(refusal3.attempted) }),
12904
12384
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "flex flex-wrap gap-1", children: [
12905
12385
  /* @__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
12386
  /* @__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
12387
  ] })
12908
12388
  ] })
12909
- ) : refusal4.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12389
+ ) : refusal3.conflict ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12910
12390
  RefusalNotice,
12911
12391
  {
12912
- error: refusal4.error,
12392
+ error: refusal3.error,
12913
12393
  className: "py-1.5 text-left",
12914
12394
  actions: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "flex flex-col gap-1", "data-refusal-conflict": "", children: [
12915
12395
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-[11px]", children: [
12916
12396
  "Theirs: ",
12917
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("strong", { children: formatTheirs(refusal4.conflict, field2.key) })
12397
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("strong", { children: formatTheirs(refusal3.conflict, field2.key) })
12918
12398
  ] }),
12919
12399
  /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "flex flex-wrap gap-1", children: [
12920
12400
  /* @__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 +12405,7 @@ function CellRefusalNotice({
12925
12405
  ) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
12926
12406
  RefusalNotice,
12927
12407
  {
12928
- error: refusal4.error,
12408
+ error: refusal3.error,
12929
12409
  className: "py-1.5 text-left",
12930
12410
  ...typed2 ? { onKeepEditing: () => editing?.keepEditing(row.id, field2.key) } : {},
12931
12411
  onDiscard: () => editing?.discard(row.id, field2.key)
@@ -12939,8 +12419,8 @@ function CellRefusalNotice({
12939
12419
  "data-records-cell-refusal-line": "",
12940
12420
  title: line,
12941
12421
  "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"}`,
12422
+ "data-records-cell-unsent-mark": refusal3.unsent ? "" : void 0,
12423
+ 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
12424
  children: "!"
12945
12425
  }
12946
12426
  ) }),
@@ -13439,7 +12919,7 @@ var import_react128 = require("@ai-matrx/records/react");
13439
12919
  var import_records44 = require("@ai-matrx/records");
13440
12920
  var import_records45 = require("@ai-matrx/records");
13441
12921
  var import_data_table16 = require("@ai-matrx/design-system/data-table");
13442
- var import_core18 = require("@ai-matrx/records/core");
12922
+ var import_core17 = require("@ai-matrx/records/core");
13443
12923
 
13444
12924
  // src/tableDecorations.ts
13445
12925
  var import_react69 = require("react");
@@ -13541,7 +13021,7 @@ function EmptyRecords({ words: words2 }) {
13541
13021
 
13542
13022
  // src/gridControls.tsx
13543
13023
  var import_clipboard = require("@ai-matrx/kit/clipboard");
13544
- var import_core10 = require("@ai-matrx/records/core");
13024
+ var import_core9 = require("@ai-matrx/records/core");
13545
13025
  var import_react90 = require("react");
13546
13026
  var import_react91 = require("@ai-matrx/records/react");
13547
13027
  var import_design_system51 = require("@ai-matrx/design-system");
@@ -13563,7 +13043,7 @@ function MergeRecordDialog({ tableId, record, open, onOpenChange, onMerged }) {
13563
13043
  const records = (0, import_react72.useRecords)(tableId, { pageSize: 200 });
13564
13044
  const [other, setOther] = (0, import_react71.useState)(null);
13565
13045
  const [busy, setBusy] = (0, import_react71.useState)(false);
13566
- const [refusal4, setRefusal] = (0, import_react71.useState)(null);
13046
+ const [refusal3, setRefusal] = (0, import_react71.useState)(null);
13567
13047
  const options = (0, import_react71.useMemo)(
13568
13048
  () => (records.data?.rows ?? []).filter((row) => row.id !== record.id).map((row) => ({ value: row.id, label: rowNameIn(table.data ?? null, row) })),
13569
13049
  [records.data, record.id, table.data]
@@ -13633,7 +13113,7 @@ function MergeRecordDialog({ tableId, record, open, onOpenChange, onMerged }) {
13633
13113
  ariaLabel: "Record to merge"
13634
13114
  }
13635
13115
  ),
13636
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(RefusalNotice, { error: refusal4 }) : null,
13116
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(RefusalNotice, { error: refusal3 }) : null,
13637
13117
  /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_design_system40.DialogFooter, { children: [
13638
13118
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_design_system40.Button, { variant: "ghost", size: "sm", onClick: () => close(false), disabled: busy, children: "Cancel" }),
13639
13119
  /* @__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 +13283,7 @@ function useGridColours(args) {
13803
13283
  [client, tableId, decorations, notify]
13804
13284
  );
13805
13285
  const idOf = (0, import_react73.useCallback)((key) => fields.find((f) => f.key === key), [fields]);
13806
- const refusal4 = mayColour ? void 0 : whyNot;
13286
+ const refusal3 = mayColour ? void 0 : whyNot;
13807
13287
  const headerItem = (0, import_react73.useCallback)(
13808
13288
  (columnKey) => {
13809
13289
  if (!enabled) return null;
@@ -13818,7 +13298,7 @@ function useGridColours(args) {
13818
13298
  id: "col-colour",
13819
13299
  label: "Colour by\u2026",
13820
13300
  icon: "palette",
13821
- disabledReason: refusal4,
13301
+ disabledReason: refusal3,
13822
13302
  submenu: [
13823
13303
  byThis ? {
13824
13304
  id: "col-colour-off",
@@ -13854,7 +13334,7 @@ function useGridColours(args) {
13854
13334
  ]
13855
13335
  };
13856
13336
  },
13857
- [enabled, idOf, decorations.data, refusal4, write]
13337
+ [enabled, idOf, decorations.data, refusal3, write]
13858
13338
  );
13859
13339
  const cellItem = (0, import_react73.useCallback)(
13860
13340
  (rowId, columnKey) => {
@@ -13866,7 +13346,7 @@ function useGridColours(args) {
13866
13346
  id: "cell-highlight",
13867
13347
  label: "Highlight cell",
13868
13348
  icon: "palette",
13869
- disabledReason: refusal4,
13349
+ disabledReason: refusal3,
13870
13350
  submenu: swatches(
13871
13351
  "cell-highlight",
13872
13352
  current,
@@ -13874,7 +13354,7 @@ function useGridColours(args) {
13874
13354
  )
13875
13355
  };
13876
13356
  },
13877
- [enabled, idOf, decorations.data, refusal4, write]
13357
+ [enabled, idOf, decorations.data, refusal3, write]
13878
13358
  );
13879
13359
  const cellsItem = (0, import_react73.useCallback)(
13880
13360
  (cells) => {
@@ -13884,7 +13364,7 @@ function useGridColours(args) {
13884
13364
  id: "sel-highlight",
13885
13365
  label: `Highlight ${n} cells`,
13886
13366
  icon: "palette",
13887
- disabledReason: refusal4,
13367
+ disabledReason: refusal3,
13888
13368
  submenu: swatches("sel-highlight", void 0, (color) => {
13889
13369
  void (async () => {
13890
13370
  let kept = 0;
@@ -13904,7 +13384,7 @@ function useGridColours(args) {
13904
13384
  })
13905
13385
  };
13906
13386
  },
13907
- [enabled, idOf, refusal4, client, tableId, decorations, notify]
13387
+ [enabled, idOf, refusal3, client, tableId, decorations, notify]
13908
13388
  );
13909
13389
  const rowItem = (0, import_react73.useCallback)(
13910
13390
  (rowId) => {
@@ -13914,7 +13394,7 @@ function useGridColours(args) {
13914
13394
  id: "row-highlight",
13915
13395
  label: "Highlight row",
13916
13396
  icon: "palette",
13917
- disabledReason: refusal4,
13397
+ disabledReason: refusal3,
13918
13398
  submenu: swatches(
13919
13399
  "row-highlight",
13920
13400
  current,
@@ -13922,7 +13402,7 @@ function useGridColours(args) {
13922
13402
  )
13923
13403
  };
13924
13404
  },
13925
- [enabled, decorations.data, refusal4, write]
13405
+ [enabled, decorations.data, refusal3, write]
13926
13406
  );
13927
13407
  const dialogs = enabled ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
13928
13408
  ColourRulesDialog,
@@ -14673,7 +14153,7 @@ function stepOf(step2, original) {
14673
14153
  return { field: field2, set: "value", value: step2.value };
14674
14154
  }
14675
14155
  function actionOf(draft, original) {
14676
- const base = {
14156
+ const base2 = {
14677
14157
  ...draft.id ? { id: draft.id } : {},
14678
14158
  name: draft.name.trim(),
14679
14159
  kind: draft.kind,
@@ -14681,9 +14161,9 @@ function actionOf(draft, original) {
14681
14161
  ...draft.color ? { color: draft.color } : {},
14682
14162
  ...draft.icon ? { icon: draft.icon } : {}
14683
14163
  };
14684
- if (draft.kind === "agent") return { ...base, prompt: draft.prompt };
14164
+ if (draft.kind === "agent") return { ...base2, prompt: draft.prompt };
14685
14165
  return {
14686
- ...base,
14166
+ ...base2,
14687
14167
  steps: draft.steps.map((s, i) => stepOf(s, original?.steps?.[i]))
14688
14168
  };
14689
14169
  }
@@ -15829,7 +15309,7 @@ function WholeTextDialog({
15829
15309
  }
15830
15310
 
15831
15311
  // src/pasteValues.ts
15832
- var import_core9 = require("@ai-matrx/records/core");
15312
+ var import_core8 = require("@ai-matrx/records/core");
15833
15313
  var import_records36 = require("@ai-matrx/records");
15834
15314
  function wordForStoredChoice(options, value) {
15835
15315
  if (options === void 0 || typeof value !== "string" || value === "") return null;
@@ -15908,20 +15388,20 @@ function planPastedBlock(args) {
15908
15388
  });
15909
15389
  accepted[key] = judged.value;
15910
15390
  }
15911
- const predicted = (0, import_core9.predictValueRefusals)(args.fields, accepted);
15912
- for (const refusal4 of predicted) {
15913
- const key = refusal4.field_key;
15391
+ const predicted = (0, import_core8.predictValueRefusals)(args.fields, accepted);
15392
+ for (const refusal3 of predicted) {
15393
+ const key = refusal3.field_key;
15914
15394
  if (key === void 0) continue;
15915
15395
  const cell2 = built.find((b) => b.key === key && b.refusal === null);
15916
15396
  if (!cell2) continue;
15917
- cell2.refusal = refusal4.message;
15397
+ cell2.refusal = refusal3.message;
15918
15398
  cell2.value = null;
15919
15399
  delete accepted[key];
15920
15400
  refusals.push({
15921
15401
  fromLine,
15922
15402
  column: fieldName(byKey.get(key) ?? { key }),
15923
15403
  raw: cell2.raw,
15924
- why: refusal4.message
15404
+ why: refusal3.message
15925
15405
  });
15926
15406
  }
15927
15407
  cells += Object.keys(accepted).length;
@@ -16125,8 +15605,8 @@ function useMergedGridControls(args) {
16125
15605
  setHeld(null);
16126
15606
  }, [keptKey]);
16127
15607
  const order = (0, import_react90.useMemo)(() => {
16128
- const base = held?.order ?? columnsInKeptOrder(fieldKeys, keptOrder);
16129
- const known = columnsInKeptOrder(fieldKeys, base);
15608
+ const base2 = held?.order ?? columnsInKeptOrder(fieldKeys, keptOrder);
15609
+ const known = columnsInKeptOrder(fieldKeys, base2);
16130
15610
  if (frozenKeys.size === 0) return known;
16131
15611
  return [...known.filter((k) => frozenKeys.has(k)), ...known.filter((k) => !frozenKeys.has(k))];
16132
15612
  }, [held, fieldKeys, keptOrder, frozenKeys]);
@@ -16175,17 +15655,17 @@ function useMergedGridControls(args) {
16175
15655
  const fieldsRef = (0, import_react90.useRef)(fields);
16176
15656
  fieldsRef.current = fields;
16177
15657
  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]);
15658
+ (0, import_react90.useEffect)(() => (0, import_core9.onRecordChanged)(() => (0, askOnce_exports.forgetAsked)(client, `value_counts:${tableId}:`)), [client, tableId]);
16179
15659
  (0, import_react90.useEffect)(() => {
16180
15660
  if (!enabled || choiceKeys.length === 0) {
16181
15661
  setChoiceCounts({});
16182
15662
  return;
16183
15663
  }
16184
15664
  let cancelled = false;
16185
- const [keys, filters, base, searched] = JSON.parse(countQuestionKey);
15665
+ const [keys, filters, base2, searched] = JSON.parse(countQuestionKey);
16186
15666
  for (const key of keys) {
16187
15667
  const { [key]: _own, ...others } = filters;
16188
- const asked2 = storeQuestion(fieldsRef.current, base ?? void 0, others);
15668
+ const asked2 = storeQuestion(fieldsRef.current, base2 ?? void 0, others);
16189
15669
  void (0, askOnce_exports.askOnce)(
16190
15670
  client,
16191
15671
  `value_counts:${tableId}:${key}:${searched}:${JSON.stringify(asked2.filter ?? null)}`,
@@ -16801,9 +16281,9 @@ function readersThrough(fields, key) {
16801
16281
  });
16802
16282
  }
16803
16283
  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}`;
16284
+ 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.`;
16285
+ if (readers.length === 0) return base2;
16286
+ return `${readersSentence(readers.length, tableName2)} ${base2}`;
16807
16287
  }
16808
16288
  function afterMenuLayerCloses(next) {
16809
16289
  if (typeof window === "undefined") return next();
@@ -16832,7 +16312,7 @@ var import_design_system55 = require("@ai-matrx/design-system");
16832
16312
  // src/RecordForm.tsx
16833
16313
  var import_react96 = require("react");
16834
16314
  var import_react97 = require("@ai-matrx/records/react");
16835
- var import_core12 = require("@ai-matrx/records/core");
16315
+ var import_core11 = require("@ai-matrx/records/core");
16836
16316
  var import_design_system54 = require("@ai-matrx/design-system");
16837
16317
  var import_text_case6 = require("@ai-matrx/kit/text-case");
16838
16318
 
@@ -16845,7 +16325,7 @@ var import_design_system53 = require("@ai-matrx/design-system");
16845
16325
  var import_react92 = require("react");
16846
16326
  var import_react93 = require("@ai-matrx/records/react");
16847
16327
  var import_design_system52 = require("@ai-matrx/design-system");
16848
- var import_core11 = require("@ai-matrx/records/core");
16328
+ var import_core10 = require("@ai-matrx/records/core");
16849
16329
  var import_jsx_runtime59 = require("react/jsx-runtime");
16850
16330
  function isEmptyValue(value) {
16851
16331
  return value === null || value === void 0 || value === "" || Array.isArray(value) && value.length === 0;
@@ -16917,7 +16397,7 @@ async function writeStandardRowValues(client, args) {
16917
16397
  { schema: config.schema ?? "custom" }
16918
16398
  );
16919
16399
  if (!old.error) return { ok: true };
16920
- const error = (0, import_core11.mapPgError)(old.error, "entityValueWrite");
16400
+ const error = (0, import_core10.mapPgError)(old.error, "entityValueWrite");
16921
16401
  return { ok: false, error: doorIsAbsent(error) && first && first.error.code !== "door_absent" ? first.error : error };
16922
16402
  }
16923
16403
  function doorIsAbsent(error) {
@@ -17498,7 +16978,7 @@ function CustomRecordForm({
17498
16978
  return out;
17499
16979
  }, [draft]);
17500
16980
  const predicted = (0, import_react96.useMemo)(
17501
- () => fields.data ? (0, import_core12.predictWriteRefusals)({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
16981
+ () => fields.data ? (0, import_core11.predictWriteRefusals)({ fields: fields.data, document: document2, ...recordType ? { recordType } : {} }) : [],
17502
16982
  [fields.data, document2, recordType]
17503
16983
  );
17504
16984
  if (fields.error) return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(RefusalNotice, { error: fields.error, className });
@@ -17548,7 +17028,7 @@ function CustomRecordForm({
17548
17028
  setEdit({
17549
17029
  saving: false,
17550
17030
  error: answered2.ok ? null : answered2.error,
17551
- conflict: answered2.ok ? null : (0, import_core12.asWriteConflict)(answered2.error, recordId)
17031
+ conflict: answered2.ok ? null : (0, import_core11.asWriteConflict)(answered2.error, recordId)
17552
17032
  });
17553
17033
  const moved = answered2.ok ? answered2.data : null;
17554
17034
  if (moved !== null) {
@@ -17659,7 +17139,7 @@ function FieldRow({
17659
17139
  }) {
17660
17140
  const id = `field-${field2.id}`;
17661
17141
  const storedWords = document2?.[field2.key];
17662
- const whole = typeof storedWords === "string" ? (0, import_core12.wholeValueOf)(document2, field2.key) : null;
17142
+ const whole = typeof storedWords === "string" ? (0, import_core11.wholeValueOf)(document2, field2.key) : null;
17663
17143
  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
17144
  /* @__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
17145
  whole ? (
@@ -18110,8 +17590,8 @@ function useDrillDefinition(source) {
18110
17590
  }, [client, key]);
18111
17591
  return state.key === key ? { def: state.def, error: state.error } : { def: null, error: null };
18112
17592
  }
18113
- function drillWhere(base, trail, booleans) {
18114
- const where = { ...base ?? {} };
17593
+ function drillWhere(base2, trail, booleans) {
17594
+ const where = { ...base2 ?? {} };
18115
17595
  for (const w of trail) {
18116
17596
  const { key, grain } = (0, import_data_table14.parseDimensionRef)(w.dim);
18117
17597
  if (grain) where[w.dim] = w.value;
@@ -18290,10 +17770,10 @@ function useDrill(args) {
18290
17770
  const booleans = (0, import_react102.useMemo)(() => new Set((def?.dimensions ?? []).filter((d) => d.kind === "boolean").map((d) => d.key)), [def]);
18291
17771
  const baseKey = JSON.stringify(args.base ?? []);
18292
17772
  const filter = (0, import_react102.useMemo)(() => {
18293
- const base = JSON.parse(baseKey);
18294
- if (base.length === 0) return args.filter;
17773
+ const base2 = JSON.parse(baseKey);
17774
+ if (base2.length === 0) return args.filter;
18295
17775
  const out = { ...args.filter ?? {} };
18296
- for (const b of base) out[b.key] = b.value;
17776
+ for (const b of base2) out[b.key] = b.value;
18297
17777
  return out;
18298
17778
  }, [args.filter, baseKey]);
18299
17779
  const where = (0, import_react102.useMemo)(() => drillWhere(filter, question.where, booleans), [filter, question.where, booleans]);
@@ -18422,17 +17902,17 @@ function trailClause(fields, w) {
18422
17902
  }
18423
17903
  return { key, value: w.value, field: field2 };
18424
17904
  }
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 ?? {} };
17905
+ function filterWithTrail(fields, base2, trail) {
17906
+ if (trail.length === 0) return base2;
17907
+ if (!base2 || !(0, import_records37.isRuleFilter)(base2)) {
17908
+ const flat = { ...base2 ?? {} };
18429
17909
  for (const w of trail) {
18430
17910
  const clause = trailClause(fields, w);
18431
17911
  flat[clause.key] = clause.value;
18432
17912
  }
18433
17913
  return flat;
18434
17914
  }
18435
- const args = [base];
17915
+ const args = [base2];
18436
17916
  for (const w of trail) {
18437
17917
  const clause = trailClause(fields, w);
18438
17918
  if (!clause.field) continue;
@@ -18446,14 +17926,14 @@ function filterWithTrail(fields, base, trail) {
18446
17926
  }
18447
17927
  return { op: "and", args };
18448
17928
  }
18449
- function filterWithWindow(fields, base, key, range) {
18450
- if (!base || !(0, import_records37.isRuleFilter)(base)) return { ...base ?? {}, [key]: { from: range.from, to: range.to } };
17929
+ function filterWithWindow(fields, base2, key, range) {
17930
+ if (!base2 || !(0, import_records37.isRuleFilter)(base2)) return { ...base2 ?? {}, [key]: { from: range.from, to: range.to } };
18451
17931
  const field2 = fields.find((f) => f.key === key);
18452
- if (!field2) return base;
17932
+ if (!field2) return base2;
18453
17933
  const ref = { field: field2.id };
18454
17934
  return {
18455
17935
  op: "and",
18456
- args: [base, { op: "gte", args: [ref, { const: range.from }] }, { op: "lt", args: [ref, { const: range.to }] }]
17936
+ args: [base2, { op: "gte", args: [ref, { const: range.from }] }, { op: "lt", args: [ref, { const: range.to }] }]
18457
17937
  };
18458
17938
  }
18459
17939
  function useGridDrillQuestion(args) {
@@ -19120,7 +18600,7 @@ function columnForField(field2, editing, mayWriteRow, whyNotRow, look, onAskWhoC
19120
18600
  ...look?.frozen ? { frozen: true, width: Math.max(FROZEN_COLUMN_WIDTH, defaultColumnWidth(field2)) } : { width: defaultColumnWidth(field2) },
19121
18601
  // A column that holds numbers filters as numbers (=, <, >, between) — the record number too,
19122
18602
  // 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",
18603
+ filter: filterRefusal(field2) !== null ? false : editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? "select" : (0, import_first_page2.holdsNumbers)(field2) ? "number" : "auto",
19124
18604
  // THE MENU'S VALUE LIST WEARS THE CHOICES' COLOURS (lane CELL-EDITORS, night walk 2026-10-06): the
19125
18605
  // same chip the cell draws, never bare words beside a coloured column.
19126
18606
  ...editorKindFor(field2) === "select" || editorKindFor(field2) === "multi_select" ? { filterValueClass: (value, label) => choiceChipLookOf(field2, value, label).className } : {},
@@ -19247,6 +18727,11 @@ function withTypeMark(field2, header) {
19247
18727
  // src/ReverseColumns.tsx
19248
18728
  var import_react106 = require("react");
19249
18729
  var import_records38 = require("@ai-matrx/records");
18730
+
18731
+ // src/groupReads.ts
18732
+ var import_first_page6 = require("@ai-matrx/records/first-page");
18733
+
18734
+ // src/ReverseColumns.tsx
19250
18735
  var import_react107 = require("@ai-matrx/records/react");
19251
18736
  var import_design_system58 = require("@ai-matrx/design-system");
19252
18737
  var import_jsx_runtime65 = require("react/jsx-runtime");
@@ -19320,7 +18805,7 @@ function useReverseGridColumns(tableId, rowIds) {
19320
18805
  const reverse = (0, import_react107.useReverseColumns)(tableId);
19321
18806
  const columns = useStableColumns(reverse.data);
19322
18807
  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);
18808
+ const links = (0, import_react107.useReverseLinks)(tableId, columns, ids, import_first_page6.REVERSE_CELL_CHIPS);
19324
18809
  const held = useLinksStore(links.data, links.loading);
19325
18810
  return (0, import_react106.useMemo)(
19326
18811
  () => columns.length === 0 ? NO_GRID_COLUMNS : columns.map((column) => ({
@@ -19707,10 +19192,10 @@ function PastePreview({
19707
19192
  /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(PlanTable, { plan }),
19708
19193
  plan.refusals.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { "data-matrx-paste-refusals": true, className: "flex flex-col gap-1", children: [
19709
19194
  /* @__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 }),
19195
+ /* @__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: [
19196
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "font-medium", children: refusal3.fromLine > 0 ? `Row ${refusal3.fromLine}, ${refusal3.column}` : refusal3.column }),
19712
19197
  " \u2014 ",
19713
- refusal4.why
19198
+ refusal3.why
19714
19199
  ] }, index)) }),
19715
19200
  plan.refusals.length > 12 ? /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
19716
19201
  plan.refusals.length - 12,
@@ -19936,12 +19421,12 @@ function withOpenRecord(columns, onOpen, nameOf2, place = "end", hrefOf) {
19936
19421
  // src/ImportWizard.tsx
19937
19422
  var import_react109 = require("react");
19938
19423
  var import_react110 = require("@ai-matrx/records/react");
19939
- var import_core14 = require("@ai-matrx/records/core");
19424
+ var import_core13 = require("@ai-matrx/records/core");
19940
19425
  var import_design_system60 = require("@ai-matrx/design-system");
19941
19426
  var import_records41 = require("@ai-matrx/records");
19942
19427
 
19943
19428
  // src/importRuleCheck.ts
19944
- var import_core13 = require("@ai-matrx/records/core");
19429
+ var import_core12 = require("@ai-matrx/records/core");
19945
19430
  function checkImportRules(fields, rows, mapping, choiceOptions, relationNames) {
19946
19431
  const byKey = new Map(fields.map((f) => [f.key, f]));
19947
19432
  const verdicts = [];
@@ -19967,7 +19452,7 @@ function checkImportRules(fields, rows, mapping, choiceOptions, relationNames) {
19967
19452
  if ("unmatchedNames" in meant) return;
19968
19453
  if ("refusal" in meant) why = meant.refusal;
19969
19454
  else {
19970
- const predicted = (0, import_core13.predictValueRefusals)([field2], { [key]: meant.value }).filter(
19455
+ const predicted = (0, import_core12.predictValueRefusals)([field2], { [key]: meant.value }).filter(
19971
19456
  (p) => p.field_key === void 0 || p.field_key === key
19972
19457
  );
19973
19458
  if (predicted.length > 0) why = predicted[0].message;
@@ -20174,8 +19659,8 @@ function offerDownload(name, text, type = "text/csv") {
20174
19659
  return true;
20175
19660
  }
20176
19661
  function refusedFileName(sourceName) {
20177
- const base = (sourceName ?? "import").replace(/\.(csv|xlsx)$/i, "");
20178
- return `${base} \u2014 rows not added.csv`;
19662
+ const base2 = (sourceName ?? "import").replace(/\.(csv|xlsx)$/i, "");
19663
+ return `${base2} \u2014 rows not added.csv`;
20179
19664
  }
20180
19665
 
20181
19666
  // src/ImportWizard.tsx
@@ -20471,7 +19956,7 @@ function ImportWizard({ tableId, source, onDone, onWrote, className }) {
20471
19956
  try {
20472
19957
  const xlsx = file.name.toLowerCase().endsWith(".xlsx");
20473
19958
  const bytes = await file.arrayBuffer();
20474
- const result = xlsx ? await (0, import_core14.importXlsx)(bytes) : (0, import_core14.importCsv)(new TextDecoder().decode(bytes));
19959
+ const result = xlsx ? await (0, import_core13.importXlsx)(bytes) : (0, import_core13.importCsv)(new TextDecoder().decode(bytes));
20475
19960
  await planFrom(result, { name: file.name, bytes: file.size, hash: await sha256(bytes), format: xlsx ? "xlsx" : "csv" });
20476
19961
  } catch (thrown) {
20477
19962
  setProblem(
@@ -21629,11 +21114,11 @@ function cellWords(raw) {
21629
21114
  function uniqueLabels(raw) {
21630
21115
  const seen = /* @__PURE__ */ new Map();
21631
21116
  return raw.map((label, index) => {
21632
- const base = label.trim() || `Column ${index + 1}`;
21633
- const key = base.toLowerCase();
21117
+ const base2 = label.trim() || `Column ${index + 1}`;
21118
+ const key = base2.toLowerCase();
21634
21119
  const count = (seen.get(key) ?? 0) + 1;
21635
21120
  seen.set(key, count);
21636
- return count === 1 ? base : `${base} ${count}`;
21121
+ return count === 1 ? base2 : `${base2} ${count}`;
21637
21122
  });
21638
21123
  }
21639
21124
  function rowsOf(headers, matrix) {
@@ -21694,7 +21179,7 @@ function recordsFromPairs(pairs) {
21694
21179
  if (current.size > 0) records.push(current);
21695
21180
  return records;
21696
21181
  }
21697
- function shapeFromRecords(records, base, from) {
21182
+ function shapeFromRecords(records, base2, from) {
21698
21183
  const order = [];
21699
21184
  for (const r of records) for (const k of r.keys()) if (!order.some((o) => o.toLowerCase() === k.toLowerCase())) order.push(k);
21700
21185
  const headers = uniqueLabels(order);
@@ -21707,7 +21192,7 @@ function shapeFromRecords(records, base, from) {
21707
21192
  return row;
21708
21193
  });
21709
21194
  return {
21710
- ...base,
21195
+ ...base2,
21711
21196
  kind: "key_value",
21712
21197
  headers,
21713
21198
  rows,
@@ -22275,7 +21760,7 @@ function valueListKind(field2) {
22275
21760
  if (kind === "text" || kind === "long_text" || kind === "email" || kind === "phone" || kind === "url") return "words";
22276
21761
  if (kind === "datetime" || kind === "date") return "days";
22277
21762
  if (kind === "checkbox") return "yesno";
22278
- if (holdsNumbers(field2) || kind === "rating") return "numbers";
21763
+ if ((0, import_first_page2.holdsNumbers)(field2) || kind === "rating") return "numbers";
22279
21764
  return "loaded";
22280
21765
  }
22281
21766
  function noValueList(columnId2) {
@@ -22407,7 +21892,7 @@ function useGroupFacts(args) {
22407
21892
  const entries = JSON.parse(chosenKey);
22408
21893
  const asked2 = JSON.parse(filterKey);
22409
21894
  const filter = Object.keys(asked2).length > 0 ? asked2 : void 0;
22410
- const measures = groupFactMeasures(Object.fromEntries(entries));
21895
+ const measures = (0, import_first_page6.groupFactMeasures)(Object.fromEntries(entries));
22411
21896
  let cancelled = false;
22412
21897
  void client.recordAggregate({ table_id: tableId, groupBy: [groupKey], measures, limit: 1e3, ...filter ? { filter } : {} }).then((answered) => {
22413
21898
  if (cancelled) return;
@@ -22480,7 +21965,7 @@ function useGroupLabel(fields, groupKey) {
22480
21965
  // src/gridUndo.tsx
22481
21966
  var import_react117 = require("react");
22482
21967
  var import_react118 = require("@ai-matrx/records/react");
22483
- var import_core15 = require("@ai-matrx/records/core");
21968
+ var import_core14 = require("@ai-matrx/records/core");
22484
21969
  var import_design_system62 = require("@ai-matrx/design-system");
22485
21970
  var import_data_table15 = require("@ai-matrx/design-system/data-table");
22486
21971
  var import_jsx_runtime73 = require("react/jsx-runtime");
@@ -22541,40 +22026,40 @@ function useGridUndo(args) {
22541
22026
  if (!step2) return;
22542
22027
  setBusy(true);
22543
22028
  const changes = changesFor(step2, direction, known.current);
22544
- let refusal4 = null;
22029
+ let refusal3 = null;
22545
22030
  if (direction === "redo" && (step2.created?.length ?? 0) > 0) {
22546
22031
  const answers = await Promise.all((step2.created ?? []).map((id) => client.recordRestore({ record_id: id })));
22547
22032
  const failed = answers.find((a) => !a.ok);
22548
- if (failed && !failed.ok) refusal4 = failed.error;
22033
+ if (failed && !failed.ok) refusal3 = failed.error;
22549
22034
  }
22550
- if (!refusal4 && step2.retiredField) {
22035
+ if (!refusal3 && step2.retiredField) {
22551
22036
  const fieldId = step2.retiredField.fieldId;
22552
22037
  const done = direction === "undo" ? await client.fieldRestore({ field_id: fieldId }) : await client.fieldRetire({ field_id: fieldId });
22553
- if (!done.ok) refusal4 = done.error;
22038
+ if (!done.ok) refusal3 = done.error;
22554
22039
  else (0, import_react118.tableShapeChanged)(tableId);
22555
22040
  }
22556
- if (!refusal4 && changes.length > 0) {
22041
+ if (!refusal3 && changes.length > 0) {
22557
22042
  const done = await (0, recordVersions_exports.changeRecordsAt)(client, { table_id: tableId, changes });
22558
- if (!done.ok) refusal4 = done.error;
22043
+ if (!done.ok) refusal3 = done.error;
22559
22044
  else {
22560
22045
  for (const result of done.data ?? []) if (result.op === "update") known.current.set(result.id, result.version);
22561
22046
  onVersions?.((done.data ?? []).flatMap((r) => r.op === "update" ? [{ id: r.id, version: r.version }] : []));
22562
22047
  }
22563
22048
  }
22564
- if (!refusal4 && direction === "undo" && (step2.archived?.length ?? 0) > 0) {
22049
+ if (!refusal3 && direction === "undo" && (step2.archived?.length ?? 0) > 0) {
22565
22050
  const answers = await Promise.all((step2.archived ?? []).map((id) => client.recordRestore({ record_id: id })));
22566
22051
  const failed = answers.find((a) => !a.ok);
22567
- if (failed && !failed.ok) refusal4 = failed.error;
22052
+ if (failed && !failed.ok) refusal3 = failed.error;
22568
22053
  }
22569
22054
  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();
22055
+ if (refusal3) {
22056
+ setNotice({ says: `${direction === "undo" ? "Undo" : "Redo"} changed nothing: ${refusalSentence(refusal3)}`, refusal: refusal3, canUndo: false });
22057
+ if ((0, recordVersions_exports.isChangedElsewhere)(refusal3)) reload();
22573
22058
  return;
22574
22059
  }
22575
22060
  forget(step2.cells.map((c) => ({ rowId: c.rowId, key: c.key })));
22576
22061
  for (const id of /* @__PURE__ */ new Set([...step2.cells.map((c) => c.rowId), ...step2.created ?? [], ...step2.archived ?? []])) {
22577
- (0, import_core15.announceRecordChanged)(id);
22062
+ (0, import_core14.announceRecordChanged)(id);
22578
22063
  }
22579
22064
  setHeld(() => {
22580
22065
  let stack = taken.stack;
@@ -22962,7 +22447,7 @@ function holdKeys() {
22962
22447
  // src/gridAssist.tsx
22963
22448
  var import_clipboard2 = require("@ai-matrx/kit/clipboard");
22964
22449
  var import_react121 = require("react");
22965
- var import_core16 = require("@ai-matrx/records/core");
22450
+ var import_core15 = require("@ai-matrx/records/core");
22966
22451
  var import_workspace = require("@ai-matrx/alchemy/react/workspace");
22967
22452
 
22968
22453
  // src/gridAgentContext.ts
@@ -23092,7 +22577,7 @@ function useGridAssist(args) {
23092
22577
  const copyRecordReference = (0, import_react121.useCallback)(
23093
22578
  (rowId) => {
23094
22579
  void (async () => {
23095
- const text = JSON.stringify({ __kind: (0, import_core16.tableKindSlug)(tableId), _record_id: rowId });
22580
+ const text = JSON.stringify({ __kind: (0, import_core15.tableKindSlug)(tableId), _record_id: rowId });
23096
22581
  if (!await (0, import_clipboard2.copyText)(text)) {
23097
22582
  say2(false, "This browser did not let the page write to the clipboard.");
23098
22583
  return;
@@ -23148,7 +22633,7 @@ function useGridAssist(args) {
23148
22633
  if (!row) return;
23149
22634
  const document2 = row.document ?? {};
23150
22635
  const value = editing.valueFor(row, fieldOf2(key));
23151
- const pointer = typeof document2[key] === "string" ? (0, import_core16.wholeValueOf)(document2, key) : null;
22636
+ const pointer = typeof document2[key] === "string" ? (0, import_core15.wholeValueOf)(document2, key) : null;
23152
22637
  setWhole({ rowId, key, rowTitle: titleOf(row), value, pointer });
23153
22638
  },
23154
22639
  [rowOf, fieldOf2, titleOf, editing]
@@ -23244,7 +22729,7 @@ function useGridAssist(args) {
23244
22729
  // src/gridBulk.tsx
23245
22730
  var import_react122 = require("react");
23246
22731
  var import_react123 = require("@ai-matrx/records/react");
23247
- var import_core17 = require("@ai-matrx/records/core");
22732
+ var import_core16 = require("@ai-matrx/records/core");
23248
22733
  var import_design_system63 = require("@ai-matrx/design-system");
23249
22734
  var import_jsx_runtime75 = require("react/jsx-runtime");
23250
22735
  function countOf(n, one, many) {
@@ -23290,7 +22775,7 @@ function useGridBulk(args) {
23290
22775
  const client = (0, import_react123.useRecordsClient)();
23291
22776
  const { tableId, rows, fields, noun, nounPlural, reload, forget, pushUndo: pushUndo2, versions } = args;
23292
22777
  const [busy, setBusy] = (0, import_react122.useState)(false);
23293
- const [refusal4, setRefusal] = (0, import_react122.useState)(null);
22778
+ const [refusal3, setRefusal] = (0, import_react122.useState)(null);
23294
22779
  const send = (0, import_react122.useCallback)(
23295
22780
  async (changes) => {
23296
22781
  setBusy(true);
@@ -23310,7 +22795,7 @@ function useGridBulk(args) {
23310
22795
  return null;
23311
22796
  }
23312
22797
  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);
22798
+ for (const change of changes) if ("record_id" in change && change.record_id) (0, import_core16.announceRecordChanged)(change.record_id);
23314
22799
  return done.data;
23315
22800
  },
23316
22801
  [client, tableId, versions, reload]
@@ -23354,7 +22839,7 @@ function useGridBulk(args) {
23354
22839
  },
23355
22840
  [send, rows, pushUndo2, reload, noun, nounPlural]
23356
22841
  );
23357
- return { busy, refusal: refusal4, clearRefusal: () => setRefusal(null), apply, duplicate, archive };
22842
+ return { busy, refusal: refusal3, clearRefusal: () => setRefusal(null), apply, duplicate, archive };
23358
22843
  }
23359
22844
  function BulkActions({
23360
22845
  ids,
@@ -23475,6 +22960,12 @@ var import_react124 = require("react");
23475
22960
  var import_react125 = require("@ai-matrx/records/react");
23476
22961
  var import_records43 = require("@ai-matrx/records");
23477
22962
  var import_design_system64 = require("@ai-matrx/design-system");
22963
+
22964
+ // src/views.ts
22965
+ var import_views2 = require("@ai-matrx/records/views");
22966
+ var { viewDocument, viewFromRow, declareView, saveViewPatch, viewPatchDocument } = boundViews;
22967
+
22968
+ // src/handOrder.tsx
23478
22969
  var import_jsx_runtime76 = require("react/jsx-runtime");
23479
22970
  function sortArrow(direction) {
23480
22971
  return direction === "asc" ? "\u2191" : "\u2193";
@@ -23842,7 +23333,7 @@ function GridBody({
23842
23333
  const viewSorts = heldOrder?.sorts ?? viewOrder?.sorts ?? [];
23843
23334
  const manual = order === "manual" && viewId !== null;
23844
23335
  const storePaged = merged || tableCard === null && !manual;
23845
- const defaultSort = (0, import_react127.useMemo)(() => defaultSortOf(table.data, fields.data ?? []), [table.data, fields.data]);
23336
+ const defaultSort = (0, import_react127.useMemo)(() => (0, import_first_page3.defaultSortOf)(table.data, fields.data ?? []), [table.data, fields.data]);
23846
23337
  const viewSort = (0, import_react127.useMemo)(() => {
23847
23338
  const first = viewSorts[0];
23848
23339
  if (!first) return null;
@@ -23959,7 +23450,7 @@ function GridBody({
23959
23450
  const seatedSort = seatedOn === openingKey ? query.sort : addressSort.current ?? openingSort;
23960
23451
  const rowGroupKey = merged && !drillState.enabled ? presentation.grouping?.field ?? null : null;
23961
23452
  const pageSort = (0, import_react127.useMemo)(
23962
- () => storePaged ? groupedPageSort(fields.data ?? [], rowGroupKey, pageSortFor(fields.data ?? [], seatedSort)) : [],
23453
+ () => storePaged ? (0, import_first_page6.groupedPageSort)(fields.data ?? [], rowGroupKey, (0, import_first_page2.pageSortFor)(fields.data ?? [], seatedSort)) : [],
23963
23454
  [storePaged, fields.data, seatedSort, rowGroupKey]
23964
23455
  );
23965
23456
  const classicInCard = !merged && tableCard !== null;
@@ -24011,7 +23502,7 @@ function GridBody({
24011
23502
  const seen = new Set(storeRows.map((row) => row.id));
24012
23503
  return [...storeRows, ...appendedRows.filter((row) => !seen.has(row.id))];
24013
23504
  }, [manual, storePaged, hand.rows, storeRows, embeddedMore, appendedRows]);
24014
- const nextEmbeddedPhysicalOffset = query.pageSize + appendedPhysicalPages * EMBEDDED_PAGE_SIZE;
23505
+ const nextEmbeddedPhysicalOffset = query.pageSize + appendedPhysicalPages * import_first_page5.EMBEDDED_PAGE_SIZE;
24015
23506
  const showMoreRows = (0, import_react127.useCallback)(async () => {
24016
23507
  if (appending || !embeddedMore) return;
24017
23508
  const requestAskKey = askKey2;
@@ -24022,7 +23513,7 @@ function GridBody({
24022
23513
  search: pageSearch.trim() === "" ? null : pageSearch.trim(),
24023
23514
  sort: pageSort,
24024
23515
  view_id: pageDoorViewId,
24025
- limit: EMBEDDED_PAGE_SIZE,
23516
+ limit: import_first_page5.EMBEDDED_PAGE_SIZE,
24026
23517
  offset: nextEmbeddedPhysicalOffset
24027
23518
  });
24028
23519
  if (embeddedAskKey.current !== requestAskKey) return;
@@ -24498,7 +23989,7 @@ function GridBody({
24498
23989
  }))
24499
23990
  );
24500
23991
  editing.forget(cells);
24501
- for (const u of updates) (0, import_core18.announceRecordChanged)(u.row.recordId);
23992
+ for (const u of updates) (0, import_core17.announceRecordChanged)(u.row.recordId);
24502
23993
  const lines = updates.length + creates.length;
24503
23994
  undo.push({ label: `Pasted ${lines} ${lines === 1 ? "row" : "rows"}`, cells, created });
24504
23995
  const expected = [
@@ -24778,7 +24269,7 @@ function GridBody({
24778
24269
  const addRowHere = (0, import_react127.useCallback)(async (values) => {
24779
24270
  setAddRefused(null);
24780
24271
  if (formHosted && fields.data) {
24781
- const wouldRefuse = (0, import_core18.predictWriteRefusals)({ fields: fields.data, document: values ?? {} });
24272
+ const wouldRefuse = (0, import_core17.predictWriteRefusals)({ fields: fields.data, document: values ?? {} });
24782
24273
  if (wouldRefuse.length > 0) {
24783
24274
  setFormAsk((held) => ({ n: (held?.n ?? 0) + 1, initial: { ...values ?? {} } }));
24784
24275
  return;
@@ -26026,6 +25517,11 @@ var import_react129 = require("react");
26026
25517
  var import_data_table17 = require("@ai-matrx/design-system/data-table");
26027
25518
  var import_react130 = require("@ai-matrx/records/react");
26028
25519
  var import_react131 = require("@ai-matrx/records/entity/react");
25520
+
25521
+ // src/entityQuery.ts
25522
+ var import_first_page7 = require("@ai-matrx/records/first-page");
25523
+
25524
+ // src/entityTable.tsx
26029
25525
  var import_jsx_runtime78 = require("react/jsx-runtime");
26030
25526
  function EntityDataScope({ children }) {
26031
25527
  const above = (0, import_react131.useOptionalEntityScope)();
@@ -26077,7 +25573,7 @@ function editTypeOf(column) {
26077
25573
  function useEntityTable(token2, options = {}) {
26078
25574
  const type = (0, import_react131.useEntityType)(token2);
26079
25575
  const columns = (0, import_react131.useEntityColumns)(token2);
26080
- const list = (0, import_react131.useEntityList)(token2, entityTableQuery(options));
25576
+ const list = (0, import_react131.useEntityList)(token2, (0, import_first_page7.entityTableQuery)(options));
26081
25577
  const write = (0, import_react131.useEntityWrite)(token2);
26082
25578
  const shown4 = (0, import_react129.useMemo)(() => entityShownColumns(columns.data ?? []), [columns.data]);
26083
25579
  const refused = list.error ?? columns.error ?? type.error;
@@ -26276,7 +25772,7 @@ function ConnectedRecordsTableCard({
26276
25772
  var import_download2 = require("@ai-matrx/kit/download");
26277
25773
  var import_react133 = require("react");
26278
25774
  var import_react134 = require("@ai-matrx/records/react");
26279
- var import_core19 = require("@ai-matrx/records/core");
25775
+ var import_core18 = require("@ai-matrx/records/core");
26280
25776
 
26281
25777
  // src/viewExport.ts
26282
25778
  var import_format6 = require("@ai-matrx/kit/format");
@@ -26293,7 +25789,7 @@ function viewColumns(fields, presentation) {
26293
25789
  function viewPageSorts(fields, sorts) {
26294
25790
  return (sorts ?? []).flatMap((s) => {
26295
25791
  const field2 = fields.find((f) => f.key === s.field);
26296
- return field2 ? [{ field: field2.key, direction: s.direction, as: sortAsFor(field2) }] : [];
25792
+ return field2 ? [{ field: field2.key, direction: s.direction, as: (0, import_first_page2.sortAsFor)(field2) }] : [];
26297
25793
  });
26298
25794
  }
26299
25795
  async function readViewRows(client, tableId, fields, view, ceiling = VIEW_EXPORT_CEILING) {
@@ -26349,7 +25845,7 @@ function toRows(fields, records, labels) {
26349
25845
  absent_reason: envelope?.absent ?? null,
26350
25846
  // A VALUE KEPT AS A FILE carries its pointer, so the export writes the whole text
26351
25847
  // (`withWholeValues`), never the first words passed off as the value.
26352
- source: (0, import_core19.wholeValueOf)(document2, field2.key)
25848
+ source: (0, import_core18.wholeValueOf)(document2, field2.key)
26353
25849
  };
26354
25850
  }
26355
25851
  return row;
@@ -26380,7 +25876,7 @@ async function rowsForFile(args) {
26380
25876
  );
26381
25877
  const lookup = ((field2, id) => labels(field2, id) ?? learned.get(`${field2.id}:${id}`) ?? null);
26382
25878
  const read = host.readFileText;
26383
- return (0, import_core19.withWholeValues)(toRows(all, records, lookup), read ? (fileId) => read({ fileId }) : null);
25879
+ return (0, import_core18.withWholeValues)(toRows(all, records, lookup), read ? (fileId) => read({ fileId }) : null);
26384
25880
  }
26385
25881
  function ExportMenu({ tableId, rows, label, className, view }) {
26386
25882
  const client = (0, import_react134.useRecordsClient)();
@@ -26419,7 +25915,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26419
25915
  {
26420
25916
  size: "sm",
26421
25917
  variant: "outline",
26422
- onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core19.exportCsv)(columns, rows2))).catch(
25918
+ onClick: () => void exported().then((rows2) => download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core18.exportCsv)(columns, rows2))).catch(
26423
25919
  (thrown) => setFailure((0, refusals_exports.refusalFromThrown)(thrown, "The CSV could not be written.", "Try again in a moment."))
26424
25920
  ),
26425
25921
  children: "CSV"
@@ -26440,7 +25936,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26440
25936
  );
26441
25937
  setFailure(null);
26442
25938
  try {
26443
- exported().then((rows2) => (0, import_core19.exportXlsx)(columns, rows2, name)).then(
25939
+ exported().then((rows2) => (0, import_core18.exportXlsx)(columns, rows2, name)).then(
26444
25940
  (bytes) => download(
26445
25941
  `${name}.xlsx`,
26446
25942
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
@@ -26461,7 +25957,7 @@ function ExportMenu({ tableId, rows, label, className, view }) {
26461
25957
  sourceId: `records:${tableId}`,
26462
25958
  size: "xs",
26463
25959
  json: () => records.map((r) => r.document),
26464
- human: () => (0, import_core19.exportCsv)(columns, toRows(columns, records, labels))
25960
+ human: () => (0, import_core18.exportCsv)(columns, toRows(columns, records, labels))
26465
25961
  }
26466
25962
  ),
26467
25963
  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 +26077,7 @@ var import_design_system78 = require("@ai-matrx/design-system");
26581
26077
  // src/TablesHome.tsx
26582
26078
  var import_react147 = require("react");
26583
26079
  var import_react148 = require("@ai-matrx/records/react");
26584
- var import_core20 = require("@ai-matrx/records/core");
26080
+ var import_core19 = require("@ai-matrx/records/core");
26585
26081
  var import_records50 = require("@ai-matrx/records");
26586
26082
  var import_design_system77 = require("@ai-matrx/design-system");
26587
26083
 
@@ -26745,19 +26241,19 @@ function fieldsForNewColumns(columns) {
26745
26241
  let key = (0, import_core2.tokenFor)(column.label) || `column_${i + 1}`;
26746
26242
  while (keys.has(key)) key = `${key}_${i + 1}`;
26747
26243
  keys.add(key);
26748
- const base = { key, label: column.label, sort: (i + 1) * 10, required: false };
26244
+ const base2 = { key, label: column.label, sort: (i + 1) * 10, required: false };
26749
26245
  switch (column.type) {
26750
26246
  case "date":
26751
- return { ...base, type: "datetime", kind: "date" };
26247
+ return { ...base2, type: "datetime", kind: "date" };
26752
26248
  case "datetime":
26753
- return { ...base, type: "datetime", kind: "datetime" };
26249
+ return { ...base2, type: "datetime", kind: "datetime" };
26754
26250
  case "currency":
26755
- return { ...base, type: "currency", unit: "$" };
26251
+ return { ...base2, type: "currency", unit: "$" };
26756
26252
  case "select":
26757
26253
  case "multi_select":
26758
- return { ...base, type: column.type, multi: column.type === "multi_select", options: column.options ?? [] };
26254
+ return { ...base2, type: column.type, multi: column.type === "multi_select", options: column.options ?? [] };
26759
26255
  default:
26760
- return { ...base, type: column.type };
26256
+ return { ...base2, type: column.type };
26761
26257
  }
26762
26258
  });
26763
26259
  }
@@ -27406,15 +26902,15 @@ function objectActionForKey(actions, event) {
27406
26902
  const id = Object.keys(TABLE_ACTION_KEYS).find((k) => TABLE_ACTION_KEYS[k].code === event.code);
27407
26903
  return id ? actions.find((a) => a.id === id) ?? null : null;
27408
26904
  }
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 };
26905
+ function action(base2, needs, input, perform) {
26906
+ const chord = TABLE_ACTION_KEYS[base2.id];
26907
+ if (chord && base2.shortcut === void 0) base2 = { ...base2, shortcut: chord.label };
27412
26908
  const refused = rightsReason(input.rights, needs, input.table);
27413
- if (refused !== null) return { ...base, disabledReason: refused, run: NOOP };
26909
+ if (refused !== null) return { ...base2, disabledReason: refused, run: NOOP };
27414
26910
  if (perform === void 0) {
27415
- return { ...base, disabledReason: input.host.unavailableReasons?.[base.id] ?? ACTION_NOT_HERE_REASON, run: NOOP };
26911
+ return { ...base2, disabledReason: input.host.unavailableReasons?.[base2.id] ?? ACTION_NOT_HERE_REASON, run: NOOP };
27416
26912
  }
27417
- return { ...base, run: perform };
26913
+ return { ...base2, run: perform };
27418
26914
  }
27419
26915
  function bind(handler, table) {
27420
26916
  return handler ? () => handler(table) : void 0;
@@ -27485,9 +26981,9 @@ function tableActions(input) {
27485
26981
  ];
27486
26982
  return withExtensions(built, host.extend ? host.extend(table, input.rights) : []);
27487
26983
  }
27488
- function withExtensions(base, extra) {
27489
- if (extra.length === 0) return [...base];
27490
- const seen = new Set(base.map((a) => a.id));
26984
+ function withExtensions(base2, extra) {
26985
+ if (extra.length === 0) return [...base2];
26986
+ const seen = new Set(base2.map((a) => a.id));
27491
26987
  for (const entry of extra) {
27492
26988
  if (entry.group === "danger") {
27493
26989
  throw new Error(`Object action "${entry.id}": the danger group is closed to extensions.`);
@@ -27502,7 +26998,7 @@ function withExtensions(base, extra) {
27502
26998
  }
27503
26999
  const out = [];
27504
27000
  for (const group of OBJECT_ACTION_GROUPS) {
27505
- out.push(...base.filter((a) => a.group === group.id), ...extra.filter((a) => a.group === group.id));
27001
+ out.push(...base2.filter((a) => a.group === group.id), ...extra.filter((a) => a.group === group.id));
27506
27002
  }
27507
27003
  return out;
27508
27004
  }
@@ -27708,7 +27204,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
27708
27204
  const [things, setThings] = (0, import_react141.useState)(null);
27709
27205
  const [error, setError] = (0, import_react141.useState)(null);
27710
27206
  const [restoring, setRestoring] = (0, import_react141.useState)(null);
27711
- const [refusal4, setRefusal] = (0, import_react141.useState)(null);
27207
+ const [refusal3, setRefusal] = (0, import_react141.useState)(null);
27712
27208
  const [said2, setSaid] = (0, import_react141.useState)(null);
27713
27209
  const read = (0, import_react141.useCallback)(async () => {
27714
27210
  const [forms, checklists] = await Promise.all([
@@ -27761,7 +27257,7 @@ function ArchivedBuiltOn({ tableId, onRestored }) {
27761
27257
  " \xB7 archived ",
27762
27258
  (0, import_records47.archivedWhen)(thing.archivedAt)
27763
27259
  ] }),
27764
- refusal4 && refusal4.id === thing.id ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(RefusalNotice, { error: refusal4.error, className: "mt-2" }) : null
27260
+ refusal3 && refusal3.id === thing.id ? /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
27765
27261
  ] }),
27766
27262
  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
27263
  import_design_system74.Button,
@@ -28318,7 +27814,7 @@ function TablesHome({ onOpenTable, organizationName, makingOnly = false, askedBy
28318
27814
  };
28319
27815
  }, [client]);
28320
27816
  const listed = facts.phase === "read" ? (0, import_records50.withTablePlacement)(
28321
- (0, import_core20.withTableFacts)(tables.data ?? [], facts.rows, me),
27817
+ (0, import_core19.withTableFacts)(tables.data ?? [], facts.rows, me),
28322
27818
  facts.rows
28323
27819
  ) : tables.data ?? [];
28324
27820
  const [showEverything, setShowEverything] = (0, import_react147.useState)(false);
@@ -28605,20 +28101,20 @@ function draftsFor(headers, rows) {
28605
28101
  function keysFor(labels) {
28606
28102
  const used = /* @__PURE__ */ new Set();
28607
28103
  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;
28104
+ const base2 = (0, import_core2.tokenFor)(label) === "table" && !/table/i.test(label) ? `column_${i + 1}` : (0, import_core2.tokenFor)(label);
28105
+ let key = base2;
28610
28106
  let n = 2;
28611
- while (used.has(key)) key = `${base}_${n++}`;
28107
+ while (used.has(key)) key = `${base2}_${n++}`;
28612
28108
  used.add(key);
28613
28109
  return key;
28614
28110
  });
28615
28111
  }
28616
28112
  function freeName(name, taken) {
28617
28113
  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()}`;
28114
+ const base2 = name.trim() || "Saved table";
28115
+ if (!lower.has(base2.toLowerCase())) return base2;
28116
+ for (let n = 2; n < 100; n += 1) if (!lower.has(`${base2} ${n}`.toLowerCase())) return `${base2} ${n}`;
28117
+ return `${base2} ${Date.now()}`;
28622
28118
  }
28623
28119
  async function sha256Text(text) {
28624
28120
  const subtle = globalThis.crypto?.subtle;
@@ -29522,11 +29018,11 @@ var import_design_system86 = require("@ai-matrx/design-system");
29522
29018
  var TableRestoreRefused = class extends Error {
29523
29019
  refusal;
29524
29020
  sentence;
29525
- constructor(refusal4) {
29526
- const sentence2 = refusalSentence(refusal4);
29021
+ constructor(refusal3) {
29022
+ const sentence2 = refusalSentence(refusal3);
29527
29023
  super(sentence2);
29528
29024
  this.name = "TableRestoreRefused";
29529
- this.refusal = refusal4;
29025
+ this.refusal = refusal3;
29530
29026
  this.sentence = sentence2;
29531
29027
  }
29532
29028
  };
@@ -31032,6 +30528,22 @@ function usePlatformTable(spec) {
31032
30528
  return state;
31033
30529
  }
31034
30530
 
30531
+ // src/viewLook.ts
30532
+ var import_views3 = require("@ai-matrx/records/views");
30533
+ var { lookDocument, lookFromDocument, readLooks, keepLook } = boundViews;
30534
+ var LOOK_WORDS = {
30535
+ /** The reason, for a tooltip or a screen reader — never a line on the page (interface-text). */
30536
+ yours: "You changed how this view looks. Only you see it.",
30537
+ /** The visible label for the same fact. */
30538
+ yoursLabel: "Only you see this",
30539
+ saveToView: "Save to view",
30540
+ saveAsNew: "Save as new view",
30541
+ reset: "Reset to view",
30542
+ /** The one button your look's doors fold into when the toolbar row has no room for three. */
30543
+ folded: "Your look",
30544
+ newName: "Name for the new view"
30545
+ };
30546
+
31035
30547
  // src/ViewSwitcher.tsx
31036
30548
  var import_react196 = require("react");
31037
30549
  var import_react197 = require("@ai-matrx/records/react");
@@ -31290,13 +30802,13 @@ function recordLink(tableId, recordId, origin = DEFAULT_ACTION_ORIGIN) {
31290
30802
  }
31291
30803
  var NOOP2 = () => {
31292
30804
  };
31293
- function action2(base, needs, input, perform) {
30805
+ function action2(base2, needs, input, perform) {
31294
30806
  const refused = rightsReason(input.rights, needs);
31295
- if (refused !== null) return { ...base, disabledReason: refused, run: NOOP2 };
30807
+ if (refused !== null) return { ...base2, disabledReason: refused, run: NOOP2 };
31296
30808
  if (perform === void 0) {
31297
- return { ...base, disabledReason: input.host.unavailableReasons?.[base.id] ?? ACTION_NOT_HERE_REASON, run: NOOP2 };
30809
+ return { ...base2, disabledReason: input.host.unavailableReasons?.[base2.id] ?? ACTION_NOT_HERE_REASON, run: NOOP2 };
31298
30810
  }
31299
- return { ...base, run: perform };
30811
+ return { ...base2, run: perform };
31300
30812
  }
31301
30813
  function bind2(handler, record) {
31302
30814
  return handler ? () => handler(record) : void 0;
@@ -33885,7 +33397,7 @@ function TimelineView({
33885
33397
  ] });
33886
33398
  if (!startField) {
33887
33399
  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 }),
33400
+ /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("p", { children: dates.length > 0 ? import_views2.VIEW_NEEDS.timeline?.pick : import_views2.VIEW_NEEDS.timeline?.missing }),
33889
33401
  dates.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime111.jsx)("div", { className: "flex flex-wrap gap-2", children: settings }) : null
33890
33402
  ] }) });
33891
33403
  }
@@ -34060,15 +33572,15 @@ var import_react192 = require("@ai-matrx/records/react");
34060
33572
  var import_design_system96 = require("@ai-matrx/design-system");
34061
33573
  var import_jsx_runtime112 = require("react/jsx-runtime");
34062
33574
  function viewNeedFor(layout) {
34063
- return VIEW_NEEDS[layout];
33575
+ return import_views2.VIEW_NEEDS[layout];
34064
33576
  }
34065
33577
  function columnDeclarationFor(need, label, options, fields) {
34066
- const base = { label: label.trim(), sort: nextFieldSort(fields) };
33578
+ const base2 = { label: label.trim(), sort: nextFieldSort(fields) };
34067
33579
  if (need.starter.type === "select") {
34068
- return { ...base, parity_type: "select", options: options.map((o) => o.trim()).filter((o) => o !== "") };
33580
+ return { ...base2, parity_type: "select", options: options.map((o) => o.trim()).filter((o) => o !== "") };
34069
33581
  }
34070
- if (need.starter.type === "datetime") return { ...base, parity_type: "datetime", kind: "date" };
34071
- return { ...base, parity_type: "attachment" };
33582
+ if (need.starter.type === "datetime") return { ...base2, parity_type: "datetime", kind: "date" };
33583
+ return { ...base2, parity_type: "attachment" };
34072
33584
  }
34073
33585
  var askedFor = /* @__PURE__ */ new Map();
34074
33586
  var askKey = (tableId, layout) => `${tableId}:${layout}`;
@@ -34091,7 +33603,7 @@ function ViewNeeds({ layout, tableId, fields, onMade, className }) {
34091
33603
  const mutation = (0, import_react192.useFieldMutation)();
34092
33604
  const client = (0, import_react192.useRecordsClient)();
34093
33605
  const taken = fields.map((f) => fieldName(f));
34094
- const [label, setLabel] = (0, import_react191.useState)(() => freeColumnName(need?.starter.label ?? "", taken));
33606
+ const [label, setLabel] = (0, import_react191.useState)(() => (0, import_views2.freeColumnName)(need?.starter.label ?? "", taken));
34095
33607
  const [options, setOptions] = (0, import_react191.useState)(() => [...need?.starter.options ?? []]);
34096
33608
  const [refused, setRefused] = (0, import_react191.useState)(null);
34097
33609
  const [pendingId, setPendingId] = (0, import_react191.useState)(null);
@@ -34558,7 +34070,7 @@ function ViewSwitcher({
34558
34070
  newRowLabel,
34559
34071
  className
34560
34072
  }) {
34561
- const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 200);
34073
+ const pageSize = pageSizeAsked ?? (embedded ? import_first_page5.EMBEDDED_PAGE_SIZE : 200);
34562
34074
  const [layout, setLayout] = (0, import_react196.useState)(view.layout);
34563
34075
  const [local, setLocal] = (0, import_react196.useState)({});
34564
34076
  (0, import_react196.useEffect)(() => {
@@ -34577,14 +34089,14 @@ function ViewSwitcher({
34577
34089
  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
34090
  chooser && !embedded ? /* @__PURE__ */ (0, import_jsx_runtime115.jsxs)("div", { className: "flex items-center gap-2", children: [
34579
34091
  /* @__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)(
34092
+ /* @__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
34093
  import_design_system98.Button,
34582
34094
  {
34583
34095
  size: "sm",
34584
34096
  variant: option === layout ? "secondary" : "ghost",
34585
34097
  "aria-pressed": option === layout,
34586
34098
  onClick: () => pick(option),
34587
- children: LAYOUT_LABEL[option]
34099
+ children: import_views2.LAYOUT_LABEL[option]
34588
34100
  },
34589
34101
  option
34590
34102
  )) })
@@ -34948,10 +34460,10 @@ function Board({
34948
34460
  ...view.endField ? { endKey: view.endField } : {},
34949
34461
  groupKey: view.groupField ?? null,
34950
34462
  ...view.presentation?.style?.colorBy !== void 0 ? { colorKey: view.presentation.style.colorBy?.field ?? null } : {},
34951
- layoutKept: remembered && STORE_KEEPS_TIMELINE,
34463
+ layoutKept: remembered && import_views2.STORE_KEEPS_TIMELINE,
34952
34464
  onSettingsChange: (patch) => {
34953
34465
  if (patch.startKey !== void 0) {
34954
- onChange({ startField: patch.startKey, ...STORE_KEEPS_TIMELINE ? {} : { dateField: patch.startKey } });
34466
+ onChange({ startField: patch.startKey, ...import_views2.STORE_KEEPS_TIMELINE ? {} : { dateField: patch.startKey } });
34955
34467
  }
34956
34468
  if (patch.endKey !== void 0) onChange({ endField: patch.endKey });
34957
34469
  if (patch.groupKey !== void 0) onChange({ groupField: patch.groupKey });
@@ -35052,7 +34564,7 @@ function FieldPicker({
35052
34564
  onPick,
35053
34565
  placing
35054
34566
  }) {
35055
- const want = LAYOUT_FIELD_KIND[layout];
34567
+ const want = import_views2.LAYOUT_FIELD_KIND[layout];
35056
34568
  const offerable = want ? offerableFields(all, want, placing) : [];
35057
34569
  const chosenField = chosen ? all.find((field2) => field2.key === chosen) : void 0;
35058
34570
  const unusual = chosenField && !offerable.some((field2) => field2.key === chosenField.key) ? chosenField : void 0;
@@ -35081,7 +34593,7 @@ function FieldPicker({
35081
34593
  }
35082
34594
  function Pick({ layout, picker }) {
35083
34595
  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 }),
34596
+ /* @__PURE__ */ (0, import_jsx_runtime115.jsx)("p", { children: import_views2.VIEW_NEEDS[layout]?.pick }),
35085
34597
  picker
35086
34598
  ] });
35087
34599
  }
@@ -35544,7 +35056,7 @@ function ArchivedView({
35544
35056
  const [loading, setLoading] = (0, import_react198.useState)(true);
35545
35057
  const [error, setError] = (0, import_react198.useState)(null);
35546
35058
  const [restoring, setRestoring] = (0, import_react198.useState)(null);
35547
- const [refusal4, setRefusal] = (0, import_react198.useState)(null);
35059
+ const [refusal3, setRefusal] = (0, import_react198.useState)(null);
35548
35060
  (0, import_react198.useEffect)(() => {
35549
35061
  if (laneFromHost) setLane(laneFromHost);
35550
35062
  }, [laneFromHost]);
@@ -35621,7 +35133,7 @@ function ArchivedView({
35621
35133
  /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
35622
35134
  /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("span", { className: "truncate text-sm", children: recordName(row.document, titleKey) }),
35623
35135
  /* @__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
35136
+ refusal3 && refusal3.recordId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
35625
35137
  ] }),
35626
35138
  mayRestore ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(
35627
35139
  import_design_system99.Button,
@@ -35650,7 +35162,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35650
35162
  const [rows, setRows] = (0, import_react198.useState)(null);
35651
35163
  const [error, setError] = (0, import_react198.useState)(null);
35652
35164
  const [restoring, setRestoring] = (0, import_react198.useState)(null);
35653
- const [refusal4, setRefusal] = (0, import_react198.useState)(null);
35165
+ const [refusal3, setRefusal] = (0, import_react198.useState)(null);
35654
35166
  const read = (0, import_react198.useCallback)(async () => {
35655
35167
  const answer = await client.fieldsRetired({ table_id: tableId });
35656
35168
  if (answer.ok) {
@@ -35694,7 +35206,7 @@ function RetiredColumns({ tableId, mayRestore, whyNot }) {
35694
35206
  /* @__PURE__ */ (0, import_jsx_runtime116.jsxs)("div", { className: "flex min-w-0 flex-1 flex-col", children: [
35695
35207
  /* @__PURE__ */ (0, import_jsx_runtime116.jsx)("span", { className: "truncate text-sm", children: name }),
35696
35208
  /* @__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
35209
+ refusal3 && refusal3.fieldId === row.id ? /* @__PURE__ */ (0, import_jsx_runtime116.jsx)(RefusalNotice, { error: refusal3.error, className: "mt-2" }) : null
35698
35210
  ] }),
35699
35211
  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
35212
  ]
@@ -35759,7 +35271,7 @@ function ArchivedPortals({
35759
35271
  const [confirming, setConfirming] = (0, import_react200.useState)(null);
35760
35272
  const [typed2, setTyped] = (0, import_react200.useState)("");
35761
35273
  const [restoring, setRestoring] = (0, import_react200.useState)(null);
35762
- const [refusal4, setRefusal] = (0, import_react200.useState)(null);
35274
+ const [refusal3, setRefusal] = (0, import_react200.useState)(null);
35763
35275
  const [said2, setSaid] = (0, import_react200.useState)(null);
35764
35276
  const read = (0, import_react200.useCallback)(async () => {
35765
35277
  const answered = await client.listPortals({ archived: "archived" });
@@ -35875,7 +35387,7 @@ function ArchivedPortals({
35875
35387
  )
35876
35388
  ] })
35877
35389
  ] }) : null,
35878
- refusal4 && refusal4.portalId === portal.portal_id ? /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(RefusalNotice, { error: refusal4.error }) : null
35390
+ refusal3 && refusal3.portalId === portal.portal_id ? /* @__PURE__ */ (0, import_jsx_runtime117.jsx)(RefusalNotice, { error: refusal3.error }) : null
35879
35391
  ]
35880
35392
  },
35881
35393
  portal.portal_id
@@ -35909,10 +35421,10 @@ var import_react205 = require("@ai-matrx/records/react");
35909
35421
  var NOOP3 = () => {
35910
35422
  };
35911
35423
  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 };
35424
+ const one = (base2, run) => {
35425
+ if (whyNot !== null) return { ...base2, disabledReason: whyNot, run: NOOP3 };
35426
+ if (!run) return { ...base2, disabledReason: ACTION_NOT_HERE_REASON, run: NOOP3 };
35427
+ return { ...base2, run };
35916
35428
  };
35917
35429
  return [
35918
35430
  one({ id: "rename", label: "Rename view\u2026", icon: "pencil", group: "organize", verb: "rename" }, host.rename),
@@ -35924,8 +35436,8 @@ function viewActions(whyNot, host) {
35924
35436
  ];
35925
35437
  }
35926
35438
  function copyName(name, taken) {
35927
- const base = `${name} (copy)`;
35928
- if (!taken.includes(base)) return base;
35439
+ const base2 = `${name} (copy)`;
35440
+ if (!taken.includes(base2)) return base2;
35929
35441
  for (let n = 2; ; n += 1) {
35930
35442
  const next = `${name} (copy ${n})`;
35931
35443
  if (!taken.includes(next)) return next;
@@ -35951,7 +35463,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
35951
35463
  const [unavailable, setUnavailable] = (0, import_react203.useState)(false);
35952
35464
  const [active, setActive] = (0, import_react203.useState)(() => {
35953
35465
  if (!initialViews || initialViews.length === 0) return activeViewId ?? null;
35954
- return (initialViews.find((v) => v.id === activeViewId) ?? defaultViewOf(initialViews) ?? initialViews[0]).id;
35466
+ return (initialViews.find((v) => v.id === activeViewId) ?? (0, import_views2.defaultViewOf)(initialViews) ?? initialViews[0]).id;
35955
35467
  });
35956
35468
  const readOnMount = (0, import_react203.useRef)(initialViews === void 0);
35957
35469
  const [naming, setNaming] = (0, import_react203.useState)(false);
@@ -36008,7 +35520,7 @@ function ViewBar({ tableId, activeViewId, onActiveView, seed, settings, onViews,
36008
35520
  }, [load]);
36009
35521
  (0, import_react203.useEffect)(() => {
36010
35522
  if (!views || views.length === 0) return;
36011
- const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? defaultViewOf(views) ?? views[0];
35523
+ const chosen = views.find((v) => v.id === (activeViewId ?? active)) ?? (0, import_views2.defaultViewOf)(views) ?? views[0];
36012
35524
  if (chosen.id !== active) setActive(chosen.id);
36013
35525
  onActiveView?.(chosen);
36014
35526
  }, [views, activeViewId]);
@@ -36697,7 +36209,7 @@ function MyChecklistSteps({
36697
36209
  }, [held, onSteps]);
36698
36210
  const steps = onlyIds ? held.filter((s) => onlyIds.has(s.step_id)) : held;
36699
36211
  const [busy, setBusy] = (0, import_react208.useState)(null);
36700
- const [refusal4, setRefusal] = (0, import_react208.useState)(null);
36212
+ const [refusal3, setRefusal] = (0, import_react208.useState)(null);
36701
36213
  const complete = (0, import_react208.useCallback)(
36702
36214
  async (step2, evidence) => {
36703
36215
  setBusy(step2.step_id);
@@ -36720,7 +36232,7 @@ function MyChecklistSteps({
36720
36232
  /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("span", { className: "tabular-nums", children: steps.length })
36721
36233
  ] }),
36722
36234
  error ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(RefusalNotice, { error }) : null,
36723
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(RefusalNotice, { error: refusal4 }) : null,
36235
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(RefusalNotice, { error: refusal3 }) : null,
36724
36236
  /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("ol", { className: "flex flex-col gap-1.5", children: steps.map(
36725
36237
  (step2) => actions ? /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("div", { className: "flex flex-col gap-0.5", "data-step-row": step2.step_id, children: [
36726
36238
  /* @__PURE__ */ (0, import_jsx_runtime120.jsx)(StepRow, { step: step2, busy: busy === step2.step_id, onComplete: (evidence) => void complete(step2, evidence) }),
@@ -36920,7 +36432,7 @@ function ChecklistTemplateEditor({
36920
36432
  const [saved, setSaved] = (0, import_react208.useState)(false);
36921
36433
  const [name, setName] = (0, import_react208.useState)("");
36922
36434
  const [rows, setRows] = (0, import_react208.useState)([{ ...EMPTY_ROW }]);
36923
- const [refusal4, setRefusal] = (0, import_react208.useState)(null);
36435
+ const [refusal3, setRefusal] = (0, import_react208.useState)(null);
36924
36436
  const [error, setError] = (0, import_react208.useState)(null);
36925
36437
  const [busy, setBusy] = (0, import_react208.useState)(false);
36926
36438
  const [loading, setLoading] = (0, import_react208.useState)(Boolean(templateId));
@@ -37096,10 +36608,10 @@ function ChecklistTemplateEditor({
37096
36608
  ] }, index)) }),
37097
36609
  /* @__PURE__ */ (0, import_jsx_runtime120.jsxs)("div", { className: "flex items-center gap-1.5", children: [
37098
36610
  /* @__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" }),
36611
+ /* @__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
36612
  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
36613
  ] }),
37102
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-refusal", children: refusal4 }) : null
36614
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime120.jsx)("p", { className: "text-xs text-muted-foreground", "data-testid": "checklist-editor-refusal", children: refusal3 }) : null
37103
36615
  ] });
37104
36616
  }
37105
36617
  function toStepSpec(row, index) {
@@ -38682,7 +38194,7 @@ var import_design_system110 = require("@ai-matrx/design-system");
38682
38194
  var import_react223 = require("react");
38683
38195
  var import_recharts = require("recharts");
38684
38196
  var import_records59 = require("@ai-matrx/records");
38685
- var import_core21 = require("@ai-matrx/records/core");
38197
+ var import_core20 = require("@ai-matrx/records/core");
38686
38198
  var import_design_system109 = require("@ai-matrx/design-system");
38687
38199
  var import_format11 = require("@ai-matrx/kit/format");
38688
38200
 
@@ -39144,7 +38656,7 @@ function pretty(n) {
39144
38656
  return Number.isInteger(n) ? n.toLocaleString() : n.toLocaleString(void 0, { maximumFractionDigits: 2 });
39145
38657
  }
39146
38658
  function asRefusal2(block) {
39147
- return (0, import_core21.mapPgError)(
38659
+ return (0, import_core20.mapPgError)(
39148
38660
  {
39149
38661
  message: block.refused ?? "",
39150
38662
  ...block.sqlstate ? { code: block.sqlstate } : {}
@@ -42015,7 +41527,7 @@ function SubscriptionsPanel({ tableId, activeRuleId, className }) {
42015
41527
  var import_clipboard9 = require("@ai-matrx/kit/clipboard");
42016
41528
  var import_design_system121 = require("@ai-matrx/design-system");
42017
41529
  var import_react241 = require("react");
42018
- var import_core22 = require("@dnd-kit/core");
41530
+ var import_core21 = require("@dnd-kit/core");
42019
41531
  var import_sortable = require("@dnd-kit/sortable");
42020
41532
  var import_utilities = require("@dnd-kit/utilities");
42021
41533
  var import_react242 = require("@ai-matrx/records/react");
@@ -42376,7 +41888,7 @@ function FormStage({
42376
41888
  const [answers, setAnswers] = (0, import_react239.useState)(() => ({ ...initialAnswers ?? {} }));
42377
41889
  const [at, setAt] = (0, import_react239.useState)(0);
42378
41890
  const [error, setError] = (0, import_react239.useState)(null);
42379
- const [refusal4, setRefusal] = (0, import_react239.useState)(null);
41891
+ const [refusal3, setRefusal] = (0, import_react239.useState)(null);
42380
41892
  const [writing, setWriting] = (0, import_react239.useState)(false);
42381
41893
  const [done, setDone] = (0, import_react239.useState)(null);
42382
41894
  const [hidden, setHidden] = (0, import_react239.useState)({});
@@ -42749,10 +42261,10 @@ function FormStage({
42749
42261
  ) : null,
42750
42262
  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
42263
  error ? /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(RefusalNotice, { error, className: "text-left" }) : null,
42752
- refusal4 ? /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(
42264
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(
42753
42265
  RefusalNotice,
42754
42266
  {
42755
- error: refusal4,
42267
+ error: refusal3,
42756
42268
  className: "text-left",
42757
42269
  onKeepEditing: () => {
42758
42270
  setRefusal(null);
@@ -42941,11 +42453,11 @@ function Question({
42941
42453
  // src/FormBuilder.tsx
42942
42454
  var import_forms3 = require("@ai-matrx/records/forms");
42943
42455
  var import_jsx_runtime138 = require("react/jsx-runtime");
42944
- function freshFormName(base, taken) {
42456
+ function freshFormName(base2, taken) {
42945
42457
  const names = new Set(taken.map((n) => n.trim().toLowerCase()));
42946
- if (!names.has(base.toLowerCase())) return base;
42458
+ if (!names.has(base2.toLowerCase())) return base2;
42947
42459
  for (let n = 2; ; n += 1) {
42948
- const next = `${base} ${n}`;
42460
+ const next = `${base2} ${n}`;
42949
42461
  if (!names.has(next.toLowerCase())) return next;
42950
42462
  }
42951
42463
  }
@@ -43242,8 +42754,8 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
43242
42754
  return;
43243
42755
  }
43244
42756
  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(
42757
+ const base2 = table.data?.name?.trim() ? `${table.data.name.trim()} form` : "Form";
42758
+ void create(freshFormName(base2, forms.map((f) => f.name))).then(
43247
42759
  (made) => setMakeOnMount(made ? "made" : "not-made")
43248
42760
  );
43249
42761
  }, [createOnMount, makeOnMount, forms, fields.data, create, table.data, table.error]);
@@ -43648,9 +43160,9 @@ function QuestionList({
43648
43160
  onQuestions,
43649
43161
  onQuestion
43650
43162
  }) {
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 })
43163
+ const sensors = (0, import_core21.useSensors)(
43164
+ (0, import_core21.useSensor)(import_core21.PointerSensor, { activationConstraint: { distance: 4 } }),
43165
+ (0, import_core21.useSensor)(import_core21.KeyboardSensor, { coordinateGetter: import_sortable.sortableKeyboardCoordinates })
43654
43166
  );
43655
43167
  const askable = askableFields([...fields]);
43656
43168
  const unasked = askable.filter((f) => !draft.questions.some((q) => q.field === f.key));
@@ -43672,7 +43184,7 @@ function QuestionList({
43672
43184
  /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("span", { className: "font-medium text-foreground", children: "Questions" }),
43673
43185
  /* @__PURE__ */ (0, import_jsx_runtime138.jsx)("span", { className: "tabular-nums", children: draft.questions.length })
43674
43186
  ] }),
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)(
43187
+ /* @__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
43188
  QuestionRow,
43677
43189
  {
43678
43190
  index,
@@ -44668,7 +44180,7 @@ var import_react259 = require("@ai-matrx/records/react");
44668
44180
  var import_design_system130 = require("@ai-matrx/design-system");
44669
44181
 
44670
44182
  // src/DashboardGrid.tsx
44671
- var import_core23 = require("@dnd-kit/core");
44183
+ var import_core22 = require("@dnd-kit/core");
44672
44184
  var import_sortable2 = require("@dnd-kit/sortable");
44673
44185
  var import_utilities2 = require("@dnd-kit/utilities");
44674
44186
  var import_design_system127 = require("@ai-matrx/design-system");
@@ -44724,7 +44236,7 @@ function withBlockIds(blocks) {
44724
44236
  // src/DashboardGrid.tsx
44725
44237
  var import_jsx_runtime143 = require("react/jsx-runtime");
44726
44238
  var dashboardCollision = (args) => {
44727
- const under = (0, import_core23.pointerWithin)(args);
44239
+ const under = (0, import_core22.pointerWithin)(args);
44728
44240
  if (under.length > 0) return under;
44729
44241
  const at = args.collisionRect;
44730
44242
  return args.droppableContainers.flatMap((container) => {
@@ -44734,9 +44246,9 @@ var dashboardCollision = (args) => {
44734
44246
  }).sort((a, b) => a.data.value - b.data.value);
44735
44247
  };
44736
44248
  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 })
44249
+ const sensors = (0, import_core22.useSensors)(
44250
+ (0, import_core22.useSensor)(import_core22.PointerSensor, { activationConstraint: { distance: 4 } }),
44251
+ (0, import_core22.useSensor)(import_core22.KeyboardSensor, { coordinateGetter: import_sortable2.sortableKeyboardCoordinates })
44740
44252
  );
44741
44253
  const ids = items.map((item) => item.id);
44742
44254
  function dragEnd(event) {
@@ -44746,7 +44258,7 @@ function DashboardGrid({ items, arranging, onMove, onSpan }) {
44746
44258
  }
44747
44259
  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
44260
  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 }) });
44261
+ 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
44262
  }
44751
44263
  function GridCell2({
44752
44264
  item,
@@ -45173,7 +44685,7 @@ function AddChart({ subject, onAdd, onClose }) {
45173
44685
  const field2 = all.find((f) => f.key === key);
45174
44686
  return field2 ? scalarText(field2, value, labels) : String(value);
45175
44687
  };
45176
- const [measureKey5, setMeasureKey] = (0, import_react256.useState)("count");
44688
+ const [measureKey4, setMeasureKey] = (0, import_react256.useState)("count");
45177
44689
  const [splitKey, setSplitKey] = (0, import_react256.useState)("none");
45178
44690
  const [kind, setKind] = (0, import_react256.useState)("auto");
45179
44691
  const [filter, setFilter] = (0, import_react256.useState)({});
@@ -45181,7 +44693,7 @@ function AddChart({ subject, onAdd, onClose }) {
45181
44693
  const numbers = numberColumns(all);
45182
44694
  const choices = offerableFields(all, "choice");
45183
44695
  const dates = offerableFields(all, "date");
45184
- const measure = measureKey5 === "count" ? { op: "count" } : { op: measureKey5.split(":")[0], key: measureKey5.split(":")[1] };
44696
+ const measure = measureKey4 === "count" ? { op: "count" } : { op: measureKey4.split(":")[0], key: measureKey4.split(":")[1] };
45185
44697
  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
44698
  const shape = kind !== "auto" ? kind : split.kind === "period" ? "line" : split.kind === "column" ? "column" : "number";
45187
44699
  function pickTable(next) {
@@ -45199,7 +44711,7 @@ function AddChart({ subject, onAdd, onClose }) {
45199
44711
  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
44712
  /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)("div", { className: "flex flex-wrap items-center gap-1", children: [
45201
44713
  /* @__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: [
44714
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_design_system129.Select, { value: measureKey4, onValueChange: setMeasureKey, children: [
45203
44715
  /* @__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
44716
  /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_design_system129.SelectContent, { children: [
45205
44717
  /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(import_design_system129.SelectItem, { value: "count", children: "How many" }),
@@ -45295,14 +44807,14 @@ function filterTargets(filter, blocks) {
45295
44807
  if (filter.targets && filter.targets.length > 0) return filter.targets;
45296
44808
  return blocks.filter((b) => b.kind === "list" && b.table_id === filter.table_id).map((b) => b.id);
45297
44809
  }
45298
- function combineFilter(base, extra, fieldIdOf) {
44810
+ function combineFilter(base2, extra, fieldIdOf) {
45299
44811
  const extraKeys = Object.keys(extra);
45300
- if (!base || !(0, import_records65.isRuleFilter)(base) && Object.keys(base).length === 0) {
44812
+ if (!base2 || !(0, import_records65.isRuleFilter)(base2) && Object.keys(base2).length === 0) {
45301
44813
  return { filter: extraKeys.length > 0 ? { ...extra } : null, dropped: [] };
45302
44814
  }
45303
- if (!(0, import_records65.isRuleFilter)(base)) return { filter: { ...base, ...extra }, dropped: [] };
44815
+ if (!(0, import_records65.isRuleFilter)(base2)) return { filter: { ...base2, ...extra }, dropped: [] };
45304
44816
  const dropped = [];
45305
- let rule = base;
44817
+ let rule = base2;
45306
44818
  for (const key of extraKeys) {
45307
44819
  const id = fieldIdOf(key);
45308
44820
  if (!id) {
@@ -45958,372 +45470,8 @@ var import_design_system131 = require("@ai-matrx/design-system");
45958
45470
  var import_react261 = require("@ai-matrx/records/react");
45959
45471
 
45960
45472
  // 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
- }
45473
+ var question_exports = {};
45474
+ __reExport(question_exports, require("@ai-matrx/records/questions"));
46327
45475
 
46328
45476
  // src/QuestionPanel.tsx
46329
45477
  var import_jsx_runtime148 = require("react/jsx-runtime");
@@ -46379,12 +45527,12 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46379
45527
  }
46380
45528
  let live = true;
46381
45529
  void (async () => {
46382
- const mine2 = await unreadableKeys(client, tableId, all);
45530
+ const mine2 = await (0, question_exports.unreadableKeys)(client, tableId, all);
46383
45531
  const out = {};
46384
45532
  for (const rel of all.filter((f) => editorKindFor(f) === "relation" && f.relation_target && !mine2.has(f.key))) {
46385
45533
  const target = await client.fields({ table_id: rel.relation_target });
46386
45534
  if (!target.ok) continue;
46387
- const theirs = await unreadableKeys(client, rel.relation_target, target.data);
45535
+ const theirs = await (0, question_exports.unreadableKeys)(client, rel.relation_target, target.data);
46388
45536
  out[rel.key] = { relation: rel, fields: target.data.filter((f) => !theirs.has(f.key) && editorKindFor(f) !== "relation") };
46389
45537
  }
46390
45538
  if (!live) return;
@@ -46399,7 +45547,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46399
45547
  const [saved, setSaved] = (0, import_react260.useState)(null);
46400
45548
  const [savedEpoch, setSavedEpoch] = (0, import_react260.useState)(0);
46401
45549
  const [current, setCurrent] = (0, import_react260.useState)(null);
46402
- const [spec, setSpec] = (0, import_react260.useState)(newQuestion);
45550
+ const [spec, setSpec] = (0, import_react260.useState)(question_exports.newQuestion);
46403
45551
  const [name, setName] = (0, import_react260.useState)("");
46404
45552
  const [shared, setShared] = (0, import_react260.useState)(true);
46405
45553
  const [saveError, setSaveError] = (0, import_react260.useState)(null);
@@ -46408,7 +45556,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46408
45556
  const openedFromLink = (0, import_react260.useRef)(false);
46409
45557
  (0, import_react260.useEffect)(() => {
46410
45558
  let live = true;
46411
- void questionsOf(client, tableId).then((answer2) => {
45559
+ void (0, question_exports.questionsOf)(client, tableId).then((answer2) => {
46412
45560
  if (!live) return;
46413
45561
  setSaved(answer2.ok ? answer2.data : []);
46414
45562
  if (answer2.ok && activeQuestionId && !openedFromLink.current) {
@@ -46424,7 +45572,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46424
45572
  }, [client, tableId, savedEpoch, activeQuestionId]);
46425
45573
  const open = (q) => {
46426
45574
  setCurrent(q);
46427
- setSpec(q ? q.spec : newQuestion());
45575
+ setSpec(q ? q.spec : (0, question_exports.newQuestion)());
46428
45576
  setName(q ? q.name : "");
46429
45577
  setShared(q ? q.shared : true);
46430
45578
  setSaveError(null);
@@ -46443,7 +45591,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46443
45591
  let live = true;
46444
45592
  setAsking(true);
46445
45593
  const t = setTimeout(() => {
46446
- void askQuestion(client, tableId, spec, all).then((a) => {
45594
+ void (0, question_exports.askQuestion)(client, tableId, spec, all).then((a) => {
46447
45595
  if (!live) return;
46448
45596
  setAnswer(a);
46449
45597
  setAsking(false);
@@ -46459,7 +45607,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46459
45607
  setSaving(true);
46460
45608
  setSaveError(null);
46461
45609
  const editing = !asNew && current && mine;
46462
- const kept = await questionSave(client, {
45610
+ const kept = await (0, question_exports.questionSave)(client, {
46463
45611
  ...editing ? { id: current.id, expectedVersion: current.version } : {},
46464
45612
  tableId,
46465
45613
  name: asNew && current && name.trim() === current.name ? `${name.trim()} (copy)` : name,
@@ -46477,7 +45625,7 @@ function QuestionPanel({ tableId, activeQuestionId, draft, className }) {
46477
45625
  };
46478
45626
  const archive = async () => {
46479
45627
  if (!current) return;
46480
- const gone = await questionArchive(client, current.id, current.version);
45628
+ const gone = await (0, question_exports.questionArchive)(client, current.id, current.version);
46481
45629
  if (!gone.ok) return setSaveError(gone.error);
46482
45630
  open(null);
46483
45631
  setSavedEpoch((n) => n + 1);
@@ -46632,17 +45780,17 @@ function Measures({ measures, fields, onChange }) {
46632
45780
  const set = (i, next) => onChange(measures.map((m, j) => j === i ? next : m));
46633
45781
  return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex flex-col gap-1", children: [
46634
45782
  measures.map((m, i) => {
46635
- const eligible = measurableFields(fields, m.op);
45783
+ const eligible = (0, question_exports.measurableFields)(fields, m.op);
46636
45784
  return /* @__PURE__ */ (0, import_jsx_runtime148.jsxs)("div", { className: "flex items-center gap-1", "data-testid": "question-measure", children: [
46637
45785
  /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(
46638
45786
  PickOne,
46639
45787
  {
46640
45788
  label: "Measure",
46641
45789
  value: m.op,
46642
- options: QUESTION_OPS.map((op2) => ({ value: op2, label: OP_LABEL[op2] })),
45790
+ options: question_exports.QUESTION_OPS.map((op2) => ({ value: op2, label: OP_LABEL[op2] })),
46643
45791
  onChange: (op2) => {
46644
45792
  const nextOp = op2;
46645
- const keep = nextOp !== "count" && measurableFields(fields, nextOp).some((f) => f.key === m.key);
45793
+ const keep = nextOp !== "count" && (0, question_exports.measurableFields)(fields, nextOp).some((f) => f.key === m.key);
46646
45794
  set(i, nextOp === "count" ? { op: "count" } : { op: nextOp, ...keep ? { key: m.key } : {} });
46647
45795
  },
46648
45796
  className: "w-28",
@@ -46882,7 +46030,7 @@ function QuestionAnswerView({ tableId, spec, answer, fields, related = NO_RELATE
46882
46030
  // src/TableAsk.tsx
46883
46031
  var import_react262 = require("react");
46884
46032
  var import_design_system132 = require("@ai-matrx/design-system");
46885
- var import_records67 = require("@ai-matrx/records");
46033
+ var import_records66 = require("@ai-matrx/records");
46886
46034
  var import_react263 = require("@ai-matrx/records/react");
46887
46035
 
46888
46036
  // src/askWords.ts
@@ -47074,14 +46222,14 @@ function questionFromWords(text, fields, choices = {}) {
47074
46222
  const measured = head === "" ? null : columnNamed2(head, names);
47075
46223
  if (op2 === null) {
47076
46224
  if (head === "") op2 = "count";
47077
- else if (measured && measurableFields([...fields], "sum").some((f) => f.key === measured.key)) op2 = "sum";
46225
+ else if (measured && (0, question_exports.measurableFields)([...fields], "sum").some((f) => f.key === measured.key)) op2 = "sum";
47078
46226
  else return { ok: false, why: "Start with count, sum, average, smallest or largest" };
47079
46227
  }
47080
- const spec = { ...newQuestion(), group };
46228
+ const spec = { ...(0, question_exports.newQuestion)(), group };
47081
46229
  let measureReads = "Count";
47082
46230
  if (op2 !== "count") {
47083
46231
  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)) {
46232
+ if (!(0, question_exports.measurableFields)([...fields], op2).some((f) => f.key === measured.key)) {
47085
46233
  return { ok: false, why: `${fieldName(measured)} is not a number column` };
47086
46234
  }
47087
46235
  spec.measures = [{ op: op2, key: measured.key }];
@@ -47112,13 +46260,13 @@ function TableAsk({ tableId, onOpenInQuestions }) {
47112
46260
  await Promise.all(
47113
46261
  all.filter(isChoiceField).map(async (field2) => {
47114
46262
  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));
46263
+ if (got.ok) choices[field2.key] = (got.data ?? []).map((o) => (0, import_records66.optionLabel)(o)).filter((w) => Boolean(w));
47116
46264
  })
47117
46265
  );
47118
46266
  const read = questionFromWords(words2, all, choices);
47119
46267
  if (!read.ok) return setSaid({ kind: "not-read", why: read.why });
47120
46268
  setSaid({ kind: "asking", reads: read.reads });
47121
- const answered = await askQuestion(client, tableId, read.spec, all);
46269
+ const answered = await (0, question_exports.askQuestion)(client, tableId, read.spec, all);
47122
46270
  setSaid(answered.ok ? { kind: "answer", reads: read.reads, spec: read.spec, answer: answered.data } : { kind: "refused", error: answered.error });
47123
46271
  };
47124
46272
  return /* @__PURE__ */ (0, import_jsx_runtime149.jsxs)(import_design_system132.Popover, { open, onOpenChange: setOpen, children: [
@@ -47180,7 +46328,7 @@ function TableAsk({ tableId, onOpenInQuestions }) {
47180
46328
  // src/PageScreen.tsx
47181
46329
  var import_react264 = require("react");
47182
46330
  var import_react265 = require("@ai-matrx/records/react");
47183
- var import_core25 = require("@ai-matrx/records/core");
46331
+ var import_core23 = require("@ai-matrx/records/core");
47184
46332
  var import_design_system133 = require("@ai-matrx/design-system");
47185
46333
  var import_forms4 = require("@ai-matrx/records/forms");
47186
46334
  var import_jsx_runtime150 = require("react/jsx-runtime");
@@ -47597,7 +46745,7 @@ function ListBlockView({
47597
46745
  ...sort.length > 0 ? { sort } : {}
47598
46746
  });
47599
46747
  const reload = page.reload;
47600
- (0, import_react264.useEffect)(() => (0, import_core25.onRecordChanged)(() => reload()), [reload]);
46748
+ (0, import_react264.useEffect)(() => (0, import_core23.onRecordChanged)(() => reload()), [reload]);
47601
46749
  const rows = nobodyIsMe ? [] : page.data?.rows ?? [];
47602
46750
  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
46751
  const firstId = rows[0]?.id ?? null;
@@ -47963,7 +47111,7 @@ function onePerKey3(all) {
47963
47111
  var import_clipboard11 = require("@ai-matrx/kit/clipboard");
47964
47112
  var import_react266 = require("react");
47965
47113
  var import_react267 = require("@ai-matrx/records/react");
47966
- var import_records68 = require("@ai-matrx/records");
47114
+ var import_records67 = require("@ai-matrx/records");
47967
47115
  var import_design_system134 = require("@ai-matrx/design-system");
47968
47116
  var import_forms5 = require("@ai-matrx/records/forms");
47969
47117
  var import_jsx_runtime151 = require("react/jsx-runtime");
@@ -48069,7 +47217,7 @@ function FormsPanel({ tableId, activeFormId, className }) {
48069
47217
  }
48070
47218
  ) : null,
48071
47219
  /* @__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)}`;
47220
+ const url = `${origin}${(0, import_records67.publicFormPath)(form.form_id)}`;
48073
47221
  return /* @__PURE__ */ (0, import_jsx_runtime151.jsxs)(
48074
47222
  "li",
48075
47223
  {
@@ -48151,7 +47299,7 @@ var import_design_system136 = require("@ai-matrx/design-system");
48151
47299
 
48152
47300
  // src/CaptureRun.tsx
48153
47301
  var import_react268 = require("react");
48154
- var import_records69 = require("@ai-matrx/records");
47302
+ var import_records68 = require("@ai-matrx/records");
48155
47303
  var import_react269 = require("@ai-matrx/records/react");
48156
47304
  var import_design_system135 = require("@ai-matrx/design-system");
48157
47305
  var import_jsx_runtime152 = require("react/jsx-runtime");
@@ -48206,7 +47354,7 @@ function CaptureRun({ sheetId, face: given, className }) {
48206
47354
  const [sending, setSending] = (0, import_react268.useState)(false);
48207
47355
  const queueRef = (0, import_react268.useRef)(null);
48208
47356
  (0, import_react268.useEffect)(() => {
48209
- const q2 = (0, import_records69.openCaptureQueue)({
47357
+ const q2 = (0, import_records68.openCaptureQueue)({
48210
47358
  onChange: (c, all) => {
48211
47359
  setCounts(c);
48212
47360
  setItems(all);
@@ -48473,7 +47621,7 @@ function CaptureRun({ sheetId, face: given, className }) {
48473
47621
  value: String(answers[q.field] ?? ""),
48474
47622
  onChange: (e) => {
48475
47623
  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 };
47624
+ const answered2 = field2 ? (0, import_records68.coerceTypedAnswer)(field2, raw, { label: q.ask ?? (0, import_records68.coercionLabel)(field2) }) : { value: raw };
48477
47625
  setAnswers((held) => ({
48478
47626
  ...held,
48479
47627
  [q.field]: raw === "" ? "" : "refusal" in answered2 ? raw : answered2.value
@@ -49116,13 +48264,13 @@ function useEmbedHandshake(args) {
49116
48264
  // src/TablePage.tsx
49117
48265
  var import_clipboard14 = require("@ai-matrx/kit/clipboard");
49118
48266
  var import_react288 = require("react");
49119
- var import_records70 = require("@ai-matrx/records");
48267
+ var import_records69 = require("@ai-matrx/records");
49120
48268
  var import_react289 = require("@ai-matrx/records/react");
49121
48269
  var import_design_system146 = require("@ai-matrx/design-system");
49122
48270
  var import_text_case19 = require("@ai-matrx/kit/text-case");
49123
48271
 
49124
48272
  // src/viewShare.ts
49125
- var import_core26 = require("@ai-matrx/records/core");
48273
+ var import_core24 = require("@ai-matrx/records/core");
49126
48274
  var NO_VIEW_REASON = "No saved view yet";
49127
48275
  function viewLink(tableId, viewId, origin) {
49128
48276
  return `${tableLink(tableId, origin)}?view=${encodeURIComponent(viewId)}`;
@@ -49158,7 +48306,7 @@ async function downloadViewCsv(args) {
49158
48306
  const columns = viewColumns(fields, view.presentation);
49159
48307
  const rows = await rowsForFile({ client, host, fields: columns, records: read.rows, labels });
49160
48308
  const name = fileNameOf(args.tableName) || "records";
49161
- download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core26.exportCsv)(columns, rows));
48309
+ download(`${name}.csv`, "text/csv;charset=utf-8", (0, import_core24.exportCsv)(columns, rows));
49162
48310
  host.notify?.success(read.cut ? cutWords(read.rows.length) : "CSV downloaded");
49163
48311
  }
49164
48312
 
@@ -49681,16 +48829,16 @@ function toolbarFold(input) {
49681
48829
  };
49682
48830
  const withGap = (width) => width > 0 ? width + gap : 0;
49683
48831
  const shareNow = input.share ? withGap(input.share.now) : 0;
49684
- const base = pieces.reduce((rest, p) => rest - withGap(p.piece.now), needsNow - shareNow);
48832
+ const base2 = pieces.reduce((rest, p) => rest - withGap(p.piece.now), needsNow - shareNow);
49685
48833
  const stages = input.tools ? [0, 1, 2, 3] : [0, 1, 2];
49686
48834
  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));
48835
+ const needs = stages.map((fold) => pieces.reduce((sum, p) => sum + withGap(widthAt(p, fold)), base2 + shareOn));
49688
48836
  const fits = needs.findIndex((need) => need <= available + 0.5);
49689
48837
  if (fits >= 0) return stages[fits];
49690
48838
  const least = Math.min(...needs);
49691
48839
  const most = stages[needs.findIndex((need) => need <= least + 0.5)];
49692
48840
  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);
48841
+ const fixed = pieces.reduce((sum, p) => sum + withGap(p.stage === 3 ? SLOT_MIN : widthAt(p, 3)), base2 + shareOn);
49694
48842
  return fixed > available + 0.5 ? 4 : most;
49695
48843
  }
49696
48844
  function naturalWidth(el) {
@@ -49847,7 +48995,7 @@ function useSlotScroll(slot) {
49847
48995
  }
49848
48996
 
49849
48997
  // src/TablePage.tsx
49850
- var import_uuid4 = require("@ai-matrx/kit/uuid");
48998
+ var import_uuid3 = require("@ai-matrx/kit/uuid");
49851
48999
  var import_jsx_runtime163 = require("react/jsx-runtime");
49852
49000
  var RAIL_TITLE = {
49853
49001
  settings: "Table settings",
@@ -49934,7 +49082,7 @@ function TableNotHere({
49934
49082
  const client = (0, import_react289.useRecordsClient)();
49935
49083
  const [archived, setArchived] = (0, import_react288.useState)({ phase: "asking" });
49936
49084
  const [restoring, setRestoring] = (0, import_react288.useState)(false);
49937
- const [refusal4, setRefusal] = (0, import_react288.useState)(null);
49085
+ const [refusal3, setRefusal] = (0, import_react288.useState)(null);
49938
49086
  (0, import_react288.useEffect)(() => {
49939
49087
  let alive = true;
49940
49088
  void client.tableArchived({ table_id: tableId }).then((answered) => {
@@ -49951,8 +49099,8 @@ function TableNotHere({
49951
49099
  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
49100
  /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "text-sm font-medium", children: "This table is archived" }),
49953
49101
  /* @__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,
49102
+ /* @__PURE__ */ (0, import_jsx_runtime163.jsx)("p", { className: "text-xs text-muted-foreground", children: (0, import_records69.archivedByLine)(row) }),
49103
+ refusal3 ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(RefusalNotice, { error: refusal3 }) : null,
49956
49104
  /* @__PURE__ */ (0, import_jsx_runtime163.jsxs)("div", { className: "flex gap-2", children: [
49957
49105
  /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
49958
49106
  import_design_system146.Button,
@@ -50054,7 +49202,7 @@ function unknownRailLine(raw) {
50054
49202
  }
50055
49203
  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
49204
  function openingView(activeView, activeDashboardId) {
50057
- const named = pageViewFromParam(activeView);
49205
+ const named = (0, import_views2.pageViewFromParam)(activeView);
50058
49206
  if (named === null) {
50059
49207
  const asked2 = typeof activeView === "string" ? activeView.trim() : "";
50060
49208
  return {
@@ -50069,7 +49217,7 @@ function openingView(activeView, activeDashboardId) {
50069
49217
  }
50070
49218
  function savedViewFromParam(activeView) {
50071
49219
  const word = typeof activeView === "string" ? activeView.trim() : "";
50072
- return (0, import_uuid4.isUuidShape)(word) ? word.toLowerCase() : null;
49220
+ return (0, import_uuid3.isUuidShape)(word) ? word.toLowerCase() : null;
50073
49221
  }
50074
49222
  function addressForView(view, layout) {
50075
49223
  return view && !view.isDefault ? view.id : layout;
@@ -50152,7 +49300,7 @@ function TablePage({
50152
49300
  const [view, setView] = (0, import_react288.useState)(() => {
50153
49301
  if (!seededViews || seededViews.length === 0) return null;
50154
49302
  const asked2 = savedViewFromParam(activeView);
50155
- return seededViews.find((v) => v.id === asked2) ?? defaultViewOf(seededViews) ?? seededViews[0];
49303
+ return seededViews.find((v) => v.id === asked2) ?? (0, import_views2.defaultViewOf)(seededViews) ?? seededViews[0];
50156
49304
  });
50157
49305
  const [looks, setLooks] = (0, import_react288.useState)(() => seededViews ? seededOpening?.looks : void 0);
50158
49306
  const looksSeededFor = (0, import_react288.useRef)(seededViews && seededOpening ? tableId : null);
@@ -50172,7 +49320,7 @@ function TablePage({
50172
49320
  };
50173
49321
  }, [client, tableId]);
50174
49322
  const look = view && looks ? looks[view.id] : void 0;
50175
- const shown4 = view ? applyLook(view, look) : null;
49323
+ const shown4 = view ? (0, import_views3.applyLook)(view, look) : null;
50176
49324
  const [viewsEpoch, setViewsEpoch] = (0, import_react288.useState)(0);
50177
49325
  const opening = openingRail(activeRecordId, activeRail);
50178
49326
  const recordsUi = useRecordsUi();
@@ -50245,7 +49393,7 @@ function TablePage({
50245
49393
  const toolbarFold2 = useToolbarFit(toolbarRow);
50246
49394
  const slotClipped = useSlotScroll(toolbarSlot);
50247
49395
  const embedded = pagePresentation2 === "embedded";
50248
- const pageSize = pageSizeAsked ?? (embedded ? EMBEDDED_PAGE_SIZE : 100);
49396
+ const pageSize = pageSizeAsked ?? (embedded ? import_first_page5.EMBEDDED_PAGE_SIZE : 100);
50249
49397
  const chooserInline = !embedded && !phone && toolbarFold2 < 2;
50250
49398
  const chooserCompact = !embedded && !phone && toolbarFold2 >= 2;
50251
49399
  const controlsInSheet = phone;
@@ -50281,7 +49429,7 @@ function TablePage({
50281
49429
  (k) => look[k] !== void 0 && !(k === "groupField" && activeGroupField) && !(k === "layout" && layoutFromLink)
50282
49430
  ) : [],
50283
49431
  fromAddress: [...layoutFromLink ? ["layout"] : [], ...activeGroupField ? ["groupField"] : []],
50284
- lookDiffers: view ? lookDiffers(view, look) : false
49432
+ lookDiffers: view ? (0, import_views3.lookDiffers)(view, look) : false
50285
49433
  };
50286
49434
  const shownSignature = JSON.stringify(shownReport);
50287
49435
  const reportRef = (0, import_react288.useRef)(onShownViewChange);
@@ -50307,7 +49455,7 @@ function TablePage({
50307
49455
  setSurface((now) => ({ ...now, rail: named }));
50308
49456
  }, [activeRail, activeRecordId]);
50309
49457
  (0, import_react288.useEffect)(() => {
50310
- const named = pageViewFromParam(activeView);
49458
+ const named = (0, import_views2.pageViewFromParam)(activeView);
50311
49459
  if (named === null) return;
50312
49460
  const isLayout = named !== "dashboards" && named !== "archived";
50313
49461
  setLayoutFromLink(isLayout ? named : null);
@@ -50318,7 +49466,7 @@ function TablePage({
50318
49466
  async (asked2) => {
50319
49467
  const current = view;
50320
49468
  if (!current) return;
50321
- const part = lookPart(asked2);
49469
+ const part = (0, import_views3.lookPart)(asked2);
50322
49470
  if (Object.keys(part).length === 0) return;
50323
49471
  const before = looks?.[current.id];
50324
49472
  const next = { ...before ?? {}, ...part };
@@ -50376,7 +49524,7 @@ function TablePage({
50376
49524
  addressReportRef.current?.(isViewAddressEmpty(addressNow) ? null : addressNow);
50377
49525
  }, [addressReady, addressSignature]);
50378
49526
  const queryShowing = !isViewAddressEmpty({ ...gridQuery ?? {}, hidden: [] });
50379
- const lookShowing = Boolean(view && looks && (lookDiffers(view, looks[view.id]) || queryShowing));
49527
+ const lookShowing = Boolean(view && looks && ((0, import_views3.lookDiffers)(view, looks[view.id]) || queryShowing));
50380
49528
  const [lookRefused, setLookRefused] = (0, import_react288.useState)(null);
50381
49529
  const [namingLook, setNamingLook] = (0, import_react288.useState)(false);
50382
49530
  const [lookName, setLookName] = (0, import_react288.useState)("");
@@ -50402,7 +49550,7 @@ function TablePage({
50402
49550
  const mine = current && looks ? looks[current.id] : void 0;
50403
49551
  if (!current || !mine) return;
50404
49552
  setLookRefused(null);
50405
- const { patch, left } = saveToViewPlan(current, mine);
49553
+ const { patch, left } = (0, import_views3.saveToViewPlan)(current, mine);
50406
49554
  if (Object.keys(viewPatchDocument(patch)).length > 0) {
50407
49555
  const written = await saveViewPatch(client, tableId, current.id, patch);
50408
49556
  if (!written.ok) {
@@ -50441,14 +49589,14 @@ function TablePage({
50441
49589
  const [designateRefused, setDesignateRefused] = (0, import_react288.useState)(null);
50442
49590
  const opensAs = view?.isDefault ? view.layout : null;
50443
49591
  const canDesignate = Boolean(
50444
- rights.organise && view && layoutShowing && layoutShowing !== opensAs && storeKeepsLayout(layoutShowing)
49592
+ rights.organise && view && layoutShowing && layoutShowing !== opensAs && (0, import_views2.storeKeepsLayout)(layoutShowing)
50445
49593
  );
50446
- const layoutShowingLabel = layoutShowing ? LAYOUT_LABEL[layoutShowing] : "";
49594
+ const layoutShowingLabel = layoutShowing ? import_views2.LAYOUT_LABEL[layoutShowing] : "";
50447
49595
  const designate = async () => {
50448
49596
  const current = view;
50449
49597
  if (!current || !layoutShowing) return;
50450
49598
  setDesignateRefused(null);
50451
- const written = await designateView(client, tableId, current.id, layoutShowing);
49599
+ const written = await (0, import_views2.designateView)(client, tableId, current.id, layoutShowing);
50452
49600
  if (!written.ok) {
50453
49601
  setDesignateRefused(written.error);
50454
49602
  return;
@@ -50464,14 +49612,14 @@ function TablePage({
50464
49612
  {
50465
49613
  value: layoutShowing ?? "",
50466
49614
  onValueChange: (value) => {
50467
- if (VIEW_LAYOUTS.includes(value)) pickLayout(value);
49615
+ if (import_views2.VIEW_LAYOUTS.includes(value)) pickLayout(value);
50468
49616
  },
50469
- children: VIEW_LAYOUTS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(import_design_system146.DropdownMenuRadioItem, { value: option, children: LAYOUT_LABEL[option] }, option))
49617
+ 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
49618
  }
50471
49619
  );
50472
49620
  const sheetExtras = controlsInSheet && main === "records" && shownLayout === "grid" ? /* @__PURE__ */ (0, import_jsx_runtime163.jsxs)(import_jsx_runtime163.Fragment, { children: [
50473
49621
  /* @__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)(
49622
+ /* @__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
49623
  import_design_system146.Button,
50476
49624
  {
50477
49625
  size: "sm",
@@ -50479,7 +49627,7 @@ function TablePage({
50479
49627
  "aria-pressed": layoutShowing === option,
50480
49628
  className: "h-8 !w-auto",
50481
49629
  onClick: () => pickLayout(option),
50482
- children: LAYOUT_LABEL[option]
49630
+ children: import_views2.LAYOUT_LABEL[option]
50483
49631
  },
50484
49632
  option
50485
49633
  )) }),
@@ -50736,7 +49884,7 @@ function TablePage({
50736
49884
  ] });
50737
49885
  }
50738
49886
  const lookSavable = Boolean(
50739
- rights.write && view && Object.keys(viewPatchDocument(saveToViewPlan(view, look ?? {}).patch)).length > 0
49887
+ rights.write && view && Object.keys(viewPatchDocument((0, import_views3.saveToViewPlan)(view, look ?? {}).patch)).length > 0
50740
49888
  );
50741
49889
  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
49890
  headerNode,
@@ -50763,7 +49911,7 @@ function TablePage({
50763
49911
  if (before !== null && before !== next.id) {
50764
49912
  setViewLinkMissed(false);
50765
49913
  setPickedViewId(next.id);
50766
- onViewChanged?.(addressForView(next, applyLook(next, looks?.[next.id]).layout ?? "grid"));
49914
+ onViewChanged?.(addressForView(next, (0, import_views3.applyLook)(next, looks?.[next.id]).layout ?? "grid"));
50767
49915
  }
50768
49916
  },
50769
49917
  onViews: setViews,
@@ -50800,14 +49948,14 @@ function TablePage({
50800
49948
  },
50801
49949
  viewsEpoch
50802
49950
  ),
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)(
49951
+ 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
49952
  import_design_system146.Button,
50805
49953
  {
50806
49954
  size: "sm",
50807
49955
  variant: layoutShowing === option ? "secondary" : "ghost",
50808
49956
  "aria-pressed": layoutShowing === option,
50809
49957
  onClick: () => pickLayout(option),
50810
- children: LAYOUT_LABEL[option]
49958
+ children: import_views2.LAYOUT_LABEL[option]
50811
49959
  },
50812
49960
  option
50813
49961
  )) }) : null,
@@ -50945,7 +50093,7 @@ function TablePage({
50945
50093
  QuestionPanel,
50946
50094
  {
50947
50095
  tableId,
50948
- activeQuestionId: questionsFromLink && activeItemId && (0, import_uuid4.isUuidShape)(activeItemId) ? activeItemId : null,
50096
+ activeQuestionId: questionsFromLink && activeItemId && (0, import_uuid3.isUuidShape)(activeItemId) ? activeItemId : null,
50949
50097
  draft: questionDraft
50950
50098
  }
50951
50099
  ) : main === "archived" ? (
@@ -50978,7 +50126,7 @@ function TablePage({
50978
50126
  children: [
50979
50127
  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
50128
  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,
50129
+ 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
50130
  viewLinkMissed ? /* @__PURE__ */ (0, import_jsx_runtime163.jsx)(
50983
50131
  "p",
50984
50132
  {
@@ -51201,7 +50349,7 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51201
50349
  const writable = !column.readOnly && entity.canUpdate;
51202
50350
  const placed = (row) => entityValueText(column, entityCellValue(row, column)) || null;
51203
50351
  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);
50352
+ const rowsOf2 = (key) => entity.rows.filter((r) => (placed(r) ?? "") === key);
51205
50353
  const drop = async (event, to) => {
51206
50354
  event.preventDefault();
51207
50355
  setOver(null);
@@ -51213,7 +50361,7 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51213
50361
  if (says) setRefused({ to, says });
51214
50362
  };
51215
50363
  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);
50364
+ const cards = rowsOf2(lane.key);
51217
50365
  if (lane.key === "" && cards.length === 0) return null;
51218
50366
  return /* @__PURE__ */ (0, import_jsx_runtime164.jsxs)(
51219
50367
  "section",
@@ -51255,9 +50403,9 @@ function EntityBoard({ entity, groupBy, cardFields, onOpenRecord, className }) {
51255
50403
  );
51256
50404
  }) });
51257
50405
  }
51258
- function blockOfAnswer(answer, base, by) {
50406
+ function blockOfAnswer(answer, base2, by) {
51259
50407
  if (!answer.ok) {
51260
- return { ...base, refused: refusalSentence(answer.error) || "This chart could not be read.", ...answer.error.code ? { sqlstate: answer.error.code } : {} };
50408
+ return { ...base2, refused: refusalSentence(answer.error) || "This chart could not be read.", ...answer.error.code ? { sqlstate: answer.error.code } : {} };
51261
50409
  }
51262
50410
  const rows = answer.data.rows.filter((r) => by ? r.kind !== "total" : r.kind === "total").map((r) => {
51263
50411
  const groups = {};
@@ -51269,17 +50417,17 @@ function blockOfAnswer(answer, base, by) {
51269
50417
  for (const [k, v] of Object.entries(r.measures ?? {})) measuresOut[k] = typeof v === "number" ? v : v === null ? null : Number(v);
51270
50418
  return { groups, measures: measuresOut, row_count: Number(r.row_count) };
51271
50419
  });
51272
- return { ...base, rows };
50420
+ return { ...base2, rows };
51273
50421
  }
51274
50422
  function EntityChartBlock({ source, kind, by, measure, title, where, organization, centerValue, variant, className }) {
51275
50423
  const client = (0, import_react291.useRecordsClient)();
51276
50424
  const m = measure ?? { op: "count" };
51277
50425
  const ask = JSON.stringify([source.token, by ?? null, m, where ?? null, organization ?? null]);
51278
- const question = entityChartQuestion({ by, measure, where, organization });
50426
+ const question = (0, import_first_page7.entityChartQuestion)({ by, measure, where, organization });
51279
50427
  const measures = [m.op === "count" ? { op: "count" } : { op: m.op, key: m.of }];
51280
- const base = { title: title ?? "", kind, measures, group_by: by ? [by] : [] };
50428
+ const base2 = { title: title ?? "", kind, measures, group_by: by ? [by] : [] };
51281
50429
  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);
50430
+ const [block, setBlock] = (0, import_react290.useState)(() => seeded ? blockOfAnswer({ ok: true, data: seeded.data }, base2, by) : null);
51283
50431
  const seededFor = (0, import_react290.useRef)(seeded ? { ask: `${ask}|${kind}|${title ?? ""}`, at: seeded.at } : null);
51284
50432
  (0, import_react290.useEffect)(() => {
51285
50433
  const held = seededFor.current;
@@ -51288,7 +50436,7 @@ function EntityChartBlock({ source, kind, by, measure, title, where, organizatio
51288
50436
  let cancelled = false;
51289
50437
  void client.drillAsk({ source, question }).then((answer) => {
51290
50438
  if (cancelled) return;
51291
- setBlock(blockOfAnswer(answer, base, by));
50439
+ setBlock(blockOfAnswer(answer, base2, by));
51292
50440
  });
51293
50441
  return () => {
51294
50442
  cancelled = true;
@@ -51318,7 +50466,7 @@ function EntityTablePageBody({
51318
50466
  searchOverride,
51319
50467
  onSearchChange,
51320
50468
  searchBox = true,
51321
- pageSize = presentation === "embedded" ? EMBEDDED_PAGE_SIZE : 100,
50469
+ pageSize = presentation === "embedded" ? import_first_page5.EMBEDDED_PAGE_SIZE : 100,
51322
50470
  layout: opened = "grid",
51323
50471
  onLayoutChange,
51324
50472
  groupBy,
@@ -51457,7 +50605,7 @@ function TablePage2(props) {
51457
50605
 
51458
50606
  // src/DataBindingPicker.tsx
51459
50607
  var import_react292 = require("react");
51460
- var import_records71 = require("@ai-matrx/records");
50608
+ var import_records70 = require("@ai-matrx/records");
51461
50609
  var import_react293 = require("@ai-matrx/records/react");
51462
50610
  var import_design_system149 = require("@ai-matrx/design-system");
51463
50611
  var import_jsx_runtime166 = require("react/jsx-runtime");
@@ -51491,7 +50639,7 @@ function isCompleteDataBinding(binding) {
51491
50639
  }
51492
50640
  function bindingPlaceholdersFor(field2) {
51493
50641
  const label = fieldName(field2);
51494
- if ((0, import_records71.isEntityReferenceConfig)(field2.config)) {
50642
+ if ((0, import_records70.isEntityReferenceConfig)(field2.config)) {
51495
50643
  return [
51496
50644
  { token: `{${field2.key}.name}`, label: `${label} \xB7 name` },
51497
50645
  { token: `{${field2.key}.id}`, label: `${label} \xB7 id` }
@@ -51566,7 +50714,7 @@ function BindingDetails({
51566
50714
  }, [disabled, shape, binding, fields.loading, fieldList, table.data, onChange]);
51567
50715
  const selectShape = (next) => {
51568
50716
  if (next === shape) return;
51569
- const base = {
50717
+ const base2 = {
51570
50718
  kind: "merge_field",
51571
50719
  source: "record",
51572
50720
  semantic_type: next,
@@ -51574,21 +50722,21 @@ function BindingDetails({
51574
50722
  missing: binding.missing,
51575
50723
  override_policy: "shown_locked"
51576
50724
  };
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;
50725
+ if (next !== "collection" && binding.record_id) base2.record_id = binding.record_id;
50726
+ if (next === "value" && binding.field_key) base2.field_key = binding.field_key;
51579
50727
  if (next === "collection") {
51580
50728
  const limit = binding.limit ?? defaultRowLimit;
51581
- if (limit) base.limit = limit;
50729
+ if (limit) base2.limit = limit;
51582
50730
  }
51583
50731
  if (next !== "value" && binding.transform) {
51584
- base.transform = {
50732
+ base2.transform = {
51585
50733
  name: "list",
51586
50734
  template: binding.transform.template,
51587
50735
  ...binding.transform.join !== void 0 ? { join: binding.transform.join } : {},
51588
- ...next === "collection" && base.limit !== void 0 ? { max: base.limit } : {}
50736
+ ...next === "collection" && base2.limit !== void 0 ? { max: base2.limit } : {}
51589
50737
  };
51590
50738
  }
51591
- onChange(base);
50739
+ onChange(base2);
51592
50740
  };
51593
50741
  const fieldOptions = fieldList.map((f) => ({ value: f.key, label: fieldName(f) }));
51594
50742
  const template = binding.transform?.template ?? "";