@adoptai/genui-components 0.1.56 → 0.1.58

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.
Files changed (52) hide show
  1. package/dist/builders/BuilderForm.d.ts.map +1 -1
  2. package/dist/composites/decision-card/resolver.cjs +634 -0
  3. package/dist/composites/decision-card/resolver.cjs.map +1 -0
  4. package/dist/composites/decision-card/resolver.d.ts +13 -0
  5. package/dist/composites/decision-card/resolver.d.ts.map +1 -0
  6. package/dist/composites/decision-card/resolver.js +627 -0
  7. package/dist/composites/decision-card/resolver.js.map +1 -0
  8. package/dist/composites/document-field-extraction/FieldAuditLog.d.ts +27 -0
  9. package/dist/composites/document-field-extraction/FieldAuditLog.d.ts.map +1 -0
  10. package/dist/composites/document-field-extraction/FieldDetail.d.ts +22 -0
  11. package/dist/composites/document-field-extraction/FieldDetail.d.ts.map +1 -0
  12. package/dist/composites/document-field-extraction/FieldDetails.d.ts +18 -0
  13. package/dist/composites/document-field-extraction/FieldDetails.d.ts.map +1 -0
  14. package/dist/composites/document-field-extraction/bboxTransform.d.ts +25 -0
  15. package/dist/composites/document-field-extraction/bboxTransform.d.ts.map +1 -0
  16. package/dist/composites/document-field-extraction/fieldLabels.d.ts +2 -0
  17. package/dist/composites/document-field-extraction/fieldLabels.d.ts.map +1 -0
  18. package/dist/composites/document-field-extraction/resolver.d.ts +16 -0
  19. package/dist/composites/document-field-extraction/resolver.d.ts.map +1 -0
  20. package/dist/composites/workflow-stepper/resolver.cjs +4 -1
  21. package/dist/composites/workflow-stepper/resolver.cjs.map +1 -1
  22. package/dist/composites/workflow-stepper/resolver.js +4 -1
  23. package/dist/composites/workflow-stepper/resolver.js.map +1 -1
  24. package/dist/index.cjs +2735 -382
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2530 -183
  29. package/dist/index.js.map +1 -1
  30. package/dist/renderer.cjs +2410 -178
  31. package/dist/renderer.cjs.map +1 -1
  32. package/dist/renderer.js +2267 -35
  33. package/dist/renderer.js.map +1 -1
  34. package/dist/resolver.cjs +2409 -177
  35. package/dist/resolver.cjs.map +1 -1
  36. package/dist/resolver.d.ts.map +1 -1
  37. package/dist/resolver.js +2267 -35
  38. package/dist/resolver.js.map +1 -1
  39. package/dist/schemas/decision-card.d.ts +149 -0
  40. package/dist/schemas/decision-card.d.ts.map +1 -0
  41. package/dist/schemas/document-field-extraction.d.ts +258 -0
  42. package/dist/schemas/document-field-extraction.d.ts.map +1 -0
  43. package/dist/schemas/index.cjs +283 -1
  44. package/dist/schemas/index.cjs.map +1 -1
  45. package/dist/schemas/index.d.ts +407 -0
  46. package/dist/schemas/index.d.ts.map +1 -1
  47. package/dist/schemas/index.js +283 -1
  48. package/dist/schemas/index.js.map +1 -1
  49. package/dist/shared/InteractionContext.d.ts +10 -0
  50. package/dist/shared/InteractionContext.d.ts.map +1 -1
  51. package/dist/tool-definitions.json +359 -3
  52. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import React41, { lazy, createContext, useMemo, useContext, useState, useCallback, useEffect, useRef, useLayoutEffect, Suspense } from 'react';
2
+ import React45, { lazy, createContext, useMemo, useContext, useState, useCallback, useEffect, useRef, useLayoutEffect, Suspense } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import dagre from '@dagrejs/dagre';
5
5
  import { createPortal } from 'react-dom';
@@ -5287,6 +5287,286 @@ var workflowStepperTool = {
5287
5287
  required: ["type", "title", "steps"]
5288
5288
  }
5289
5289
  };
5290
+ var bbox = z.tuple([z.number(), z.number(), z.number(), z.number()]);
5291
+ var fieldSchema = z.object({
5292
+ field_key: z.string(),
5293
+ label: z.string(),
5294
+ value: z.string(),
5295
+ page: z.number(),
5296
+ // 0-indexed, matches PageDimension.page
5297
+ bbox: bbox.nullable().optional(),
5298
+ confidence: z.number().optional(),
5299
+ confidence_tier: z.enum(["green", "amber", "red"]).optional(),
5300
+ badge: z.enum(["SC", "CN", "AB", "SW"]).optional(),
5301
+ state: z.enum(["ok", "corrected", "missing", "warn"]).optional(),
5302
+ entity_type: z.string().optional(),
5303
+ is_primary: z.boolean().optional(),
5304
+ // Set after a human correction (extractor output, or an optimistic in-card
5305
+ // edit) so the editable field card can show old → new and who changed it.
5306
+ previous_value: z.string().nullable().optional(),
5307
+ corrected_by: z.string().nullable().optional()
5308
+ });
5309
+ var pageSchema = z.object({
5310
+ page: z.number(),
5311
+ // 0-indexed
5312
+ imageUrl: z.string().optional(),
5313
+ // host-resolved from the durable image_ref
5314
+ width_pt: z.number(),
5315
+ height_pt: z.number()
5316
+ });
5317
+ var summaryStatSchema = z.object({
5318
+ field_key: z.string(),
5319
+ label: z.string(),
5320
+ value: z.string(),
5321
+ caption: z.string().nullable().optional()
5322
+ });
5323
+ var summaryFactSchema = z.object({
5324
+ field_key: z.string(),
5325
+ label: z.string(),
5326
+ value: z.string(),
5327
+ badge: z.string().nullable().optional()
5328
+ });
5329
+ var summarySchema = z.object({
5330
+ display_name: z.string().nullable().optional(),
5331
+ short_name: z.string().nullable().optional(),
5332
+ organization: z.string().nullable().optional(),
5333
+ domain: z.string().nullable().optional(),
5334
+ domain_group: z.string().nullable().optional(),
5335
+ tax_year: z.union([z.string(), z.number()]).nullable().optional(),
5336
+ crumbs: z.array(z.string()).optional(),
5337
+ tags: z.array(z.string()).optional(),
5338
+ stats: z.array(summaryStatSchema).optional(),
5339
+ facts: z.array(summaryFactSchema).optional()
5340
+ });
5341
+ var documentFieldExtractionSchema = z.object({
5342
+ type: z.literal("document-field-extraction"),
5343
+ doc_type: z.string().optional(),
5344
+ // Original uploaded filename (e.g. "2024_gl.pdf"); preferred over doc_type for
5345
+ // the card title since doc_type is often the "generic_fallback" schema name.
5346
+ file_name: z.string().optional(),
5347
+ // Server-side token; resolved by the host into pages/fields before render.
5348
+ payload_ref: z.string().optional(),
5349
+ // Present for persisted workstream docs; absent for pre-existing cards.
5350
+ store_id: z.string().optional(),
5351
+ doc_id: z.string().optional(),
5352
+ pages: z.array(pageSchema).max(100).optional(),
5353
+ fields: z.array(fieldSchema).max(1e3).optional(),
5354
+ // Page-count metadata for the Details tab ("N of M pages extracted").
5355
+ page_count: z.number().optional(),
5356
+ pages_processed: z.number().optional(),
5357
+ // Deterministic document summary for the Details tab.
5358
+ summary: summarySchema.nullable().optional()
5359
+ });
5360
+ var documentFieldExtractionTool = {
5361
+ name: "render_document_field_extraction",
5362
+ description: "Render extracted document fields as an interactive overlay on the page image(s) \u2014 colored bounding boxes per field plus a synced field-card list. Use after the extract_document tool returns; pass the returned payload_ref (the host expands it). For invoices, statements, tax forms, receipts, KYC/loan docs, POs where the user wants to SEE where each value sits on the page.",
5363
+ input_schema: {
5364
+ type: "object",
5365
+ properties: {
5366
+ type: { type: "string", enum: ["document-field-extraction"] },
5367
+ doc_type: { type: "string" },
5368
+ file_name: {
5369
+ type: "string",
5370
+ description: "Original uploaded filename; shown as the card title."
5371
+ },
5372
+ payload_ref: {
5373
+ type: "string",
5374
+ description: "Durable store key returned by extract_document; the GenUI host expands it into pages/fields at render time. Pass this verbatim \u2014 do NOT hand-build pages/fields."
5375
+ },
5376
+ store_id: {
5377
+ type: "string",
5378
+ description: "Docstore store id; present for persisted workstream docs. The host uses this to open the editable viewer."
5379
+ },
5380
+ doc_id: {
5381
+ type: "string",
5382
+ description: "Docstore document id; present for persisted workstream docs. Required for the editable viewer."
5383
+ },
5384
+ pages: {
5385
+ type: "array",
5386
+ items: {
5387
+ type: "object",
5388
+ properties: {
5389
+ page: { type: "number", description: "0-indexed page number" },
5390
+ imageUrl: { type: "string" },
5391
+ width_pt: { type: "number" },
5392
+ height_pt: { type: "number" }
5393
+ },
5394
+ required: ["page", "width_pt", "height_pt"]
5395
+ }
5396
+ },
5397
+ fields: {
5398
+ type: "array",
5399
+ items: {
5400
+ type: "object",
5401
+ properties: {
5402
+ field_key: { type: "string" },
5403
+ label: { type: "string" },
5404
+ value: { type: "string" },
5405
+ page: { type: "number", description: "0-indexed page number" },
5406
+ bbox: {
5407
+ type: "array",
5408
+ items: { type: "number" },
5409
+ description: "[x0,y0,x1,y1] PDF points, origin bottom-left; null if unlocated"
5410
+ },
5411
+ confidence: { type: "number" },
5412
+ confidence_tier: { type: "string", enum: ["green", "amber", "red"] },
5413
+ badge: { type: "string", enum: ["SC", "CN", "AB", "SW"] },
5414
+ state: { type: "string", enum: ["ok", "corrected", "missing", "warn"] },
5415
+ entity_type: { type: "string" },
5416
+ is_primary: { type: "boolean" }
5417
+ },
5418
+ required: ["field_key", "label", "value", "page"]
5419
+ }
5420
+ },
5421
+ page_count: { type: "number" },
5422
+ pages_processed: { type: "number" },
5423
+ summary: {
5424
+ type: "object",
5425
+ description: "Deterministic document summary for the Details tab (display_name, organization, domain, stats, facts, tags). Produced by the extractor \u2014 pass through verbatim.",
5426
+ properties: {
5427
+ display_name: { type: "string" },
5428
+ short_name: { type: "string" },
5429
+ organization: { type: "string" },
5430
+ domain: { type: "string" },
5431
+ domain_group: { type: "string" },
5432
+ tax_year: { type: "string" },
5433
+ crumbs: { type: "array", items: { type: "string" } },
5434
+ tags: { type: "array", items: { type: "string" } },
5435
+ stats: {
5436
+ type: "array",
5437
+ items: {
5438
+ type: "object",
5439
+ properties: {
5440
+ field_key: { type: "string" },
5441
+ label: { type: "string" },
5442
+ value: { type: "string" },
5443
+ caption: { type: "string" }
5444
+ },
5445
+ required: ["field_key", "label", "value"]
5446
+ }
5447
+ },
5448
+ facts: {
5449
+ type: "array",
5450
+ items: {
5451
+ type: "object",
5452
+ properties: {
5453
+ field_key: { type: "string" },
5454
+ label: { type: "string" },
5455
+ value: { type: "string" },
5456
+ badge: { type: "string" }
5457
+ },
5458
+ required: ["field_key", "label", "value"]
5459
+ }
5460
+ }
5461
+ }
5462
+ }
5463
+ },
5464
+ required: ["type"]
5465
+ }
5466
+ };
5467
+ var decisionCardSchema = z.object({
5468
+ type: z.literal("decision-card"),
5469
+ id: z.string().optional(),
5470
+ decision_type: z.string().optional(),
5471
+ title: z.string(),
5472
+ question: z.string(),
5473
+ amount: z.number().optional(),
5474
+ currency: z.string().optional(),
5475
+ amount_label: z.string().optional(),
5476
+ severity: z.enum(["low", "medium", "high"]).optional(),
5477
+ flags: z.array(
5478
+ z.object({
5479
+ field: z.string().optional(),
5480
+ issue: z.string(),
5481
+ severity: z.enum(["low", "medium", "high"]).optional()
5482
+ })
5483
+ ).max(6).optional(),
5484
+ options: z.array(
5485
+ z.object({
5486
+ id: z.string().optional(),
5487
+ label: z.string(),
5488
+ recommended: z.boolean().optional()
5489
+ })
5490
+ ).min(1).max(5),
5491
+ source: z.object({
5492
+ label: z.string().optional(),
5493
+ url: z.string().optional()
5494
+ }).optional(),
5495
+ resolved: z.object({
5496
+ option: z.string()
5497
+ }).optional()
5498
+ });
5499
+ var decisionCardTool = {
5500
+ name: "render_decision_card",
5501
+ description: "Render an inline human-in-the-loop (HITL) decision card \u2014 a single judgment the agent needs from the user, resolved in-thread. Shows a titled question with an optional dollar amount at stake, optional data-quality flags, and 2-5 mutually-exclusive resolution options (the first or `recommended` one renders as the primary action), plus an optional 'view source' link. Use for inline approve/choose decisions the user resolves directly in the conversation. NOT for handing off to an external review portal (use escalation-card) and NOT for collecting multiple typed fields (use render_builder).",
5502
+ input_schema: {
5503
+ type: "object",
5504
+ properties: {
5505
+ type: { type: "string", enum: ["decision-card"] },
5506
+ id: { type: "string", description: "Stable id for update-in-place rendering" },
5507
+ decision_type: {
5508
+ type: "string",
5509
+ description: "Short category shown in the eyebrow, e.g. 'Cross-check', 'Allocation', 'Reserve'"
5510
+ },
5511
+ title: { type: "string", description: "The decision headline, e.g. 'AR reserve adequacy'" },
5512
+ question: { type: "string", description: "The full question / context the user must judge" },
5513
+ amount: { type: "number", description: "Dollar value at stake, e.g. 27100" },
5514
+ currency: { type: "string", description: "ISO currency code; defaults to USD" },
5515
+ amount_label: { type: "string", description: "Caption above the amount, e.g. 'At stake'" },
5516
+ severity: {
5517
+ type: "string",
5518
+ enum: ["low", "medium", "high"],
5519
+ description: "Severity of the decision; tints the accent rail"
5520
+ },
5521
+ flags: {
5522
+ type: "array",
5523
+ maxItems: 6,
5524
+ description: "Optional data-quality flags surfaced on the card",
5525
+ items: {
5526
+ type: "object",
5527
+ properties: {
5528
+ field: { type: "string" },
5529
+ issue: { type: "string" },
5530
+ severity: { type: "string", enum: ["low", "medium", "high"] }
5531
+ },
5532
+ required: ["issue"]
5533
+ }
5534
+ },
5535
+ options: {
5536
+ type: "array",
5537
+ minItems: 1,
5538
+ maxItems: 5,
5539
+ description: "Mutually-exclusive resolution choices; mark one `recommended` to make it primary",
5540
+ items: {
5541
+ type: "object",
5542
+ properties: {
5543
+ id: { type: "string" },
5544
+ label: { type: "string" },
5545
+ recommended: { type: "boolean" }
5546
+ },
5547
+ required: ["label"]
5548
+ }
5549
+ },
5550
+ source: {
5551
+ type: "object",
5552
+ description: "Optional provenance link for the figure",
5553
+ properties: {
5554
+ label: { type: "string" },
5555
+ url: { type: "string" }
5556
+ }
5557
+ },
5558
+ resolved: {
5559
+ type: "object",
5560
+ description: "Pre-resolved state for transcript replay",
5561
+ properties: {
5562
+ option: { type: "string" }
5563
+ },
5564
+ required: ["option"]
5565
+ }
5566
+ },
5567
+ required: ["type", "title", "question", "options"]
5568
+ }
5569
+ };
5290
5570
 
5291
5571
  // src/schemas/buildRenderUITool.ts
