@open-mercato/core 0.9.1-develop.7497.1.543ea44c40 → 0.9.1-develop.7513.1.ae2715553f

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 (68) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/audit_logs/components/AuditLogsActions.js +1 -1
  3. package/dist/modules/audit_logs/components/AuditLogsActions.js.map +2 -2
  4. package/dist/modules/auth/frontend/reset.js +7 -3
  5. package/dist/modules/auth/frontend/reset.js.map +2 -2
  6. package/dist/modules/business_rules/api/rules/route.js +12 -1
  7. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  8. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +17 -2
  9. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  10. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +3 -2
  11. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  12. package/dist/modules/catalog/backend/catalog/products/create/page.js +1 -0
  13. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  14. package/dist/modules/catalog/components/products/productFormUtils.js +9 -0
  15. package/dist/modules/catalog/components/products/productFormUtils.js.map +2 -2
  16. package/dist/modules/customers/backend/customers/companies/page.js +32 -32
  17. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  18. package/dist/modules/customers/backend/customers/deals/page.js +22 -22
  19. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  20. package/dist/modules/customers/backend/customers/people/page.js +34 -34
  21. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  22. package/dist/modules/ecommerce/search.js +1 -2
  23. package/dist/modules/ecommerce/search.js.map +2 -2
  24. package/dist/modules/staff/backend/staff/time-tracking/entries/page.js +10 -7
  25. package/dist/modules/staff/backend/staff/time-tracking/entries/page.js.map +2 -2
  26. package/dist/modules/wms/api/interceptors.js +3 -0
  27. package/dist/modules/wms/api/interceptors.js.map +2 -2
  28. package/dist/modules/wms/commands/configuration.js +16 -16
  29. package/dist/modules/wms/commands/configuration.js.map +2 -2
  30. package/dist/modules/wms/events.js +1 -0
  31. package/dist/modules/wms/events.js.map +2 -2
  32. package/dist/modules/wms/lib/catalogInventoryProfileIntent.js +9 -0
  33. package/dist/modules/wms/lib/catalogInventoryProfileIntent.js.map +2 -2
  34. package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js +11 -3
  35. package/dist/modules/wms/widgets/injection/catalog-inventory-profile/widget.js.map +2 -2
  36. package/package.json +7 -7
  37. package/src/modules/audit_logs/components/AuditLogsActions.tsx +1 -1
  38. package/src/modules/auth/frontend/reset.tsx +8 -3
  39. package/src/modules/business_rules/api/rules/route.ts +11 -0
  40. package/src/modules/business_rules/i18n/de.json +1 -0
  41. package/src/modules/business_rules/i18n/en.json +1 -0
  42. package/src/modules/business_rules/i18n/es.json +1 -0
  43. package/src/modules/business_rules/i18n/ko.json +1 -0
  44. package/src/modules/business_rules/i18n/pl.json +1 -0
  45. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +20 -1
  46. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +2 -1
  47. package/src/modules/catalog/backend/catalog/products/create/page.tsx +1 -0
  48. package/src/modules/catalog/components/products/productFormUtils.ts +9 -0
  49. package/src/modules/customers/backend/customers/companies/page.tsx +32 -32
  50. package/src/modules/customers/backend/customers/deals/page.tsx +22 -22
  51. package/src/modules/customers/backend/customers/people/page.tsx +34 -34
  52. package/src/modules/customers/i18n/de.json +12 -0
  53. package/src/modules/customers/i18n/en.json +12 -0
  54. package/src/modules/customers/i18n/es.json +12 -0
  55. package/src/modules/customers/i18n/ko.json +12 -0
  56. package/src/modules/customers/i18n/pl.json +12 -0
  57. package/src/modules/ecommerce/i18n/de.json +2 -1
  58. package/src/modules/ecommerce/i18n/en.json +2 -1
  59. package/src/modules/ecommerce/i18n/es.json +2 -1
  60. package/src/modules/ecommerce/i18n/ko.json +2 -1
  61. package/src/modules/ecommerce/i18n/pl.json +2 -1
  62. package/src/modules/ecommerce/search.ts +0 -1
  63. package/src/modules/staff/backend/staff/time-tracking/entries/page.tsx +20 -14
  64. package/src/modules/wms/api/interceptors.ts +9 -0
  65. package/src/modules/wms/commands/configuration.ts +28 -16
  66. package/src/modules/wms/events.ts +1 -0
  67. package/src/modules/wms/lib/catalogInventoryProfileIntent.ts +9 -0
  68. package/src/modules/wms/widgets/injection/catalog-inventory-profile/widget.ts +13 -4
@@ -7,6 +7,14 @@ function toTrimmedOrNull(value) {
7
7
  const trimmed = value.trim();
8
8
  return trimmed.length ? trimmed : null;
9
9
  }