5292
5572
  function buildRenderUITool(selectedSchemas) {
@@ -5405,7 +5685,9 @@ var schemaRegistry = {
5405
5685
  "connect-integration": { schema: connectIntegrationSchema, tool: connectIntegrationTool },
5406
5686
  "integrations-list": { schema: integrationsListSchema, tool: integrationsListTool },
5407
5687
  "pipeline-preview": { schema: pipelinePreviewSchema, tool: pipelinePreviewTool },
5408
- "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool }
5688
+ "workflow-stepper": { schema: workflowStepperSchema, tool: workflowStepperTool },
5689
+ "document-field-extraction": { schema: documentFieldExtractionSchema, tool: documentFieldExtractionTool },
5690
+ "decision-card": { schema: decisionCardSchema, tool: decisionCardTool }
5409
5691
  };
5410
5692
 
5411
5693
  // src/shared/ColumnSettingsPanel.tsx
@@ -6118,17 +6400,17 @@ function SparklineTableResolver(p) {
6118
6400
  // src/composites/heatmap-table/resolver.tsx
6119
6401
  init_theme();
6120
6402
  init_ThemeContext();
6121
- function heatColor(z59) {
6122
- const clamped = Math.max(-3, Math.min(3, z59));
6403
+ function heatColor(z61) {
6404
+ const clamped = Math.max(-3, Math.min(3, z61));
6123
6405
  const abs = Math.abs(clamped);
6124
6406
  const lightness = 95 - abs * 8;
6125
6407
  const hue = clamped >= 0 ? 142 : 0;
6126
6408
  return `hsl(${hue} 60% ${lightness}%)`;
6127
6409
  }
6128
- function heatTextColor(z59) {
6129
- const abs = Math.abs(z59);
6130
- if (abs > 2) return z59 >= 0 ? "#14532d" : "#7f1d1d";
6131
- if (abs > 1) return z59 >= 0 ? "#166534" : "#991b1b";
6410
+ function heatTextColor(z61) {
6411
+ const abs = Math.abs(z61);
6412
+ if (abs > 2) return z61 >= 0 ? "#14532d" : "#7f1d1d";
6413
+ if (abs > 1) return z61 >= 0 ? "#166534" : "#991b1b";
6132
6414
  return "var(--foreground)";
6133
6415
  }
6134
6416
  var th2 = {
@@ -6762,7 +7044,7 @@ function WaterfallChartResolver(p) {
6762
7044
  ] }) });
6763
7045
  }
6764
7046
  init_ThemeContext();