10
+ function pickEnrichmentNamespaces(record) {
11
+ const namespaces = {};
12
+ if (!record) return namespaces;
13
+ for (const [key, value] of Object.entries(record)) {
14
+ if (key.length > 1 && key.startsWith("_")) namespaces[key] = value;
15
+ }
16
+ return namespaces;
17
+ }
10
18
  function parseNumericInput(value) {
11
19
  if (typeof value === "number") return value;
12
20
  if (typeof value === "string") {
@@ -61,6 +69,7 @@ export {
61
69
  UNIT_PRICE_REFERENCE_UNITS,
62
70
  normalizeProductConversionInputs,
63
71
  parseNumericInput,
72
+ pickEnrichmentNamespaces,
64
73
  toIntegerInRangeOrDefault,
65
74
  toPositiveNumberOrNull,
66
75
  toTrimmedOrNull
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/catalog/components/products/productFormUtils.ts"],
4
- "sourcesContent": ["import { REFERENCE_UNIT_CODES, type ReferenceUnitCode } from \"@open-mercato/shared/lib/units/unitCodes\";\nimport { canonicalizeUnitCode } from \"../../lib/unitCodes\";\nimport { createCrudFormError } from \"@open-mercato/ui/backend/utils/serverErrors\";\nimport type { ProductUnitConversionDraft } from \"./productForm\";\n\nexport const UNIT_PRICE_REFERENCE_UNITS = new Set<ReferenceUnitCode>(REFERENCE_UNIT_CODES);\n\nexport function toTrimmedOrNull(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed.length ? trimmed : null;\n}\n\nexport function parseNumericInput(value: unknown): number {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const normalized = value.trim().replace(/\\s+/g, \"\").replace(/,/g, \".\");\n if (!normalized.length) return Number.NaN;\n return Number(normalized);\n }\n return Number(value);\n}\n\nexport function toPositiveNumberOrNull(value: unknown): number | null {\n const numeric = parseNumericInput(value);\n if (!Number.isFinite(numeric) || numeric <= 0) return null;\n return numeric;\n}\n\nexport function toIntegerInRangeOrDefault(\n value: unknown,\n min: number,\n max: number,\n fallback: number,\n): number {\n const numeric = parseNumericInput(value);\n if (!Number.isInteger(numeric) || numeric < min || numeric > max)\n return fallback;\n return numeric;\n}\n\nexport type ProductUnitConversionInput = {\n id?: string | null;\n unitCode: string;\n toBaseFactor: number;\n sortOrder: number;\n isActive: boolean;\n};\n\nexport function normalizeProductConversionInputs(\n rows: ProductUnitConversionDraft[] | undefined,\n duplicateMessage: string,\n): ProductUnitConversionInput[] {\n const list = Array.isArray(rows) ? rows : [];\n const normalized: ProductUnitConversionInput[] = [];\n const seen = new Set<string>();\n for (const row of list) {\n const unitCode = canonicalizeUnitCode(row?.unitCode);\n const toBaseFactor = toPositiveNumberOrNull(row?.toBaseFactor);\n if (!unitCode || toBaseFactor === null) continue;\n const unitKey = unitCode.toLowerCase();\n if (seen.has(unitKey)) {\n throw createCrudFormError(duplicateMessage, {\n unitConversions: duplicateMessage,\n });\n }\n seen.add(unitKey);\n normalized.push({\n id: toTrimmedOrNull(row?.id),\n unitCode,\n toBaseFactor,\n sortOrder: toIntegerInRangeOrDefault(\n row?.sortOrder,\n 0,\n 100000,\n normalized.length * 10,\n ),\n isActive: row?.isActive !== false,\n });\n }\n return normalized;\n}\n"],
5
- "mappings": "AAAA,SAAS,4BAAoD;AAC7D,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AAG7B,MAAM,6BAA6B,IAAI,IAAuB,oBAAoB;AAElF,SAAS,gBAAgB,OAA+B;AAC7D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,UAAU;AACpC;AAEO,SAAS,kBAAkB,OAAwB;AACxD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,QAAQ,EAAE,EAAE,QAAQ,MAAM,GAAG;AACrE,QAAI,CAAC,WAAW,OAAQ,QAAO,OAAO;AACtC,WAAO,OAAO,UAAU;AAAA,EAC1B;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,SAAS,uBAAuB,OAA+B;AACpE,QAAM,UAAU,kBAAkB,KAAK;AACvC,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,EAAG,QAAO;AACtD,SAAO;AACT;AAEO,SAAS,0BACd,OACA,KACA,KACA,UACQ;AACR,QAAM,UAAU,kBAAkB,KAAK;AACvC,MAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,OAAO,UAAU;AAC3D,WAAO;AACT,SAAO;AACT;AAUO,SAAS,iCACd,MACA,kBAC8B;AAC9B,QAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AAC3C,QAAM,aAA2C,CAAC;AAClD,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,qBAAqB,KAAK,QAAQ;AACnD,UAAM,eAAe,uBAAuB,KAAK,YAAY;AAC7D,QAAI,CAAC,YAAY,iBAAiB,KAAM;AACxC,UAAM,UAAU,SAAS,YAAY;AACrC,QAAI,KAAK,IAAI,OAAO,GAAG;AACrB,YAAM,oBAAoB,kBAAkB;AAAA,QAC1C,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AACA,SAAK,IAAI,OAAO;AAChB,eAAW,KAAK;AAAA,MACd,IAAI,gBAAgB,KAAK,EAAE;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,WAAW,SAAS;AAAA,MACtB;AAAA,MACA,UAAU,KAAK,aAAa;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["import { REFERENCE_UNIT_CODES, type ReferenceUnitCode } from \"@open-mercato/shared/lib/units/unitCodes\";\nimport { canonicalizeUnitCode } from \"../../lib/unitCodes\";\nimport { createCrudFormError } from \"@open-mercato/ui/backend/utils/serverErrors\";\nimport type { ProductUnitConversionDraft } from \"./productForm\";\n\nexport const UNIT_PRICE_REFERENCE_UNITS = new Set<ReferenceUnitCode>(REFERENCE_UNIT_CODES);\n\nexport function toTrimmedOrNull(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n const trimmed = value.trim();\n return trimmed.length ? trimmed : null;\n}\n\nexport function pickEnrichmentNamespaces(record: Record<string, unknown> | null | undefined): Record<string, unknown> {\n const namespaces: Record<string, unknown> = {};\n if (!record) return namespaces;\n for (const [key, value] of Object.entries(record)) {\n if (key.length > 1 && key.startsWith(\"_\")) namespaces[key] = value;\n }\n return namespaces;\n}\n\nexport function parseNumericInput(value: unknown): number {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const normalized = value.trim().replace(/\\s+/g, \"\").replace(/,/g, \".\");\n if (!normalized.length) return Number.NaN;\n return Number(normalized);\n }\n return Number(value);\n}\n\nexport function toPositiveNumberOrNull(value: unknown): number | null {\n const numeric = parseNumericInput(value);\n if (!Number.isFinite(numeric) || numeric <= 0) return null;\n return numeric;\n}\n\nexport function toIntegerInRangeOrDefault(\n value: unknown,\n min: number,\n max: number,\n fallback: number,\n): number {\n const numeric = parseNumericInput(value);\n if (!Number.isInteger(numeric) || numeric < min || numeric > max)\n return fallback;\n return numeric;\n}\n\nexport type ProductUnitConversionInput = {\n id?: string | null;\n unitCode: string;\n toBaseFactor: number;\n sortOrder: number;\n isActive: boolean;\n};\n\nexport function normalizeProductConversionInputs(\n rows: ProductUnitConversionDraft[] | undefined,\n duplicateMessage: string,\n): ProductUnitConversionInput[] {\n const list = Array.isArray(rows) ? rows : [];\n const normalized: ProductUnitConversionInput[] = [];\n const seen = new Set<string>();\n for (const row of list) {\n const unitCode = canonicalizeUnitCode(row?.unitCode);\n const toBaseFactor = toPositiveNumberOrNull(row?.toBaseFactor);\n if (!unitCode || toBaseFactor === null) continue;\n const unitKey = unitCode.toLowerCase();\n if (seen.has(unitKey)) {\n throw createCrudFormError(duplicateMessage, {\n unitConversions: duplicateMessage,\n });\n }\n seen.add(unitKey);\n normalized.push({\n id: toTrimmedOrNull(row?.id),\n unitCode,\n toBaseFactor,\n sortOrder: toIntegerInRangeOrDefault(\n row?.sortOrder,\n 0,\n 100000,\n normalized.length * 10,\n ),\n isActive: row?.isActive !== false,\n });\n }\n return normalized;\n}\n"],
5
+ "mappings": "AAAA,SAAS,4BAAoD;AAC7D,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AAG7B,MAAM,6BAA6B,IAAI,IAAuB,oBAAoB;AAElF,SAAS,gBAAgB,OAA+B;AAC7D,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,UAAU;AACpC;AAEO,SAAS,yBAAyB,QAA6E;AACpH,QAAM,aAAsC,CAAC;AAC7C,MAAI,CAAC,OAAQ,QAAO;AACpB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,IAAI,SAAS,KAAK,IAAI,WAAW,GAAG,EAAG,YAAW,GAAG,IAAI;AAAA,EAC/D;AACA,SAAO;AACT;AAEO,SAAS,kBAAkB,OAAwB;AACxD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,QAAQ,EAAE,EAAE,QAAQ,MAAM,GAAG;AACrE,QAAI,CAAC,WAAW,OAAQ,QAAO,OAAO;AACtC,WAAO,OAAO,UAAU;AAAA,EAC1B;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,SAAS,uBAAuB,OAA+B;AACpE,QAAM,UAAU,kBAAkB,KAAK;AACvC,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,EAAG,QAAO;AACtD,SAAO;AACT;AAEO,SAAS,0BACd,OACA,KACA,KACA,UACQ;AACR,QAAM,UAAU,kBAAkB,KAAK;AACvC,MAAI,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,OAAO,UAAU;AAC3D,WAAO;AACT,SAAO;AACT;AAUO,SAAS,iCACd,MACA,kBAC8B;AAC9B,QAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AAC3C,QAAM,aAA2C,CAAC;AAClD,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,MAAM;AACtB,UAAM,WAAW,qBAAqB,KAAK,QAAQ;AACnD,UAAM,eAAe,uBAAuB,KAAK,YAAY;AAC7D,QAAI,CAAC,YAAY,iBAAiB,KAAM;AACxC,UAAM,UAAU,SAAS,YAAY;AACrC,QAAI,KAAK,IAAI,OAAO,GAAG;AACrB,YAAM,oBAAoB,kBAAkB;AAAA,QAC1C,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AACA,SAAK,IAAI,OAAO;AAChB,eAAW,KAAK;AAAA,MACd,IAAI,gBAAgB,KAAK,EAAE;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,WAAW,SAAS;AAAA,MACtB;AAAA,MACA,UAAU,KAAK,aAAa;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -503,9 +503,9 @@ function CustomersCompaniesPage() {
503
503
  header: t("customers.companies.list.columns.name"),
504
504
  meta: {
505
505
  alwaysVisible: true,
506
- columnChooserGroup: "Basic Info",
506
+ columnChooserGroup: t("customers.columnGroups.basicInfo", "Basic Info"),
507
507
  filterKey: "display_name",
508
- filterGroup: "CRM",
508
+ filterGroup: t("customers.columnGroups.crm", "CRM"),
509
509
  maxWidth: "260px"
510
510
  },
511
511
  cell: ({ row }) => /* @__PURE__ */ jsx(Link, { href: `/backend/customers/companies-v2/${row.original.id}`, className: "font-medium hover:underline", children: row.original.name })
@@ -514,9 +514,9 @@ function CustomersCompaniesPage() {
514
514
  accessorKey: "email",
515
515
  header: t("customers.companies.list.columns.email"),
516
516
  meta: {
517
- columnChooserGroup: "Contact",
517
+ columnChooserGroup: t("customers.columnGroups.contact", "Contact"),
518
518
  filterKey: "primary_email",
519
- filterGroup: "Contact",
519
+ filterGroup: t("customers.columnGroups.contact", "Contact"),
520
520
  filterIconName: "mail",
521
521
  maxWidth: "220px"
522
522
  },
@@ -526,10 +526,10 @@ function CustomersCompaniesPage() {
526
526
  accessorKey: "phone",
527
527
  header: t("customers.companies.detail.highlights.primaryPhone", "Primary phone"),
528
528
  meta: {
529
- columnChooserGroup: "Contact",
529
+ columnChooserGroup: t("customers.columnGroups.contact", "Contact"),
530
530
  hidden: true,
531
531
  filterKey: "primary_phone",
532
- filterGroup: "Contact",
532
+ filterGroup: t("customers.columnGroups.contact", "Contact"),
533
533
  filterIconName: "phone",
534
534
  maxWidth: "180px"
535
535
  },
@@ -541,8 +541,8 @@ function CustomersCompaniesPage() {
541
541
  meta: {
542
542
  filterType: "select",
543
543
  filterOptions: dictionaryOptions.statuses,
544
- columnChooserGroup: "Basic Info",
545
- filterGroup: "CRM"
544
+ columnChooserGroup: t("customers.columnGroups.basicInfo", "Basic Info"),
545
+ filterGroup: t("customers.columnGroups.crm", "CRM")
546
546
  },
547
547
  cell: ({ row }) => renderDictionaryCell("statuses", row.original.status)
548
548
  },
@@ -552,9 +552,9 @@ function CustomersCompaniesPage() {
552
552
  meta: {
553
553
  filterType: "select",
554
554
  filterOptions: dictionaryOptions.lifecycleStages,
555
- columnChooserGroup: "Basic Info",
555
+ columnChooserGroup: t("customers.columnGroups.basicInfo", "Basic Info"),
556
556
  filterKey: "lifecycle_stage",
557
- filterGroup: "CRM"
557
+ filterGroup: t("customers.columnGroups.crm", "CRM")
558
558
  },
559
559
  cell: ({ row }) => renderDictionaryCell("lifecycle-stages", row.original.lifecycleStage)
560
560
  },
@@ -562,9 +562,9 @@ function CustomersCompaniesPage() {
562
562
  accessorKey: "nextInteractionAt",
563
563
  header: t("customers.companies.list.columns.nextInteraction"),
564
564
  meta: {
565
- columnChooserGroup: "Dates",
565
+ columnChooserGroup: t("customers.columnGroups.dates", "Dates"),
566
566
  filterKey: "next_interaction_at",
567
- filterGroup: "Activity",
567
+ filterGroup: t("customers.columnGroups.activity", "Activity"),
568
568
  filterIconName: "calendar"
569
569
  },
570
570
  cell: ({ row }) => row.original.nextInteractionAt ? /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 text-sm", children: [
@@ -582,8 +582,8 @@ function CustomersCompaniesPage() {
582
582
  meta: {
583
583
  filterType: "select",
584
584
  filterOptions: dictionaryOptions.sources,
585
- columnChooserGroup: "Basic Info",
586
- filterGroup: "CRM"
585
+ columnChooserGroup: t("customers.columnGroups.basicInfo", "Basic Info"),
586
+ filterGroup: t("customers.columnGroups.crm", "CRM")
587
587
  },
588
588
  cell: ({ row }) => renderDictionaryCell("sources", row.original.source)
589
589
  },
@@ -591,11 +591,11 @@ function CustomersCompaniesPage() {
591
591
  accessorKey: "ownerUserId",
592
592
  header: t("customers.companies.list.columns.owner", "Owner"),
593
593
  meta: {
594
- columnChooserGroup: "CRM",
594
+ columnChooserGroup: t("customers.columnGroups.crm", "CRM"),
595
595
  filterType: "select",
596
596
  filterOptions: resolvedOwnerFilterOptions,
597
597
  filterLoadOptions: loadOwnerFilterOptions,
598
- filterGroup: "CRM",
598
+ filterGroup: t("customers.columnGroups.crm", "CRM"),
599
599
  filterIconName: "user-round",
600
600
  filterKey: "owner_user_id",
601
601
  hidden: true
@@ -606,10 +606,10 @@ function CustomersCompaniesPage() {
606
606
  accessorKey: "legalName",
607
607
  header: t("customers.companies.detail.fields.legalName", "Legal name"),
608
608
  meta: {
609
- columnChooserGroup: "Profile",
609
+ columnChooserGroup: t("customers.columnGroups.profile", "Profile"),
610
610
  hidden: true,
611
611
  filterKey: "company_profile.legal_name",
612
- filterGroup: "Profile"
612
+ filterGroup: t("customers.columnGroups.profile", "Profile")
613
613
  },
614
614
  cell: ({ row }) => row.original.legalName || noValue
615
615
  },
@@ -617,10 +617,10 @@ function CustomersCompaniesPage() {
617
617
  accessorKey: "brandName",
618
618
  header: t("customers.companies.detail.fields.brandName", "Brand name"),
619
619
  meta: {
620
- columnChooserGroup: "Profile",
620
+ columnChooserGroup: t("customers.columnGroups.profile", "Profile"),
621
621
  hidden: true,
622
622
  filterKey: "company_profile.brand_name",
623
- filterGroup: "Profile"
623
+ filterGroup: t("customers.columnGroups.profile", "Profile")
624
624
  },
625
625
  cell: ({ row }) => row.original.brandName || noValue
626
626
  },
@@ -628,10 +628,10 @@ function CustomersCompaniesPage() {
628
628
  accessorKey: "domain",
629
629
  header: t("customers.companies.detail.fields.domain", "Domain"),
630
630
  meta: {
631
- columnChooserGroup: "Profile",
631
+ columnChooserGroup: t("customers.columnGroups.profile", "Profile"),
632
632
  hidden: true,
633
633
  filterKey: "company_profile.domain",
634
- filterGroup: "Profile"
634
+ filterGroup: t("customers.columnGroups.profile", "Profile")
635
635
  },
636
636
  cell: ({ row }) => row.original.domain || noValue
637
637
  },
@@ -639,10 +639,10 @@ function CustomersCompaniesPage() {
639
639
  accessorKey: "websiteUrl",
640
640
  header: t("customers.companies.detail.fields.website", "Website"),
641
641
  meta: {
642
- columnChooserGroup: "Profile",
642
+ columnChooserGroup: t("customers.columnGroups.profile", "Profile"),
643
643
  hidden: true,
644
644
  filterKey: "company_profile.website_url",
645
- filterGroup: "Profile"
645
+ filterGroup: t("customers.columnGroups.profile", "Profile")
646
646
  },
647
647
  cell: ({ row }) => row.original.websiteUrl || noValue
648
648
  },
@@ -650,10 +650,10 @@ function CustomersCompaniesPage() {
650
650
  accessorKey: "industry",
651
651
  header: t("customers.companies.detail.fields.industry", "Industry"),
652
652
  meta: {
653
- columnChooserGroup: "Profile",
653
+ columnChooserGroup: t("customers.columnGroups.profile", "Profile"),
654
654
  hidden: true,
655
655
  filterKey: "company_profile.industry",
656
- filterGroup: "Profile"
656
+ filterGroup: t("customers.columnGroups.profile", "Profile")
657
657
  },
658
658
  cell: ({ row }) => row.original.industry || noValue
659
659
  },
@@ -661,10 +661,10 @@ function CustomersCompaniesPage() {
661
661
  accessorKey: "sizeBucket",
662
662
  header: t("customers.companies.detail.fields.sizeBucket", "Company size"),
663
663
  meta: {
664
- columnChooserGroup: "Profile",
664
+ columnChooserGroup: t("customers.columnGroups.profile", "Profile"),
665
665
  hidden: true,
666
666
  filterKey: "company_profile.size_bucket",
667
- filterGroup: "Profile"
667
+ filterGroup: t("customers.columnGroups.profile", "Profile")
668
668
  },
669
669
  cell: ({ row }) => row.original.sizeBucket || noValue
670
670
  },
@@ -672,11 +672,11 @@ function CustomersCompaniesPage() {
672
672
  accessorKey: "annualRevenue",
673
673
  header: t("customers.companies.detail.highlights.annualRevenue", "Annual revenue"),
674
674
  meta: {
675
- columnChooserGroup: "Profile",
675
+ columnChooserGroup: t("customers.columnGroups.profile", "Profile"),
676
676
  hidden: true,
677
677
  filterKey: "company_profile.annual_revenue",
678
678
  filterType: "number",
679
- filterGroup: "Profile"
679
+ filterGroup: t("customers.columnGroups.profile", "Profile")
680
680
  },
681
681
  cell: ({ row }) => row.original.annualRevenue || noValue
682
682
  },
@@ -684,10 +684,10 @@ function CustomersCompaniesPage() {
684
684
  accessorKey: "description",
685
685
  header: t("customers.companies.detail.fields.description", "Description"),
686
686
  meta: {
687
- columnChooserGroup: "Notes",
687
+ columnChooserGroup: t("customers.columnGroups.notes", "Notes"),
688
688
  hidden: true,
689
689
  filterKey: "description",
690
- filterGroup: "Notes"
690
+ filterGroup: t("customers.columnGroups.notes", "Notes")
691
691
  },
692
692
  cell: ({ row }) => row.original.description || noValue
693
693
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/customers/backend/customers/companies/page.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/customers/extension-points'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { groupBulkDeleteFailures, runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { coalesceLastOperations } from '@open-mercato/ui/backend/operations/store'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport type { FilterFieldDef, FilterOption as AdvancedFilterOption } from '@open-mercato/shared/lib/query/advanced-filter'\nimport type { AdvancedFilterTree } from '@open-mercato/shared/lib/query/advanced-filter-tree'\nimport { createEmptyTree, makeRuleTree } from '@open-mercato/shared/lib/query/advanced-filter-tree'\nimport { deserializeAdvancedFilter, deserializeTree, flatToTree, mapDictionaryColorToTone, serializeTree } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { useCurrentUserId } from '@open-mercato/ui/backend/utils/useCurrentUserId'\nimport { useCurrentOrganization } from '@open-mercato/ui/backend/BackendChromeProvider'\nimport {\n DictionaryValue,\n createEmptyCustomerDictionaryMaps,\n renderDictionaryColor,\n renderDictionaryIcon,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n useCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport {\n mapCustomFieldKindToFilterType,\n normalizeCustomFieldFilterOptions,\n supportsCustomFieldColumn,\n} from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport { useAutoDiscoveredFields } from '@open-mercato/ui/backend/utils/useAutoDiscoveredFields'\nimport { useAdvancedFilterTree } from '@open-mercato/ui/backend/hooks/useAdvancedFilter'\nimport { AdvancedFilterPanel } from '@open-mercato/ui/backend/filters/AdvancedFilterPanel'\nimport { ActiveFilterChips } from '@open-mercato/ui/backend/filters/ActiveFilterChips'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport type { FilterPreset } from '@open-mercato/ui/backend/filters/QuickFilters'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ensureCustomerDictionary } from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n ensureCurrentUserFilterOption,\n fetchAssignableStaffMembers,\n mapAssignableStaffToFilterOptions,\n} from '../../../components/detail/assignableStaff'\nimport { CollectionPreviewCell, normalizeCollectionLabels } from '../../../components/list/CollectionPreviewCell'\nimport { appendCustomerListSortParams } from '../listSorting'\n\ntype DictionaryOptionWithTone = AdvancedFilterOption & FilterOption\n\nfunction makeCompaniesPresets(): FilterPreset[] {\n return [\n {\n id: 'my-accounts',\n labelKey: 'customers.companies.presets.myAccounts',\n requiresUser: true,\n build: ({ userId }) => makeRuleTree({ field: 'owner_user_id', operator: 'is', value: userId }),\n },\n {\n id: 'recently-created',\n labelKey: 'customers.companies.presets.recentlyCreated',\n iconName: 'clock',\n build: ({ now }) => {\n const cutoff = new Date(now.getTime() - 7 * 24 * 3600 * 1000).toISOString().slice(0, 10)\n return makeRuleTree({ field: 'created_at', operator: 'is_after', value: cutoff })\n },\n },\n {\n id: 'inactive-60',\n labelKey: 'customers.companies.presets.inactive60',\n build: ({ now }) => {\n const cutoff = new Date(now.getTime() - 60 * 24 * 3600 * 1000).toISOString().slice(0, 10)\n return makeRuleTree({ field: 'next_interaction_at', operator: 'is_before', value: cutoff })\n },\n },\n ]\n}\n\n\ntype CompanyRow = {\n id: string\n name: string\n description?: string | null\n email?: string | null\n phone?: string | null\n legalName?: string | null\n brandName?: string | null\n domain?: string | null\n websiteUrl?: string | null\n industry?: string | null\n sizeBucket?: string | null\n annualRevenue?: string | null\n status?: string | null\n lifecycleStage?: string | null\n nextInteractionAt?: string | null\n nextInteractionName?: string | null\n nextInteractionIcon?: string | null\n nextInteractionColor?: string | null\n organizationId?: string | null\n source?: string | null\n ownerUserId?: string | null\n} & Record<string, unknown>\n\ntype CompaniesResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n page?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\ntype DictionaryKindKey = CustomerDictionaryKind\ntype DictionaryMap = CustomerDictionaryMap\n\nfunction formatDate(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction mapApiItem(item: Record<string, unknown>): CompanyRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name = typeof item.display_name === 'string' ? item.display_name : ''\n const description = typeof item.description === 'string' ? item.description : null\n const email = typeof item.primary_email === 'string' ? item.primary_email : null\n const phone = typeof item.primary_phone === 'string' ? item.primary_phone : null\n const legalName = typeof item.legal_name === 'string' ? item.legal_name : null\n const brandName = typeof item.brand_name === 'string' ? item.brand_name : null\n const domain = typeof item.domain === 'string' ? item.domain : null\n const websiteUrl = typeof item.website_url === 'string' ? item.website_url : null\n const industry = typeof item.industry === 'string' ? item.industry : null\n const sizeBucket = typeof item.size_bucket === 'string' ? item.size_bucket : null\n const annualRevenue =\n typeof item.annual_revenue === 'string'\n ? item.annual_revenue\n : typeof item.annual_revenue === 'number'\n ? String(item.annual_revenue)\n : null\n const status = typeof item.status === 'string' ? item.status : null\n const lifecycleStage = typeof item.lifecycle_stage === 'string' ? item.lifecycle_stage : null\n const nextInteractionAt = typeof item.next_interaction_at === 'string' ? item.next_interaction_at : null\n const nextInteractionName = typeof item.next_interaction_name === 'string' ? item.next_interaction_name : null\n const nextInteractionIcon = typeof item.next_interaction_icon === 'string' ? item.next_interaction_icon : null\n const nextInteractionColor = typeof item.next_interaction_color === 'string' ? item.next_interaction_color : null\n const organizationId = typeof item.organization_id === 'string' ? item.organization_id : null\n const source = typeof item.source === 'string' ? item.source : null\n const ownerUserId = typeof item.owner_user_id === 'string' ? item.owner_user_id : null\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) {\n customFields[key] = value\n }\n }\n return withDataTableNamespaces({\n id,\n name,\n description,\n email,\n phone,\n legalName,\n brandName,\n domain,\n websiteUrl,\n industry,\n sizeBucket,\n annualRevenue,\n status,\n lifecycleStage,\n nextInteractionAt,\n nextInteractionName,\n nextInteractionIcon,\n nextInteractionColor,\n organizationId,\n source,\n ownerUserId,\n ...customFields,\n }, item)\n}\n\nexport default function CustomersCompaniesPage() {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<CompanyRow[]>([])\n const [page, setPage] = React.useState(1)\n const [pageSize, setPageSize] = React.useState(20)\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n // One-shot URL hydration used as the hook's initial value. The hook is the\n // single source of truth from this point on \u2014 the page MUST NOT keep a\n // parallel `useState<AdvancedFilterTree>` (see spec \"Migration & Backward\n // Compatibility\" \u2192 state ownership).\n const initialFilterTree = React.useMemo<AdvancedFilterTree>(() => {\n if (!searchParams) return createEmptyTree()\n const record: Record<string, string> = {}\n searchParams.forEach((value, key) => {\n if (key.startsWith('filter[')) record[key] = value\n })\n const v2 = deserializeTree(record)\n if (v2) return v2\n const flat = deserializeAdvancedFilter(record)\n if (flat) return flatToTree(flat)\n return createEmptyTree()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n // `filterPanel` lives at the top of the component so derived state below\n // (URL params, data fetch, export config) can read `filterPanel.appliedTree`\n // directly. Real `FilterFieldDef[]` arrives later from `useAutoDiscoveredFields`\n // (it depends on columns) and is synced into the hook via a small effect at\n // the bottom of the component. The hook reads fields through a ref at\n // validation time only \u2014 first validation cannot fire before user input, by\n // which point fields have settled, so the empty initial value is safe.\n const [panelFields, setPanelFields] = React.useState<FilterFieldDef[]>([])\n const [filtersOpen, setFiltersOpen] = React.useState(false)\n const filtersTriggerRef = React.useRef<HTMLButtonElement | null>(null)\n const filterPanel = useAdvancedFilterTree({\n initial: initialFilterTree,\n fields: panelFields,\n onApply: () => setPage(1),\n })\n const advancedFilterState = filterPanel.appliedTree\n const handleAdvancedFilterClear = React.useCallback(() => {\n filterPanel.clear()\n setPage(1)\n }, [filterPanel])\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKindKey, DictionaryMap>>(createEmptyCustomerDictionaryMaps())\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n const t = useT()\n const router = useRouter()\n const handlePageSizeChange = React.useCallback((newSize: number) => {\n setPageSize(newSize)\n setPage(1)\n }, [])\n const handleSortingChange = React.useCallback((nextSorting: SortingState) => {\n setSorting(nextSorting)\n setPage(1)\n }, [])\n\n const bulkMutationContextId = 'customers-companies-list:bulk-delete'\n const { runMutation: runBulkMutation, retryLastMutation: retryBulkMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: bulkMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const singleMutationContextId = 'customers-companies-list:single-delete'\n const { runMutation: runSingleMutation, retryLastMutation: retrySingleMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: singleMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const fetchDictionaryEntries = React.useCallback(async (kind: DictionaryKindKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({\n ...prev,\n [kind]: data.map,\n }))\n return data.entries\n } catch {\n return []\n }\n }, [queryClient, scopeVersion])\n const dictionaryOptions = React.useMemo(() => {\n const toOptions = (map?: DictionaryMap | null): DictionaryOptionWithTone[] =>\n Object.values(map ?? {})\n .map((entry) => {\n const tone = mapDictionaryColorToTone(entry.color)\n const option: DictionaryOptionWithTone = { value: entry.value, label: entry.label }\n if (tone) option.tone = tone\n return option\n })\n .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))\n return {\n statuses: toOptions(dictionaryMaps.statuses),\n sources: toOptions(dictionaryMaps.sources),\n lifecycleStages: toOptions(dictionaryMaps['lifecycle-stages']),\n }\n }, [dictionaryMaps])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadAll() {\n if (cancelled) return\n setDictionaryMaps(createEmptyCustomerDictionaryMaps())\n await Promise.all([\n fetchDictionaryEntries('statuses'),\n fetchDictionaryEntries('sources'),\n fetchDictionaryEntries('lifecycle-stages'),\n ])\n }\n loadAll().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [fetchDictionaryEntries, scopeVersion, reloadToken])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs(\n [E.customers.customer_entity, E.customers.customer_company_profile],\n { keyExtras: [scopeVersion, reloadToken] },\n )\n const currentUserId = useCurrentUserId()\n const activeOrgId = useCurrentOrganization()?.id ?? null\n const [ownerFilterOptions, setOwnerFilterOptions] = React.useState<AdvancedFilterOption[]>([])\n React.useEffect(() => {\n const controller = new AbortController()\n let cancelled = false\n void fetchAssignableStaffMembers('', { pageSize: 100, activeOrgId, signal: controller.signal })\n .then((items) => {\n if (!cancelled) setOwnerFilterOptions(mapAssignableStaffToFilterOptions(items))\n })\n .catch(() => {\n if (!cancelled) setOwnerFilterOptions([])\n })\n return () => {\n cancelled = true\n controller.abort()\n }\n }, [activeOrgId, scopeVersion])\n const resolvedOwnerFilterOptions = React.useMemo(\n () => ensureCurrentUserFilterOption(\n ownerFilterOptions,\n currentUserId,\n t('customers.filters.currentUser', 'Current user'),\n ),\n [currentUserId, ownerFilterOptions, t],\n )\n const loadOwnerFilterOptions = React.useCallback(async (query?: string): Promise<AdvancedFilterOption[]> => {\n const items = await fetchAssignableStaffMembers(query ?? '', { pageSize: 100, activeOrgId })\n return mapAssignableStaffToFilterOptions(items)\n }, [activeOrgId])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n appendCustomerListSortParams(params, sorting)\n if (search.trim()) params.set('search', search.trim())\n const advancedParams = serializeTree(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n return params.toString()\n }, [advancedFilterState, page, pageSize, search, sorting])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n\n // Mirror page state into the URL so refresh restores the same filter tree,\n // including nested subgroups. Same pattern as the Deals page; without it\n // refreshes silently dropped everything past whatever a stale localStorage\n // perspective snapshot happened to contain.\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (page > 1) params.set('page', String(page))\n appendCustomerListSortParams(params, sorting)\n const advancedParams = serializeTree(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, sorting, advancedFilterState])\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/companies', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/companies', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const call = await apiCall<CompaniesResponse>(`/api/customers/companies?${queryParams}`)\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('customers.companies.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? {}\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map((item) => mapApiItem(item as Record<string, unknown>)).filter((row): row is CompanyRow => !!row))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n setTotalIsCapped(payload?.totalIsCapped === true)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.companies.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (company: CompanyRow) => {\n if (!company?.id) return\n const name = company.name || t('customers.companies.list.deleteFallbackName')\n const confirmed = await confirm({\n title: t('customers.companies.list.deleteConfirm', undefined, { name }),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n await runSingleMutation({\n operation: async () => {\n // optimistic-lock-exempt: delete-only mutation \u2014 no field-level lost-update\n await apiCallOrThrow(\n `/api/customers/companies?id=${encodeURIComponent(company.id)}`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n },\n { errorMessage: t('customers.companies.list.deleteError') },\n )\n },\n context: {\n formId: singleMutationContextId,\n resourceKind: 'customers.company',\n resourceId: company.id,\n retryLastMutation: retrySingleMutation,\n },\n })\n setRows((prev) => prev.filter((row) => row.id !== company.id))\n setTotal((prev) => Math.max(prev - 1, 0))\n handleRefresh()\n flash(t('customers.companies.list.deleteSuccess'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : t('customers.companies.list.deleteError')\n flash(message, 'error')\n }\n }, [confirm, handleRefresh, retrySingleMutation, runSingleMutation, singleMutationContextId, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: CompanyRow[]) => {\n const confirmed = await confirm({\n title: t('customers.companies.list.bulkDelete.title', 'Delete {count} companies?', { count: selectedRows.length }),\n description: t('customers.companies.list.bulkDelete.description', 'This action cannot be undone.'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n\n const { succeeded, failures } = await runBulkMutation({\n operation: async () =>\n runBulkDelete(\n selectedRows,\n async (row) => {\n // optimistic-lock-exempt: bulk delete-only mutation \u2014 no field-level lost-update\n await apiCallOrThrow(`/api/customers/companies?id=${encodeURIComponent(row.id)}`, {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n })\n },\n {\n fallbackErrorMessage: t('customers.companies.list.deleteError', 'Failed to delete company.'),\n logTag: 'customers.companies.list',\n progress: {\n jobType: 'customers.companies.bulk_delete',\n name: t('customers.companies.list.bulkDelete.progressName', 'Delete selected companies'),\n description: t(\n 'customers.companies.list.bulkDelete.progressDescription',\n '{count} companies selected for deletion',\n { count: selectedRows.length },\n ),\n meta: { source: 'customers.companies.list' },\n },\n },\n ),\n context: {\n formId: bulkMutationContextId,\n resourceKind: 'customers.company',\n retryLastMutation: retryBulkMutation,\n },\n })\n\n if (succeeded.length > 0) {\n const succeededIds = new Set(succeeded.map((r) => r.id))\n setRows((prev) => prev.filter((r) => !succeededIds.has(r.id)))\n setTotal((prev) => Math.max(0, prev - succeeded.length))\n setReloadToken((prev) => prev + 1)\n if (succeeded.length > 1) {\n coalesceLastOperations(succeeded.length, {\n commandId: 'customers.companies.delete',\n actionLabel: t('customers.companies.list.bulkDelete.operationLabel', 'Delete {count} companies', { count: succeeded.length }),\n resourceKind: 'customers.company',\n })\n }\n if (failures.length === 0) {\n flash(\n t('customers.companies.list.bulkDelete.success', '{count} companies deleted', { count: succeeded.length }),\n 'success',\n )\n } else {\n flash(\n t('customers.companies.list.bulkDelete.partial', '{deleted} of {total} companies deleted; {failed} failed', {\n deleted: succeeded.length,\n total: selectedRows.length,\n failed: failures.length,\n }),\n 'warning',\n )\n }\n }\n\n for (const group of groupBulkDeleteFailures(failures)) {\n const message = group.count === 1\n ? group.sampleMessage\n : t(\n 'customers.companies.list.bulkDelete.failedGroup',\n '{count} companies could not be deleted: {message}',\n { count: group.count, message: group.sampleMessage },\n )\n flash(message, 'error')\n }\n\n return succeeded.length > 0\n }, [bulkMutationContextId, confirm, retryBulkMutation, runBulkMutation, t])\n\n const columns = React.useMemo<ColumnDef<CompanyRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.companies.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKindKey, rawValue: string | null | undefined) => (\n <DictionaryValue\n value={rawValue}\n map={dictionaryMaps[kind]}\n fallback={rawValue ? <span>{rawValue}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n\n const renderCustomFieldCell = (value: unknown) => {\n if (value == null) return noValue\n if (Array.isArray(value)) {\n if (!value.length) return noValue\n const normalized = normalizeCollectionLabels(\n value.map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item\n return String(item)\n }),\n )\n if (!normalized.length) return noValue\n return <CollectionPreviewCell labels={normalized} maxVisible={2} />\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.companies.list.booleanYes', 'Yes')\n : t('customers.companies.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n }\n\n const baseColumns: ColumnDef<CompanyRow>[] = [\n {\n accessorKey: 'name',\n header: t('customers.companies.list.columns.name'),\n meta: {\n alwaysVisible: true,\n columnChooserGroup: 'Basic Info',\n filterKey: 'display_name',\n filterGroup: 'CRM',\n maxWidth: '260px',\n },\n cell: ({ row }) => (\n <Link href={`/backend/customers/companies-v2/${row.original.id}`} className=\"font-medium hover:underline\">\n {row.original.name}\n </Link>\n ),\n },\n {\n accessorKey: 'email',\n header: t('customers.companies.list.columns.email'),\n meta: {\n columnChooserGroup: 'Contact',\n filterKey: 'primary_email',\n filterGroup: 'Contact',\n filterIconName: 'mail',\n maxWidth: '220px',\n },\n cell: ({ row }) => row.original.email || noValue,\n },\n {\n accessorKey: 'phone',\n header: t('customers.companies.detail.highlights.primaryPhone', 'Primary phone'),\n meta: {\n columnChooserGroup: 'Contact',\n hidden: true,\n filterKey: 'primary_phone',\n filterGroup: 'Contact',\n filterIconName: 'phone',\n maxWidth: '180px',\n },\n cell: ({ row }) => row.original.phone || noValue,\n },\n {\n accessorKey: 'status',\n header: t('customers.companies.list.columns.status'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.statuses,\n columnChooserGroup: 'Basic Info',\n filterGroup: 'CRM',\n },\n cell: ({ row }) => renderDictionaryCell('statuses', row.original.status),\n },\n {\n accessorKey: 'lifecycleStage',\n header: t('customers.companies.list.columns.lifecycleStage'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.lifecycleStages,\n columnChooserGroup: 'Basic Info',\n filterKey: 'lifecycle_stage',\n filterGroup: 'CRM',\n },\n cell: ({ row }) => renderDictionaryCell('lifecycle-stages', row.original.lifecycleStage),\n },\n {\n accessorKey: 'nextInteractionAt',\n header: t('customers.companies.list.columns.nextInteraction'),\n meta: {\n columnChooserGroup: 'Dates',\n filterKey: 'next_interaction_at',\n filterGroup: 'Activity',\n filterIconName: 'calendar',\n },\n cell: ({ row }) =>\n row.original.nextInteractionAt\n ? (\n <div className=\"flex items-start gap-2 text-sm\">\n {row.original.nextInteractionIcon ? (\n <span className=\"mt-0.5 inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\">\n {renderDictionaryIcon(row.original.nextInteractionIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <div className=\"flex flex-col\">\n <span>{formatDate(row.original.nextInteractionAt, t('customers.companies.list.noValue'))}</span>\n {row.original.nextInteractionName ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.nextInteractionName}</span>\n ) : null}\n </div>\n {row.original.nextInteractionColor ? (\n <span className=\"mt-1\">\n {renderDictionaryColor(row.original.nextInteractionColor, 'h-3 w-3 rounded-full border border-border')}\n </span>\n ) : null}\n </div>\n )\n : noValue,\n },\n {\n accessorKey: 'source',\n header: t('customers.companies.list.columns.source'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.sources,\n columnChooserGroup: 'Basic Info',\n filterGroup: 'CRM',\n },\n cell: ({ row }) => renderDictionaryCell('sources', row.original.source),\n },\n {\n accessorKey: 'ownerUserId',\n header: t('customers.companies.list.columns.owner', 'Owner'),\n meta: {\n columnChooserGroup: 'CRM',\n filterType: 'select',\n filterOptions: resolvedOwnerFilterOptions,\n filterLoadOptions: loadOwnerFilterOptions,\n filterGroup: 'CRM',\n filterIconName: 'user-round',\n filterKey: 'owner_user_id',\n hidden: true,\n },\n cell: ({ row }) => row.original.ownerUserId ?? null,\n },\n {\n accessorKey: 'legalName',\n header: t('customers.companies.detail.fields.legalName', 'Legal name'),\n meta: {\n columnChooserGroup: 'Profile',\n hidden: true,\n filterKey: 'company_profile.legal_name',\n filterGroup: 'Profile',\n },\n cell: ({ row }) => row.original.legalName || noValue,\n },\n {\n accessorKey: 'brandName',\n header: t('customers.companies.detail.fields.brandName', 'Brand name'),\n meta: {\n columnChooserGroup: 'Profile',\n hidden: true,\n filterKey: 'company_profile.brand_name',\n filterGroup: 'Profile',\n },\n cell: ({ row }) => row.original.brandName || noValue,\n },\n {\n accessorKey: 'domain',\n header: t('customers.companies.detail.fields.domain', 'Domain'),\n meta: {\n columnChooserGroup: 'Profile',\n hidden: true,\n filterKey: 'company_profile.domain',\n filterGroup: 'Profile',\n },\n cell: ({ row }) => row.original.domain || noValue,\n },\n {\n accessorKey: 'websiteUrl',\n header: t('customers.companies.detail.fields.website', 'Website'),\n meta: {\n columnChooserGroup: 'Profile',\n hidden: true,\n filterKey: 'company_profile.website_url',\n filterGroup: 'Profile',\n },\n cell: ({ row }) => row.original.websiteUrl || noValue,\n },\n {\n accessorKey: 'industry',\n header: t('customers.companies.detail.fields.industry', 'Industry'),\n meta: {\n columnChooserGroup: 'Profile',\n hidden: true,\n filterKey: 'company_profile.industry',\n filterGroup: 'Profile',\n },\n cell: ({ row }) => row.original.industry || noValue,\n },\n {\n accessorKey: 'sizeBucket',\n header: t('customers.companies.detail.fields.sizeBucket', 'Company size'),\n meta: {\n columnChooserGroup: 'Profile',\n hidden: true,\n filterKey: 'company_profile.size_bucket',\n filterGroup: 'Profile',\n },\n cell: ({ row }) => row.original.sizeBucket || noValue,\n },\n {\n accessorKey: 'annualRevenue',\n header: t('customers.companies.detail.highlights.annualRevenue', 'Annual revenue'),\n meta: {\n columnChooserGroup: 'Profile',\n hidden: true,\n filterKey: 'company_profile.annual_revenue',\n filterType: 'number' as const,\n filterGroup: 'Profile',\n },\n cell: ({ row }) => row.original.annualRevenue || noValue,\n },\n {\n accessorKey: 'description',\n header: t('customers.companies.detail.fields.description', 'Description'),\n meta: {\n columnChooserGroup: 'Notes',\n hidden: true,\n filterKey: 'description',\n filterGroup: 'Notes',\n },\n cell: ({ row }) => row.original.description || noValue,\n },\n ]\n\n const customColumns = customFieldDefs\n .filter((def) => supportsCustomFieldColumn(def))\n .map<ColumnDef<CompanyRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n enableSorting: true,\n meta: {\n columnChooserGroup: def.group?.title ?? t('ui.columnChooser.customFieldsGroup', 'Custom Fields'),\n filterGroup: def.group?.title ?? t('ui.columnChooser.customFieldsGroup', 'Custom Fields'),\n filterType: mapCustomFieldKindToFilterType(def.kind),\n filterOptions: normalizeCustomFieldFilterOptions(def.options),\n hidden: def.listVisible === false,\n maxWidth: '220px',\n },\n cell: ({ getValue }) => renderCustomFieldCell(getValue()),\n }))\n\n return [...baseColumns, ...customColumns]\n }, [customFieldDefs, dictionaryMaps, dictionaryOptions, loadOwnerFilterOptions, resolvedOwnerFilterOptions, t])\n\n const { advancedFilterFields } = useAutoDiscoveredFields({ columns, customFieldDefs })\n\n // Sync auto-discovered fields into the `filterPanel` declared at the top of\n // the component. See the comment on the `panelFields` state for why this\n // late-binding is safe. Bail out by content (field-key list) \u2014 every render\n // of `useAutoDiscoveredFields` produces fresh `FilterFieldDef` object refs\n // even when the set of fields hasn't actually changed, so a naive reference\n // setState would loop (\"Maximum update depth exceeded\").\n React.useEffect(() => {\n setPanelFields((prev) => {\n if (prev === advancedFilterFields) return prev\n if (prev.length === advancedFilterFields.length) {\n let same = true\n for (let i = 0; i < prev.length; i++) {\n if (prev[i].key !== advancedFilterFields[i].key) { same = false; break }\n }\n if (same) return prev\n }\n return advancedFilterFields\n })\n }, [advancedFilterFields])\n\n const companiesPresets = React.useMemo<FilterPreset[]>(() => makeCompaniesPresets(), [])\n\n return (\n <Page>\n <PageBody>\n <DataTable<CompanyRow>\n stickyFirstColumn\n stickyActionsColumn\n title={t('customers.companies.list.title')}\n titleHeadingLevel={1}\n refreshButton={{\n label: t('customers.companies.list.actions.refresh'),\n onRefresh: () => { setSearch(''); setPage(1); handleRefresh() },\n }}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/companies/create\">\n {t('customers.companies.list.actions.new')}\n </Link>\n </Button>\n )}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n searchPlaceholder={t('customers.companies.list.searchPlaceholder')}\n entityIds={[E.customers.customer_entity, E.customers.customer_company_profile]}\n onRowClick={(row) => router.push(`/backend/customers/companies-v2/${row.id}`)}\n perspective={{ tableId: extensionPoints.hosts.companiesTable.tableId }}\n sortable\n manualSorting\n sorting={sorting}\n onSortingChange={handleSortingChange}\n bulkActions={[\n {\n id: 'delete',\n label: t('customers.companies.list.actions.bulkDelete', 'Delete selected'),\n destructive: true,\n onExecute: handleBulkDelete,\n },\n ]}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'view',\n label: t('customers.companies.list.actions.view'),\n onSelect: () => { router.push(`/backend/customers/companies-v2/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.companies.list.actions.openInNewTab'),\n onSelect: () => window.open(`/backend/customers/companies-v2/${row.id}`, '_blank', 'noopener'),\n },\n {\n id: 'delete',\n label: t('customers.companies.list.actions.delete'),\n destructive: true,\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n advancedFilter={{\n auto: true,\n value: filterPanel.tree,\n onChange: filterPanel.setTree,\n onApply: () => filterPanel.flush(),\n onClear: handleAdvancedFilterClear,\n triggerRef: filtersTriggerRef,\n externalPopover: true,\n onTriggerClick: () => setFiltersOpen((prev) => !prev),\n onApplyTree: (tree) => {\n filterPanel.replaceTree(tree)\n setPage(1)\n },\n }}\n activeFilterChips={(\n <ActiveFilterChips\n tree={filterPanel.appliedTree}\n fields={advancedFilterFields}\n popoverOpen={filtersOpen}\n onRemoveNode={(id) => filterPanel.dispatch({ type: 'removeNode', nodeId: id })}\n onOpen={() => setFiltersOpen(true)}\n />\n )}\n filterAwareEmptyState={{\n active: advancedFilterState.root.children.length > 0,\n entityNamePlural: t('customers.companies.entityPlural', 'companies'),\n canRemoveLast: filterPanel.tree.root.children.length > 0,\n onClearAll: handleAdvancedFilterClear,\n onRemoveLast: () => filterPanel.dispatch({ type: 'removeLast' }),\n }}\n emptyState={(\n <ListEmptyState\n entityName={t('customers.companies.entityPlural', 'companies')}\n createHref=\"/backend/customers/companies/create\"\n createLabel={t('customers.companies.list.actions.new')}\n />\n )}\n virtualized\n pagination={{ page, pageSize, total, totalPages, totalIsCapped, onPageChange: setPage, pageSizeOptions: [10, 25, 50, 100], onPageSizeChange: handlePageSizeChange, cacheStatus }}\n isLoading={isLoading}\n />\n <AdvancedFilterPanel\n fields={advancedFilterFields}\n value={filterPanel.tree}\n onChange={filterPanel.setTree}\n onApply={filterPanel.flush}\n onClear={handleAdvancedFilterClear}\n onFlush={filterPanel.flush}\n pendingErrors={filterPanel.pendingErrors}\n userId={currentUserId}\n presets={companiesPresets}\n open={filtersOpen}\n onOpenChange={setFiltersOpen}\n triggerRef={filtersTriggerRef}\n savedFilterStorageKey=\"customers.companies.list\"\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { extensionPoints } from '@open-mercato/core/modules/customers/extension-points'\nimport Link from 'next/link'\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { DataTable, type DataTableExportFormat, withDataTableNamespaces } from '@open-mercato/ui/backend/DataTable'\nimport type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'\nimport type { SortingState } from '@tanstack/react-table'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { RowActions } from '@open-mercato/ui/backend/RowActions'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'\nimport { groupBulkDeleteFailures, runBulkDelete } from '@open-mercato/ui/backend/utils/bulkDelete'\nimport { coalesceLastOperations } from '@open-mercato/ui/backend/operations/store'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { FilterOption } from '@open-mercato/ui/backend/FilterOverlay'\nimport type { FilterFieldDef, FilterOption as AdvancedFilterOption } from '@open-mercato/shared/lib/query/advanced-filter'\nimport type { AdvancedFilterTree } from '@open-mercato/shared/lib/query/advanced-filter-tree'\nimport { createEmptyTree, makeRuleTree } from '@open-mercato/shared/lib/query/advanced-filter-tree'\nimport { deserializeAdvancedFilter, deserializeTree, flatToTree, mapDictionaryColorToTone, serializeTree } from '@open-mercato/shared/lib/query/advanced-filter'\nimport { useCurrentUserId } from '@open-mercato/ui/backend/utils/useCurrentUserId'\nimport { useCurrentOrganization } from '@open-mercato/ui/backend/BackendChromeProvider'\nimport {\n DictionaryValue,\n createEmptyCustomerDictionaryMaps,\n renderDictionaryColor,\n renderDictionaryIcon,\n type CustomerDictionaryKind,\n type CustomerDictionaryMap,\n} from '../../../lib/dictionaries'\nimport {\n useCustomFieldDefs,\n} from '@open-mercato/ui/backend/utils/customFieldDefs'\nimport {\n mapCustomFieldKindToFilterType,\n normalizeCustomFieldFilterOptions,\n supportsCustomFieldColumn,\n} from '@open-mercato/ui/backend/utils/customFieldColumns'\nimport { useAutoDiscoveredFields } from '@open-mercato/ui/backend/utils/useAutoDiscoveredFields'\nimport { useAdvancedFilterTree } from '@open-mercato/ui/backend/hooks/useAdvancedFilter'\nimport { AdvancedFilterPanel } from '@open-mercato/ui/backend/filters/AdvancedFilterPanel'\nimport { ActiveFilterChips } from '@open-mercato/ui/backend/filters/ActiveFilterChips'\nimport { ListEmptyState } from '@open-mercato/ui/backend/filters/ListEmptyState'\nimport type { FilterPreset } from '@open-mercato/ui/backend/filters/QuickFilters'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { ensureCustomerDictionary } from '../../../components/detail/hooks/useCustomerDictionary'\nimport {\n ensureCurrentUserFilterOption,\n fetchAssignableStaffMembers,\n mapAssignableStaffToFilterOptions,\n} from '../../../components/detail/assignableStaff'\nimport { CollectionPreviewCell, normalizeCollectionLabels } from '../../../components/list/CollectionPreviewCell'\nimport { appendCustomerListSortParams } from '../listSorting'\n\ntype DictionaryOptionWithTone = AdvancedFilterOption & FilterOption\n\nfunction makeCompaniesPresets(): FilterPreset[] {\n return [\n {\n id: 'my-accounts',\n labelKey: 'customers.companies.presets.myAccounts',\n requiresUser: true,\n build: ({ userId }) => makeRuleTree({ field: 'owner_user_id', operator: 'is', value: userId }),\n },\n {\n id: 'recently-created',\n labelKey: 'customers.companies.presets.recentlyCreated',\n iconName: 'clock',\n build: ({ now }) => {\n const cutoff = new Date(now.getTime() - 7 * 24 * 3600 * 1000).toISOString().slice(0, 10)\n return makeRuleTree({ field: 'created_at', operator: 'is_after', value: cutoff })\n },\n },\n {\n id: 'inactive-60',\n labelKey: 'customers.companies.presets.inactive60',\n build: ({ now }) => {\n const cutoff = new Date(now.getTime() - 60 * 24 * 3600 * 1000).toISOString().slice(0, 10)\n return makeRuleTree({ field: 'next_interaction_at', operator: 'is_before', value: cutoff })\n },\n },\n ]\n}\n\n\ntype CompanyRow = {\n id: string\n name: string\n description?: string | null\n email?: string | null\n phone?: string | null\n legalName?: string | null\n brandName?: string | null\n domain?: string | null\n websiteUrl?: string | null\n industry?: string | null\n sizeBucket?: string | null\n annualRevenue?: string | null\n status?: string | null\n lifecycleStage?: string | null\n nextInteractionAt?: string | null\n nextInteractionName?: string | null\n nextInteractionIcon?: string | null\n nextInteractionColor?: string | null\n organizationId?: string | null\n source?: string | null\n ownerUserId?: string | null\n} & Record<string, unknown>\n\ntype CompaniesResponse = {\n items?: Array<Record<string, unknown>>\n total?: number\n page?: number\n totalPages?: number\n totalIsCapped?: boolean\n}\n\ntype DictionaryKindKey = CustomerDictionaryKind\ntype DictionaryMap = CustomerDictionaryMap\n\nfunction formatDate(value: string | null | undefined, fallback: string): string {\n if (!value) return fallback\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return fallback\n return date.toLocaleDateString()\n}\n\nfunction mapApiItem(item: Record<string, unknown>): CompanyRow | null {\n const id = typeof item.id === 'string' ? item.id : null\n if (!id) return null\n const name = typeof item.display_name === 'string' ? item.display_name : ''\n const description = typeof item.description === 'string' ? item.description : null\n const email = typeof item.primary_email === 'string' ? item.primary_email : null\n const phone = typeof item.primary_phone === 'string' ? item.primary_phone : null\n const legalName = typeof item.legal_name === 'string' ? item.legal_name : null\n const brandName = typeof item.brand_name === 'string' ? item.brand_name : null\n const domain = typeof item.domain === 'string' ? item.domain : null\n const websiteUrl = typeof item.website_url === 'string' ? item.website_url : null\n const industry = typeof item.industry === 'string' ? item.industry : null\n const sizeBucket = typeof item.size_bucket === 'string' ? item.size_bucket : null\n const annualRevenue =\n typeof item.annual_revenue === 'string'\n ? item.annual_revenue\n : typeof item.annual_revenue === 'number'\n ? String(item.annual_revenue)\n : null\n const status = typeof item.status === 'string' ? item.status : null\n const lifecycleStage = typeof item.lifecycle_stage === 'string' ? item.lifecycle_stage : null\n const nextInteractionAt = typeof item.next_interaction_at === 'string' ? item.next_interaction_at : null\n const nextInteractionName = typeof item.next_interaction_name === 'string' ? item.next_interaction_name : null\n const nextInteractionIcon = typeof item.next_interaction_icon === 'string' ? item.next_interaction_icon : null\n const nextInteractionColor = typeof item.next_interaction_color === 'string' ? item.next_interaction_color : null\n const organizationId = typeof item.organization_id === 'string' ? item.organization_id : null\n const source = typeof item.source === 'string' ? item.source : null\n const ownerUserId = typeof item.owner_user_id === 'string' ? item.owner_user_id : null\n const customFields: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(item)) {\n if (key.startsWith('cf_')) {\n customFields[key] = value\n }\n }\n return withDataTableNamespaces({\n id,\n name,\n description,\n email,\n phone,\n legalName,\n brandName,\n domain,\n websiteUrl,\n industry,\n sizeBucket,\n annualRevenue,\n status,\n lifecycleStage,\n nextInteractionAt,\n nextInteractionName,\n nextInteractionIcon,\n nextInteractionColor,\n organizationId,\n source,\n ownerUserId,\n ...customFields,\n }, item)\n}\n\nexport default function CustomersCompaniesPage() {\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [rows, setRows] = React.useState<CompanyRow[]>([])\n const [page, setPage] = React.useState(1)\n const [pageSize, setPageSize] = React.useState(20)\n const [sorting, setSorting] = React.useState<SortingState>([])\n const [total, setTotal] = React.useState(0)\n const [totalPages, setTotalPages] = React.useState(1)\n const [totalIsCapped, setTotalIsCapped] = React.useState(false)\n const pathname = usePathname()\n const searchParams = useSearchParams()\n const [search, setSearch] = React.useState(() => searchParams?.get('search')?.trim() ?? '')\n // One-shot URL hydration used as the hook's initial value. The hook is the\n // single source of truth from this point on \u2014 the page MUST NOT keep a\n // parallel `useState<AdvancedFilterTree>` (see spec \"Migration & Backward\n // Compatibility\" \u2192 state ownership).\n const initialFilterTree = React.useMemo<AdvancedFilterTree>(() => {\n if (!searchParams) return createEmptyTree()\n const record: Record<string, string> = {}\n searchParams.forEach((value, key) => {\n if (key.startsWith('filter[')) record[key] = value\n })\n const v2 = deserializeTree(record)\n if (v2) return v2\n const flat = deserializeAdvancedFilter(record)\n if (flat) return flatToTree(flat)\n return createEmptyTree()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n // `filterPanel` lives at the top of the component so derived state below\n // (URL params, data fetch, export config) can read `filterPanel.appliedTree`\n // directly. Real `FilterFieldDef[]` arrives later from `useAutoDiscoveredFields`\n // (it depends on columns) and is synced into the hook via a small effect at\n // the bottom of the component. The hook reads fields through a ref at\n // validation time only \u2014 first validation cannot fire before user input, by\n // which point fields have settled, so the empty initial value is safe.\n const [panelFields, setPanelFields] = React.useState<FilterFieldDef[]>([])\n const [filtersOpen, setFiltersOpen] = React.useState(false)\n const filtersTriggerRef = React.useRef<HTMLButtonElement | null>(null)\n const filterPanel = useAdvancedFilterTree({\n initial: initialFilterTree,\n fields: panelFields,\n onApply: () => setPage(1),\n })\n const advancedFilterState = filterPanel.appliedTree\n const handleAdvancedFilterClear = React.useCallback(() => {\n filterPanel.clear()\n setPage(1)\n }, [filterPanel])\n const [isLoading, setIsLoading] = React.useState(true)\n const [reloadToken, setReloadToken] = React.useState(0)\n const [cacheStatus, setCacheStatus] = React.useState<'hit' | 'miss' | null>(null)\n const [dictionaryMaps, setDictionaryMaps] = React.useState<Record<DictionaryKindKey, DictionaryMap>>(createEmptyCustomerDictionaryMaps())\n const scopeVersion = useOrganizationScopeVersion()\n const queryClient = useQueryClient()\n const t = useT()\n const router = useRouter()\n const handlePageSizeChange = React.useCallback((newSize: number) => {\n setPageSize(newSize)\n setPage(1)\n }, [])\n const handleSortingChange = React.useCallback((nextSorting: SortingState) => {\n setSorting(nextSorting)\n setPage(1)\n }, [])\n\n const bulkMutationContextId = 'customers-companies-list:bulk-delete'\n const { runMutation: runBulkMutation, retryLastMutation: retryBulkMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: bulkMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const singleMutationContextId = 'customers-companies-list:single-delete'\n const { runMutation: runSingleMutation, retryLastMutation: retrySingleMutation } = useGuardedMutation<{\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: singleMutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n const fetchDictionaryEntries = React.useCallback(async (kind: DictionaryKindKey) => {\n try {\n const data = await ensureCustomerDictionary(queryClient, kind, scopeVersion)\n setDictionaryMaps((prev) => ({\n ...prev,\n [kind]: data.map,\n }))\n return data.entries\n } catch {\n return []\n }\n }, [queryClient, scopeVersion])\n const dictionaryOptions = React.useMemo(() => {\n const toOptions = (map?: DictionaryMap | null): DictionaryOptionWithTone[] =>\n Object.values(map ?? {})\n .map((entry) => {\n const tone = mapDictionaryColorToTone(entry.color)\n const option: DictionaryOptionWithTone = { value: entry.value, label: entry.label }\n if (tone) option.tone = tone\n return option\n })\n .sort((a, b) => a.label.localeCompare(b.label, undefined, { sensitivity: 'base' }))\n return {\n statuses: toOptions(dictionaryMaps.statuses),\n sources: toOptions(dictionaryMaps.sources),\n lifecycleStages: toOptions(dictionaryMaps['lifecycle-stages']),\n }\n }, [dictionaryMaps])\n\n React.useEffect(() => {\n let cancelled = false\n async function loadAll() {\n if (cancelled) return\n setDictionaryMaps(createEmptyCustomerDictionaryMaps())\n await Promise.all([\n fetchDictionaryEntries('statuses'),\n fetchDictionaryEntries('sources'),\n fetchDictionaryEntries('lifecycle-stages'),\n ])\n }\n loadAll().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [fetchDictionaryEntries, scopeVersion, reloadToken])\n\n const { data: customFieldDefs = [] } = useCustomFieldDefs(\n [E.customers.customer_entity, E.customers.customer_company_profile],\n { keyExtras: [scopeVersion, reloadToken] },\n )\n const currentUserId = useCurrentUserId()\n const activeOrgId = useCurrentOrganization()?.id ?? null\n const [ownerFilterOptions, setOwnerFilterOptions] = React.useState<AdvancedFilterOption[]>([])\n React.useEffect(() => {\n const controller = new AbortController()\n let cancelled = false\n void fetchAssignableStaffMembers('', { pageSize: 100, activeOrgId, signal: controller.signal })\n .then((items) => {\n if (!cancelled) setOwnerFilterOptions(mapAssignableStaffToFilterOptions(items))\n })\n .catch(() => {\n if (!cancelled) setOwnerFilterOptions([])\n })\n return () => {\n cancelled = true\n controller.abort()\n }\n }, [activeOrgId, scopeVersion])\n const resolvedOwnerFilterOptions = React.useMemo(\n () => ensureCurrentUserFilterOption(\n ownerFilterOptions,\n currentUserId,\n t('customers.filters.currentUser', 'Current user'),\n ),\n [currentUserId, ownerFilterOptions, t],\n )\n const loadOwnerFilterOptions = React.useCallback(async (query?: string): Promise<AdvancedFilterOption[]> => {\n const items = await fetchAssignableStaffMembers(query ?? '', { pageSize: 100, activeOrgId })\n return mapAssignableStaffToFilterOptions(items)\n }, [activeOrgId])\n\n const queryParams = React.useMemo(() => {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('pageSize', String(pageSize))\n appendCustomerListSortParams(params, sorting)\n if (search.trim()) params.set('search', search.trim())\n const advancedParams = serializeTree(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n return params.toString()\n }, [advancedFilterState, page, pageSize, search, sorting])\n\n const currentParams = React.useMemo(() => Object.fromEntries(new URLSearchParams(queryParams)), [queryParams])\n\n // Mirror page state into the URL so refresh restores the same filter tree,\n // including nested subgroups. Same pattern as the Deals page; without it\n // refreshes silently dropped everything past whatever a stale localStorage\n // perspective snapshot happened to contain.\n const queryRef = React.useRef(searchParams?.toString() ?? '')\n React.useEffect(() => {\n if (!pathname) return\n const params = new URLSearchParams()\n if (search.trim().length) params.set('search', search.trim())\n if (page > 1) params.set('page', String(page))\n appendCustomerListSortParams(params, sorting)\n const advancedParams = serializeTree(advancedFilterState)\n for (const [key, val] of Object.entries(advancedParams)) {\n params.set(key, val)\n }\n const next = params.toString()\n if (queryRef.current === next) return\n queryRef.current = next\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false })\n }, [pathname, router, page, search, sorting, advancedFilterState])\n\n const exportConfig = React.useMemo(() => ({\n view: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/companies', { ...currentParams, exportScope: 'view' }, format),\n },\n full: {\n getUrl: (format: DataTableExportFormat) =>\n buildCrudExportUrl('customers/companies', { ...currentParams, exportScope: 'full', all: 'true' }, format),\n },\n }), [currentParams])\n\n React.useEffect(() => {\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setCacheStatus(null)\n try {\n const call = await apiCall<CompaniesResponse>(`/api/customers/companies?${queryParams}`)\n if (!call.ok) {\n const errorPayload = call.result as { error?: string } | undefined\n const message = typeof errorPayload?.error === 'string' ? errorPayload.error : t('customers.companies.list.error.load')\n flash(message, 'error')\n if (!cancelled) setCacheStatus(null)\n return\n }\n const payload = call.result ?? {}\n if (cancelled) return\n setCacheStatus(call.cacheStatus ?? null)\n const items = Array.isArray(payload.items) ? payload.items : []\n setRows(items.map((item) => mapApiItem(item as Record<string, unknown>)).filter((row): row is CompanyRow => !!row))\n setTotal(typeof payload.total === 'number' ? payload.total : items.length)\n setTotalPages(typeof payload.totalPages === 'number' ? payload.totalPages : 1)\n setTotalIsCapped(payload?.totalIsCapped === true)\n } catch (err) {\n if (!cancelled) {\n setCacheStatus(null)\n const message = err instanceof Error ? err.message : t('customers.companies.list.error.load')\n flash(message, 'error')\n }\n } finally {\n if (!cancelled) setIsLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [queryParams, reloadToken, scopeVersion, t])\n\n const handleRefresh = React.useCallback(() => {\n setReloadToken((token) => token + 1)\n }, [])\n\n const handleDelete = React.useCallback(async (company: CompanyRow) => {\n if (!company?.id) return\n const name = company.name || t('customers.companies.list.deleteFallbackName')\n const confirmed = await confirm({\n title: t('customers.companies.list.deleteConfirm', undefined, { name }),\n variant: 'destructive',\n })\n if (!confirmed) return\n try {\n await runSingleMutation({\n operation: async () => {\n // optimistic-lock-exempt: delete-only mutation \u2014 no field-level lost-update\n await apiCallOrThrow(\n `/api/customers/companies?id=${encodeURIComponent(company.id)}`,\n {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n },\n { errorMessage: t('customers.companies.list.deleteError') },\n )\n },\n context: {\n formId: singleMutationContextId,\n resourceKind: 'customers.company',\n resourceId: company.id,\n retryLastMutation: retrySingleMutation,\n },\n })\n setRows((prev) => prev.filter((row) => row.id !== company.id))\n setTotal((prev) => Math.max(prev - 1, 0))\n handleRefresh()\n flash(t('customers.companies.list.deleteSuccess'), 'success')\n } catch (err) {\n const message = err instanceof Error ? err.message : t('customers.companies.list.deleteError')\n flash(message, 'error')\n }\n }, [confirm, handleRefresh, retrySingleMutation, runSingleMutation, singleMutationContextId, t])\n\n const handleBulkDelete = React.useCallback(async (selectedRows: CompanyRow[]) => {\n const confirmed = await confirm({\n title: t('customers.companies.list.bulkDelete.title', 'Delete {count} companies?', { count: selectedRows.length }),\n description: t('customers.companies.list.bulkDelete.description', 'This action cannot be undone.'),\n variant: 'destructive',\n })\n if (!confirmed) return false\n\n const { succeeded, failures } = await runBulkMutation({\n operation: async () =>\n runBulkDelete(\n selectedRows,\n async (row) => {\n // optimistic-lock-exempt: bulk delete-only mutation \u2014 no field-level lost-update\n await apiCallOrThrow(`/api/customers/companies?id=${encodeURIComponent(row.id)}`, {\n method: 'DELETE',\n headers: { 'content-type': 'application/json' },\n })\n },\n {\n fallbackErrorMessage: t('customers.companies.list.deleteError', 'Failed to delete company.'),\n logTag: 'customers.companies.list',\n progress: {\n jobType: 'customers.companies.bulk_delete',\n name: t('customers.companies.list.bulkDelete.progressName', 'Delete selected companies'),\n description: t(\n 'customers.companies.list.bulkDelete.progressDescription',\n '{count} companies selected for deletion',\n { count: selectedRows.length },\n ),\n meta: { source: 'customers.companies.list' },\n },\n },\n ),\n context: {\n formId: bulkMutationContextId,\n resourceKind: 'customers.company',\n retryLastMutation: retryBulkMutation,\n },\n })\n\n if (succeeded.length > 0) {\n const succeededIds = new Set(succeeded.map((r) => r.id))\n setRows((prev) => prev.filter((r) => !succeededIds.has(r.id)))\n setTotal((prev) => Math.max(0, prev - succeeded.length))\n setReloadToken((prev) => prev + 1)\n if (succeeded.length > 1) {\n coalesceLastOperations(succeeded.length, {\n commandId: 'customers.companies.delete',\n actionLabel: t('customers.companies.list.bulkDelete.operationLabel', 'Delete {count} companies', { count: succeeded.length }),\n resourceKind: 'customers.company',\n })\n }\n if (failures.length === 0) {\n flash(\n t('customers.companies.list.bulkDelete.success', '{count} companies deleted', { count: succeeded.length }),\n 'success',\n )\n } else {\n flash(\n t('customers.companies.list.bulkDelete.partial', '{deleted} of {total} companies deleted; {failed} failed', {\n deleted: succeeded.length,\n total: selectedRows.length,\n failed: failures.length,\n }),\n 'warning',\n )\n }\n }\n\n for (const group of groupBulkDeleteFailures(failures)) {\n const message = group.count === 1\n ? group.sampleMessage\n : t(\n 'customers.companies.list.bulkDelete.failedGroup',\n '{count} companies could not be deleted: {message}',\n { count: group.count, message: group.sampleMessage },\n )\n flash(message, 'error')\n }\n\n return succeeded.length > 0\n }, [bulkMutationContextId, confirm, retryBulkMutation, runBulkMutation, t])\n\n const columns = React.useMemo<ColumnDef<CompanyRow>[]>(() => {\n const noValue = <span className=\"text-muted-foreground text-sm\">{t('customers.companies.list.noValue')}</span>\n const renderDictionaryCell = (kind: DictionaryKindKey, rawValue: string | null | undefined) => (\n <DictionaryValue\n value={rawValue}\n map={dictionaryMaps[kind]}\n fallback={rawValue ? <span>{rawValue}</span> : noValue}\n className=\"text-sm\"\n iconWrapperClassName=\"inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\"\n iconClassName=\"h-4 w-4\"\n colorClassName=\"h-3 w-3 rounded-full\"\n />\n )\n\n const renderCustomFieldCell = (value: unknown) => {\n if (value == null) return noValue\n if (Array.isArray(value)) {\n if (!value.length) return noValue\n const normalized = normalizeCollectionLabels(\n value.map((item) => {\n if (item == null) return ''\n if (typeof item === 'string') return item\n return String(item)\n }),\n )\n if (!normalized.length) return noValue\n return <CollectionPreviewCell labels={normalized} maxVisible={2} />\n }\n if (typeof value === 'boolean') {\n return (\n <span className=\"text-sm\">\n {value\n ? t('customers.companies.list.booleanYes', 'Yes')\n : t('customers.companies.list.booleanNo', 'No')}\n </span>\n )\n }\n const stringValue = typeof value === 'string' ? value.trim() : String(value)\n if (!stringValue) return noValue\n return <span className=\"text-sm\">{stringValue}</span>\n }\n\n const baseColumns: ColumnDef<CompanyRow>[] = [\n {\n accessorKey: 'name',\n header: t('customers.companies.list.columns.name'),\n meta: {\n alwaysVisible: true,\n columnChooserGroup: t('customers.columnGroups.basicInfo', 'Basic Info'),\n filterKey: 'display_name',\n filterGroup: t('customers.columnGroups.crm', 'CRM'),\n maxWidth: '260px',\n },\n cell: ({ row }) => (\n <Link href={`/backend/customers/companies-v2/${row.original.id}`} className=\"font-medium hover:underline\">\n {row.original.name}\n </Link>\n ),\n },\n {\n accessorKey: 'email',\n header: t('customers.companies.list.columns.email'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.contact', 'Contact'),\n filterKey: 'primary_email',\n filterGroup: t('customers.columnGroups.contact', 'Contact'),\n filterIconName: 'mail',\n maxWidth: '220px',\n },\n cell: ({ row }) => row.original.email || noValue,\n },\n {\n accessorKey: 'phone',\n header: t('customers.companies.detail.highlights.primaryPhone', 'Primary phone'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.contact', 'Contact'),\n hidden: true,\n filterKey: 'primary_phone',\n filterGroup: t('customers.columnGroups.contact', 'Contact'),\n filterIconName: 'phone',\n maxWidth: '180px',\n },\n cell: ({ row }) => row.original.phone || noValue,\n },\n {\n accessorKey: 'status',\n header: t('customers.companies.list.columns.status'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.statuses,\n columnChooserGroup: t('customers.columnGroups.basicInfo', 'Basic Info'),\n filterGroup: t('customers.columnGroups.crm', 'CRM'),\n },\n cell: ({ row }) => renderDictionaryCell('statuses', row.original.status),\n },\n {\n accessorKey: 'lifecycleStage',\n header: t('customers.companies.list.columns.lifecycleStage'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.lifecycleStages,\n columnChooserGroup: t('customers.columnGroups.basicInfo', 'Basic Info'),\n filterKey: 'lifecycle_stage',\n filterGroup: t('customers.columnGroups.crm', 'CRM'),\n },\n cell: ({ row }) => renderDictionaryCell('lifecycle-stages', row.original.lifecycleStage),\n },\n {\n accessorKey: 'nextInteractionAt',\n header: t('customers.companies.list.columns.nextInteraction'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.dates', 'Dates'),\n filterKey: 'next_interaction_at',\n filterGroup: t('customers.columnGroups.activity', 'Activity'),\n filterIconName: 'calendar',\n },\n cell: ({ row }) =>\n row.original.nextInteractionAt\n ? (\n <div className=\"flex items-start gap-2 text-sm\">\n {row.original.nextInteractionIcon ? (\n <span className=\"mt-0.5 inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-card\">\n {renderDictionaryIcon(row.original.nextInteractionIcon, 'h-4 w-4')}\n </span>\n ) : null}\n <div className=\"flex flex-col\">\n <span>{formatDate(row.original.nextInteractionAt, t('customers.companies.list.noValue'))}</span>\n {row.original.nextInteractionName ? (\n <span className=\"text-xs text-muted-foreground\">{row.original.nextInteractionName}</span>\n ) : null}\n </div>\n {row.original.nextInteractionColor ? (\n <span className=\"mt-1\">\n {renderDictionaryColor(row.original.nextInteractionColor, 'h-3 w-3 rounded-full border border-border')}\n </span>\n ) : null}\n </div>\n )\n : noValue,\n },\n {\n accessorKey: 'source',\n header: t('customers.companies.list.columns.source'),\n meta: {\n filterType: 'select' as const,\n filterOptions: dictionaryOptions.sources,\n columnChooserGroup: t('customers.columnGroups.basicInfo', 'Basic Info'),\n filterGroup: t('customers.columnGroups.crm', 'CRM'),\n },\n cell: ({ row }) => renderDictionaryCell('sources', row.original.source),\n },\n {\n accessorKey: 'ownerUserId',\n header: t('customers.companies.list.columns.owner', 'Owner'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.crm', 'CRM'),\n filterType: 'select',\n filterOptions: resolvedOwnerFilterOptions,\n filterLoadOptions: loadOwnerFilterOptions,\n filterGroup: t('customers.columnGroups.crm', 'CRM'),\n filterIconName: 'user-round',\n filterKey: 'owner_user_id',\n hidden: true,\n },\n cell: ({ row }) => row.original.ownerUserId ?? null,\n },\n {\n accessorKey: 'legalName',\n header: t('customers.companies.detail.fields.legalName', 'Legal name'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.profile', 'Profile'),\n hidden: true,\n filterKey: 'company_profile.legal_name',\n filterGroup: t('customers.columnGroups.profile', 'Profile'),\n },\n cell: ({ row }) => row.original.legalName || noValue,\n },\n {\n accessorKey: 'brandName',\n header: t('customers.companies.detail.fields.brandName', 'Brand name'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.profile', 'Profile'),\n hidden: true,\n filterKey: 'company_profile.brand_name',\n filterGroup: t('customers.columnGroups.profile', 'Profile'),\n },\n cell: ({ row }) => row.original.brandName || noValue,\n },\n {\n accessorKey: 'domain',\n header: t('customers.companies.detail.fields.domain', 'Domain'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.profile', 'Profile'),\n hidden: true,\n filterKey: 'company_profile.domain',\n filterGroup: t('customers.columnGroups.profile', 'Profile'),\n },\n cell: ({ row }) => row.original.domain || noValue,\n },\n {\n accessorKey: 'websiteUrl',\n header: t('customers.companies.detail.fields.website', 'Website'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.profile', 'Profile'),\n hidden: true,\n filterKey: 'company_profile.website_url',\n filterGroup: t('customers.columnGroups.profile', 'Profile'),\n },\n cell: ({ row }) => row.original.websiteUrl || noValue,\n },\n {\n accessorKey: 'industry',\n header: t('customers.companies.detail.fields.industry', 'Industry'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.profile', 'Profile'),\n hidden: true,\n filterKey: 'company_profile.industry',\n filterGroup: t('customers.columnGroups.profile', 'Profile'),\n },\n cell: ({ row }) => row.original.industry || noValue,\n },\n {\n accessorKey: 'sizeBucket',\n header: t('customers.companies.detail.fields.sizeBucket', 'Company size'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.profile', 'Profile'),\n hidden: true,\n filterKey: 'company_profile.size_bucket',\n filterGroup: t('customers.columnGroups.profile', 'Profile'),\n },\n cell: ({ row }) => row.original.sizeBucket || noValue,\n },\n {\n accessorKey: 'annualRevenue',\n header: t('customers.companies.detail.highlights.annualRevenue', 'Annual revenue'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.profile', 'Profile'),\n hidden: true,\n filterKey: 'company_profile.annual_revenue',\n filterType: 'number' as const,\n filterGroup: t('customers.columnGroups.profile', 'Profile'),\n },\n cell: ({ row }) => row.original.annualRevenue || noValue,\n },\n {\n accessorKey: 'description',\n header: t('customers.companies.detail.fields.description', 'Description'),\n meta: {\n columnChooserGroup: t('customers.columnGroups.notes', 'Notes'),\n hidden: true,\n filterKey: 'description',\n filterGroup: t('customers.columnGroups.notes', 'Notes'),\n },\n cell: ({ row }) => row.original.description || noValue,\n },\n ]\n\n const customColumns = customFieldDefs\n .filter((def) => supportsCustomFieldColumn(def))\n .map<ColumnDef<CompanyRow>>((def) => ({\n accessorKey: `cf_${def.key}`,\n header: def.label || def.key,\n enableSorting: true,\n meta: {\n columnChooserGroup: def.group?.title ?? t('ui.columnChooser.customFieldsGroup', 'Custom Fields'),\n filterGroup: def.group?.title ?? t('ui.columnChooser.customFieldsGroup', 'Custom Fields'),\n filterType: mapCustomFieldKindToFilterType(def.kind),\n filterOptions: normalizeCustomFieldFilterOptions(def.options),\n hidden: def.listVisible === false,\n maxWidth: '220px',\n },\n cell: ({ getValue }) => renderCustomFieldCell(getValue()),\n }))\n\n return [...baseColumns, ...customColumns]\n }, [customFieldDefs, dictionaryMaps, dictionaryOptions, loadOwnerFilterOptions, resolvedOwnerFilterOptions, t])\n\n const { advancedFilterFields } = useAutoDiscoveredFields({ columns, customFieldDefs })\n\n // Sync auto-discovered fields into the `filterPanel` declared at the top of\n // the component. See the comment on the `panelFields` state for why this\n // late-binding is safe. Bail out by content (field-key list) \u2014 every render\n // of `useAutoDiscoveredFields` produces fresh `FilterFieldDef` object refs\n // even when the set of fields hasn't actually changed, so a naive reference\n // setState would loop (\"Maximum update depth exceeded\").\n React.useEffect(() => {\n setPanelFields((prev) => {\n if (prev === advancedFilterFields) return prev\n if (prev.length === advancedFilterFields.length) {\n let same = true\n for (let i = 0; i < prev.length; i++) {\n if (prev[i].key !== advancedFilterFields[i].key) { same = false; break }\n }\n if (same) return prev\n }\n return advancedFilterFields\n })\n }, [advancedFilterFields])\n\n const companiesPresets = React.useMemo<FilterPreset[]>(() => makeCompaniesPresets(), [])\n\n return (\n <Page>\n <PageBody>\n <DataTable<CompanyRow>\n stickyFirstColumn\n stickyActionsColumn\n title={t('customers.companies.list.title')}\n titleHeadingLevel={1}\n refreshButton={{\n label: t('customers.companies.list.actions.refresh'),\n onRefresh: () => { setSearch(''); setPage(1); handleRefresh() },\n }}\n actions={(\n <Button asChild>\n <Link href=\"/backend/customers/companies/create\">\n {t('customers.companies.list.actions.new')}\n </Link>\n </Button>\n )}\n columns={columns}\n columnChooser={{ auto: true }}\n data={rows}\n exporter={exportConfig}\n searchValue={search}\n onSearchChange={(value) => { setSearch(value); setPage(1) }}\n searchPlaceholder={t('customers.companies.list.searchPlaceholder')}\n entityIds={[E.customers.customer_entity, E.customers.customer_company_profile]}\n onRowClick={(row) => router.push(`/backend/customers/companies-v2/${row.id}`)}\n perspective={{ tableId: extensionPoints.hosts.companiesTable.tableId }}\n sortable\n manualSorting\n sorting={sorting}\n onSortingChange={handleSortingChange}\n bulkActions={[\n {\n id: 'delete',\n label: t('customers.companies.list.actions.bulkDelete', 'Delete selected'),\n destructive: true,\n onExecute: handleBulkDelete,\n },\n ]}\n rowActions={(row) => (\n <RowActions\n items={[\n {\n id: 'view',\n label: t('customers.companies.list.actions.view'),\n onSelect: () => { router.push(`/backend/customers/companies-v2/${row.id}`) },\n },\n {\n id: 'open-new-tab',\n label: t('customers.companies.list.actions.openInNewTab'),\n onSelect: () => window.open(`/backend/customers/companies-v2/${row.id}`, '_blank', 'noopener'),\n },\n {\n id: 'delete',\n label: t('customers.companies.list.actions.delete'),\n destructive: true,\n onSelect: () => handleDelete(row),\n },\n ]}\n />\n )}\n advancedFilter={{\n auto: true,\n value: filterPanel.tree,\n onChange: filterPanel.setTree,\n onApply: () => filterPanel.flush(),\n onClear: handleAdvancedFilterClear,\n triggerRef: filtersTriggerRef,\n externalPopover: true,\n onTriggerClick: () => setFiltersOpen((prev) => !prev),\n onApplyTree: (tree) => {\n filterPanel.replaceTree(tree)\n setPage(1)\n },\n }}\n activeFilterChips={(\n <ActiveFilterChips\n tree={filterPanel.appliedTree}\n fields={advancedFilterFields}\n popoverOpen={filtersOpen}\n onRemoveNode={(id) => filterPanel.dispatch({ type: 'removeNode', nodeId: id })}\n onOpen={() => setFiltersOpen(true)}\n />\n )}\n filterAwareEmptyState={{\n active: advancedFilterState.root.children.length > 0,\n entityNamePlural: t('customers.companies.entityPlural', 'companies'),\n canRemoveLast: filterPanel.tree.root.children.length > 0,\n onClearAll: handleAdvancedFilterClear,\n onRemoveLast: () => filterPanel.dispatch({ type: 'removeLast' }),\n }}\n emptyState={(\n <ListEmptyState\n entityName={t('customers.companies.entityPlural', 'companies')}\n createHref=\"/backend/customers/companies/create\"\n createLabel={t('customers.companies.list.actions.new')}\n />\n )}\n virtualized\n pagination={{ page, pageSize, total, totalPages, totalIsCapped, onPageChange: setPage, pageSizeOptions: [10, 25, 50, 100], onPageSizeChange: handlePageSizeChange, cacheStatus }}\n isLoading={isLoading}\n />\n <AdvancedFilterPanel\n fields={advancedFilterFields}\n value={filterPanel.tree}\n onChange={filterPanel.setTree}\n onApply={filterPanel.flush}\n onClear={handleAdvancedFilterClear}\n onFlush={filterPanel.flush}\n pendingErrors={filterPanel.pendingErrors}\n userId={currentUserId}\n presets={companiesPresets}\n open={filtersOpen}\n onOpenChange={setFiltersOpen}\n triggerRef={filtersTriggerRef}\n savedFilterStorageKey=\"customers.companies.list\"\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
+ "mappings": ";AA0jBoB,cA4HJ,YA5HI;AAxjBpB,YAAY,WAAW;AACvB,SAAS,uBAAuB;AAChC,OAAO,UAAU;AACjB,SAAS,aAAa,WAAW,uBAAuB;AACxD,SAAS,MAAM,gBAAgB;AAC/B,SAAS,WAAuC,+BAA+B;AAG/E,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAC3B,SAAS,SAAS,sBAAsB;AACxC,SAAS,0BAA0B;AACnC,SAAS,yBAAyB,qBAAqB;AACvD,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,aAAa;AACtB,SAAS,SAAS;AAClB,SAAS,mCAAmC;AAC5C,SAAS,YAAY;AACrB,SAAS,wBAAwB;AAIjC,SAAS,iBAAiB,oBAAoB;AAC9C,SAAS,2BAA2B,iBAAiB,YAAY,0BAA0B,qBAAqB;AAChH,SAAS,wBAAwB;AACjC,SAAS,8BAA8B;AACvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,+BAA+B;AACxC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAClC,SAAS,sBAAsB;AAE/B,SAAS,sBAAsB;AAC/B,SAAS,gCAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB,iCAAiC;AACjE,SAAS,oCAAoC;AAI7C,SAAS,uBAAuC;AAC9C,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,cAAc;AAAA,MACd,OAAO,CAAC,EAAE,OAAO,MAAM,aAAa,EAAE,OAAO,iBAAiB,UAAU,MAAM,OAAO,OAAO,CAAC;AAAA,IAC/F;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,UAAU;AAAA,MACV,OAAO,CAAC,EAAE,IAAI,MAAM;AAClB,cAAM,SAAS,IAAI,KAAK,IAAI,QAAQ,IAAI,IAAI,KAAK,OAAO,GAAI,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACvF,eAAO,aAAa,EAAE,OAAO,cAAc,UAAU,YAAY,OAAO,OAAO,CAAC;AAAA,MAClF;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,OAAO,CAAC,EAAE,IAAI,MAAM;AAClB,cAAM,SAAS,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,KAAK,OAAO,GAAI,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACxF,eAAO,aAAa,EAAE,OAAO,uBAAuB,UAAU,aAAa,OAAO,OAAO,CAAC;AAAA,MAC5F;AAAA,IACF;AAAA,EACF;AACF;AAsCA,SAAS,WAAW,OAAkC,UAA0B;AAC9E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,KAAK,mBAAmB;AACjC;AAEA,SAAS,WAAW,MAAkD;AACpE,QAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,OAAO,OAAO,KAAK,iBAAiB,WAAW,KAAK,eAAe;AACzE,QAAM,cAAc,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;AAC9E,QAAM,QAAQ,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AAC5E,QAAM,QAAQ,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AAC5E,QAAM,YAAY,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;AAC1E,QAAM,YAAY,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;AAC1E,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,QAAM,aAAa,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;AAC7E,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,aAAa,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc;AAC7E,QAAM,gBACJ,OAAO,KAAK,mBAAmB,WAC3B,KAAK,iBACL,OAAO,KAAK,mBAAmB,WAC7B,OAAO,KAAK,cAAc,IAC1B;AACR,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,QAAM,iBAAiB,OAAO,KAAK,oBAAoB,WAAW,KAAK,kBAAkB;AACzF,QAAM,oBAAoB,OAAO,KAAK,wBAAwB,WAAW,KAAK,sBAAsB;AACpG,QAAM,sBAAsB,OAAO,KAAK,0BAA0B,WAAW,KAAK,wBAAwB;AAC1G,QAAM,sBAAsB,OAAO,KAAK,0BAA0B,WAAW,KAAK,wBAAwB;AAC1G,QAAM,uBAAuB,OAAO,KAAK,2BAA2B,WAAW,KAAK,yBAAyB;AAC7G,QAAM,iBAAiB,OAAO,KAAK,oBAAoB,WAAW,KAAK,kBAAkB;AACzF,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,QAAM,cAAc,OAAO,KAAK,kBAAkB,WAAW,KAAK,gBAAgB;AAClF,QAAM,eAAwC,CAAC;AAC/C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,IAAI,WAAW,KAAK,GAAG;AACzB,mBAAa,GAAG,IAAI;AAAA,IACtB;AAAA,EACF;AACA,SAAO,wBAAwB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GAAG,IAAI;AACT;AAEe,SAAR,yBAA0C;AAC/C,QAAM,EAAE,SAAS,qBAAqB,IAAI,iBAAiB;AAC3D,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAuB,CAAC,CAAC;AACvD,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAAS,CAAC;AACxC,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAS,EAAE;AACjD,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAuB,CAAC,CAAC;AAC7D,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAS,CAAC;AAC1C,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAS,CAAC;AACpD,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAAS,KAAK;AAC9D,QAAM,WAAW,YAAY;AAC7B,QAAM,eAAe,gBAAgB;AACrC,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,MAAM,cAAc,IAAI,QAAQ,GAAG,KAAK,KAAK,EAAE;AAK1F,QAAM,oBAAoB,MAAM,QAA4B,MAAM;AAChE,QAAI,CAAC,aAAc,QAAO,gBAAgB;AAC1C,UAAM,SAAiC,CAAC;AACxC,iBAAa,QAAQ,CAAC,OAAO,QAAQ;AACnC,UAAI,IAAI,WAAW,SAAS,EAAG,QAAO,GAAG,IAAI;AAAA,IAC/C,CAAC;AACD,UAAM,KAAK,gBAAgB,MAAM;AACjC,QAAI,GAAI,QAAO;AACf,UAAM,OAAO,0BAA0B,MAAM;AAC7C,QAAI,KAAM,QAAO,WAAW,IAAI;AAChC,WAAO,gBAAgB;AAAA,EAEzB,GAAG,CAAC,CAAC;AAQL,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAA2B,CAAC,CAAC;AACzE,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,KAAK;AAC1D,QAAM,oBAAoB,MAAM,OAAiC,IAAI;AACrE,QAAM,cAAc,sBAAsB;AAAA,IACxC,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS,MAAM,QAAQ,CAAC;AAAA,EAC1B,CAAC;AACD,QAAM,sBAAsB,YAAY;AACxC,QAAM,4BAA4B,MAAM,YAAY,MAAM;AACxD,gBAAY,MAAM;AAClB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,WAAW,CAAC;AAChB,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAS,IAAI;AACrD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,CAAC;AACtD,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAgC,IAAI;AAChF,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,MAAM,SAAmD,kCAAkC,CAAC;AACxI,QAAM,eAAe,4BAA4B;AACjD,QAAM,cAAc,eAAe;AACnC,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,uBAAuB,MAAM,YAAY,CAAC,YAAoB;AAClE,gBAAY,OAAO;AACnB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,CAAC;AACL,QAAM,sBAAsB,MAAM,YAAY,CAAC,gBAA8B;AAC3E,eAAW,WAAW;AACtB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,wBAAwB;AAC9B,QAAM,EAAE,aAAa,iBAAiB,mBAAmB,kBAAkB,IAAI,mBAI5E;AAAA,IACD,WAAW;AAAA,IACX,gBAAgB,EAAE,8BAA8B,4BAA4B;AAAA,EAC9E,CAAC;AACD,QAAM,0BAA0B;AAChC,QAAM,EAAE,aAAa,mBAAmB,mBAAmB,oBAAoB,IAAI,mBAKhF;AAAA,IACD,WAAW;AAAA,IACX,gBAAgB,EAAE,8BAA8B,4BAA4B;AAAA,EAC9E,CAAC;AACD,QAAM,yBAAyB,MAAM,YAAY,OAAO,SAA4B;AAClF,QAAI;AACF,YAAM,OAAO,MAAM,yBAAyB,aAAa,MAAM,YAAY;AAC3E,wBAAkB,CAAC,UAAU;AAAA,QAC3B,GAAG;AAAA,QACH,CAAC,IAAI,GAAG,KAAK;AAAA,MACf,EAAE;AACF,aAAO,KAAK;AAAA,IACd,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF,GAAG,CAAC,aAAa,YAAY,CAAC;AAC9B,QAAM,oBAAoB,MAAM,QAAQ,MAAM;AAC5C,UAAM,YAAY,CAAC,QACjB,OAAO,OAAO,OAAO,CAAC,CAAC,EACpB,IAAI,CAAC,UAAU;AACd,YAAM,OAAO,yBAAyB,MAAM,KAAK;AACjD,YAAM,SAAmC,EAAE,OAAO,MAAM,OAAO,OAAO,MAAM,MAAM;AAClF,UAAI,KAAM,QAAO,OAAO;AACxB,aAAO;AAAA,IACT,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,OAAO,QAAW,EAAE,aAAa,OAAO,CAAC,CAAC;AACtF,WAAO;AAAA,MACL,UAAU,UAAU,eAAe,QAAQ;AAAA,MAC3C,SAAS,UAAU,eAAe,OAAO;AAAA,MACzC,iBAAiB,UAAU,eAAe,kBAAkB,CAAC;AAAA,IAC/D;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,UAAU;AACvB,UAAI,UAAW;AACf,wBAAkB,kCAAkC,CAAC;AACrD,YAAM,QAAQ,IAAI;AAAA,QAChB,uBAAuB,UAAU;AAAA,QACjC,uBAAuB,SAAS;AAAA,QAChC,uBAAuB,kBAAkB;AAAA,MAC3C,CAAC;AAAA,IACH;AACA,YAAQ,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AACxB,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,wBAAwB,cAAc,WAAW,CAAC;AAEtD,QAAM,EAAE,MAAM,kBAAkB,CAAC,EAAE,IAAI;AAAA,IACrC,CAAC,EAAE,UAAU,iBAAiB,EAAE,UAAU,wBAAwB;AAAA,IAClE,EAAE,WAAW,CAAC,cAAc,WAAW,EAAE;AAAA,EAC3C;AACA,QAAM,gBAAgB,iBAAiB;AACvC,QAAM,cAAc,uBAAuB,GAAG,MAAM;AACpD,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,MAAM,SAAiC,CAAC,CAAC;AAC7F,QAAM,UAAU,MAAM;AACpB,UAAM,aAAa,IAAI,gBAAgB;AACvC,QAAI,YAAY;AAChB,SAAK,4BAA4B,IAAI,EAAE,UAAU,KAAK,aAAa,QAAQ,WAAW,OAAO,CAAC,EAC3F,KAAK,CAAC,UAAU;AACf,UAAI,CAAC,UAAW,uBAAsB,kCAAkC,KAAK,CAAC;AAAA,IAChF,CAAC,EACA,MAAM,MAAM;AACX,UAAI,CAAC,UAAW,uBAAsB,CAAC,CAAC;AAAA,IAC1C,CAAC;AACH,WAAO,MAAM;AACX,kBAAY;AACZ,iBAAW,MAAM;AAAA,IACnB;AAAA,EACF,GAAG,CAAC,aAAa,YAAY,CAAC;AAC9B,QAAM,6BAA6B,MAAM;AAAA,IACvC,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA,EAAE,iCAAiC,cAAc;AAAA,IACnD;AAAA,IACA,CAAC,eAAe,oBAAoB,CAAC;AAAA,EACvC;AACA,QAAM,yBAAyB,MAAM,YAAY,OAAO,UAAoD;AAC1G,UAAM,QAAQ,MAAM,4BAA4B,SAAS,IAAI,EAAE,UAAU,KAAK,YAAY,CAAC;AAC3F,WAAO,kCAAkC,KAAK;AAAA,EAChD,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,cAAc,MAAM,QAAQ,MAAM;AACtC,UAAM,SAAS,IAAI,gBAAgB;AACnC,WAAO,IAAI,QAAQ,OAAO,IAAI,CAAC;AAC/B,WAAO,IAAI,YAAY,OAAO,QAAQ,CAAC;AACvC,iCAA6B,QAAQ,OAAO;AAC5C,QAAI,OAAO,KAAK,EAAG,QAAO,IAAI,UAAU,OAAO,KAAK,CAAC;AACrD,UAAM,iBAAiB,cAAc,mBAAmB;AACxD,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,cAAc,GAAG;AACvD,aAAO,IAAI,KAAK,GAAG;AAAA,IACrB;AACA,WAAO,OAAO,SAAS;AAAA,EACzB,GAAG,CAAC,qBAAqB,MAAM,UAAU,QAAQ,OAAO,CAAC;AAEzD,QAAM,gBAAgB,MAAM,QAAQ,MAAM,OAAO,YAAY,IAAI,gBAAgB,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC;AAM7G,QAAM,WAAW,MAAM,OAAO,cAAc,SAAS,KAAK,EAAE;AAC5D,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,SAAU;AACf,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,OAAO,KAAK,EAAE,OAAQ,QAAO,IAAI,UAAU,OAAO,KAAK,CAAC;AAC5D,QAAI,OAAO,EAAG,QAAO,IAAI,QAAQ,OAAO,IAAI,CAAC;AAC7C,iCAA6B,QAAQ,OAAO;AAC5C,UAAM,iBAAiB,cAAc,mBAAmB;AACxD,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,cAAc,GAAG;AACvD,aAAO,IAAI,KAAK,GAAG;AAAA,IACrB;AACA,UAAM,OAAO,OAAO,SAAS;AAC7B,QAAI,SAAS,YAAY,KAAM;AAC/B,aAAS,UAAU;AACnB,WAAO,QAAQ,OAAO,GAAG,QAAQ,IAAI,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,CAAC;AAAA,EAC3E,GAAG,CAAC,UAAU,QAAQ,MAAM,QAAQ,SAAS,mBAAmB,CAAC;AAEjE,QAAM,eAAe,MAAM,QAAQ,OAAO;AAAA,IACxC,MAAM;AAAA,MACJ,QAAQ,CAAC,WACP,mBAAmB,uBAAuB,EAAE,GAAG,eAAe,aAAa,OAAO,GAAG,MAAM;AAAA,IAC/F;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ,CAAC,WACP,mBAAmB,uBAAuB,EAAE,GAAG,eAAe,aAAa,QAAQ,KAAK,OAAO,GAAG,MAAM;AAAA,IAC5G;AAAA,EACF,IAAI,CAAC,aAAa,CAAC;AAEnB,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY;AAChB,mBAAe,OAAO;AACpB,mBAAa,IAAI;AACjB,qBAAe,IAAI;AACnB,UAAI;AACF,cAAM,OAAO,MAAM,QAA2B,4BAA4B,WAAW,EAAE;AACvF,YAAI,CAAC,KAAK,IAAI;AACZ,gBAAM,eAAe,KAAK;AAC1B,gBAAM,UAAU,OAAO,cAAc,UAAU,WAAW,aAAa,QAAQ,EAAE,qCAAqC;AACtH,gBAAM,SAAS,OAAO;AACtB,cAAI,CAAC,UAAW,gBAAe,IAAI;AACnC;AAAA,QACF;AACA,cAAM,UAAU,KAAK,UAAU,CAAC;AAChC,YAAI,UAAW;AACf,uBAAe,KAAK,eAAe,IAAI;AACvC,cAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK,IAAI,QAAQ,QAAQ,CAAC;AAC9D,gBAAQ,MAAM,IAAI,CAAC,SAAS,WAAW,IAA+B,CAAC,EAAE,OAAO,CAAC,QAA2B,CAAC,CAAC,GAAG,CAAC;AAClH,iBAAS,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,MAAM,MAAM;AACzE,sBAAc,OAAO,QAAQ,eAAe,WAAW,QAAQ,aAAa,CAAC;AAC7E,yBAAiB,SAAS,kBAAkB,IAAI;AAAA,MAClD,SAAS,KAAK;AACZ,YAAI,CAAC,WAAW;AACd,yBAAe,IAAI;AACnB,gBAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,EAAE,qCAAqC;AAC5F,gBAAM,SAAS,OAAO;AAAA,QACxB;AAAA,MACF,UAAE;AACA,YAAI,CAAC,UAAW,cAAa,KAAK;AAAA,MACpC;AAAA,IACF;AACA,SAAK;AACL,WAAO,MAAM;AAAE,kBAAY;AAAA,IAAK;AAAA,EAClC,GAAG,CAAC,aAAa,aAAa,cAAc,CAAC,CAAC;AAE9C,QAAM,gBAAgB,MAAM,YAAY,MAAM;AAC5C,mBAAe,CAAC,UAAU,QAAQ,CAAC;AAAA,EACrC,GAAG,CAAC,CAAC;AAEL,QAAM,eAAe,MAAM,YAAY,OAAO,YAAwB;AACpE,QAAI,CAAC,SAAS,GAAI;AAClB,UAAM,OAAO,QAAQ,QAAQ,EAAE,6CAA6C;AAC5E,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,EAAE,0CAA0C,QAAW,EAAE,KAAK,CAAC;AAAA,MACtE,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,UAAW;AAChB,QAAI;AACF,YAAM,kBAAkB;AAAA,QACtB,WAAW,YAAY;AAErB,gBAAM;AAAA,YACJ,+BAA+B,mBAAmB,QAAQ,EAAE,CAAC;AAAA,YAC7D;AAAA,cACE,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAChD;AAAA,YACA,EAAE,cAAc,EAAE,sCAAsC,EAAE;AAAA,UAC5D;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,YAAY,QAAQ;AAAA,UACpB,mBAAmB;AAAA,QACrB;AAAA,MACF,CAAC;AACD,cAAQ,CAAC,SAAS,KAAK,OAAO,CAAC,QAAQ,IAAI,OAAO,QAAQ,EAAE,CAAC;AAC7D,eAAS,CAAC,SAAS,KAAK,IAAI,OAAO,GAAG,CAAC,CAAC;AACxC,oBAAc;AACd,YAAM,EAAE,wCAAwC,GAAG,SAAS;AAAA,IAC9D,SAAS,KAAK;AACZ,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,EAAE,sCAAsC;AAC7F,YAAM,SAAS,OAAO;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,SAAS,eAAe,qBAAqB,mBAAmB,yBAAyB,CAAC,CAAC;AAE/F,QAAM,mBAAmB,MAAM,YAAY,OAAO,iBAA+B;AAC/E,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,EAAE,6CAA6C,6BAA6B,EAAE,OAAO,aAAa,OAAO,CAAC;AAAA,MACjH,aAAa,EAAE,mDAAmD,+BAA+B;AAAA,MACjG,SAAS;AAAA,IACX,CAAC;AACD,QAAI,CAAC,UAAW,QAAO;AAEvB,UAAM,EAAE,WAAW,SAAS,IAAI,MAAM,gBAAgB;AAAA,MACpD,WAAW,YACT;AAAA,QACE;AAAA,QACA,OAAO,QAAQ;AAEb,gBAAM,eAAe,+BAA+B,mBAAmB,IAAI,EAAE,CAAC,IAAI;AAAA,YAChF,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAChD,CAAC;AAAA,QACH;AAAA,QACA;AAAA,UACE,sBAAsB,EAAE,wCAAwC,2BAA2B;AAAA,UAC3F,QAAQ;AAAA,UACR,UAAU;AAAA,YACR,SAAS;AAAA,YACT,MAAM,EAAE,oDAAoD,2BAA2B;AAAA,YACvF,aAAa;AAAA,cACX;AAAA,cACA;AAAA,cACA,EAAE,OAAO,aAAa,OAAO;AAAA,YAC/B;AAAA,YACA,MAAM,EAAE,QAAQ,2BAA2B;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAAA,MACF,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,mBAAmB;AAAA,MACrB;AAAA,IACF,CAAC;AAED,QAAI,UAAU,SAAS,GAAG;AACxB,YAAM,eAAe,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AACvD,cAAQ,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC,CAAC;AAC7D,eAAS,CAAC,SAAS,KAAK,IAAI,GAAG,OAAO,UAAU,MAAM,CAAC;AACvD,qBAAe,CAAC,SAAS,OAAO,CAAC;AACjC,UAAI,UAAU,SAAS,GAAG;AACxB,+BAAuB,UAAU,QAAQ;AAAA,UACvC,WAAW;AAAA,UACX,aAAa,EAAE,sDAAsD,4BAA4B,EAAE,OAAO,UAAU,OAAO,CAAC;AAAA,UAC5H,cAAc;AAAA,QAChB,CAAC;AAAA,MACH;AACA,UAAI,SAAS,WAAW,GAAG;AACzB;AAAA,UACE,EAAE,+CAA+C,6BAA6B,EAAE,OAAO,UAAU,OAAO,CAAC;AAAA,UACzG;AAAA,QACF;AAAA,MACF,OAAO;AACL;AAAA,UACE,EAAE,+CAA+C,2DAA2D;AAAA,YAC1G,SAAS,UAAU;AAAA,YACnB,OAAO,aAAa;AAAA,YACpB,QAAQ,SAAS;AAAA,UACnB,CAAC;AAAA,UACD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,eAAW,SAAS,wBAAwB,QAAQ,GAAG;AACrD,YAAM,UAAU,MAAM,UAAU,IAC5B,MAAM,gBACN;AAAA,QACE;AAAA,QACA;AAAA,QACA,EAAE,OAAO,MAAM,OAAO,SAAS,MAAM,cAAc;AAAA,MACrD;AACJ,YAAM,SAAS,OAAO;AAAA,IACxB;AAEA,WAAO,UAAU,SAAS;AAAA,EAC5B,GAAG,CAAC,uBAAuB,SAAS,mBAAmB,iBAAiB,CAAC,CAAC;AAE1E,QAAM,UAAU,MAAM,QAAiC,MAAM;AAC3D,UAAM,UAAU,oBAAC,UAAK,WAAU,iCAAiC,YAAE,kCAAkC,GAAE;AACvG,UAAM,uBAAuB,CAAC,MAAyB,aACrD;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,KAAK,eAAe,IAAI;AAAA,QACxB,UAAU,WAAW,oBAAC,UAAM,oBAAS,IAAU;AAAA,QAC/C,WAAU;AAAA,QACV,sBAAqB;AAAA,QACrB,eAAc;AAAA,QACd,gBAAe;AAAA;AAAA,IACjB;AAGF,UAAM,wBAAwB,CAAC,UAAmB;AAChD,UAAI,SAAS,KAAM,QAAO;AAC1B,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,cAAM,aAAa;AAAA,UACjB,MAAM,IAAI,CAAC,SAAS;AAClB,gBAAI,QAAQ,KAAM,QAAO;AACzB,gBAAI,OAAO,SAAS,SAAU,QAAO;AACrC,mBAAO,OAAO,IAAI;AAAA,UACpB,CAAC;AAAA,QACH;AACA,YAAI,CAAC,WAAW,OAAQ,QAAO;AAC/B,eAAO,oBAAC,yBAAsB,QAAQ,YAAY,YAAY,GAAG;AAAA,MACnE;AACA,UAAI,OAAO,UAAU,WAAW;AAC9B,eACE,oBAAC,UAAK,WAAU,WACb,kBACG,EAAE,uCAAuC,KAAK,IAC9C,EAAE,sCAAsC,IAAI,GAClD;AAAA,MAEJ;AACA,YAAM,cAAc,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI,OAAO,KAAK;AAC3E,UAAI,CAAC,YAAa,QAAO;AACzB,aAAO,oBAAC,UAAK,WAAU,WAAW,uBAAY;AAAA,IAChD;AAEA,UAAM,cAAuC;AAAA,MAC3C;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,uCAAuC;AAAA,QACjD,MAAM;AAAA,UACJ,eAAe;AAAA,UACf,oBAAoB,EAAE,oCAAoC,YAAY;AAAA,UACtE,WAAW;AAAA,UACX,aAAa,EAAE,8BAA8B,KAAK;AAAA,UAClD,UAAU;AAAA,QACZ;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MACX,oBAAC,QAAK,MAAM,mCAAmC,IAAI,SAAS,EAAE,IAAI,WAAU,+BACzE,cAAI,SAAS,MAChB;AAAA,MAEJ;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,wCAAwC;AAAA,QAClD,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,UAC1D,gBAAgB;AAAA,UAChB,UAAU;AAAA,QACZ;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,SAAS;AAAA,MAC3C;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,sDAAsD,eAAe;AAAA,QAC/E,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,UAC1D,gBAAgB;AAAA,UAChB,UAAU;AAAA,QACZ;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,SAAS;AAAA,MAC3C;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,yCAAyC;AAAA,QACnD,MAAM;AAAA,UACJ,YAAY;AAAA,UACZ,eAAe,kBAAkB;AAAA,UACjC,oBAAoB,EAAE,oCAAoC,YAAY;AAAA,UACtE,aAAa,EAAE,8BAA8B,KAAK;AAAA,QACpD;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,qBAAqB,YAAY,IAAI,SAAS,MAAM;AAAA,MACzE;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,iDAAiD;AAAA,QAC3D,MAAM;AAAA,UACJ,YAAY;AAAA,UACZ,eAAe,kBAAkB;AAAA,UACjC,oBAAoB,EAAE,oCAAoC,YAAY;AAAA,UACtE,WAAW;AAAA,UACX,aAAa,EAAE,8BAA8B,KAAK;AAAA,QACpD;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,qBAAqB,oBAAoB,IAAI,SAAS,cAAc;AAAA,MACzF;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,kDAAkD;AAAA,QAC5D,MAAM;AAAA,UACJ,oBAAoB,EAAE,gCAAgC,OAAO;AAAA,UAC7D,WAAW;AAAA,UACX,aAAa,EAAE,mCAAmC,UAAU;AAAA,UAC5D,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MACX,IAAI,SAAS,oBAET,qBAAC,SAAI,WAAU,kCACZ;AAAA,cAAI,SAAS,sBACZ,oBAAC,UAAK,WAAU,+FACb,+BAAqB,IAAI,SAAS,qBAAqB,SAAS,GACnE,IACE;AAAA,UACJ,qBAAC,SAAI,WAAU,iBACb;AAAA,gCAAC,UAAM,qBAAW,IAAI,SAAS,mBAAmB,EAAE,kCAAkC,CAAC,GAAE;AAAA,YACxF,IAAI,SAAS,sBACZ,oBAAC,UAAK,WAAU,iCAAiC,cAAI,SAAS,qBAAoB,IAChF;AAAA,aACN;AAAA,UACC,IAAI,SAAS,uBACZ,oBAAC,UAAK,WAAU,QACb,gCAAsB,IAAI,SAAS,sBAAsB,2CAA2C,GACvG,IACE;AAAA,WACN,IAEA;AAAA,MACR;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,yCAAyC;AAAA,QACnD,MAAM;AAAA,UACJ,YAAY;AAAA,UACZ,eAAe,kBAAkB;AAAA,UACjC,oBAAoB,EAAE,oCAAoC,YAAY;AAAA,UACtE,aAAa,EAAE,8BAA8B,KAAK;AAAA,QACpD;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,qBAAqB,WAAW,IAAI,SAAS,MAAM;AAAA,MACxE;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,0CAA0C,OAAO;AAAA,QAC3D,MAAM;AAAA,UACJ,oBAAoB,EAAE,8BAA8B,KAAK;AAAA,UACzD,YAAY;AAAA,UACZ,eAAe;AAAA,UACf,mBAAmB;AAAA,UACnB,aAAa,EAAE,8BAA8B,KAAK;AAAA,UAClD,gBAAgB;AAAA,UAChB,WAAW;AAAA,UACX,QAAQ;AAAA,QACV;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,eAAe;AAAA,MACjD;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,+CAA+C,YAAY;AAAA,QACrE,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,QAC5D;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,aAAa;AAAA,MAC/C;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,+CAA+C,YAAY;AAAA,QACrE,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,QAC5D;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,aAAa;AAAA,MAC/C;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,4CAA4C,QAAQ;AAAA,QAC9D,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,QAC5D;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,UAAU;AAAA,MAC5C;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,6CAA6C,SAAS;AAAA,QAChE,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,QAC5D;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,cAAc;AAAA,MAChD;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,8CAA8C,UAAU;AAAA,QAClE,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,QAC5D;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,YAAY;AAAA,MAC9C;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,gDAAgD,cAAc;AAAA,QACxE,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,kCAAkC,SAAS;AAAA,QAC5D;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,cAAc;AAAA,MAChD;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,uDAAuD,gBAAgB;AAAA,QACjF,MAAM;AAAA,UACJ,oBAAoB,EAAE,kCAAkC,SAAS;AAAA,UACjE,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,YAAY;AAAA,UACZ,aAAa,EAAE,kCAAkC,SAAS;AAAA,QAC5D;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,iBAAiB;AAAA,MACnD;AAAA,MACA;AAAA,QACE,aAAa;AAAA,QACb,QAAQ,EAAE,iDAAiD,aAAa;AAAA,QACxE,MAAM;AAAA,UACJ,oBAAoB,EAAE,gCAAgC,OAAO;AAAA,UAC7D,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,aAAa,EAAE,gCAAgC,OAAO;AAAA,QACxD;AAAA,QACA,MAAM,CAAC,EAAE,IAAI,MAAM,IAAI,SAAS,eAAe;AAAA,MACjD;AAAA,IACF;AAEA,UAAM,gBAAgB,gBACnB,OAAO,CAAC,QAAQ,0BAA0B,GAAG,CAAC,EAC9C,IAA2B,CAAC,SAAS;AAAA,MACpC,aAAa,MAAM,IAAI,GAAG;AAAA,MAC1B,QAAQ,IAAI,SAAS,IAAI;AAAA,MACzB,eAAe;AAAA,MACf,MAAM;AAAA,QACJ,oBAAoB,IAAI,OAAO,SAAS,EAAE,sCAAsC,eAAe;AAAA,QAC/F,aAAa,IAAI,OAAO,SAAS,EAAE,sCAAsC,eAAe;AAAA,QACxF,YAAY,+BAA+B,IAAI,IAAI;AAAA,QACnD,eAAe,kCAAkC,IAAI,OAAO;AAAA,QAC5D,QAAQ,IAAI,gBAAgB;AAAA,QAC5B,UAAU;AAAA,MACZ;AAAA,MACA,MAAM,CAAC,EAAE,SAAS,MAAM,sBAAsB,SAAS,CAAC;AAAA,IAC1D,EAAE;AAEJ,WAAO,CAAC,GAAG,aAAa,GAAG,aAAa;AAAA,EAC1C,GAAG,CAAC,iBAAiB,gBAAgB,mBAAmB,wBAAwB,4BAA4B,CAAC,CAAC;AAE9G,QAAM,EAAE,qBAAqB,IAAI,wBAAwB,EAAE,SAAS,gBAAgB,CAAC;AAQrF,QAAM,UAAU,MAAM;AACpB,mBAAe,CAAC,SAAS;AACvB,UAAI,SAAS,qBAAsB,QAAO;AAC1C,UAAI,KAAK,WAAW,qBAAqB,QAAQ;AAC/C,YAAI,OAAO;AACX,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,cAAI,KAAK,CAAC,EAAE,QAAQ,qBAAqB,CAAC,EAAE,KAAK;AAAE,mBAAO;AAAO;AAAA,UAAM;AAAA,QACzE;AACA,YAAI,KAAM,QAAO;AAAA,MACnB;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAC,oBAAoB,CAAC;AAEzB,QAAM,mBAAmB,MAAM,QAAwB,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvF,SACE,qBAAC,QACC;AAAA,yBAAC,YACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,mBAAiB;AAAA,UACjB,qBAAmB;AAAA,UACnB,OAAO,EAAE,gCAAgC;AAAA,UACzC,mBAAmB;AAAA,UACnB,eAAe;AAAA,YACb,OAAO,EAAE,0CAA0C;AAAA,YACnD,WAAW,MAAM;AAAE,wBAAU,EAAE;AAAG,sBAAQ,CAAC;AAAG,4BAAc;AAAA,YAAE;AAAA,UAChE;AAAA,UACA,SACE,oBAAC,UAAO,SAAO,MACb,8BAAC,QAAK,MAAK,uCACR,YAAE,sCAAsC,GAC3C,GACF;AAAA,UAEF;AAAA,UACA,eAAe,EAAE,MAAM,KAAK;AAAA,UAC5B,MAAM;AAAA,UACN,UAAU;AAAA,UACV,aAAa;AAAA,UACb,gBAAgB,CAAC,UAAU;AAAE,sBAAU,KAAK;AAAG,oBAAQ,CAAC;AAAA,UAAE;AAAA,UAC1D,mBAAmB,EAAE,4CAA4C;AAAA,UACjE,WAAW,CAAC,EAAE,UAAU,iBAAiB,EAAE,UAAU,wBAAwB;AAAA,UAC7E,YAAY,CAAC,QAAQ,OAAO,KAAK,mCAAmC,IAAI,EAAE,EAAE;AAAA,UAC5E,aAAa,EAAE,SAAS,gBAAgB,MAAM,eAAe,QAAQ;AAAA,UACrE,UAAQ;AAAA,UACR,eAAa;AAAA,UACb;AAAA,UACA,iBAAiB;AAAA,UACjB,aAAa;AAAA,YACX;AAAA,cACE,IAAI;AAAA,cACJ,OAAO,EAAE,+CAA+C,iBAAiB;AAAA,cACzE,aAAa;AAAA,cACb,WAAW;AAAA,YACb;AAAA,UACF;AAAA,UACA,YAAY,CAAC,QACX;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,gBACL;AAAA,kBACE,IAAI;AAAA,kBACJ,OAAO,EAAE,uCAAuC;AAAA,kBAChD,UAAU,MAAM;AAAE,2BAAO,KAAK,mCAAmC,IAAI,EAAE,EAAE;AAAA,kBAAE;AAAA,gBAC7E;AAAA,gBACA;AAAA,kBACE,IAAI;AAAA,kBACJ,OAAO,EAAE,+CAA+C;AAAA,kBACxD,UAAU,MAAM,OAAO,KAAK,mCAAmC,IAAI,EAAE,IAAI,UAAU,UAAU;AAAA,gBAC/F;AAAA,gBACA;AAAA,kBACE,IAAI;AAAA,kBACJ,OAAO,EAAE,yCAAyC;AAAA,kBAClD,aAAa;AAAA,kBACb,UAAU,MAAM,aAAa,GAAG;AAAA,gBAClC;AAAA,cACF;AAAA;AAAA,UACF;AAAA,UAEF,gBAAgB;AAAA,YACd,MAAM;AAAA,YACN,OAAO,YAAY;AAAA,YACnB,UAAU,YAAY;AAAA,YACtB,SAAS,MAAM,YAAY,MAAM;AAAA,YACjC,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,iBAAiB;AAAA,YACjB,gBAAgB,MAAM,eAAe,CAAC,SAAS,CAAC,IAAI;AAAA,YACpD,aAAa,CAAC,SAAS;AACrB,0BAAY,YAAY,IAAI;AAC5B,sBAAQ,CAAC;AAAA,YACX;AAAA,UACF;AAAA,UACA,mBACE;AAAA,YAAC;AAAA;AAAA,cACC,MAAM,YAAY;AAAA,cAClB,QAAQ;AAAA,cACR,aAAa;AAAA,cACb,cAAc,CAAC,OAAO,YAAY,SAAS,EAAE,MAAM,cAAc,QAAQ,GAAG,CAAC;AAAA,cAC7E,QAAQ,MAAM,eAAe,IAAI;AAAA;AAAA,UACnC;AAAA,UAEF,uBAAuB;AAAA,YACrB,QAAQ,oBAAoB,KAAK,SAAS,SAAS;AAAA,YACnD,kBAAkB,EAAE,oCAAoC,WAAW;AAAA,YACnE,eAAe,YAAY,KAAK,KAAK,SAAS,SAAS;AAAA,YACvD,YAAY;AAAA,YACZ,cAAc,MAAM,YAAY,SAAS,EAAE,MAAM,aAAa,CAAC;AAAA,UACjE;AAAA,UACA,YACE;AAAA,YAAC;AAAA;AAAA,cACC,YAAY,EAAE,oCAAoC,WAAW;AAAA,cAC7D,YAAW;AAAA,cACX,aAAa,EAAE,sCAAsC;AAAA;AAAA,UACvD;AAAA,UAEF,aAAW;AAAA,UACX,YAAY,EAAE,MAAM,UAAU,OAAO,YAAY,eAAe,cAAc,SAAS,iBAAiB,CAAC,IAAI,IAAI,IAAI,GAAG,GAAG,kBAAkB,sBAAsB,YAAY;AAAA,UAC/K;AAAA;AAAA,MACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,OAAO,YAAY;AAAA,UACnB,UAAU,YAAY;AAAA,UACtB,SAAS,YAAY;AAAA,UACrB,SAAS;AAAA,UACT,SAAS,YAAY;AAAA,UACrB,eAAe,YAAY;AAAA,UAC3B,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,MAAM;AAAA,UACN,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,uBAAsB;AAAA;AAAA,MACxB;AAAA,OACF;AAAA,IACC;AAAA,KACH;AAEJ;",
6
6
  "names": []
7
7
  }