6765
- var FlowGraph2 = React41.lazy(
7047
+ var FlowGraph2 = React45.lazy(
6766
7048
  () => Promise.resolve().then(() => (init_FlowGraph(), FlowGraph_exports)).then((m) => ({ default: m.FlowGraph }))
6767
7049
  );
6768
7050
  function FlowCanvasRenderer({
@@ -7036,7 +7318,7 @@ function TrialBalanceResolver(p) {
7036
7318
  gDebit += a.debit;
7037
7319
  gCredit += a.credit;
7038
7320
  });
7039
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
7321
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
7040
7322
  /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 4, style: {
7041
7323
  padding: "8px 12px",
7042
7324
  fontSize: "12px",
@@ -8422,10 +8704,10 @@ function useFullscreen(ref) {
8422
8704
  // src/composites/document-preview/resolver.tsx
8423
8705
  init_theme();
8424
8706
  init_ThemeContext();
8425
- var PdfViewer2 = React41.lazy(
8707
+ var PdfViewer2 = React45.lazy(
8426
8708
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
8427
8709
  );
8428
- var ExcelViewer2 = React41.lazy(
8710
+ var ExcelViewer2 = React45.lazy(
8429
8711
  () => Promise.resolve().then(() => (init_ExcelViewer(), ExcelViewer_exports)).then((m) => ({ default: m.ExcelViewer }))
8430
8712
  );
8431
8713
  var highlightColors = {
@@ -9381,7 +9663,7 @@ function EngagementPipelineResolver(p) {
9381
9663
  const color = (_a3 = statusColor2[phase.status]) != null ? _a3 : "#d6d3d1";
9382
9664
  const isCurrent = i === activeIdx;
9383
9665
  const size = isCurrent ? 28 : 20;
9384
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
9666
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
9385
9667
  i > 0 && /* @__PURE__ */ jsx(
9386
9668
  "div",
9387
9669
  {
@@ -11547,7 +11829,7 @@ function FileCard({
11547
11829
  whiteSpace: "nowrap"
11548
11830
  },
11549
11831
  children: [
11550
- metaTokens.map((t, i) => /* @__PURE__ */ jsxs(React41.Fragment, { children: [
11832
+ metaTokens.map((t, i) => /* @__PURE__ */ jsxs(React45.Fragment, { children: [
11551
11833
  i > 0 && /* @__PURE__ */ jsx("span", { style: { color: "#c4c4c4" }, children: "\xB7" }),
11552
11834
  /* @__PURE__ */ jsx("span", { children: t })
11553
11835
  ] }, i)),
@@ -12122,7 +12404,7 @@ function KeyValueListResolver(p) {
12122
12404
  var _a4;
12123
12405
  return sum + ((_a4 = g.items) != null ? _a4 : []).length;
12124
12406
  }, 0);
12125
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12407
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12126
12408
  /* @__PURE__ */ jsxs(
12127
12409
  "div",
12128
12410
  {
@@ -12300,7 +12582,7 @@ function BalanceSheetResolver(p) {
12300
12582
  /* @__PURE__ */ jsxs("tbody", { children: [
12301
12583
  ((_p = p.sections) != null ? _p : []).map((section) => {
12302
12584
  var _a3;
12303
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12585
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12304
12586
  /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan, style: {
12305
12587
  padding: "8px 12px",
12306
12588
  fontSize: "12px",
@@ -12313,7 +12595,7 @@ function BalanceSheetResolver(p) {
12313
12595
  }, children: (_a3 = categoryLabels2[section.category]) != null ? _a3 : section.category }) }),
12314
12596
  section.subsections.map((sub, si) => {
12315
12597
  var _a4;
12316
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12598
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12317
12599
  /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan, style: {
12318
12600
  padding: "6px 10px 6px 24px",
12319
12601
  fontSize: "12px",
@@ -12489,7 +12771,7 @@ function IncomeStatementResolver(p) {
12489
12771
  textAlign: "left",
12490
12772
  whiteSpace: "nowrap"
12491
12773
  }, children: "\xA0" }),
12492
- periods.map((period) => /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12774
+ periods.map((period) => /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12493
12775
  /* @__PURE__ */ jsx("th", { style: {
12494
12776
  fontSize: "11px",
12495
12777
  fontWeight: 500,
@@ -12520,7 +12802,7 @@ function IncomeStatementResolver(p) {
12520
12802
  sections.map((section, si) => {
12521
12803
  var _a3;
12522
12804
  const isSubtotal = section.sectionType === "subtotal";
12523
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12805
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12524
12806
  /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: colCount, style: {
12525
12807
  padding: "8px 12px",
12526
12808
  fontSize: "12px",
@@ -12551,7 +12833,7 @@ function IncomeStatementResolver(p) {
12551
12833
  var _a5;
12552
12834
  const val = (_a5 = amounts[pi]) != null ? _a5 : 0;
12553
12835
  const isNeg = val < 0;
12554
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12836
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12555
12837
  /* @__PURE__ */ jsx("td", { style: {
12556
12838
  padding: "6px 10px",
12557
12839
  fontSize: "13px",
@@ -12586,7 +12868,7 @@ function IncomeStatementResolver(p) {
12586
12868
  var _a3;
12587
12869
  const val = (_a3 = grossProfit[pi]) != null ? _a3 : 0;
12588
12870
  const isNeg = val < 0;
12589
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12871
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12590
12872
  /* @__PURE__ */ jsx("td", { style: {
12591
12873
  padding: "8px 10px",
12592
12874
  fontSize: "12px",
@@ -12621,7 +12903,7 @@ function IncomeStatementResolver(p) {
12621
12903
  var _a3;
12622
12904
  const val = (_a3 = operatingIncome[pi]) != null ? _a3 : 0;
12623
12905
  const isNeg = val < 0;
12624
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12906
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12625
12907
  /* @__PURE__ */ jsx("td", { style: {
12626
12908
  padding: "8px 10px",
12627
12909
  fontSize: "12px",
@@ -12655,7 +12937,7 @@ function IncomeStatementResolver(p) {
12655
12937
  var _a3;
12656
12938
  const val = (_a3 = netIncome[pi]) != null ? _a3 : 0;
12657
12939
  const isNeg = val < 0;
12658
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
12940
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12659
12941
  /* @__PURE__ */ jsx("td", { style: {
12660
12942
  padding: "10px 10px",
12661
12943
  fontSize: "13px",
@@ -12875,7 +13157,7 @@ function CashFlowStatementResolver(p) {
12875
13157
  /* @__PURE__ */ jsxs("tbody", { children: [
12876
13158
  activities.map((activity, ai) => {
12877
13159
  var _a3, _b2, _c2;
12878
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
13160
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
12879
13161
  ai > 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
12880
13162
  "td",
12881
13163
  {
@@ -17176,7 +17458,10 @@ function PipelinePreviewResolver(p) {
17176
17458
  init_ThemeContext();
17177
17459
  var DEFAULT_INTERACTION = {
17178
17460
  selectedStepId: null,
17179
- onStepSelect: void 0
17461
+ onStepSelect: void 0,
17462
+ resolvedDecisions: void 0,
17463
+ onDecisionResolve: void 0,
17464
+ onDecisionSource: void 0
17180
17465
  };
17181
17466
  var GenUIInteractionContext = createContext(DEFAULT_INTERACTION);
17182
17467
  function GenUIInteractionProvider({ value, children }) {
@@ -17312,8 +17597,8 @@ var CARD_MIN = 132;
17312
17597
  var CARD_GAP = 16;
17313
17598
  var AUTO_COMPACT_BELOW = 360;
17314
17599
  function useContainerWidth(ref) {
17315
- const [w, setW] = React41.useState(0);
17316
- React41.useLayoutEffect(() => {
17600
+ const [w, setW] = React45.useState(0);
17601
+ React45.useLayoutEffect(() => {
17317
17602
  const el = ref.current;
17318
17603
  if (!el || typeof ResizeObserver === "undefined") return;
17319
17604
  const ro = new ResizeObserver((entries) => {
@@ -17414,15 +17699,15 @@ function WorkflowStepperRenderer({
17414
17699
  const interactive = typeof onSelectStep === "function";
17415
17700
  const statusColor3 = (s) => s === "active" ? ACCENT2 : STATUS_COLORS3[s];
17416
17701
  const doneCount = steps.filter((s) => s.status === "done").length;
17417
- const rootRef = React41.useRef(null);
17702
+ const rootRef = React45.useRef(null);
17418
17703
  const containerW = useContainerWidth(rootRef);
17419
17704
  let resolved = density === "auto" ? "full" : density;
17420
17705
  if (density === "auto" && containerW > 0) {
17421
17706
  const needed = steps.length * CARD_MIN + Math.max(0, steps.length - 1) * CARD_GAP;
17422
17707
  resolved = containerW < AUTO_COMPACT_BELOW || needed > containerW * 1.6 ? "compact" : "full";
17423
17708
  }
17424
- const scrollerRef = React41.useRef(null);
17425
- React41.useEffect(() => {
17709
+ const scrollerRef = React45.useRef(null);
17710
+ React45.useEffect(() => {
17426
17711
  if (resolved !== "full" || loading) return;
17427
17712
  const sc = scrollerRef.current;
17428
17713
  if (!sc) return;
@@ -17433,11 +17718,11 @@ function WorkflowStepperRenderer({
17433
17718
  el.scrollIntoView({ inline: "center", block: "nearest", behavior: "smooth" });
17434
17719
  }
17435
17720
  }, [resolved, loading, selectedStep, activeStepId]);
17436
- const [edges, setEdges] = React41.useState({
17721
+ const [edges, setEdges] = React45.useState({
17437
17722
  left: false,
17438
17723
  right: false
17439
17724
  });
17440
- const updateEdges = React41.useCallback(() => {
17725
+ const updateEdges = React45.useCallback(() => {
17441
17726
  const sc = scrollerRef.current;
17442
17727
  if (!sc) return;
17443
17728
  const max = sc.scrollWidth - sc.clientWidth;
@@ -17446,7 +17731,7 @@ function WorkflowStepperRenderer({
17446
17731
  const right = sl < max - 1;
17447
17732
  setEdges((prev) => prev.left === left && prev.right === right ? prev : { left, right });
17448
17733
  }, []);
17449
- React41.useLayoutEffect(() => {
17734
+ React45.useLayoutEffect(() => {
17450
17735
  if (resolved !== "full" || loading) return;
17451
17736
  updateEdges();
17452
17737
  const sc = scrollerRef.current;
@@ -17502,7 +17787,7 @@ function WorkflowStepperRenderer({
17502
17787
  const reached = s.status !== "pending";
17503
17788
  const clickable = interactive && reached;
17504
17789
  const size = act ? 11 : done ? 9 : 8;
17505
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
17790
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
17506
17791
  i > 0 && /* @__PURE__ */ jsx(
17507
17792
  "span",
17508
17793
  {
@@ -17645,7 +17930,7 @@ function WorkflowStepperRenderer({
17645
17930
  const color = statusColor3(step.status);
17646
17931
  const humans = ((_a3 = step.assignees) != null ? _a3 : []).filter((a) => a.kind === "human");
17647
17932
  const roleCaption = humans.map((h) => h.role).filter(Boolean).slice(0, 2).join(" \xB7 ");
17648
- return /* @__PURE__ */ jsxs(React41.Fragment, { children: [
17933
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
17649
17934
  i > 0 && /* @__PURE__ */ jsx(
17650
17935
  "div",
17651
17936
  {
@@ -17898,144 +18183,2202 @@ function WorkflowStepperResolver(p) {
17898
18183
  )
17899
18184
  ] }) });
17900
18185
  }
17901
- function resolveUI(rawPayload) {
17902
- const payload = coercePayload(rawPayload);
17903
- switch (payload.type) {
17904
- case "data-table":
17905
- return /* @__PURE__ */ jsx(DataTableResolver, __spreadValues({}, payload));
17906
- case "status-card":
17907
- return /* @__PURE__ */ jsx(StatusCardResolver, __spreadValues({}, payload));
17908
- case "alert":
17909
- return /* @__PURE__ */ jsx(AlertResolver, __spreadValues({}, payload));
17910
- case "stat-grid":
17911
- return /* @__PURE__ */ jsx(StatGridResolver, __spreadValues({}, payload));
17912
- case "tabs-panel":
17913
- return /* @__PURE__ */ jsx(TabsPanelResolver, __spreadValues({}, payload));
17914
- case "sparkline-table":
17915
- return /* @__PURE__ */ jsx(SparklineTableResolver, __spreadValues({}, payload));
17916
- case "heatmap-table":
17917
- return /* @__PURE__ */ jsx(HeatmapTableResolver, __spreadValues({}, payload));
17918
- case "screener-table":
17919
- return /* @__PURE__ */ jsx(ScreenerTableResolver, __spreadValues({}, payload));
17920
- case "grouped-table":
17921
- return /* @__PURE__ */ jsx(GroupedTableResolver, __spreadValues({}, payload));
17922
- case "news-feed":
17923
- return /* @__PURE__ */ jsx(NewsFeedResolver, __spreadValues({}, payload));
17924
- case "area-chart":
17925
- return /* @__PURE__ */ jsx(AreaChartResolver, __spreadValues({}, payload));
17926
- case "allocation-donut":
17927
- return /* @__PURE__ */ jsx(AllocationDonutResolver, __spreadValues({}, payload));
17928
- case "waterfall-chart":
17929
- return /* @__PURE__ */ jsx(WaterfallChartResolver, __spreadValues({}, payload));
17930
- case "flow-canvas":
17931
- return /* @__PURE__ */ jsx(FlowCanvasResolver, __spreadValues({}, payload));
17932
- case "trial-balance":
17933
- return /* @__PURE__ */ jsx(TrialBalanceResolver, __spreadValues({}, payload));
17934
- case "journal-entry":
17935
- return /* @__PURE__ */ jsx(JournalEntryResolver, __spreadValues({}, payload));
17936
- case "aging-report":
17937
- return /* @__PURE__ */ jsx(AgingReportResolver, __spreadValues({}, payload));
17938
- case "variance-analysis":
17939
- return /* @__PURE__ */ jsx(VarianceAnalysisResolver, __spreadValues({}, payload));
17940
- case "stacked-breakdown":
17941
- return /* @__PURE__ */ jsx(StackedBreakdownResolver, __spreadValues({}, payload));
17942
- case "comparative-bar-chart":
17943
- return /* @__PURE__ */ jsx(ComparativeBarChartResolver, __spreadValues({}, payload));
17944
- case "compliance-checklist":
17945
- return /* @__PURE__ */ jsx(ComplianceChecklistResolver, __spreadValues({}, payload));
17946
- case "reconciliation-view":
17947
- return /* @__PURE__ */ jsx(ReconciliationViewResolver, __spreadValues({}, payload));
17948
- case "audit-trail":
17949
- return /* @__PURE__ */ jsx(AuditTrailResolver, __spreadValues({}, payload));
17950
- case "document-preview":
17951
- return /* @__PURE__ */ jsx(DocumentPreviewResolver, __spreadValues({}, payload));
17952
- case "provenance-chain":
17953
- return /* @__PURE__ */ jsx(ProvenanceChainResolver, __spreadValues({}, payload));
17954
- case "search-results":
17955
- return /* @__PURE__ */ jsx(SearchResultsResolver, __spreadValues({}, payload));
17956
- case "legal-test-result":
17957
- return /* @__PURE__ */ jsx(LegalTestResultResolver, __spreadValues({}, payload));
17958
- case "engagement-pipeline":
17959
- return /* @__PURE__ */ jsx(EngagementPipelineResolver, __spreadValues({}, payload));
17960
- case "entity-card-grid":
17961
- return /* @__PURE__ */ jsx(EntityCardGridResolver, __spreadValues({}, payload));
17962
- case "job-tracker":
17963
- return /* @__PURE__ */ jsx(JobTrackerResolver, __spreadValues({}, payload));
17964
- case "cited-answer":
17965
- return /* @__PURE__ */ jsx(CitedAnswerResolver, __spreadValues({}, payload));
17966
- case "transaction-feed":
17967
- return /* @__PURE__ */ jsx(TransactionFeedResolver, __spreadValues({}, payload));
17968
- case "file-browser":
17969
- return /* @__PURE__ */ jsx(FileBrowserResolver, __spreadValues({}, payload));
17970
- case "download-card":
17971
- return /* @__PURE__ */ jsx(DownloadCardResolver, __spreadValues({}, payload));
17972
- case "ops-dashboard":
17973
- return /* @__PURE__ */ jsx(OpsDashboardResolver, __spreadValues({}, payload));
17974
- case "key-value-list":
17975
- return /* @__PURE__ */ jsx(KeyValueListResolver, __spreadValues({}, payload));
17976
- case "balance-sheet":
17977
- return /* @__PURE__ */ jsx(BalanceSheetResolver, __spreadValues({}, payload));
17978
- case "income-statement":
17979
- return /* @__PURE__ */ jsx(IncomeStatementResolver, __spreadValues({}, payload));
17980
- case "cash-flow-statement":
17981
- return /* @__PURE__ */ jsx(CashFlowStatementResolver, __spreadValues({}, payload));
17982
- case "general-ledger":
17983
- return /* @__PURE__ */ jsx(GeneralLedgerResolver, __spreadValues({}, payload));
17984
- case "chart-of-accounts":
17985
- return /* @__PURE__ */ jsx(ChartOfAccountsResolver, __spreadValues({}, payload));
17986
- case "invoice-detail":
17987
- return /* @__PURE__ */ jsx(InvoiceDetailResolver, __spreadValues({}, payload));
17988
- case "amortization-table":
17989
- return /* @__PURE__ */ jsx(AmortizationTableResolver, __spreadValues({}, payload));
17990
- case "depreciation-schedule":
17991
- return /* @__PURE__ */ jsx(DepreciationScheduleResolver, __spreadValues({}, payload));
17992
- case "escalation-card":
17993
- return /* @__PURE__ */ jsx(EscalationCardResolver, __spreadValues({}, payload));
17994
- case "line-chart":
17995
- return /* @__PURE__ */ jsx(LineChartResolver, __spreadValues({}, payload));
17996
- case "combo-chart":
17997
- return /* @__PURE__ */ jsx(ComboChartResolver, __spreadValues({}, payload));
17998
- case "gauge-chart":
17999
- return /* @__PURE__ */ jsx(GaugeChartResolver, __spreadValues({}, payload));
18000
- case "treemap-chart":
18001
- return /* @__PURE__ */ jsx(TreemapChartResolver, __spreadValues({}, payload));
18002
- case "radar-chart":
18003
- return /* @__PURE__ */ jsx(RadarChartResolver, __spreadValues({}, payload));
18004
- case "funnel-chart":
18005
- return /* @__PURE__ */ jsx(FunnelChartResolver, __spreadValues({}, payload));
18006
- case "bullet-chart":
18007
- return /* @__PURE__ */ jsx(BulletChartResolver, __spreadValues({}, payload));
18008
- case "scatter-chart":
18009
- return /* @__PURE__ */ jsx(ScatterChartResolver, __spreadValues({}, payload));
18010
- case "connect-integration":
18011
- return /* @__PURE__ */ jsx(ConnectIntegrationResolver, __spreadValues({}, payload));
18012
- case "integrations-list":
18013
- return /* @__PURE__ */ jsx(IntegrationsListResolver, __spreadValues({}, payload));
18014
- case "pipeline-preview":
18015
- return /* @__PURE__ */ jsx(PipelinePreviewResolver, __spreadValues({}, payload));
18016
- case "workflow-stepper":
18017
- return /* @__PURE__ */ jsx(WorkflowStepperResolver, __spreadValues({}, payload));
18018
- default: {
18019
- return /* @__PURE__ */ jsx(
18020
- "div",
18021
- {
18022
- role: "alert",
18023
- style: {
18024
- padding: "12px 16px",
18025
- border: "1px solid #dc2626",
18026
- borderRadius: "8px",
18027
- background: "#fef2f2",
18028
- color: "#dc2626",
18029
- fontSize: "13px",
18030
- fontWeight: 600
18031
- },
18032
- children: "Unknown UI type"
18033
- }
18034
- );
18035
- }
18036
- }
18037
- }
18038
- function InlineSpinner() {
18186
+ init_ThemeContext();
18187
+
18188
+ // src/composites/document-field-extraction/bboxTransform.ts
18189
+ function bboxToRect(bbox2, page, px) {
18190
+ if (!bbox2 || bbox2.length !== 4) return null;
18191
+ const { wPts, hPts } = page;
18192
+ const { wPx, hPx } = px;
18193
+ if (!wPts || !hPts || !wPx || !hPx) return null;
18194
+ const [x0, y0, x1, y1] = bbox2;
18195
+ const sx = wPx / wPts;
18196
+ const sy = hPx / hPts;
18197
+ return {
18198
+ left: x0 * sx,
18199
+ width: (x1 - x0) * sx,
18200
+ // Flip Y: the box's TOP in screen space is the page height minus its upper
18201
+ // PDF-point edge (y1), because PDF y grows upward from the bottom.
18202
+ top: (hPts - y1) * sy,
18203
+ height: (y1 - y0) * sy
18204
+ };
18205
+ }
18206
+
18207
+ // src/composites/document-field-extraction/FieldDetail.tsx
18208
+ init_ThemeContext();
18209
+
18210
+ // src/composites/document-field-extraction/fieldLabels.ts
18211
+ var LABEL_DISPLAY = {
18212
+ "employer identification number": "Employer ID (EIN)",
18213
+ "company or business name": "Company Name",
18214
+ "total revenue": "Total Revenue",
18215
+ "net income": "Net Income",
18216
+ "tax year": "Tax Year",
18217
+ "invoice number": "Invoice Number",
18218
+ "invoice date": "Invoice Date",
18219
+ "total amount due": "Total Amount Due",
18220
+ "vendor name": "Vendor Name",
18221
+ "receipt total": "Receipt Total",
18222
+ "transaction date": "Transaction Date",
18223
+ "merchant name": "Merchant Name"
18224
+ };
18225
+ function prettyLabel(label) {
18226
+ var _a2;
18227
+ return (_a2 = LABEL_DISPLAY[label]) != null ? _a2 : label.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
18228
+ }
18229
+ var TIER_COLORS = {
18230
+ green: "#15803d",
18231
+ amber: "#f59e0b",
18232
+ red: "#dc2626"
18233
+ };
18234
+ var BADGE_TITLE = {
18235
+ SC: "High confidence",
18236
+ CN: "Medium confidence",
18237
+ AB: "Low confidence",
18238
+ SW: "Very low confidence"
18239
+ };
18240
+ var BADGE_STYLE = {
18241
+ SC: { bg: "#dcfce7", fg: "#15803d" },
18242
+ CN: { bg: "#eff6ff", fg: "#0364ff" },
18243
+ AB: { bg: "#fff7ed", fg: "#92400e" },
18244
+ SW: { bg: "#fef2f2", fg: "#dc2626" }
18245
+ };
18246
+ var STATE_DOT = {
18247
+ ok: "#15803d",
18248
+ corrected: "#0364ff",
18249
+ missing: "#dc2626",
18250
+ warn: "#f59e0b"
18251
+ };
18252
+ function hexToRgba(hex, alpha) {
18253
+ const h = hex.replace("#", "");
18254
+ const r = parseInt(h.slice(0, 2), 16);
18255
+ const g = parseInt(h.slice(2, 4), 16);
18256
+ const b = parseInt(h.slice(4, 6), 16);
18257
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
18258
+ }
18259
+ function badgeStyle(f) {
18260
+ var _a2, _b;
18261
+ return (_b = BADGE_STYLE[(_a2 = f.badge) != null ? _a2 : ""]) != null ? _b : { bg: "#f6f6f6", fg: "#777777" };
18262
+ }
18263
+ function dotColor2(f) {
18264
+ var _a2, _b;
18265
+ return (_b = STATE_DOT[(_a2 = f.state) != null ? _a2 : "ok"]) != null ? _b : "#15803d";
18266
+ }
18267
+ function fieldColor(f, secondary) {
18268
+ var _a2, _b;
18269
+ if (f.state === "corrected") return secondary;
18270
+ return (_b = TIER_COLORS[(_a2 = f.confidence_tier) != null ? _a2 : "amber"]) != null ? _b : TIER_COLORS.amber;
18271
+ }
18272
+ function confidenceLabel(f) {
18273
+ var _a2;
18274
+ if (typeof f.confidence === "number" && !Number.isNaN(f.confidence)) {
18275
+ return `${Math.round(f.confidence * 100)}%`;
18276
+ }
18277
+ return (_a2 = f.badge) != null ? _a2 : "\u2014";
18278
+ }
18279
+ function FieldDetail({
18280
+ field,
18281
+ selected,
18282
+ onSelect,
18283
+ onSave,
18284
+ correctionCount = 0,
18285
+ cardRef
18286
+ }) {
18287
+ var _a2, _b, _c, _d;
18288
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18289
+ const [editing, setEditing] = React45.useState(false);
18290
+ const [draft, setDraft] = React45.useState("");
18291
+ const [saving, setSaving] = React45.useState(false);
18292
+ const [saveError, setSaveError] = React45.useState(null);
18293
+ const textareaRef = React45.useRef(null);
18294
+ const color = fieldColor(field, SECONDARY2);
18295
+ const corrected = field.state === "corrected";
18296
+ const startEdit = (e) => {
18297
+ e.stopPropagation();
18298
+ setDraft(field.value || "");
18299
+ setSaveError(null);
18300
+ setEditing(true);
18301
+ setTimeout(() => {
18302
+ var _a3, _b2;
18303
+ (_a3 = textareaRef.current) == null ? void 0 : _a3.focus();
18304
+ (_b2 = textareaRef.current) == null ? void 0 : _b2.select();
18305
+ }, 0);
18306
+ };
18307
+ const cancelEdit = (e) => {
18308
+ e.stopPropagation();
18309
+ setEditing(false);
18310
+ setSaveError(null);
18311
+ };
18312
+ const save = async (e) => {
18313
+ var _a3, _b2;
18314
+ e.stopPropagation();
18315
+ if (!onSave || draft === field.value) {
18316
+ setEditing(false);
18317
+ return;
18318
+ }
18319
+ setSaving(true);
18320
+ setSaveError(null);
18321
+ try {
18322
+ await onSave(field.field_key, draft);
18323
+ setEditing(false);
18324
+ } catch (err) {
18325
+ const msg = ((_b2 = (_a3 = err == null ? void 0 : err.response) == null ? void 0 : _a3.data) == null ? void 0 : _b2.detail) || "Save failed. Try again.";
18326
+ setSaveError(msg);
18327
+ } finally {
18328
+ setSaving(false);
18329
+ }
18330
+ };
18331
+ const handleKeyDown = (e) => {
18332
+ if (e.key === "Escape") cancelEdit(e);
18333
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) void save(e);
18334
+ };
18335
+ return /* @__PURE__ */ jsxs(
18336
+ "div",
18337
+ {
18338
+ ref: cardRef,
18339
+ "data-testid": "field-card",
18340
+ "data-field-key": field.field_key,
18341
+ "data-selected": selected ? "true" : "false",
18342
+ role: "button",
18343
+ tabIndex: 0,
18344
+ onClick: () => !editing && onSelect(selected ? null : field.field_key),
18345
+ onKeyDown: (e) => {
18346
+ if (!editing && e.key === "Enter") onSelect(selected ? null : field.field_key);
18347
+ },
18348
+ style: {
18349
+ display: "flex",
18350
+ flexDirection: "column",
18351
+ gap: "4px",
18352
+ padding: "8px 10px",
18353
+ borderRadius: "0.5rem",
18354
+ border: `1px solid ${selected ? color : BORDER4}`,
18355
+ background: selected ? hexToRgba(color, 0.06) : "white",
18356
+ cursor: editing ? "default" : "pointer",
18357
+ transition: "background 0.15s, border-color 0.15s"
18358
+ },
18359
+ children: [
18360
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", minWidth: 0 }, children: [
18361
+ /* @__PURE__ */ jsx(
18362
+ "span",
18363
+ {
18364
+ title: (_c = (_b = BADGE_TITLE[(_a2 = field.badge) != null ? _a2 : ""]) != null ? _b : field.badge) != null ? _c : "",
18365
+ style: {
18366
+ fontSize: "10px",
18367
+ fontWeight: 700,
18368
+ padding: "2px 6px",
18369
+ borderRadius: "4px",
18370
+ flexShrink: 0,
18371
+ letterSpacing: "0.02em",
18372
+ minWidth: "34px",
18373
+ textAlign: "center",
18374
+ fontVariantNumeric: "tabular-nums",
18375
+ background: badgeStyle(field).bg,
18376
+ color: badgeStyle(field).fg
18377
+ },
18378
+ children: confidenceLabel(field)
18379
+ }
18380
+ ),
18381
+ /* @__PURE__ */ jsx(
18382
+ "span",
18383
+ {
18384
+ title: prettyLabel(field.label),
18385
+ style: {
18386
+ fontSize: "12.5px",
18387
+ fontWeight: 600,
18388
+ color: "var(--foreground)",
18389
+ flex: 1,
18390
+ minWidth: 0,
18391
+ whiteSpace: "nowrap",
18392
+ overflow: "hidden",
18393
+ textOverflow: "ellipsis"
18394
+ },
18395
+ children: prettyLabel(field.label)
18396
+ }
18397
+ ),
18398
+ field.is_primary && /* @__PURE__ */ jsx(
18399
+ "span",
18400
+ {
18401
+ style: {
18402
+ fontSize: "9px",
18403
+ fontWeight: 600,
18404
+ textTransform: "uppercase",
18405
+ letterSpacing: "0.04em",
18406
+ color: MUTED2,
18407
+ flexShrink: 0
18408
+ },
18409
+ children: "Primary"
18410
+ }
18411
+ ),
18412
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: [
18413
+ "p.",
18414
+ field.page + 1
18415
+ ] }),
18416
+ !editing && onSave && /* @__PURE__ */ jsx(
18417
+ "button",
18418
+ {
18419
+ type: "button",
18420
+ onClick: startEdit,
18421
+ title: "Edit value",
18422
+ "aria-label": "Edit value",
18423
+ style: {
18424
+ border: `1px solid ${BORDER4}`,
18425
+ borderRadius: "6px",
18426
+ background: "white",
18427
+ cursor: "pointer",
18428
+ padding: "3px 5px",
18429
+ lineHeight: 1,
18430
+ flexShrink: 0,
18431
+ display: "inline-flex",
18432
+ alignItems: "center",
18433
+ justifyContent: "center"
18434
+ },
18435
+ children: /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: MUTED2, strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
18436
+ /* @__PURE__ */ jsx("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
18437
+ /* @__PURE__ */ jsx("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
18438
+ ] })
18439
+ }
18440
+ )
18441
+ ] }),
18442
+ editing ? /* @__PURE__ */ jsxs("div", { onClick: (e) => e.stopPropagation(), style: { display: "flex", flexDirection: "column", gap: "5px" }, children: [
18443
+ /* @__PURE__ */ jsx(
18444
+ "textarea",
18445
+ {
18446
+ ref: textareaRef,
18447
+ value: draft,
18448
+ onChange: (e) => setDraft(e.target.value),
18449
+ onKeyDown: handleKeyDown,
18450
+ rows: 3,
18451
+ placeholder: "Enter value\u2026",
18452
+ style: {
18453
+ width: "100%",
18454
+ boxSizing: "border-box",
18455
+ resize: "vertical",
18456
+ fontSize: "13px",
18457
+ fontFamily: "var(--font-sans)",
18458
+ color: "var(--foreground)",
18459
+ padding: "6px 8px",
18460
+ borderRadius: "0.4rem",
18461
+ border: `1px solid ${BORDER4}`
18462
+ }
18463
+ }
18464
+ ),
18465
+ saveError && /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: TIER_COLORS.red }, children: saveError }),
18466
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
18467
+ /* @__PURE__ */ jsx(
18468
+ "button",
18469
+ {
18470
+ type: "button",
18471
+ onClick: save,
18472
+ disabled: saving,
18473
+ title: "Save (\u2318\u21B5)",
18474
+ style: {
18475
+ display: "inline-flex",
18476
+ alignItems: "center",
18477
+ gap: "4px",
18478
+ fontSize: "11px",
18479
+ fontWeight: 600,
18480
+ padding: "4px 10px",
18481
+ borderRadius: "0.4rem",
18482
+ border: "none",
18483
+ background: "var(--foreground)",
18484
+ color: "white",
18485
+ cursor: saving ? "default" : "pointer",
18486
+ opacity: saving ? 0.7 : 1
18487
+ },
18488
+ children: saving ? "Saving\u2026" : "Save"
18489
+ }
18490
+ ),
18491
+ /* @__PURE__ */ jsx(
18492
+ "button",
18493
+ {
18494
+ type: "button",
18495
+ onClick: cancelEdit,
18496
+ disabled: saving,
18497
+ title: "Cancel (Esc)",
18498
+ style: {
18499
+ fontSize: "11px",
18500
+ fontWeight: 600,
18501
+ padding: "4px 10px",
18502
+ borderRadius: "0.4rem",
18503
+ border: `1px solid ${BORDER4}`,
18504
+ background: "white",
18505
+ color: MUTED2,
18506
+ cursor: saving ? "default" : "pointer"
18507
+ },
18508
+ children: "Cancel"
18509
+ }
18510
+ )
18511
+ ] })
18512
+ ] }) : corrected ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "2px", paddingLeft: "2px" }, children: [
18513
+ field.previous_value != null && field.previous_value !== "" && /* @__PURE__ */ jsx(
18514
+ "span",
18515
+ {
18516
+ style: {
18517
+ fontSize: "11.5px",
18518
+ color: MUTED2,
18519
+ textDecoration: "line-through",
18520
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18521
+ wordBreak: "break-word"
18522
+ },
18523
+ children: field.previous_value
18524
+ }
18525
+ ),
18526
+ /* @__PURE__ */ jsx(
18527
+ "span",
18528
+ {
18529
+ style: {
18530
+ fontSize: "12.5px",
18531
+ fontWeight: 600,
18532
+ color: "var(--foreground)",
18533
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18534
+ wordBreak: "break-word"
18535
+ },
18536
+ children: field.value || "\u2014"
18537
+ }
18538
+ ),
18539
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
18540
+ field.corrected_by && /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: SECONDARY2 }, title: `Corrected by ${field.corrected_by}`, children: field.corrected_by }),
18541
+ correctionCount > 0 && /* @__PURE__ */ jsxs(
18542
+ "span",
18543
+ {
18544
+ style: {
18545
+ fontSize: "10.5px",
18546
+ fontWeight: 600,
18547
+ color: MUTED2,
18548
+ background: PAPER2,
18549
+ borderRadius: "9999px",
18550
+ padding: "1px 7px"
18551
+ },
18552
+ children: [
18553
+ correctionCount,
18554
+ " ",
18555
+ correctionCount === 1 ? "event" : "events"
18556
+ ]
18557
+ }
18558
+ )
18559
+ ] })
18560
+ ] }) : (
18561
+ // Bottom row: monospace value + right-edge validation dot (file explorer).
18562
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", paddingLeft: "2px" }, children: [
18563
+ /* @__PURE__ */ jsx(
18564
+ "span",
18565
+ {
18566
+ style: {
18567
+ fontSize: "12.5px",
18568
+ color: MUTED2,
18569
+ fontFamily: "ui-monospace, 'Cascadia Code', monospace",
18570
+ flex: 1,
18571
+ minWidth: 0,
18572
+ whiteSpace: "nowrap",
18573
+ overflow: "hidden",
18574
+ textOverflow: "ellipsis"
18575
+ },
18576
+ title: field.value || "\u2014",
18577
+ children: field.value || "\u2014"
18578
+ }
18579
+ ),
18580
+ /* @__PURE__ */ jsx(
18581
+ "span",
18582
+ {
18583
+ title: (_d = field.state) != null ? _d : "ok",
18584
+ style: {
18585
+ width: "8px",
18586
+ height: "8px",
18587
+ borderRadius: "9999px",
18588
+ flexShrink: 0,
18589
+ background: dotColor2(field)
18590
+ }
18591
+ }
18592
+ )
18593
+ ] })
18594
+ )
18595
+ ]
18596
+ }
18597
+ );
18598
+ }
18599
+
18600
+ // src/composites/document-field-extraction/FieldDetails.tsx
18601
+ init_ThemeContext();
18602
+ var BADGE_DOT = {
18603
+ // gen-ui semantic dot colors
18604
+ ok: "#15803d",
18605
+ green: "#15803d",
18606
+ warn: "#f59e0b",
18607
+ amber: "#f59e0b",
18608
+ missing: "#dc2626",
18609
+ red: "#dc2626",
18610
+ corrected: "#0364ff"
18611
+ };
18612
+ function FieldDetails({
18613
+ summary,
18614
+ fileName,
18615
+ pageCount,
18616
+ pagesProcessed
18617
+ }) {
18618
+ var _a2, _b, _c, _d, _e, _f;
18619
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18620
+ if (!summary) {
18621
+ return /* @__PURE__ */ jsxs(
18622
+ "div",
18623
+ {
18624
+ style: {
18625
+ height: "100%",
18626
+ display: "flex",
18627
+ flexDirection: "column",
18628
+ alignItems: "center",
18629
+ justifyContent: "center",
18630
+ gap: "6px",
18631
+ color: MUTED2,
18632
+ textAlign: "center",
18633
+ padding: "24px"
18634
+ },
18635
+ children: [
18636
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "26px", lineHeight: 1 }, children: "\u{1F4C4}" }),
18637
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "14px", fontWeight: 600, color: "var(--foreground)" }, children: "No summary yet" }),
18638
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "12px", maxWidth: "280px" }, children: "This document has no extracted summary." })
18639
+ ]
18640
+ }
18641
+ );
18642
+ }
18643
+ const header = buildHeader(summary);
18644
+ const crumb = buildCrumbLine(summary);
18645
+ const facts = buildFacts(summary, fileName, pageCount, pagesProcessed);
18646
+ return /* @__PURE__ */ jsx("div", { style: { height: "100%", overflowY: "auto", paddingRight: "4px" }, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "14px" }, children: [
18647
+ /* @__PURE__ */ jsxs("header", { style: { display: "flex", flexDirection: "column", gap: "3px" }, children: [
18648
+ /* @__PURE__ */ jsx(
18649
+ "h2",
18650
+ {
18651
+ title: header.title,
18652
+ style: {
18653
+ margin: 0,
18654
+ fontFamily: "var(--font-serif)",
18655
+ fontSize: "20px",
18656
+ fontWeight: 400,
18657
+ letterSpacing: "-0.01em",
18658
+ color: "var(--foreground)",
18659
+ overflow: "hidden",
18660
+ textOverflow: "ellipsis",
18661
+ whiteSpace: "nowrap"
18662
+ },
18663
+ children: header.title
18664
+ }
18665
+ ),
18666
+ header.subtitle && /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: header.subtitle })
18667
+ ] }),
18668
+ (summary.domain || summary.display_name || summary.domain_group || ((_b = (_a2 = summary.tags) == null ? void 0 : _a2.length) != null ? _b : 0) > 0) && /* @__PURE__ */ jsxs(
18669
+ "section",
18670
+ {
18671
+ style: {
18672
+ display: "flex",
18673
+ flexDirection: "column",
18674
+ gap: "6px",
18675
+ padding: "12px 14px",
18676
+ borderRadius: "0.75rem",
18677
+ border: `1px solid ${BORDER4}`,
18678
+ background: PAPER2
18679
+ },
18680
+ children: [
18681
+ summary.domain_group && /* @__PURE__ */ jsx(
18682
+ "span",
18683
+ {
18684
+ style: {
18685
+ fontSize: "10px",
18686
+ fontWeight: 600,
18687
+ textTransform: "uppercase",
18688
+ letterSpacing: "0.06em",
18689
+ color: MUTED2
18690
+ },
18691
+ children: summary.domain_group
18692
+ }
18693
+ ),
18694
+ /* @__PURE__ */ jsx(
18695
+ "h3",
18696
+ {
18697
+ style: {
18698
+ margin: 0,
18699
+ fontSize: "14px",
18700
+ fontWeight: 600,
18701
+ color: "var(--foreground)"
18702
+ },
18703
+ children: summary.domain || summary.display_name
18704
+ }
18705
+ ),
18706
+ crumb && /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2 }, children: crumb }),
18707
+ ((_d = (_c = summary.tags) == null ? void 0 : _c.length) != null ? _d : 0) > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "5px", marginTop: "2px" }, children: summary.tags.map((t) => /* @__PURE__ */ jsx(
18708
+ "span",
18709
+ {
18710
+ style: {
18711
+ fontSize: "10px",
18712
+ fontWeight: 600,
18713
+ padding: "2px 8px",
18714
+ borderRadius: "9999px",
18715
+ background: "white",
18716
+ border: `1px solid ${BORDER4}`,
18717
+ color: MUTED2
18718
+ },
18719
+ children: t
18720
+ },
18721
+ t
18722
+ )) })
18723
+ ]
18724
+ }
18725
+ ),
18726
+ ((_f = (_e = summary.stats) == null ? void 0 : _e.length) != null ? _f : 0) > 0 && /* @__PURE__ */ jsx(
18727
+ "div",
18728
+ {
18729
+ style: {
18730
+ display: "grid",
18731
+ gridTemplateColumns: "repeat(auto-fit, minmax(130px, 1fr))",
18732
+ gap: "8px"
18733
+ },
18734
+ children: summary.stats.map((s) => /* @__PURE__ */ jsxs(
18735
+ "div",
18736
+ {
18737
+ style: {
18738
+ display: "flex",
18739
+ flexDirection: "column",
18740
+ gap: "2px",
18741
+ padding: "10px 12px",
18742
+ borderRadius: "0.6rem",
18743
+ border: `1px solid ${BORDER4}`,
18744
+ background: "white"
18745
+ },
18746
+ children: [
18747
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: MUTED2 }, children: s.label }),
18748
+ /* @__PURE__ */ jsx(
18749
+ "span",
18750
+ {
18751
+ title: s.value,
18752
+ style: {
18753
+ fontSize: "15px",
18754
+ fontWeight: 600,
18755
+ color: "var(--foreground)",
18756
+ overflow: "hidden",
18757
+ textOverflow: "ellipsis",
18758
+ whiteSpace: "nowrap"
18759
+ },
18760
+ children: s.value
18761
+ }
18762
+ ),
18763
+ s.caption && /* @__PURE__ */ jsx("span", { style: { fontSize: "10px", color: MUTED2 }, children: s.caption })
18764
+ ]
18765
+ },
18766
+ s.field_key
18767
+ ))
18768
+ }
18769
+ ),
18770
+ facts.length > 0 && /* @__PURE__ */ jsxs("section", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
18771
+ /* @__PURE__ */ jsxs(
18772
+ "div",
18773
+ {
18774
+ style: {
18775
+ display: "flex",
18776
+ alignItems: "center",
18777
+ gap: "6px",
18778
+ fontSize: "11px",
18779
+ fontWeight: 600,
18780
+ textTransform: "uppercase",
18781
+ letterSpacing: "0.04em",
18782
+ color: MUTED2
18783
+ },
18784
+ children: [
18785
+ /* @__PURE__ */ jsx("span", { children: "\u25A4" }),
18786
+ /* @__PURE__ */ jsx("span", { children: "Document details" })
18787
+ ]
18788
+ }
18789
+ ),
18790
+ /* @__PURE__ */ jsx(
18791
+ "dl",
18792
+ {
18793
+ style: {
18794
+ margin: 0,
18795
+ display: "grid",
18796
+ gridTemplateColumns: "minmax(110px, auto) 1fr",
18797
+ rowGap: "6px",
18798
+ columnGap: "14px"
18799
+ },
18800
+ children: facts.map((f) => {
18801
+ var _a3;
18802
+ return /* @__PURE__ */ jsxs(React45.Fragment, { children: [
18803
+ /* @__PURE__ */ jsx("dt", { style: { fontSize: "12px", color: MUTED2 }, children: f.label }),
18804
+ /* @__PURE__ */ jsxs(
18805
+ "dd",
18806
+ {
18807
+ title: typeof f.value === "string" ? f.value : void 0,
18808
+ style: {
18809
+ margin: 0,
18810
+ fontSize: "12px",
18811
+ color: "var(--foreground)",
18812
+ display: "flex",
18813
+ alignItems: "center",
18814
+ gap: "6px",
18815
+ wordBreak: "break-word"
18816
+ },
18817
+ children: [
18818
+ f.badge && /* @__PURE__ */ jsx(
18819
+ "span",
18820
+ {
18821
+ style: {
18822
+ width: "7px",
18823
+ height: "7px",
18824
+ borderRadius: "9999px",
18825
+ flexShrink: 0,
18826
+ background: (_a3 = BADGE_DOT[f.badge]) != null ? _a3 : SECONDARY2
18827
+ }
18828
+ }
18829
+ ),
18830
+ f.value
18831
+ ]
18832
+ }
18833
+ )
18834
+ ] }, f.key);
18835
+ })
18836
+ }
18837
+ )
18838
+ ] })
18839
+ ] }) });
18840
+ }
18841
+ function buildHeader(summary) {
18842
+ const form = [summary.short_name, summary.display_name].filter(Boolean);
18843
+ const title = summary.organization || form.shift() || summary.domain || "Document";
18844
+ const parts = summary.organization ? [...form] : form;
18845
+ if (summary.tax_year) parts.push(`TY ${summary.tax_year}`);
18846
+ return { title, subtitle: parts.join(" \xB7 ") };
18847
+ }
18848
+ function buildCrumbLine(summary) {
18849
+ const parts = [...summary.crumbs || [], summary.short_name].filter(Boolean);
18850
+ if (parts.length > 0) return parts.join(" \xB7 ");
18851
+ return summary.domain && summary.display_name ? summary.display_name : "";
18852
+ }
18853
+ function buildFacts(summary, fileName, pageCount, pagesProcessed) {
18854
+ const rows = [];
18855
+ if (fileName) rows.push({ key: "file", label: "File", value: fileName });
18856
+ if (summary.display_name) {
18857
+ rows.push({ key: "doctype", label: "Document type", value: summary.display_name });
18858
+ }
18859
+ if (summary.tax_year != null && summary.tax_year !== "") {
18860
+ rows.push({ key: "year", label: "Tax year", value: String(summary.tax_year) });
18861
+ }
18862
+ for (const f of summary.facts || []) {
18863
+ rows.push({ key: f.field_key, label: f.label, value: f.value, badge: f.badge });
18864
+ }
18865
+ if (pageCount) {
18866
+ rows.push({
18867
+ key: "pages",
18868
+ label: "Pages processed",
18869
+ value: `${pagesProcessed != null ? pagesProcessed : pageCount} / ${pageCount}`
18870
+ });
18871
+ }
18872
+ return rows;
18873
+ }
18874
+
18875
+ // src/composites/document-field-extraction/FieldAuditLog.tsx
18876
+ init_ThemeContext();
18877
+ function initials(name) {
18878
+ return name.trim().split(/\s+/).slice(0, 2).map((w) => {
18879
+ var _a2;
18880
+ return ((_a2 = w[0]) != null ? _a2 : "").toUpperCase();
18881
+ }).join("");
18882
+ }
18883
+ function formatTs(ts) {
18884
+ if (!ts) return "\u2014";
18885
+ const d = new Date(ts);
18886
+ if (Number.isNaN(d.getTime())) return ts;
18887
+ return d.toLocaleString(void 0, {
18888
+ month: "short",
18889
+ day: "numeric",
18890
+ hour: "2-digit",
18891
+ minute: "2-digit"
18892
+ });
18893
+ }
18894
+ function FieldAuditLog({
18895
+ events = [],
18896
+ loading = false,
18897
+ fields = []
18898
+ }) {
18899
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
18900
+ const fieldLabelMap = React45.useMemo(() => {
18901
+ var _a2;
18902
+ const map = {};
18903
+ for (const f of fields) map[f.field_key] = (_a2 = f.label) != null ? _a2 : f.field_key;
18904
+ return map;
18905
+ }, [fields]);
18906
+ if (loading) {
18907
+ return /* @__PURE__ */ jsx(
18908
+ "div",
18909
+ {
18910
+ style: {
18911
+ flex: 1,
18912
+ display: "flex",
18913
+ alignItems: "center",
18914
+ justifyContent: "center",
18915
+ padding: "32px 20px",
18916
+ fontSize: "13px",
18917
+ color: MUTED2
18918
+ },
18919
+ children: "Loading audit trail\u2026"
18920
+ }
18921
+ );
18922
+ }
18923
+ if (events.length === 0) {
18924
+ return /* @__PURE__ */ jsxs(
18925
+ "div",
18926
+ {
18927
+ style: {
18928
+ flex: 1,
18929
+ display: "flex",
18930
+ flexDirection: "column",
18931
+ alignItems: "center",
18932
+ justifyContent: "center",
18933
+ gap: "6px",
18934
+ padding: "32px 20px",
18935
+ textAlign: "center"
18936
+ },
18937
+ children: [
18938
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "13.5px", fontWeight: 600, color: "var(--foreground)" }, children: "No changes yet" }),
18939
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "12px", color: MUTED2, maxWidth: "240px", lineHeight: 1.5 }, children: "Field corrections will appear here." })
18940
+ ]
18941
+ }
18942
+ );
18943
+ }
18944
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", flex: 1, minHeight: 0, overflow: "hidden" }, children: [
18945
+ /* @__PURE__ */ jsx("div", { style: { padding: "8px 14px 6px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs(
18946
+ "span",
18947
+ {
18948
+ style: {
18949
+ fontSize: "11.5px",
18950
+ fontWeight: 600,
18951
+ color: MUTED2,
18952
+ textTransform: "uppercase",
18953
+ letterSpacing: "0.04em"
18954
+ },
18955
+ children: [
18956
+ events.length,
18957
+ " ",
18958
+ events.length === 1 ? "change" : "changes"
18959
+ ]
18960
+ }
18961
+ ) }),
18962
+ /* @__PURE__ */ jsx("ol", { style: { listStyle: "none", margin: 0, padding: "0 0 16px", overflowY: "auto", flex: 1, minHeight: 0 }, children: events.map((ev) => {
18963
+ var _a2, _b;
18964
+ const rawLabel = (_a2 = fieldLabelMap[ev.field_key]) != null ? _a2 : ev.field_key;
18965
+ const label = prettyLabel(rawLabel);
18966
+ const isAI = ev.actor_type === "system" || ev.event_type === "ai_corrected" || ev.event_type === "ai_extracted";
18967
+ const actor = isAI ? "AI" : ev.actor_name || "Unknown";
18968
+ const eventLabel = isAI ? "Re-extracted" : "Corrected";
18969
+ return /* @__PURE__ */ jsxs(
18970
+ "li",
18971
+ {
18972
+ "data-testid": "audit-row",
18973
+ style: { display: "flex", gap: "10px", padding: "10px 14px", borderBottom: `1px solid ${BORDER4}` },
18974
+ children: [
18975
+ /* @__PURE__ */ jsx(
18976
+ "div",
18977
+ {
18978
+ title: isAI ? "AI extraction" : actor,
18979
+ style: {
18980
+ flexShrink: 0,
18981
+ width: "28px",
18982
+ height: "28px",
18983
+ borderRadius: "50%",
18984
+ background: isAI ? "#dcfce7" : "#eff6ff",
18985
+ color: isAI ? "#15803d" : SECONDARY2,
18986
+ fontSize: "10.5px",
18987
+ fontWeight: 700,
18988
+ display: "flex",
18989
+ alignItems: "center",
18990
+ justifyContent: "center",
18991
+ marginTop: "1px"
18992
+ },
18993
+ children: isAI ? "\u2728" : initials(actor)
18994
+ }
18995
+ ),
18996
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "3px", flex: 1, minWidth: 0 }, children: [
18997
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "6px", flexWrap: "wrap" }, children: [
18998
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "12.5px", fontWeight: 600, color: isAI ? "#15803d" : "var(--foreground)" }, children: actor }),
18999
+ /* @__PURE__ */ jsx(
19000
+ "span",
19001
+ {
19002
+ style: {
19003
+ fontSize: "10.5px",
19004
+ fontWeight: 600,
19005
+ color: MUTED2,
19006
+ background: PAPER2,
19007
+ borderRadius: "4px",
19008
+ padding: "1px 6px",
19009
+ whiteSpace: "nowrap",
19010
+ flexShrink: 0
19011
+ },
19012
+ children: eventLabel
19013
+ }
19014
+ ),
19015
+ /* @__PURE__ */ jsx(
19016
+ "span",
19017
+ {
19018
+ style: {
19019
+ fontSize: "12px",
19020
+ color: MUTED2,
19021
+ flex: 1,
19022
+ minWidth: 0,
19023
+ whiteSpace: "nowrap",
19024
+ overflow: "hidden",
19025
+ textOverflow: "ellipsis"
19026
+ },
19027
+ children: label
19028
+ }
19029
+ ),
19030
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: MUTED2, flexShrink: 0 }, children: formatTs(ev.created_at) })
19031
+ ] }),
19032
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "6px", flexWrap: "wrap" }, children: [
19033
+ ev.previous_value != null && /* @__PURE__ */ jsxs(Fragment, { children: [
19034
+ /* @__PURE__ */ jsx(
19035
+ "span",
19036
+ {
19037
+ style: {
19038
+ fontSize: "12px",
19039
+ fontFamily: "ui-monospace, monospace",
19040
+ color: MUTED2,
19041
+ textDecoration: "line-through"
19042
+ },
19043
+ children: ev.previous_value
19044
+ }
19045
+ ),
19046
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: BORDER4 }, children: "\u2192" })
19047
+ ] }),
19048
+ /* @__PURE__ */ jsx(
19049
+ "span",
19050
+ {
19051
+ style: {
19052
+ fontSize: "12px",
19053
+ fontFamily: "ui-monospace, monospace",
19054
+ fontWeight: 600,
19055
+ color: "var(--foreground)"
19056
+ },
19057
+ children: (_b = ev.new_value) != null ? _b : "\u2014"
19058
+ }
19059
+ )
19060
+ ] }),
19061
+ ev.reason && /* @__PURE__ */ jsxs("p", { style: { margin: "2px 0 0", fontSize: "11.5px", color: MUTED2, fontStyle: "italic" }, children: [
19062
+ "\u201C",
19063
+ ev.reason,
19064
+ "\u201D"
19065
+ ] })
19066
+ ] })
19067
+ ]
19068
+ },
19069
+ ev.id
19070
+ );
19071
+ }) })
19072
+ ] });
19073
+ }
19074
+ var TIER_COLORS2 = {
19075
+ green: "#15803d",
19076
+ amber: "#f59e0b",
19077
+ red: "#dc2626"
19078
+ };
19079
+ function fieldColor2(f, secondary) {
19080
+ var _a2, _b;
19081
+ if (f.state === "corrected") return secondary;
19082
+ return (_b = TIER_COLORS2[(_a2 = f.confidence_tier) != null ? _a2 : "amber"]) != null ? _b : TIER_COLORS2.amber;
19083
+ }
19084
+ function hexToRgba2(hex, alpha) {
19085
+ const h = hex.replace("#", "");
19086
+ const r = parseInt(h.slice(0, 2), 16);
19087
+ const g = parseInt(h.slice(2, 4), 16);
19088
+ const b = parseInt(h.slice(4, 6), 16);
19089
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
19090
+ }
19091
+ function PageOverlay({
19092
+ page,
19093
+ fields,
19094
+ selectedKey,
19095
+ onSelect,
19096
+ secondary
19097
+ }) {
19098
+ const { PAPER: PAPER2, MUTED: MUTED2 } = useTheme();
19099
+ const imgRef = React45.useRef(null);
19100
+ const selectedBoxRef = React45.useRef(null);
19101
+ const [px, setPx] = React45.useState(null);
19102
+ React45.useEffect(() => {
19103
+ const el = imgRef.current;
19104
+ if (!el) return;
19105
+ const measure = () => {
19106
+ if (el.clientWidth && el.clientHeight) {
19107
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19108
+ }
19109
+ };
19110
+ measure();
19111
+ if (typeof ResizeObserver === "undefined") return;
19112
+ const ro = new ResizeObserver(measure);
19113
+ ro.observe(el);
19114
+ return () => ro.disconnect();
19115
+ }, [page.imageUrl]);
19116
+ React45.useEffect(() => {
19117
+ if (!selectedKey) return;
19118
+ if (!fields.some((f) => f.field_key === selectedKey && f.bbox)) return;
19119
+ const el = selectedBoxRef.current;
19120
+ if (el && typeof el.scrollIntoView === "function") {
19121
+ el.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
19122
+ }
19123
+ }, [selectedKey, fields, px]);
19124
+ const pagePts = { wPts: page.width_pt, hPts: page.height_pt };
19125
+ return /* @__PURE__ */ jsxs("div", { style: { position: "relative", width: "100%", lineHeight: 0 }, children: [
19126
+ page.imageUrl ? /* @__PURE__ */ jsx(
19127
+ "img",
19128
+ {
19129
+ ref: imgRef,
19130
+ src: page.imageUrl,
19131
+ alt: `Page ${page.page + 1}`,
19132
+ onLoad: () => {
19133
+ const el = imgRef.current;
19134
+ if (el && el.clientWidth && el.clientHeight) {
19135
+ setPx({ wPx: el.clientWidth, hPx: el.clientHeight });
19136
+ }
19137
+ },
19138
+ style: { display: "block", width: "100%", height: "auto" }
19139
+ }
19140
+ ) : (
19141
+ // No resolved image (host couldn't resolve the raster) — keep the
19142
+ // aspect box so cards still make sense, but show nothing to overlay on.
19143
+ /* @__PURE__ */ jsxs(
19144
+ "div",
19145
+ {
19146
+ style: {
19147
+ width: "100%",
19148
+ aspectRatio: `${page.width_pt} / ${page.height_pt}`,
19149
+ background: PAPER2,
19150
+ display: "flex",
19151
+ alignItems: "center",
19152
+ justifyContent: "center",
19153
+ fontSize: "12px",
19154
+ color: MUTED2,
19155
+ lineHeight: 1.4
19156
+ },
19157
+ children: [
19158
+ "Page ",
19159
+ page.page + 1,
19160
+ " image unavailable"
19161
+ ]
19162
+ }
19163
+ )
19164
+ ),
19165
+ px && page.imageUrl && fields.map((f) => {
19166
+ var _a2;
19167
+ const rect = bboxToRect((_a2 = f.bbox) != null ? _a2 : null, pagePts, px);
19168
+ if (!rect) return null;
19169
+ const color = fieldColor2(f, secondary);
19170
+ const selected = selectedKey === f.field_key;
19171
+ return /* @__PURE__ */ jsx(
19172
+ "div",
19173
+ {
19174
+ ref: selected ? selectedBoxRef : null,
19175
+ "data-testid": "bbox-rect",
19176
+ "data-field-key": f.field_key,
19177
+ "data-selected": selected ? "true" : "false",
19178
+ onClick: () => onSelect(selected ? null : f.field_key),
19179
+ title: `${f.label}: ${f.value}`,
19180
+ style: {
19181
+ position: "absolute",
19182
+ left: `${rect.left}px`,
19183
+ top: `${rect.top}px`,
19184
+ width: `${rect.width}px`,
19185
+ height: `${rect.height}px`,
19186
+ border: `1px solid ${color}`,
19187
+ background: hexToRgba2(color, selected ? 0.28 : 0.12),
19188
+ boxShadow: selected ? `0 0 0 2px ${hexToRgba2(color, 0.5)}` : "none",
19189
+ borderRadius: "2px",
19190
+ cursor: "pointer",
19191
+ transition: "background 0.15s, box-shadow 0.15s"
19192
+ }
19193
+ },
19194
+ f.field_key
19195
+ );
19196
+ })
19197
+ ] });
19198
+ }
19199
+ function ExtractionDetail({
19200
+ pages,
19201
+ orderedFields,
19202
+ fieldsByPage,
19203
+ selectedKey,
19204
+ setSelectedKey,
19205
+ onFieldSave,
19206
+ correctionCounts,
19207
+ tab,
19208
+ setTab,
19209
+ editable,
19210
+ summary,
19211
+ fileName,
19212
+ pageCount,
19213
+ pagesProcessed,
19214
+ auditEvents,
19215
+ auditLoading
19216
+ }) {
19217
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2, SECONDARY: SECONDARY2 } = useTheme();
19218
+ const selectedCardRef = React45.useRef(null);
19219
+ React45.useEffect(() => {
19220
+ if (!selectedKey || tab !== "fields") return;
19221
+ const el = selectedCardRef.current;
19222
+ if (el && typeof el.scrollIntoView === "function") {
19223
+ el.scrollIntoView({ behavior: "smooth", block: "nearest" });
19224
+ }
19225
+ }, [selectedKey, tab]);
19226
+ const tabs = [
19227
+ { key: "details", label: "Details" },
19228
+ { key: "fields", label: "Fields", count: orderedFields.length }
19229
+ ];
19230
+ if (editable) tabs.push({ key: "audit", label: "Audit Trails", count: (auditEvents == null ? void 0 : auditEvents.length) || void 0 });
19231
+ return /* @__PURE__ */ jsxs(
19232
+ "div",
19233
+ {
19234
+ style: {
19235
+ display: "grid",
19236
+ gridTemplateColumns: "minmax(0, 3fr) minmax(260px, 1fr)",
19237
+ gap: "12px",
19238
+ height: "100%",
19239
+ minHeight: 0
19240
+ },
19241
+ children: [
19242
+ /* @__PURE__ */ jsx(
19243
+ "div",
19244
+ {
19245
+ style: {
19246
+ display: "flex",
19247
+ flexDirection: "column",
19248
+ gap: "10px",
19249
+ borderRadius: "0.75rem",
19250
+ border: `1px solid ${BORDER4}`,
19251
+ overflowY: "auto",
19252
+ minHeight: 0
19253
+ },
19254
+ children: pages.map((pg) => /* @__PURE__ */ jsx(
19255
+ PageOverlay,
19256
+ {
19257
+ page: pg,
19258
+ fields: fieldsByPage(pg.page),
19259
+ selectedKey,
19260
+ onSelect: (key) => {
19261
+ setSelectedKey(key);
19262
+ if (key) setTab("fields");
19263
+ },
19264
+ secondary: SECONDARY2
19265
+ },
19266
+ pg.page
19267
+ ))
19268
+ }
19269
+ ),
19270
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", minWidth: 0, minHeight: 0 }, children: [
19271
+ /* @__PURE__ */ jsx(
19272
+ "div",
19273
+ {
19274
+ style: {
19275
+ display: "flex",
19276
+ gap: "16px",
19277
+ borderBottom: `1px solid ${BORDER4}`,
19278
+ flexShrink: 0,
19279
+ marginBottom: "10px"
19280
+ },
19281
+ children: tabs.map((t) => {
19282
+ const active = tab === t.key;
19283
+ return /* @__PURE__ */ jsxs(
19284
+ "button",
19285
+ {
19286
+ type: "button",
19287
+ onClick: () => setTab(t.key),
19288
+ "data-testid": `tab-${t.key}`,
19289
+ style: {
19290
+ appearance: "none",
19291
+ background: "transparent",
19292
+ borderTop: "none",
19293
+ borderLeft: "none",
19294
+ borderRight: "none",
19295
+ borderBottom: `2px solid ${active ? SECONDARY2 : "transparent"}`,
19296
+ padding: "6px 2px",
19297
+ marginBottom: "-1px",
19298
+ cursor: "pointer",
19299
+ fontSize: "13px",
19300
+ fontWeight: 600,
19301
+ color: active ? SECONDARY2 : MUTED2,
19302
+ display: "inline-flex",
19303
+ alignItems: "center",
19304
+ gap: "6px"
19305
+ },
19306
+ children: [
19307
+ t.label,
19308
+ typeof t.count === "number" && /* @__PURE__ */ jsx(
19309
+ "span",
19310
+ {
19311
+ style: {
19312
+ fontSize: "11px",
19313
+ fontWeight: 600,
19314
+ padding: "1px 7px",
19315
+ borderRadius: "9999px",
19316
+ background: active ? "#eff6ff" : PAPER2,
19317
+ color: active ? SECONDARY2 : MUTED2
19318
+ },
19319
+ children: t.count
19320
+ }
19321
+ )
19322
+ ]
19323
+ },
19324
+ t.key
19325
+ );
19326
+ })
19327
+ }
19328
+ ),
19329
+ tab === "details" ? /* @__PURE__ */ jsx(
19330
+ FieldDetails,
19331
+ {
19332
+ summary,
19333
+ fileName,
19334
+ pageCount,
19335
+ pagesProcessed
19336
+ }
19337
+ ) : tab === "audit" ? /* @__PURE__ */ jsx("div", { style: { minHeight: 0, overflowY: "auto" }, children: /* @__PURE__ */ jsx(
19338
+ FieldAuditLog,
19339
+ {
19340
+ events: auditEvents != null ? auditEvents : [],
19341
+ loading: auditLoading != null ? auditLoading : false,
19342
+ fields: orderedFields.map((f) => ({ field_key: f.field_key, label: f.label }))
19343
+ }
19344
+ ) }) : /* @__PURE__ */ jsxs(
19345
+ "div",
19346
+ {
19347
+ style: {
19348
+ display: "flex",
19349
+ flexDirection: "column",
19350
+ minHeight: 0,
19351
+ overflowY: "auto",
19352
+ paddingRight: "4px"
19353
+ },
19354
+ children: [
19355
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: "12px", color: MUTED2, padding: "0 0 8px 2px", flexShrink: 0 }, children: [
19356
+ orderedFields.length,
19357
+ " extracted"
19358
+ ] }),
19359
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: orderedFields.map((f) => {
19360
+ var _a2;
19361
+ const selected = selectedKey === f.field_key;
19362
+ return /* @__PURE__ */ jsx(
19363
+ FieldDetail,
19364
+ {
19365
+ field: f,
19366
+ selected,
19367
+ onSelect: setSelectedKey,
19368
+ onSave: onFieldSave,
19369
+ correctionCount: (_a2 = correctionCounts == null ? void 0 : correctionCounts[f.field_key]) != null ? _a2 : 0,
19370
+ cardRef: selected ? selectedCardRef : void 0
19371
+ },
19372
+ f.field_key
19373
+ );
19374
+ }) })
19375
+ ]
19376
+ }
19377
+ )
19378
+ ] })
19379
+ ]
19380
+ }
19381
+ );
19382
+ }
19383
+ function ExtractionModal({
19384
+ open,
19385
+ onClose,
19386
+ title,
19387
+ children
19388
+ }) {
19389
+ const { BORDER: BORDER4, MUTED: MUTED2 } = useTheme();
19390
+ React45.useEffect(() => {
19391
+ if (!open) return;
19392
+ const onKey = (e) => {
19393
+ if (e.key === "Escape") onClose();
19394
+ };
19395
+ window.addEventListener("keydown", onKey);
19396
+ const prev = document.body.style.overflow;
19397
+ document.body.style.overflow = "hidden";
19398
+ return () => {
19399
+ window.removeEventListener("keydown", onKey);
19400
+ document.body.style.overflow = prev;
19401
+ };
19402
+ }, [open, onClose]);
19403
+ if (!open || typeof document === "undefined") return null;
19404
+ return createPortal(
19405
+ /* @__PURE__ */ jsx(
19406
+ "div",
19407
+ {
19408
+ role: "dialog",
19409
+ "aria-modal": "true",
19410
+ "aria-label": title,
19411
+ onClick: onClose,
19412
+ style: {
19413
+ position: "fixed",
19414
+ inset: 0,
19415
+ zIndex: 2147483e3,
19416
+ background: "rgba(0,0,0,0.5)",
19417
+ display: "flex",
19418
+ alignItems: "center",
19419
+ justifyContent: "center",
19420
+ padding: "4vh 4vw",
19421
+ backdropFilter: "blur(2px)"
19422
+ },
19423
+ children: /* @__PURE__ */ jsxs(
19424
+ "div",
19425
+ {
19426
+ onClick: (e) => e.stopPropagation(),
19427
+ style: {
19428
+ width: "90vw",
19429
+ height: "90vh",
19430
+ background: "white",
19431
+ borderRadius: "0.875rem",
19432
+ border: `1px solid ${BORDER4}`,
19433
+ boxShadow: "0 20px 60px rgba(0,0,0,0.30)",
19434
+ display: "flex",
19435
+ flexDirection: "column",
19436
+ overflow: "hidden"
19437
+ },
19438
+ children: [
19439
+ /* @__PURE__ */ jsxs(
19440
+ "div",
19441
+ {
19442
+ style: {
19443
+ display: "flex",
19444
+ alignItems: "center",
19445
+ gap: "10px",
19446
+ padding: "11px 16px",
19447
+ borderBottom: `1px solid ${BORDER4}`,
19448
+ flexShrink: 0
19449
+ },
19450
+ children: [
19451
+ /* @__PURE__ */ jsx(
19452
+ "span",
19453
+ {
19454
+ style: {
19455
+ flex: 1,
19456
+ minWidth: 0,
19457
+ fontFamily: "var(--font-serif)",
19458
+ fontSize: "16px",
19459
+ fontWeight: 400,
19460
+ letterSpacing: "-0.01em",
19461
+ color: "var(--foreground)",
19462
+ overflow: "hidden",
19463
+ textOverflow: "ellipsis",
19464
+ whiteSpace: "nowrap"
19465
+ },
19466
+ children: title
19467
+ }
19468
+ ),
19469
+ /* @__PURE__ */ jsx(
19470
+ "button",
19471
+ {
19472
+ type: "button",
19473
+ "aria-label": "Close",
19474
+ onClick: onClose,
19475
+ style: {
19476
+ border: `1px solid ${BORDER4}`,
19477
+ borderRadius: "8px",
19478
+ background: "white",
19479
+ cursor: "pointer",
19480
+ padding: "5px 9px",
19481
+ fontSize: "13px",
19482
+ color: MUTED2,
19483
+ lineHeight: 1
19484
+ },
19485
+ children: "\u2715"
19486
+ }
19487
+ )
19488
+ ]
19489
+ }
19490
+ ),
19491
+ /* @__PURE__ */ jsx(
19492
+ "div",
19493
+ {
19494
+ style: {
19495
+ flex: 1,
19496
+ minHeight: 0,
19497
+ overflow: "hidden",
19498
+ display: "flex",
19499
+ flexDirection: "column",
19500
+ padding: "14px 16px"
19501
+ },
19502
+ children
19503
+ }
19504
+ )
19505
+ ]
19506
+ }
19507
+ )
19508
+ }
19509
+ ),
19510
+ document.body
19511
+ );
19512
+ }
19513
+ function DocumentFieldExtractionResolver(p) {
19514
+ var _a2, _b;
19515
+ const { BORDER: BORDER4, MUTED: MUTED2, PAPER: PAPER2 } = useTheme();
19516
+ const [selectedKey, setSelectedKey] = React45.useState(null);
19517
+ const [open, setOpen] = React45.useState(false);
19518
+ const [tab, setTab] = React45.useState("fields");
19519
+ const pages = (_a2 = p.pages) != null ? _a2 : [];
19520
+ const fields = (_b = p.fields) != null ? _b : [];
19521
+ const editable = typeof p.onFieldSave === "function";
19522
+ const onLoadAudit = p.onLoadAudit;
19523
+ React45.useEffect(() => {
19524
+ if (tab === "audit" && onLoadAudit) {
19525
+ onLoadAudit();
19526
+ }
19527
+ }, [tab, onLoadAudit]);
19528
+ const correctionCounts = React45.useMemo(() => {
19529
+ var _a3, _b2;
19530
+ const counts = {};
19531
+ for (const ev of (_a3 = p.auditEvents) != null ? _a3 : []) {
19532
+ const human = ev.actor_type !== "system" && ev.event_type !== "ai_extracted";
19533
+ if (human) counts[ev.field_key] = ((_b2 = counts[ev.field_key]) != null ? _b2 : 0) + 1;
19534
+ }
19535
+ return counts;
19536
+ }, [p.auditEvents]);
19537
+ const orderedFields = [...fields].sort((a, b) => {
19538
+ var _a3, _b2;
19539
+ if (!!a.is_primary !== !!b.is_primary) return a.is_primary ? -1 : 1;
19540
+ return ((_a3 = b.confidence) != null ? _a3 : 0) - ((_b2 = a.confidence) != null ? _b2 : 0);
19541
+ });
19542
+ const fieldsByPage = (pageNo) => fields.filter((f) => f.page === pageNo);
19543
+ const csvCols = [
19544
+ { key: "label", label: "Field" },
19545
+ { key: "value", label: "Value" },
19546
+ { key: "page", label: "Page" },
19547
+ { key: "confidence", label: "Confidence" },
19548
+ { key: "badge", label: "Badge" },
19549
+ { key: "state", label: "State" }
19550
+ ];
19551
+ const csvRows = orderedFields.map((f) => {
19552
+ var _a3, _b2, _c;
19553
+ return {
19554
+ label: f.label,
19555
+ value: f.value,
19556
+ page: f.page + 1,
19557
+ confidence: (_a3 = f.confidence) != null ? _a3 : "",
19558
+ badge: (_b2 = f.badge) != null ? _b2 : "",
19559
+ state: (_c = f.state) != null ? _c : ""
19560
+ };
19561
+ });
19562
+ const title = p.file_name || (p.doc_type ? `${p.doc_type} \u2014 extracted fields` : "Extracted fields");
19563
+ const tierCounts = fields.reduce(
19564
+ (acc, f) => {
19565
+ var _a3;
19566
+ const t = (_a3 = f.confidence_tier) != null ? _a3 : "amber";
19567
+ if (t === "green") acc.high += 1;
19568
+ else if (t === "red") acc.low += 1;
19569
+ else acc.med += 1;
19570
+ return acc;
19571
+ },
19572
+ { high: 0, med: 0, low: 0 }
19573
+ );
19574
+ const chips = [
19575
+ { n: tierCounts.high, label: "high", color: TIER_COLORS2.green },
19576
+ { n: tierCounts.med, label: "medium", color: TIER_COLORS2.amber },
19577
+ { n: tierCounts.low, label: "low", color: TIER_COLORS2.red }
19578
+ ].filter((c) => c.n > 0);
19579
+ const thumb = pages.find((pg) => pg.imageUrl);
19580
+ return /* @__PURE__ */ jsxs(
19581
+ ComponentActions,
19582
+ {
19583
+ filename: "document-fields",
19584
+ onDownloadCSV: () => downloadCSV(csvCols, csvRows, "document-fields"),
19585
+ children: [
19586
+ /* @__PURE__ */ jsxs(
19587
+ "div",
19588
+ {
19589
+ role: "button",
19590
+ tabIndex: 0,
19591
+ onClick: () => setOpen(true),
19592
+ onKeyDown: (e) => {
19593
+ if (e.key === "Enter" || e.key === " ") {
19594
+ e.preventDefault();
19595
+ setOpen(true);
19596
+ }
19597
+ },
19598
+ style: {
19599
+ display: "flex",
19600
+ alignItems: "stretch",
19601
+ gap: "12px",
19602
+ padding: "12px",
19603
+ width: "100%",
19604
+ maxWidth: "440px",
19605
+ borderRadius: "0.75rem",
19606
+ border: `1px solid ${BORDER4}`,
19607
+ background: "white",
19608
+ cursor: "pointer",
19609
+ textAlign: "left",
19610
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.05)"
19611
+ },
19612
+ children: [
19613
+ /* @__PURE__ */ jsx(
19614
+ "div",
19615
+ {
19616
+ style: {
19617
+ width: "64px",
19618
+ flexShrink: 0,
19619
+ borderRadius: "0.5rem",
19620
+ border: `1px solid ${BORDER4}`,
19621
+ background: PAPER2,
19622
+ overflow: "hidden",
19623
+ display: "flex",
19624
+ alignItems: "center",
19625
+ justifyContent: "center"
19626
+ },
19627
+ children: (thumb == null ? void 0 : thumb.imageUrl) ? /* @__PURE__ */ jsx(
19628
+ "img",
19629
+ {
19630
+ src: thumb.imageUrl,
19631
+ alt: "Document preview",
19632
+ style: { width: "100%", height: "auto", display: "block" }
19633
+ }
19634
+ ) : /* @__PURE__ */ jsx("span", { style: { fontSize: "22px", lineHeight: 1, padding: "16px 0" }, children: "\u{1F4C4}" })
19635
+ }
19636
+ ),
19637
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "6px" }, children: [
19638
+ /* @__PURE__ */ jsx(
19639
+ "p",
19640
+ {
19641
+ style: {
19642
+ fontFamily: "var(--font-serif)",
19643
+ fontSize: "15px",
19644
+ fontWeight: 400,
19645
+ color: "var(--foreground)",
19646
+ letterSpacing: "-0.01em",
19647
+ margin: 0,
19648
+ overflow: "hidden",
19649
+ textOverflow: "ellipsis",
19650
+ whiteSpace: "nowrap"
19651
+ },
19652
+ children: p.file_name || p.doc_type || "Document"
19653
+ }
19654
+ ),
19655
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: "12px", color: MUTED2 }, children: [
19656
+ fields.length,
19657
+ " field",
19658
+ fields.length === 1 ? "" : "s",
19659
+ " extracted \xB7 ",
19660
+ pages.length,
19661
+ " page",
19662
+ pages.length === 1 ? "" : "s"
19663
+ ] }),
19664
+ chips.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: "5px" }, children: chips.map((c) => /* @__PURE__ */ jsxs(
19665
+ "span",
19666
+ {
19667
+ style: {
19668
+ display: "inline-flex",
19669
+ alignItems: "center",
19670
+ gap: "4px",
19671
+ fontSize: "10px",
19672
+ fontWeight: 600,
19673
+ padding: "2px 7px",
19674
+ borderRadius: "9999px",
19675
+ background: hexToRgba2(c.color, 0.12),
19676
+ color: c.color
19677
+ },
19678
+ children: [
19679
+ /* @__PURE__ */ jsx(
19680
+ "span",
19681
+ {
19682
+ style: {
19683
+ width: "6px",
19684
+ height: "6px",
19685
+ borderRadius: "9999px",
19686
+ background: c.color
19687
+ }
19688
+ }
19689
+ ),
19690
+ c.n,
19691
+ " ",
19692
+ c.label
19693
+ ]
19694
+ },
19695
+ c.label
19696
+ )) }),
19697
+ /* @__PURE__ */ jsx(
19698
+ "span",
19699
+ {
19700
+ style: {
19701
+ marginTop: "2px",
19702
+ alignSelf: "flex-start",
19703
+ fontSize: "12px",
19704
+ fontWeight: 600,
19705
+ padding: "6px 12px",
19706
+ borderRadius: "0.5rem",
19707
+ background: "var(--foreground)",
19708
+ color: "white"
19709
+ },
19710
+ children: "View & edit fields"
19711
+ }
19712
+ )
19713
+ ] })
19714
+ ]
19715
+ }
19716
+ ),
19717
+ /* @__PURE__ */ jsx(ExtractionModal, { open, onClose: () => setOpen(false), title, children: /* @__PURE__ */ jsx(
19718
+ ExtractionDetail,
19719
+ {
19720
+ pages,
19721
+ orderedFields,
19722
+ fieldsByPage,
19723
+ selectedKey,
19724
+ setSelectedKey,
19725
+ onFieldSave: p.onFieldSave,
19726
+ correctionCounts,
19727
+ tab,
19728
+ setTab,
19729
+ editable,
19730
+ summary: p.summary,
19731
+ fileName: p.file_name,
19732
+ pageCount: p.page_count,
19733
+ pagesProcessed: p.pages_processed,
19734
+ auditEvents: p.auditEvents,
19735
+ auditLoading: p.auditLoading
19736
+ }
19737
+ ) })
19738
+ ]
19739
+ }
19740
+ );
19741
+ }
19742
+ function DocumentFieldExtractionSkeleton() {
19743
+ const { BORDER: BORDER4, PAPER: PAPER2 } = useTheme();
19744
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
19745
+ /* @__PURE__ */ jsx("style", { children: `
19746
+ @keyframes dfeSkeletonPulse {
19747
+ 0%, 100% { opacity: 1; }
19748
+ 50% { opacity: 0.45; }
19749
+ }
19750
+ ` }),
19751
+ /* @__PURE__ */ jsxs(
19752
+ "div",
19753
+ {
19754
+ "aria-busy": "true",
19755
+ "aria-label": "Loading extracted document",
19756
+ style: {
19757
+ display: "flex",
19758
+ alignItems: "stretch",
19759
+ gap: "12px",
19760
+ padding: "12px",
19761
+ width: "100%",
19762
+ maxWidth: "440px",
19763
+ borderRadius: "0.75rem",
19764
+ border: `1px solid ${BORDER4}`,
19765
+ background: "white",
19766
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.05)"
19767
+ },
19768
+ children: [
19769
+ /* @__PURE__ */ jsx(
19770
+ "div",
19771
+ {
19772
+ style: {
19773
+ width: "64px",
19774
+ flexShrink: 0,
19775
+ borderRadius: "0.5rem",
19776
+ border: `1px solid ${BORDER4}`,
19777
+ background: PAPER2,
19778
+ minHeight: "82px",
19779
+ animation: "dfeSkeletonPulse 1.6s ease-in-out infinite"
19780
+ }
19781
+ }
19782
+ ),
19783
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "8px", paddingTop: "2px" }, children: [
19784
+ /* @__PURE__ */ jsx(
19785
+ "div",
19786
+ {
19787
+ style: {
19788
+ height: "14px",
19789
+ width: "65%",
19790
+ borderRadius: "4px",
19791
+ background: PAPER2,
19792
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.08s infinite"
19793
+ }
19794
+ }
19795
+ ),
19796
+ /* @__PURE__ */ jsx(
19797
+ "div",
19798
+ {
19799
+ style: {
19800
+ height: "11px",
19801
+ width: "45%",
19802
+ borderRadius: "4px",
19803
+ background: PAPER2,
19804
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.14s infinite"
19805
+ }
19806
+ }
19807
+ ),
19808
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "5px" }, children: [
19809
+ /* @__PURE__ */ jsx(
19810
+ "div",
19811
+ {
19812
+ style: {
19813
+ height: "18px",
19814
+ width: "66px",
19815
+ borderRadius: "9999px",
19816
+ background: PAPER2,
19817
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.2s infinite"
19818
+ }
19819
+ }
19820
+ ),
19821
+ /* @__PURE__ */ jsx(
19822
+ "div",
19823
+ {
19824
+ style: {
19825
+ height: "18px",
19826
+ width: "56px",
19827
+ borderRadius: "9999px",
19828
+ background: PAPER2,
19829
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.25s infinite"
19830
+ }
19831
+ }
19832
+ )
19833
+ ] }),
19834
+ /* @__PURE__ */ jsx(
19835
+ "div",
19836
+ {
19837
+ style: {
19838
+ height: "28px",
19839
+ width: "122px",
19840
+ borderRadius: "0.5rem",
19841
+ background: PAPER2,
19842
+ marginTop: "2px",
19843
+ animation: "dfeSkeletonPulse 1.6s ease-in-out 0.3s infinite"
19844
+ }
19845
+ }
19846
+ )
19847
+ ] })
19848
+ ]
19849
+ }
19850
+ )
19851
+ ] });
19852
+ }
19853
+ init_ThemeContext();
19854
+ var SEVERITY_COLORS = {
19855
+ high: { color: "#dc2626", bg: "#fef2f2" },
19856
+ medium: { color: "#f59e0b", bg: "#fff7ed" },
19857
+ low: { color: "#777777", bg: "#f2f2f2" }
19858
+ };
19859
+ var GREEN3 = "#15803d";
19860
+ var GREEN_SOFT = "#dcfce7";
19861
+ var STACK_BELOW = 380;
19862
+ function formatAmount2(amount, currency = "USD") {
19863
+ var _a2, _b;
19864
+ const abs = Math.abs(amount);
19865
+ const sign = amount < 0 ? "-" : "";
19866
+ let body;
19867
+ if (abs >= 1e6) body = `${(abs / 1e6).toFixed(abs >= 1e7 ? 0 : 1)}M`;
19868
+ else if (abs >= 1e3) body = `${(abs / 1e3).toFixed(abs >= 1e4 ? 0 : 1)}K`;
19869
+ else body = `${abs}`;
19870
+ let symbol = "$";
19871
+ try {
19872
+ const parts = new Intl.NumberFormat("en-US", {
19873
+ style: "currency",
19874
+ currency,
19875
+ maximumFractionDigits: 0
19876
+ }).formatToParts(0);
19877
+ symbol = (_b = (_a2 = parts.find((p) => p.type === "currency")) == null ? void 0 : _a2.value) != null ? _b : "$";
19878
+ } catch (e) {
19879
+ symbol = "$";
19880
+ }
19881
+ return `${sign}${symbol}${body}`;
19882
+ }
19883
+ function useContainerWidth2(ref) {
19884
+ const [w, setW] = React45.useState(0);
19885
+ React45.useLayoutEffect(() => {
19886
+ const el = ref.current;
19887
+ if (!el || typeof ResizeObserver === "undefined") return;
19888
+ const ro = new ResizeObserver((entries) => {
19889
+ var _a2;
19890
+ const cr = (_a2 = entries[0]) == null ? void 0 : _a2.contentRect;
19891
+ if (cr) setW(cr.width);
19892
+ });
19893
+ ro.observe(el);
19894
+ setW(el.getBoundingClientRect().width);
19895
+ return () => ro.disconnect();
19896
+ }, [ref]);
19897
+ return w;
19898
+ }
19899
+ var KEYFRAMES2 = `
19900
+ @keyframes dcRise{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
19901
+ .dc-rise{animation:dcRise 0.28s cubic-bezier(0.22,1,0.36,1) both}
19902
+ @media (prefers-reduced-motion: reduce){
19903
+ .dc-rise{animation:none !important;opacity:1 !important;transform:none !important}
19904
+ }`;
19905
+ function SparkCheck({ size, color }) {
19906
+ return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
19907
+ "path",
19908
+ {
19909
+ d: "M5 13l4 4L19 7",
19910
+ stroke: color,
19911
+ strokeWidth: 2.5,
19912
+ strokeLinecap: "round",
19913
+ strokeLinejoin: "round"
19914
+ }
19915
+ ) });
19916
+ }
19917
+ function FlagPill({ flag }) {
19918
+ var _a2;
19919
+ const sev = (_a2 = flag.severity) != null ? _a2 : "medium";
19920
+ const { color, bg } = SEVERITY_COLORS[sev];
19921
+ return /* @__PURE__ */ jsxs(
19922
+ "span",
19923
+ {
19924
+ style: {
19925
+ display: "inline-flex",
19926
+ alignItems: "center",
19927
+ gap: 5,
19928
+ fontSize: 11,
19929
+ fontWeight: 600,
19930
+ padding: "3px 9px",
19931
+ borderRadius: 9999,
19932
+ background: bg,
19933
+ color,
19934
+ lineHeight: 1.2
19935
+ },
19936
+ children: [
19937
+ /* @__PURE__ */ jsx(
19938
+ "span",
19939
+ {
19940
+ "aria-hidden": "true",
19941
+ style: { width: 6, height: 6, borderRadius: "50%", background: color, flexShrink: 0 }
19942
+ }
19943
+ ),
19944
+ flag.field ? `${flag.field}: ${flag.issue}` : flag.issue
19945
+ ]
19946
+ }
19947
+ );
19948
+ }
19949
+ function DecisionCardRenderer({
19950
+ data,
19951
+ resolved = null,
19952
+ onResolve,
19953
+ onOpenSource
19954
+ }) {
19955
+ var _a2, _b;
19956
+ const { BORDER: BORDER4, MUTED: MUTED2, ACCENT: ACCENT2, ACCENT_SOFT: ACCENT_SOFT2 } = useTheme();
19957
+ const rootRef = React45.useRef(null);
19958
+ const width = useContainerWidth2(rootRef);
19959
+ const stacked = width > 0 && width < STACK_BELOW;
19960
+ const options = (_a2 = data.options) != null ? _a2 : [];
19961
+ const recommendedIdx = Math.max(
19962
+ 0,
19963
+ options.findIndex((o) => o.recommended)
19964
+ );
19965
+ const railColor = data.severity ? SEVERITY_COLORS[data.severity].color : ACCENT2;
19966
+ const isResolved = Boolean(resolved);
19967
+ const amountNode = typeof data.amount === "number" ? /* @__PURE__ */ jsxs(
19968
+ "div",
19969
+ {
19970
+ style: {
19971
+ display: "flex",
19972
+ flexDirection: "column",
19973
+ alignItems: stacked ? "flex-start" : "flex-end",
19974
+ gap: 1,
19975
+ flexShrink: 0
19976
+ },
19977
+ children: [
19978
+ data.amount_label && /* @__PURE__ */ jsx(
19979
+ "span",
19980
+ {
19981
+ style: {
19982
+ fontSize: 10,
19983
+ textTransform: "uppercase",
19984
+ letterSpacing: "0.07em",
19985
+ fontWeight: 700,
19986
+ color: MUTED2
19987
+ },
19988
+ children: data.amount_label
19989
+ }
19990
+ ),
19991
+ /* @__PURE__ */ jsx(
19992
+ "span",
19993
+ {
19994
+ style: {
19995
+ fontSize: 18,
19996
+ fontWeight: 700,
19997
+ color: "var(--foreground)",
19998
+ fontVariantNumeric: "tabular-nums",
19999
+ letterSpacing: "-0.01em",
20000
+ lineHeight: 1.1
20001
+ },
20002
+ children: formatAmount2(data.amount, data.currency)
20003
+ }
20004
+ )
20005
+ ]
20006
+ }
20007
+ ) : null;
20008
+ return /* @__PURE__ */ jsxs(
20009
+ "div",
20010
+ {
20011
+ ref: rootRef,
20012
+ className: "dc-rise",
20013
+ "data-testid": "decision-card",
20014
+ "data-resolved": isResolved || void 0,
20015
+ style: {
20016
+ position: "relative",
20017
+ width: "100%",
20018
+ minWidth: 0,
20019
+ boxSizing: "border-box",
20020
+ borderRadius: "0.75rem",
20021
+ border: `1px solid ${isResolved ? GREEN_SOFT : BORDER4}`,
20022
+ background: isResolved ? "#f6fef9" : "white",
20023
+ boxShadow: "0 1px 2px rgba(0,0,0,0.03), 0 4px 12px rgba(0,0,0,0.04)",
20024
+ padding: "16px 18px 16px 20px",
20025
+ display: "flex",
20026
+ flexDirection: "column",
20027
+ gap: 12,
20028
+ overflow: "hidden"
20029
+ },
20030
+ children: [
20031
+ /* @__PURE__ */ jsx("style", { children: KEYFRAMES2 }),
20032
+ /* @__PURE__ */ jsx(
20033
+ "div",
20034
+ {
20035
+ "aria-hidden": "true",
20036
+ style: {
20037
+ position: "absolute",
20038
+ top: 0,
20039
+ left: 0,
20040
+ bottom: 0,
20041
+ width: 4,
20042
+ background: isResolved ? GREEN3 : railColor
20043
+ }
20044
+ }
20045
+ ),
20046
+ /* @__PURE__ */ jsxs(
20047
+ "div",
20048
+ {
20049
+ style: {
20050
+ display: "flex",
20051
+ flexDirection: stacked ? "column" : "row",
20052
+ alignItems: stacked ? "flex-start" : "flex-start",
20053
+ justifyContent: "space-between",
20054
+ gap: stacked ? 6 : 12
20055
+ },
20056
+ children: [
20057
+ /* @__PURE__ */ jsxs("div", { style: { minWidth: 0, display: "flex", flexDirection: "column", gap: 4 }, children: [
20058
+ /* @__PURE__ */ jsx(
20059
+ "span",
20060
+ {
20061
+ style: {
20062
+ fontSize: 10.5,
20063
+ textTransform: "uppercase",
20064
+ letterSpacing: "0.07em",
20065
+ fontWeight: 700,
20066
+ color: ACCENT2
20067
+ },
20068
+ children: data.decision_type ? `Decision needs you \xB7 ${data.decision_type}` : "Decision needs you"
20069
+ }
20070
+ ),
20071
+ /* @__PURE__ */ jsx(
20072
+ "p",
20073
+ {
20074
+ style: {
20075
+ fontFamily: "var(--font-serif)",
20076
+ fontSize: 17,
20077
+ fontWeight: 400,
20078
+ color: "var(--foreground)",
20079
+ letterSpacing: "-0.01em",
20080
+ margin: 0,
20081
+ lineHeight: 1.2
20082
+ },
20083
+ children: data.title
20084
+ }
20085
+ )
20086
+ ] }),
20087
+ amountNode
20088
+ ]
20089
+ }
20090
+ ),
20091
+ /* @__PURE__ */ jsx("p", { style: { fontSize: 13, lineHeight: 1.5, color: MUTED2, margin: 0 }, children: data.question }),
20092
+ data.flags && data.flags.length > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: data.flags.map((flag, i) => {
20093
+ var _a3;
20094
+ return /* @__PURE__ */ jsx(FlagPill, { flag }, `${(_a3 = flag.field) != null ? _a3 : "flag"}-${i}`);
20095
+ }) }),
20096
+ isResolved ? /* @__PURE__ */ jsxs(
20097
+ "div",
20098
+ {
20099
+ style: {
20100
+ display: "inline-flex",
20101
+ alignItems: "center",
20102
+ gap: 7,
20103
+ fontSize: 13,
20104
+ fontWeight: 600,
20105
+ color: GREEN3
20106
+ },
20107
+ children: [
20108
+ /* @__PURE__ */ jsx(SparkCheck, { size: 16, color: GREEN3 }),
20109
+ "Resolved \xB7 ",
20110
+ resolved
20111
+ ]
20112
+ }
20113
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
20114
+ /* @__PURE__ */ jsx(
20115
+ "div",
20116
+ {
20117
+ style: {
20118
+ display: "flex",
20119
+ flexDirection: stacked ? "column" : "row",
20120
+ flexWrap: stacked ? "nowrap" : "wrap",
20121
+ gap: 8
20122
+ },
20123
+ children: options.map((opt, idx) => {
20124
+ var _a3;
20125
+ const primary = idx === recommendedIdx;
20126
+ return /* @__PURE__ */ jsx(
20127
+ "button",
20128
+ {
20129
+ type: "button",
20130
+ onClick: () => onResolve == null ? void 0 : onResolve(opt.label),
20131
+ style: {
20132
+ width: stacked ? "100%" : "auto",
20133
+ textAlign: stacked ? "left" : "center",
20134
+ border: `1px solid ${primary ? ACCENT2 : BORDER4}`,
20135
+ background: primary ? ACCENT2 : "white",
20136
+ color: primary ? "white" : "var(--foreground)",
20137
+ borderRadius: 8,
20138
+ fontSize: 13,
20139
+ fontWeight: 600,
20140
+ padding: "9px 14px",
20141
+ cursor: "pointer",
20142
+ transition: "background 0.15s, border-color 0.15s, color 0.15s"
20143
+ },
20144
+ onMouseEnter: (e) => {
20145
+ if (primary) {
20146
+ e.currentTarget.style.background = ACCENT_SOFT2;
20147
+ } else {
20148
+ e.currentTarget.style.borderColor = ACCENT2;
20149
+ e.currentTarget.style.background = "#fafafa";
20150
+ }
20151
+ },
20152
+ onMouseLeave: (e) => {
20153
+ if (primary) {
20154
+ e.currentTarget.style.background = ACCENT2;
20155
+ } else {
20156
+ e.currentTarget.style.borderColor = BORDER4;
20157
+ e.currentTarget.style.background = "white";
20158
+ }
20159
+ },
20160
+ children: opt.label
20161
+ },
20162
+ (_a3 = opt.id) != null ? _a3 : opt.label
20163
+ );
20164
+ })
20165
+ }
20166
+ ),
20167
+ data.source && /* @__PURE__ */ jsxs(
20168
+ "button",
20169
+ {
20170
+ type: "button",
20171
+ onClick: onOpenSource,
20172
+ style: {
20173
+ alignSelf: "flex-start",
20174
+ display: "inline-flex",
20175
+ alignItems: "center",
20176
+ gap: 5,
20177
+ border: "none",
20178
+ background: "none",
20179
+ padding: 0,
20180
+ cursor: "pointer",
20181
+ fontSize: 12,
20182
+ fontWeight: 600,
20183
+ color: MUTED2,
20184
+ transition: "color 0.15s"
20185
+ },
20186
+ onMouseEnter: (e) => e.currentTarget.style.color = ACCENT2,
20187
+ onMouseLeave: (e) => e.currentTarget.style.color = MUTED2,
20188
+ children: [
20189
+ /* @__PURE__ */ jsx("svg", { width: 13, height: 13, viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
20190
+ "path",
20191
+ {
20192
+ d: "M14 3v4a1 1 0 001 1h4M5 4a1 1 0 011-1h8l5 5v11a1 1 0 01-1 1H6a1 1 0 01-1-1V4z",
20193
+ stroke: "currentColor",
20194
+ strokeWidth: 1.8,
20195
+ strokeLinecap: "round",
20196
+ strokeLinejoin: "round"
20197
+ }
20198
+ ) }),
20199
+ (_b = data.source.label) != null ? _b : "View source for this figure"
20200
+ ]
20201
+ }
20202
+ )
20203
+ ] })
20204
+ ]
20205
+ }
20206
+ );
20207
+ }
20208
+ function DecisionCardResolver(p) {
20209
+ var _a2, _b, _c, _d;
20210
+ const { resolvedDecisions, onDecisionResolve, onDecisionSource } = useGenUIInteraction();
20211
+ const decisionId = (_a2 = p.id) != null ? _a2 : p.title;
20212
+ const hostResolved = resolvedDecisions == null ? void 0 : resolvedDecisions[decisionId];
20213
+ const initial = (_c = hostResolved != null ? hostResolved : (_b = p.resolved) == null ? void 0 : _b.option) != null ? _c : null;
20214
+ const [localResolved, setLocalResolved] = React45.useState(initial);
20215
+ React45.useEffect(() => {
20216
+ if (hostResolved !== void 0) setLocalResolved(hostResolved);
20217
+ }, [hostResolved]);
20218
+ const resolved = hostResolved != null ? hostResolved : localResolved;
20219
+ const handleResolve = (option) => {
20220
+ setLocalResolved(option);
20221
+ onDecisionResolve == null ? void 0 : onDecisionResolve(decisionId, option);
20222
+ };
20223
+ const handleSource = () => {
20224
+ var _a3;
20225
+ onDecisionSource == null ? void 0 : onDecisionSource(decisionId, p.source);
20226
+ if (!onDecisionSource && ((_a3 = p.source) == null ? void 0 : _a3.url) && typeof window !== "undefined") {
20227
+ window.open(p.source.url, "_blank", "noopener,noreferrer");
20228
+ }
20229
+ };
20230
+ return /* @__PURE__ */ jsx(ComponentActions, { filename: (_d = p.title) != null ? _d : "decision-card", children: /* @__PURE__ */ jsx(
20231
+ DecisionCardRenderer,
20232
+ {
20233
+ data: p,
20234
+ resolved,
20235
+ onResolve: handleResolve,
20236
+ onOpenSource: handleSource
20237
+ }
20238
+ ) });
20239
+ }
20240
+ function resolveUI(rawPayload) {
20241
+ const payload = coercePayload(rawPayload);
20242
+ switch (payload.type) {
20243
+ case "data-table":
20244
+ return /* @__PURE__ */ jsx(DataTableResolver, __spreadValues({}, payload));
20245
+ case "status-card":
20246
+ return /* @__PURE__ */ jsx(StatusCardResolver, __spreadValues({}, payload));
20247
+ case "alert":
20248
+ return /* @__PURE__ */ jsx(AlertResolver, __spreadValues({}, payload));
20249
+ case "stat-grid":
20250
+ return /* @__PURE__ */ jsx(StatGridResolver, __spreadValues({}, payload));
20251
+ case "tabs-panel":
20252
+ return /* @__PURE__ */ jsx(TabsPanelResolver, __spreadValues({}, payload));
20253
+ case "sparkline-table":
20254
+ return /* @__PURE__ */ jsx(SparklineTableResolver, __spreadValues({}, payload));
20255
+ case "heatmap-table":
20256
+ return /* @__PURE__ */ jsx(HeatmapTableResolver, __spreadValues({}, payload));
20257
+ case "screener-table":
20258
+ return /* @__PURE__ */ jsx(ScreenerTableResolver, __spreadValues({}, payload));
20259
+ case "grouped-table":
20260
+ return /* @__PURE__ */ jsx(GroupedTableResolver, __spreadValues({}, payload));
20261
+ case "news-feed":
20262
+ return /* @__PURE__ */ jsx(NewsFeedResolver, __spreadValues({}, payload));
20263
+ case "area-chart":
20264
+ return /* @__PURE__ */ jsx(AreaChartResolver, __spreadValues({}, payload));
20265
+ case "allocation-donut":
20266
+ return /* @__PURE__ */ jsx(AllocationDonutResolver, __spreadValues({}, payload));
20267
+ case "waterfall-chart":
20268
+ return /* @__PURE__ */ jsx(WaterfallChartResolver, __spreadValues({}, payload));
20269
+ case "flow-canvas":
20270
+ return /* @__PURE__ */ jsx(FlowCanvasResolver, __spreadValues({}, payload));
20271
+ case "trial-balance":
20272
+ return /* @__PURE__ */ jsx(TrialBalanceResolver, __spreadValues({}, payload));
20273
+ case "journal-entry":
20274
+ return /* @__PURE__ */ jsx(JournalEntryResolver, __spreadValues({}, payload));
20275
+ case "aging-report":
20276
+ return /* @__PURE__ */ jsx(AgingReportResolver, __spreadValues({}, payload));
20277
+ case "variance-analysis":
20278
+ return /* @__PURE__ */ jsx(VarianceAnalysisResolver, __spreadValues({}, payload));
20279
+ case "stacked-breakdown":
20280
+ return /* @__PURE__ */ jsx(StackedBreakdownResolver, __spreadValues({}, payload));
20281
+ case "comparative-bar-chart":
20282
+ return /* @__PURE__ */ jsx(ComparativeBarChartResolver, __spreadValues({}, payload));
20283
+ case "compliance-checklist":
20284
+ return /* @__PURE__ */ jsx(ComplianceChecklistResolver, __spreadValues({}, payload));
20285
+ case "reconciliation-view":
20286
+ return /* @__PURE__ */ jsx(ReconciliationViewResolver, __spreadValues({}, payload));
20287
+ case "audit-trail":
20288
+ return /* @__PURE__ */ jsx(AuditTrailResolver, __spreadValues({}, payload));
20289
+ case "document-preview":
20290
+ return /* @__PURE__ */ jsx(DocumentPreviewResolver, __spreadValues({}, payload));
20291
+ case "provenance-chain":
20292
+ return /* @__PURE__ */ jsx(ProvenanceChainResolver, __spreadValues({}, payload));
20293
+ case "search-results":
20294
+ return /* @__PURE__ */ jsx(SearchResultsResolver, __spreadValues({}, payload));
20295
+ case "legal-test-result":
20296
+ return /* @__PURE__ */ jsx(LegalTestResultResolver, __spreadValues({}, payload));
20297
+ case "engagement-pipeline":
20298
+ return /* @__PURE__ */ jsx(EngagementPipelineResolver, __spreadValues({}, payload));
20299
+ case "entity-card-grid":
20300
+ return /* @__PURE__ */ jsx(EntityCardGridResolver, __spreadValues({}, payload));
20301
+ case "job-tracker":
20302
+ return /* @__PURE__ */ jsx(JobTrackerResolver, __spreadValues({}, payload));
20303
+ case "cited-answer":
20304
+ return /* @__PURE__ */ jsx(CitedAnswerResolver, __spreadValues({}, payload));
20305
+ case "transaction-feed":
20306
+ return /* @__PURE__ */ jsx(TransactionFeedResolver, __spreadValues({}, payload));
20307
+ case "file-browser":
20308
+ return /* @__PURE__ */ jsx(FileBrowserResolver, __spreadValues({}, payload));
20309
+ case "download-card":
20310
+ return /* @__PURE__ */ jsx(DownloadCardResolver, __spreadValues({}, payload));
20311
+ case "ops-dashboard":
20312
+ return /* @__PURE__ */ jsx(OpsDashboardResolver, __spreadValues({}, payload));
20313
+ case "key-value-list":
20314
+ return /* @__PURE__ */ jsx(KeyValueListResolver, __spreadValues({}, payload));
20315
+ case "balance-sheet":
20316
+ return /* @__PURE__ */ jsx(BalanceSheetResolver, __spreadValues({}, payload));
20317
+ case "income-statement":
20318
+ return /* @__PURE__ */ jsx(IncomeStatementResolver, __spreadValues({}, payload));
20319
+ case "cash-flow-statement":
20320
+ return /* @__PURE__ */ jsx(CashFlowStatementResolver, __spreadValues({}, payload));
20321
+ case "general-ledger":
20322
+ return /* @__PURE__ */ jsx(GeneralLedgerResolver, __spreadValues({}, payload));
20323
+ case "chart-of-accounts":
20324
+ return /* @__PURE__ */ jsx(ChartOfAccountsResolver, __spreadValues({}, payload));
20325
+ case "invoice-detail":
20326
+ return /* @__PURE__ */ jsx(InvoiceDetailResolver, __spreadValues({}, payload));
20327
+ case "amortization-table":
20328
+ return /* @__PURE__ */ jsx(AmortizationTableResolver, __spreadValues({}, payload));
20329
+ case "depreciation-schedule":
20330
+ return /* @__PURE__ */ jsx(DepreciationScheduleResolver, __spreadValues({}, payload));
20331
+ case "escalation-card":
20332
+ return /* @__PURE__ */ jsx(EscalationCardResolver, __spreadValues({}, payload));
20333
+ case "line-chart":
20334
+ return /* @__PURE__ */ jsx(LineChartResolver, __spreadValues({}, payload));
20335
+ case "combo-chart":
20336
+ return /* @__PURE__ */ jsx(ComboChartResolver, __spreadValues({}, payload));
20337
+ case "gauge-chart":
20338
+ return /* @__PURE__ */ jsx(GaugeChartResolver, __spreadValues({}, payload));
20339
+ case "treemap-chart":
20340
+ return /* @__PURE__ */ jsx(TreemapChartResolver, __spreadValues({}, payload));
20341
+ case "radar-chart":
20342
+ return /* @__PURE__ */ jsx(RadarChartResolver, __spreadValues({}, payload));
20343
+ case "funnel-chart":
20344
+ return /* @__PURE__ */ jsx(FunnelChartResolver, __spreadValues({}, payload));
20345
+ case "bullet-chart":
20346
+ return /* @__PURE__ */ jsx(BulletChartResolver, __spreadValues({}, payload));
20347
+ case "scatter-chart":
20348
+ return /* @__PURE__ */ jsx(ScatterChartResolver, __spreadValues({}, payload));
20349
+ case "connect-integration":
20350
+ return /* @__PURE__ */ jsx(ConnectIntegrationResolver, __spreadValues({}, payload));
20351
+ case "integrations-list":
20352
+ return /* @__PURE__ */ jsx(IntegrationsListResolver, __spreadValues({}, payload));
20353
+ case "pipeline-preview":
20354
+ return /* @__PURE__ */ jsx(PipelinePreviewResolver, __spreadValues({}, payload));
20355
+ case "workflow-stepper":
20356
+ return /* @__PURE__ */ jsx(WorkflowStepperResolver, __spreadValues({}, payload));
20357
+ case "document-field-extraction":
20358
+ return /* @__PURE__ */ jsx(DocumentFieldExtractionResolver, __spreadValues({}, payload));
20359
+ case "decision-card":
20360
+ return /* @__PURE__ */ jsx(DecisionCardResolver, __spreadValues({}, payload));
20361
+ default: {
20362
+ return /* @__PURE__ */ jsx(
20363
+ "div",
20364
+ {
20365
+ role: "alert",
20366
+ style: {
20367
+ padding: "12px 16px",
20368
+ border: "1px solid #dc2626",
20369
+ borderRadius: "8px",
20370
+ background: "#fef2f2",
20371
+ color: "#dc2626",
20372
+ fontSize: "13px",
20373
+ fontWeight: 600
20374
+ },
20375
+ children: "Unknown UI type"
20376
+ }
20377
+ );
20378
+ }
20379
+ }
20380
+ }
20381
+ function InlineSpinner() {
18039
20382
  return /* @__PURE__ */ jsxs(Fragment, { children: [
18040
20383
  /* @__PURE__ */ jsx("style", { children: `@keyframes genui-spin{to{transform:rotate(360deg)}}` }),
18041
20384
  /* @__PURE__ */ jsx(
@@ -18395,7 +20738,7 @@ function DocGlyph({ color }) {
18395
20738
  }
18396
20739
  function FileUploadField({ field, value, onChange, disabled, onFileUpload, error, dense }) {
18397
20740
  const { MUTED: MUTED2, ACCENT: ACCENT2, BORDER: BORDER4, PAPER: PAPER2 } = useTheme();
18398
- const keyRef = React41.useRef(0);
20741
+ const keyRef = React45.useRef(0);
18399
20742
  const [entries, setEntries] = useState(() => {
18400
20743
  const arr = Array.isArray(value) ? value : value && typeof value === "object" ? [value] : [];
18401
20744
  return arr.map((item) => {
@@ -18404,11 +20747,11 @@ function FileUploadField({ field, value, onChange, disabled, onFileUpload, error
18404
20747
  return { key: keyRef.current += 1, name: (_b = (_a2 = r.filename) != null ? _a2 : r.name) != null ? _b : "file", size: r.size, status: "done", result: r };
18405
20748
  });
18406
20749
  });
18407
- const entriesRef = React41.useRef(entries);
20750
+ const entriesRef = React45.useRef(entries);
18408
20751
  entriesRef.current = entries;
18409
20752
  const [dragOver, setDragOver] = useState(false);
18410
- const inputRef = React41.useRef(null);
18411
- React41.useEffect(() => {
20753
+ const inputRef = React45.useRef(null);
20754
+ React45.useEffect(() => {
18412
20755
  ensureFileUploadKeyframes();
18413
20756
  }, []);
18414
20757
  const interactive = !disabled;
@@ -19015,7 +21358,7 @@ function FieldRenderer({ field, value, onChange, disabled, error, onFileUpload,
19015
21358
  ] });
19016
21359
  }
19017
21360
  init_ThemeContext();
19018
- var SlotErrorBoundary = class extends React41.Component {
21361
+ var SlotErrorBoundary = class extends React45.Component {
19019
21362
  constructor(props) {
19020
21363
  super(props);
19021
21364
  this.state = { hasError: false };
@@ -19733,10 +22076,14 @@ function BuilderFormResolver({
19733
22076
  }
19734
22077
  onSubmit(buildSubmission());
19735
22078
  }, [disabled, state.validateAllDetailed, onSubmit, buildSubmission, onValidationError]);
22079
+ const onChangeRef = useRef(onChange);
22080
+ useEffect(() => {
22081
+ onChangeRef.current = onChange;
22082
+ });
19736
22083
  useEffect(() => {
19737
- if (!onChange) return;
19738
- onChange(buildSubmission());
19739
- }, [onChange, state.values]);
22084
+ var _a3;
22085
+ (_a3 = onChangeRef.current) == null ? void 0 : _a3.call(onChangeRef, buildSubmission());
22086
+ }, [state.values]);
19740
22087
  useEffect(() => {
19741
22088
  if (!submitRef) return;
19742
22089
  submitRef.current = handleSubmit;
@@ -19796,7 +22143,7 @@ function BuilderFormResolver({
19796
22143
  }
19797
22144
  }
19798
22145
  function resolveBuilder(payload, callbacks) {
19799
- return React41.createElement(BuilderFormResolver, __spreadValues({
22146
+ return React45.createElement(BuilderFormResolver, __spreadValues({
19800
22147
  builder: payload
19801
22148
  }, callbacks));
19802
22149
  }
@@ -19804,6 +22151,6 @@ function resolveBuilder(payload, callbacks) {
19804
22151
  // src/index.ts
19805
22152
  init_Markdown();
19806
22153
 
19807
- export { ACCENT, ACCENT_SOFT, AgingReportResolver, AlertResolver, AllocationDonutResolver, AreaChartResolver, AuditTrailResolver, BORDER, BUILDER_FIELD_TYPES, BuilderFormResolver, BuilderRecap, CHART_PALETTE, ComparativeBarChartResolver, ComplianceChecklistResolver, ComponentActions, ContextSlot, DEFAULT_INTERACTION, DEFAULT_TOKENS, DataTableResolver, DocumentPreviewResolver, EngagementPipelineResolver, FIELD_REGISTRY, FieldRenderer, FileCard, FitText, FlowCanvasRenderer, FlowCanvasResolver, GenUIInteractionProvider, GenUIRenderer, GenUIThemeProvider, GroupedTableResolver, HeatmapTableResolver, JournalEntryResolver, LegalTestResultResolver, MUTED, Markdown, NUMERIC_CELL, NewsFeedResolver, PAPER, PreviewHost, PreviewModal, ProvenanceChainResolver, ReconciliationViewResolver, SECONDARY, ScreenerTableResolver, SearchResultsResolver, SparklineTableResolver, StackedBreakdownResolver, StatGridResolver, StatusCardResolver, TRUNCATE, TabsPanelResolver, TrialBalanceResolver, VarianceAnalysisResolver, WaterfallChartResolver, WorkflowStepperRenderer, WorkflowStepperResolver, buildRenderUITool, builderBlockSchema, builderFieldSchema, builderSchema, coercePayload, downloadCSV, fileTypeMeta, formatExpiry, isExpirySoon, isPreviewable, previewKindFor, resolveBuilder, resolveUI, schemaRegistry, useBuilderState, useGenUIInteraction, useTheme, validateBuilderPayload, validatePayload };
22154
+ export { ACCENT, ACCENT_SOFT, AgingReportResolver, AlertResolver, AllocationDonutResolver, AreaChartResolver, AuditTrailResolver, BORDER, BUILDER_FIELD_TYPES, BuilderFormResolver, BuilderRecap, CHART_PALETTE, ComparativeBarChartResolver, ComplianceChecklistResolver, ComponentActions, ContextSlot, DEFAULT_INTERACTION, DEFAULT_TOKENS, DataTableResolver, DecisionCardRenderer, DecisionCardResolver, DocumentFieldExtractionResolver, DocumentFieldExtractionSkeleton, DocumentPreviewResolver, EngagementPipelineResolver, FIELD_REGISTRY, FieldAuditLog, FieldDetails, FieldRenderer, FileCard, FitText, FlowCanvasRenderer, FlowCanvasResolver, GenUIInteractionProvider, GenUIRenderer, GenUIThemeProvider, GroupedTableResolver, HeatmapTableResolver, JournalEntryResolver, LegalTestResultResolver, MUTED, Markdown, NUMERIC_CELL, NewsFeedResolver, PAPER, PreviewHost, PreviewModal, ProvenanceChainResolver, ReconciliationViewResolver, SECONDARY, ScreenerTableResolver, SearchResultsResolver, SparklineTableResolver, StackedBreakdownResolver, StatGridResolver, StatusCardResolver, TRUNCATE, TabsPanelResolver, TrialBalanceResolver, VarianceAnalysisResolver, WaterfallChartResolver, WorkflowStepperRenderer, WorkflowStepperResolver, buildRenderUITool, builderBlockSchema, builderFieldSchema, builderSchema, coercePayload, downloadCSV, fileTypeMeta, formatExpiry, isExpirySoon, isPreviewable, previewKindFor, resolveBuilder, resolveUI, schemaRegistry, useBuilderState, useGenUIInteraction, useTheme, validateBuilderPayload, validatePayload };
19808
22155
  //# sourceMappingURL=index.js.map
19809
22156
  //# sourceMappingURL=index.js.map