{"version":3,"file":"tin-spa.mjs","sources":["../../../projects/tin-spa/src/lib/services/tin-spa.service.ts","../../../projects/tin-spa/src/lib/classes/DateBounds.ts","../../../projects/tin-spa/src/lib/classes/TinCore.ts","../../../projects/tin-spa/src/lib/classes/LibClasses.ts","../../../projects/tin-spa/src/lib/classes/Classes.ts","../../../projects/tin-spa/src/lib/services/storage.service.ts","../../../projects/tin-spa/src/lib/services/http.service.ts","../../../projects/tin-spa/src/lib/pages/accounting/receipts/receipt-dialog.component.ts","../../../projects/tin-spa/src/lib/services/general.service.ts","../../../projects/tin-spa/src/lib/services/inventory.service.ts","../../../projects/tin-spa/src/lib/services/accounting.service.ts","../../../projects/tin-spa/src/lib/services/sales.service.ts","../../../projects/tin-spa/src/lib/services/purchasing.service.ts","../../../projects/tin-spa/src/lib/services/production.service.ts","../../../projects/tin-spa/src/lib/services/payroll.service.ts","../../../projects/tin-spa/src/lib/services/loans.service.ts","../../../projects/tin-spa/src/lib/runtime/silent-request.ts","../../../projects/tin-spa/src/lib/runtime/appsettings.ts","../../../projects/tin-spa/src/lib/runtime/tinspa-runtime.ts","../../../projects/tin-spa/src/lib/services/api-error.service.ts","../../../projects/tin-spa/src/lib/services/signalr.service.ts","../../../projects/tin-spa/src/lib/services/offline.service.ts","../../../projects/tin-spa/src/lib/services/log.service.ts","../../../projects/tin-spa/src/lib/services/auth.service.ts","../../../projects/tin-spa/src/lib/services/datalib.service.ts","../../../projects/tin-spa/src/lib/components/message/messageDialog.component.ts","../../../projects/tin-spa/src/lib/components/message/messageDialog.component.html","../../../projects/tin-spa/src/lib/services/message.service.ts","../../../projects/tin-spa/src/lib/services/export.service.ts","../../../projects/tin-spa/src/lib/services/loader.service.ts","../../../projects/tin-spa/src/lib/services/dialog-component.token.ts","../../../projects/tin-spa/src/lib/services/document.service.ts","../../../projects/tin-spa/src/lib/components/document-viewer/documentViewerDialog.component.ts","../../../projects/tin-spa/src/lib/components/document-viewer/documentViewerDialog.component.html","../../../projects/tin-spa/src/lib/services/dialog.service.ts","../../../projects/tin-spa/src/lib/services/assets.service.ts","../../../projects/tin-spa/src/lib/runtime/quiet-loading.ts","../../../projects/tin-spa/src/lib/services/button.service.ts","../../../projects/tin-spa/src/lib/services/table-config.service.ts","../../../projects/tin-spa/src/lib/services/tab.service.ts","../../../projects/tin-spa/src/lib/services/subscription.service.ts","../../../projects/tin-spa/src/lib/components/update-prompt/update-prompt.component.ts","../../../projects/tin-spa/src/lib/components/update-prompt/update-prompt.component.html","../../../projects/tin-spa/src/lib/services/update.service.ts","../../../projects/tin-spa/src/lib/services/push-notification.service.ts","../../../projects/tin-spa/src/lib/services/notifications.service.ts","../../../projects/tin-spa/src/lib/services/agent.service.ts","../../../projects/tin-spa/src/lib/services/analytics.service.ts","../../../projects/tin-spa/src/lib/services/setup.service.ts","../../../projects/tin-spa/src/lib/services/config.service.ts","../../../projects/tin-spa/src/lib/services/last-route.service.ts","../../../projects/tin-spa/src/lib/services/tenant-transfer.service.ts","../../../projects/tin-spa/src/lib/services/password-policy.service.ts","../../../projects/tin-spa/src/lib/runtime/field-load-indicator.ts","../../../projects/tin-spa/src/lib/runtime/field-placeholder.ts","../../../projects/tin-spa/src/lib/components/suffix/suffix.component.ts","../../../projects/tin-spa/src/lib/components/suffix/suffix.component.html","../../../projects/tin-spa/src/lib/components/select-multi/select-multi.component.ts","../../../projects/tin-spa/src/lib/components/select-multi/select-multi.component.html","../../../projects/tin-spa/src/lib/components/checklist/checklist.component.ts","../../../projects/tin-spa/src/lib/components/checklist/checklist.component.html","../../../projects/tin-spa/src/lib/pages/setup-guide/setup-guide.component.ts","../../../projects/tin-spa/src/lib/pages/setup-guide/setup-guide.component.html","../../../projects/tin-spa/src/lib/services/row-order.service.ts","../../../projects/tin-spa/src/lib/classes/perceived-progress.ts","../../../projects/tin-spa/src/lib/services/condition.service.ts","../../../projects/tin-spa/src/lib/components/filter/filter.component.ts","../../../projects/tin-spa/src/lib/components/filter/filter.component.html","../../../projects/tin-spa/src/lib/components/text/text.component.ts","../../../projects/tin-spa/src/lib/components/text/text.component.html","../../../projects/tin-spa/src/lib/components/text-single/text-single.component.ts","../../../projects/tin-spa/src/lib/components/text-single/text-single.component.html","../../../projects/tin-spa/src/lib/components/date/date.component.ts","../../../projects/tin-spa/src/lib/components/date/date.component.html","../../../projects/tin-spa/src/lib/components/select-common/select-common.component.ts","../../../projects/tin-spa/src/lib/components/select-common/select-common.component.html","../../../projects/tin-spa/src/lib/components/select-lite/select-lite.component.ts","../../../projects/tin-spa/src/lib/components/select-lite/select-lite.component.html","../../../projects/tin-spa/src/lib/components/text-multi/text-multi.component.ts","../../../projects/tin-spa/src/lib/components/text-multi/text-multi.component.html","../../../projects/tin-spa/src/lib/components/editor/editor.component.ts","../../../projects/tin-spa/src/lib/components/editor/editor.component.html","../../../projects/tin-spa/src/lib/components/option/option.component.ts","../../../projects/tin-spa/src/lib/components/option/option.component.html","../../../projects/tin-spa/src/lib/pipes/camelToWords.pipe.ts","../../../projects/tin-spa/src/lib/components/search/search.component.ts","../../../projects/tin-spa/src/lib/components/search/search.component.html","../../../projects/tin-spa/src/lib/services/csv.service.ts","../../../projects/tin-spa/src/lib/directives/ellipsis.directive.ts","../../../projects/tin-spa/src/lib/components/tiles/tiles.component.ts","../../../projects/tin-spa/src/lib/components/tiles/tiles.component.html","../../../projects/tin-spa/src/lib/components/filter-chips/filter-chips.component.ts","../../../projects/tin-spa/src/lib/components/filter-chips/filter-chips.component.html","../../../projects/tin-spa/src/lib/components/table-header/table-header.component.ts","../../../projects/tin-spa/src/lib/components/table-header/table-header.component.html","../../../projects/tin-spa/src/lib/components/check/check.component.ts","../../../projects/tin-spa/src/lib/components/check/check.component.html","../../../projects/tin-spa/src/lib/components/monogram/monogram.component.ts","../../../projects/tin-spa/src/lib/components/monogram/monogram.component.html","../../../projects/tin-spa/src/lib/components/table-row/table-row.component.ts","../../../projects/tin-spa/src/lib/components/table-row/table-row.component.html","../../../projects/tin-spa/src/lib/components/table-action/table-action.component.ts","../../../projects/tin-spa/src/lib/components/table-action/table-action.component.html","../../../projects/tin-spa/src/lib/runtime/email-single.ts","../../../projects/tin-spa/src/lib/components/text-area/text-area.component.ts","../../../projects/tin-spa/src/lib/components/text-area/text-area.component.html","../../../projects/tin-spa/src/lib/components/datetime/datetime.component.ts","../../../projects/tin-spa/src/lib/components/datetime/datetime.component.html","../../../projects/tin-spa/src/lib/components/select/select.component.ts","../../../projects/tin-spa/src/lib/components/select/select.component.html","../../../projects/tin-spa/src/lib/components/money/currency-input-mask.directive.ts","../../../projects/tin-spa/src/lib/components/money/money.component.ts","../../../projects/tin-spa/src/lib/components/money/money.component.html","../../../projects/tin-spa/src/lib/components/number/number.component.ts","../../../projects/tin-spa/src/lib/components/number/number.component.html","../../../projects/tin-spa/src/lib/components/email/email.component.ts","../../../projects/tin-spa/src/lib/components/email/email.component.html","../../../projects/tin-spa/src/lib/components/table/inline-cell.component.ts","../../../projects/tin-spa/src/lib/components/capsules/capsules.component.ts","../../../projects/tin-spa/src/lib/components/capsules/capsules.component.html","../../../projects/tin-spa/src/lib/components/cards/cards.component.ts","../../../projects/tin-spa/src/lib/components/cards/cards.component.html","../../../projects/tin-spa/src/lib/components/groups/groups.component.ts","../../../projects/tin-spa/src/lib/components/groups/groups.component.html","../../../projects/tin-spa/src/lib/components/table/table.component.ts","../../../projects/tin-spa/src/lib/components/table/table.component.html","../../../projects/tin-spa/src/lib/pages/day-book/day-book.component.ts","../../../projects/tin-spa/src/lib/pages/day-book/day-book.component.html","../../../projects/tin-spa/src/lib/components/text-mask/text-mask.component.ts","../../../projects/tin-spa/src/lib/components/text-mask/text-mask.component.html","../../../projects/tin-spa/src/lib/components/label/label.component.ts","../../../projects/tin-spa/src/lib/components/label/label.component.html","../../../projects/tin-spa/src/lib/components/attach/attach.component.ts","../../../projects/tin-spa/src/lib/components/attach/attach.component.html","../../../projects/tin-spa/src/lib/components/document-viewer/document.component.ts","../../../projects/tin-spa/src/lib/components/document-viewer/document.component.html","../../../projects/tin-spa/src/lib/components/html/html.component.ts","../../../projects/tin-spa/src/lib/components/html/html.component.html","../../../projects/tin-spa/src/lib/components/notes/notes.component.ts","../../../projects/tin-spa/src/lib/components/notes/notes.component.html","../../../projects/tin-spa/src/lib/components/form/form.component.ts","../../../projects/tin-spa/src/lib/components/form/form.component.html","../../../projects/tin-spa/src/lib/pages/app-configuration/app-configuration.component.ts","../../../projects/tin-spa/src/lib/pages/app-configuration/app-configuration.component.html","../../../projects/tin-spa/src/lib/pages/password-policy/password-policy.component.ts","../../../projects/tin-spa/src/lib/pages/password-policy/password-policy.component.html","../../../projects/tin-spa/src/lib/pipes/agent-markdown.pipe.ts","../../../projects/tin-spa/src/lib/components/agent/agent.component.ts","../../../projects/tin-spa/src/lib/components/agent/agent.component.html","../../../projects/tin-spa/src/lib/pages/agent-page/agent-page.component.ts","../../../projects/tin-spa/src/lib/pages/agent-page/agent-page.component.html","../../../projects/tin-spa/src/lib/components/offline/offline-indicator.component.ts","../../../projects/tin-spa/src/lib/components/alert/alert.component.ts","../../../projects/tin-spa/src/lib/components/alert/alert.component.html","../../../projects/tin-spa/src/lib/pages/sync/sync.component.ts","../../../projects/tin-spa/src/lib/pages/sync/sync.component.html","../../../projects/tin-spa/src/lib/guards/auth.guard.ts","../../../projects/tin-spa/src/lib/guards/feature.guard.ts","../../../projects/tin-spa/src/lib/guards/module.guard.ts","../../../projects/tin-spa/src/lib/guards/capability.guard.ts","../../../projects/tin-spa/src/lib/directives/feature.directive.ts","../../../projects/tin-spa/src/lib/components/tin-spa.component.ts","../../../projects/tin-spa/src/lib/modules/spa-mat.module.ts","../../../projects/tin-spa/src/lib/components/activity/activity.component.ts","../../../projects/tin-spa/src/lib/components/activity/activity.component.html","../../../projects/tin-spa/src/lib/components/steps/steps.component.ts","../../../projects/tin-spa/src/lib/components/steps/steps.component.html","../../../projects/tin-spa/src/lib/components/progress-ring/progress-ring.component.ts","../../../projects/tin-spa/src/lib/components/progress-ring/progress-ring.component.html","../../../projects/tin-spa/src/lib/components/chips/chips.component.ts","../../../projects/tin-spa/src/lib/components/chips/chips.component.html","../../../projects/tin-spa/src/lib/components/loader/loader.component.ts","../../../projects/tin-spa/src/lib/components/loader/loader.component.html","../../../projects/tin-spa/src/lib/components/terms-dialog/terms-dialog.component.ts","../../../projects/tin-spa/src/lib/components/terms-dialog/terms-dialog.component.html","../../../projects/tin-spa/src/lib/components/privacy-dialog/privacy-dialog.component.ts","../../../projects/tin-spa/src/lib/components/privacy-dialog/privacy-dialog.component.html","../../../projects/tin-spa/src/lib/components/toast/toast.component.ts","../../../projects/tin-spa/src/lib/components/toast/toast.component.html","../../../projects/tin-spa/src/lib/components/bottom-tabs/bottom-tabs.component.ts","../../../projects/tin-spa/src/lib/components/bottom-tabs/bottom-tabs.component.html","../../../projects/tin-spa/src/lib/components/nav-menu/nav-menu.component.ts","../../../projects/tin-spa/src/lib/components/nav-menu/nav-menu.component.html","../../../projects/tin-spa/src/lib/services/loader-interceptor.service.ts","../../../projects/tin-spa/src/lib/components/money/currency-input-mask.module.ts","../../../projects/tin-spa/src/lib/components/form-skeleton/form-skeleton.component.ts","../../../projects/tin-spa/src/lib/components/form-skeleton/form-skeleton.component.html","../../../projects/tin-spa/src/lib/components/tabs/tabs.component.ts","../../../projects/tin-spa/src/lib/components/tabs/tabs.component.html","../../../projects/tin-spa/src/lib/components/statuses/statuses.component.ts","../../../projects/tin-spa/src/lib/components/statuses/statuses.component.html","../../../projects/tin-spa/src/lib/components/tabs/tabsFloat.component.ts","../../../projects/tin-spa/src/lib/components/tabs/tabsFloat.component.html","../../../projects/tin-spa/src/lib/components/table/detailsDialog.component.ts","../../../projects/tin-spa/src/lib/components/table/detailsDialog.component.html","../../../projects/tin-spa/src/lib/classes/MapClasses.ts","../../../projects/tin-spa/src/lib/components/map/map.component.ts","../../../projects/tin-spa/src/lib/components/map/map.component.html","../../../projects/tin-spa/src/lib/components/map/mapDialog.component.ts","../../../projects/tin-spa/src/lib/components/map/mapDialog.component.html","../../../projects/tin-spa/src/lib/components/list-dialog/list-dialog.component.ts","../../../projects/tin-spa/src/lib/components/list-dialog/list-dialog.component.html","../../../projects/tin-spa/src/lib/pages/invitations-table/invitations-table.component.ts","../../../projects/tin-spa/src/lib/pages/invitations-table/invitations-table.component.html","../../../projects/tin-spa/src/lib/components/import/import-dialog.component.ts","../../../projects/tin-spa/src/lib/components/import/import-dialog.component.html","../../../projects/tin-spa/src/lib/components/table-dialog/table-dialog.component.ts","../../../projects/tin-spa/src/lib/components/table-dialog/table-dialog.component.html","../../../projects/tin-spa/src/lib/components/title-actions/title-actions.component.ts","../../../projects/tin-spa/src/lib/components/title-actions/title-actions.component.html","../../../projects/tin-spa/src/lib/components/page/page.component.ts","../../../projects/tin-spa/src/lib/components/page/page.component.html","../../../projects/tin-spa/src/lib/select-context.directive.ts","../../../projects/tin-spa/src/lib/components/select-bitwise/select-bitwise.component.ts","../../../projects/tin-spa/src/lib/components/select-bitwise/select-bitwise.component.html","../../../projects/tin-spa/src/lib/pages/welcome/welcome.component.ts","../../../projects/tin-spa/src/lib/pages/welcome/welcome.component.html","../../../projects/tin-spa/src/lib/components/charts/charts.component.ts","../../../projects/tin-spa/src/lib/components/charts/charts.component.html","../../../projects/tin-spa/src/lib/pages/landing/landing.component.ts","../../../projects/tin-spa/src/lib/pages/landing/landing.component.html","../../../projects/tin-spa/src/lib/tin-spa.module.ts","../../../projects/tin-spa/src/lib/pages/login/login.component.ts","../../../projects/tin-spa/src/lib/pages/login/login.component.html","../../../projects/tin-spa/src/lib/pages/signup/signup.component.ts","../../../projects/tin-spa/src/lib/pages/signup/signup.component.html","../../../projects/tin-spa/src/lib/pages/recover-account/recover-account.component.ts","../../../projects/tin-spa/src/lib/pages/recover-account/recover-account.component.html","../../../projects/tin-spa/src/lib/modules/spa-index.module.ts","../../../projects/tin-spa/src/lib/pages/change-password/change-password.component.ts","../../../projects/tin-spa/src/lib/pages/change-password/change-password.component.html","../../../projects/tin-spa/src/lib/pages/profile/profile.component.ts","../../../projects/tin-spa/src/lib/pages/profile/profile.component.html","../../../projects/tin-spa/src/lib/modules/spa-user.module.ts","../../../projects/tin-spa/src/lib/pages/settings/settings.component.ts","../../../projects/tin-spa/src/lib/pages/settings/settings.component.html","../../../projects/tin-spa/src/lib/pages/logs/logs.component.ts","../../../projects/tin-spa/src/lib/pages/logs/logs.component.html","../../../projects/tin-spa/src/lib/pages/users/users.component.ts","../../../projects/tin-spa/src/lib/pages/users/users.component.html","../../../projects/tin-spa/src/lib/pages/roles/roles.component.ts","../../../projects/tin-spa/src/lib/pages/roles/roles.component.html","../../../projects/tin-spa/src/lib/pages/create-account/create-account.component.ts","../../../projects/tin-spa/src/lib/pages/create-account/create-account.component.html","../../../projects/tin-spa/src/lib/pages/categories/categories.component.ts","../../../projects/tin-spa/src/lib/pages/subcategories/subcategories.component.ts","../../../projects/tin-spa/src/lib/pages/brands/brands.component.ts","../../../projects/tin-spa/src/lib/modules/spa-admin.module.ts","../../../projects/tin-spa/src/lib/modules/index/index-routing.module.ts","../../../projects/tin-spa/src/lib/modules/index/index.module.ts","../../../projects/tin-spa/src/lib/pages/gpt-caches/gpt-caches.component.ts","../../../projects/tin-spa/src/lib/modules/admin/admin.module.ts","../../../projects/tin-spa/src/lib/modules/user/user.module.ts","../../../projects/tin-spa/src/lib/modules/user/user-routing.module.ts","../../../projects/tin-spa/src/lib/modules/admin/admin-routing.module.ts","../../../projects/tin-spa/src/lib/pages/accounting/accounts/accounts.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/aggregates/aggregates.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/aging/aging.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/supplier-aging/supplier-aging.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/transaction-types/transaction-types.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/transactions/transactions.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/invoices/invoices.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/outstanding-invoices/outstanding-invoices.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/reports/reports.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/tax-rates/tax-rates.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/standing-orders/standing-orders.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/currencies/currencies.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/budgets/budgets.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/budget-vs-actual/budget-vs-actual.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/accounting-dashboard/accounting-dashboard.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/invoice-dashboard/invoice-dashboard.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/credit-notes/credit-notes.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/vat-return/vat-return.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/fiscal-periods/fiscal-periods.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/receipts/receipts.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/bank-reconciliation/statement-import-dialog.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/bank-reconciliation/reconcile-dialog.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/bank-reconciliation/bank-reconciliation.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/tenant-transfers/tenant-transfers.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/tenant-transfers/tenant-transfers.component.html","../../../projects/tin-spa/src/lib/pages/accounting/revenue-schedules/revenue-schedule-dialog.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/revenue-schedules/revenue-schedules.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/quotes/quotes.component.ts","../../../projects/tin-spa/src/lib/modules/accounting/accounting-routing.module.ts","../../../projects/tin-spa/src/lib/pages/inventory/products/products.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/inventory-items/inventory-items.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/requisitions/requisitions.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/inventory-adjustments/inventory-adjustments.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/inventory-returns/inventory-returns.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/inventory-transactions/inventory-transactions.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/inventory-dashboard/inventory-dashboard.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/inventory-stock/inventory-stock.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/bundle-products/bundle-products.component.ts","../../../projects/tin-spa/src/lib/pages/inventory/service-items/service-items.component.ts","../../../projects/tin-spa/src/lib/modules/inventory/inventory-routing.module.ts","../../../projects/tin-spa/src/lib/pages/sales/sales-orders/sales-orders.component.ts","../../../projects/tin-spa/src/lib/pages/sales/sales/sales.component.ts","../../../projects/tin-spa/src/lib/pages/sales/sales-dashboard/sales-dashboard.component.ts","../../../projects/tin-spa/src/lib/modules/sales/sales-routing.module.ts","../../../projects/tin-spa/src/lib/pages/purchasing/supplier-purchase-orders/supplier-purchase-orders.component.ts","../../../projects/tin-spa/src/lib/pages/purchasing/inventory-receipts/inventory-receipts.component.ts","../../../projects/tin-spa/src/lib/pages/purchasing/purchasing-dashboard/purchasing-dashboard.component.ts","../../../projects/tin-spa/src/lib/modules/purchasing/purchasing-routing.module.ts","../../../projects/tin-spa/src/lib/pages/employees/employees.component.ts","../../../projects/tin-spa/src/lib/pages/departments/departments.component.ts","../../../projects/tin-spa/src/lib/pages/positions/positions.component.ts","../../../projects/tin-spa/src/lib/pages/grades/grades.component.ts","../../../projects/tin-spa/src/lib/pages/grades/grades.component.html","../../../projects/tin-spa/src/lib/pages/onboarding/onboarding.component.ts","../../../projects/tin-spa/src/lib/pages/onboarding/onboarding.component.html","../../../projects/tin-spa/src/lib/modules/hr/hr-routing.module.ts","../../../projects/tin-spa/src/lib/pages/payroll/salary-structures/salary-structures.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/statutory-deductions/statutory-deductions.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/payroll-runs/payroll-runs.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/commission-configs/commission-configs.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/commission-entries/commission-entries.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/commission-statement/commission-statement.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/salary-advances/salary-advances.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/overtime-entries/overtime-entries.component.ts","../../../projects/tin-spa/src/lib/pages/payroll/payroll-dashboard/payroll-dashboard.component.ts","../../../projects/tin-spa/src/lib/modules/payroll/payroll-routing.module.ts","../../../projects/tin-spa/src/lib/pages/manufacturing/production-recipes/production-recipes.component.ts","../../../projects/tin-spa/src/lib/pages/manufacturing/production-orders/production-orders.component.ts","../../../projects/tin-spa/src/lib/modules/manufacturing/manufacturing-routing.module.ts","../../../projects/tin-spa/src/lib/pages/loans/loan-products/loan-products.component.ts","../../../projects/tin-spa/src/lib/pages/loans/loans/loans.component.ts","../../../projects/tin-spa/src/lib/pages/loans/loan-payments/loan-payments.component.ts","../../../projects/tin-spa/src/lib/modules/loans/loans-routing.module.ts","../../../projects/tin-spa/src/lib/pages/customers/customers.component.ts","../../../projects/tin-spa/src/lib/pages/suppliers/suppliers.component.ts","../../../projects/tin-spa/src/lib/pages/tasks/tasks.component.ts","../../../projects/tin-spa/src/lib/pages/tasks/tasks.component.html","../../../projects/tin-spa/src/lib/modules/general/general-routing.module.ts","../../../projects/tin-spa/src/lib/pages/tenant-settings/tenant-settings.component.ts","../../../projects/tin-spa/src/lib/pages/tenant-settings/tenant-settings.component.html","../../../projects/tin-spa/src/lib/pages/tenants/tenants.component.ts","../../../projects/tin-spa/src/lib/pages/bug/bug.component.ts","../../../projects/tin-spa/src/lib/pages/bug/bug.component.html","../../../projects/tin-spa/src/lib/pages/membership/membership.component.ts","../../../projects/tin-spa/src/lib/pages/plans/plans.component.ts","../../../projects/tin-spa/src/lib/pages/features/features.component.ts","../../../projects/tin-spa/src/lib/pages/plan-features/plan-features.component.ts","../../../projects/tin-spa/src/lib/pages/subscription/subscription.component.ts","../../../projects/tin-spa/src/lib/pages/billing/billing.component.ts","../../../projects/tin-spa/src/lib/modules/tenancy/tenancy-routing.module.ts","../../../projects/tin-spa/src/lib/pages/approvals/approvals.component.ts","../../../projects/tin-spa/src/lib/pages/approvals/approvals.component.html","../../../projects/tin-spa/src/lib/pages/approvals-config/approvals-config.component.ts","../../../projects/tin-spa/src/lib/pages/approvals-config/approvals-config.component.html","../../../projects/tin-spa/src/lib/pages/notifications/notifications.component.ts","../../../projects/tin-spa/src/lib/pages/notifications/notifications.component.html","../../../projects/tin-spa/src/lib/pages/app-models/app-models.component.ts","../../../projects/tin-spa/src/lib/pages/notifications-config/notifications-config.component.ts","../../../projects/tin-spa/src/lib/pages/notifications-config/notifications-config.component.html","../../../projects/tin-spa/src/lib/modules/workflow/workflow-routing.module.ts","../../../projects/tin-spa/src/lib/pages/overview/overview-dashboard/overview-dashboard.component.ts","../../../projects/tin-spa/src/lib/modules/overview/overview-routing.module.ts","../../../projects/tin-spa/src/lib/pages/assets/fixed-assets-dashboard/fixed-assets-dashboard.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/fixed-assets/fixed-assets.component.ts","../../../projects/tin-spa/src/lib/pages/accounting/fixed-asset-categories/fixed-asset-categories.component.ts","../../../projects/tin-spa/src/lib/modules/assets/assets-routing.module.ts","../../../projects/tin-spa/src/lib/pages/no-access/no-access.component.ts","../../../projects/tin-spa/src/lib/pages/no-access/no-access.component.html","../../../projects/tin-spa/src/lib/modules/spa-home-routing.module.ts","../../../projects/tin-spa/src/lib/modules/accounting/accounting.module.ts","../../../projects/tin-spa/src/lib/modules/inventory/inventory.module.ts","../../../projects/tin-spa/src/lib/modules/sales/sales.module.ts","../../../projects/tin-spa/src/lib/modules/purchasing/purchasing.module.ts","../../../projects/tin-spa/src/lib/modules/hr/hr.module.ts","../../../projects/tin-spa/src/lib/modules/payroll/payroll.module.ts","../../../projects/tin-spa/src/lib/modules/manufacturing/manufacturing.module.ts","../../../projects/tin-spa/src/lib/modules/loans/loans.module.ts","../../../projects/tin-spa/src/lib/modules/general/general.module.ts","../../../projects/tin-spa/src/lib/modules/tenancy/tenancy.module.ts","../../../projects/tin-spa/src/lib/modules/workflow/workflow.module.ts","../../../projects/tin-spa/src/lib/modules/overview/overview.module.ts","../../../projects/tin-spa/src/lib/modules/assets/assets.module.ts","../../../projects/tin-spa/src/lib/pages/day-book/day-book.module.ts","../../../projects/tin-spa/src/lib/modules/setup/setup.module.ts","../../../projects/tin-spa/src/lib/modules/spa-home.module.ts","../../../projects/tin-spa/src/lib/classes/DocumentClasses.ts","../../../projects/tin-spa/src/lib/pages/landing/landing.config.ts","../../../projects/tin-spa/src/public-api.ts","../../../projects/tin-spa/src/tin-spa.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class TinSpaService {\n\n  constructor() { }\n}\n","// Added (NFD-1): resolves a Field.min / Field.max bound that is expressed as a DYNAMIC TOKEN rather than a\n// literal date, so a config can say `max: 'today'` and mean \"today at the moment the control is rendered\",\n// never the day the bundle was built. Lives in its own file deliberately: Classes.ts, TinCore.ts and\n// form.component are all held by concurrent workers, and nothing here needs any of them.\n//\n// Accepted forms for a bound:\n//   'today'          — the local calendar day\n//   'today-7'        — 7 local days before today   (offsets in whole days, + or -)\n//   'today+30'       — 30 local days after today\n//   'now'            — the current instant (matches the existing defaultValue: 'now' token, TinCore.ts:535)\n//   () => Date|string — a function, called at resolve time; its result is resolved again by these same rules\n//   anything else    — passed to `new Date()` unchanged, which is the pre-existing behaviour\n//\n// TIMEZONE: every token resolves against the USER'S LOCAL calendar via getFullYear/getMonth/getDate. It\n// deliberately does NOT go through Core.getFormatedDate/nowDate, which add a hard-coded two hours and then\n// call toISOString — that pair shifts the calendar day for anyone not on UTC+2 and would let \"today\" mean\n// tomorrow for part of the evening.\nexport class DateBounds {\n\n  private static readonly TODAY = /^today\\s*([+-]\\s*\\d+)?$/i;\n\n  // `edge` decides which end of the resolved DAY is returned. A max bound must be the END of today or the\n  // picker greys today out along with tomorrow; a min bound must be the START of it.\n  // Changed (SBD-1): returns Date | null, and a FUNCTION bound now receives a `context` argument. That pair is what\n  // lets a config say `min: (row) => ...` and have the bound RE-EVALUATED against the live row every time the picker\n  // opens, instead of being written once as a value that nothing ever re-reads.\n  // 🔴 A null/undefined/empty/unparseable bound now resolves to NULL — \"no bound\" — where it used to produce an\n  // Invalid Date. matDatepicker discards an Invalid Date silently, which made \"this field has no lower bound\" and\n  // \"this field kept the PREVIOUS field's lower bound\" look identical from the outside. That ambiguity is the whole\n  // reason a stage switch could leave a stale window behind (see date.component.refreshBounds).\n  public static resolve(bound: any, edge: 'start' | 'end', context?: any): Date | null {\n    if (bound === null || bound === undefined || bound === '') return null; // Added (SBD-1): an absent bound is \"no bound\", stated explicitly rather than left to Invalid Date\n\n    if (typeof bound === 'function') return this.resolve(bound(context), edge, context); // Changed (SBD-1): the row context reaches the function, and its result is re-resolved by these same rules\n\n    if (typeof bound === 'string') {\n      const token = bound.trim();\n\n      if (token.toLowerCase() === 'now') return new Date();\n\n      const match = this.TODAY.exec(token);\n      if (match) {\n        const offset = match[1] ? parseInt(match[1].replace(/\\s+/g, ''), 10) : 0;\n        const d = new Date();\n        d.setDate(d.getDate() + offset); // local-calendar arithmetic; rolls month/year and survives DST\n        return edge === 'end' ? this.endOfDay(d) : this.startOfDay(d);\n      }\n    }\n\n    const literal = new Date(bound); // literal '2026-01-01', a Date, a number — unchanged from before\n    return isNaN(literal.getTime()) ? null : literal; // Changed (SBD-1): an unparseable bound is \"no bound\", never an Invalid Date handed to the picker\n  }\n\n  // Returns true when the bound is a token this class resolves dynamically, i.e. it must be re-read rather\n  // than snapshotted for the lifetime of a dialog. Callers use it to decide whether to refresh on open.\n  public static isDynamic(bound: any): boolean {\n    if (typeof bound === 'function') return true;\n    if (typeof bound !== 'string') return false;\n    const token = bound.trim();\n    return token.toLowerCase() === 'now' || this.TODAY.test(token);\n  }\n\n  // Formats a resolved bound for a native <input type=\"datetime-local\">, whose min/max attributes require\n  // LOCAL 'YYYY-MM-DDTHH:mm'. toISOString() cannot be used here: it converts to UTC and would move the bound\n  // by the offset, which is the whole bug this class exists to avoid.\n  public static toLocalInput(d: Date): string {\n    const p = (n: number) => `${n}`.padStart(2, '0');\n    return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}T${p(d.getHours())}:${p(d.getMinutes())}`;\n  }\n\n  // Added (DVT-1): the DATE-ONLY sibling of toLocalInput, for a `type:'date'` control whose value format is\n  // 'YYYY-MM-DD'. Same reason toLocalInput exists and toISOString is refused here: toISOString converts to UTC\n  // and can move the value onto the PREVIOUS calendar day for anyone east of Greenwich, which for a midnight-\n  // anchored 'today' default is not a rounding error but the wrong day.\n  public static toLocalDate(d: Date): string {\n    const p = (n: number) => `${n}`.padStart(2, '0');\n    return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n  }\n\n  private static startOfDay(d: Date): Date {\n    const c = new Date(d);\n    c.setHours(0, 0, 0, 0);\n    return c;\n  }\n\n  private static endOfDay(d: Date): Date {\n    const c = new Date(d);\n    c.setHours(23, 59, 59, 999);\n    return c;\n  }\n}\n","import { Action, DetailsDialogConfig, DetailsSource, Field, FormConfig, NoAccessInfo, RoleAccess, SecurityConfig, VisibilityValue } from \"./Classes\"; // Changed: import VisibilityValue for unified visibility resolver; Changed: NoAccessInfo for describeFormAccess\nimport { DateBounds } from \"./DateBounds\"; // Added (DVT-1): one shared token vocabulary — the same class that resolves a 'today' min/max bound now resolves a 'today' defaultValue, so the two cannot drift. DateBounds imports nothing, so this adds no cycle.\n\nexport class Core {\n\n\n  public static deepClone(obj) {\n    if (obj === null || typeof obj !== 'object') {\n      return obj;\n    }\n\n    if (Array.isArray(obj)) {\n      const arrCopy = [];\n      obj.forEach((item, index) => {\n        arrCopy[index] = this.deepClone(item);\n      });\n      return arrCopy;\n    }\n\n    const objCopy = {};\n    Object.keys(obj).forEach(key => {\n      objCopy[key] = this.deepClone(obj[key]);\n    });\n    return objCopy;\n  }\n\n  public static deepClone2(obj: any): any {\n    // Create new WeakMap for each clone operation\n    const cloneVisited = new WeakMap();\n\n    // Inner function that has access to the cloneVisited map\n    const clone = (value: any): any => {\n      // Handle null, undefined and primitives\n      if (value === null || typeof value !== 'object') {\n        return value;\n      }\n\n      // Check if object was already cloned\n      if (cloneVisited.has(value)) {\n        return cloneVisited.get(value);\n      }\n\n      // Handle arrays\n      if (Array.isArray(value)) {\n        const arrCopy = [];\n        cloneVisited.set(value, arrCopy);\n        value.forEach((item, index) => {\n          arrCopy[index] = clone(item);\n        });\n        return arrCopy;\n      }\n\n      // Handle dates\n      if (value instanceof Date) {\n        return new Date(value);\n      }\n\n      // Handle regular objects\n      const objCopy = Object.create(Object.getPrototypeOf(value));\n      cloneVisited.set(value, objCopy);\n\n      Object.entries(value).forEach(([key, val]) => {\n        if (Object.prototype.hasOwnProperty.call(value, key)) {\n          objCopy[key] = clone(val);\n        }\n      });\n\n      return objCopy;\n    };\n\n    // Start the clone operation with a fresh WeakMap\n    return clone(obj);\n  }\n\n\n\n  public static camelToWords(value: string): string {\n    if (!value) return value;\n\n    if (typeof value !== 'string') return value;\n\n    if (value.length == 0) return value;\n\n    let v = value.charAt(0).toUpperCase() + value.substring(1)\n    // Changed: only split at a REAL camelCase boundary — an alphanumeric immediately followed by Capital+lowercase.\n    // The old /([A-Z]+)*([A-Z][a-z])/g inserted a space before EVERY TitleCase run regardless of what preceded it,\n    // so it also fired at position 0 and straight after a space, hyphen or bracket. Every call site is\n    // `field.alias ?? field.name | camelToWords`, which Angular parses as `(alias ?? name) | camelToWords` — so\n    // explicit aliases were being run through the camelCase splitter too. A leading/doubled space is invisible\n    // (HTML collapses whitespace), which is why this went unnoticed, but a space inserted after a non-space\n    // character does NOT collapse: alias 'Check-In Inspection' rendered as 'Check- In Inspection', and\n    // 'Year-To-Date (Net)' as 'Year- To- Date ( Net)'. The lookahead does not consume the preceding character,\n    // so consecutive boundaries still match ('serviceByDate' -> 'Service By Date'; a consuming capture group\n    // yields 'Service ByDate'). Verified against every field name in the config forms: output is identical to\n    // the old behaviour for camelCase names, and only the spurious spaces are gone.\n    return v.replace(/([a-zA-Z0-9])(?=[A-Z][a-z])/g, \"$1 \");\n  }\n\n  public static generateObject(fields: Field[]) {\n\n    let data = {};\n    fields.forEach(field => {\n\n      if (field.type != 'section' && field.type != 'blank' && field.hideOnCreate != true) {\n        data[field.name] = this.getInitialValue(field);\n      }\n\n    });\n\n    // console.log(data)\n\n    return data;\n  }\n\n  public static resetObject(fields: Field[], data) {\n\n    fields.forEach(field => {\n      if (field.type != 'section' && field.type != 'blank') {\n        data[field.name] = this.getInitialValue(field);\n      }\n    });\n\n  }\n\n  public static checkSecurity(security: SecurityConfig, currentRole: any): boolean {\n    if (!security) {\n      return true;\n    }\n\n    if (security.deny?.some(role => currentRole[role.name])) {\n      return false;\n    }\n\n    if (!security.allow || security.allow.length === 0) {\n      return true;\n    }\n\n    return security.allow.some(role => currentRole[role.name]);\n  }\n\n  public static hasFormAccess(formConfig: FormConfig, currentRole: any): boolean {\n    return this.getFormAccess(formConfig, currentRole) > RoleAccess.None;\n  }\n\n  public static getFormAccess(formConfig: FormConfig, currentRole: any): RoleAccess {\n    if (!formConfig?.security?.allow) {\n      return RoleAccess.Full; // Full access if no restrictions\n    }\n\n    // Check deny first\n    if (formConfig.security.deny?.some(role => this.getRoleAccess(currentRole, role.name) > RoleAccess.None)) {\n      return RoleAccess.None;\n    }\n\n    // Get highest level of access from allowed capabilities\n    let maxAccess = RoleAccess.None;\n    formConfig.security.allow.forEach(role => {\n      const access = this.getRoleAccess(currentRole, role.name);\n      if (access > maxAccess) {\n        maxAccess = access;\n      }\n    });\n\n    return maxAccess;\n  }\n\n  // Added: the refusal, NAMED. A denied grid said only \"Access Restricted\", which names neither the page nor the\n  // permission, so a user could not repeat it to an administrator and a support engineer could not act on it.\n  // The information was already in the config — security.allow is a CapItem[] and every CapItem carries name and\n  // display — so nothing is fetched, plumbed or stored to produce it.\n  // Returns null whenever access is NOT refused, INCLUDING the unsecured case, so a caller cannot build a banner\n  // for a config that declares nothing even by mistake. That null is the Arbiter's binding constraint enforced\n  // at the source rather than at the template.\n  public static describeFormAccess(formConfig: FormConfig, currentRole: any): NoAccessInfo | null {\n    if (!formConfig?.security?.allow?.length) return null; // nothing declared = nothing missing = never a banner\n    if (this.hasFormAccess(formConfig, currentRole)) return null; // granted = never a banner\n\n    const allow = formConfig.security.allow;\n    const wanted = allow[0];\n    // Several allowed caps means any ONE of them opens the page, so offering only the first would send the user\n    // to ask for a permission that is not the only answer. They are listed instead of arbitrarily chosen.\n    const displays = allow.map(c => c?.display).filter(d => !!d);\n    const capDisplay = displays.length > 1 ? displays.slice(0, -1).join(', ') + ' or ' + displays[displays.length - 1] : (displays[0] ?? 'this data');\n\n    return { entity: formConfig.title || 'this data', capDisplay, capName: wanted?.name ?? '' };\n  }\n\n  // Added (Phase 4): the refusal SENTENCES, in one place. There are now two tiers that refuse — the grid\n  // (table.component.html) and the route (the no-access page behind capabilityGuard) — and if each restated the\n  // wording they would drift apart the first time someone edited one of them, leaving a user who followed a deep\n  // link and a user who opened a tab reading two different accounts of the same denial.\n  // Both take the DISPLAY, never the raw capN key: the key belongs in the log line, the display is what a user\n  // repeats to an administrator.\n  public static noAccessTitle(entity?: string | null): string {\n    return `You do not have access to ${entity || 'this data'}`;\n  }\n\n  public static noAccessHint(capDisplay?: string | null): string {\n    return capDisplay ? `Ask your administrator for the “${capDisplay}” permission.` : 'Ask your administrator for access to this page.';\n  }\n\n  private static getRoleAccess(role: any, capName: string): RoleAccess {\n    if (!role || !capName) return RoleAccess.None;\n    return role[capName] ?? RoleAccess.None;\n  }\n\n  // Changed: central resolver for the unified visible/hidden properties (boolean | condition)\n  public static resolveVisibility(v: VisibilityValue | undefined, data: any): boolean | undefined {\n    if (v === undefined || v === null) return undefined;\n    // Changed: never hand a consumer predicate an undefined record. A details dialog renders its tabs, fields and\n    // buttons on the first change-detection pass, BEFORE loadAction has returned the record, so `data` is genuinely\n    // undefined there. Every app config written as `hidden: x => !x.vehicleID` (the natural form) then threw a\n    // TypeError out of this call and killed whatever lifecycle hook was running — in spa-tabs that was ngOnInit,\n    // which aborted before it could seed counts, so no tab badge was ever requested for the life of the dialog.\n    // An empty object reads every property as undefined, which is exactly what \"the record has not arrived\" means,\n    // and is what a `x?.`-guarded predicate already saw. Same defence steps.component.ts already applies locally.\n    return typeof v === 'function' ? !!v(data ?? {}) : v;\n  }\n\n  // Changed: single visibility rule — hidden wins over visible on collision; undefined defaults to visible\n  public static isItemVisible(item: { visible?: VisibilityValue, hidden?: VisibilityValue }, data: any): boolean {\n    if (!item) return true;\n    if (this.resolveVisibility(item.hidden, data) === true) return false;\n    return this.resolveVisibility(item.visible, data) !== false;\n  }\n\n  public static testVisible(config: FormConfig, data, field: Field, currentRole: any): boolean {\n\n    // First check form level security if exists\n    if (config.security && !this.hasFormAccess(config, currentRole)) {\n      return false;\n    }\n\n    if (field.section) {\n      const sectionField = config.fields.find(f => f.type === 'section' && f.name === field.section);\n      if (sectionField) {\n        // Inherit section's conditions\n        if (!this.checkSecurity(sectionField.securityConfig, currentRole)) {\n          return false;\n        }\n        if (sectionField.hideOnCreate && config.mode == 'create') return false;\n        if (sectionField.hideOnExists && config.mode != 'create') return false;\n        // Changed: members inherit ONLY the section's condition functions (legacy hiddenCondition behavior).\n        // A static hidden:true hides just the section header — members stay rendered so field types that\n        // produce values on render (e.g. select defaultFirstValue) still populate the submitted object.\n        if (typeof sectionField.hidden === 'function' && sectionField.hidden(data)) return false;\n        if (typeof sectionField.visible === 'function' && !sectionField.visible(data)) return false;\n      }\n    }\n\n    // Then check field level security if exists\n    if (!this.checkSecurity(field.securityConfig, currentRole)) {\n      return false;\n    }\n\n    if (config.mode == 'create' && field.hideOnCreate) {\n      return false;\n    }\n\n\n    if (config.mode != 'create' && field.hideOnExists) {\n      return false;\n    }\n\n    return this.isItemVisible(field, data); // Changed: unified visible/hidden replaces hidden + hiddenCondition\n  }\n\n  // Added (C60): NARROW test — is this field out of sight because a PREDICATE says so right now?\n  // True only when a FUNCTION-VALUED hidden/visible, on the field or on its section, resolves to hidden.\n  // Deliberately NOT testVisible, and this is the whole point of a separate helper:\n  //   - testVisible also folds in static hidden:true, hideOnCreate/hideOnExists and security gating, and\n  //     :207-209 above documents a static hidden:true on a SECTION as a VALUE-CARRYING pattern (members stay\n  //     rendered so a select's defaultFirstValue still populates the submitted object). Stripping those keys\n  //     from the payload would delete values the config deliberately produces.\n  //   - testVisible is also AND-ed with \"not under a collapsed section\" by the form's getVisibleFields(), and\n  //     collapsing a section must never touch a value the user typed.\n  // Only a predicate can flip mid-form on sibling data the user just changed, which is the defect (C60).\n  public static isPredicateHidden(config: FormConfig, data, field: Field): boolean {\n    if (!field) return false;\n\n    // Section-level predicates first — a member of a predicate-hidden section is just as invisible\n    if (field.section && config?.fields) {\n      const sectionField = config.fields.find(f => f.type === 'section' && f.name === field.section);\n      if (sectionField) {\n        if (typeof sectionField.hidden === 'function' && sectionField.hidden(data ?? {})) return true;\n        if (typeof sectionField.visible === 'function' && !sectionField.visible(data ?? {})) return true;\n      }\n    }\n\n    // `data ?? {}` for the same reason resolveVisibility does it — a predicate can run before the record lands\n    if (typeof field.hidden === 'function' && field.hidden(data ?? {})) return true;\n    if (typeof field.visible === 'function' && !field.visible(data ?? {})) return true;\n\n    return false;\n  }\n\n  // Added (C60): build the OUTGOING payload — a shallow COPY of the bound model with every PREDICATE-HIDDEN\n  // field's key OMITTED. Shared deliberately: there are TWO independent submit paths in this library\n  // (form.component.processCall and detailsDialog.performApiCall) and each had its own copy of\n  // \"post the whole model wholesale\". Fixing one and not the other is how the defect got two homes; a single\n  // helper is the only way they stay fixed together.\n  //\n  // The defect: a value that lands in a field while it is VISIBLE was still posted, and persisted, once a\n  // predicate hid the field. Runtime-proven on pulse-spa Quick Sale — `paymentMethod` and the user-TYPED\n  // `paymentReference` both carry `hidden: x => x.timing === 1`, and a Deferred (credit) sale saved holding\n  // PaymentMethod = Cash and a payment reference the operator could not see. Validation is filtered to VISIBLE\n  // fields, so nothing inspected them.\n  //\n  // Three decisions worth the reader's time:\n  //   1. A COPY, never a mutation of the bound model. Clearing on hide would destroy the user's typed value on\n  //      an accidental toggle (flip to Deferred and back and the reference is silently gone). The form keeps\n  //      its state; only the WRITE is corrected, at the boundary where the defect actually is.\n  //   2. OMIT the key rather than send null. A null into a non-nullable backend enum/int is refused at model\n  //      binding with an HTTP 400 that logs nothing, and seeding 0 is equally unsafe — paymentMethod's\n  //      legitimate Cash IS 0. Absence is the one signal with no false reading, and TinWeb's present-set\n  //      honours only the keys that arrive.\n  //   3. isPredicateHidden, never testVisible and never the form's visibleFields — see that helper's comment.\n  //      Keying off visibleFields would wipe data the instant a user COLLAPSED a section.\n  //\n  // Opt out per field with Field.preserveOnHide, or form-wide with FormConfig.preserveHiddenValues.\n  public static buildSubmitPayload(config: FormConfig, data: any): any {\n    if (!data || config?.preserveHiddenValues || !config?.fields) return data;\n\n    const payload = { ...data }; // shallow — the model is the plain JSON object the projection/loadAction returned\n\n    const omit = (field: Field, forced: boolean) => {\n      if (!field?.name || field.type === 'section' || field.type === 'blank') return; // layout-only fields own no key\n      if (field.serverOwned) { delete payload[field.name]; return; } // Added (CFW-1): UNCONDITIONAL — the server computes this key, so it must never ride the wire. Ahead of preserveOnHide deliberately: that escape hatch is about PREDICATES, and a server-owned value is not something the operator authored under any predicate. Absence, not null, for the C60 reason and one more — TinWeb's present-set (PresentPropertiesFilter) skips absent keys on edit, so omission lands on exactly the same stored value as the server's own [ServerOwned] exclusion, and on create the server clears it to the CLR default regardless\n      if (field.preserveOnHide) return;\n      if (!forced && !this.isPredicateHidden(config, data, field)) return;\n      delete payload[field.name];\n    };\n\n    config.fields.forEach(field => {\n      const parentHidden = this.isPredicateHidden(config, data, field);\n      omit(field, false);\n      // A composite's subfields carry their OWN keys on the model and their own predicates — getVisibleSubfields\n      // runs testVisible per subfield — so a hidden subfield is the same defect one level down. A hidden PARENT\n      // takes its whole set with it, since none of them were on screen either.\n      field.subfields?.forEach(subfield => omit(subfield, parentHidden));\n    });\n\n    return payload;\n  }\n\n  public static testReadOnly(config: FormConfig, data, field: Field): boolean {\n    // Added (CFW-1): serverOwned outranks EVERY mode, create included. `readonly` cannot express this — the\n    // create branch below returns false for every field, so a readonly server-owned figure was fully editable\n    // on a create form while the server cleared it to the CLR default the moment it arrived. Offering an\n    // operator a box whose value is discarded is UI dishonesty; this is the honesty half of the flag.\n    if (field.serverOwned) {\n      return true;\n    }\n\n    // Added (readonly-always-1, ARBITER-RULED 2026-08-22 option A): the SECOND instance of the serverOwned\n    // override pattern above, and it sits here for the same structural reason — ahead of the create branch,\n    // which returns false for every field and is what made `readonly` unusable as a display lock on a create\n    // form. Nine sites across shift and piglet had to stay `type: 'label'` because of that, each carrying a\n    // note saying so. This is a DISPLAY lock only: unlike serverOwned it does NOT touch buildSubmitPayload,\n    // so the value still posts — which is what a valueCalculation-fed reference or a picker-computed readout\n    // needs. Required-validation is untouched either way.\n    if (field.readonlyAlways) {\n      return true;\n    }\n\n    // Default readonly conditions\n    if (config.mode == 'create') {\n      return false;\n    }\n\n    if (field.readonly) {\n      return true;\n    }\n\n    if (config.mode == 'view') {\n      return true;\n    }\n\n    // Check section readonly condition first\n    if (field.section) {\n      const sectionField = config.fields.find(f => f.type === 'section' && f.name === field.section);\n      if (sectionField?.readonlyCondition && sectionField.readonlyCondition(data)) {\n        return true;\n      }\n    }\n\n    // Check field level readonly condition last\n    if (field.readonlyCondition) {\n      return field.readonlyCondition(data);\n    }\n\n    return false;\n  }\n\n  public static testVisibleHeaderButton(data, btn): boolean {\n    return this.isItemVisible(btn, data); // Changed: unified visible/hidden replaces hiddenCondition\n  }\n\n  public static getVisibleSubfields(config: FormConfig, data, field: Field, currentRole: any ): Field[] {\n    return field.subfields?.filter(subfield => Core.testVisible(config, data, subfield,currentRole )) || [];\n  }\n\n  // Changed: onInvalid reports WHICH field failed, so a host can bring it back into view — a required field\n  // inside a collapsed section would otherwise be rejected with no way to see what is being complained about\n  public static validateObject(fields: Field[], data, onInvalid?: (field: Field) => void): string {\n\n    // TS-21: removed per-submit console.log(\"Validations\")\n\n    for (let field of fields) {\n\n      const message = this.validateField(field, data);\n\n      if (message) {\n        onInvalid?.(field);\n        return message;\n      }\n\n    };\n\n    return '';\n  }\n\n  // Changed: the per-field checks, lifted out of validateObject unchanged so the loop can report the failing field\n  private static validateField(field: Field, data): string {\n\n      if (field.type == 'file' || field.type == 'file-view' || field.type == 'blank' || field.type == 'section' ) return ''\n\n\n\n      let name = field.alias ?? this.camelToWords(field.name);\n      let d = data[field.name];\n\n      let isRequired = field.required;\n\n      if (!isRequired && field.requiredCondition) {\n        isRequired = field.requiredCondition(data);\n      }\n\n      // TS-21: removed per-field console.log of every submitted value\n\n      if (isRequired){\n\n        if (d == undefined || d == null) return `${name} is required`;\n\n        if (field.type == 'text'){\n\n          if (d == '') return `Please enter ${name}`;\n\n          if (field.min && d.length < field.min) return `Minimum  ${name} length is ${field.min}`\n\n          if (field.max && d.length > field.max) return `Maximum ${name} length is ${field.max}`\n\n        }\n        else if (field.type == 'number' || field.type == 'money' || field.type == 'date'){\n\n          // Added: the null/undefined guard above is the ONLY emptiness check a date ever got, and an empty date\n          // can arrive here as '' — which equals neither. That is not hypothetical: 5a520aa gave four date fields\n          // `defaultValue: ''` to stop TinCore pre-filling them with TODAY, so a required Date of Birth now opens\n          // holding '' and sailed straight through this function. The POST went out, the API refused the '' at\n          // model binding with a 400, and the user was shown the generic \"Something went wrong ... a technical\n          // problem in the app\" panel with no mention of Date of Birth — told the software had broken when they\n          // had simply left a box empty. Same shape, same function and same fix as 2fc917f did for text-area,\n          // select-multi and text-multi. Scoped to date/datetime deliberately: number and money emit null rather\n          // than '' on both their clear paths (datetime.component.ts:26-36 measured all four), so widening this\n          // to them would change nothing but is not this chunk's to prove.\n          if ((field.type == 'date') && d === '') return `Please select ${name}`;\n\n          if (field.min && d < field.min) return `Minimum  ${name} is ${field.min}`\n\n          if (field.max && d > field.max) return `Maximum ${name} is ${field.max}`\n\n        }\n        else if (field.type == 'datetime'){\n\n          if (d === '') return `Please select ${name}`; // Added: datetime had no branch in this switch at all, so it had the identical '' gap\n        }\n        else if (field.type == 'select') {\n\n          if (typeof(d) == 'string' && d == '') return `Please select ${name}`;\n        }\n        // Added: these three controls CLEAR TO '' rather than to null (select-multi/text-multi join their\n        // values with ';' so an empty list is ''; text-area follows the house `text` convention). The guard\n        // above only catches null/undefined, and the '' refusal existed for 'text' and 'select' only — so a\n        // REQUIRED field of one of these types could be emptied with the suffix clear button and submitted,\n        // and the empty value was written to the database with no error and nothing on screen. Observed\n        // 2026-08-15 on all three (test-spa products edit): the POST was sent and the column was overwritten.\n        // Deliberately checks '' ONLY — it does not change what any control emits, so no payload shape moves\n        // and non-nullable string columns keep receiving '' rather than a null they cannot store.\n        else if (field.type == 'text-area') {\n\n          if (d == '') return `Please enter ${name}`;\n        }\n        else if (field.type == 'select-multi') {\n\n          if (d == '') return `Please select ${name}`;\n        }\n        else if (field.type == 'text-multi') {\n\n          if (d == '') return `Please enter ${name}`;\n        }\n\n      }\n\n\n\n      if (field.type == 'text' && field.regex && d && d.toString().trim() !== '') {\n        const regexPattern = new RegExp(field.regex.pattern);\n        if (!regexPattern.test(d)) {\n          return field.regex.message;\n        }\n      }\n\n    return '';\n  }\n\n  public static testRequired(config: FormConfig, data, field: Field): boolean {\n    if (field.required) {\n      return true;\n    }\n    \n    if (field.requiredCondition) {\n      return field.requiredCondition(data);\n    }\n    \n    return false;\n  }\n\n  public static getInitialValue(field: Field) {\n\n    // Changed (E21): was `if (field.defaultValue)` — a TRUTHINESS test, so a deliberately falsy default\n    // (0, false, '') was silently ignored and the field fell through to the type default below. For most\n    // types that is harmless, because the fallthrough happens to land on the same value anyway (number -> 0,\n    // checkbox -> false, text -> ''). For a SELECT it is not: the fallthrough is `return null`, and a null\n    // posted into a non-nullable backend enum is rejected at model binding with an HTTP 400 that the user\n    // sees as the generic \"Something went wrong ... a technical problem in the app\" panel\n    // (api-error.service.ts:138-144). Nothing is logged server-side, because a binding failure is not an\n    // exception — which is exactly why this stayed hidden through a 124k-line API log.\n    //\n    // Measured before changing it: across ng-space and all four consumer apps exactly 11 fields declare a\n    // falsy defaultValue. Seven are number/money/checkbox and are unaffected, their fallthrough already\n    // producing the same value. The other four are selects that asked for 0 and were silently getting null:\n    // accounting.service.ts:152 itemType, :574 kind, assets.service.ts:25 defaultDepreciationMethod and\n    // :115 disposalType — three of them required, so users were being made to re-pick a value the config had\n    // already chosen for them. This is therefore behaviour-neutral everywhere except where it repairs a bug.\n    if (field.defaultValue !== undefined && field.defaultValue !== null){\n\n      if ((field.type == 'date' || field.type == 'datetime') && field.defaultValue == 'now') return this.nowDate(true);\n\n      // Added (DVT-1): the 'today' token — and its offsets 'today-7' / 'today+30' — as a DEFAULT VALUE. It was\n      // already the documented vocabulary for a min/max BOUND (DateBounds, Classes.ts:185-196) and a config\n      // author has no way to tell from the outside that the same word means nothing here: it fell through to\n      // `return field.defaultValue` below and handed the control the literal STRING 'today'. A spa-date discards\n      // that as an unparseable date and opens BLANK, so on a required field the user is asked to supply a value\n      // the config had already chosen — the same class of defect E21 fixed for falsy select defaults above, and\n      // measured in single-spa (single.service.ts:148, which had to document the gap in a comment rather than\n      // use the token).\n      //\n      // 🔑 'today' is deliberately the START of the local day, NOT the current instant. That is the distinction\n      // DateBounds already draws and it is the only thing that makes this token worth having: 'now' (the line\n      // above) is the instant, so a 'today' that also carried the wall-clock time would be a second spelling of\n      // 'now' and no new capability. Anchored at midnight it is the token that means \"the calendar day\", which is\n      // what a date field stores anyway and what a datetime field wants when it is recording a DAY that happens\n      // to be typed into a datetime column.\n      //\n      // Resolution goes through DateBounds so there is ONE token vocabulary rather than two that drift: any form\n      // DateBounds learns to parse becomes available here for free, and 'today+1' cannot mean one thing to a\n      // ceiling and another to a default. The 'start' edge is what pins it to midnight.\n      // Formatted locally, never via nowDate/getFormatedDate — those add two hours before toISOString() and that\n      // skew moves a midnight-anchored value onto the wrong day outside UTC+2 (the same trap DateBounds exists\n      // to avoid). A token that fails to resolve falls through to the return below, unchanged.\n      // 🔴 The `typeof === 'string'` guard is load-bearing and is NOT redundant with isDynamic: isDynamic also\n      // returns true for a FUNCTION bound, and a function is a legitimate — if unusual — thing to already be\n      // sitting in defaultValue, where today it is returned untouched. Without this guard that function would\n      // start being CALLED, which is a behaviour change nobody asked for and one that would reach the untracked\n      // consumers. Only a STRING token is claimed here; everything else keeps falling through exactly as before.\n      if ((field.type == 'date' || field.type == 'datetime') && typeof field.defaultValue === 'string' && DateBounds.isDynamic(field.defaultValue) && field.defaultValue.trim().toLowerCase() != 'now') {\n        const resolved = DateBounds.resolve(field.defaultValue, 'start');\n        if (resolved) return field.type == 'datetime' ? DateBounds.toLocalInput(resolved) : DateBounds.toLocalDate(resolved);\n      }\n\n      // Added: 'yearStart' — 1 January of the CURRENT year, the sibling token to 'now'. Introduced for\n      // booksOpenFrom (datalib.service.ts configSectionFinancial), whose server-side creation path stamps\n      // exactly this value (AppConfigurationControllerBase.cs:49 `new DateTime(DateTime.Now.Year, 1, 1)`)\n      // while the form showed nothing at all. It is a TOKEN rather than a date computed in the field config\n      // because every config object that declares a field is a `providedIn:'root'` service property, i.e.\n      // evaluated ONCE at app bootstrap — a computed date would freeze the year there and an app left open\n      // across New Year would silently default to the wrong year. Resolving here makes it render-time.\n      // Built as a string, not via nowDate/getFormatedDate, because those add two hours before calling\n      // toISOString() and that skew can move a midnight-anchored date onto the wrong day outside UTC+2.\n      if ((field.type == 'date' || field.type == 'datetime') && field.defaultValue == 'yearStart') return `${new Date().getFullYear()}-01-01`;\n\n      return field.defaultValue;\n    }\n\n    // Changed: a select that will NOT be rendered never produces a value, so this has to supply one its column can\n    // accept — and the test now recognises `visible: false` as well as `hidden: true`. The visibility unification\n    // widened both properties to `boolean | ((data)=>boolean)` (Classes.ts:178-179) and gave `visible` the inverted\n    // sense, but only `hidden === true` was ever checked here, so `visible: false` — the same statement in the other\n    // spelling — fell through to `case 'select': return null` at the bottom of this method. Per the comment above, a\n    // null posted into a non-nullable backend enum/int is refused at model binding with an HTTP 400 that logs NOTHING\n    // server-side, so the two spellings disagreeing is a real defect and not a cosmetic one.\n    //\n    // 🔴 A FUNCTION-VALUED `hidden`/`visible` IS DELIBERATELY OUT OF SCOPE and still falls through to null. It is\n    // tempting to route this through Core.isItemVisible and catch all four spellings at once; that was written,\n    // measured and REJECTED, because a predicate has to be evaluated against a record that does not exist yet, and\n    // most predicates in this codebase read \"hidden while the form is empty, visible once the user fills it in\"\n    // (e.g. `hidden: x => x.category !== 0` is TRUE against {}). Such a field would be seeded 0 and then SHOWN. The\n    // value is computed once and never revisited when visibility flips, and validateField (:291-310) has no `select`\n    // branch — its `d == undefined || d == null` test is the only emptiness check a select gets, so a seeded 0\n    // PASSES `required`. Meanwhile select-common.component.ts:167 renders a non-nullable 0 as blank. The user would\n    // therefore see an empty required box, submit it successfully, and post a value they never chose: a silent wrong\n    // value in place of a loud 400. Widening to predicates is safe only once a select's value FOLLOWS its visibility.\n    //\n    // The 0-vs-null choice is NOT invented here: select-common.component.ts:164-167 already defines a select's blank\n    // as `0` when the field is non-nullable and as `null` when it declares `nullable: true`. Honouring field.nullable\n    // is therefore reading an opt-in the consumer explicitly declared, not flipping a default on one that declared\n    // nothing. Measured blast radius — exactly three fields move from 0 to null, and all three are optional FK links\n    // whose backend column is `int?`, so 0 was a latent insert against a non-existent row 0:\n    // accounting.service.ts:1481 invoiceID (CreditNote.InvoiceID), payroll.service.ts:364 customerID and :365\n    // serviceItemID (CommissionConfig.CustomerID/.ServiceItemID). payroll.service.ts:380 metricType is `hidden: true`\n    // but also carries defaultValue:1, so it returns above and is untouched.\n    if (field.type == 'select' && (field.hideOnCreate || field.hidden === true || field.visible === false)) return field.nullable === true ? null : 0;\n\n    switch (field.type) {\n      case 'text':\n        return '';\n      case 'text-area': // Changed: Added text-area to return empty string\n        return '';\n      case 'text-single': // Changed: Added text-single to return empty string\n        return null;\n      case 'text-multi': // Changed: Added text-multi to return empty string\n        return '';\n      case 'text-mask': // Changed: Added text-mask to return empty string\n        return '';\n      case 'money':\n        return 0;\n      case 'number':\n        return 0;\n      case 'date':\n        return this.nowDate(true);\n      case 'checkbox':\n        return false;\n      case 'select':\n        return null;\n      default:\n        return null;\n    }\n  }\n\n\n\n  public static getClone(x) {\n    return this.deepClone2(x);\n  }\n\n  public static getNumber(value: string) {\n\n    if (value == null || value == \"\") {\n      return 0;\n    }\n\n    const onlyNumbers = value.replace(/[^\\d.-]/g, '');\n    return onlyNumbers\n  }\n\n  // Added: THE multi-value contract — the one place that knows how a multi-select value is shaped.\n  // spa-select-multi and spa-text-multi publish their selection as a ';'-delimited string (updateValue does\n  // selectedValues.join(';')), and every consumer that needs the parts back — a button's onClick converting to\n  // a List<int> DTO, a component re-reading its own bound value — used to re-implement the split inline. That\n  // drifted, expensively: piglet's two sale buttons split on ',' instead of ';', so \"12;13\" parsed to [NaN] →\n  // JSON [null] → a 400 from model binding, and NO sale row was ever written. A single selection contains no\n  // delimiter, so the one-pig case worked and hid the bug from every test anyone thought to run. Written once.\n  //\n  // Accepts all three shapes that legitimately reach a consumer:\n  //   'a;b'   the documented wire shape\n  //   12      a bare scalar — one selection that was never stringified\n  //   [1, 2]  an array — any form whose DTO takes a List<int> rewrites the bound property in place, and that\n  //           array flows straight back down [(value)] on the next change-detection pass\n  // Every part is trimmed and empties are dropped, so 'a; ;b' and ' a ;b ' both give ['a','b'].\n  // null/undefined/''/0 give [] — the established falsy-means-nothing-selected rule, preserved deliberately.\n  // ⚠️ A value CONTAINING ';' is not representable: join(';') is lossy and no escape is defined. The shape is\n  // for ids and codes, never free text the operator can type a semicolon into.\n  public static parseMultiValue(raw: any): string[] {\n    if (Array.isArray(raw)) return raw.filter(v => v !== null && v !== undefined && String(v).trim() !== '').map(v => String(v).trim());\n    if (!raw) return [];\n    return String(raw).split(';').filter(v => v.trim() !== '').map(v => v.trim()); // String() first, so a bare scalar never throws \"split is not a function\"\n  }\n\n  public static getFirstDayOfMonth() {\n    const date = new Date();\n    return new Date(date.getFullYear(), date.getMonth(), 1);\n  }\n\n  public static emailIsValid(email) {\n    // return /\\S+@\\S+\\.\\S+/.test(email)\n    return false;\n  }\n\n  public static isValidUNCPath(path: string) {\n    // return /\\\\\\\\([a-zA-Z0-9_.$●-]+)\\\\([a-zA-Z0-9_.$●-]+).*/.test(path)\n    return false;\n  }\n\n  public static isValidDate(date) {\n\n    var parsedDate = Date.parse(date);\n\n\n    if (isNaN(date) && !isNaN(parsedDate)) {\n      return true;\n    } else {\n      return false;\n    }\n\n  }\n\n  public static isValidEmailList(list: string) {\n    // Changed: was an inline split(\";\") behind an includes(\";\") branch — parseMultiValue is the one owner of the\n    // delimiter now, and because it TRIMS, \"a@b.com; c@d.com\" no longer fails on the space after the semicolon\n    // (the previous code validated \" c@d.com\" verbatim, which no email pattern accepts — a real false negative).\n    const emails = this.parseMultiValue(list);\n    if (!emails.length) return this.emailIsValid(list); // preserves the old behaviour for ''/null — an empty list is not silently \"valid\"\n    return emails.every(email => this.emailIsValid(email));\n  }\n\n  public static nullDate = \"01 Jan 1969\"\n\n  public static isNumber(value: string | number): boolean {\n    return ((value != null) &&\n      (value !== '') &&\n      !isNaN(Number(value.toString())));\n  }\n\n  public static getDiff(startDate, endDate = Date()) {\n\n    var eventStartTime = new Date(startDate);\n    var eventEndTime = new Date(endDate);\n    var milliseconds = eventEndTime.valueOf() - eventStartTime.valueOf();\n\n    function numberEnding(number: number) {\n\n      if (number.toFixed() == '1') {\n        return ''\n      } else {\n        return 's';\n      }\n\n    }\n\n    var minutes = (milliseconds / (1000 * 60));\n\n    var hours: number = (milliseconds / (1000 * 60 * 60));\n\n    var days = (milliseconds / (1000 * 60 * 60 * 24));\n\n    var weeks: number = (milliseconds / (1000 * 60 * 60 * 24 * 7));\n\n    var months = (milliseconds / (1000 * 60 * 60 * 24 * 7 * 4));\n\n    var years = (milliseconds / (1000 * 60 * 60 * 24 * 365));\n\n\n    if (years >= 1) {\n\n      return years.toFixed() + ' year' + numberEnding(years);\n\n    } else if (months >= 1) {\n\n      return months.toFixed() + ' month' + numberEnding(months);\n\n    } else if (weeks >= 1) {\n\n      return weeks.toFixed() + ' week' + numberEnding(weeks);\n\n    } else if (days >= 1) {\n\n      return days.toFixed() + ' day' + numberEnding(days);\n\n    } else if (hours >= 1) {\n\n      return hours.toFixed() + ' hour' + numberEnding(hours);\n\n    } else if (minutes >= 1) {\n\n      return minutes.toFixed() + ' minute' + numberEnding(minutes);\n\n    } else if (milliseconds >= (-1000 * 60)) {\n\n      return 'a minute';\n\n    } else {\n\n      return 'N/A';\n    }\n\n  }\n\n\n  public static nowDate(NoTime: boolean = false) {\n\n    if (NoTime) {\n      return this.getFormatedDate(Date(), true);\n    } else {\n      return this.getFormatedDate(Date());\n    }\n  }\n\n  public static getFormatedDate(dateString: string, NoTime: boolean = false) {\n\n    let d: Date = new Date(dateString);\n    d.setHours(d.getHours() + 2);\n\n    if (NoTime == true) {\n      return d.toISOString().split('T')[0];\n    } else {\n      return d.toISOString().split('.')[0];\n    }\n\n  }\n\n  public static getFormatedDate2(d : Date, NoTime: boolean = false) {\n\n\n    d.setHours(d.getHours() + 2);\n\n    if (NoTime == true) {\n      return d.toISOString().split('T')[0];\n    } else {\n      return d.toISOString().split('.')[0];\n    }\n\n  }\n\n  public static getBusinessDatesCount(startDate: string, endDate: string) {\n    var count = 0;\n    var _startDate = new Date(startDate);\n    var _endDate = new Date(endDate);\n\n    var curDate = _startDate;\n\n    while (curDate < _endDate) {\n      var dayOfWeek = curDate.getDay();\n      if (!(dayOfWeek == 6 || dayOfWeek == 0)) count++;\n      curDate.setDate(curDate.getDate() + 1);\n    }\n\n    return count;\n  }\n\n}\n\n\nexport class DetailsDialogProcessor {\n\n  public static processDetailsConfig(detailsConfig: DetailsDialogConfig, row: any): DetailsDialogConfig {\n\n    const updatedDetailsConfig: DetailsDialogConfig = Core.getClone(detailsConfig); //{...detailsConfig}\n    updatedDetailsConfig.details = row;\n\n\n    //Form Config\n    updatedDetailsConfig.formConfig.mode = updatedDetailsConfig.mode ?? \"view\";\n\n\n\n    if (updatedDetailsConfig.heroField && row) {\n      updatedDetailsConfig.heroValue = row[updatedDetailsConfig.heroField];\n    }\n\n\n    //Table configs\n    if (updatedDetailsConfig.tableConfig) {\n      updateTableConfig(updatedDetailsConfig.tableConfig);\n    }\n\n    if (updatedDetailsConfig.tableConfigs) {\n      updatedDetailsConfig.tableConfigs.forEach(updateTableConfig);\n    }\n\n    function updateTableConfig(tableConfig) {\n      tableConfig.heroField = updatedDetailsConfig?.heroField;\n      tableConfig.heroValue = updatedDetailsConfig?.heroValue;\n      // tableConfig.setHero = updatedDetailsConfig.setHero;\n      tableConfig.searchConfig = null;\n      tableConfig.tileConfig = null;\n      tableConfig.parentData = updatedDetailsConfig.details;\n      tableConfig.elevation = 'none';\n    }\n\n\n\n    //URL\n    if (updatedDetailsConfig.tableConfig) {\n      transformLoadUrl(updatedDetailsConfig.tableConfig);\n    }\n\n    if (updatedDetailsConfig.tableConfigs) {\n      updatedDetailsConfig.tableConfigs.forEach(transformLoadUrl);\n    }\n\n    if (updatedDetailsConfig.stepConfig?.loadAction) {\n      transformStepUrl(updatedDetailsConfig.stepConfig);\n    }\n\n    function transformLoadUrl(tableConfig) {\n      if (!tableConfig.loadAction) return;\n\n      if (tableConfig.loadCriteria && tableConfig.loadIDField) {\n        const idValue = updatedDetailsConfig.details?.[tableConfig.loadIDField]; // Changed: Null guard for header buttons with no row data\n        tableConfig.loadAction.url = `${tableConfig.loadAction.url.split('/')[0]}/${tableConfig.loadCriteria}/${idValue ?? 'x'}`;\n      }\n    }\n\n    function transformStepUrl(stepConfig) {\n      if (stepConfig.loadAction && stepConfig.loadIDField ) {\n        stepConfig.loadAction.url = `${stepConfig.loadAction.url.replace('{id}', updatedDetailsConfig.details[stepConfig.loadIDField])}`;\n      }\n    }\n\n\n\n    return updatedDetailsConfig;\n  }\n\n\n  static initializeConfigs(detailsConfig: DetailsDialogConfig) {\n    const tableConfig = detailsConfig.tableConfig;\n    const tableConfigs = detailsConfig.tableConfigs;\n    const formConfig = detailsConfig.formConfig;\n    const stepConfig = detailsConfig.stepConfig;\n    const statusConfig = detailsConfig.statusConfig;\n    const buttons = detailsConfig.buttons;\n    formConfig.mode = formConfig.mode ?? \"view\";\n    return { tableConfig, tableConfigs, formConfig, stepConfig, statusConfig, buttons };\n  }\n\n  static setHeroValue(detailsConfig: DetailsDialogConfig, details: any) {\n\n\n    if ((detailsConfig.formConfig.mode == \"create\"  ) && detailsConfig.heroField && detailsConfig.heroValue) {\n      details[detailsConfig.heroField] = detailsConfig.heroValue;\n\n      // Ensure hero values are set in form config\n      detailsConfig.formConfig.heroField = detailsConfig.heroField;\n      detailsConfig.formConfig.heroValue = detailsConfig.heroValue;\n\n      return;\n    }\n\n\n  }\n\n  static handleFormMode(detailsConfig: DetailsDialogConfig, formConfig: FormConfig,) {\n    let details;\n    let action;\n    let loadByAction = false;\n\n    if (formConfig.mode === \"create\") {\n\n      details = Core.generateObject(formConfig.fields);\n      // Changed: merge row data into create form if available (e.g. pre-populating sowID from pig row)\n      if (detailsConfig.details) {\n        Object.keys(detailsConfig.details).forEach(key => {\n          if (detailsConfig.details[key] !== null && detailsConfig.details[key] !== undefined) {\n            details[key] = detailsConfig.details[key];\n          }\n        });\n      }\n\n    } else {\n      let resp = this.loadDetailsData(detailsConfig, formConfig);\n      details = resp.details;\n\n      action = resp.action;\n      loadByAction = resp.loadByAction;\n    }\n\n    // Changed: resolve {placeholder} in field loadAction URLs using row data (works for both create and edit modes)\n    if (detailsConfig.details) {\n      formConfig.fields?.forEach(field => {\n        if (field.loadAction?.url && field.loadAction.url.includes('{')) {\n          // Changed (treat-5): an UNRESOLVABLE token used to become '' unconditionally, producing a url that LOOKS\n          // complete — 'pigs/list/bypen-{penID}' -> 'pigs/list/bypen-', which the server answers 200 to with the whole\n          // UNFILTERED list. Every downstream guard keys off a remaining '{' (spa-select-common and spa-select-multi\n          // both return early on one), so stripping the brace here silently disarmed all of them.\n          // This is now byte-identical to the sibling resolver for the same syntax, FormComponent.resolveLoadAction\n          // (form.component.ts:223-227), including its two asymmetries: '' counts as UNRESOLVED alongside\n          // null/undefined (a placeholder cleared back to blank is exactly as unready as one never set), and a\n          // resolved value is String()-coerced. Two resolvers for one placeholder syntax disagreeing is the drift\n          // this defect was made of, so the gate is taken whole rather than approximated with `??`.\n          // 🔑 Gated on refetchOnChange DELIBERATELY (Arbiter ruling, 2026-08-20): keeping the token is a semantic\n          // change for any config that relies on '', and tin-spa ships by tarball to UNTRACKED consumers outside this\n          // workspace that no enumeration here can reach. House rule is never flip a default, add an opt-in — so this\n          // branch is unreachable unless the field opts in, and no existing non-opted-in url changes by one character.\n          field.loadAction = { ...field.loadAction, url: field.loadAction.url.replace(/\\{(\\w+)\\}/g, (m, key) => { const v = detailsConfig.details[key]; return (v !== undefined && v !== null && v !== '') ? String(v) : (field.refetchOnChange ? m : ''); }) };\n        }\n      });\n    }\n\n    return { details, loadByAction, action };\n  }\n\n  private static loadDetailsData(detailsConfig: DetailsDialogConfig, formConfig: FormConfig) {\n\n    let details;\n    let action;\n    let loadByAction = false;\n\n\n    //Choose source\n    if (detailsConfig.detailsSource == DetailsSource.Row) {\n\n      // console.log(\"Data from Details - Row option\")\n      details = detailsConfig.details;\n\n    } else if (detailsConfig.detailsSource == DetailsSource.Url) {\n      // console.log(\"Data from Url option\")\n      action = this.loadDetailsFromUrl(detailsConfig, formConfig);\n      loadByAction = true;\n\n    } else {\n\n      //new logic\n      if (formConfig.loadAction){\n        // console.log(\"Data from Url - Guessed\");\n          action = this.loadDetailsFromUrl(detailsConfig, formConfig);\n          loadByAction = true;\n\n      }else{\n          // console.log(\"Data from Details - Guessed\");\n          details = detailsConfig.details;\n      }\n\n    }\n\n    return { details, loadByAction, action };\n  }\n\n  private static loadDetailsFromUrl(detailsConfig: DetailsDialogConfig, formConfig: FormConfig) {\n    let action : Action;\n\n    if (formConfig.loadAction) {\n\n      if (formConfig.heroField && detailsConfig.details) { // Changed: prioritize formConfig.heroField - the form's own identity field takes precedence over parent's heroField\n\n        // console.log(\"FormConfig Hero ID Field \" + formConfig.heroField);\n        action = { url: `${formConfig.loadAction.url}/${detailsConfig.details[formConfig.heroField]}` };\n\n      } else if (detailsConfig.heroField && detailsConfig.details) { // Changed: fallback to detailsConfig.heroField when formConfig doesn't define one\n\n        // console.log(\"DetailsConfig Hero ID Field \" + detailsConfig.heroField);\n        action = { url: `${formConfig.loadAction.url}/${detailsConfig.details[detailsConfig.heroField]}` };\n\n      } else if (detailsConfig.heroValue) {\n\n        // console.log(\"Defined Hero Value \" + detailsConfig.heroValue);\n        action = { url: `${formConfig.loadAction.url}/${detailsConfig.heroValue}` };\n\n      }\n      else{\n        console.log(\"url source failed : setup hero field or hero value\");\n      }\n\n      action.cacheDurationMinutes = formConfig.loadAction.cacheDurationMinutes ?? 0;\n      action.skipCache = formConfig.loadAction.skipCache ?? false;\n      action.successMessage = formConfig.loadAction.successMessage ?? null;\n\n    }else{\n      console.log(\"No load action set\");\n    }\n\n    return action;\n  }\n\n  static setFileField(formConfig: FormConfig) {\n    return formConfig.fields.find(x => x.type === 'file');\n  }\n\n\n  static setupButtons(buttons: any) {\n    let extraButtons, createButton, editButton, deleteButton;\n\n    if (buttons) {\n      extraButtons = buttons.filter(x => x.name !== \"create\" && x.name !== \"edit\" && x.name !== \"delete\" && x.name !== \"view\" && x.inDialog);\n      createButton = buttons.find(x => x.name === \"create\");\n      editButton = buttons.find(x => x.name === \"edit\");\n      deleteButton = buttons.find(x => x.name === \"delete\");\n    }\n    return { extraButtons, createButton, editButton, deleteButton };\n  }\n\n\n\n\n}\n\n\n","import { Core } from \"./TinCore\";\n\n\nexport enum InvoiceStatus {\n  Draft, Submitted, Paid, Discarded, Paying, WrittenOff // Changed: Added WrittenOff terminal status for bad-debt write-offs\n}\n\n// Changed: Credit note status enum - mirrors backend CreditNoteStatus (B6)\nexport enum CreditNoteStatus {\n  Draft, Submitted, Applied, Discarded\n}\n\n// Changed: Fiscal period status enum - mirrors backend FiscalPeriodStatus (C2)\nexport enum FiscalPeriodStatus {\n  Open, Closed, Locked\n}\n\n// Changed: Quote status enum - mirrors backend QuoteStatus (C10)\nexport enum QuoteStatus {\n  Draft, Sent, Accepted, Rejected, Expired, Converted\n}\n\n// Added: Invoice item type enum - mirrors backend InvoiceItemType\nexport enum InvoiceItemType {\n  General = 0,\n  Product = 1,\n  Service = 2\n}\n\n// Fixed asset status enum - mirrors backend AssetStatus\nexport enum AssetStatus { Draft = 0, Active = 1, FullyDepreciated = 2, Disposed = 3 }\n\n// Transaction timing enum - separates WHEN payment occurs from HOW\nexport enum TransactionTiming {\n  Immediate = 0,  // Payment occurs now - no AR/AP created\n  Deferred = 1    // Payment occurs later - creates AR/AP\n}\n\n// Changed: Renamed from InventoryReceiptStatus to PurchaseStatus\nexport enum PurchaseStatus {\n  Draft,\n  Confirmed, // Changed: Receiving → Confirmed (same int=1)\n  Completed\n}\n\n// Added: Receipt status for goods confirmation tracking\nexport enum ReceiptStatus {\n  Draft,\n  Completed\n}\n\n// Unit of measure enum - mirrors backend\nexport enum UnitOfMeasure {\n  Piece,\n  Box,\n  Case,\n  Carton,\n  Pallet,\n  Kilogram,\n  Gram,\n  Litre,\n  Millilitre,\n  Meter,\n  Pack,\n  Set,\n  Dozen\n}\n\nexport class loginConfig {\n\n  constructor() {\n    this.appName = \"\";\n    this.selfService = false;\n    this.logo = \"\";\n    this.logoSize = \"normal\";\n  }\n\n  appName: string;\n  selfService: boolean;\n  logo: string;\n  logoSize: string;\n}\n\n\nexport class Account {\n  user: User;\n  profile: Profile;\n}\n\nexport class User {\n\n  constructor() {\n\n\n    this.userName = \"\";\n    this.password = \"\";\n    this.tries = \"0\";\n    this.locked = \"0\";\n    this.logged = \"0\";\n    this.disabled = \"0\";\n    this.changepassword = \"0\";\n    this.dateCreated = Core.nowDate();\n    this.dateUpdated = Core.nowDate();\n    this.token = \"\";\n    this.dateExpire = Core.nowDate();\n    this.tokenExpire = Core.nowDate();\n    this.authType = \"\";\n    this.rememberMe = false; // Changed: Added for \"Keep me signed in\" feature\n  }\n\n  userName: string;\n  password: string;\n  tries: string;\n  locked: string;\n  logged: string;\n  disabled: string;\n  changepassword: string;\n  dateCreated: string;\n  dateUpdated: string;\n  dateExpire: string;\n  token: string;\n  tokenExpire: string;\n\n  authType: string;\n  rememberMe: boolean; // Changed: Added for \"Keep me signed in\" feature\n}\n\nexport class ChangeUserPassword {\n\n  constructor() {\n    this.userName = \"\";\n    this.currentPassword = \"\";\n    this.newPassword = \"\";\n    this.confirmPassword = \"\";\n  }\n  userName: string;\n  currentPassword: string;\n  newPassword: string;\n  confirmPassword: string;\n}\n\n\nexport class Register {\n\n  constructor() {\n    this.userName = \"\";\n    this.roleID = 1;\n    this.firstName = \"\";\n    this.lastName = \"\";\n    this.email = \"\";\n    this.authType = \"local\";\n    this.password = \"\";\n  }\n\n  userName: string;\n  roleID: number;\n  firstName: string;\n  lastName: string;\n  email: string;\n  authType: string;\n  password: string;\n}\n\nexport class Profile {\n\n  constructor() {\n    this.profileID = \"\";\n    this.userName = \"\";\n    this.roleID = 1;\n    this.firstName = \"\";\n    this.lastName = \"\";\n    this.email = \"\";\n    this.empID = \"\";\n    this.arID = \"0\";\n    this.authType = \"\";\n    this.password = \"\";\n    this.role = new Role();\n    this.code = \"\";\n  }\n\n  profileID: string;\n  userName: string;\n  roleID: number;\n  firstName: string;\n  lastName: string;\n  email: string;\n  empID: string;\n  arID: string;\n  authType: string;\n  password: string;\n  role: Role\n  code : string;\n}\n\n\n\nexport class Role {\n\n  constructor() {\n    this.roleID = 0;\n    this.roleName = \"New Role\";\n    this.cap1 = false;\n    this.cap2 = false;\n    this.cap3 = false;\n    this.cap4 = false;\n    this.cap5 = false;\n    this.cap6 = false;\n    this.cap7 = false;\n    this.cap8 = false;\n    this.cap9 = false;\n    this.cap10 = false;\n    this.cap11 = false;\n    this.cap12 = false;\n    this.cap13 = false;\n    this.cap14 = false;\n    this.cap15 = false;\n    this.cap16 = false;\n    this.cap17 = false;\n    this.cap18 = false;\n    this.cap19 = false;\n    this.cap20 = false;\n    this.cap21 = false;\n    this.cap22 = false;\n    this.cap23 = false;\n    this.cap24 = false;\n    this.cap25 = false;\n    this.cap26 = false;\n    this.cap27 = false;\n    this.cap28 = false;\n    this.cap29 = false;\n    this.cap30 = false;\n    this.cap31 = false;\n    this.cap32 = false;\n    this.cap33 = false;\n    this.cap34 = false;\n    this.cap35 = false;\n    this.cap36 = false;\n    this.cap37 = false;\n    this.cap38 = false;\n    this.cap39 = false;\n    this.cap40 = false;\n    this.cap41 = false;\n    this.cap42 = false;\n    this.cap43 = false;\n    this.cap44 = false;\n    this.cap45 = false;\n    this.cap46 = false;\n    this.cap47 = false;\n    this.cap48 = false;\n    this.cap49 = false;\n    this.cap50 = false;\n    this.cap51 = false;\n    this.cap52 = false;\n    this.cap53 = false;\n    this.cap54 = false;\n    this.cap55 = false;\n    this.cap56 = false;\n    this.cap57 = false;\n    this.cap58 = false;\n    this.cap59 = false;\n    this.cap60 = false;\n    this.cap61 = false;\n    this.cap62 = false;\n    this.cap63 = false;\n    this.cap64 = false;\n    this.cap65 = false;\n    this.cap66 = false;\n    this.cap67 = false;\n    this.cap68 = false;\n    this.cap69 = false;\n    this.cap70 = false;\n    this.cap71 = false;\n    this.cap72 = false;\n    this.cap73 = false;\n    this.cap74 = false;\n    this.cap75 = false;\n    this.cap76 = false;\n    this.cap77 = false;\n    this.cap78 = false;\n    this.cap79 = false;\n    this.cap80 = false;\n    this.cap81 = false;\n    this.cap82 = false;\n    this.cap83 = false;\n    this.cap84 = false;\n    this.cap85 = false;\n    this.cap86 = false;\n    this.cap87 = false;\n    this.cap88 = false;\n    this.cap89 = false;\n    this.cap90 = false;\n    this.cap91 = false;\n    this.cap92 = false;\n    this.cap93 = false;\n    this.cap94 = false;\n    this.cap95 = false;\n    this.cap96 = false;\n    this.cap97 = false;\n    this.cap98 = false;\n    this.cap99 = false;\n    this.cap100 = false;\n    // Changed: Extended cap101-cap200 to match backend Role model (Cap1-Cap200)\n    this.cap101 = false;\n    this.cap102 = false;\n    this.cap103 = false;\n    this.cap104 = false;\n    this.cap105 = false;\n    this.cap106 = false;\n    this.cap107 = false;\n    this.cap108 = false;\n    this.cap109 = false;\n    this.cap110 = false;\n    this.cap111 = false;\n    this.cap112 = false;\n    this.cap113 = false;\n    this.cap114 = false;\n    this.cap115 = false;\n    this.cap116 = false;\n    this.cap117 = false;\n    this.cap118 = false;\n    this.cap119 = false;\n    this.cap120 = false;\n    this.cap121 = false;\n    this.cap122 = false;\n    this.cap123 = false;\n    this.cap124 = false;\n    this.cap125 = false;\n    this.cap126 = false;\n    this.cap127 = false;\n    this.cap128 = false;\n    this.cap129 = false;\n    this.cap130 = false;\n    this.cap131 = false;\n    this.cap132 = false;\n    this.cap133 = false;\n    this.cap134 = false;\n    this.cap135 = false;\n    this.cap136 = false;\n    this.cap137 = false;\n    this.cap138 = false;\n    this.cap139 = false;\n    this.cap140 = false;\n    this.cap141 = false;\n    this.cap142 = false;\n    this.cap143 = false;\n    this.cap144 = false;\n    this.cap145 = false;\n    this.cap146 = false;\n    this.cap147 = false;\n    this.cap148 = false;\n    this.cap149 = false;\n    this.cap150 = false;\n    this.cap151 = false;\n    this.cap152 = false;\n    this.cap153 = false;\n    this.cap154 = false;\n    this.cap155 = false;\n    this.cap156 = false;\n    this.cap157 = false;\n    this.cap158 = false;\n    this.cap159 = false;\n    this.cap160 = false;\n    this.cap161 = false;\n    this.cap162 = false;\n    this.cap163 = false;\n    this.cap164 = false;\n    this.cap165 = false;\n    this.cap166 = false;\n    this.cap167 = false;\n    this.cap168 = false;\n    this.cap169 = false;\n    this.cap170 = false;\n    this.cap171 = false;\n    this.cap172 = false;\n    this.cap173 = false;\n    this.cap174 = false;\n    this.cap175 = false;\n    this.cap176 = false;\n    this.cap177 = false;\n    this.cap178 = false;\n    this.cap179 = false;\n    this.cap180 = false;\n    this.cap181 = false;\n    this.cap182 = false;\n    this.cap183 = false;\n    this.cap184 = false;\n    this.cap185 = false;\n    this.cap186 = false;\n    this.cap187 = false;\n    this.cap188 = false;\n    this.cap189 = false;\n    this.cap190 = false;\n    this.cap191 = false;\n    this.cap192 = false;\n    this.cap193 = false;\n    this.cap194 = false;\n    this.cap195 = false;\n    this.cap196 = false;\n    this.cap197 = false;\n    this.cap198 = false;\n    this.cap199 = false;\n    this.cap200 = false;\n  }\n\n  roleID: number;\n  roleName: string;\n  cap1: boolean;\n  cap2: boolean;\n  cap3: boolean;\n  cap4: boolean;\n  cap5: boolean;\n  cap6: boolean;\n  cap7: boolean;\n  cap8: boolean;\n  cap9: boolean;\n  cap10: boolean;\n  cap11: boolean;\n  cap12: boolean;\n  cap13: boolean;\n  cap14: boolean;\n  cap15: boolean;\n  cap16: boolean;\n  cap17: boolean;\n  cap18: boolean;\n  cap19: boolean;\n  cap20: boolean;\n  cap21: boolean;\n  cap22: boolean;\n  cap23: boolean;\n  cap24: boolean;\n  cap25: boolean;\n  cap26: boolean;\n  cap27: boolean;\n  cap28: boolean;\n  cap29: boolean;\n  cap30: boolean;\n  cap31: boolean;\n  cap32: boolean;\n  cap33: boolean;\n  cap34: boolean;\n  cap35: boolean;\n  cap36: boolean;\n  cap37: boolean;\n  cap38: boolean;\n  cap39: boolean;\n  cap40: boolean;\n  cap41: boolean;\n  cap42: boolean;\n  cap43: boolean;\n  cap44: boolean;\n  cap45: boolean;\n  cap46: boolean;\n  cap47: boolean;\n  cap48: boolean;\n  cap49: boolean;\n  cap50: boolean;\n  cap51: boolean;\n  cap52: boolean;\n  cap53: boolean;\n  cap54: boolean;\n  cap55: boolean;\n  cap56: boolean;\n  cap57: boolean;\n  cap58: boolean;\n  cap59: boolean;\n  cap60: boolean;\n  cap61: boolean;\n  cap62: boolean;\n  cap63: boolean;\n  cap64: boolean;\n  cap65: boolean;\n  cap66: boolean;\n  cap67: boolean;\n  cap68: boolean;\n  cap69: boolean;\n  cap70: boolean;\n  cap71: boolean;\n  cap72: boolean;\n  cap73: boolean;\n  cap74: boolean;\n  cap75: boolean;\n  cap76: boolean;\n  cap77: boolean;\n  cap78: boolean;\n  cap79: boolean;\n  cap80: boolean;\n  cap81: boolean;\n  cap82: boolean;\n  cap83: boolean;\n  cap84: boolean;\n  cap85: boolean;\n  cap86: boolean;\n  cap87: boolean;\n  cap88: boolean;\n  cap89: boolean;\n  cap90: boolean;\n  cap91: boolean;\n  cap92: boolean;\n  cap93: boolean;\n  cap94: boolean;\n  cap95: boolean;\n  cap96: boolean;\n  cap97: boolean;\n  cap98: boolean;\n  cap99: boolean;\n  cap100: boolean;\n  // Changed: Extended cap101-cap200 to match backend Role model (Cap1-Cap200)\n  cap101: boolean;\n  cap102: boolean;\n  cap103: boolean;\n  cap104: boolean;\n  cap105: boolean;\n  cap106: boolean;\n  cap107: boolean;\n  cap108: boolean;\n  cap109: boolean;\n  cap110: boolean;\n  cap111: boolean;\n  cap112: boolean;\n  cap113: boolean;\n  cap114: boolean;\n  cap115: boolean;\n  cap116: boolean;\n  cap117: boolean;\n  cap118: boolean;\n  cap119: boolean;\n  cap120: boolean;\n  cap121: boolean;\n  cap122: boolean;\n  cap123: boolean;\n  cap124: boolean;\n  cap125: boolean;\n  cap126: boolean;\n  cap127: boolean;\n  cap128: boolean;\n  cap129: boolean;\n  cap130: boolean;\n  cap131: boolean;\n  cap132: boolean;\n  cap133: boolean;\n  cap134: boolean;\n  cap135: boolean;\n  cap136: boolean;\n  cap137: boolean;\n  cap138: boolean;\n  cap139: boolean;\n  cap140: boolean;\n  cap141: boolean;\n  cap142: boolean;\n  cap143: boolean;\n  cap144: boolean;\n  cap145: boolean;\n  cap146: boolean;\n  cap147: boolean;\n  cap148: boolean;\n  cap149: boolean;\n  cap150: boolean;\n  cap151: boolean;\n  cap152: boolean;\n  cap153: boolean;\n  cap154: boolean;\n  cap155: boolean;\n  cap156: boolean;\n  cap157: boolean;\n  cap158: boolean;\n  cap159: boolean;\n  cap160: boolean;\n  cap161: boolean;\n  cap162: boolean;\n  cap163: boolean;\n  cap164: boolean;\n  cap165: boolean;\n  cap166: boolean;\n  cap167: boolean;\n  cap168: boolean;\n  cap169: boolean;\n  cap170: boolean;\n  cap171: boolean;\n  cap172: boolean;\n  cap173: boolean;\n  cap174: boolean;\n  cap175: boolean;\n  cap176: boolean;\n  cap177: boolean;\n  cap178: boolean;\n  cap179: boolean;\n  cap180: boolean;\n  cap181: boolean;\n  cap182: boolean;\n  cap183: boolean;\n  cap184: boolean;\n  cap185: boolean;\n  cap186: boolean;\n  cap187: boolean;\n  cap188: boolean;\n  cap189: boolean;\n  cap190: boolean;\n  cap191: boolean;\n  cap192: boolean;\n  cap193: boolean;\n  cap194: boolean;\n  cap195: boolean;\n  cap196: boolean;\n  cap197: boolean;\n  cap198: boolean;\n  cap199: boolean;\n  cap200: boolean;\n}\n\n\n// Added: Model for passing signup data from login redirect to signup page\nexport class SignupData {\n    token: string = \"\";\n    authType: string = \"\";\n    firstName: string = \"\";\n    lastName: string = \"\";\n    email: string = \"\";\n    orgName: string = \"\";\n    termsAccepted: boolean = false;\n    invitations: any[] = [];\n    acceptedInvitationIds: number[] = [];\n}\n\nexport enum LogLevel {\n  All = 0,\n  Debug = 1,\n  Info = 2,\n  Warn = 3,\n  Error = 4,\n  Fatal = 5,\n  Off = 6,\n}\n","import { BehaviorSubject } from \"rxjs\";\n// 🔴 `import type`, NOT a value import. DocumentClasses.ts imports `Action` FROM this file, so a value\n// import here would close a module cycle. `import type` is erased at compile time and emits no require/\n// import at all, so the cycle never exists at runtime. Field.documentSource is the only member that needs it.\nimport type { DocumentSource } from \"./DocumentClasses\";\n\nexport interface BitwiseOption {\n  name?: string;\n  value: number;\n  selected: boolean;\n  icon?: Icon;\n}\n\nexport enum RoleAccess {\n  None = 0,\n  View = 1,\n  Edit = 2,\n  Create = 3,\n  Full = 4\n}\n\n\nexport enum MovementType {\n  In = 0,\n  Out = 1\n}\n\nexport enum DetailsSource {Row, Url}\n\nexport class dialogOptions {\n  width?: string;\n  height?: string;\n}\n\nexport interface CloseOptions {\n  position?: 'top' | 'bottom'; // Default: 'bottom'\n  text?: string; // Default: 'Cancel' - only applies when position is 'bottom'\n}\n\nexport class DetailsDialogConfig {\n\n  stepConfig? : StepConfig;\n  statusConfig? : StatusConfig;\n  formConfig: FormConfig;\n  tableConfig?: TableConfig;\n  tableConfigs?: TableConfig[];\n  buttons?: Button[];\n  details? : any\n  heroField? : any\n  heroValue?: any\n  mode?: 'create' | 'edit' | 'view'\n  // width?: string\n  detailsSource?: DetailsSource\n  options?: dialogOptions\n  autoRefreshConfig?: AutoRefreshConfig;\n  refreshOnClose?: boolean;\n  refreshOnCloseIfActioned?: boolean; // Changed: like refreshOnClose but conditional — Close triggers a parent refresh only when a successful action (POST) happened inside the dialog (footer button, nested-tab table action, or nested dialog); pure view-then-close stays refresh-free\n  causeTableRefresh?: boolean;\n  closeOptions?: CloseOptions;\n  initAction?: Action; // Called on dialog open to check for existing state\n  hideTablesInCreateMode?: boolean; // Hide nested tables when mode is 'create'\n  disableFloatingTabs?: boolean; // Added: opt OUT of the floating tab-title strip (default is ON — the strip only ever appears while the real tab strip is scrolled out of view, and it is zero-height in flow, so it cannot move anything)\n  allowUserKeepOpen?: boolean; // Set by table config — shows a Keep Open checkbox in the dialog title bar; TableConfig is the single source of truth\n  keepOpenBehavior?: 'reset' | 'edit'; // Set by table config — controls what happens after successful create when user has Keep Open ticked\n  nestingLevel?: number; // Changed: Controls dialog nesting depth — tabs hidden when >= 2\n  localMode?: boolean; // Added: one-step create — dialog validates and returns details to the caller without POSTing (rows kept in memory until the parent is created)\n  quietLoading?: boolean; // Added (Quiet Loading): overrides AppConfig.quietLoading for this dialog — an explicit false opts OUT of an app-wide opt-in\n  seedDefaults?: boolean; // Added: OPT-IN, default OFF. Applies each field's defaultValue AFTER the record lands on the edit path. Core.generateObject only ever ran for mode:'create', so every defaultValue on a CAPTURE dialog built as mode:'edit' (Record Payment, Dispose Asset, Record Death) was silently inert. Semantics mirror TableComponent.seedInlineDefaults exactly: seed ONLY where the current value is null/undefined/'' so real data is never overwritten, and ONLY for fields the operator can actually see — an unrendered field must never be silently seeded, because nobody can see or correct what it was seeded with. Leave it OFF for a true-edit dialog: a default is honest where a human is looking at it and can change it, not where it materialises unseen.\n  drillIn?: boolean; // Added: set by TableComponent.columnClicked — this dialog was reached by tapping a COLUMN (chip / button / monogram), so the clicked row is NOT necessarily a row of the entity this form describes. Read by the details dialog's failed-load path, which must not adopt the clicked row as the record.\n}\n\nexport class Action{\n  method?: 'get' | 'post'\n  url: string;\n  params? : any[]\n  successMessage?: string\n  isFormData?: boolean\n  skipCache?: boolean\n  cacheDurationMinutes?: number;\n  silent?: boolean; // Added (Quiet Loading): this action never raises the global scrim. Prefer CallApi's call-time { silent } option — Actions on configs are shared singletons\n}\n\n// Centralized cache configuration for URL patterns\nexport interface CacheRule {\n  pattern: string;      \n  durationMinutes: number;\n}\n\nexport class CacheConfig {\n  rules: CacheRule[] = [];\n  \n  addRule(pattern: string, durationMinutes: number) {\n    this.rules.push({ pattern, durationMinutes });\n  }\n  \n  getDuration(url: string): number | null {\n    for (const rule of this.rules) {\n      if (this.matchesPattern(url, rule.pattern)) {\n        return rule.durationMinutes;\n      }\n    }\n    return null;\n  }\n  \n  private matchesPattern(url: string, pattern: string): boolean {\n    const regexPattern = pattern\n      .replace(/\\*/g, '.*')\n      .replace(/\\?/g, '\\\\?');\n    const regex = new RegExp(`^${regexPattern}$`);\n    return regex.test(url);\n  }\n}\n\n\n// Offline mode (TinSync): per-record sync state carried on rows via the _offline marker\nexport type OfflineOpStatus = 'pending' | 'syncing' | 'synced' | 'failed' | 'conflict' | 'stale';\n\n// Offline mode (TinSync): per-table opt-in configuration — absence of the property means ZERO offline machinery touches the table\nexport interface OfflineConfig {\n  enabled: boolean;\n  cacheRows?: number;                  // max rows persisted from the table loadAction list (default 500)\n  cacheLookups?: boolean | string[];   // true (default) = persist all field loadAction option lists reachable from formConfig; string[] = explicit URL allowlist\n  lookupMaxAgeHours?: number;          // staleness threshold for cached option lists (default 72)\n  queue?: { create?: boolean; edit?: boolean; delete?: boolean }; // which mutations queue offline — create/edit default true, delete default FALSE\n  maxQueueAgeHours?: number;           // ops older than this stop auto-replaying and flip to 'stale' (default 72)\n  readOnly?: boolean;                  // cache reads/lookups only, queue nothing\n}\n\nexport interface SearchField extends Field {\n  show?: boolean\n}\n\nexport class SearchConfig {\n  fields: SearchField[]\n  searchAction?: Action\n  emailResults?: boolean\n  tileConfig?: TileConfig\n}\n\n\n\nexport class SecurityConfig {\n  allow?: CapItem[];\n  deny?: CapItem[];\n}\n\n// Added: what a denied grid knows about its own refusal — computed at the gate from the config and the role,\n// never inferred from a response. Non-null ONLY when a capability was positively declared and is positively\n// lacked, which is what keeps a legitimately empty grid from ever acquiring a no-access banner.\nexport interface NoAccessInfo {\n  entity: string;      // 'Sales Order' — from formConfig.title, what the user calls the page\n  capDisplay: string;  // 'Sales Orders' — the CapItem.display an administrator would grant\n  capName: string;     // 'cap39' — for the log line and for support, never shown as the primary text\n}\n\nexport interface ChildField {\n  childField?: string\n  childValueField?: string\n}\n\nexport interface AutoRefreshConfig {\n  // Time between refreshes in milliseconds (default: 5000ms = 5 seconds)\n  interval?: number;\n  stopCondition?: (data: any) => boolean;\n  defaultOn?: boolean;\n}\n\n\n// Changed: unified visibility type — a static boolean or a data-driven condition; used by visible/hidden everywhere\nexport type VisibilityValue = boolean | ((value: any) => boolean);\n\nexport interface Field {\n  securityConfig?: SecurityConfig;\n  name: string;\n  // Added: the control's placeholder text. The spa-form BINDING for this already shipped (67ce57f,\n  // placeholder-passthrough-1), so a config placeholder works at runtime — but the property was missing from\n  // this interface, so a consumer literal declaring one failed to compile with TS2353 and the feature was\n  // unreachable from the only place anyone would use it. Type-only and purely additive: no default, no\n  // behaviour, and a field that does not declare one is unchanged.\n  placeholder?: string;\n  // 🔴 'email' IS A MULTI-ADDRESS CONTROL, not a single-address text box with validation. It renders a\n  // mat-chip-grid: each address becomes a removable chip, Enter and ';' both commit one, a paste is scanned for\n  // every address it contains, and the value is stored as a SEMICOLON-DELIMITED STRING ('a@x.com;b@y.com') —\n  // never a bare address. Its resting placeholder reads \"Enter email addresses\", plural. See\n  // components/email/email.component.ts.\n  //   ✅ Use it for   — a recipient LIST: notification targets, CC lines, \"who should be alerted\".\n  //   ❌ Not for      — a single contact column (a person's own email, an invoice's billing address). Those get\n  //                     one value each, and a chip control both invites a second one and stores a format the\n  //                     column does not expect. Use `type: 'email-single'` there.\n  // Changed (email-single): the single-address case now has its OWN type, `'email-single'`. It is a SEPARATE type\n  // and never a flag on `'email'` — the two store different things ('a@x.com' vs 'a@x.com;b@y.com'), so one\n  // control that did both would make the stored format depend on a config option, which no consumer column wants.\n  //   `'email-single'` renders the ORDINARY text box (spa-text, so every text affordance — placeholder, suffix,\n  //   copy/clear, hint, mat-error — behaves exactly as on `'text'`) with an anchored email pattern applied for\n  //   free. A field may still pass its own `regex` to override, and `hint` follows the usual convention below.\n  //   ⚠️ Existing `type: 'email'` fields are completely UNCHANGED. Nothing opts in by upgrading.\n  type: 'text' | 'email-single' | 'text-area' | 'text-single' | 'text-multi' | 'text-mask' | 'date' | 'date-short' | 'datetime' | 'datetimesec' | 'checkbox' | 'select' | 'select-multi' | 'money' | 'number' | 'section' | 'blank' | 'chip' | 'file' | 'file-view' | 'icon' | 'spinner' | 'button' | 'label' | 'email' | 'composite' | 'string' | 'html' | 'editor'; // Changed: added date-short (d MMM format); added editor (rich-text/WYSIWYG)\n  alias?: string;\n  options?: any[];\n  optionDisplay?: string\n  optionValue?: string\n  masterOptionValue?: string\n  // A literal value, or — on a DATE or DATETIME field — one of these dynamic tokens, resolved at RENDER time by\n  // Core.getInitialValue so an app left open across midnight or New Year cannot default to a stale day:\n  //   'now'        — the current instant, with the wall-clock time\n  //   'today'      — Added (DVT-1). MIDNIGHT of the local calendar day. Deliberately not the same as 'now': that\n  //                  distinction is the only reason the token is worth having, and it matches what the identical\n  //                  token already means as a min/max bound.\n  //   'today-7' / 'today+30' — whole-day offsets, same arithmetic as the bounds below\n  //   'yearStart'  — 1 January of the current year\n  // 🔑 The token vocabulary is SHARED with min/max (both resolve through DateBounds), so a word that works as a\n  // ceiling works as a default and means the same thing in both places.\n  // NOTE `defaultValue: ''` is honoured as a deliberate empty (E21) — it is NOT treated as \"no default\", which is\n  // how a date field opts OUT of being pre-filled.\n  defaultValue?: any\n  defaultFirstValue?: boolean\n  required?: boolean\n  requiredCondition?: (value: any) => boolean;\n  // For a number or money field these are plain numeric bounds. For a DATE or DATETIME field a bound may be:\n  //   a literal        '2026-01-01', a Date          — fixed for the life of the form\n  //   a dynamic token  'today', 'today-28', 'now'    — re-resolved every time the picker opens\n  //   a function       (row) => Date|string|null     — Added (SBD-1); re-EVALUATED every time the picker opens,\n  //                                                    with the form's live data object passed in as `row`\n  // 🔑 Reach for the FUNCTION form whenever the window depends on ANOTHER FIELD. It is PULLED at open time rather\n  // than pushed once, which is what makes it correct in the two cases a written value gets wrong: data that arrives\n  // AFTER the user has already made their choice, and a choice the user then CHANGES again. Writing field.min from\n  // an onSelectChange handler works only if every one of those pushes lands, and a push that is skipped leaves the\n  // previous window in force — see date.component.refreshBounds for the measured failure that motivated this.\n  min?: any\n  max?: any\n  rows?: number\n  span?: boolean\n  width?: string\n  size?: string\n  readonly?: boolean\n  hidden?: VisibilityValue // Changed: boolean | condition — hidden wins over visible on collision\n  visible?: VisibilityValue // Changed: boolean | condition — replaces the removed hiddenCondition (inverted sense)\n  preserveOnHide?: boolean // Added (C60): ESCAPE HATCH, default false. By default a field whose FUNCTION-VALUED hidden/visible (its own, or its section's) resolves to hidden at submit time has its key OMITTED from the outgoing payload — the value a predicate has taken out of sight is not something the operator can see or correct, and it was being posted and persisted (a credit sale stored PaymentMethod=Cash plus a payment reference nobody could see). Set true where a predicate hides a field that must STILL be submitted — e.g. a value computed by valueCalculation and shown only while relevant. Only ever affects the payload: this.data keeps the value either way, so re-showing the field restores what the user typed.\n  serverOwned?: boolean // Added (CFW-1): the SERVER computes this value — declare it only where the backing property carries [ServerOwned]. Three effects: the key is UNCONDITIONALLY omitted from the outgoing payload by Core.buildSubmitPayload (preserveOnHide is about predicates and does not apply), the field renders READ-ONLY in every mode including create and edit (Core.testReadOnly), and the value is never used to patch a grid row after a save. DEFENCE IN DEPTH ONLY — the server's [ServerOwned] exclusion is the real guarantee; nothing here may be load-bearing. Distinct from readonly, which is a UI hint testReadOnly also returns for every field in view mode and IGNORES in create mode.\n  readonlyAlways?: boolean // Added (readonly-always-1, ARBITER-RULED 2026-08-22 option A): DISPLAY LOCK ONLY — the field renders read-only in EVERY mode, create included, and unlike `readonly` it is not short-circuited by the create branch of Core.testReadOnly. Deliberately NARROWER than serverOwned in exactly one respect and that difference is the whole point: the value STILL RIDES THE OUTGOING PAYLOAD (buildSubmitPayload never reads this flag), so a field filled by valueCalculation or by a picker's onSelectChange keeps being submitted. Required-validation is untouched. Declare it on a read-only READOUT the operator must not overtype on a create form — a rate carried from a template, an identity being restocked, a stock figure computed in the picker. Keep `readonly: true` alongside it for edit-mode consistency with the rest of the estate.\n  strict?: boolean\n  path?: string\n  keyField?: string\n  // Persistent helper text under the control. CONVENTION: state what the field EXPECTS, not what it is — the\n  // mat-label already names it, so \"Email address\" as a hint spends the line saying nothing.\n  // 🔑 Where a control accepts MORE than its label implies, the hint is where that is disclosed, because the\n  // label cannot be. `type: 'email'` is the standing example: it takes a semicolon-separated LIST, which nothing\n  // in a label reading \"Notify\" would tell anyone — so give it `hint: 'Separate addresses with ;'`. Same\n  // obligation for a total-first amount (\"What you paid for all 8 pigs — $125.00 each\") and for any field whose\n  // accepted format is narrower or wider than its name suggests.\n  hint?: string\n  masterField?: string\n  masterValueField?: string\n  masterDefaultValueField?: string\n  // child?: ChildField\n  children?: ChildField[]\n  masterOptions?: any[]\n  optionsUnavailableOffline?: boolean // Added (WS-1): RUNTIME state, not config — set by form.component.ts's loadChildMasterOptions when a dependent select's option fetch died offline, read by select-common to draw the notice. Sits beside masterOptions deliberately: that is written onto the Field by the same method, for the same field, and is the existing precedent for this channel\n  nullable?: boolean\n  copyContent?: boolean\n  clearContent?: boolean\n  selectAll?: boolean // Changed: auto-select all options for select-multi\n  // Added: opt-in re-fetch for a loadAction URL carrying a {placeholder}. Absent or false is byte-identical to the\n  // previous behaviour — spa-select-multi fetched once in ngOnInit and never again, so a URL like\n  // 'pigs/list/bypen-{penID}' resolved with an empty penID at dialog open and stayed that way after the user picked\n  // a pen. The field already declares its dependency in the URL tokens, so no watched-field name is needed here.\n  // Two things ride on this flag together and both are required: form.component.ts leaves an UNRESOLVED token in\n  // place (rather than substituting '') so the component can decline to fetch a half-built URL, and select-multi\n  // clears its options + selection on a URL change and re-applies selectAll once the new options land.\n  refetchOnChange?: boolean\n  format?: 'text' | 'money' | 'date' | 'datetime' | 'number'\n  hideOnCreate?: boolean\n  hideOnExists?: boolean\n  readonlyCondition?: (value: any) => boolean;\n  detailsConfig?: DetailsDialogConfig;\n  loadAction?: Action\n  loadIDField?: string;\n  infoMessage?: string;\n  suffix?: string;\n  subfields?: Field[];\n  optionsSubject?: BehaviorSubject<any[]>;\n  section?: string;\n  fileOptions?: {\n    allowedExtensions?: string[];\n    maxSizeMB?: number;\n    compressImages?: boolean;\n  };\n  documentSource?: DocumentSource; // Added (Phase 6): type:'file-view' renders <spa-document> against the app's OWN authorized stream instead of the legacy <spa-viewer>, which resolved documents through ./assets/ or a PUBLIC Azure container. DocumentSource deliberately cannot express a direct storage URL — see DocumentClasses.ts. Changed (Phase 7, BREAKING): documentSource is now REQUIRED for the field to render at all — the legacy loadAction/path/keyField fallback to <spa-viewer> is deleted\n  collapsed?: boolean;\n  collapsedCondition?: (value: any) => boolean;\n  collapseOnView?: boolean; // Added: type:'section' — open while creating (everything the user must capture is in front of them), collapsed once the record exists so a crowded dialog's tabs stay above the fold. collapsedCondition still wins where the rule is data-driven rather than mode-driven.\n  maxHeight?: string;\n  editorConfig?: any; // Changed: pass-through AngularEditorConfig for type:'editor' (rich-text/WYSIWYG) fields\n  valueCalculation?: (value: any) => any;\n  regex?: {\n\n    pattern: string;\n    message: string;\n  };\n  onSelectChange?: (value: any, data: any, option?: any, config?: any) => void; // Changed (addpig-label-leak): trailing `config` — the LIVE FormConfig the form is rendering, so a handler can rewrite a SIBLING field's alias/hint and have it repaint. See onChange below for the full reason; both hooks get it so a select and a checkbox can drive the same handler // Changed: Added option parameter to provide direct access to selected option\n  icon?: Icon;\n  color?: string;\n  onChange?: (value: any, allValues: any, config?: any) => void; // Changed (addpig-label-leak): added the trailing `config` — the LIVE FormConfig object this form is rendering. A handler that must rewrite ANOTHER field's `alias`/`hint` (a label that depends on a sibling's value) previously had no way to reach it: it received only value + data, so app code reached for its own service-singleton config instead — and since 20.14.82 deep-clones the config per dialog open (42d665c), that write landed on an object the open dialog does not render and then leaked into the NEXT open. MEASURED on piglet :4203: after ticking a checkbox the live component's own field still read the old alias, while the next dialog opened with the mutated one. Writing the LIVE field object repaints both label and hint immediately (also measured), so handing the handler that object is the whole fix. Optional and TRAILING, so every existing 2-arg handler in the estate is untouched — JS ignores extra arguments\n}\n\nexport interface StatusState {\n  condition: (data: any) => boolean;\n  icon: string;                        \n  color: string;                       \n}\n\nexport interface StatusItem {\n  name: string;\n  hidden?: VisibilityValue; // Changed: replaces hiddenCondition\n  visible?: VisibilityValue; // Changed: unified visibility\n  states: StatusState[];\n}\n\nexport interface StatusConfig {\n  items: StatusItem[];\n  sticky?: boolean;\n  hidden?: VisibilityValue; // Changed: replaces hiddenCondition\n  visible?: VisibilityValue; // Changed: unified visibility\n}\n\n\nexport class AlertMessage {\n  type?: 'success' | 'info' | 'warn' | 'critical'\n  message?: string  // Changed: renamed from content to message\n  messageField?: string  // Changed: renamed from contentField to messageField\n  hidden?: VisibilityValue; // Changed: replaces hiddenCondition\n  visible?: VisibilityValue; // Changed: replaces showCondition\n}\n\nexport class AlertConfig {\n  subject?: string\n  compact? : boolean\n  sticky?: boolean \n  messages: AlertMessage[]\n}\n\nexport class NotesConfig {\n  title?: string;\n  loadAction?: Action;\n  loadIDField?: string;\n  notes?: any[];\n  nameField?: string;\n  dateField?: string;\n  commentField?: string;\n}\n\nexport class FormConfig {\n  title?: string\n  fixedTitle?: boolean\n  alertConfig?: AlertConfig\n  fields: Field[]\n  mode?: 'create' | 'edit' | 'view'\n  button? : Button\n  multiColumn?: boolean\n  reset?: boolean\n  loadAction?: Action\n  heroField?: any\n  heroValue?: any\n  security?: SecurityConfig;\n  includeAudit?: boolean\n  notesConfig?: NotesConfig;\n  preserveHiddenValues?: boolean // Added (C60): ESCAPE HATCH, default false — form-wide opt-out of the predicate-hidden payload filter described on Field.preserveOnHide. Set true to post this.data verbatim, exactly as every form did before C60. Prefer the per-field preserveOnHide: this one disables the protection for the whole form.\n}\n\nexport interface Confirm {\n  message?: string\n  func?: (data: any) => string;\n  // Added: name the action being confirmed instead of answering a question. A destructive prompt reading\n  // \"Keep\" / \"Delete\" states the consequence on the button the user is about to press; \"Yes\" / \"No\" makes them\n  // re-read the sentence to work out which way round it is. Only the config knows the intent — the dialog is\n  // handed a sentence — so the distinction can only come from here.\n  // ⚠️ ALL THREE ARE UNDEFINED BY DEFAULT and must stay that way: an omitted label renders \"Yes\" / \"No\" exactly\n  // as before, which is what every untracked consumer outside this workspace relies on, and what the 51 E2E\n  // assertions that select these buttons expect. Opting in is per call site, never global.\n  confirmLabel?: string; // Added: label for the affirmative button — 'Delete', 'Void', 'Discard'\n  cancelLabel?: string; // Added: label for the dismissive button — 'Keep'\n  destructive?: boolean; // Added: true colours the affirmative action as a warning (red) and the safe one as neutral\n  // Added (N22): demand the user TYPE this exact phrase before the affirmative button enables. Undefined by\n  // default like the three above, and the default path is untouched — a confirm without it still closes with the\n  // bare 'yes' / 'no' string, which is what the 51 E2E assertions and every untracked consumer rely on.\n  // 🔴 The comparison is ORDINAL and CASE-SENSITIVE, and that is not a style choice: it mirrors the server's own\n  // `string.Equals(request?.Phrase, ResetPhrase, StringComparison.Ordinal)`\n  // (AppConfigurationControllerBase.cs:165). A `.trim()` or `.toLowerCase()` anywhere on the client would ENABLE\n  // the button on text the server then REJECTS, leaving the user a bare \"Reset not confirmed\" and nothing on\n  // screen explaining why.\n  // ⚠️ Setting this changes the dialog's CLOSE SHAPE to `{ response, phrase }` — the typed text has to reach the\n  // server, which re-validates independently. The library call sites unwrap both shapes via\n  // ButtonService.confirmAccepted / confirmPhrase; a hand-written subscriber that only tests `result === 'yes'`\n  // must be updated before it sets this.\n  requirePhrase?: string;\n}\n\nexport interface Button{\n  name: string\n  visible?: VisibilityValue; // Changed: widened to boolean | condition\n  hidden?: VisibilityValue; // Changed: unified visibility — hidden wins over visible on collision\n  display?: string;\n  icon?: Icon;\n  disabled?: (value: any) => boolean;\n  color?: string;\n  tip?: string\n  dialog?: boolean\n  action?: Action\n  confirm?: Confirm\n  inDialog?: boolean\n  inHeader?: boolean\n  // Added: OPT-IN — make a details-dialog FOOTER button's close emit under its OWN name. Without it, table.component\n  // open() emits every success/emit close under the name of the button that OPENED the dialog, so an `inDialog: true`\n  // button is a pure silent no-op at the host: shift-spa's Location button closed the dialog and the map never opened\n  // because the host received actionClick('view'), never 'location' (GPS phase 6, 2026-08-19). It is opt-in and NOT\n  // the default because the framework approvals buttons (Approve/Decline/Cancel) are all inDialog and have emitted\n  // under the opener's name since they existed — flipping that would rewrite the event name for approvals in five\n  // apps, and consumer apps outside this workspace use tin-spa too.\n  emitOwnName?: boolean;\n  detailsConfig?: DetailsDialogConfig\n  setHeroField?: boolean;\n  ignorePendingApproval?: boolean;\n  keepOpen?: boolean;\n  onSuccess?: (response: ApiResponse, details: any) => void;\n  onClick?: (details: any, reload?: () => void) => void; // Changed: SECOND ARGUMENT `reload` — a pure onClick is terminal (the host returns the moment it comes back), so a handler that runs its own multi-call job had no way to say \"the list I just changed is stale, fetch it again\" and two apps reached for window.location.reload(). Call reload() when the work settles. Purely additive: a one-parameter handler is still assignable and, calling nothing, behaves exactly as before. NOT a widened RETURN type — six live handlers are concise-body `() => router.navigate(...)`, so returning a Promise would silently start reloading after every navigation\n  editOnSuccess?: boolean\n  onSuccessButton?: Button\n  skipValidation?: boolean\n  resetMode?: 'create' | 'edit'; // Reset dialog to this mode after keepOpen success\n  rowDataMap?: Record<string, string | ((data: any) => any)>; // Changed: Map row data fields — string for simple mapping, function for computed values\n  capability?: CapItem | string; // Added: OPT-IN capability gate — the role column the SERVER checks for this button's action. Pass the CapItem OBJECT (`this.dataService.capTrips`), exactly as SecurityConfig.allow does, so the name resolves at CALL time: CapItem's constructor sets name = \"\" and datalib assigns \"cap53\" later, so an eagerly-read `.name` would capture \"\" and silently gate nothing. A literal string is accepted too. Omit it and the button behaves exactly as before; a CUSTOM-named button is otherwise ungated because hasRequiredAccess() maps only view/edit/create/delete\n  requiredAccess?: RoleAccess; // Added: level `capability` must reach, mirroring the server. Defaults to RoleAccess.Edit — BaseController.CustomActionAccess's floor for every custom action. Use Create for `?action=create` posts and Full where the controller raises the bar\n}\n\n\nexport interface CapsuleConfig {\n  displayField: string;\n  leftIcons?: Icon[];\n  rightIcons?: Icon[];\n  // buttons?: Button[];\n  loadAction?: Action;\n}\n\nexport interface CardConfig {\n  imageField?: string;\n  titleField: string;\n  subtitleField?: string;\n  contentFields: string[];\n  columns?: number;\n  elevation?: 'low' | 'medium' | 'high';\n}\n\n// Changed: Added tile style type for different visual modes\nexport type TileStyle = 'basic' | 'icon' | 'chart';\n\n// Changed: Added chart type for tile chart style\nexport type TileChartType = 'line' | 'bar' | 'pie' | 'doughnut';\n\n// Changed: Added chart config for tile chart style\nexport interface TileChartConfig {\n  type: TileChartType;               // Chart type to render\n  dataField?: string;                 // Changed: Made optional — Field name from API response containing Chart.js data\n  data?: any;                         // Changed: Added inline Chart.js data (alternative to dataField)\n  color?: string;                     // Primary chart color\n  colors?: string[];                  // Multiple series/segment colors\n  height?: number;                    // Chart height in px (default 120)\n  gaugeValue?: number;                // Doughnut gauge: percentage (0-100), auto-generates data\n  gaugeColor?: string;                // Doughnut gauge: fill color\n}\n\nexport interface Tile {\n\n  name: string;\n  alias?: string;\n  value?: string;\n  color?: string | ((data: any) => string); // Changed: widened to a function of the tile DATA — a figure whose colour depends on its own value (outstanding red / settled green) had no config expression before, only a static colour\n  format?: 'money' | 'number'; // Added: format the tile figure. 'money' renders 1,234.50 exactly as the table's money column does; 'number' matches the number column. Absent = the raw value, which is what every existing tile keeps.\n  selectedTile?: string;\n  hidden?: VisibilityValue; // Changed: boolean | condition — absorbs removed hiddenCondition\n  visible?: VisibilityValue; // Changed: unified visibility\n  info?: string;\n  prefix?: string;\n  suffix?: string;\n  action?: Action;\n  // Changed: Added properties for icon and chart tile styles\n  style?: TileStyle;                  // Tile visual mode: 'basic' (default), 'icon', 'chart'\n  icon?: string;                      // Mat-icon name for icon style (e.g., 'storage', 'attach_money')\n  footer?: string;                    // Footer text (for icon and chart styles)\n  footerIcon?: string;                // Footer mat-icon name\n  badge?: string;                     // Badge field name from API response (e.g., '+18%')\n  badgeColor?: string;                // Badge background color\n  chart?: TileChartConfig;            // Chart config for chart style\n  filter?: (row: any) => boolean;     // Added: client-side row filter for LOCAL-data tables — a clicked tile filters the grid in memory (no loadAction swap); unclick restores all rows\n  data?: any;                         // Added: arbitrary host payload carried on the tile (e.g. a section key the click handler resolves)\n}\n// Added: one quick-filter chip in the row that sits directly under the tiles. Deliberately shaped like Tile:\n// a chip filters EITHER by swapping the table's loadAction (`action` — the server narrows the result) OR by a\n// client predicate (`filter` — the rows already in memory are narrowed). Those are the same two paths\n// tileClicked() has always had, so a chip is not a new mechanism, only a new control surface for the old one.\nexport interface FilterChip {\n  key: string;                        // identity of the chip; 'all' is reserved for the leading All chip\n  label: string;                      // what the user reads on the pill\n  icon?: string;                      // optional leading mat-icon, exactly as a Day Book lane pill carries one\n  count?: number;                     // optional trailing count bubble\n  action?: Action;                    // SERVER mode: replaces the table's loadAction while this chip is selected\n  filter?: (row: any) => boolean;     // LOCAL mode: narrows the rows already loaded, no round trip\n  data?: any;                         // arbitrary host payload (dynamic chips carry their source row here)\n  hidden?: VisibilityValue;           // same visibility contract every other library item uses\n  visible?: VisibilityValue;\n}\n\n// Added: the quick-filter chip row. STRICTLY OPT-IN — a TableConfig that does not declare `chipConfig` renders\n// exactly as it does today, which is the guarantee owed to the untracked external consumers of this library.\n// Two sourcing modes, both supported:\n//   STATIC  — `chips` are declared in the config, the way the Day Book declares its lanes.\n//   DYNAMIC — `loadAction` fetches the chips from the server ({ id, name } from the base controller's list\n//             projection), and `chipAction` is the per-chip template whose {value} is substituted with each\n//             row's id. This is the mode Piglet's shelter chips use.\n// If both are given, the static chips are placed first and the loaded ones appended after them.\nexport class FilterChipConfig {\n  chips?: FilterChip[]                // STATIC mode\n  loadAction?: Action                 // DYNAMIC mode: returns the rows the chips are built from\n  chipAction?: Action                 // DYNAMIC mode: per-chip action template; {value} -> the row's id\n  chipFilter?: (row: any, chip: FilterChip) => boolean; // DYNAMIC alternative to chipAction — filter in memory instead\n  valueField?: string                 // field on a loaded row to use as the chip key (default 'value' — BaseController.GetList projects ListOption { Name, Value })\n  labelField?: string                 // field on a loaded row to use as the chip label (default 'name')\n  icon?: string                       // icon applied to every dynamically-built chip\n  showAll?: boolean                   // default true — the leading \"All\" chip the owner asked to always be first\n  allLabel?: string                   // default 'All'\n  allIcon?: string                    // optional icon for the All chip\n  default?: string                    // key selected on load (default 'all'); a configurable default, as asked\n  layout?: 'wrap' | 'carousel'        // default 'carousel' — one scrollable row with arrows, the Day Book feel\n  remember?: string                   // localStorage key; when set, the chosen chip survives a reload\n}\n\nexport class TileConfig {\n  tiles: Tile[]\n  loadAction?: Action\n  loadInit?: boolean\n  clickable?: boolean\n  headerPosition?: | 'top' | 'middle';\n  quietLoading?: boolean; // Added (Quiet Loading): overrides AppConfig.quietLoading for these tiles — an explicit false opts OUT of an app-wide opt-in\n  // Added: how a tile row behaves when there are more tiles than fit.\n  // 'auto' (DEFAULT, and what every existing page gets) — the original behaviour: tiles stretch to fill the\n  //   row and shrink to a 150px floor, wrapping when they run out of room. Left as the default deliberately;\n  //   briefly making 'wrap' the default regressed every page on a phone (one tile per row).\n  // 'wrap' — a grid of equal-width tracks: tiles that do not fit flow onto the next row at the SAME width.\n  // 'carousel' — one row, horizontal scroll with arrows. What the Day Book uses.\n  layout?: 'auto' | 'wrap' | 'carousel';\n  minTileWidth?: number;  // Added: px floor for one tile (default 200). 'wrap' and 'carousel' only — 'auto' keeps its original 150px\n  maxPerRow?: number;     // Added: 'wrap' only — hard cap on tiles per row regardless of how many would fit\n  hideValueOnMobile?: boolean; // Added: drop the money badge under 700px. Opt-in, because on most pages the badge is the only place that number appears — the Day Book sets it since the figure is already on the group header\n}\n\n// Changed: Added chart type union for standalone charts component\nexport type SpaChartType = 'line' | 'bar' | 'pie' | 'doughnut';\n\n// Changed: Added individual chart definition interface\nexport interface ChartItem {\n  name: string;                      // Unique identifier\n  title?: string;                    // Card title\n  subtitle?: string;                 // Card subtitle\n  footer?: string;                   // Footer text\n  footerIcon?: string;               // Mat-icon name for footer\n  type: SpaChartType;                // Chart type\n  loadAction?: Action;               // URL to load Chart.js-format data\n  data?: any;                        // Pre-loaded data (alternative to loadAction)\n  colors?: string[];                 // Series/segment colors\n  height?: string;                   // Chart area height (default '300px')\n  showLegend?: boolean;              // Changed: Show Chart.js auto-generated legend below chart\n  showPoints?: boolean;              // Line chart: show data points\n  tension?: number;                  // Line chart: curve tension (0=straight, 0.4=smooth)\n  gaugeValue?: number;               // Doughnut gauge: percentage (0-100), auto-generates data\n  gaugeColor?: string;               // Doughnut gauge: fill color\n  hidden?: VisibilityValue;          // Changed: boolean | condition — absorbs removed hiddenCondition\n  visible?: VisibilityValue;         // Changed: unified visibility\n  options?: any;                     // Chart.js options passthrough\n}\n\n// Changed: Added chart config container class\nexport class ChartConfig {\n  charts: ChartItem[];               // Array of chart definitions\n  loadAction?: Action;               // Single endpoint returning all chart data by name\n  loadInit?: boolean;                // Auto-load on component init\n  columns?: number;                  // Fixed grid columns (default: responsive auto-fit)\n}\n\nexport class Step {\n  name: string\n  value?: any\n  icon?: string;\n  hidden?: VisibilityValue; // Changed: replaces hiddenCondition\n  visible?: VisibilityValue; // Changed: unified visibility\n}\nexport class StepConfig {\n  steps: Step[]\n  valueField?: string\n  loadAction?: Action;\n  loadIDField?: string;\n  sticky?: boolean \n}\n\nexport interface Icon {\n  name: string\n  color?: string\n  tip?: string\n  tipField?: string\n  bannerField?: string\n  condition?: (value: any) => boolean;\n}\n\nexport interface Color {\n  name: string\n  condition?: (value: any) => boolean;\n}\n\n\nexport interface GroupData {\n  groupValue: any;\n  displayName: string;\n  icon?: string;\n  color?: string;\n  items: any[];\n  order: number;\n}\n\n\nexport interface GroupConfig {\n  // Server response field mapping (defaults match GroupedItemDto property names)\n  groupValueField?: string;       // Default: 'groupValue'\n  displayNameField?: string;      // Default: 'displayName'\n  iconField?: string;             // Default: 'icon'\n  colorField?: string;            // Default: 'color'\n  orderField?: string;            // Default: 'order'\n  itemsField?: string;            // Default: 'items'\n\n  // Item display\n  itemTextField: string;\n  itemIcon?: Icon;\n  itemIcons?: Icon[];\n  itemAdditionalIcons?: Icon[];\n\n  // Group display\n  groupIcons?: Icon[];\n  showGroupCount?: boolean;\n  emptyGroupMessage?: string;\n  showEmptyGroups?: boolean;\n\n  // Actions\n  headerButtons?: Button[];\n  contextMenuEnabled?: boolean;\n\n  // Filter\n  filterEnabled?: boolean; // Changed: Show search input above groups (default: true for grouped views)\n\n  // Drag and drop\n  dragEnabled?: boolean;\n  dropAction?: Action;\n}\n\nexport interface Column {\n  name: string;\n  type?: 'text' | 'date' | 'date-short' | 'datetime' | 'datetimesec' | 'checkbox' | 'select' | 'money' | 'number' | 'chip' | 'chips' | 'icon' | 'spinner' | 'button' | 'monogram'; // Changed: added chips — an ARRAY field renders one chip per item instead of interpolating as '12,13'; each chip drills into ITS OWN record, not the row's. Changed earlier: added monogram — renders a person's name as a deterministic coloured initials circle; sorting/filtering still use the underlying value\n  alias?: string;\n  keyField?: string; // Changed: monogram only — row field holding the STABLE identity (e.g. 'createdBy' username) that seeds the colour; falls back to the normalized display value when absent\n  listField?: string; // Added: chips only — the row field holding the array; defaults to name. Separate from name so the column can be named/sorted on one field and list another\n  idField?: string; // Added: chips only — the property the CLICKED ITEM is handed to detailsConfig under, i.e. that dialog's heroField (e.g. 'rentalID' for an invoice's rentalIDs). Without it a scalar item has no identity to open, so the chip stays inert rather than opening the ROW — the drill-in must be about the item, never the record that merely references it\n  maxLength?: number;\n  icon?: Icon;\n  color?: Color;\n  colors?: Color[];\n  icons?: Icon[];\n  options?: any[];\n  optionDisplay?: string\n  optionValue?: string\n  detailsConfig?: DetailsDialogConfig\n  hidden?: VisibilityValue; // Changed: replaces hiddenCondition — condition receives parentData\n  visible?: VisibilityValue; // Changed: unified visibility\n}\n\n\n// Added: opt-in inline row editing — edit opens the row's cells in place instead of a dialog\nexport interface InlineEditConfig {\n  fields?: string[] // subset of column names editable inline; default = all columns with a matching formConfig field\n}\n\n// Added: one-step create — marks a nested tab as visible during create mode; its rows are kept in memory\n// on the parent form model under navigationProperty and submitted with the parent in a single POST\nexport interface CreateTabConfig {\n  navigationProperty: string // parent model property the local rows bind to — must match the backend navigation property's JSON name (e.g. 'items')\n}\n\n// Added: opt-in server-side pagination — presence of TableConfig.pagination activates paged mode\nexport class PaginationConfig {\n  pageSize?: number // server fetch chunk per request (default 20); display page size stays paginator-driven via TableConfig.pageSizes\n}\n\n// Added: opt-in drag-to-reorder rows. Pairs with the backend IOrder convention — the entity must implement\n// TinWeb's IOrder or the reorder POST is refused; nothing here can make a non-IOrder entity orderable.\n// The client posts the COMPLETE ordered id list for one scope and never posts order numbers: position IS the\n// order and the server assigns 1..N, which is what lets its set-comparison guard detect a stale page instead\n// of silently scrambling somebody else's arrangement (see TinWeb Contracts\\ReorderRequest.cs).\nexport interface OrderableConfig {\n  scopeField?: string    // row field holding the [OrderScope] value; omit entirely for a flat tenant-wide sequence\n  scopeValue?: any       // explicit scope when it is not on the rows (Pen Overview: the chosen shelter). Wins over scopeField\n  action?: Action        // defaults to { url: '<entity>/reorder', method: 'post' } derived from loadAction\n  handle?: boolean       // true = drag only by the grip handle; false/absent = the whole row is the drag target\n  idField?: string       // row field carrying the entity id; defaults to heroField, then the row's own ...ID key\n}\n\nexport type TableViewType = 'table' | 'capsule' | 'card' | 'grouped';\nexport class TableConfig{\n  viewType?: TableViewType \n  capsuleConfig?: CapsuleConfig\n  cardConfig?: CardConfig\n  groupConfig?: GroupConfig\n  tabTitle?: string\n  tabTemplate?: any // Added: TemplateRef rendered as the tab's content instead of a spa-table (assigned at runtime by the host component); count badge (countAction) + lazy loading still apply\n  noDataMessage ?: string\n  columns? : Column[]\n  minColumns?: string[]\n  // Added (clickable identity): which column names the thing a row IS — the invoice number on an invoice, the\n  // trip number on a trip — as opposed to a column that merely mentions a RELATED entity (a trip’s vehicle name).\n  // DECLARED, never guessed. A “first name-ish column” rule was built and measured against the 46 configs whose\n  // authors had already declared an identity in code: it picked a column a human would not on 47.8% of them,\n  // including hanging a work order’s identity on the VEHICLE’s name. So the library resolves a declaration; it\n  // never infers one. `false` states positively that this table’s rows are not entities (aggregate, report and\n  // summary grids) — which also means no locked-row cue, because there is no identity on screen to decorate.\n  // Absent, the existing name -> description -> id/PK convention applies unchanged, exactly as it did before.\n  identityColumn?: string | false\n  showFilter?: boolean\n  showFilterButton?: boolean\n  holdFilterSpace?: boolean\n  holdHeaderButtonSpace?: boolean\n  elevation?: 'none' | 'low' | 'medium' | 'high'\n  formConfig?: FormConfig\n  searchConfig?: SearchConfig\n  tileConfig?: TileConfig\n  chipConfig?: FilterChipConfig // Added: opt-in quick-filter chip row rendered directly under the tile row. Absent = no chip row and no behaviour change whatsoever.\n  stepConfig?: StepConfig\n  buttons?: Button[]\n  minButtons?: string[]\n  loadAction?: Action\n  countAction?: Action\n  loadIDField ?: string\n  loadCriteria?: string\n  lazyLoad?: boolean\n  causeFormRefresh?: boolean\n  logResponse?: boolean\n  flatButtons?: boolean\n  greyOut?: (value: any) => boolean;\n  heroField?: any\n  heroValue?: any\n  collapseButtons?: boolean\n  parentData ? : any\n  pageSizes?: number[]\n  maxButtonsCount?: number\n  hidden?: VisibilityValue; // Changed: replaces hideTabCondition — hides this table's tab (condition receives parent details)\n  visible?: VisibilityValue; // Changed: unified visibility for the tab\n\n  download?: { columns: string[], fileName?: string, hidden?: VisibilityValue, visible?: VisibilityValue } // Changed: hiddenCondition → hidden/visible\n  upload?: { action: Action, messages?: AlertMessage[], hidden?: VisibilityValue, visible?: VisibilityValue } // Changed: hiddenCondition → hidden/visible\n  import?: ImportConfig // Added: generic AI-assisted data import wizard (spa-import-dialog)\n  realTime?: boolean // Changed: Enable real-time SignalR updates — skips refresh after CUD operations\n  realTimeFallbackMs?: number // Added: how long a real-time table waits for its own write to arrive as a broadcast before falling back to a refresh (default 3000)\n  entityName?: string // Changed: Entity name for SignalR subscription (defaults to URL-derived name)\n  offline?: OfflineConfig | boolean // Added: TinSync offline opt-in — boolean shorthand: true === { enabled: true } with defaults\n  pagination?: PaginationConfig // Added: opt-in server-side pagination — chunked fetches with true server total; disabled when offline is set (offline wins)\n  // Added: opt-in drag-to-reorder. STRICTLY OPT-IN — a TableConfig that does not declare `orderable` renders\n  // ZERO drag affordances and behaves exactly as it did before, which is the regression guard the spec pins.\n  // `true` is shorthand for `{}`. Dragging is suppressed while the natural view is not on screen — an active\n  // filter or a scope spanning more than one page — because the contract requires the COMPLETE scope.\n  orderable?: OrderableConfig | boolean\n  allowUserKeepOpen?: boolean; // Added: propagates to inline DetailsDialogConfig for buttons without their own detailsConfig\n  keepOpenBehavior?: 'reset' | 'edit'; // Added: controls what happens after successful create when user has Keep Open ticked — 'reset' clears form for next entry (default), 'edit' switches to edit mode with new entity\n  inlineEdit?: boolean | InlineEditConfig // Added: edit opens the row cells in place (submit/cancel icons) instead of a dialog\n  createConfig?: CreateTabConfig // Added: one-step create — show this nested tab during create with rows kept in memory on the parent model\n  quietLoading?: boolean // Added (Quiet Loading): overrides AppConfig.quietLoading for this table — an explicit false opts OUT of an app-wide opt-in\n  sectionConfig?: TableSectionConfig // Added: collapsible flat section header wrapped around the table (Day Book sections)\n  // Added (delivered-order-lines-ui-gate): the table's own one-line \"why this list is the way it is\", drawn in\n  // the SAME <p class=\"tbl-section-caption\"> the section header already uses — reach extended from\n  // sectionConfig to the table itself, no second mechanism and no new styling. It exists because a table whose\n  // write buttons are HIDDEN by a `hidden` predicate otherwise says nothing at all about why they are gone.\n  // May be a function so it can read config.parentData and name the remedy that actually applies (the\n  // string | fn form is precedented on DayBookSection.caption). NOT the read-only annotation bar removed on\n  // 2026-08-19 — that one was unconditional and told every dialog the same content-free thing; this renders\n  // only when a config asks for it, and carries the remedy the server names when it refuses the write.\n  caption?: string | ((parent: any) => string)\n  hideColumnHeaders?: boolean // Added: suppress the column-name header row (grid-look sections)\n  // Added (phone density): drop the paginator on a PHONE when every row already fits on one page. A pager\n  // reading \"1 – 4 of 4\" is 56px spent navigating nothing — the single largest item in a Day Book section\n  // card, which is otherwise 46px of section header + 50px of column headers around 4 rows. It stays on\n  // desktop, and it stays on a phone the moment there is a second page to reach.\n  // OPT-IN, and deliberately so: a library default is a contract with consumer apps that are not in this\n  // workspace, so this changes nothing for a table that does not ask for it.\n  hideSinglePagePaginator?: boolean\n}\n\n// Added: collapsible flat section header for spa-table — icon, title, count pill, summary chips, bulk\n// buttons, chevron. 1px-border flat styling (no elevation). Collapse state lives on the component, never\n// on this shared config; `collapsed` only seeds the initial state.\nexport interface TableSectionChip { text?: string; color?: string; hidden?: VisibilityValue; visible?: VisibilityValue; } // visibility predicates receive the table's rows\nexport interface TableSectionConfig { title: string; icon?: string; caption?: string; showCount?: boolean; chips?: TableSectionChip[]; buttons?: Button[]; collapsible?: boolean; collapsed?: boolean; hideWhenEmpty?: boolean; } // Changed: caption — the one-line \"why this list exists\", drawn under the title where it belongs (a chip is too short to carry it)\n\nexport class PageConfig {\n  title?: string;\n  tableConfig?: TableConfig;\n  searchTableConfig?: TableConfig;\n  titleActions?: Field[];\n}\n\n// Generic AI-assisted data import wizard config — enables a \"spa-import-dialog\" wizard on a table\nexport interface ImportConfig {\n  entity: string;                          // backend endpoint key, e.g. 'equipments'\n  title?: string;                          // dialog title, default 'Import ' + entity\n  securityConfig?: SecurityConfig;         // hide the Import button per capabilities\n  hidden?: VisibilityValue;                // Changed: replaces hiddenCondition\n  visible?: VisibilityValue;               // Changed: unified visibility\n  onComplete?: (summary: any) => void;     // called after a successful commit\n}\n\n\n\n\n//---Base---\n\nexport class ApiResponse {\n  success: boolean;\n  message: string;\n  data;\n  total?: number; // Added: true server row count — present IFF the server actually paged the response\n  reason?: string; // Added: machine-readable failure class from RepoResponse (\"conflict\" | \"not_found\" | \"validation\") — \"conflict\" means the record was modified by another user and data carries the fresh server row\n  rowVersion?: string; // Added: refreshed optimistic-concurrency token after a successful edit — patched back into the open record so it can be saved again without a reload\n  fileMessage?: string; // Added (Phase 6): RepoResponse.FileMessage — what HandleSaveFiles made of the uploaded files (BaseController.cs:920/933/949). 🔴 It is INDEPENDENT of `success`: the record can save while every attachment is rejected, which is exactly the case that used to report a plain \"Submitted\". camelCase because that is what the wire carries, as confirmed on the live stream in Phase 3\n}\n\nexport class Constants {\n  public static readonly AUTH_USER = 'a';\n  public static readonly AUTH_NAME = 'b';\n  public static readonly AUTH_ROLES = 'c';\n  public static readonly AUTH_TOKEN = 'd';\n  public static readonly AUTH_TOKEN_EXPIRE = 'e';\n  public static readonly AUTH_TENANT_NAME = 'f';\n  public static readonly AUTH_REFRESH_TOKEN = 'g'; // Changed: Added for refresh token storage\n  public static readonly AUTH_REFRESH_TOKEN_EXPIRE = 'h'; // Changed: Added for refresh token expiry\n  public static readonly AUTH_REMEMBER_ME = 'r'; // Changed: Added for remember me flag\n  public static readonly AUTH_TYPE = 'i'; // Added: the signed-in user's AuthType ('local' | 'AD' | 'google' | ...) — surfaces that only apply to password-backed accounts need it after a reload, not just at login\n  public static readonly LAST_ROUTE = 'lr'; // Added: last visited route per user, for resumeLastRoute (persistent — survives browser close)\n}\n\nexport class ListDialogConfig {\n  name: string;\n  title: string;\n  listName: string;\n}\n\n// Added: payload for DialogService.openTableDialog — a READ-ONLY window onto an entity list, hosted in a MatDialog.\n// config is the entity own TableConfig, spread by the caller, so the dialog reads through THAT capability-gated\n// loadAction and never through a route that is merely [Authorize]-gated. spa-table-dialog hardens whatever arrives here\n// (readOnlyTableConfig) — read-only is enforced by the dialog, never assumed of the caller.\nexport interface TableDialogConfig { title: string; subtitle?: string; config: TableConfig; } // Changed: subtitle is now UNRENDERED — its only render site was the read-only annotation bar removed on 2026-08-19. Kept, not deleted, so untracked consumers passing it still compile; it is simply ignored.\n\nexport class CapItem {\n\n  constructor() {\n    this.name = \"\";\n    this.display = \"New Cap Item\";\n    this.enabled = false;\n    this.type = \"\";\n    this.newLine = false;\n    this.showMenu = true;\n    this.ignoreSubsDisplay = false;\n    this.link = \"\";\n    this.icon = \"navigate_next\";\n    this.color = \"black\";\n    this.isBool = false;\n    this.featureKey = \"\"; // Added: default empty — no feature restriction\n    this.moduleKey = \"\"; // Added (Setup v2): default empty — no module restriction\n\n  }\n\n  name: string;\n  display: string;\n  enabled: boolean;\n  showMenu: boolean;\n\n  ignoreSubsDisplay: boolean;\n  type: string;\n  newLine: boolean;\n  link: string;\n  icon: string;\n  capSubItems: CapItem[];\n  color: string;\n  isBool : boolean;\n  featureKey: string; // Added: maps to subscription feature key for plan-based gating\n  moduleKey: string; // Added (Setup v2): maps to a SetupModule key — menu hidden while that module is disabled\n\n}\n\n// Added: one cell of the mobile bottom tab bar (spa-bottom-tabs). Config-driven like CapItem so an app can\n// rename/relink/reorder its tabs without touching the library. badge names a live count stream ('notifications'\n// is the only one wired today); moduleKey reuses the Setup-module gating contract that already hides menus.\nexport class BottomTab {\n\n  constructor() {\n    this.name = \"\";\n    this.display = \"New Tab\";\n    this.icon = \"navigate_next\";\n    this.link = \"\";\n    this.badge = \"\"; // Added: default empty — no badge\n    this.moduleKey = \"\"; // Added: default empty — no module restriction\n    this.requires = undefined; // Added (DBT-1): default undefined — no SURFACE requirement, so a hand-written tab is gated exactly as it is today\n  }\n\n  name: string;\n  display: string;\n  icon: string;\n  link: string;\n  badge?: 'notifications' | ''; // Added: which live count decorates this tab\n  moduleKey?: string; // Added: maps to a SetupModule key — tab hidden while that module is disabled\n\n  // Added (DBT-1): names a library SURFACE this tab leads to, so the tab can be ABSENT when the surface does not\n  // exist in this app rather than being a cell that navigates to an empty state. This is a different question\n  // from moduleKey and that is why it is a separate property: moduleKey asks \"has this TENANT switched the\n  // module on\", which presupposes tenancy and a Getting Started toggle, while `requires` asks \"does this APP\n  // configure the surface at all\" — a build-time fact that is true or false before anyone logs in.\n  // 'dayBook' resolves against AppConfig.dayBookConfig, whose absence already disables the feature (see its\n  // declaration below). Undefined — the default — means no surface requirement, which is why every existing\n  // hand-written tab is unaffected.\n  requires?: 'dayBook';\n\n}\n\nexport class AppConfig {\n  constructor() {\n    this.appName = \"App Name\";\n    this.logo = \"\";\n    this.logoSize = \"normal\";\n    this.ADAuth = true;\n    this.localAuth = true;\n    this.googleAuth = false;\n    this.microsoftAuth = false;\n    this.microsoftAuthMessage = \"Sign in with Microsoft\";\n    this.selfService = false;\n    this.multitenant = false;\n    this.navigation = 'top';\n    // Changed: progressLine removed — it was inert since 2026-08-05 and no app assigns it any more; quietLoading owns the dialog's progress line\n    this.loginStyle = 'default';\n    this.dialogStyle = 'default'; // Added: opt-in modern dialog styling — 'default' keeps the long-standing look for every existing app\n    this.termsUrl = \"\";\n    this.privacyUrl = \"\";\n    this.siteUrl = \"https://alsquaretech.net/\";\n    this.navWidth = '200px';\n    this.navColor = 'rgba(0,0,0,0.78)'; // Changed: Default dark overlay for side-modern sidebar\n    this.navImage = ''; // Changed: Default no background image for side-modern sidebar\n    this.keepSignedIn = false; // Changed: Hide \"Keep me signed in\" unless explicitly enabled\n    this.resumeLastRoute = false; // Added: opt-in — off by default so existing apps keep landing on their default page\n    this.quietLoading = false; // Added: opt-in — off by default so existing apps keep the classic full-screen loader\n\n    // Added: default bottom tabs — the mobile-only bar, so every app gets it with zero config. Notifications\n    // earns a slot because every layout hides its bell behind *ngIf=\"!smallScreen\", leaving phones no way in.\n    // 'home/day-book' resolves per app (shared page or the app's own), so one default link works everywhere.\n    this.bottomTabs = [\n      { name: 'home', display: 'Home', icon: 'home', link: 'home', badge: '', moduleKey: '' },\n      { name: 'daybook', display: 'Day Book', icon: 'menu_book', link: 'home/day-book', badge: '', moduleKey: '', requires: 'dayBook' }, // Changed (DBT-1): Day Book cannot exist without an app-supplied dayBookConfig, so the DEFAULT tab bar was offering a quarter of its cells to an empty state in every app that never configured one. `requires` makes the tab absent there instead of dead. moduleKey stays '' deliberately — Day Book is not a Getting Started module and gating it as one would ALSO hide it in single-tenant apps that do configure it.\n      { name: 'notifications', display: 'Alerts', icon: 'notifications', link: 'home/workflow/notifications', badge: 'notifications', moduleKey: '' },\n      { name: 'agent', display: 'Chat', icon: 'chat_bubble', link: 'home/agent', badge: '', moduleKey: 'agent' }\n    ];\n\n  }\n\n  appName: string;\n  logo: string;\n  logoSize: string;\n  ADAuth: boolean;\n  localAuth: boolean;\n  googleAuth: boolean;\n  microsoftAuth: boolean;\n  microsoftAuthMessage: string;\n  selfService: boolean;\n  capItems: CapItem[];\n  multitenant : boolean;\n  navigation : 'top' | 'side' | 'side-modern' | 'top-modern' // Changed: Added side-modern + top-modern navigation options\n  // Changed: the @deprecated progressLine flag is gone. It gated the details dialog's old indeterminate\n  // mat-progress-bar, which quietLoading's perceived-progress line replaced; it had been inert since\n  // 2026-08-05 and every consumer SPA has dropped its assignment, so the declaration goes too.\n  // Changed (Phase 7): optional and DEPRECATED — INERT. Its only reader was viewerDialog, which built a\n  // public storage URL from it; that component is deleted. Kept as an optional declaration purely so the\n  // consumer apps still assigning it keep compiling. Nothing in the library reads it. Do not add a reader.\n  docsBaseUrl?: string;\n  loginStyle : string;\n  // Added: 'modern' switches EVERY dialog (message, confirm, details, list, import, viewer) to the modern\n  // treatment in one setting. Anything else — including undefined — keeps the previous look, so an app that\n  // never sets it is unaffected. Mirrors how loginStyle works.\n  dialogStyle : string;\n  loginTitle : string;\n  loginMessage : string;\n  termsUrl: string;\n  privacyUrl: string;\n  siteUrl: string;\n  navWidth: string;\n  navColor: string; // Changed: Sidebar overlay color for side-modern\n  navImage: string; // Changed: Sidebar background image path for side-modern\n  keepSignedIn: boolean; // Changed: Toggle the \"Keep me signed in\" option on the login page (hidden when false/undefined)\n  resumeLastRoute: boolean; // Added: land a resumed session on the user's last visited page instead of the default start page\n  // Added (Quiet Loading): app-wide loading style. false (default) keeps the global blocking scrim for every read;\n  // true lets tables, tiles and details dialogs render their own local loading state instead. Individual\n  // TableConfig/TileConfig/DetailsDialogConfig can override either way. Mirrors how dialogStyle works. // Changed: dropped the progressLine reference — that flag no longer exists\n  quietLoading: boolean;\n  // Added: app-wide opt-in for NAMED destructive confirmations. false/undefined (the default) keeps every\n  // built-in prompt reading \"Yes\" / \"No\" exactly as it does today, so an app that never sets it — including the\n  // untracked consumers outside this workspace — is completely unaffected. true lets the library name the\n  // action on its OWN built-in prompts (the delete/remove confirmations it generates when a button declares no\n  // confirm message of its own), so \"Are you sure you want to delete Volvo?\" answers with \"Keep\" / \"Delete\".\n  // NOTE: this flag gates the LABELS and the colour ONLY — never the message. The sentence itself, including the\n  // record's name, is composed by ButtonService.getConfirmOptions for flagged and unflagged apps alike.\n  // It does NOT gate a per-button `confirm.confirmLabel` — an explicit label is already a deliberate opt-in and\n  // is always honoured. Mirrors how dialogStyle and quietLoading work.\n  namedDestructiveActions: boolean;\n  setupConfig: SetupConfig; // Added: Setup readiness (\"Getting Started\") config — undefined disables the feature\n  dayBookConfig: DayBookConfig; // Added: Day Book config — undefined disables the feature (route renders empty state)\n  appConfigurationConfig: AppConfigurationConfig; // Added: App Configuration page — app sections compose ON TOP of the library base sections, so leaving it undefined still gives a working page\n  bottomTabs: BottomTab[]; // Added: mobile bottom tab bar cells — defaulted in the constructor, so an app only assigns this to override\n\n}\n\n// Added: Setup readiness (\"Getting Started\") — per-app config mapping backend step keys to frontend actions\nexport interface SetupStepAction { button?: Button; link?: string; linkDisplay?: string; import?: ImportConfig; roleTemplates?: boolean; seed?: boolean; view?: TableConfig; } // Changed (seed seam): seed opts the step into the example-data offers GET setup/seedoffers returns for it — same opt-in shape as roleTemplates, so a step that does not set it is byte-for-byte unaffected\nexport interface SetupConfig { enabled: boolean; title?: string; stepActions: { [key: string]: SetupStepAction }; demoData?: boolean; } // Changed: demoData opts the app into the library Demo Data card (seed/remove) at the foot of Getting Started — moved off the retired per-app configuration components, where seeding example records never belonged\nexport interface SetupStep { key: string; title: string; description: string; category: string; order: number; required: boolean; target: number; current: number; complete: boolean; link: string; icon: string; module?: string; } // Changed (v2): module = owning module key\nexport interface SetupStatus { steps: SetupStep[]; completed: number; total: number; percent: number; pending: number; requiredTotal?: number; requiredCompleted?: number; modules?: SetupModule[]; } // Changed (v2): modules = selectable module catalog. Changed (gs-percent-required-only): percent is now REQUIRED-steps-only while completed/total still count everything, so the hero needs requiredTotal/requiredCompleted to tell \"all done\" apart from \"all REQUIRED done, optional extras remain\". Optional so an older backend still renders\n// Added (v2): selectable onboarding module — core modules are locked on; optional ones gate steps + menus\nexport interface SetupModule { key: string; title: string; description: string; icon: string; group?: string; order: number; core: boolean; enabled: boolean; } // Changed (v3): group bands the picker (Operations, Finance, People...); optional so an older backend still renders flat\n// Added (v2): predefined role template offered on the roles step — created server-side, refined in the roles editor\nexport interface SetupRoleTemplate { key: string; name: string; description: string; icon: string; module?: string; exists: boolean; }\n// Added (seed seam): one EXAMPLE-DATA offer a step can make. Everything the row says is authored SERVER-SIDE —\n// `effect` is the plain-English \"what this creates\" sentence, `sampleNotice` is the standing \"these are examples\n// you can edit\" line, and `includes` names the prerequisites the apply will satisfy first (a vehicle cannot exist\n// without its makes and models). The UI composes NO wording of its own. `applied`, `wouldCreate` and `existing`\n// are stamped per offer at request time, so emptiness is judged AREA BY AREA rather than by one global sentinel.\nexport interface SetupSeedOffer { key: string; stepKey: string; name: string; description: string; effect: string; sampleNotice: string; icon: string; module?: string; includes: string[]; wouldCreate: number; existing: number; applied: boolean; }\n// Added (presets): the fields EVERY onboarding preset has, whatever it configures. `effect` is the plain-English\n// sentence AUTHORED SERVER-SIDE in PresetCatalog and carries a {role} placeholder marking where the picker embeds\n// its role select — the UI SPLITS that sentence and never composes one itself, so the wording stays a single\n// editable source of truth. `exists` and `roleID` are stamped by SetupController.\n// Changed (presets P4): extracted from SetupNotificationPreset so the approval picker reuses the notification\n// picker's code path instead of copy-pasting it — the picker only ever needs these shared fields.\nexport interface SetupPreset { key: string; name: string; description: string; effect: string; icon: string; group: string; module?: string; modelName: string; preferredRoleKeys: string[]; exists: boolean; roleID?: number; }\n// Added (presets): an onboarding notification rule offered on the \"Choose what you want to be told about\" step\nexport interface SetupNotificationPreset extends SetupPreset { operationType: number; }\n// Added (presets P4): an onboarding approval rule offered on the \"Choose what needs sign-off\" step. Applying one\n// creates an ApprovalConfig plus a single ApprovalLevel (named by levelName) holding the chosen role.\nexport interface SetupApprovalPreset extends SetupPreset { createApprovalRequired: boolean; editApprovalRequired: boolean; deleteApprovalRequired: boolean; levelName: string; }\n// Added (presets): one ticked preset plus the role the user chose for it — the item shape of the apply POST body\n// Changed (GS Phase 5): roleIDs carries the whole choice; roleID stays REQUIRED and carries the first of them, so a payload from this build is still understood in full by a server that predates the plural field\nexport interface SetupPresetSelection { key: string; roleID: number; roleIDs?: number[]; }\n// Added (presets): a tenant role the picker offers as a recipient — backend NameValuePair (name + role id)\nexport interface SetupPresetRole { name: string; value: number; }\n// Added (presets): payload of GET setup/notificationpresets — the presets on offer plus the roles to choose from\nexport interface SetupPresetCatalog<T> { presets: T[]; roles: SetupPresetRole[]; }\n\n// Added: Day Book (spa-day-book) — config-driven daily worklist page. The backend stays app-specific and\n// returns ONE flat object of named lists (+ optional `<name>Value` money totals); stages map counts to\n// spa-tiles (zero-count tiles HIDE) and sections render their list as a spa-table with a sectionConfig header.\n// Changed: there is now exactly ONE rendering path. The *spaDayBookSection / *spaDayBookSectionHeader template\n// hatches are gone — every consumer had taken them for every section, which reproduced the pre-library fork\n// inside the library's chrome and made the shared page invisible. Section-level (batch) actions live in\n// tableConfig.sectionConfig.buttons and page-level actions in DayBookConfig.actions, both of which are config,\n// so an app needs no component of its own to host the page.\nexport interface DayBookLane { key: string; label: string; icon?: string; valueField?: string | ((book: any) => number); hidden?: VisibilityValue; visible?: VisibilityValue; } // Changed: icon + visibility — a lane whose module is off must not offer itself; valueField — the money a COLLAPSED lane group still has to show (omit it and the group sums its own stages' instead)\nexport interface DayBookStage { key: string; lane?: string; label: string; icon?: string; countField: string; valueField?: string | ((book: any) => number); hint?: string; alert?: VisibilityValue; hidden?: VisibilityValue; visible?: VisibilityValue; } // countField may name the count OR the list itself — the page takes .length off an array; valueField may name the total OR compute it off the book (a strip total the backend never sent)\n// Changed: a section is ALWAYS a spa-table now, so tableConfig is what makes it render. `caption` is the\n// section's \"why this list exists\" line — the library feeds it into the table's own section header, so it sits\n// under the title rather than above it.\n// Added (config injection): the ONLY properties a Day Book card may restate over an injected PAGE definition.\n// The Day Book's friendlier voice (\"Book this truck onto a new trip\" where the page says \"Create\") is wanted,\n// so a per-card delta is sanctioned — but restricted to the FACE. Pick<> is what enforces it: TypeScript's\n// excess-property check refuses a behavioural key on these object literals at COMPILE time, so the rule is held\n// by the compiler rather than by review. Widening either type is the one change that silently reintroduces drift.\n// 🔴 `name` is deliberately absent and must stay absent. It is a security and routing key, not a label:\n// button.service.ts:320 gates ['create','edit','view','delete'] against tableConfig.formConfig.security BY NAME,\n// so a friendlier name drops the button out of that mapping and quietly loosens security. Friendly wording goes\n// on `display`; `name` is always inherited untouched.\nexport type DayBookPresentation = Pick<Button, 'display' | 'icon' | 'color' | 'tip'>;\n// Added: a row button injected BY NAME out of the page's TableConfig.buttons, plus its presentation delta.\nexport interface DayBookButtonView extends DayBookPresentation {\n  button: string; // the page button's `name` — what is being injected\n  // The single deliberate non-presentation escape, named so it is visible in review: re-aiming a page dialog at\n  // a Day Book row. Maps straight onto Button.rowDataMap and is what grip already does for Record Payment. It\n  // supplies CONTEXT, never behaviour.\n  prefill?: Record<string, string | ((data: any) => any)>;\n}\n// Added: the column equivalent. Deliberately NOT `extends DayBookPresentation` — `display` and `tip` are Button\n// properties that do not exist on Column, and spreading them onto one would produce a silently invalid column.\nexport type DayBookColumnPresentation = Pick<Column, 'alias' | 'icon' | 'color'>;\nexport interface DayBookColumnView extends DayBookColumnPresentation { column: string; } // the page column's `name`\n// Added: the table-level escape hatch — chrome only. Nothing here can change what the table fetches, submits or gates.\nexport type DayBookTableView = Pick<TableConfig, 'minColumns' | 'elevation' | 'sectionConfig' | 'flatButtons' | 'collapseButtons' | 'maxButtonsCount' | 'showFilter' | 'showFilterButton' | 'noDataMessage' | 'identityColumn' | 'hideColumnHeaders'>;\n// Changed (config injection): a section may now be a SNIPPET OF an existing page TableConfig rather than a\n// restatement of it. columns/buttons select BY NAME out of the injected config — the definitions, their dialogs,\n// their capabilities and their conditions stay on the page and arrive here by reference, which is the whole point.\nexport interface DayBookSection { key: string; lane?: string; listField: string; collapsed?: boolean; tableConfig?: TableConfig; columns?: (string | DayBookColumnView)[]; omitColumns?: string[]; extraColumns?: Column[]; buttons?: (string | DayBookButtonView)[]; extraButtons?: Button[]; overrides?: DayBookTableView; label?: string; icon?: string; caption?: string | ((book: any) => string); tone?: 'alert' | 'quiet'; pageSize?: number; hidden?: VisibilityValue; visible?: VisibilityValue; } // caption may read the book — a threshold the section explains is a tenant setting, not a constant\n// Added: groupLanes / expandedGroups — on 'Everything' the sections are stacked into one collapsible group per\n// lane instead of one long column, because a book with 9-16 section cards overcrowds the page. A collapsed group\n// still shows its label, its total count, its money and a chip per list, so it is identifiable at a glance. Only\n// the first expandedGroups (default 1) open on a first visit; after that the operator's own choice is remembered.\n// groupLanes:false opts a book out entirely; a book with fewer than two visible lanes never groups anyway.\n// Added: `actions` — the page-level buttons in the header (Refresh, \"All trips\", \"Pen overview\"). They used to\n// arrive ONLY by content projection into [dayBookActions], which needs a consumer component to do the\n// projecting — and a config-only Day Book has no component, so every converted app silently lost them. A\n// button with no `action` and no `onClick` reloads the book, which is what Refresh has always been.\n// Changed: `stageStyle` is gone. The stage row is always spa-tiles.\n// Added: how the stage row behaves when the stages outnumber the width — 'wrap' (default) flows onto the next\n// row with every tile the same width, 'carousel' keeps one row and scrolls. maxPerRow caps the columns.\nexport interface DayBookStageTiles { layout?: 'wrap' | 'carousel'; minTileWidth?: number; maxPerRow?: number; }\nexport interface DayBookConfig { title?: string; subtitle?: string; loadAction: Action; lanes?: DayBookLane[]; stages: DayBookStage[]; sections: DayBookSection[]; actions?: Button[]; stageTiles?: DayBookStageTiles; booksFromField?: string; owedField?: string | ((book: any) => number); allClearMessage?: string; loadingMessage?: string; pageSize?: number; groupLanes?: boolean; expandedGroups?: number; } // owedField may name the total OR compute it off the book (Grip's is the sum of four lane totals the backend never adds up)\n\n// Added: App Configuration (spa-app-configuration) — the single settings page for every app, replacing the\n// retired spa-preferences and the four hand-written per-app configuration components. The library owns the\n// behaviour (load, card-per-section, collapse, toggle cascade, one save); the app supplies only\n// appConfig.appConfigurationConfig, composing its own sections after the library base sections\n// (DataServiceLib.configSectionFinancial et al). Sections reuse the ordinary `Field` type, so hints, suffixes,\n// visibility, readonlyCondition and loadAction selects all come for free.\nexport interface AppConfigSection {\n  key: string;\n  title: string;\n  icon?: string;\n  hint?: string;\n  collapsible?: boolean; // default true — a section can opt out and stay permanently open\n  collapsed?: boolean;   // initial state only\n  toggleField?: string;  // a boolean config field rendered as the card header's switch; its children go readonly while it is off\n  fields: Field[];\n  hidden?: VisibilityValue;\n  visible?: VisibilityValue;\n}\nexport interface AppConfigurationConfig { title?: string; loadAction?: Action; saveAction?: Action; resetAction?: Action; security?: SecurityConfig; sections: AppConfigSection[]; } // actions default to configuration/get + configuration/update + configuration/reset; security gates SAVE only (reads are open server-side too). Changed (N22): resetAction follows the same default-and-override idiom as the other two — the endpoint is on AppConfigurationControllerBase, so all five apps inherit it and none has to configure anything\n\n// Added: flat collapsible checklist (spa-checklist) — bordered to-do items rendered directly on the host card\n// (no elevation, no panel background). Single-expand accordion semantics; actions render as library buttons.\nexport interface ChecklistAction { type?: 'create' | 'import' | 'link' | 'view' | 'seed' | 'custom'; display?: string; icon?: string; primary?: boolean; disabled?: (item: ChecklistItem) => boolean; onClick: (item: ChecklistItem) => void; } // Changed (P6): 'seed' joins the union. Additive to a string-literal union with every member optional, so no existing declaration changes meaning — and it is a TYPE only: checklist.component.html branches on 'import' alone and treats everything else as a generic secondary, so naming the seed action is for the READER and for anyone who later wants to style or order by type, not a rendering switch\nexport interface ChecklistItem { key: string; title: string; description?: string; complete?: boolean; optional?: boolean; progressText?: string; actions?: ChecklistAction[]; data?: any; hidden?: VisibilityValue; visible?: VisibilityValue; section?: string; } // Changed (v2-1): section — the OPTIONAL third collapse tier. Items carrying the same section string fold together inside the expanded checklist. Optional and additive: an item that sets none, or a list whose items all resolve to ONE section, renders exactly as before with no sub-tier at all\nexport interface ChecklistConfig { items: ChecklistItem[]; expandedKey?: string; itemTemplate?: any; } // itemTemplate: TemplateRef projected into the expanded body (assigned at runtime by the host, same idiom as tabTemplate)\n\n// Re-export from LibClasses\nexport { PurchaseStatus, ReceiptStatus } from './LibClasses'; // Changed: InventoryReceiptStatus → PurchaseStatus, added ReceiptStatus\n\n\n\n\n","import { Injectable } from '@angular/core';\nimport { Constants } from '../classes/Classes'; // Changed: Import for clearSessionData key preservation\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class StorageService {\n\n  private useSession = false; // Changed: Flag to toggle between localStorage/sessionStorage\n\n  constructor() { }\n\n  // Changed: Set storage mode - true for sessionStorage, false for localStorage\n  setSessionMode(useSession: boolean) {\n    this.useSession = useSession;\n  }\n\n  // Changed: Returns the active storage engine based on mode\n  private getStorage(): Storage {\n    return this.useSession ? sessionStorage : localStorage;\n  }\n\n  // Store the value in the active storage\n  async store(storageKey: string, value: any) {\n    const encryptedValue = btoa(escape(JSON.stringify(value)));\n    await this.getStorage().setItem(storageKey, encryptedValue);\n  }\n\n  // Get the value from the active storage, falling back to the other storage\n  async get(storageKey: string) {\n    let ret = this.getStorage().getItem(storageKey);\n    if (ret === null) {\n      // Changed: Fallback to the other storage for backwards compatibility\n      ret = (this.useSession ? localStorage : sessionStorage).getItem(storageKey);\n    }\n    if (ret === null) return null;\n    // Changed: corrupt/legacy values must degrade to \"not stored\" instead of rejecting the auth guard promise\n    try { return JSON.parse(unescape(atob(ret))); } catch { return null; }\n  }\n\n  // Remove from active storage\n  async removeStorageItem(storageKey: string) {\n    await this.getStorage().removeItem(storageKey);\n  }\n\n  // Clear active storage\n  async clear() {\n    await this.getStorage().clear();\n  }\n\n  // Changed: Store in localStorage always (for refresh token + remember-me flag that survive browser close)\n  storePersistent(storageKey: string, value: any) {\n    const encryptedValue = btoa(escape(JSON.stringify(value)));\n    localStorage.setItem(storageKey, encryptedValue);\n  }\n\n  // Changed: Get from localStorage always\n  getPersistent(storageKey: string): any {\n    const ret = localStorage.getItem(storageKey);\n    if (ret === null) return null;\n    // Changed: corrupt/legacy values must degrade to \"not stored\" instead of throwing into auth flows\n    try { return JSON.parse(unescape(atob(ret))); } catch { return null; }\n  }\n\n  // Changed: Remove from localStorage always\n  removePersistent(storageKey: string) {\n    localStorage.removeItem(storageKey);\n  }\n\n  // Changed: Clear both localStorage and sessionStorage\n  clearAll() {\n    localStorage.clear();\n    sessionStorage.clear();\n  }\n\n  // Changed: Clear session data but preserve refresh token + remember-me for \"keep me signed in\"\n  clearSessionData() {\n    const keysToPreserve = [Constants.AUTH_REFRESH_TOKEN, Constants.AUTH_REFRESH_TOKEN_EXPIRE, Constants.AUTH_REMEMBER_ME];\n    const preserved: { [key: string]: string | null } = {};\n\n    for (const key of keysToPreserve) {\n      preserved[key] = localStorage.getItem(key);\n    }\n\n    localStorage.clear();\n    sessionStorage.clear();\n\n    for (const key of keysToPreserve) {\n      if (preserved[key] !== null) {\n        localStorage.setItem(key, preserved[key]!);\n      }\n    }\n  }\n\n  // Changed: Check if a key exists in either storage\n  hasKey(storageKey: string): boolean {\n    return localStorage.getItem(storageKey) !== null || sessionStorage.getItem(storageKey) !== null;\n  }\n\n}\n","import { Injectable, Inject } from \"@angular/core\";\nimport { Observable } from \"rxjs\";\nimport { HttpClient, HttpHeaders, HttpErrorResponse, HttpContext, HttpResponse, } from \"@angular/common/http\"; // Changed: HttpContext carries the Quiet Loading silent flag through to the interceptor; HttpResponse added for the document byte stream, which must be observed at the response level to branch on status\nimport { Router } from \"@angular/router\";\n\n@Injectable({\n  providedIn: \"root\",\n})\nexport class HttpService {\n\n  constructor(private httpClient: HttpClient, private router: Router) { }\n\n\n  //----Set apiUrl from the data service of the project---//\n  public apiUrl = \"https://api.solinc.co.zw/\"; //default\n\n\n\n  //POST\n  // Changed: optional context — omitted by every existing caller, so the request built is identical to before\n  public Post(service: string, data: any, context?: HttpContext): Observable<any> {\n    return this.httpClient.post(this.apiUrl + service, data, this.withContext(context));\n  }\n\n  //PUT\n  public Put(service: string, data: any): Observable<any> {\n    return this.httpClient.put(this.apiUrl + service, data, this.httpOptions_Legacy);\n  }\n\n\n  //POST RAW\n  public Post_Raw(url: string, data: any): Observable<any> {\n\n    return this.httpClient.post(url, data, this.httpOptions_Legacy);\n  }\n\n  //POST with file\n  public Post_WithFile(service: string, data: any, file: File) {\n\n    let formData: FormData = new FormData();\n\n    if (file) {\n      formData.append(\"uploadFile\", file, file.name);\n    }\n\n    formData.append(\"data\", JSON.stringify(data));\n\n    return this.httpClient.post(this.apiUrl + service, formData, this.httpOptions_Files);\n  }\n\n  //  //POST with files\n  // Changed: optional context for parity with Post/Get\n  public Post_FormData(service: string, formData: FormData, context?: HttpContext) {\n\n    return this.httpClient.post(this.apiUrl + service, formData, context ? { ...this.httpOptions_Files, context } : this.httpOptions_Files);\n  }\n\n  //GET\n  // Changed: optional context — omitted by every existing caller, so the request built is identical to before\n  public Get(service: string, context?: HttpContext): Observable<any> {\n    return this.httpClient.get(this.apiUrl + service, this.withContext(context));\n  }\n\n  //Get RAW\n  public Get_Raw(url: string): Observable<any> {\n    return this.httpClient.get(url, this.httpOptions_Legacy);\n  }\n\n  // Added: GET raw bytes from the app's own API, for the authorized document stream.\n  // Returns the FULL HttpResponse rather than just the body because the document stream branches on HTTP\n  // STATUS — its success body is bytes, not a RepoResponse, so `response.Success` does not exist to test.\n  // Goes through this service (not a bare HttpClient) so it inherits apiUrl and, via LoaderInterceptor, the\n  // bearer token — which is the entire point: no document is ever fetched from storage directly.\n  // No Accept/Content-Type headers here: this is a byte stream, and declaring application/json would be a lie.\n  public Get_Blob(service: string, context?: HttpContext): Observable<HttpResponse<Blob>> {\n    return this.httpClient.get(this.apiUrl + service, { observe: 'response', responseType: 'blob', context });\n  }\n\n  //ERROR\n  public Error(error: HttpErrorResponse) {\n    if (error.statusText == \"Unauthorized\") {\n      this.router.navigate([\"login\"]);\n      return \"Unauthorized\";\n    } else {\n      return \"Connection failed\";\n    }\n  }\n\n  // Changed: removed hardcoded Basic-auth credentials. Authentication is handled centrally by\n  // LoaderInterceptor, which attaches the Bearer token to every request. Embedding a credential here\n  // shipped it in the JS bundle where anyone could recover it.\n  // Added: returns the legacy options untouched when there is no context, so the non-quiet path is unchanged\n  private withContext(context?: HttpContext) {\n    return context ? { ...this.httpOptions_Legacy, context } : this.httpOptions_Legacy;\n  }\n\n  private httpOptions_Legacy = {\n    headers: new HttpHeaders({\n      Accept: \"application/json\",\n      \"Content-Type\": \"application/json\",\n    }),\n    responseType: \"json\" as const,\n  };\n\n  // No Content-Type here — the browser sets the multipart boundary for FormData uploads.\n  private httpOptions_Files = {\n    responseType: \"json\" as const,\n  };\n}\n","// Customer receipt dialog (C3) — record a payment and allocate it across open invoices; remainder goes on-account\nimport { Component, OnInit, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { HttpService } from '../../../services/http.service';\nimport { MessageService } from '../../../services/message.service';\n\n@Component({\n  selector: 'spa-receipt-dialog',\n  template: `\n    <h2 mat-dialog-title>{{ allocateMode ? 'Allocate Receipt ' + data.receiptNumber : 'New Receipt' }}</h2>\n    <mat-dialog-content>\n      <div style=\"display: flex; gap: 16px; flex-wrap: wrap;\" *ngIf=\"!allocateMode\">\n        <mat-form-field style=\"min-width: 220px;\">\n          <mat-label>Customer</mat-label>\n          <mat-select [(ngModel)]=\"customerID\" (ngModelChange)=\"loadOpenInvoices()\">\n            <mat-option *ngFor=\"let option of customers\" [value]=\"option.value\">{{ option.name }}</mat-option>\n          </mat-select>\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>Date</mat-label>\n          <input matInput type=\"date\" [(ngModel)]=\"receiptDate\">\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>Amount</mat-label>\n          <input matInput type=\"number\" min=\"0\" [(ngModel)]=\"amount\">\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>Method</mat-label>\n          <mat-select [(ngModel)]=\"method\">\n            <mat-option [value]=\"0\">Cash</mat-option>\n            <mat-option [value]=\"1\">Bank</mat-option>\n          </mat-select>\n        </mat-form-field>\n        <mat-form-field style=\"min-width: 200px;\">\n          <mat-label>Reference</mat-label>\n          <input matInput [(ngModel)]=\"reference\" placeholder=\"e.g. bank ref / receipt book #\">\n        </mat-form-field>\n      </div>\n      <p *ngIf=\"allocateMode\"><b>Unallocated balance: {{ available | number:'1.2-2' }}</b></p>\n\n      <table style=\"width: 100%; border-collapse: collapse;\" *ngIf=\"openInvoices.length; else noInvoices\">\n        <tr style=\"text-align: left; border-bottom: 1px solid #ccc;\">\n          <th style=\"padding: 4px;\">Invoice #</th>\n          <th style=\"padding: 4px;\">Date</th>\n          <th style=\"padding: 4px; text-align: right;\">Outstanding</th>\n          <th style=\"padding: 4px; width: 160px;\">Allocate</th>\n        </tr>\n        <tr *ngFor=\"let invoice of openInvoices\" style=\"border-bottom: 1px solid #eee;\">\n          <td style=\"padding: 4px;\">{{ invoice.invoiceNumber }}</td>\n          <td style=\"padding: 4px;\">{{ invoice.invoiceDate | date:'mediumDate' }}</td>\n          <td style=\"padding: 4px; text-align: right;\">{{ invoice.outstandingAmount | number:'1.2-2' }}</td>\n          <td style=\"padding: 4px;\">\n            <mat-form-field style=\"width: 100%;\" subscriptSizing=\"dynamic\">\n              <input matInput type=\"number\" min=\"0\" [max]=\"invoice.outstandingAmount\" [(ngModel)]=\"invoice.allocation\">\n            </mat-form-field>\n          </td>\n        </tr>\n        <tr style=\"border-top: 2px solid #333;\">\n          <td style=\"padding: 8px 4px;\" colspan=\"2\">\n            <button mat-stroked-button (click)=\"autoAllocate()\">Auto Allocate (oldest first)</button>\n          </td>\n          <td style=\"padding: 8px 4px; text-align: right;\"><b>Allocated:</b></td>\n          <td style=\"padding: 8px 4px;\"><b>{{ totalAllocated | number:'1.2-2' }}</b></td>\n        </tr>\n      </table>\n      <ng-template #noInvoices><p><em>{{ customerID ? 'No open invoices — the full amount will be recorded on-account' : 'Select a customer to load open invoices' }}</em></p></ng-template>\n      <p *ngIf=\"overAllocated\" style=\"color: red;\"><em>Allocations exceed the {{ allocateMode ? 'unallocated balance' : 'receipt amount' }}</em></p>\n    </mat-dialog-content>\n    <mat-dialog-actions align=\"end\">\n      <button mat-button (click)=\"dialogRef.close(false)\">Cancel</button>\n      <button mat-flat-button color=\"primary\" (click)=\"save()\" [disabled]=\"!canSave\">{{ allocateMode ? 'Allocate' : 'Record Receipt' }}</button>\n    </mat-dialog-actions>\n  `,\n  standalone: false\n})\nexport class ReceiptDialogComponent implements OnInit {\n  public dialogRef = inject(MatDialogRef<ReceiptDialogComponent>);\n  public data: any = inject(MAT_DIALOG_DATA, { optional: true });\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n  private messageService = inject(MessageService);\n\n  customerID: number | null = null;\n  receiptDate = new Date().toISOString().substring(0, 10);\n  amount = 0;\n  method = 0;\n  reference = '';\n  customers: any[] = [];\n  openInvoices: any[] = [];\n\n  get allocateMode(): boolean { return !!this.data?.customerReceiptID; }\n  get available(): number { return this.allocateMode ? this.data.unallocatedAmount : this.amount; }\n  get totalAllocated(): number { return this.openInvoices.reduce((sum, invoice) => sum + (+invoice.allocation || 0), 0); }\n  get overAllocated(): boolean { return this.totalAllocated > this.available + 0.005; }\n  get canSave(): boolean {\n    if (this.overAllocated) return false;\n    if (this.allocateMode) return this.totalAllocated > 0;\n    return !!this.customerID && this.amount > 0;\n  }\n\n  ngOnInit(): void {\n    if (this.allocateMode) {\n      this.customerID = this.data.customerID;\n      this.loadOpenInvoices();\n    } else {\n      this.http.get<any>(`${this.httpService.apiUrl}customers/list/x`)\n        .subscribe(res => this.customers = res?.data ?? []);\n    }\n  }\n\n  loadOpenInvoices() {\n    if (!this.customerID) { this.openInvoices = []; return; }\n    this.http.get<any>(`${this.httpService.apiUrl}customerreceipts/open-invoices/${this.customerID}`)\n      .subscribe(res => this.openInvoices = (res?.data ?? []).map((invoice: any) => ({ ...invoice, allocation: 0 })));\n  }\n\n  // Fill allocations oldest-first until the available amount is used up\n  autoAllocate() {\n    let remaining = this.available;\n    for (const invoice of this.openInvoices) {\n      invoice.allocation = Math.min(remaining, invoice.outstandingAmount);\n      remaining = Math.round((remaining - invoice.allocation) * 100) / 100;\n    }\n  }\n\n  save() {\n    const allocations = this.openInvoices.filter(invoice => (+invoice.allocation || 0) > 0)\n      .map(invoice => ({ invoiceID: invoice.invoiceID, amount: +invoice.allocation }));\n    const dto: any = this.allocateMode\n      ? { customerReceiptID: this.data.customerReceiptID, allocations }\n      : { customerID: this.customerID, receiptDate: this.receiptDate, amount: this.amount, method: this.method, reference: this.reference, allocations };\n    const action = this.allocateMode ? 'allocate' : 'create';\n    this.http.post<any>(`${this.httpService.apiUrl}customerreceipts/dto?action=${action}`, dto)\n      .subscribe(res => {\n        this.messageService.toast(res?.message ?? (res?.success ? 'Saved' : 'Failed'));\n        if (res?.success) this.dialogRef.close(true);\n      });\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, TableConfig, DetailsDialogConfig, Button } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\n\n// Service for generic entities: Categories, SubCategories, Brands, and ListItems\n@Injectable({\n  providedIn: 'root'\n})\nexport class GeneralService {\n\n  private dataService = inject(DataServiceLib);\n\n  //--------------------------Categories-------------------------\n\n  categoryFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capCategories] }, // Added: gate category form by categories cap\n    title: 'Category',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, alias: 'Name' },\n      { name: 'description', type: 'text', alias: 'Description' }\n    ],\n    loadAction: { url: 'categories/id' },\n    heroField: 'categoryID'\n  }\n\n  categoryCreateButton: Button = { name: 'create', display: 'Create Category', dialog: true, action: { url: 'categories?action=create', method: 'post' } }\n  categoryEditButton: Button = { name: 'edit', dialog: true, action: { url: 'categories?action=edit', method: 'post' } }\n  categoryDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'categories?action=delete', method: 'post' } }\n\n  categoryDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.categoryFormConfig,\n    heroField: 'categoryID',\n    buttons: [this.categoryCreateButton, this.categoryEditButton, this.categoryDeleteButton]\n  }\n\n  categoriesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'description'],\n    columns: [\n      { name: 'name', type: 'text', alias: 'Name' },\n      { name: 'description', type: 'text', alias: 'Description' }\n    ],\n    buttons: [\n      this.categoryCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.categoryDetailsConfig },\n      this.categoryEditButton,\n      this.categoryDeleteButton\n    ],\n    loadAction: { url: 'categories/all/x' },\n    formConfig: this.categoryFormConfig,\n    realTime: true,\n    entityName: 'Category',\n    inlineEdit: { fields: ['name', 'description'] }, // Added: edit rows in the grid — the edit button swaps the row into editable cells instead of opening a dialog\n    offline: { enabled: true, queue: { create: true, edit: true, delete: true } } // Changed: TinSync offline-enabled (delete on for these reference-data test entities)\n  }\n\n  //--------------------------SubCategories-------------------------\n\n  subCategoryFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSubCategories] }, // Added: gate sub category form by sub categories cap\n    title: 'Sub Category',\n    fixedTitle: true,\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, alias: 'Name' },\n      { name: 'categoryID', type: 'select', required: true, alias: 'Category', loadAction: { url: 'categories/list/x' }, detailsConfig: this.categoryDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'description', type: 'text', alias: 'Description' }\n    ],\n    loadAction: { url: 'subcategories/id' },\n    heroField: 'subCategoryID'\n  }\n\n  subCategoryCreateButton: Button = { name: 'create', display: 'Create Sub Category', dialog: true, action: { url: 'subcategories?action=create', method: 'post' } }\n  subCategoryEditButton: Button = { name: 'edit', dialog: true, action: { url: 'subcategories?action=edit', method: 'post' } }\n  subCategoryDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'subcategories?action=delete', method: 'post' } }\n\n  subCategoryDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.subCategoryFormConfig,\n    heroField: 'subCategoryID',\n    buttons: [this.subCategoryCreateButton, this.subCategoryEditButton, this.subCategoryDeleteButton]\n  }\n\n  subCategoriesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'categoryName', 'description'],\n    columns: [\n      { name: 'name', type: 'text', alias: 'Name' },\n      { name: 'categoryName', type: 'text', alias: 'Category' },\n      { name: 'description', type: 'text', alias: 'Description' }\n    ],\n    buttons: [\n      this.subCategoryCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.subCategoryDetailsConfig },\n      this.subCategoryEditButton,\n      this.subCategoryDeleteButton\n    ],\n    loadAction: { url: 'subcategories/all/x' },\n    formConfig: this.subCategoryFormConfig,\n    realTime: true,\n    entityName: 'SubCategory',\n    inlineEdit: { fields: ['name', 'description'] }, // Added: inline edit. Category is omitted deliberately — the grid shows categoryName (display) while the form field is categoryID, and getInlineField matches on column name, so an FK column cannot be inline-edited today\n    offline: { enabled: true, queue: { create: true, edit: true, delete: true } } // Changed: TinSync offline-enabled (delete on for these reference-data test entities)\n  }\n\n  //--------------------------Brands-------------------------\n\n  brandFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capBrands] }, // Added: gate brand form by brands cap\n    title: 'Brand',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, alias: 'Name' },\n      { name: 'description', type: 'text', alias: 'Description' }\n    ],\n    loadAction: { url: 'brands/id' },\n    heroField: 'brandID'\n  }\n\n  brandCreateButton: Button = { name: 'create', display: 'Create Brand', dialog: true, action: { url: 'brands?action=create', method: 'post' } }\n  brandEditButton: Button = { name: 'edit', dialog: true, action: { url: 'brands?action=edit', method: 'post' } }\n  brandDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'brands?action=delete', method: 'post' } }\n\n  brandDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.brandFormConfig,\n    heroField: 'brandID',\n    buttons: [this.brandCreateButton, this.brandEditButton, this.brandDeleteButton]\n  }\n\n  brandsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'description'],\n    columns: [\n      { name: 'name', type: 'text', alias: 'Name' },\n      { name: 'description', type: 'text', alias: 'Description' }\n    ],\n    buttons: [\n      this.brandCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.brandDetailsConfig },\n      this.brandEditButton,\n      this.brandDeleteButton\n    ],\n    loadAction: { url: 'brands/all/x' },\n    formConfig: this.brandFormConfig,\n    realTime: true,\n    entityName: 'Brand',\n    inlineEdit: { fields: ['name', 'description'] }, // Added: edit rows in the grid instead of a dialog\n    offline: { enabled: true, queue: { create: true, edit: true, delete: true } } // Added: TinSync offline-enabled to match categories/subcategories\n  }\n\n  //--------------------------ListItems-------------------------\n\n  listItemFormConfig: FormConfig = {\n    title: 'List Item',\n    includeAudit: true,\n    fields: [\n      { name: 'listName', type: 'text', required: true, alias: 'List Name', readonly: true },\n      { name: 'name', type: 'text', required: true, alias: 'Name' }\n    ],\n    loadAction: { url: 'listitems/id' },\n    heroField: 'listItemID'\n  }\n\n  listItemCreateButton: Button = { name: 'create', display: 'Create Item', dialog: true, action: { url: 'listitems?action=create', method: 'post' } }\n  listItemEditButton: Button = { name: 'edit', dialog: true, action: { url: 'listitems?action=edit', method: 'post' } }\n  listItemDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'listitems?action=delete', method: 'post' } }\n\n  listItemDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.listItemFormConfig,\n    heroField: 'listItemID',\n    buttons: [this.listItemCreateButton, this.listItemEditButton, this.listItemDeleteButton]\n  }\n\n  listItemsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['listName', 'name'],\n    columns: [\n      { name: 'listName', type: 'text', alias: 'List Name' },\n      { name: 'name', type: 'text', alias: 'Name' }\n    ],\n    buttons: [\n      this.listItemCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.listItemDetailsConfig },\n      this.listItemEditButton,\n      this.listItemDeleteButton\n    ],\n    loadAction: { url: 'listitems/all/x' },\n    formConfig: this.listItemFormConfig,\n    realTime: true,\n    entityName: 'ListItem'\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, TableConfig, DetailsDialogConfig, Button, TileConfig } from '../classes/Classes'; // Changed: Removed StepConfig, InventoryReceiptStatus — moved to PurchasingService\nimport { DataServiceLib } from './datalib.service';\nimport { GeneralService } from './general.service';\n\n// Service to centralize all inventory-related table and form configurations\n@Injectable({\n  providedIn: 'root'\n})\nexport class InventoryService {\n\n  private dataService = inject(DataServiceLib);\n  private generalService = inject(GeneralService);\n\n\n  productDetailsConfig!: DetailsDialogConfig;\n\n\n  constructor() {\n    \n\n    this.productDetailsConfig = {\n      formConfig: this.productFormConfig,\n      tableConfigs: [this.productComponentsTableConfig], // Added: Show components for bundle products\n      heroField: 'productID',\n      buttons: [this.productCreateButton, this.productEditButton, this.productDeleteButton]\n    };\n\n    // Changed: dropdown quick-add — productDetailsConfig is built above (field initializers run before this constructor body), so wire the product selects here to avoid capturing undefined\n    this.inventoryAdjustmentFormConfig.fields.find(f => f.name === 'productID').detailsConfig = this.productDetailsConfig;\n    this.inventoryReturnItemFormConfig.fields.find(f => f.name === 'productID').detailsConfig = this.productDetailsConfig;\n  }\n\n  //--------------------------Products-------------------------\n\n  productFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capProducts] },\n    title: 'Product',\n    fixedTitle: true, // Changed: Use fixedTitle to avoid title duplication\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'productInfo', type: 'section', alias: 'Product Information' },\n      { name: 'name', type: 'text', required: true, alias: 'Product Name', section: 'productInfo', infoMessage: 'The unique name of the product' },\n      { name: 'sku', type: 'text', alias: 'SKU (optional)', section: 'productInfo', infoMessage: 'Stock Keeping Unit for inventory tracking (optional)' }, // Changed: Removed required flag\n      { name: 'description', type: 'text', alias: 'Description', span: true, section: 'productInfo', infoMessage: 'Detailed description of the product' },\n      { name: 'isBundle', type: 'checkbox', alias: 'Bundle Product', span: true, section: 'productInfo', infoMessage: 'Check if this is a bundle/combo product made up of other products' }, // Added: Bundle product flag\n      \n      { name: 'pricingInfo', type: 'section', alias: 'Pricing' },\n      { name: 'sellingPrice', type: 'money', required: true, alias: 'Selling Price', section: 'pricingInfo', infoMessage: 'Default selling price per unit' },\n      { name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, section: 'pricingInfo', loadAction: { url: 'products/list/tax-rates' }, infoMessage: 'VAT rate applied to this product' }, // Changed: Tax rate selector\n      { name: 'isTaxInclusive', type: 'checkbox', alias: 'Price includes Tax', section: 'pricingInfo', infoMessage: 'If checked, the selling price already includes tax' }, // Changed: Tax-inclusive flag\n\n      { name: 'inventoryInfo', type: 'section', alias: 'Inventory Settings', collapsedCondition: x => x.productID }, \n      { name: 'isSerialized', type: 'checkbox', alias: 'Serialized Product', span: true, section: 'inventoryInfo', infoMessage: 'Track individual items by serial number', hidden: x => x.isBundle }, // Changed: Hide for bundles\n      { name: 'baseUnit', type: 'select', required: true, alias: 'Base Unit', section: 'inventoryInfo', loadAction: { url: 'products/list/base-unit' }, defaultFirstValue: true, infoMessage: 'Unit of measure for inventory tracking' }, // Changed: Added defaultFirstValue flag\n      { name: 'minimumInventoryLevel', type: 'number', required: true, alias: 'Minimum Inventory Level', section: 'inventoryInfo', infoMessage: 'Alert threshold for low stock', hidden: x => x.isBundle }, // Changed: Hide for bundles\n\n      { name: 'categoryInfo', type: 'section', alias: 'Categorization', collapseOnView: true },\n      { name: 'categoryID', type: 'select', alias: 'Category', nullable: true, section: 'categoryInfo', loadAction: { url: 'categories/list/x' }, detailsConfig: this.generalService.categoryDetailsConfig, infoMessage: 'The main product category' }, // Changed: Added nullable flag\n      { name: 'subCategoryID', type: 'select', alias: 'Sub Category', section: 'categoryInfo', loadAction: { url: 'subcategories/list/x' }, detailsConfig: this.generalService.subCategoryDetailsConfig, infoMessage: 'More specific product classification' },\n      { name: 'brandID', type: 'select', alias: 'Brand', nullable: true, section: 'categoryInfo', loadAction: { url: 'brands/list/x' }, detailsConfig: this.generalService.brandDetailsConfig, infoMessage: 'Product brand or manufacturer' }, // Changed: Added nullable flag\n      \n\n      \n\n    ],\n    loadAction: { url: 'products/id' },\n    heroField: 'productID'\n  }\n\n  productViewButton : Button = { name: 'view', dialog: true, detailsConfig: this.productDetailsConfig }\n  productCreateButton: Button = { name: 'create', display: 'Create Product', dialog: true, action: { url: 'products?action=create', method: 'post' } }\n  productEditButton: Button = { name: 'edit', dialog: true, action: { url: 'products?action=edit', method: 'post' } }\n  productDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'products?action=delete', method: 'post' } }\n\n\n\n\n  productsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'sku', 'categoryName'],\n    columns: [\n      { name: 'name', type: 'text', alias: 'Product Name' },\n      { name: 'sku', type: 'text', alias: 'SKU' },\n      { name: 'categoryName', type: 'text', alias: 'Category' },\n      { name: 'brandName', type: 'text', alias: 'Brand' },\n      { name: 'currentInventoryLevel', type: 'number', alias: 'Current Stock', icon: { name: 'warning', color: 'orange', condition: (x: any) => x.isLowInventory } }, // Changed: Removed separate columns, added low stock icon to current stock\n      { name: 'minimumInventoryLevel', type: 'number', alias: 'Min Stock' },\n      { name: 'sellingPrice', type: 'money' },\n      { name: 'taxRateName', type: 'text', alias: 'Tax Rate' }, // Changed: Tax rate display with N/A fallback\n      { name: 'priceExclTax', type: 'text', alias: 'Price (Excl)' }, // Changed: Computed price excluding tax\n      { name: 'priceInclTax', type: 'text', alias: 'Price (Incl)' }, // Changed: Computed price including tax\n    ],\n    buttons: [\n      this.productCreateButton,\n      this.productViewButton,\n      this.productEditButton,\n      this.productDeleteButton,\n    ],\n    loadAction: { url: 'products/all/x' },\n    formConfig: this.productFormConfig,\n    realTime: true,\n    pagination: { pageSize: 25 }, // Added: server-side pagination — the product catalogue is the longest reference list in the suite\n    offline: { enabled: true, readOnly: true }, // Added: offline reads only — the catalogue must resolve inside forms with no network; nothing is captured here so nothing queues\n    entityName: 'Product',\n  }\n\n  //--------------------------Product Components (Bundle Configuration)-------------------------\n\n  // Product component form for adding/editing bundle components\n  productComponentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capProducts] }, // Added: gate bundle component form by products cap (parent entity)\n    title: 'Bundle Component',\n    fixedTitle: true,\n    fields: [\n      { name: 'productComponentID', type: 'number', alias: 'ID', hidden: true },\n      { name: 'productID', type: 'number', alias: 'Bundle Product ID', hidden: true },\n      { name: 'componentProductID', type: 'select', alias: 'Component Product', required: true, detailsConfig: this.productDetailsConfig, \n        loadAction: { url: 'products/list/components' }, \n        infoMessage: 'Select a non-bundle product to include in this bundle' \n      },\n      { name: 'quantity', type: 'number', alias: 'Quantity', required: true, defaultValue: 1 , infoMessage: 'Number of units required per bundle' }\n    ],\n    loadAction: { url: 'productcomponents/id' },\n    heroField: 'productComponentID'\n  }\n\n  // Product components table for bundle details\n  productComponentsTableConfig: TableConfig = {\n    tabTitle: 'Components',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    causeFormRefresh: true,\n    minColumns: ['componentProductName', 'quantity', 'estimatedCost'],\n    columns: [\n      { name: 'componentProductName', type: 'text', alias: 'Component' },\n      { name: 'quantity', type: 'number', alias: 'Quantity per Bundle' },\n      { name: 'componentCurrentStock', type: 'number', alias: 'Available Stock' },\n      { name: 'estimatedCost', type: 'money', alias: 'Est. Cost' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Component', dialog: true, action: { url: 'productcomponents?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'productcomponents?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'productcomponents?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'productcomponents/x/x' }, loadCriteria: 'bundle', loadIDField: 'productID',\n    formConfig: this.productComponentFormConfig\n  }\n\n  // Bundle product form configuration\n  bundleProductFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capProducts] },\n    title: 'Bundle Product',\n    fixedTitle: true,\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'productInfo', type: 'section', alias: 'Bundle Information' },\n      { name: 'name', type: 'text', required: true, alias: 'Bundle Name', section: 'productInfo', infoMessage: 'Name for this product bundle' },\n      { name: 'sku', type: 'text', alias: 'SKU (optional)', section: 'productInfo', infoMessage: 'Stock Keeping Unit for bundle tracking' },\n      { name: 'description', type: 'text', alias: 'Description', span: true, section: 'productInfo', infoMessage: 'Description of what is included in this bundle' },\n      { name: 'isBundle', type: 'checkbox', alias: 'Is Bundle', hidden: true, defaultValue: true },\n      \n      { name: 'pricingInfo', type: 'section', alias: 'Pricing' },\n      { name: 'sellingPrice', type: 'money', required: true, alias: 'Bundle Price', section: 'pricingInfo', infoMessage: 'Selling price for the complete bundle' },\n      { name: 'bundleEstimatedCost', type: 'money', alias: 'Estimated Cost', section: 'pricingInfo', readonly: true, hideOnCreate: true, infoMessage: 'Total estimated cost based on component costs' },\n\n      { name: 'inventoryInfo', type: 'section', alias: 'Inventory Settings', collapsedCondition: x => x.productID }, \n      { name: 'baseUnit', type: 'select', required: true, alias: 'Base Unit', section: 'inventoryInfo', loadAction: { url: 'products/list/base-unit' }, defaultFirstValue: true, infoMessage: 'Unit of measure for bundle' },\n      { name: 'bundleAvailableQuantity', type: 'number', alias: 'Available to Sell', section: 'inventoryInfo', readonly: true, hideOnCreate: true, infoMessage: 'Number of bundles that can be assembled from current component stock' },\n\n\n    ],\n    loadAction: { url: 'products/id' },\n    heroField: 'productID'\n  }\n\n  bundleProductDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.bundleProductFormConfig,\n    tableConfigs: [this.productComponentsTableConfig],\n    heroField: 'productID',\n    buttons: [\n      { name: 'create', display: 'Create Bundle', dialog: true, action: { url: 'products?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'products?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'products?action=delete', method: 'post' } }\n    ]\n  }\n\n  bundleProductViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.bundleProductDetailsConfig }\n  bundleProductCreateButton: Button = { name: 'create', display: 'Create Bundle', dialog: true, action: { url: 'products?action=create', method: 'post' } }\n\n  // Table configuration for bundle products\n  bundleProductsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'sku', 'bundleAvailableQuantity'],\n    columns: [\n      { name: 'name', type: 'text', alias: 'Bundle Name' },\n      { name: 'sku', type: 'text', alias: 'SKU' },\n      { name: 'bundleAvailableQuantity', type: 'number', alias: 'Available', icon: { name: 'info', color: '#2196F3', condition: (x: any) => x.bundleAvailableQuantity > 0 } }, // Changed: Removed infoMessage as it's not valid for columns\n      { name: 'bundleEstimatedCost', type: 'money', alias: 'Est. Cost' },\n      { name: 'sellingPrice', type: 'money', alias: 'Selling Price' },\n      { name: 'categoryName', type: 'text', alias: 'Category' }\n    ],\n    buttons: [\n      this.bundleProductCreateButton,\n      this.bundleProductViewButton,\n      { name: 'edit', dialog: true, action: { url: 'products?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'products?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'products/bundles/x' },\n    formConfig: this.bundleProductFormConfig,\n    realTime: true,\n    entityName: 'Product'\n  }\n\n  //--------------------------ServiceItems-------------------------\n\n  // ServiceItem form configuration - follows Product pattern\n  serviceItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capServiceItems] }, // Added: gate service item form by service items cap\n    title: 'Service',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, alias: 'Service Name' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true },\n      { name: 'description', type: 'text', alias: 'Description' },\n      { name: 'unitPrice', type: 'money', required: true, alias: 'Unit Price' },\n      { name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, loadAction: { url: 'serviceitems/list/tax-rates' }, infoMessage: 'VAT rate applied to this service' }, // Changed: Tax rate selector\n      { name: 'isTaxInclusive', type: 'checkbox', alias: 'Price includes Tax', infoMessage: 'If checked, the unit price already includes tax' }, // Changed: Tax-inclusive flag\n    ],\n    loadAction: { url: 'serviceitems/id' },\n    heroField: 'serviceItemID'\n  }\n\n  serviceItemCreateButton: Button = { name: 'create', display: 'Create Service', dialog: true, action: { url: 'serviceitems?action=create', method: 'post' } }\n  serviceItemEditButton: Button = { name: 'edit', dialog: true, action: { url: 'serviceitems?action=edit', method: 'post' } }\n  serviceItemDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'serviceitems?action=delete', method: 'post' } }\n\n  serviceItemDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.serviceItemFormConfig,\n    heroField: 'serviceItemID',\n    buttons: [this.serviceItemCreateButton, this.serviceItemEditButton, this.serviceItemDeleteButton]\n  }\n\n  serviceItemsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'unitPrice', 'statusName'],\n    columns: [\n      { name: 'name', type: 'text', alias: 'Service Name' },\n      { name: 'description', type: 'text', alias: 'Description' },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price' },\n      { name: 'taxRateName', type: 'text', alias: 'Tax Rate' }, // Changed: Tax rate display with N/A fallback\n      { name: 'priceExclTax', type: 'text', alias: 'Price (Excl)' }, // Changed: Computed price excluding tax\n      { name: 'priceInclTax', type: 'text', alias: 'Price (Incl)' }, // Changed: Computed price including tax\n      { name: 'statusName', type: 'text', alias: 'Status' }\n    ],\n    buttons: [\n      this.serviceItemCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.serviceItemDetailsConfig },\n      this.serviceItemEditButton,\n      this.serviceItemDeleteButton\n    ],\n    loadAction: { url: 'serviceitems/all/x' },\n    formConfig: this.serviceItemFormConfig,\n    realTime: true,\n    entityName: 'ServiceItem'\n  }\n\n  //--------------------------Requisitions-------------------------\n\n  requisitionItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capRequisitions] }, // Added: gate requisition item form by requisitions cap (parent entity)\n    title: 'Requisition Item',\n    fixedTitle: true, // Changed: Use fixedTitle to avoid duplication with 'Add Item' button\n    fields: [\n      { name: 'productID', type: 'select', alias: 'Product', required: true, loadAction: { url: 'products/list/x' }, detailsConfig: this.productDetailsConfig },\n      { name: 'requestedQuantity', type: 'number', alias: 'Requested Qty', required: true },\n      { name: 'issuedQuantity', type: 'number', alias: 'Issued Qty', readonly: true },\n      { name: 'inventoryItemID', type: 'select', alias: 'Serial Number', loadAction: { url: 'inventoryitems/list/x' } }\n    ],\n    loadAction: { url: 'requisitionitems/id' }\n  }\n\n  requisitionItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    // showInModes: ['edit'],\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'requestedQuantity', type: 'number', alias: 'Requested Qty' },\n      { name: 'issuedQuantity', type: 'number', alias: 'Issued Qty' },\n      { name: 'serialNumber', type: 'text', alias: 'Serial Number' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'requisitionitems?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'requisitionitems?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'requisitionitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'requisitionitems/x/x' }, loadCriteria: 'requisition', loadIDField: 'requisitionID',\n    formConfig: this.requisitionItemFormConfig\n  }\n\n  requisitionFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capRequisitions] },\n    title: 'Requisition',\n    fixedTitle: true, // Changed: Use fixedTitle to avoid duplication with 'New Requisition' button\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'reqInfo', type: 'section', alias: 'Requisition Information' },\n      { name: 'requisitionNumber', type: 'text', alias: 'Requisition #', readonly: true, section: 'reqInfo' },\n      { name: 'requestedBy', type: 'text', alias: 'Requested By', readonly: true, section: 'reqInfo' },\n      { name: 'departmentID', type: 'select', alias: 'Department', section: 'reqInfo', loadAction: { url: 'departments/list/x' } },\n      { name: 'requestDate', type: 'date', alias: 'Request Date', readonly: true, section: 'reqInfo' },\n      { name: 'issuedDate', type: 'date', alias: 'Issued Date', readonly: true, section: 'reqInfo' },\n      { name: 'status', type: 'select', alias: 'Status', readonly: true, serverOwned: true, hideOnCreate: true, section: 'reqInfo', loadAction: { url: 'requisitions/list/status' } }, // Changed (CFW-1): Requisition.Status carries [ServerOwned] // Changed: hideOnCreate so getInitialValue seeds status 0 on create (was omitted → create 400)\n      \n      { name: 'purposeInfo', type: 'section', alias: 'Purpose & Notes', collapseOnView: true },\n      { name: 'purpose', type: 'text', required: true, alias: 'Purpose', span: true, section: 'purposeInfo' },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'purposeInfo' }\n    ],\n    loadAction: { url: 'requisitions/id' },\n    heroField: 'requisitionID'\n  }\n\n  requisitionEditButton: Button = { name: 'edit', dialog: true, action: { url: 'requisitions?action=edit', method: 'post' } }\n  // Changed: `inDialog: true` added. This button lives ONLY in requisitionDetailsConfig.buttons and is absent\n  // from the table's own buttons, and Core.setupButtons filters a details dialog's extraButtons on exactly that\n  // flag — so it rendered NOWHERE. Its two siblings below both carry it. Colour changed from the Material palette\n  // name 'primary', which ButtonService.getButtonColor puts verbatim into [style.color] where it computes to the\n  // inherited grey, to the house CSS keyword 'blue'.\n  requisitionSubmitButton: Button = { name: 'submit', display: 'Submit Requisition', icon: { name: 'send', color: 'blue' }, inDialog : true, action: { url: 'requisitions?action=submit', method: 'post', successMessage: 'Requisition Submitted' }, confirm: { message: 'Submit this requisition for approval?' },  visible: (row) => row.status === 0 }\n  requisitionIssueButton: Button = { name: 'issue', display: 'Issue Items', icon: { name: 'check', color: 'green' }, inDialog : true, action: { url: 'requisitions?action=issue', method: 'post', successMessage: 'Items Issued' }, confirm: { message: 'Issue items for this requisition?' }, visible: (row) => row.pendingApproval === false && row.status === 0 }\n  requisitionCancelButton: Button = { name: 'cancel', display: 'Cancel Request', icon: { name: 'close', color: 'red' }, inDialog : true, action: { url: 'requisitions?action=cancel', method: 'post', successMessage: 'Requisition Cancelled' }, confirm: { message: 'Cancel this requisition?' }, visible: (row) => row.status === 0 }\n\n  requisitionDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.requisitionFormConfig,\n    tableConfigs: [this.requisitionItemsTableConfig],\n    heroField: 'requisitionID',\n    buttons: [ this.requisitionEditButton, this.requisitionSubmitButton, this.requisitionIssueButton, this.requisitionCancelButton]\n  }\n\n  requisitionViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.requisitionDetailsConfig }\n\n  requisitionsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['requisitionNumber', 'requesterName', 'requestDate'],\n    columns: [\n      { name: 'requisitionNumber', type: 'text', alias: 'Requisition #' },\n      { name: 'requesterName', type: 'monogram', alias: 'Requested By' }, // Changed: monogram — the row still carries the full name, so filter/sort are untouched\n      { name: 'departmentName', type: 'text', alias: 'Department' },\n      { name: 'requestDate', type: 'date', alias: 'Request Date' },\n      { name: 'issuedDate', type: 'date', alias: 'Issued Date' },\n      { name: 'status', type: 'text', alias: 'Status' },\n      { name: 'purpose', type: 'text', alias: 'Purpose', maxLength: 100 },\n      { name: 'pendingApproval', type: 'checkbox', alias: 'Pending' }\n    ],\n    buttons: [\n      { name: 'create', display: 'New Requisition', dialog: true, action: { url: 'requisitions?action=create', method: 'post' }, onSuccessButton: this.requisitionViewButton },\n      { name: 'view', dialog: true, detailsConfig: this.requisitionDetailsConfig },\n      { name: 'edit', dialog: true, detailsConfig: this.requisitionDetailsConfig },\n      { name: 'delete', dialog: true, action: { url: 'requisitions?action=delete', method: 'post' } },\n      this.requisitionIssueButton,\n      this.requisitionCancelButton\n    ],\n    loadAction: { url: 'requisitions/all/x' },\n    formConfig: this.requisitionFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — requisitions append continuously\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — requisitions are raised at the point of need, often away from the desk\n    entityName: 'Requisition',\n  }\n\n  // Removed: Purchase Orders configs moved to PurchasingService\n  // Removed: Inventory Receipts configs moved to PurchasingService\n\n  //--------------------------Inventory Items-------------------------\n\n  inventoryItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryItems] },\n    title: 'Inventory Item',\n    includeAudit: true,\n    fields: [\n      { name: 'productName', type: 'text', alias: 'Product', readonly: true },\n      { name: 'serialNumber', type: 'text', alias: 'Serial Number', readonly: true },\n      { name: 'quantity', type: 'number', alias: 'Quantity', readonly: true },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost', readonly: true },\n      { name: 'totalValue', type: 'money', alias: 'Total Value', readonly: true },\n      { name: 'status', type: 'text', alias: 'Status', readonly: true },\n      { name: 'receivedDate', type: 'date', alias: 'Received Date', readonly: true }\n    ],\n    loadAction: { url: 'inventoryitems/id' },\n    heroField: 'inventoryItemID'\n  }\n\n  inventoryItemDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.inventoryItemFormConfig,\n    heroField: 'inventoryItemID',\n    buttons: []\n  }\n\n  // Added (WS-1 sweep): paginated but deliberately NOT offline — InventoryItem does not implement ISync, so a queued write has no RowVersion/ClientRef to sync or dedupe on. Adding it is a migration, not a config change. A read-only cache for stock lookups on the floor belongs to the CACHE phase.\n  inventoryItemsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['productName', 'serialNumber', 'quantity'],\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'serialNumber', type: 'text', alias: 'Serial Number' }, // Changed: Backend should return N/A for non-serialized products\n      { name: 'quantity', type: 'number', alias: 'Quantity' },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost' },\n      { name: 'totalValue', type: 'money', alias: 'Total Value' },\n      { name: 'statusName', type: 'text', alias: 'Status' }, // Changed: Use statusName instead of status to show status name\n      { name: 'receivedDate', type: 'date', alias: 'Received Date' }\n    ],\n    \n    buttons: [\n      // this.inventoryQuickPurchaseButton,\n      { name: 'view', dialog: true, detailsConfig: this.inventoryItemDetailsConfig }\n    ],\n    loadAction: { url: 'inventoryitems/all/x' },\n    formConfig: this.inventoryItemFormConfig,\n    realTime: true,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — one row per stock record — the largest table in inventory\n    entityName: 'InventoryItem',\n  }\n\n  \n\n  //--------------------------Inventory Adjustments-------------------------\n\n  // Updated: Changed form from all-readonly to editable fields for create/edit\n  inventoryAdjustmentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryAdjustments] },\n    title: 'Inventory Adjustment',\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'adjustmentInfo', type: 'section', alias: 'Adjustment Information' },\n      { name: 'adjustmentNumber', type: 'text', alias: 'Adjustment #', readonly: true, section: 'adjustmentInfo' },\n      { name: 'productID', type: 'select', required: true, alias: 'Product', section: 'adjustmentInfo', loadAction: { url: 'products/list/x' } },\n      { name: 'reason', type: 'select', required: true, alias: 'Reason', section: 'adjustmentInfo', loadAction: { url: 'inventoryadjustments/list/reason' } },\n      { name: 'adjustmentQuantity', type: 'number', required: true, alias: 'Quantity (+/-)', section: 'adjustmentInfo' },\n      { name: 'adjustmentDate', type: 'date', alias: 'Date', readonly: true, section: 'adjustmentInfo' },\n      { name: 'additionalInfo', type: 'section', alias: 'Additional Information', collapseOnView: true },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'additionalInfo' },\n      { name: 'pendingApproval', type: 'checkbox', alias: 'Pending Approval', readonly: true, section: 'additionalInfo' }\n    ],\n    loadAction: { url: 'inventoryadjustments/id' },\n    heroField: 'inventoryAdjustmentID'\n  }\n\n  // Added: CRUD buttons for adjustments\n  inventoryAdjustmentCreateButton: Button = { name: 'create', display: 'Create Adjustment', dialog: true, action: { url: 'inventoryadjustments?action=create', method: 'post' } }\n  inventoryAdjustmentEditButton: Button = { name: 'edit', dialog: true, action: { url: 'inventoryadjustments?action=edit', method: 'post' } }\n  inventoryAdjustmentDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'inventoryadjustments?action=delete', method: 'post' } }\n\n  // Updated: Added edit/delete buttons to details dialog\n  inventoryAdjustmentDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.inventoryAdjustmentFormConfig,\n    heroField: 'inventoryAdjustmentID',\n    buttons: [this.inventoryAdjustmentEditButton, this.inventoryAdjustmentDeleteButton]\n  }\n\n  // Updated: Added create/edit/delete buttons to table\n  inventoryAdjustmentsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['adjustmentNumber', 'productName', 'reason'],\n    columns: [\n      { name: 'adjustmentNumber', type: 'text', alias: 'Adjustment #' },\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'reason', type: 'text', alias: 'Reason' },\n      { name: 'adjustmentQuantity', type: 'number', alias: 'Quantity' },\n      { name: 'adjustmentDate', type: 'date', alias: 'Date' },\n      { name: 'pendingApproval', type: 'checkbox', alias: 'Pending' }\n    ],\n    buttons: [\n      this.inventoryAdjustmentCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.inventoryAdjustmentDetailsConfig },\n      this.inventoryAdjustmentEditButton,\n      this.inventoryAdjustmentDeleteButton\n    ],\n    loadAction: { url: 'inventoryadjustments/all/x' },\n    formConfig: this.inventoryAdjustmentFormConfig,\n    realTime: true,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — adjustments append with every stock count\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — adjustments are captured on the warehouse floor\n    entityName: 'InventoryAdjustment',\n  }\n\n  //--------------------------Inventory Returns-------------------------\n\n  // Added: Return item form config with conditional fields based on return type\n  inventoryReturnItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReturns] },\n    title: 'Return Item',\n    fields: [\n      { name: 'productID', type: 'select', required: true, alias: 'Product', loadAction: { url: 'products/list/x' } },\n      { name: 'quantity', type: 'number', required: true, alias: 'Quantity' },\n      { name: 'unitValue', type: 'money', required: true, alias: 'Unit Value' },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total', readonly: true },\n      { name: 'restockApproved', type: 'checkbox', alias: 'Restock', hidden: (x: any) => x._parentReturnType === 2 },\n      { name: 'isGoodCondition', type: 'checkbox', alias: 'Good Condition', hidden: (x: any) => x._parentReturnType !== 2 },\n      { name: 'conditionNotes', type: 'text', alias: 'Condition Notes', span: true, hidden: (x: any) => x._parentReturnType !== 2 }\n    ],\n    loadAction: { url: 'inventoryreturnitems/id' },\n    heroField: 'inventoryReturnItemID'\n  }\n\n  // Added: Return items table for details dialog\n  inventoryReturnItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'quantity', type: 'number', alias: 'Quantity' },\n      { name: 'unitValue', type: 'money', alias: 'Unit Value' },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total' },\n      { name: 'restockApproved', type: 'checkbox', alias: 'Restock' },\n      { name: 'isGoodCondition', type: 'checkbox', alias: 'Good Condition' },\n      { name: 'conditionNotes', type: 'text', alias: 'Notes' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'inventoryreturnitems?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'inventoryreturnitems?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'inventoryreturnitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'inventoryreturnitems/x/x' }, loadCriteria: 'return', loadIDField: 'inventoryReturnID',\n    formConfig: this.inventoryReturnItemFormConfig\n  }\n\n  // Added: Return form config with conditional source fields based on return type\n  inventoryReturnFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReturns] },\n    title: 'Inventory Return',\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'returnInfo', type: 'section', alias: 'Return Information' },\n      { name: 'returnNumber', type: 'text', alias: 'Return #', readonly: true, section: 'returnInfo' },\n      { name: 'returnType', type: 'select', required: true, alias: 'Return Type', section: 'returnInfo', loadAction: { url: 'inventoryreturns/list/return-type' } },\n      { name: 'returnDate', type: 'date', alias: 'Return Date', readonly: true, section: 'returnInfo' },\n      { name: 'status', type: 'select', alias: 'Status', readonly: true, serverOwned: true, hideOnCreate: true, section: 'returnInfo', loadAction: { url: 'inventoryreturns/list/status' } }, // Changed (CFW-1): InventoryReturn.Status carries [ServerOwned] // Changed: hideOnCreate so getInitialValue seeds status 0 on create (was omitted → create 400)\n      { name: 'sourceInfo', type: 'section', alias: 'Source Details', collapseOnView: true },\n      { name: 'customerID', type: 'select', alias: 'Customer', section: 'sourceInfo', loadAction: { url: 'customers/list/x' }, hidden: (x: any) => x.returnType !== 0, detailsConfig: this.dataService.customerDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'saleID', type: 'select', alias: 'Sale', section: 'sourceInfo', loadAction: { url: 'sales/list/x' }, hidden: (x: any) => x.returnType !== 0 },\n      { name: 'supplierID', type: 'select', alias: 'Supplier', section: 'sourceInfo', loadAction: { url: 'suppliers/list/x' }, hidden: (x: any) => x.returnType !== 1, detailsConfig: this.dataService.supplierDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'purchaseID', type: 'select', alias: 'Purchase', section: 'sourceInfo', loadAction: { url: 'purchases/list/x' }, hidden: (x: any) => x.returnType !== 1 }, // Changed: inventoryReceiptID → purchaseID, inventoryreceipts → purchases\n      { name: 'requisitionID', type: 'select', alias: 'Requisition', section: 'sourceInfo', loadAction: { url: 'requisitions/list/x' }, hidden: (x: any) => x.returnType !== 2 },\n      { name: 'details', type: 'section', alias: 'Details', collapseOnView: true },\n      { name: 'reason', type: 'text', required: true, alias: 'Reason', span: true, section: 'details' },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'details' },\n      { name: 'totals', type: 'section', alias: 'Totals', collapseOnView: true },\n      { name: 'totalAmount', type: 'money', alias: 'Total Amount', readonly: true, serverOwned: true, section: 'totals' } // Changed (CFW-1): InventoryReturn.TotalAmount carries [ServerOwned] — the Phase 4/5 before-and-after row, forged to 555 and now held at the recomputed figure\n    ],\n    loadAction: { url: 'inventoryreturns/id' },\n    heroField: 'inventoryReturnID'\n  }\n\n  // Added: CRUD + action buttons for returns\n  inventoryReturnEditButton: Button = { name: 'edit', dialog: true, action: { url: 'inventoryreturns?action=edit', method: 'post' } }\n  inventoryReturnDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'inventoryreturns?action=delete', method: 'post' } }\n  inventoryReturnRejectButton: Button = { name: 'reject', display: 'Reject', icon: { name: 'cancel', color: 'red' }, inDialog: true, action: { url: 'inventoryreturns?action=reject', method: 'post', successMessage: 'Return rejected' }, confirm: { message: 'Reject this return?' }, visible: (x: any) => x.status === 0 }\n\n  // Added: Details dialog with items table\n  inventoryReturnDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.inventoryReturnFormConfig,\n    tableConfigs: [this.inventoryReturnItemsTableConfig],\n    heroField: 'inventoryReturnID',\n    buttons: [this.inventoryReturnEditButton, this.inventoryReturnDeleteButton, this.inventoryReturnRejectButton]\n  }\n\n  inventoryReturnViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.inventoryReturnDetailsConfig }\n\n  // Changed: moved below detailsConfig/viewButton and given onSuccessButton so a new return auto-opens its details dialog for item entry (two-step create pattern, as per requisitions). Defining it above viewButton left the reference undefined at field-initializer time\n  inventoryReturnCreateButton: Button = { name: 'create', display: 'Create Return', dialog: true, action: { url: 'inventoryreturns?action=create', method: 'post' }, onSuccessButton: this.inventoryReturnViewButton }\n\n  // Added: Main returns table config\n  inventoryReturnsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['returnNumber', 'entityName', 'returnDate'],\n    columns: [\n      { name: 'returnNumber', type: 'text', alias: 'Return #' },\n      { name: 'returnType', type: 'text', alias: 'Type' },\n      { name: 'entityName', type: 'text', alias: 'Source' },\n      { name: 'returnDate', type: 'date', alias: 'Date' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'status', type: 'text', alias: 'Status' },\n      { name: 'pendingApproval', type: 'checkbox', alias: 'Pending' }\n    ],\n    buttons: [\n      this.inventoryReturnCreateButton,\n      this.inventoryReturnViewButton,\n      this.inventoryReturnEditButton,\n      this.inventoryReturnDeleteButton,\n      this.inventoryReturnRejectButton\n    ],\n    loadAction: { url: 'inventoryreturns/all/x' },\n    formConfig: this.inventoryReturnFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — returns append continuously\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — returns are captured at the counter as goods come back\n    entityName: 'InventoryReturn',\n  }\n\n  //--------------------------Inventory Transactions-------------------------\n\n  inventoryTransactionFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryTransactions] },\n    title: 'Inventory Transaction',\n    includeAudit: true,\n    fields: [\n      { name: 'productName', type: 'text', alias: 'Product', readonly: true },\n      { name: 'transactionType', type: 'text', alias: 'Type', readonly: true },\n      { name: 'quantity', type: 'number', alias: 'Quantity', readonly: true },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost', readonly: true },\n      { name: 'totalValue', type: 'money', alias: 'Total Value', readonly: true },\n      { name: 'transactionDate', type: 'date', alias: 'Date', readonly: true },\n      { name: 'referenceType', type: 'text', alias: 'Reference', readonly: true }\n    ],\n    loadAction: { url: 'inventorytransactions/id' },\n    heroField: 'inventoryTransactionID'\n  }\n\n  inventoryTransactionDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.inventoryTransactionFormConfig,\n    heroField: 'inventoryTransactionID',\n    buttons: []\n  }\n\n  inventoryTransactionsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['productName', 'transactionTypeName', 'quantity'],\n    columns: [\n      { name: 'transactionDate', type: 'date', alias: 'Date' },\n      { name: 'transactionTypeName', type: 'text', alias: 'Type' },\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'quantity', type: 'number', alias: 'Quantity' },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost' },\n      { name: 'totalValue', type: 'money', alias: 'Total Value' },\n      { name: 'referenceType', type: 'text', alias: 'Reference' }\n    ],\n    buttons: [\n      { name: 'view', dialog: true, detailsConfig: this.inventoryTransactionDetailsConfig }\n    ],\n    loadAction: { url: 'inventorytransactions/all/x' },\n    formConfig: this.inventoryTransactionFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — the stock movement ledger grows with every transaction\n    offline: { enabled: true, readOnly: true }, // Added: offline reads only — read-only ledger (view is the only button) so there is nothing to queue — cache the reads instead\n    entityName: 'InventoryTransaction',\n  }\n\n  //--------------------------Inventory Stock (Grouped by Product)-------------------------\n\n  // Changed: Reuse existing inventoryItemsTableConfig with product criteria filter\n  inventoryStockItemsTableConfig: TableConfig = {\n    ...this.inventoryItemsTableConfig,\n    tabTitle: 'Stock Items',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    buttons: [],\n    loadAction: { url: 'inventoryitems/stock/x' }, loadCriteria: 'product', loadIDField: 'productID'\n  }\n\n  // Changed: Reuse product form config, filter to show only Product Information section fields\n  inventoryStockProductFormConfig: FormConfig = {\n    ...this.productFormConfig,\n    security: { allow: [this.dataService.capInventoryStock] },\n    fields: this.productFormConfig.fields.filter(f => f.section === 'productInfo' || f.name === 'productInfo').map(f => ({ ...f, readonly: true })),\n    loadAction: { url: 'products/id' }\n  }\n\n  // Changed: Details config reuses simplified product form and inventory items table\n  inventoryStockDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.inventoryStockProductFormConfig,\n    tableConfigs: [this.inventoryStockItemsTableConfig],\n    heroField: 'productID',\n    buttons: []\n  }\n\n  // Inventory stock summary tiles\n  inventoryStockTileConfig: TileConfig = {\n    clickable: true,\n    headerPosition: 'top',\n    tiles: [\n      { name: 'totalProducts', alias: 'Total Products', color: '#2196F3', icon: 'category', info: 'Total number of products in inventory', action: { url: 'inventoryitems/stock/all' } }, // Changed: Added icon\n      { name: 'lowStockProducts', alias: 'Low Stock', color: '#FFC107', icon: 'warning', info: 'Products below minimum quantity', action: { url: 'inventoryitems/stock/lowstock' } }, // Changed: Added icon\n      { name: 'outOfStockProducts', alias: 'Out of Stock', color: '#F44336', icon: 'remove_shopping_cart', info: 'Products with zero quantity', action: { url: 'inventoryitems/stock/outofstock' } }, // Changed: Added icon\n      { name: 'serializedProducts', alias: 'Serialized Products', color: '#9C27B0', icon: 'qr_code_2', info: 'Number of products with serial tracking', action: { url: 'inventoryitems/stock/serialized' } }, // Changed: Added icon\n    ],\n    loadAction: { url: 'inventoryitems/stock/summary' }\n  }\n\n  // Changed: Table config for inventory stock grouped by product\n  inventoryStockTableConfig: TableConfig = {\n    showFilter: true,\n    holdHeaderButtonSpace: true,\n    flatButtons: true,\n    minColumns: ['productName', 'totalQuantity'],\n    columns: [\n      { name: 'productName', type: 'button', alias: 'Product', detailsConfig: this.inventoryStockDetailsConfig },\n      { name: 'totalQuantity', type: 'number', alias: 'Total Stock', icon: { name: 'warning', color: 'orange', condition: (x: any) => x.isLowInventory } }\n    ],\n    buttons: [\n      { name: 'view', dialog: true, detailsConfig: this.inventoryStockDetailsConfig, },\n\n    ],\n    loadAction: { url: 'inventoryitems/stock/all' },\n    formConfig: this.productFormConfig,\n    tileConfig: this.inventoryStockTileConfig\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { HttpClient } from '@angular/common/http'; // Added: the PDF button downloads its blob from the SERVICE now, same reason as the dialog below — a page-owned handler is dead in every other consumer\nimport { MatDialog } from '@angular/material/dialog'; // Added: the allocate button opens its dialog from the SERVICE now, so it works in every consumer and not just on the receipts page\nimport { ReceiptDialogComponent } from '../pages/accounting/receipts/receipt-dialog.component'; // Added: no import cycle — this dialog injects only HttpService/MessageService and never reaches back into AccountingService\nimport { FormConfig, TableConfig, DetailsDialogConfig, Button, TileConfig, Column, RoleAccess } from '../classes/Classes'; // Changed: RoleAccess — the invoice lifecycle buttons now demand the level InvoicesController demands\nimport { DataServiceLib } from './datalib.service';\nimport { HttpService } from './http.service'; // Added: supplies apiUrl for the receipt PDF download — the same source ReceiptsComponent used, so the URL is unchanged\nimport { InventoryService } from './inventory.service'; // Changed: dropdown quick-add — product/service configs for invoice item selects\nimport { InvoiceStatus, CreditNoteStatus, FiscalPeriodStatus, QuoteStatus } from '../classes/LibClasses'; // Changed: Added QuoteStatus for quotations (C10)\n\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class AccountingService {\n\n  private dataService = inject(DataServiceLib);\n  private inventoryService = inject(InventoryService); // Changed: dropdown quick-add — product/service configs for invoice item selects\n  private dialog = inject(MatDialog); // Added: declared ABOVE receiptAllocateButton deliberately — that button is a field initialiser and its handler closes over this\n  private httpService = inject(HttpService); // Added: same field-initialiser ordering reason — receiptPdfButton's handler closes over this\n  private http = inject(HttpClient); // Added: a bare HttpClient exactly as ReceiptsComponent used, so the bearer token still comes from LoaderInterceptor; HttpService has no POST-blob helper and adding one would touch a file this chunk does not own\n\n  //--------------------------Accounts Base-------------------------\n  accountFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccounts] },\n    title: 'Financial Account',\n    includeAudit: true,\n    // Changed: split into what you need every time you open an account, and what you set once. Balance was\n    // buried among the reporting toggles despite being the thing people open an account to see, while the\n    // account code, the cash/bank total toggles and the IAS 7 classification are configuration — set at\n    // creation and rarely looked at again. Those now live in a collapsed section.\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'type', type: 'select', required: true, loadAction: { url: 'accounts/list/accountTypes' } },\n      { name: 'currencyID', type: 'select', alias: 'Currency', loadAction: { url: 'currencies/list/x' } }, // Changed: Added currency select for multi-currency support\n      { name: 'balanceDisplay', alias: 'Balance', type: 'text', readonly: true, hideOnCreate: true }, // Changed: promoted — this is the reason the dialog gets opened // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'classification', type: 'section', alias: 'Classification & Reporting', collapseOnView: true }, // Added: collapsed by default; these are set-once settings\n      { name: 'code', type: 'text', alias: 'Account Code', section: 'classification', infoMessage: 'Chart of accounts code (1xxx assets, 2xxx liabilities, 3xxx equity, 4xxx revenue, 5xxx expenses)' }, // Changed: COA code (B1); moved into the collapsed section\n      { name: 'includeInCashTotal', type: 'checkbox', alias: 'Include in Cash Total', section: 'classification', hidden: (data: any) => data.type !== 0 }, // Changed: Only visible for Asset accounts (type 0)\n      { name: 'includeInBankTotal', type: 'checkbox', alias: 'Include in Bank Total', section: 'classification', hidden: (data: any) => data.type !== 0 }, // Changed: Only visible for Asset accounts (type 0)\n      // Changed (E21): defaultValue added. An untouched select initialises to null (TinCore.getInitialValue\n      // `case 'select': return null`), and Account.CashFlow is a NON-NULLABLE CashFlowCategory, so creating an\n      // account without opening this collapsed section posted cashFlow:null and was rejected at model binding\n      // with a 400 — surfaced to the user as \"Something went wrong ... a technical problem in the app\" and\n      // logged nowhere. 0 is Operating, which is the model's own C# default (Account.cs:69), so this makes the\n      // form agree with the entity rather than inventing a value.\n      { name: 'cashFlow', type: 'select', alias: 'Cash Flow Section', section: 'classification', defaultValue: 0, infoMessage: 'IAS 7 cash flow statement classification', // Changed: C5 cash flow category\n        options: [\n          { name: 'Operating', value: 0 },\n          { name: 'Investing', value: 1 },\n          { name: 'Financing', value: 2 },\n          { name: 'Cash Equivalent', value: 3 }\n        ]\n      },\n    ],\n    loadAction: { url: 'accounts/id' },\n    heroField: 'accountID',\n  }\n\n  accountCreateButton: Button = { name: 'create', display: 'Create Account', dialog: true, action: { url: 'accounts?action=create', method: 'post' } }\n  finAccounEditButton: Button = { name: 'edit', dialog: true, action: { url: 'accounts?action=edit', method: 'post' } }\n\n\n\n    accountBaseDetailsConfig : DetailsDialogConfig = {\n      formConfig: this.accountFormConfig,\n      tableConfigs: [],\n      heroField: 'accountID',\n      buttons: [this.accountCreateButton, this.finAccounEditButton]\n    };\n\n  //--------------------------Invoices-------------------------\n\n  // Added: Invoice payment form configuration\n  invoicePaymentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] },\n    title: 'Record Payment',\n    fixedTitle : true,\n    fields: [\n      { name: 'invoiceID', type: 'number', hidden : true},\n      { name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true }, // Changed (NFD-2, Arbiter 2026-08-19): max: 'today' REMOVED — deliberately uncapped. A payment may legitimately carry a future date (post-dated cheque), so the future IS a valid answer here. Not method-conditioned: uncapped for every payment method.\n      { name: 'method', type: 'select', alias: 'Payment Method', required: true, defaultValue : 1, loadAction: { url: 'invoicepayments/list/methods' } },\n      { name: 'currencyID', type: 'select', alias: 'Currency', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, infoMessage: 'Currency for this payment (defaults to base currency)' }, // Changed: Added currency select for multi-currency payments\n      { name: 'outstandingAmount', type: 'text', alias: 'Outstanding', readonly: true}, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'amount', type: 'money', alias: 'Amount', required: true, span : true },\n      \n      { name: 'reference', type: 'text', alias: 'Reference', span : true }\n    ],\n  }\n\n  invoicePaymentCreateButton : Button = { name : 'edit', action: { url: 'invoicepayments?action=create', method: 'post', successMessage: 'Payment Recorded' }};\n\n  invoicePaymentsCreateDetailsDialogConfig: DetailsDialogConfig = {\n    formConfig: this.invoicePaymentFormConfig, \n    heroField: 'invoiceID',\n    mode: 'edit',\n    seedDefaults: true, // Added: CAPTURE dialog wearing mode:'edit' (it posts invoicepayments?action=create), so generateObject never ran for it. VERIFIED NO-OP TODAY, and deliberately kept: InvoicesController.cs:122 already projects Method = InvoicePaymentMethod.Bank onto the invoice row, so `method` arrives POPULATED and the only-empty guard correctly leaves it alone. The flag is the declared fallback if that projection ever stops supplying it — it is not what fills the field today.\n    buttons: [\n      this.invoicePaymentCreateButton\n    ]\n  }\n\n\n  // Added: Invoice payments table for history tracking\n  invoicePaymentsTableConfig: TableConfig = {\n    tabTitle: 'Payment History',\n    showFilter: false,\n    minColumns: ['paymentDate', 'amount', 'methodName'],\n    columns: [\n      { name: 'paymentDate', type: 'date', alias: 'Date' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'methodName', type: 'text', alias: 'Method' },\n      { name: 'reference', type: 'text', alias: 'Reference' }\n    ],\n    buttons: [\n      // Changed: Removed dead 'Migrate Legacy Payments' button — backend invoicepayments/migrate endpoint is decommissioned\n      { name: 'edit', dialog: true, action: { url: 'invoicepayments?action=edit', method: 'post' }, visible: x => x.status != InvoiceStatus.Paid }, // Changed: Added edit button, hide on Paid invoices\n      { name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'invoicepayments?action=delete', method: 'post', successMessage: 'Payment deleted' }, confirm: { message: 'Delete this payment? The linked financial transaction will be reversed.' }, visible: x => x.status != InvoiceStatus.Paid } // Changed: Added delete button with reversal warning, hide on Paid invoices\n    ],\n    loadAction: { url: 'invoicepayments/x/x' }, loadCriteria: 'invoice', loadIDField: 'invoiceID',\n    formConfig: { // Changed: Added form for editing payments\n      title: 'Edit Payment',\n      fields: [\n        { name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true }, // Changed (NFD-2, Arbiter 2026-08-19): max: 'today' REMOVED — deliberately uncapped. A payment may legitimately carry a future date (post-dated cheque), so the future IS a valid answer here. Not method-conditioned: uncapped for every payment method.\n        { name: 'method', type: 'select', alias: 'Payment Method', required: true, loadAction: { url: 'invoicepayments/list/methods' } },\n        { name: 'amount', type: 'money', alias: 'Amount', required: true },\n        { name: 'reference', type: 'text', alias: 'Reference' }\n      ],\n      loadAction: { url: 'invoicepayments/id' }\n    }\n  }\n\n  // Invoice form configuration with customer and status fields\n  invoiceFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] },\n    title: 'Invoice',\n    includeAudit: true,\n    // Changed: sectioned — who owes what stays on top, the paperwork and the sub-totals fold away so the items\n    // and payments tabs sit directly under the headline figures\n    fields: [\n      { name: 'customerID', alias: 'Customer', type: 'select', required: true, loadAction: { url: 'customers/list/x' }, detailsConfig: this.dataService.customerDetailsConfig },\n      { name: 'status', type: 'select', hideOnCreate: true, readonly: true, serverOwned: true, loadAction: { url: 'invoices/list/statuses' } }, // Changed (CFW-1): Invoice.Status carries [ServerOwned] — a create body carrying status:2 stored an invoice born PAID with no items and no payments\n      { name: 'totalDisplay', type: 'text', alias: 'Total', format: 'text', readonly: true, hideOnCreate: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'outstandingAmount', type: 'text', alias: 'Outstanding', readonly: true, hideOnCreate: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n\n      { name: 'invoiceInfo', type: 'section', alias: 'Invoice Details', collapseOnView: true },\n      { name: 'invoiceDate', type: 'date', max: 'today', required: true, section: 'invoiceInfo' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'invoiceNumber', type: 'text', alias: 'Invoice #', section: 'invoiceInfo' }, // Changed: Made editable on create for optional manual numbering\n      { name: 'paymentTerms', type: 'select', alias: 'Payment Terms', required: true, defaultValue : 30, loadAction: { url: 'invoices/list/payment-terms' }, section: 'invoiceInfo' },\n      { name: 'dueDate', type: 'date', alias: 'Due Date', readonly: true, hideOnCreate: true, section: 'invoiceInfo' },\n\n      { name: 'amounts', type: 'section', alias: 'Amount Breakdown', hideOnCreate: true, collapseOnView: true },\n      { name: 'subTotal', type: 'money', alias: 'Sub Total', readonly: true, hideOnCreate: true, section: 'amounts' }, // Changed: Show SubTotal (before tax)\n      { name: 'taxTotal', type: 'money', alias: 'VAT', readonly: true, hideOnCreate: true, section: 'amounts' }, // Changed: Show TaxTotal (VAT amount)\n      { name: 'paidAmount', type: 'text', alias: 'Paid', readonly: true, hideOnCreate: true, section: 'amounts' } // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n    ],\n    loadAction: { url: 'invoices/id' },\n    heroField: 'invoiceID',\n  }\n\n  // Invoice items form configuration\n  invoiceItemsFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] }, // Added: gate invoice item form by invoices cap (parent entity)\n    title: 'Invoice Item',\n    fields: [\n      { name: 'itemType', type: 'select', required: true, alias: 'Item Type', loadAction: { url: 'invoiceitems/list/item-types' }, defaultValue: 0 }, // Added: Item type selector\n      { name: 'productID', type: 'select', alias: 'Product', loadAction: { url: 'products/list/invoice-items' }, detailsConfig: this.inventoryService.productDetailsConfig, // Changed: dropdown quick-add\n        hidden: x => x.itemType !== 1, // Added: Product selector - visible only when itemType = Product (1)\n        onSelectChange: (selectedId: number, formData: any, option?: any) => { // Changed: Auto-populate description and unitPrice when product is selected\n          if (option) {\n            formData.description = option.description || option.name;\n            formData.unitPrice = option.unitPrice;\n          }\n        }\n      },\n      { name: 'serviceItemID', type: 'select', alias: 'Service', loadAction: { url: 'serviceitems/list/active' }, detailsConfig: this.inventoryService.serviceItemDetailsConfig, // Changed: dropdown quick-add\n        hidden: x => x.itemType !== 2, // Added: Service selector - visible only when itemType = Service (2)\n        onSelectChange: (selectedId: number, formData: any, option?: any) => { // Changed: Auto-populate description and unitPrice when service is selected\n          if (option) {\n            formData.description = option.description || option.name;\n            formData.unitPrice = option.unitPrice;\n          }\n        }\n      },\n      { name: 'description', type: 'text', required: true, alias: 'Description', span: true }, // Changed: Description field (backend will populate for Product/Service)\n      { name: 'quantity', type: 'number', required: true, defaultValue : 1 },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price', required: true }, // Changed: Unit price field (backend will populate for Product/Service)\n\n      // Changed: sectioned — what is being billed stays up top; the VAT treatment and the PO reference are set\n      // once and rarely re-read, so they fold away on an existing line\n      { name: 'lineOptions', type: 'section', alias: 'Tax & Reference', collapseOnView: true },\n      { name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, loadAction: { url: 'products/list/tax-rates' }, hidden: x => x.itemType !== 0, infoMessage: 'VAT rate for this line — Product/Service lines use their own tax setting', section: 'lineOptions' }, // Changed: manual (General) lines can now carry VAT\n      { name: 'isTaxInclusive', type: 'checkbox', alias: 'Price includes Tax', hidden: x => x.itemType !== 0, infoMessage: 'If checked, the unit price already includes tax', section: 'lineOptions' }, // Changed: tax-inclusive flag for manual lines\n      { name: 'poNumber', type: 'text', alias: 'PO Number', section: 'lineOptions' }, // Added: PO Number for invoice bundling\n    ],\n    loadAction: { url: 'invoiceitems/id' }, // Fixed: removed placeholder - TinCore appends ID automatically\n    heroField: 'invoiceItemID',\n  }\n\n  invoiceItemEditButton: Button = { name: 'edit', dialog: true, action: { url: 'invoiceitems?action=edit', method: 'post' }, disabled: x => x.status != InvoiceStatus.Draft }\n\n  // Invoice item details dialog config\n  invoiceItemDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.invoiceItemsFormConfig,\n    heroField: 'invoiceItemID',\n    buttons: [\n      this.invoiceItemEditButton\n    ]\n  }\n\n  // Added: Move item form configuration - select destination invoice\n  invoiceMoveItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] }, // Added: gate move-item form by invoices cap (parent entity)\n    title: 'Move Item',\n    fixedTitle: true,\n    fields: [\n      { name: 'invoiceItemID', type: 'number', hidden: true },\n      { name: 'description', type: 'text', alias: 'Item', readonly: true, span: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'invoiceID', type: 'select', alias: 'Move to Invoice', required: true, span: true, loadAction: { url: 'invoiceitems/list/draft-invoices' } }\n    ],\n    loadAction: { url: 'invoiceitems/id' }, // Fixed: removed placeholder - TinCore appends ID automatically\n    heroField: 'invoiceItemID'\n  }\n\n  // Added: Move item details dialog config\n  invoiceMoveItemDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.invoiceMoveItemFormConfig,\n    heroField: 'invoiceItemID',\n    mode: 'edit',\n    buttons: [\n      { name: 'move', display: 'Move Item', icon: { name: 'swap_horiz', color: 'blue' }, inDialog: true, action: { url: 'invoiceitems?action=move', method: 'post', successMessage: 'Item moved successfully' } }\n    ]\n  }\n\n  // Invoice items table for manual line item entry\n  invoiceItemsTableConfig: TableConfig = {\n    tabTitle: 'Invoice Items',\n    showFilter: false,\n    minColumns: ['description', 'quantity', 'amount'],\n    causeFormRefresh: true,\n    columns: [\n      { name: 'invoiceItemID', type: 'number', alias: 'ID', hidden: () => true },\n      { name: 'description', type: 'chip', alias: 'Description', detailsConfig: this.invoiceItemDetailsConfig },\n      { name: 'poNumber', type: 'text', alias: 'PO#' }, // Added: Purchase Order Number column\n      { name: 'quantity', type: 'number', alias: 'Qty' },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'taxAmount', type: 'money', alias: 'Tax' }, // Changed: Show per-item tax amount\n      { name: 'lineTotal', type: 'money', alias: 'Total' } // Changed: Computed line total (amount + tax)\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'invoiceitems?action=create', method: 'post' }, disabled: x => x.status != InvoiceStatus.Draft },\n      this.invoiceItemEditButton,\n      { name: 'move', display: 'Move', dialog: true, icon: { name: 'swap_horiz' }, detailsConfig: this.invoiceMoveItemDetailsConfig, disabled: x => x.status != InvoiceStatus.Draft }, // Added: Move item button\n      { name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'invoiceitems?action=delete', method: 'post', successMessage: 'Deleted' }, confirm: { message: 'Delete this item?' }, disabled: x => x.status != InvoiceStatus.Draft },\n    ],\n    loadAction: { url: 'invoiceitems/x/x' }, loadCriteria: 'invoice', loadIDField: 'invoiceID',\n    formConfig: this.invoiceItemsFormConfig // Changed: Reference extracted form config\n  }\n\n  // Invoice action buttons\n\n  // Changed: the hand-rolled cap53 gate is now declared, not written. Every custom action is floored at Edit on\n  // the controller's own capability (BaseController.CustomActionAccess), and InvoicesController raises\n  // return/discard/write-off/provision to Full (InvoicesController.cs:540-546). capAccountingInvoices IS cap53,\n  // which is BOTH InvoicesController.CapabilityName and InvoicePaymentsController's — so these read the same\n  // column the server reads. `visible` is back to being about the ROW; the capability is about the ROLE.\n  // Changed: `record-payment` opens a create dialog posting to invoicepayments?action=create, and BaseController\n  // demands RoleAccess.Create for \"create\" (BaseController.cs:751) — NOT the Edit floor. It was wholly ungated:\n  // a cap53 Edit holder was offered it and refused by the server.\n  invoiceRecordPaymentButton: Button = { name: 'record-payment', display: 'Record Payment', dialog: true, icon: { name: 'payment', color: 'blue' }, capability: this.dataService.capAccountingInvoices, requiredAccess: RoleAccess.Create,\n    detailsConfig : this.invoicePaymentsCreateDetailsDialogConfig,\n    visible: x => (x.status == InvoiceStatus.Submitted || x.status == InvoiceStatus.Paying) && x.outstandingAmount > 0 // Changed: Allow on both Submitted and Paying\n  } // Changed: Use detailsConfig to open payment form dialog\n\n  invoiceDiscardButton: Button = { name: 'discard', inDialog: true, display: 'Discard', icon: { name: 'close', color: 'red' }, capability: this.dataService.capAccountingInvoices, requiredAccess: RoleAccess.Full,\n    action: { url: 'invoices?action=discard', method: 'post', successMessage: 'Discarded' },\n    confirm: { message: 'Invoice will be marked as cancelled?' },\n    visible: x => x.status == InvoiceStatus.Draft // Changed: `discard` is one of the four actions InvoicesController raises to Full — now declared above\n  }\n\n  // Changed: Return button — reverts submitted invoice back to draft, reverses accounting transactions\n  invoiceReturnButton: Button = { name: 'return', inDialog: true, display: 'Return', icon: { name: 'undo', color: 'orange' }, capability: this.dataService.capAccountingInvoices, requiredAccess: RoleAccess.Full,\n    action: { url: 'invoices?action=return', method: 'post', successMessage: 'Returned to Draft' },\n    confirm: { message: 'Return invoice to draft? This will reverse the receivable and VAT transactions.' },\n    visible: x => x.status == InvoiceStatus.Submitted // Changed: `return` requires Full at the server — now declared above\n  }\n\n  // Changed: Write-off button — expenses outstanding balance as bad debt and closes the invoice (terminal WrittenOff status)\n  invoiceWriteOffButton: Button = { name: 'write-off', inDialog: true, display: 'Write Off', icon: { name: 'money_off', color: 'red' }, capability: this.dataService.capAccountingInvoices, requiredAccess: RoleAccess.Full,\n    action: { url: 'invoices?action=write-off', method: 'post' },\n    confirm: { message: 'Outstanding balance will be expensed as bad debt and the invoice closed. This posts a GL journal.' },\n    visible: x => (x.status == InvoiceStatus.Submitted || x.status == InvoiceStatus.Paying) // Changed: `write-off` requires Full at the server — now declared above\n  }\n\n  invoiceSubmitButton: Button = { name: 'submit', inDialog: true, display: 'Submit', icon: { name: 'send', }, capability: this.dataService.capAccountingInvoices, requiredAccess: RoleAccess.Edit,\n    action: { url: 'invoices?action=submit', method: 'post', successMessage: 'Submitted' },\n    confirm: { message: 'Submit invoice? This will record revenue and create an accounts receivable entry.' },\n    visible: x => x.status == InvoiceStatus.Draft, // Changed: `submit` keeps the Edit floor — the comment on InvoicesController.CustomActionAccess says so explicitly\n    disabled: x => x.totalAmount == 0\n  }\n\n  invoiceEditButton: Button = { name: 'edit', display: 'Save', dialog: true, action: { url: 'invoices?action=edit', method: 'post', },\n    confirm: { message: 'Proceed ?' },\n    visible: x => x.status == InvoiceStatus.Draft // Changed: Draft only\n  }\n\n  invoiceDownloadButton: Button = { name: 'pdf', display: 'Download PDF', inDialog: true, icon: { name: 'picture_as_pdf', color: 'red' } }\n\n  // Invoice details dialog with items, payments history, and action buttons\n  invoiceDetailsDialogConfig: DetailsDialogConfig = {\n    formConfig: this.invoiceFormConfig,\n    tableConfigs: [this.invoiceItemsTableConfig, this.invoicePaymentsTableConfig],\n    heroField: 'invoiceID',\n    buttons: [\n      this.invoiceSubmitButton,\n      this.invoiceRecordPaymentButton,\n      this.invoiceReturnButton, // Changed: Return submitted invoice to draft\n      this.invoiceWriteOffButton, // Changed: Write off outstanding balance as bad debt\n      this.invoiceDiscardButton,\n      this.invoiceEditButton,\n      this.invoiceDownloadButton // Changed: Restored PDF download button in details dialog\n    ]\n  }\n\n  invoiceViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.invoiceDetailsDialogConfig }\n\n  // Invoice summary tiles\n  invoicesTileConfig: TileConfig = {\n    clickable: true,\n    tiles: [\n      { name: 'drafts', alias: 'Draft Invoices', color: '#FFC107', icon: 'edit_note', info: 'Invoices in draft stage', action: { url: 'invoices/drafts/x' } }, // Changed: Added icon\n      { name: 'submitted', alias: 'Pending Payment', color: '#2196F3', icon: 'send', info: 'Submitted invoices awaiting payment', action: { url: 'invoices/submitted/x' } }, // Changed: Added icon\n      { name: 'pendingPayments', alias: 'Outstanding', color: '#F44336', icon: 'payments', info: 'Total amount pending payment' } // Changed: Added icon\n    ],\n    loadAction: { url: 'invoices/summary/x' }\n  }\n\n  // Main invoices table configuration\n  invoicesTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['invoiceNumber', 'customerName', 'statusName'],\n    minButtons: ['view', 'pdf'],\n    flatButtons: true,\n    collapseButtons: true,\n    greyOut: x => x.status == InvoiceStatus.Paid || x.status == InvoiceStatus.Discarded || x.status == InvoiceStatus.WrittenOff, // Changed: Grey out terminal statuses incl. WrittenOff\n    columns: [\n      { name: 'invoiceNumber', type: 'button', alias: 'Invoice #', detailsConfig : this.invoiceDetailsDialogConfig},\n      { name: 'poNumbers', type: 'text', alias: 'PO #' }, // Changed: Added PO numbers as second column\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'invoiceDate', type: 'date' },\n      { name: 'dueDate', type: 'date', alias: 'Due Date' },\n      { name: 'daysOverdue', type: 'number', alias: 'Days Overdue',},\n      { name: 'statusName', type: 'chip', alias: 'Status', detailsConfig : this.invoiceDetailsDialogConfig,\n        colors: [\n          { name: '#FFCC80', condition: x => x.status == InvoiceStatus.Draft }, \n          { name: '#90CAF9', condition: x => x.status == InvoiceStatus.Submitted }, \n          { name: '#FFD54F', condition: x => x.status == InvoiceStatus.Paying }, // Changed: Added Paying status color (amber/yellow)\n          { name: '#A5D6A7', condition: x => x.status == InvoiceStatus.Paid },\n          { name: '#EF9A9A', condition: x => x.status == InvoiceStatus.Discarded },\n          { name: '#9E9E9E', condition: x => x.status == InvoiceStatus.WrittenOff } // Changed: Grey chip for written-off invoices\n        ]\n      },\n      { name: 'itemCount', type: 'number', alias: 'Items', icon: { name: 'info', color: '#1976D2', condition: x => x.itemCount > 0, tipField: 'itemDescriptions' } }, // Changed: Info icon with item descriptions tooltip\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'paidAmount', type: 'money', alias: 'Paid' },\n      { name: 'outstandingAmount', type: 'money', alias: 'Outstanding' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, onSuccessButton : this.invoiceViewButton,\n        action: { url: 'invoices?action=create', method: 'post' } \n      },\n      // { name: 'view', dialog: true, detailsConfig: this.invoiceDetailsDialogConfig },\n      this.invoiceSubmitButton,\n      this.invoiceRecordPaymentButton,\n      this.invoiceReturnButton, // Changed: Return submitted invoice to draft\n      this.invoiceWriteOffButton, // Changed: Write off outstanding balance as bad debt\n      // this.invoicePayButton,\n      this.invoiceDiscardButton,\n      // this.invoiceEditButton,\n      this.invoiceDownloadButton, // Changed: Restored PDF button — minButtons references 'pdf' and InvoicesComponent handles the actionClick\n    ],\n    loadAction: { url: 'invoices/all/x' },\n    formConfig: this.invoiceFormConfig,\n    tileConfig: this.invoicesTileConfig,\n    pagination: { pageSize: 15 }, // Added: server-side pagination — invoices are the widest, highest-volume grid in the suite (customer join + line totals + payments)\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — invoices are raised on site; create/edit queue to the outbox and drain on reconnect (delete stays off — voiding is a server-side reversal)\n    entityName: 'Invoice',\n  }\n\n  //--------------------------Aging Report-------------------------\n\n  // Added: Aging report summary tiles\n  agingTileConfig: TileConfig = {\n    // clickable: true,\n    tiles: [\n      { name: 'current', alias: 'Current', color: '#4CAF50', icon: 'check_circle', info: 'Not yet due' }, // Changed: Added icon\n      { name: 'days30', alias: '1-30 Days', color: '#FFC107', icon: 'schedule', info: '1-30 days overdue' }, // Changed: Added icon\n      { name: 'days60', alias: '31-60 Days', color: '#FF9800', icon: 'warning', info: '31-60 days overdue' }, // Changed: Added icon\n      { name: 'days90', alias: '61-90 Days', color: '#F44336', icon: 'error', info: '61-90 days overdue' }, // Changed: Added icon\n      { name: 'days90Plus', alias: '90+ Days', color: '#B71C1C', icon: 'dangerous', info: 'Over 90 days overdue' }, // Changed: Added icon\n      { name: 'total', alias: 'Total Outstanding', color: '#9E9E9E', icon: 'account_balance_wallet', info: 'Total outstanding amount' } // Changed: Added icon\n    ],\n    // loadAction: { url: 'invoices/aging-summary/x' }\n  }\n\n  // Added: Base aging table configuration with common properties\n  agingBaseTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['invoiceNumber', 'customerName', 'outstandingAmount'],\n    columns: [\n      { name: 'invoiceNumber', type: 'text', alias: 'Invoice #', detailsConfig : this.invoiceDetailsDialogConfig},\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'invoiceDate', type: 'date', alias: 'Invoice Date' },\n      { name: 'dueDate', type: 'date', alias: 'Due Date' },\n      { name: 'daysOverdue', type: 'number', alias: 'Days Overdue' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'paidAmount', type: 'money', alias: 'Paid' },\n      { name: 'outstandingAmount', type: 'money', alias: 'Outstanding' }\n    ],\n    buttons: [\n      { name: 'view', dialog: true, detailsConfig: this.invoiceDetailsDialogConfig },\n      this.invoiceRecordPaymentButton,\n    ]\n  }\n\n  //--------------------------Customer Invoices-------------------------\n\n  // Customer invoice form without customerID field\n  customerInvoiceFormConfig: FormConfig = {\n    ...this.invoiceFormConfig,\n    fields: this.invoiceFormConfig.fields.filter(x => ['customerID'].includes(x.name) == false),\n    loadAction: { url: 'invoices/customer-id' }\n  }\n\n  // Customer invoice items table (read-only view)\n  customerInvoiceItemsTableConfig: TableConfig = {\n    ...this.invoiceItemsTableConfig,\n    loadCriteria: 'customer-invoice',\n    buttons: []\n  }\n\n  // Added: Customer invoice payments table (read-only)\n  customerInvoicePaymentsTableConfig: TableConfig = {\n    ...this.invoicePaymentsTableConfig,\n    loadCriteria: 'customer-invoice'\n  }\n\n  // Customer invoice details dialog (read-only)\n  customerInvoiceDetailsDialogConfig: DetailsDialogConfig = {\n    formConfig: this.customerInvoiceFormConfig,\n    tableConfigs: [this.customerInvoiceItemsTableConfig, this.customerInvoicePaymentsTableConfig],\n    heroField: 'invoiceID',\n    buttons: []\n  }\n\n  // Customer invoices table configuration\n  // (WS-1) the spread inherits invoicesTableConfig's pagination AND offline, and the loadAction below is a second url on the same 'invoices' entity. Both urls now register: OfflineService.register() no longer early-returns on the second table claiming an entity, it adds that table's read urls to the existing entry. The entity's offline SETTINGS still come from whichever registered first — identical here, since this config spreads them.\n  customerInvoicesTableConfig: TableConfig = {\n    ...this.invoicesTableConfig,\n    minColumns: ['invoiceNumber', 'totalDisplay'],\n    minButtons: ['view', 'pdf'],\n    columns: [...this.invoicesTableConfig.columns.filter(x => ['invoiceNumber', 'invoiceDate', 'dueDate', 'statusName', 'itemCount', 'totalAmount', 'paidAmount', 'outstandingAmount'].includes(x.name))],\n    buttons: [{ name: 'view', dialog: true, detailsConfig: this.customerInvoiceDetailsDialogConfig }, this.invoiceDownloadButton],\n    loadAction: { url: 'invoices/customer-all/x' }\n  }\n\n  //--------------------------Statement-------------------------\n\n  // Changed: Statement form configuration (replaces Outstanding Invoices)\n  statementFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingOutstandingInvoices] },\n    title: 'Statement',\n    fields: []\n  }\n\n  // Changed: Statement table configuration — default view with smart date filtering\n  statementTableConfig: TableConfig = {\n    holdHeaderButtonSpace: true,\n    showFilter: true,\n    minColumns: ['invoiceNumber', 'customerName', 'statusName'],\n    flatButtons: true,\n    columns: [\n      { name: 'invoiceNumber', type: 'button', alias: 'Invoice #', detailsConfig: this.invoiceDetailsDialogConfig }, // Changed: Clickable to open invoice dialog\n      { name: 'poNumbers', type: 'text', alias: 'PO #' }, // Changed: Moved to second column\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'invoiceDate', type: 'date', alias: 'Date' },\n      { name: 'itemDescriptions', type: 'text', alias: 'Description', maxLength: 100 }, // Changed: Enforce max display length of 100 characters\n      { name: 'totalAmount', type: 'money', alias: 'Amount' },\n      { name: 'statusName', type: 'chip', alias: 'Status', detailsConfig: this.invoiceDetailsDialogConfig, // Changed: Clickable to open invoice dialog\n        colors: [\n          { name: '#90CAF9', condition: x => x.status == InvoiceStatus.Submitted },\n          { name: '#FFD54F', condition: x => x.status == InvoiceStatus.Paying },\n          { name: '#A5D6A7', condition: x => x.status == InvoiceStatus.Paid },\n          { name: '#9E9E9E', condition: x => x.status == InvoiceStatus.WrittenOff } // Changed: Grey chip for written-off invoices on statement\n        ]\n      },\n    ],\n    buttons: [],\n    loadAction: { url: 'invoices/statement/x' },\n    formConfig: this.statementFormConfig\n  }\n\n  // Changed: Statement search table configuration — search mode with filters\n  statementSearchTableConfig: TableConfig = {\n    ...this.statementTableConfig,\n    searchConfig: {\n      fields: [\n        { name: 'customerID', type: 'select', alias: 'Customer', show: true, loadAction: { url: 'customers/list/x' } },\n        { name: 'dateFrom', type: 'date', alias: 'From Date', show: true },\n        { name: 'dateTo', type: 'date', alias: 'To Date', show: true },\n        { name: 'status', type: 'select', alias: 'Status', show: true,\n          options: [\n            { name: 'All', value: '' },\n            { name: 'Submitted', value: InvoiceStatus.Submitted },\n            { name: 'Paying', value: InvoiceStatus.Paying },\n            { name: 'Paid', value: InvoiceStatus.Paid }\n          ]\n        }\n      ],\n      searchAction: { url: 'invoices/search?action=statement-search', method: 'post' }\n    }\n  }\n\n  //--------------------------Open-item statement (customer / supplier)-------------------------\n  // Added: the open-item statement was hand-written markup on the page (its own flex row of totals and its own\n  // <table>). These configs move it onto spa-tiles + spa-table so it looks and behaves like every other page.\n  // The figures the API returns are unrounded sums, hence format: 'money' on every tile.\n\n  // Added: headline figures for the customer open-item statement\n  customerStatementTileConfig: TileConfig = {\n    tiles: [\n      { name: 'totalInvoiced', alias: 'Total Invoiced', icon: 'receipt_long', color: '#2196f3', format: 'money', info: 'Everything invoiced in the period' },\n      { name: 'totalPaid', alias: 'Total Paid', icon: 'payments', color: '#4CAF50', format: 'money', info: 'Receipts allocated against those invoices' },\n      { name: 'totalCredited', alias: 'Total Credited', icon: 'undo', color: '#FF9800', format: 'money', info: 'Credit notes raised in the period' },\n      { name: 'totalOutstanding', alias: 'Total Outstanding', icon: 'account_balance_wallet', format: 'money', color: x => (x?.totalOutstanding > 0 ? '#F44336' : '#4CAF50'), info: 'What the customer still owes' } // red while owing, green once settled — the colour the old hand-written card carried\n    ]\n  }\n\n  // Added: headline figures for the supplier open-item statement (no credit notes on the purchase side)\n  supplierStatementTileConfig: TileConfig = {\n    tiles: [\n      { name: 'totalPurchased', alias: 'Total Purchased', icon: 'shopping_cart', color: '#2196f3', format: 'money', info: 'Everything purchased on credit in the period' },\n      { name: 'totalPaid', alias: 'Total Paid', icon: 'payments', color: '#4CAF50', format: 'money', info: 'Payments made against those purchases' },\n      { name: 'totalOutstanding', alias: 'Total Outstanding', icon: 'account_balance_wallet', format: 'money', color: x => (x?.totalOutstanding > 0 ? '#F44336' : '#4CAF50'), info: 'What is still owed to the supplier' }\n    ]\n  }\n\n  // Added: the statement lines themselves. Customer and supplier lines have the SAME shape, so one config serves\n  // both — the page clones it per tab so the two grids never share mutable state.\n  statementLinesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    noDataMessage: 'No open items for the selected period',\n    minColumns: ['date', 'reference', 'outstanding'],\n    columns: [\n      { name: 'date', type: 'date', alias: 'Date' },\n      { name: 'reference', type: 'text', alias: 'Reference' },\n      { name: 'type', type: 'text', alias: 'Type' },\n      { name: 'total', type: 'money', alias: 'Total' },\n      { name: 'paid', type: 'money', alias: 'Paid' },\n      { name: 'outstanding', type: 'money', alias: 'Outstanding' },\n      { name: 'status', type: 'chip', alias: 'Status', // Changed: a chip, NOT type 'select' — a select column renders an editable dropdown, and a statement is read-only\n        colors: [\n          { name: '#A5D6A7', condition: x => x.status == 'Paid' },\n          { name: '#FFD54F', condition: x => x.status == 'Paying' },\n          { name: '#90CAF9', condition: x => x.status == 'Submitted' },\n          { name: '#CE93D8', condition: x => x.status == 'Applied' },\n          { name: '#9E9E9E', condition: x => x.status == 'Written Off' }\n        ]\n      },\n      { name: 'agingBucket', type: 'text', alias: 'Aging' }\n    ],\n    buttons: []\n  }\n\n  //--------------------------Tax Rates-------------------------\n\n  // Changed: Tax Rate form configuration for VAT management\n  taxRateFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTaxRates] }, // Added: gate tax rate form by tax rates cap\n    title: 'Tax Rate',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, alias: 'Name' },\n      { name: 'rate', type: 'number', required: true, alias: 'Rate (%)' },\n      { name: 'kind', type: 'select', alias: 'Kind', defaultValue: 0, // Added: Phase 2 compliance — VAT kind classification\n        options: [\n          { name: 'Standard', value: 0 },\n          { name: 'Zero Rated', value: 1 },\n          { name: 'Exempt', value: 2 }\n        ], optionDisplay: 'name', optionValue: 'value'\n      },\n      { name: 'isDefault', type: 'checkbox', alias: 'Default Rate' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true }\n    ],\n    loadAction: { url: 'taxrates/id' },\n    heroField: 'taxRateID'\n  }\n\n  taxRateCreateButton: Button = { name: 'create', display: 'Create Tax Rate', dialog: true, action: { url: 'taxrates?action=create', method: 'post' } }\n  taxRateEditButton: Button = { name: 'edit', dialog: true, action: { url: 'taxrates?action=edit', method: 'post' } }\n  taxRateDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'taxrates?action=delete', method: 'post' } }\n\n  taxRateDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.taxRateFormConfig,\n    heroField: 'taxRateID',\n    buttons: [this.taxRateCreateButton, this.taxRateEditButton, this.taxRateDeleteButton]\n  }\n\n  taxRatesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'rate', 'isActive'],\n    columns: [\n      { name: 'name', type: 'text', alias: 'Name' },\n      { name: 'rate', type: 'number', alias: 'Rate (%)' },\n      { name: 'kindName', type: 'text', alias: 'Kind' }, // Added: Phase 2 compliance — VAT kind (Standard/Zero Rated/Exempt)\n      { name: 'isDefault', type: 'checkbox', alias: 'Default' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' }\n    ],\n    buttons: [\n      this.taxRateCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.taxRateDetailsConfig },\n      this.taxRateEditButton,\n      this.taxRateDeleteButton\n    ],\n    loadAction: { url: 'taxrates/all/x' },\n    formConfig: this.taxRateFormConfig,\n    realTime: true,\n    entityName: 'TaxRate'\n  }\n\n  //--------------------------Currencies-------------------------\n\n  // Changed: Currency form configuration for multi-currency management\n  currencyFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capCurrencies] }, // Added: gate currency form by currencies cap\n    title: 'Currency',\n    includeAudit: true,\n    fields: [\n      { name: 'code', type: 'text', required: true, alias: 'Code' },\n      { name: 'name', type: 'text', required: true, alias: 'Name' },\n      { name: 'symbol', type: 'text', required: true, alias: 'Symbol' },\n      { name: 'exchangeRate', type: 'number', required: true, alias: 'Exchange Rate' },\n      { name: 'isBase', type: 'checkbox', alias: 'Base Currency',\n        readonlyCondition: (x: any) => x.isBase // Changed: Prevent unchecking base currency\n      }\n    ],\n    loadAction: { url: 'currencies/id' },\n    heroField: 'currencyID'\n  }\n\n  currencyCreateButton: Button = { name: 'create', display: 'Create Currency', dialog: true, action: { url: 'currencies?action=create', method: 'post' } }\n  currencyEditButton: Button = { name: 'edit', dialog: true, action: { url: 'currencies?action=edit', method: 'post' } }\n  currencyDeleteButton: Button = { name: 'delete', dialog: true, action: { url: 'currencies?action=delete', method: 'post' } }\n\n  currencyDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.currencyFormConfig,\n    heroField: 'currencyID',\n    buttons: [this.currencyCreateButton, this.currencyEditButton, this.currencyDeleteButton]\n  }\n\n  currenciesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['code', 'name', 'exchangeRate'],\n    columns: [\n      { name: 'code', type: 'text', alias: 'Code' },\n      { name: 'name', type: 'text', alias: 'Currency' },\n      { name: 'symbol', type: 'text', alias: 'Symbol' },\n      { name: 'exchangeRate', type: 'number', alias: 'Rate' },\n      { name: 'isBase', type: 'checkbox', alias: 'Base' }\n    ],\n    buttons: [\n      this.currencyCreateButton,\n      { name: 'revalue', display: 'Run Revaluation', inHeader: true, icon: { name: 'currency_exchange' }, action: { url: 'currencies/revalue/x' }, confirm: { message: 'Revalue all foreign currency accounts at current rates? Unrealized gains/losses will be posted to the ledger.' } }, // Changed: C6 forex revaluation run\n      { name: 'view', dialog: true, detailsConfig: this.currencyDetailsConfig },\n      this.currencyEditButton,\n      this.currencyDeleteButton\n    ],\n    loadAction: { url: 'currencies/all/x' },\n    formConfig: this.currencyFormConfig,\n    realTime: true,\n    entityName: 'Currency'\n  }\n\n  //--------------------------Transaction Types-------------------------\n\n  transactionTypeFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTransactionTypes] },\n    title: 'Financial Transaction Type',\n    fields: [\n      { name: 'name', type: 'text', required: true, span: true },\n      { name: 'debitAccountType', type: 'select', alias: 'Debit Account Type', required: true, \n        loadAction: { url: 'accounts/list/accountTypes' } \n      },\n      { name: 'creditAccountType', type: 'select', alias: 'Credit Account Type', required: true, \n        loadAction: { url: 'accounts/list/accountTypes' } \n      },\n      { name: 'defaultDebitAccountID', type: 'select', alias: 'Default Debit Account', nullable: true, masterField: 'debitAccountType', masterOptionValue: 'type', \n        loadAction: { url: 'accounts/list/x' }, \n        detailsConfig: this.accountBaseDetailsConfig \n      },\n      { name: 'defaultCreditAccountID', type: 'select', alias: 'Default Credit Account', nullable: true, masterField: 'creditAccountType', masterOptionValue: 'type', \n        loadAction: { url: 'accounts/list/x' }, \n        detailsConfig: this.accountBaseDetailsConfig \n      },\n    ],\n    loadAction: { url: 'transactiontypes/id' },\n    heroField: 'transactionTypeID',\n  }\n\n  transactionTypeCreateButton: Button = { name: 'create', display: 'Create', dialog: true, action: { url: 'transactiontypes?action=create', method: 'post' } }\n  transactionTypeEditButton: Button = { name: 'edit', dialog: true, action: { url: 'transactiontypes?action=edit', method: 'post' } }\n\n  transactionTypeDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.transactionTypeFormConfig,\n    heroField: 'transactionTypeID',\n    buttons: [\n      this.transactionTypeCreateButton, this.transactionTypeEditButton\n    ]\n  }\n\n  transactionTypesTableConfig: TableConfig = {\n\n    showFilter: true,\n    minColumns: ['name', 'debitAccountName', 'creditAccountName'],\n    flatButtons: true,\n    columns: [\n      { name: 'transactionTypeID', type: 'text', alias: 'ID' },\n      { name: 'name', type: 'text' },\n      { name: 'debitAccountTypeName', type: 'text', alias: 'Debit Type' },\n      { name: 'creditAccountTypeName', type: 'text', alias: 'Credit Type' },\n      { name: 'defaultDebitAccountName', type: 'text', alias: 'Default Debit Account' },\n      { name: 'defaultCreditAccountName', type: 'text', alias: 'Default Credit Account' }\n    ],\n    buttons: [\n      this.transactionTypeCreateButton,\n      { name: 'seed', display: 'Seed Financial Data', inHeader: true, icon: { name : 'add_circle' }, action: { url: 'transactiontypes/seed/x' }, confirm: { message: 'Seed generic financial accounts and transaction types?' } }, // Changed: Use GET endpoint via criteria\n      { name: 'view', dialog: true },\n      this.transactionTypeEditButton,\n      { name: 'delete', dialog: true, action: { url: 'transactiontypes?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'transactiontypes/all/x' },\n    formConfig: this.transactionTypeFormConfig,\n    entityName: 'TransactionType'\n  }\n\n  //--------------------------Transactions-------------------------\n\n  transactionFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTransactions] },\n    title: 'Financial Transaction',\n    fixedTitle : true,\n    fields: [\n      { name: 'transactionTypeID', type: 'text-single', alias: 'Transaction Type', required: true, detailsConfig: this.transactionTypeDetailsConfig, \n        loadAction: { url: 'transactionTypes/list/x' },\n      },\n      { name: 'date', type: 'date', max: 'today', required: true }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n\n      { name: 'debitAccountID', type: 'select', alias: 'Debit Account', required: true,\n        masterField: 'transactionTypeID', masterValueField: 'debitAccountType', masterDefaultValueField: 'defaultDebitAccountID', masterOptionValue: 'type', \n        loadAction: { url: 'accounts/list/x' }, \n        detailsConfig: this.accountBaseDetailsConfig \n      },\n      { name: 'creditAccountID', type: 'select', alias: 'Credit Account', required: true,\n        masterField: 'transactionTypeID', masterValueField: 'creditAccountType', masterDefaultValueField: 'defaultCreditAccountID', masterOptionValue: 'type', \n        loadAction: { url: 'accounts/list/x' }, \n        detailsConfig: this.accountBaseDetailsConfig \n      },\n      \n      { name: 'description', type: 'text', required: true, span: true },\n      { name: 'amount', type: 'money', required: true, span: true },\n      // Changed: Removed currencyID and foreignAmount fields — backend auto-detects currency from accounts\n    ],\n\n  }\n\n\n  transactionEditButton: Button = { name: 'edit', dialog: true, \n    action: { url: 'transactions/dto?action=edit', method: 'post' },\n    visible: x => x.canEdit && !x.isReversal\n  }\n\n\n  transactionVoidButton: Button = { name: 'void', display: 'Void', icon : { name: 'undo', color: 'red' },\n    confirm: { message: 'Are you sure you want to void this transaction? This cannot be undone.' },\n    action: { url: 'transactions?action=void', method: 'post' },\n    visible: x => x.canVoid\n  }\n\n  transactionDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.transactionFormConfig,\n    heroField: 'transactionID',\n    buttons: [\n      this.transactionEditButton,\n    ]\n  }\n\n\n  // Added (journal-dialog-conform): the multi-line journal, rebuilt from library pieces. It replaces a hand-rolled\n  // MatDialog (JournalEntryDialogComponent) that drew its own header fields, its own Account/Debit/Credit grid and its\n  // own footer, so it inherited none of the house dialog styling. Nothing here is bespoke: it is the standard details\n  // dialog (form + nested tab) plus the one-step-create path, exactly as customerDetailsConfig captures contacts.\n  //\n  // WHY IT EXISTS AT ALL, since Create Transaction posts to the SAME endpoint and the SAME DTO: transactionFormConfig\n  // above has exactly ONE debitAccountID and ONE creditAccountID, so it can only produce a two-line pair. A journal is\n  // the N-line general case. TransactionDto.Entries is an optional extra on the same DTO — when it carries >= 2 balanced\n  // lines the engine posts all of them as one transaction and ignores Amount/DebitAccountID/CreditAccountID.\n  journalLineFormConfig: FormConfig = {\n    title: 'Journal Line',\n    fixedTitle: true, // the header renders \"{titleAction} {title}\" and titleAction is the create button's display, so without this the dialog read \"Add Line Journal Line\"\n    fields: [\n      { name: 'accountID', type: 'select', alias: 'Account', required: true, loadAction: { url: 'accounts/list/x' }, detailsConfig: this.accountBaseDetailsConfig },\n      { name: 'isDebit', type: 'select', alias: 'Dr / Cr', required: true, options: [{ name: 'Debit', value: true }, { name: 'Credit', value: false }] },\n      { name: 'amount', type: 'money', required: true },\n    ]\n  }\n\n  // The field names are TransactionEntryDto's own (accountID / isDebit / amount) because local rows are POSTed to the\n  // server verbatim as the parent's `entries` array — a friendlier debit/credit column pair would not deserialize.\n  journalLinesTableConfig: TableConfig = {\n    tabTitle: 'Journal Lines',\n    showFilter: false,\n    minColumns: ['accountID', 'isDebit', 'amount'],\n    columns: [\n      { name: 'accountID', type: 'number', alias: 'Account' },\n      { name: 'isDebit', type: 'select', alias: 'Dr / Cr', options: [{ name: 'Debit', value: true }, { name: 'Credit', value: false }], optionDisplay: 'name', optionValue: 'value' },\n      { name: 'amount', type: 'money' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Line', dialog: true },\n      { name: 'edit', icon: { name: 'edit' } },\n      { name: 'delete', icon: { name: 'delete', color: 'red' }, confirm: { message: 'Remove this journal line?' } },\n    ],\n    inlineEdit: { fields: ['accountID', 'isDebit', 'amount'] }, // edit a line in place; every editable field has a column, which is what canEditInline() requires\n    createConfig: { navigationProperty: 'entries' }, // one-step capture — lines live on the parent model and POST with it as TransactionDto.Entries\n    formConfig: this.journalLineFormConfig,\n    entityName: 'Journal Line'\n  }\n\n  journalFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTransactions] },\n    title: 'Journal Entry',\n    fixedTitle: true,\n    fields: [\n      { name: 'transactionTypeID', type: 'text-single', alias: 'Journal Type', required: true, loadAction: { url: 'transactionTypes/list/x' }, detailsConfig: this.transactionTypeDetailsConfig },\n      { name: 'date', type: 'date', max: 'today', required: true, defaultValue: 'now' }, // same bound as a transaction — a journal records what has already happened\n      { name: 'description', type: 'text', required: true, span: true },\n    ]\n  }\n\n  // Named 'create' because the local-rows path pushes only on that name, and because it is the dialog's submit action\n  journalPostButton: Button = { name: 'create', display: 'Post Journal', action: { url: 'transactions/dto?action=create', method: 'post' } }\n\n  journalDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.journalFormConfig,\n    mode: 'create', // load-bearing: this is what puts the dialog (and therefore its nested lines tab) on the one-step create path, since the opening button cannot be named 'create' — transactionsTableConfig already has one and tables resolve that button by name\n    tableConfigs: [this.journalLinesTableConfig],\n    buttons: [this.journalPostButton]\n  }\n\n  // inHeader puts it in line with Create Transaction in the table header — never floating on the app shell\n  journalCreateButton: Button = { name: 'journal', display: 'New Journal', icon: { name: 'library_books' }, inHeader: true, dialog: true, detailsConfig: this.journalDetailsConfig, capability: this.dataService.capTransactions, requiredAccess: RoleAccess.Create }\n\n  transactionsTableConfig: TableConfig = {\n    showFilter: true,\n    greyOut: x => x.isReversal || x.status == 1,\n    minColumns: ['date', 'description', 'amountDisplay'],\n    flatButtons: true,\n    columns: [\n      { name: 'date', type: 'date' },\n      { name: 'description', type: 'text',\n        colors: [\n          { name: 'purple', condition: x => x.isReversal },\n          { name: 'red', condition: x => x.status == 1 },\n        ],\n      },\n\n      { name: 'typeName', type: 'text', alias: 'Type' },\n      { name: 'debitAccountName', type: 'text', alias: 'Debit Account' },\n      { name: 'creditAccountName', type: 'text', alias: 'Credit Account' },\n      { name: 'amountDisplay', type: 'text', alias: 'Amount', // Changed: Single formatted column replacing CCY, Amount, Foreign Amount\n        color: { name: 'red', condition: x => x.reducesBalance && !x.isAggregate },\n      },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create Transaction', dialog: true, action: { url: 'transactions/dto?action=create', method: 'post' } },\n      this.journalCreateButton, // Added (journal-dialog-conform): sits in the table header beside Create Transaction — was a floating button on the app shell\n      { name: 'view', dialog: true, detailsConfig: this.transactionDetailsConfig },\n      this.transactionEditButton,\n      this.transactionVoidButton,\n    ],\n    loadAction: { url: 'transactions/all/x' },\n    formConfig: this.transactionFormConfig,\n    import: { entity: 'transactions', title: 'Import Transactions', securityConfig: { allow: [this.dataService.capTransactions] } }, // Changed (4b): the generic import wizard replaces the bespoke transaction-import dialog/controller/service\n    realTime: true,\n    entityName: 'Transaction',\n    pagination: { pageSize: 15 }, // Added: tier A — the heaviest grid in accounting, and unbounded. Safe now that TransactionsController overrides GetAllPaged; before that, paging would have bypassed FormatAmountDisplay and shipped unformatted amounts\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: transactions are captured in the field (expenses on the road), so creates/edits queue and sync on reconnect\n    allowUserKeepOpen: true, // Added: shows Keep Open checkbox on transaction dialogs\n    keepOpenBehavior: 'reset', // Added: reset form after create so user can capture next transaction\n  }\n\n\n  // Changed: Search mode config for transactions — date range, description contains, account filter\n  transactionSearchTableConfig: TableConfig = {\n    ...this.transactionsTableConfig,\n    searchConfig: {\n      fields: [\n        { name: 'dateFrom', type: 'date', alias: 'From Date', show: true },\n        { name: 'dateTo', type: 'date', alias: 'To Date', show: true },\n        { name: 'description', type: 'text', alias: 'Description', show: true },\n        { name: 'accountID', type: 'select', alias: 'Account', show: true, loadAction: { url: 'accounts/list/x' } },\n        { name: 'typeName', type: 'text-single', alias: 'Transaction Type', show: true, loadAction: { url: 'transactiontypes/list/x' } }, // Changed: text-single for type-to-search autocomplete\n      ],\n      searchAction: { url: 'transactions/search', method: 'post' }\n    }\n  }\n\n  // (WS-1) this spread inherits transactionsTableConfig's pagination AND offline, and the url below is rewritten per account. That used to leave it outside the offline read registry; it no longer does — OfflineService.registerReads() registers the prefix 'transactions/account/' off loadCriteria, so EVERY account's tab matches, each cached under its own url. No change needed here.\n  accountTransactionsTableConfig: TableConfig = {\n    ...this.transactionsTableConfig,\n    causeFormRefresh: true,\n    minColumns: ['date', 'description', 'amountDisplay', 'runningBalance'], // Changed: Use amountDisplay instead of amount\n    tabTitle: 'Account Transactions',\n    loadAction: { url: 'transactions/account/x' }, loadCriteria: 'account', loadIDField: 'accountID',\n    columns: [\n      ...this.transactionsTableConfig.columns!,\n      { name: 'runningBalance', type: 'money', alias: 'Balance' }\n    ],\n  };\n\n  //--------------------------Transaction Templates-------------------------\n\n  // Template form configuration (accountID hidden - auto-populated from context)\n  transactionTemplateFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTransactions] },\n    title: 'Transaction Template',\n    includeAudit: true,\n    // Changed: sectioned — the template's identity stays visible, the values it pre-fills group under one\n    // heading (the 'blank' spacer is no longer needed, the section header breaks the row)\n    fields: [\n      { name: 'name', type: 'text', required: true, span: true },\n      { name: 'accountID', type: 'number', hidden: true }, // Auto-populated from Account Details context\n      { name: 'transactionTypeID', type: 'select', alias: 'Transaction Type', required: true, detailsConfig: this.transactionTypeDetailsConfig, loadAction: { url: 'transactionTypes/list/x' } },\n\n      { name: 'defaults', type: 'section', alias: 'Default Values', collapseOnView: true },\n      { name: 'debitAccountID', type: 'select', alias: 'Default Debit Account', nullable: true, masterField: 'transactionTypeID', masterValueField: 'debitAccountType', masterDefaultValueField: 'defaultDebitAccountID', masterOptionValue: 'type', loadAction: { url: 'accounts/list/x' }, detailsConfig: this.accountBaseDetailsConfig, section: 'defaults' },\n      { name: 'creditAccountID', type: 'select', alias: 'Default Credit Account', nullable: true, masterField: 'transactionTypeID', masterValueField: 'creditAccountType', masterDefaultValueField: 'defaultCreditAccountID', masterOptionValue: 'type', loadAction: { url: 'accounts/list/x' }, detailsConfig: this.accountBaseDetailsConfig, section: 'defaults' },\n      { name: 'description', type: 'text', alias: 'Default Description', span: true, section: 'defaults' },\n      { name: 'defaultAmount', type: 'money', alias: 'Default Amount', span: true, section: 'defaults' },\n    ],\n    loadAction: { url: 'transactiontemplates/id' },\n    heroField: 'transactionTemplateID',\n  }\n\n  // Process form configuration (convert template to transaction)\n  transactionTemplateProcessFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTransactions] }, // Added: gate transaction template process form by transactions cap\n    title: 'Create Transaction from Template',\n    fixedTitle: true,\n    fields: [\n      { name: 'transactionTemplateID', type: 'number', hidden: true },\n      { name: 'name', type: 'text', alias: 'Template', readonly: true, span : true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'transactionTypeID', type: 'select', alias: 'Transaction Type', required: true, detailsConfig: this.transactionTypeDetailsConfig, loadAction: { url: 'transactionTypes/list/x' } },\n      { name: 'date', type: 'date', max: 'today', required: true, defaultValue: 'now' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'debitAccountID', type: 'select', alias: 'Debit Account', required: true, masterField: 'transactionTypeID', masterValueField: 'debitAccountType', masterOptionValue: 'type', loadAction: { url: 'accounts/list/x' }, detailsConfig: this.accountBaseDetailsConfig },\n      { name: 'creditAccountID', type: 'select', alias: 'Credit Account', required: true, masterField: 'transactionTypeID', masterValueField: 'creditAccountType', masterOptionValue: 'type', loadAction: { url: 'accounts/list/x' }, detailsConfig: this.accountBaseDetailsConfig },\n      { name: 'description', type: 'text', required: true, span: true },\n      { name: 'amount', type: 'money', required: true, span: true },\n    ],\n  }\n\n  // Template action buttons\n  transactionTemplateCreateButton: Button = { name: 'create', display: 'Create Template', dialog: true, action: { url: 'transactiontemplates?action=create', method: 'post' } }\n  transactionTemplateEditButton: Button = { name: 'edit', dialog: true, action: { url: 'transactiontemplates?action=edit', method: 'post' } }\n\n  // Template details config (for view/edit)\n  transactionTemplateDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.transactionTemplateFormConfig,\n    heroField: 'transactionTemplateID',\n    buttons: [this.transactionTemplateCreateButton, this.transactionTemplateEditButton]\n  }\n\n  // Process details config (for processing template)\n  transactionTemplateProcessDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.transactionTemplateProcessFormConfig,\n    heroField: 'transactionTemplateID',\n    mode : 'edit',\n    buttons: [\n      { name: 'process', display: 'Create Transaction', icon: { name: 'play_arrow', color: 'green' }, inDialog: true,\n        action: { url: 'transactiontemplates/dto?action=process', method: 'post', \n        successMessage: 'Transaction created from template' } \n      }\n    ]\n  }\n\n  // Templates table configuration (3rd tab in Account Details)\n  transactionTemplatesTableConfig: TableConfig = {\n    tabTitle: 'Transaction Templates',\n    showFilter: true,\n    minColumns: ['name', 'transactionTypeName', 'defaultAmountDisplay'],\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'button', detailsConfig: this.transactionTemplateProcessDetailsConfig },\n      { name: 'transactionTypeName', type: 'text', alias: 'Type' },\n      { name: 'debitAccountName', type: 'text', alias: 'Debit Account' },\n      { name: 'creditAccountName', type: 'text', alias: 'Credit Account' },\n      { name: 'defaultAmountDisplay', type: 'text', alias: 'Default Amount' },\n    ],\n    buttons: [\n      this.transactionTemplateCreateButton,\n      { name: 'process', display: 'Create Transaction', icon: { name: 'play_arrow', color: 'green' }, dialog: true, detailsConfig: this.transactionTemplateProcessDetailsConfig },\n      { name: 'view', dialog: true, detailsConfig: this.transactionTemplateDetailsConfig },\n      { name: 'edit', dialog: true, action: { url: 'transactiontemplates?action=edit', method: 'post' }, detailsConfig: this.transactionTemplateDetailsConfig }, // Changed: Inline edit button with both action and detailsConfig\n      { name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'transactiontemplates?action=delete', method: 'post', successMessage: 'Template deleted' }, confirm: { message: 'Delete this template?' } },\n    ],\n    loadAction: { url: 'transactiontemplates/account/x' }, loadCriteria: 'account', loadIDField: 'accountID',\n    formConfig: this.transactionTemplateFormConfig\n  }\n\n  //--------------------------Standing Orders-------------------------\n\n  // Standing order form configuration — schedule recurring transactions linked to templates\n  standingOrderFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capStandingOrders] }, // Changed: Use cap64 (standing orders) to match backend StandingOrdersController gate\n    title: 'Standing Order',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, span: true, alias: 'Name' },\n      { name: 'transactionTemplateID', type: 'select', required: true, alias: 'Transaction Template', loadAction: { url: 'transactiontemplates/list/x' }, detailsConfig: this.transactionTemplateDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'frequency', type: 'select', required: true, alias: 'Frequency',\n        options: [\n          { name: 'Daily', value: 1 },\n          { name: 'Weekly', value: 2 },\n          { name: 'Monthly', value: 3 }\n        ]\n      },\n      { name: 'dayOfMonth', type: 'number', alias: 'Day of Month (1-28)', min: 1, max: 28, nullable: true,\n        hidden: (x: any) => x.frequency !== 3 },\n      { name: 'dayOfWeek', type: 'select', alias: 'Day of Week', nullable: true,\n        hidden: (x: any) => x.frequency !== 2,\n        options: [\n          { name: 'Sunday', value: 0 }, { name: 'Monday', value: 1 },\n          { name: 'Tuesday', value: 2 }, { name: 'Wednesday', value: 3 },\n          { name: 'Thursday', value: 4 }, { name: 'Friday', value: 5 },\n          { name: 'Saturday', value: 6 }\n        ]\n      },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true },\n\n      // Changed: sectioned — what runs and how often stays up top; the window it runs in and the amount\n      // override are set once, so they fold away and leave the execution-history tab in view\n      { name: 'schedule', type: 'section', alias: 'Schedule & Amount', collapseOnView: true },\n      { name: 'startDate', type: 'date', required: true, alias: 'Start Date', section: 'schedule' },\n      { name: 'endDate', type: 'date', alias: 'End Date', nullable: true, section: 'schedule' },\n      { name: 'amount', type: 'money', alias: 'Amount (leave blank to use template default)', nullable: true, span: true, section: 'schedule' }\n    ],\n    loadAction: { url: 'standingorders/id' },\n    heroField: 'standingOrderID'\n  }\n\n  // Execution history child table — shows all execution attempts for a standing order\n  standingOrderExecutionsTableConfig: TableConfig = {\n    tabTitle: 'Execution History',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    minColumns: ['executionDate', 'success', 'message'],\n    columns: [\n      { name: 'executionDate', type: 'date', alias: 'Date' },\n      { name: 'executedAt', type: 'datetime', alias: 'Executed At' },\n      { name: 'success', type: 'checkbox', alias: 'Success' },\n      { name: 'isManual', type: 'checkbox', alias: 'Manual' },\n      { name: 'message', type: 'text', alias: 'Result' },\n      { name: 'transactionID', type: 'number', alias: 'Transaction ID' }\n    ],\n    buttons: [],\n    loadAction: { url: 'standingorderexecutions/order/x' }, loadCriteria: 'order', loadIDField: 'standingOrderID'\n  }\n\n  // Standing order action buttons\n  standingOrderCreateButton: Button = { name: 'create', display: 'Create Standing Order', dialog: true, action: { url: 'standingorders?action=create', method: 'post' } }\n  standingOrderEditButton: Button = { name: 'edit', dialog: true, action: { url: 'standingorders?action=edit', method: 'post' } }\n  standingOrderDeleteButton: Button = { name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'standingorders?action=delete', method: 'post', successMessage: 'Standing order deleted' }, confirm: { message: 'Delete this standing order?' } }\n  standingOrderExecuteButton: Button = { name: 'execute', display: 'Run Now', icon: { name: 'play_arrow', color: 'green' }, inDialog: true, action: { url: 'standingorders?action=execute', method: 'post', successMessage: 'Standing order executed' }, confirm: { message: 'Manually trigger this standing order now?' }, visible: (x: any) => x.isActive }\n  standingOrderPauseButton: Button = { name: 'toggle', display: 'Pause', inDialog: true, icon: { name: 'pause', color: 'orange' }, action: { url: 'standingorders?action=toggle', method: 'post', successMessage: 'Standing order paused' }, visible: (x: any) => x.isActive }\n  standingOrderResumeButton: Button = { name: 'toggle', display: 'Resume', inDialog: true, icon: { name: 'play_arrow', color: 'green' }, action: { url: 'standingorders?action=toggle', method: 'post', successMessage: 'Standing order activated' }, visible: (x: any) => !x.isActive }\n\n  // Details config for standing order — includes execution history child table\n  standingOrderDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.standingOrderFormConfig,\n    heroField: 'standingOrderID',\n    tableConfigs: [this.standingOrderExecutionsTableConfig],\n    buttons: [this.standingOrderCreateButton, this.standingOrderEditButton, this.standingOrderExecuteButton, this.standingOrderDeleteButton]\n  }\n\n  // Standing orders management table — main page\n  standingOrdersTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'templateName', 'scheduleDisplay'],\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'button', detailsConfig: this.standingOrderDetailsConfig },\n      { name: 'templateName', type: 'text', alias: 'Template' },\n      { name: 'scheduleDisplay', type: 'text', alias: 'Schedule' },\n      { name: 'amountDisplay', type: 'text', alias: 'Amount' },\n      { name: 'startDate', type: 'date', alias: 'Start Date' },\n      { name: 'endDate', type: 'date', alias: 'End Date' },\n      { name: 'lastRunDisplay', type: 'text', alias: 'Last Run' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' }\n    ],\n    buttons: [\n      this.standingOrderCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.standingOrderDetailsConfig },\n      this.standingOrderEditButton,\n      this.standingOrderPauseButton,\n      this.standingOrderResumeButton,\n      this.standingOrderExecuteButton,\n      this.standingOrderDeleteButton\n    ],\n    loadAction: { url: 'standingorders/all/x' },\n    formConfig: this.standingOrderFormConfig,\n    entityName: 'StandingOrder'\n  }\n\n  //--------------------------Accounts-------------------------\n\n  accountDetailsConfig : DetailsDialogConfig = {\n    ...this.accountBaseDetailsConfig,\n    tableConfigs: [\n      { ...this.accountTransactionsTableConfig },\n      {\n        ...this.transactionTypesTableConfig,\n        tabTitle: 'Transaction Types',\n        buttons: [],\n        loadAction: { url: 'transactionTypes/account/x' }, loadCriteria: 'account', loadIDField: 'accountID'\n      },\n      { ...this.transactionTemplatesTableConfig }, // Changed: Added 3rd tab for transaction templates\n    ]\n  };\n\n\n  // Added (WS-1 sweep): deliberately NOT paginated and NOT offline. Account IS ISync, but the chart of accounts is a bounded setup screen an accountant maintains at a desk — nobody opens it in the field, and its balance columns are live server aggregates that a cache would misreport.\n  accountsTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [5 ,10, 25, 50],\n    minColumns: ['name', 'typeName', 'balanceDisplay'],\n    flatButtons: true,\n    columns: [\n      { name: 'code', type: 'text', alias: 'Code' }, // Changed: COA code column (B1)\n      { name: 'name', type: 'button', detailsConfig: this.accountDetailsConfig },\n      { name: 'typeName', type: 'text', alias: 'Type',\n        icons: [\n          { name: 'payments', color: '#4CAF50', condition: (x: any) => x.includeInCashTotal, tip: 'Included in Cash Total' },\n          { name: 'account_balance', color: '#2196F3', condition: (x: any) => x.includeInBankTotal, tip: 'Included in Bank Total' },\n        ]\n      },\n      { name: 'balanceDisplay', type: 'text', alias: 'Balance' }, // Changed: Pre-formatted with currency prefix (e.g. \"USD 1,964.21\")\n    ],\n    buttons: [\n      this.accountCreateButton,\n      { name: 'view', dialog: true, detailsConfig: this.accountDetailsConfig },\n      this.finAccounEditButton,\n      { name: 'delete', dialog: true, action: { url: 'accounts?action=delete', method: 'post' } },\n      // { name: 'revalue', display: 'Revalue Forex', inHeader: true, icon: { name: 'currency_exchange', color: 'blue' }, // Changed: Commented out — forex revaluation deferred\n      //   action: { url: 'accounts?action=revalue', method: 'post', successMessage: 'Forex revaluation complete' },\n      //   confirm: { message: 'Revalue all forex accounts at current exchange rates?' }\n      // },\n    ],\n    loadAction: { url: 'accounts/all/x' },\n    formConfig: this.accountFormConfig,\n    realTime: true,\n    entityName: 'Account'\n  }\n\n  //--------------------------Financial Reports-------------------------\n\n  // Trial Balance table config — shows all accounts with debit/credit totals\n  trialBalanceTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [25, 50, 100],\n    minColumns: ['accountName', 'totalDebits', 'totalCredits'],\n    flatButtons: true,\n    columns: [\n      { name: 'accountCode', type: 'text', alias: 'Code' }, // Changed: COA code column (B1)\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'accountType', type: 'text', alias: 'Type' },\n      { name: 'totalDebits', type: 'money', alias: 'Debits' },\n      { name: 'totalCredits', type: 'money', alias: 'Credits' },\n      { name: 'closingBalance', type: 'money', alias: 'Balance',\n        colors: [\n          { name: 'green', condition: (x: any) => x.closingBalance > 0 },\n          { name: 'red', condition: (x: any) => x.closingBalance < 0 }\n        ]\n      }\n    ],\n    loadAction: { url: 'accounts/reports/trialbalance' }\n  }\n\n  // Profit & Loss table config — shows revenue and expense accounts with section\n  pnlTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [25, 50, 100],\n    minColumns: ['accountName', 'section', 'amount'],\n    flatButtons: true,\n    columns: [\n      { name: 'accountCode', type: 'text', alias: 'Code' }, // Changed: COA code column (B1)\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'section', type: 'text', alias: 'Section' },\n      { name: 'amount', type: 'money', alias: 'Amount',\n        colors: [\n          { name: 'green', condition: (x: any) => x.amount > 0 },\n          { name: 'red', condition: (x: any) => x.amount < 0 }\n        ]\n      }\n    ],\n    loadAction: { url: 'accounts/reports/pnl' }\n  }\n\n  // Balance Sheet report table config — shows asset, liability, equity accounts with section\n  balanceSheetReportTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [25, 50, 100],\n    minColumns: ['accountName', 'section', 'balance'],\n    flatButtons: true,\n    columns: [\n      { name: 'accountCode', type: 'text', alias: 'Code' }, // Changed: COA code column (B1)\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'section', type: 'text', alias: 'Section' },\n      { name: 'balance', type: 'money', alias: 'Balance',\n        colors: [\n          { name: 'green', condition: (x: any) => x.balance > 0 },\n          { name: 'red', condition: (x: any) => x.balance < 0 }\n        ]\n      }\n    ],\n    loadAction: { url: 'accounts/reports/balancesheet' }\n  }\n\n  //--------------------------Aggregates-------------------------\n\n  // Monthly aggregates table showing Assets, Liabilities, Income, Expenses, Profit, and Equity by month\n  aggregatesTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [12, 24, 36],\n    minColumns: ['month', 'assets', 'liabilities', 'income'],\n    flatButtons: true,\n    columns: [\n      { name: 'month', type: 'text', alias: 'Month' },\n      { name: 'assets', type: 'money', alias: 'Assets' },\n      { name: 'liabilities', type: 'money', alias: 'Liabilities' },\n      { name: 'income', type: 'money', alias: 'Income' },\n      { name: 'expenses', type: 'money', alias: 'Expenses' },\n      { name: 'profit', type: 'money', alias: 'Profit', colors: [{ name: 'green', condition: x => x.profit > 0 }, { name: 'red', condition: x => x.profit < 0 }] },\n      { name: 'equity', type: 'money', alias: 'Equity' }\n    ],\n    loadAction: { url: 'accounts/aggregates/monthly' }\n  }\n\n  // Cumulative aggregates table showing running totals over time\n  cumulativeAggregatesTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [12, 24, 36],\n    minColumns: ['month', 'totalAssets', 'totalLiabilities', 'netAssets'],\n    flatButtons: true,\n    columns: [\n      { name: 'month', type: 'text', alias: 'Month' },\n      { name: 'totalAssets', type: 'money', alias: 'Total Assets' },\n      { name: 'totalLiabilities', type: 'money', alias: 'Total Liabilities' },\n      { name: 'netAssets', type: 'money', alias: 'Net Assets' },\n      { name: 'totalEquity', type: 'money', alias: 'Total Equity' },\n      { name: 'incomeYTD', type: 'money', alias: 'Income YTD' },\n      { name: 'expensesYTD', type: 'money', alias: 'Expenses YTD' },\n      { name: 'profitYTD', type: 'money', alias: 'Profit YTD', colors: [{ name: 'green', condition: x => x.profitYTD > 0 }, { name: 'red', condition: x => x.profitYTD < 0 }] }\n    ],\n    loadAction: { url: 'accounts/aggregates/cumulative' }\n  }\n\n  // Cash flow aggregates table showing inflows, outflows and running balance\n  cashFlowAggregatesTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [12, 24, 36],\n    minColumns: ['month', 'cashInflows', 'cashOutflows', 'netCashFlow'],\n    flatButtons: true,\n    columns: [\n      { name: 'month', type: 'text', alias: 'Month' },\n      { name: 'cashInflows', type: 'money', alias: 'Cash Inflows' },\n      { name: 'cashOutflows', type: 'money', alias: 'Cash Outflows' },\n      { name: 'netCashFlow', type: 'money', alias: 'Net Cash Flow', colors: [{ name: 'green', condition: x => x.netCashFlow > 0 }, { name: 'red', condition: x => x.netCashFlow < 0 }] },\n      { name: 'runningBalance', type: 'money', alias: 'Running Balance', colors: [{ name: 'green', condition: x => x.runningBalance > 0 }, { name: 'red', condition: x => x.runningBalance < 0 }] }\n    ],\n    loadAction: { url: 'accounts/aggregates/cashflow' }\n  }\n\n  // Balance sheet aggregates table showing Assets, Liabilities, and Equity by month\n  balanceSheetAggregatesTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [12, 24, 36],\n    minColumns: ['month', 'totalAssets', 'totalLiabilities', 'totalEquity'],\n    flatButtons: true,\n    columns: [\n      { name: 'month', type: 'text', alias: 'Month' },\n      { name: 'totalAssets', type: 'money', alias: 'Total Assets' },\n      { name: 'totalLiabilities', type: 'money', alias: 'Total Liabilities' },\n      { name: 'totalEquity', type: 'money', alias: 'Total Equity' },\n      { name: 'netWorth', type: 'money', alias: 'Net Worth', colors: [{ name: 'green', condition: x => x.netWorth > 0 }, { name: 'red', condition: x => x.netWorth < 0 }] }\n    ],\n    loadAction: { url: 'accounts/aggregates/balancesheet' }\n  }\n\n  // Changed: Fixed Assets configs moved to AssetsService (assets.service.ts)\n\n  //--------------------------Budgets-------------------------\n\n  // Budget form configuration\n  budgetFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capBudgets] }, // Added: capability gate — Budgets (cap85)\n    title: 'Budget',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, alias: 'Budget Name' },\n      { name: 'fiscalYear', type: 'number', required: true, alias: 'Fiscal Year', defaultValue: new Date().getFullYear() },\n      { name: 'description', type: 'text', span: true },\n      { name: 'statusName', type: 'text', alias: 'Status', readonly: true, hideOnCreate: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'isActive', type: 'checkbox', alias: 'Active', readonly: true, hideOnCreate: true },\n      { name: 'totalBudgetedDisplay', type: 'text', alias: 'Total Budgeted', readonly: true, hideOnCreate: true } // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n    ],\n    loadAction: { url: 'budgets/id' },\n    heroField: 'budgetID'\n  }\n\n  // Budget line form configuration\n  budgetLineFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capBudgets] }, // Added: capability gate — Budgets (cap85, parent)\n    title: 'Budget Line',\n    fields: [\n      { name: 'budgetID', type: 'number', hidden: true },\n      { name: 'accountID', type: 'select', alias: 'Account', required: true, loadAction: { url: 'accounts/list/x' }, detailsConfig: this.accountBaseDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'departmentID', type: 'select', alias: 'Department', nullable: true, loadAction: { url: 'departments/list/x' } },\n      { name: 'period', type: 'date', required: true, alias: 'Period (1st of Month)' },\n      { name: 'budgetedAmount', type: 'money', required: true, alias: 'Budgeted Amount' }\n    ],\n    loadAction: { url: 'budgetlines/id' },\n    heroField: 'budgetLineID'\n  }\n\n  // Budget lines child table\n  budgetLinesTableConfig: TableConfig = {\n    tabTitle: 'Budget Lines',\n    showFilter: true,\n    minColumns: ['periodLabel', 'accountName', 'budgetedAmountDisplay'],\n    columns: [\n      { name: 'periodLabel', type: 'text', alias: 'Period' },\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'accountTypeName', type: 'text', alias: 'Type' },\n      { name: 'departmentName', type: 'text', alias: 'Department' },\n      { name: 'budgetedAmount', type: 'money', alias: 'Amount' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Line', dialog: true, action: { url: 'budgetlines?action=create', method: 'post' }, disabled: (x: any) => x.status == 2 },\n      { name: 'edit', dialog: true, action: { url: 'budgetlines?action=edit', method: 'post' }, disabled: (x: any) => x.budgetStatus == 2 },\n      { name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'budgetlines?action=delete', method: 'post', successMessage: 'Line deleted' }, confirm: { message: 'Delete this budget line?' }, disabled: (x: any) => x.budgetStatus == 2 }\n    ],\n    loadAction: { url: 'budgetlines/x/x' }, loadCriteria: 'budget', loadIDField: 'budgetID',\n    formConfig: this.budgetLineFormConfig\n  }\n\n  // Budget action buttons\n  budgetPublishButton: Button = { name: 'publish', display: 'Publish', inDialog: true, icon: { name: 'publish', color: 'green' }, action: { url: 'budgets?action=publish', method: 'post', successMessage: 'Budget published' }, confirm: { message: 'Publish this budget? Lines will be locked for editing.' }, visible: (x: any) => x.status == 1 }\n  budgetSetActiveButton: Button = { name: 'setactive', display: 'Set Active', inDialog: true, icon: { name: 'star', color: 'blue' }, action: { url: 'budgets?action=setactive', method: 'post', successMessage: 'Budget set as active' }, confirm: { message: 'Set this budget as the active budget for its fiscal year?' }, visible: (x: any) => x.status == 2 && !x.isActive }\n  budgetCopyButton: Button = { name: 'copy', display: 'Copy to Next Year', inDialog: true, icon: { name: 'content_copy', color: 'purple' }, action: { url: 'budgets?action=copy', method: 'post', successMessage: 'Budget copied' }, confirm: { message: 'Copy this budget to the next fiscal year?' } }\n  budgetEditButton: Button = { name: 'edit', dialog: true, action: { url: 'budgets?action=edit', method: 'post' }, visible: (x: any) => x.status == 1 }\n\n  // Budget details dialog with lines table and action buttons\n  budgetDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.budgetFormConfig,\n    tableConfigs: [this.budgetLinesTableConfig],\n    heroField: 'budgetID',\n    buttons: [\n      this.budgetPublishButton,\n      this.budgetSetActiveButton,\n      this.budgetCopyButton,\n      this.budgetEditButton\n    ]\n  }\n\n  // Main budgets table configuration\n  budgetsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'fiscalYear', 'statusName'],\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'button', detailsConfig: this.budgetDetailsConfig },\n      { name: 'fiscalYear', type: 'number', alias: 'Fiscal Year' },\n      { name: 'statusName', type: 'chip', alias: 'Status',\n        colors: [\n          { name: '#FFCC80', condition: (x: any) => x.status == 1 },\n          { name: '#A5D6A7', condition: (x: any) => x.status == 2 }\n        ]\n      },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' },\n      { name: 'lineCount', type: 'number', alias: 'Lines' },\n      { name: 'totalBudgetedDisplay', type: 'text', alias: 'Total Budgeted' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Create Budget', dialog: true, action: { url: 'budgets?action=create', method: 'post' } },\n      this.budgetPublishButton,\n      this.budgetSetActiveButton,\n      this.budgetCopyButton,\n      { name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'budgets?action=delete', method: 'post', successMessage: 'Budget deleted' }, confirm: { message: 'Delete this budget?' }, visible: (x: any) => x.status == 1 }\n    ],\n    loadAction: { url: 'budgets/all/x' },\n    formConfig: this.budgetFormConfig,\n    entityName: 'Budget'\n  }\n\n  //--------------------------Budget vs Actual Report-------------------------\n\n  // Budget vs Actual - By Period detail table\n  budgetVsActualByPeriodTableConfig: TableConfig = {\n    tabTitle: 'By Period',\n    showFilter: true,\n    pageSizes: [25, 50, 100],\n    minColumns: ['periodLabel', 'accountName', 'budgetedDisplay'],\n    flatButtons: true,\n    columns: [\n      { name: 'periodLabel', type: 'text', alias: 'Period' },\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'accountType', type: 'text', alias: 'Type' },\n      { name: 'departmentName', type: 'text', alias: 'Department' },\n      { name: 'budgetedDisplay', type: 'text', alias: 'Budgeted' },\n      { name: 'actualDisplay', type: 'text', alias: 'Actual' },\n      { name: 'varianceDisplay', type: 'text', alias: 'Variance',\n        colors: [\n          { name: 'green', condition: (x: any) => !x.isOverBudget },\n          { name: 'red', condition: (x: any) => x.isOverBudget }\n        ]\n      },\n      { name: 'variancePercent', type: 'number', alias: 'Variance %' }\n    ]\n  }\n\n  // Budget vs Actual - By Account summary table\n  budgetVsActualByAccountTableConfig: TableConfig = {\n    tabTitle: 'By Account',\n    showFilter: true,\n    pageSizes: [25, 50, 100],\n    minColumns: ['accountName', 'totalBudgetedDisplay', 'totalActualDisplay'],\n    flatButtons: true,\n    columns: [\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'accountType', type: 'text', alias: 'Type' },\n      { name: 'totalBudgetedDisplay', type: 'text', alias: 'Total Budgeted' },\n      { name: 'totalActualDisplay', type: 'text', alias: 'Total Actual' },\n      { name: 'varianceDisplay', type: 'text', alias: 'Variance',\n        colors: [\n          { name: 'green', condition: (x: any) => !x.isOverBudget },\n          { name: 'red', condition: (x: any) => x.isOverBudget }\n        ]\n      },\n      { name: 'variancePercent', type: 'number', alias: 'Variance %' }\n    ]\n  }\n\n  // Budget summary tiles for report page\n  budgetSummaryTileConfig: TileConfig = {\n    tiles: [\n      { name: 'totalBudgeted', alias: 'Total Budgeted', color: '#2196F3', icon: 'request_quote', info: 'Sum of all budget line amounts' }, // Changed: Added icon\n      { name: 'totalActual', alias: 'Total Actual', color: '#4CAF50', icon: 'receipt', info: 'Sum of actual amounts from ledger' }, // Changed: Added icon\n      { name: 'totalVariance', alias: 'Total Variance', color: '#FF9800', icon: 'compare_arrows', info: 'Difference between budgeted and actual' }, // Changed: Added icon\n      { name: 'overBudgetLines', alias: 'Over Budget', color: '#F44336', icon: 'warning', info: 'Number of lines over budget' } // Changed: Added icon\n    ]\n  }\n\n  //--------------------------General Ledger Report (B5)-------------------------\n\n  // General Ledger detail report — every posting line with per-account running balance\n  generalLedgerTableConfig: TableConfig = {\n    showFilter: true,\n    pageSizes: [25, 50, 100],\n    minColumns: ['date', 'accountName', 'debit'],\n    flatButtons: true,\n    columns: [\n      { name: 'date', type: 'date', alias: 'Date' },\n      { name: 'accountCode', type: 'text', alias: 'Code' },\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'transactionType', type: 'text', alias: 'Type' },\n      { name: 'description', type: 'text', alias: 'Description', maxLength: 80 },\n      { name: 'debit', type: 'money', alias: 'Debit' },\n      { name: 'credit', type: 'money', alias: 'Credit' },\n      { name: 'balance', type: 'money', alias: 'Balance' }\n    ],\n    loadAction: { url: 'reports/gl' }\n  }\n\n  //--------------------------Credit Notes (B6)-------------------------\n\n  // Credit note item form — lines editable while parent credit note is a draft\n  creditNoteItemsFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] },\n    title: 'Credit Note Item',\n    fields: [\n      { name: 'creditNoteID', type: 'number', hidden: true },\n      { name: 'description', type: 'text', required: true, alias: 'Description', span: true },\n      { name: 'quantity', type: 'number', required: true, defaultValue: 1 },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price', required: true },\n      { name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, loadAction: { url: 'products/list/tax-rates' }, detailsConfig: this.taxRateDetailsConfig, infoMessage: 'VAT rate reversed by this line' } // Changed: dropdown quick-add\n    ],\n    loadAction: { url: 'creditnoteitems/id' },\n    heroField: 'creditNoteItemID'\n  }\n\n  creditNoteItemEditButton: Button = { name: 'edit', dialog: true, action: { url: 'creditnoteitems?action=edit', method: 'post' }, disabled: x => x.status != CreditNoteStatus.Draft }\n\n  // Credit note items nested table\n  creditNoteItemsTableConfig: TableConfig = {\n    tabTitle: 'Credit Note Items',\n    showFilter: false,\n    causeFormRefresh: true,\n    minColumns: ['description', 'quantity', 'amount'],\n    columns: [\n      { name: 'description', type: 'text', alias: 'Description' },\n      { name: 'quantity', type: 'number', alias: 'Qty' },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'taxAmount', type: 'money', alias: 'Tax' },\n      { name: 'lineTotal', type: 'money', alias: 'Total' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'creditnoteitems?action=create', method: 'post' }, disabled: x => x.status != CreditNoteStatus.Draft },\n      this.creditNoteItemEditButton,\n      { name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'creditnoteitems?action=delete', method: 'post', successMessage: 'Deleted' }, confirm: { message: 'Delete this item?' }, disabled: x => x.status != CreditNoteStatus.Draft }\n    ],\n    loadAction: { url: 'creditnoteitems/x/x' }, loadCriteria: 'creditnote', loadIDField: 'creditNoteID',\n    formConfig: this.creditNoteItemsFormConfig\n  }\n\n  // Credit note header form\n  creditNoteFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] },\n    title: 'Credit Note',\n    includeAudit: true,\n    // Changed: sectioned — customer, status and total answer \"what is this credit\"; the paperwork and the\n    // sub-totals fold away so the items tab is reachable without scrolling\n    fields: [\n      { name: 'customerID', alias: 'Customer', type: 'select', required: true, loadAction: { url: 'customers/list/x' }, detailsConfig: this.dataService.customerDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'status', type: 'select', hideOnCreate: true, readonly: true, serverOwned: true, loadAction: { url: 'creditnotes/list/statuses' } }, // Changed (CFW-1): CreditNote.Status carries [ServerOwned]\n      { name: 'totalDisplay', type: 'text', alias: 'Total', readonly: true, hideOnCreate: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'reason', type: 'text', alias: 'Reason', span: true },\n      { name: 'invoiceID', type: 'select', alias: 'Invoice', nullable: true, loadAction: { url: 'invoiceitems/list/draft-invoices' }, hidden: true }, // Hidden generic select — invoice linkage set via create-from-invoice\n\n      { name: 'creditNoteInfo', type: 'section', alias: 'Credit Note Details', collapseOnView: true },\n      { name: 'creditNoteDate', type: 'date', max: 'today', required: true, alias: 'Date', section: 'creditNoteInfo' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'creditNoteNumber', type: 'text', alias: 'Credit Note #', readonly: true, hideOnCreate: true, section: 'creditNoteInfo' },\n      { name: 'invoiceNumber', type: 'text', alias: 'Invoice #', readonly: true, hideOnCreate: true, section: 'creditNoteInfo' }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n\n      { name: 'amounts', type: 'section', alias: 'Amount Breakdown', hideOnCreate: true, collapseOnView: true },\n      { name: 'subTotal', type: 'money', alias: 'Sub Total', readonly: true, hideOnCreate: true, section: 'amounts' },\n      { name: 'taxTotal', type: 'money', alias: 'VAT', readonly: true, hideOnCreate: true, section: 'amounts' }\n    ],\n    loadAction: { url: 'creditnotes/id' },\n    heroField: 'creditNoteID'\n  }\n\n  // Credit note action buttons\n  // Changed: issuing now also settles the linked invoice in the same step, so the message says so —\n  // it used to leave the ledger crediting AR while the invoice still showed the full balance.\n  creditNoteSubmitButton: Button = { name: 'submit', inDialog: true, display: 'Issue', icon: { name: 'send' },\n    action: { url: 'creditnotes?action=submit', method: 'post', successMessage: 'Credit note issued' },\n    confirm: { message: 'Issue this credit note? It reverses revenue and VAT in the ledger and credits the linked invoice.' },\n    visible: x => x.status == CreditNoteStatus.Draft,\n    disabled: x => x.totalAmount == 0\n  }\n\n  // Changed: only needed now for a credit raised against an invoice that had no balance left at the\n  // time (a return after payment) and is later netted off. The normal path applies on issue.\n  creditNoteApplyButton: Button = { name: 'apply', inDialog: true, display: 'Apply to Invoice', icon: { name: 'link', color: 'blue' },\n    action: { url: 'creditnotes?action=apply', method: 'post', successMessage: 'Credit applied to invoice' },\n    confirm: { message: 'Apply this credit against the linked invoice balance?' },\n    visible: x => x.status == CreditNoteStatus.Submitted && !!x.invoiceID\n  }\n\n  creditNoteReturnButton: Button = { name: 'return', inDialog: true, display: 'Return', icon: { name: 'undo', color: 'orange' },\n    action: { url: 'creditnotes?action=return', method: 'post', successMessage: 'Returned to Draft' },\n    confirm: { message: 'Return credit note to draft? Ledger reversals will be voided.' },\n    visible: x => x.status == CreditNoteStatus.Submitted\n  }\n\n  creditNoteDiscardButton: Button = { name: 'discard', inDialog: true, display: 'Discard', icon: { name: 'close', color: 'red' },\n    action: { url: 'creditnotes?action=discard', method: 'post', successMessage: 'Discarded' },\n    confirm: { message: 'Discard this credit note?' },\n    visible: x => x.status == CreditNoteStatus.Draft\n  }\n\n  creditNoteEditButton: Button = { name: 'edit', display: 'Save', dialog: true, action: { url: 'creditnotes?action=edit', method: 'post' }, visible: x => x.status == CreditNoteStatus.Draft }\n\n  // Credit note details dialog — two-step create pattern (header first, then items)\n  creditNoteDetailsDialogConfig: DetailsDialogConfig = {\n    formConfig: this.creditNoteFormConfig,\n    tableConfigs: [this.creditNoteItemsTableConfig],\n    heroField: 'creditNoteID',\n    buttons: [\n      this.creditNoteSubmitButton,\n      this.creditNoteApplyButton,\n      this.creditNoteReturnButton,\n      this.creditNoteDiscardButton,\n      this.creditNoteEditButton\n    ]\n  }\n\n  creditNoteViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.creditNoteDetailsDialogConfig }\n  creditNoteCreateButton: Button = { name: 'create', display: 'Create', dialog: true, onSuccessButton: this.creditNoteViewButton, action: { url: 'creditnotes?action=create', method: 'post' } }\n\n  // Raise a full credit note from an invoice (pre-populated lines)\n  invoiceCreditNoteButton: Button = { name: 'create-from-invoice', display: 'Credit Note', inDialog: true, icon: { name: 'assignment_return', color: 'purple' },\n    action: { url: 'creditnotes?action=create-from-invoice', method: 'post', successMessage: 'Draft credit note created' },\n    confirm: { message: 'Create a draft credit note for the full value of this invoice?' },\n    visible: x => x.status == InvoiceStatus.Submitted || x.status == InvoiceStatus.Paying || x.status == InvoiceStatus.Paid\n  }\n\n  // Main credit notes table\n  creditNotesTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['creditNoteNumber', 'customerName', 'statusName'],\n    flatButtons: true,\n    collapseButtons: true,\n    greyOut: x => x.status == CreditNoteStatus.Applied || x.status == CreditNoteStatus.Discarded,\n    columns: [\n      { name: 'creditNoteNumber', type: 'button', alias: 'Credit Note #', detailsConfig: this.creditNoteDetailsDialogConfig },\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'invoiceNumber', type: 'text', alias: 'Invoice #' },\n      { name: 'creditNoteDate', type: 'date', alias: 'Date' },\n      { name: 'reason', type: 'text', alias: 'Reason', maxLength: 60 },\n      { name: 'statusName', type: 'chip', alias: 'Status', detailsConfig: this.creditNoteDetailsDialogConfig,\n        colors: [\n          { name: '#FFCC80', condition: x => x.status == CreditNoteStatus.Draft },\n          { name: '#90CAF9', condition: x => x.status == CreditNoteStatus.Submitted },\n          { name: '#A5D6A7', condition: x => x.status == CreditNoteStatus.Applied },\n          { name: '#EF9A9A', condition: x => x.status == CreditNoteStatus.Discarded }\n        ]\n      },\n      { name: 'itemCount', type: 'number', alias: 'Items' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' }\n    ],\n    buttons: [\n      this.creditNoteCreateButton,\n      this.creditNoteSubmitButton,\n      this.creditNoteApplyButton,\n      this.creditNoteReturnButton,\n      this.creditNoteDiscardButton\n    ],\n    loadAction: { url: 'creditnotes/all/x' },\n    formConfig: this.creditNoteFormConfig,\n    pagination: { pageSize: 15 }, // Added: server-side pagination — credit notes carry the same customer join and money columns as invoices\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — a credit is raised where the goods come back (CreditNote : ISync says so explicitly); create/edit queue and drain on reconnect. Issue/apply/return/discard are workflow actions, not create/edit, so they stay online-only — the field act is capturing the Draft\n    entityName: 'CreditNote',\n  }\n\n  //--------------------------Customer Receipts (C3)-------------------------\n\n  // Changed: the allocate button now carries its OWN handler instead of being a no-op that ReceiptsComponent\n  // wired in its constructor. That wiring made the button work on exactly one page and left it DEAD for every\n  // other consumer — which is the sole reason shift's and grip's Day Book allocate lanes were router\n  // navigations rather than in-place actions (the last two row navigators in the estate).\n  // Changed: `tip` added — the button used to be labelled for a journey (\"...on the Receipts page\"); it now\n  // does the job where it is clicked, and the tip has to stop promising a page.\n  // Changed: the visible gate accepts EITHER field name. The receipts page projects `unallocatedAmount`\n  // (CustomerReceiptsController.SelectFields) but both Day Book providers project `unallocated`\n  // (ShiftDayBookProvider.DayBookReceipt / GripDayBookProvider's anonymous row), so the old gate would have\n  // hidden this button on every Day Book row — a live button that never appears. Widening only: nothing that\n  // was visible before is hidden now.\n  receiptAllocateButton: Button = { name: 'allocate', display: 'Allocate', icon: { name: 'call_split', color: 'blue' }, tip: 'Match this money to open invoices',\n    onClick: (row: any, reload?: () => void) => this.openReceiptAllocation(row, reload),\n    visible: x => this.receiptUnallocated(x) > 0.005\n  }\n\n  // Added: the one place that knows a receipt row's unallocated balance, whichever surface the row came from.\n  receiptUnallocated(row: any): number { return row?.unallocatedAmount ?? row?.unallocated ?? 0; }\n\n  // Added: opens the allocation dialog for a receipt row from ANY table — the receipts page, a Day Book\n  // section, or an untracked consumer. `reload` is the second argument table.component hands every\n  // Button.onClick (:1207); calling it refreshes a table that owns a loadAction AND emits actionSuccess, which\n  // is what reloads a Day Book section that has no loadAction of its own. That is why this needs no page ref.\n  // The row is normalised to the field name ReceiptDialogComponent reads, so a Day Book row allocates too.\n  openReceiptAllocation(row: any, reload?: () => void) {\n    const receipt = { ...row, unallocatedAmount: this.receiptUnallocated(row) };\n    this.dialog.open(ReceiptDialogComponent, { width: '860px', maxWidth: '95vw', data: receipt, panelClass: this.dataService?.dialogPanelClass ?? [] })\n      .afterClosed().subscribe(saved => { if (saved) reload?.(); });\n  }\n\n  // C8: PDF download — onClick is wired by ReceiptsComponent (blob download)\n  // Changed: the PDF button now carries its OWN handler instead of being a no-op that ReceiptsComponent wired\n  // in its constructor. That wiring made it work on exactly one page and left it DEAD for every other consumer\n  // — the identical defect fixed for receiptAllocateButton in 3a681d6, and the last of that pair.\n  // Changed: `tip` added — the button does its job wherever it is clicked, so nothing should promise a page.\n  // NOTE: unlike the allocate button there is NO `visible` gate here, so there was no field-name trap to widen;\n  // a PDF is printable for any receipt row regardless of its unallocated balance.\n  receiptPdfButton: Button = { name: 'pdf', display: 'Download PDF', icon: { name: 'picture_as_pdf', color: 'red' }, tip: 'Download this receipt as a PDF',\n    onClick: (row: any) => this.downloadReceiptPdf(row)\n  }\n\n  // Added: downloads a receipt PDF for a row from ANY table — the receipts page, a Day Book section, or an\n  // untracked consumer. No `reload` argument is used: a download changes no data, so there is nothing to refresh.\n  // The body is built EXPLICITLY rather than by spreading the row, so an arbitrary consumer's row shape cannot\n  // leak junk fields into the POST. CustomerReceiptsController.DownloadPdf binds [FromBody] CustomerReceipt and\n  // reads ONLY CustomerReceiptID, so the ID is the only field that actually matters.\n  // MEASURED, not assumed: a lean body and a Day-Book-shaped body missing receiptNumber/reference BOTH return\n  // 200 with byte-identical PDFs, so [ApiController]'s implicit-Required rule does NOT bite on this model —\n  // the defaults below are tidiness, not a fix for a live failure. Do not \"simplify\" them into a bare ID\n  // either: the model binds a CustomerReceipt, and keeping the shape honest costs nothing.\n  downloadReceiptPdf(row: any) {\n    const body = { customerReceiptID: row?.customerReceiptID ?? 0, receiptNumber: row?.receiptNumber ?? '', customerID: row?.customerID ?? 0, receiptDate: row?.receiptDate ?? null, amount: row?.amount ?? 0, reference: row?.reference ?? '' };\n    this.http.post(`${this.httpService.apiUrl}customerreceipts/pdf?action=x`, body, { responseType: 'blob' })\n      .subscribe((response: Blob) => {\n        const blob = new Blob([response], { type: 'application/pdf' });\n        const url = window.URL.createObjectURL(blob);\n        const link = document.createElement('a');\n        link.href = url;\n        link.download = `Receipt_${body.customerReceiptID}.pdf`;\n        link.click();\n        window.URL.revokeObjectURL(url);\n      });\n  }\n\n  customerReceiptsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['receiptNumber', 'customerName', 'amount'],\n    flatButtons: true,\n    columns: [\n      { name: 'receiptNumber', type: 'text', alias: 'Receipt #' },\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'receiptDate', type: 'date', alias: 'Date' },\n      { name: 'methodName', type: 'text', alias: 'Method' },\n      { name: 'reference', type: 'text', alias: 'Reference' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'allocatedAmount', type: 'money', alias: 'Allocated' },\n      { name: 'unallocatedAmount', type: 'money', alias: 'On Account' }\n    ],\n    buttons: [\n      this.receiptAllocateButton,\n      this.receiptPdfButton // C8: wired by ReceiptsComponent\n    ],\n    loadAction: { url: 'customerreceipts/all/x' },\n    pagination: { pageSize: 15 }, // Added: server-side pagination — receipts append continuously and each row carries allocation totals\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — receipts are captured wherever the customer pays; create/edit queue offline\n    entityName: 'CustomerReceipt',\n  }\n\n  //--------------------------Quotations (C10)-------------------------\n\n  quoteItemsFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] },\n    title: 'Quote Item',\n    fields: [\n      { name: 'quoteID', type: 'number', hidden: true },\n      { name: 'description', type: 'text', required: true, alias: 'Description', span: true },\n      { name: 'quantity', type: 'number', required: true, alias: 'Quantity', defaultValue: 1 },\n      { name: 'unitPrice', type: 'money', required: true, alias: 'Unit Price' },\n      { name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, loadAction: { url: 'taxrates/list/x' }, detailsConfig: this.taxRateDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'isTaxInclusive', type: 'checkbox', alias: 'Price Includes Tax' }\n    ],\n    loadAction: { url: 'quoteitems/id' },\n    heroField: 'quoteItemID'\n  }\n\n  quoteItemEditButton: Button = { name: 'edit', dialog: true, action: { url: 'quoteitems?action=edit', method: 'post' }, disabled: x => x.status != QuoteStatus.Draft }\n\n  quoteItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    minColumns: ['description', 'lineTotal'],\n    columns: [\n      { name: 'description', type: 'text', alias: 'Description' },\n      { name: 'quantity', type: 'number', alias: 'Qty' },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price' },\n      { name: 'amount', type: 'money', alias: 'Net' },\n      { name: 'taxAmount', type: 'money', alias: 'VAT' },\n      { name: 'lineTotal', type: 'money', alias: 'Total' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'quoteitems?action=create', method: 'post' } },\n      this.quoteItemEditButton,\n      { name: 'delete', dialog: true, action: { url: 'quoteitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'quoteitems/x/x' }, loadCriteria: 'quote', loadIDField: 'quoteID',\n    formConfig: this.quoteItemsFormConfig\n  }\n\n  quoteFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccountingInvoices] },\n    title: 'Quotation',\n    includeAudit: true,\n    // Changed: sectioned — customer, status, total and validity are the quote at a glance; numbering and the\n    // tax breakdown fold away so the items tab sits under the headline\n    fields: [\n      { name: 'customerID', alias: 'Customer', type: 'select', required: true, loadAction: { url: 'customers/list/x' }, detailsConfig: this.dataService.customerDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'status', type: 'select', hideOnCreate: true, readonly: true, serverOwned: true, loadAction: { url: 'quotes/list/statuses' } }, // Changed (CFW-1): Quote.Status carries [ServerOwned] — the flagship, MEASURED moving 0 -> 2 from an edit body in Phase 1\n      { name: 'totalDisplay', type: 'text', alias: 'Total', readonly: true, hideOnCreate: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'expiryDate', type: 'date', alias: 'Valid Until', nullable: true, defaultValue: '' }, // Changed: defaultValue '' stops TinCore pre-filling TODAY — a quote whose validity expires the day it is raised is valid for zero days, and nullable:true already says the intended default is EMPTY\n\n      { name: 'quoteInfo', type: 'section', alias: 'Quote Details', collapseOnView: true },\n      { name: 'quoteDate', type: 'date', max: 'today', required: true, alias: 'Date', section: 'quoteInfo' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'quoteNumber', type: 'text', alias: 'Quote #', readonly: true, hideOnCreate: true, section: 'quoteInfo' },\n      { name: 'convertedInvoiceNumber', type: 'text', alias: 'Invoice #', readonly: true, hideOnCreate: true, section: 'quoteInfo' }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'quoteInfo' },\n\n      { name: 'amounts', type: 'section', alias: 'Amount Breakdown', hideOnCreate: true, collapseOnView: true },\n      { name: 'subTotal', type: 'money', alias: 'Sub Total', readonly: true, hideOnCreate: true, section: 'amounts' },\n      { name: 'taxTotal', type: 'money', alias: 'VAT', readonly: true, hideOnCreate: true, section: 'amounts' }\n    ],\n    loadAction: { url: 'quotes/id' },\n    heroField: 'quoteID'\n  }\n\n  // Quote action buttons\n  quoteSendButton: Button = { name: 'send', inDialog: true, display: 'Send', icon: { name: 'send' },\n    action: { url: 'quotes?action=send', method: 'post', successMessage: 'Quote sent' },\n    confirm: { message: 'Mark this quote as sent to the customer?' },\n    visible: x => x.status == QuoteStatus.Draft,\n    disabled: x => x.totalAmount == 0\n  }\n\n  quoteAcceptButton: Button = { name: 'accept', inDialog: true, display: 'Accept', icon: { name: 'check_circle', color: 'green' },\n    action: { url: 'quotes?action=accept', method: 'post', successMessage: 'Quote accepted' },\n    visible: x => x.status == QuoteStatus.Sent\n  }\n\n  quoteRejectButton: Button = { name: 'reject', inDialog: true, display: 'Reject', icon: { name: 'cancel', color: 'red' },\n    action: { url: 'quotes?action=reject', method: 'post', successMessage: 'Quote rejected' },\n    confirm: { message: 'Mark this quote as rejected by the customer?' },\n    visible: x => x.status == QuoteStatus.Sent\n  }\n\n  quoteConvertButton: Button = { name: 'convert', inDialog: true, display: 'Convert to Invoice', icon: { name: 'receipt_long', color: 'blue' },\n    action: { url: 'quotes?action=convert', method: 'post', successMessage: 'Draft invoice created' },\n    confirm: { message: 'Convert this quote to a draft invoice?' },\n    visible: x => x.status == QuoteStatus.Accepted\n  }\n\n  quoteEditButton: Button = { name: 'edit', display: 'Save', dialog: true, action: { url: 'quotes?action=edit', method: 'post' }, visible: x => x.status == QuoteStatus.Draft }\n\n  // C8: PDF download — QuotesComponent handles the actionClick blob download (mirrors invoice PDF button)\n  quoteDownloadButton: Button = { name: 'pdf', display: 'Download PDF', inDialog: true, icon: { name: 'picture_as_pdf', color: 'red' } }\n\n  // Quote details dialog — two-step create pattern (header first, then items)\n  quoteDetailsDialogConfig: DetailsDialogConfig = {\n    formConfig: this.quoteFormConfig,\n    tableConfigs: [this.quoteItemsTableConfig],\n    heroField: 'quoteID',\n    buttons: [\n      this.quoteSendButton,\n      this.quoteAcceptButton,\n      this.quoteRejectButton,\n      this.quoteConvertButton,\n      this.quoteDownloadButton, // C8: PDF from the details dialog\n      this.quoteEditButton\n    ]\n  }\n\n  quoteViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.quoteDetailsDialogConfig }\n  quoteCreateButton: Button = { name: 'create', display: 'Create', dialog: true, onSuccessButton: this.quoteViewButton, action: { url: 'quotes?action=create', method: 'post' } }\n\n  quotesTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['quoteNumber', 'customerName', 'statusName'],\n    flatButtons: true,\n    collapseButtons: true,\n    greyOut: x => x.status == QuoteStatus.Rejected || x.status == QuoteStatus.Expired || x.status == QuoteStatus.Converted,\n    columns: [\n      { name: 'quoteNumber', type: 'button', alias: 'Quote #', detailsConfig: this.quoteDetailsDialogConfig },\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'quoteDate', type: 'date', alias: 'Date' },\n      { name: 'expiryDate', type: 'date', alias: 'Valid Until' },\n      { name: 'statusName', type: 'chip', alias: 'Status', detailsConfig: this.quoteDetailsDialogConfig,\n        colors: [\n          { name: '#FFCC80', condition: x => x.status == QuoteStatus.Draft },\n          { name: '#90CAF9', condition: x => x.status == QuoteStatus.Sent },\n          { name: '#A5D6A7', condition: x => x.status == QuoteStatus.Accepted || x.status == QuoteStatus.Converted },\n          { name: '#EF9A9A', condition: x => x.status == QuoteStatus.Rejected || x.status == QuoteStatus.Expired }\n        ]\n      },\n      { name: 'itemCount', type: 'number', alias: 'Items' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'convertedInvoiceNumber', type: 'text', alias: 'Invoice #' }\n    ],\n    buttons: [\n      this.quoteCreateButton,\n      this.quoteSendButton,\n      this.quoteAcceptButton,\n      this.quoteRejectButton,\n      this.quoteConvertButton,\n      this.quoteDownloadButton // C8: PDF from the row menu\n    ],\n    loadAction: { url: 'quotes/all/x' },\n    formConfig: this.quoteFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — quotes append steadily and are rarely purged\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — quotes are written up in front of the customer; create/edit queue offline\n    entityName: 'Quote',\n  }\n\n  //--------------------------Revenue Schedules (C7)-------------------------\n\n  // Added (WS-1 sweep): paginated but deliberately NOT offline — RevenueSchedule does not implement ISync, and deferred-revenue recognition is a period-end back-office run, never a field capture\n  revenueSchedulesTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['invoiceNumber', 'customerName', 'statusName'],\n    flatButtons: true,\n    columns: [\n      { name: 'invoiceNumber', type: 'text', alias: 'Invoice #' },\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'startDate', type: 'date', alias: 'Start' },\n      { name: 'endDate', type: 'date', alias: 'End' },\n      { name: 'totalAmount', type: 'money', alias: 'Deferred' },\n      { name: 'recognizedAmount', type: 'money', alias: 'Recognized' },\n      { name: 'deferredBalance', type: 'money', alias: 'Balance' },\n      { name: 'statusName', type: 'chip', alias: 'Status',\n        colors: [\n          { name: '#90CAF9', condition: x => x.status == 0 },\n          { name: '#A5D6A7', condition: x => x.status == 1 },\n          { name: '#EF9A9A', condition: x => x.status == 2 }\n        ]\n      }\n    ],\n    buttons: [\n      { name: 'recognize-due', display: 'Recognize Due Periods', inHeader: true, icon: { name: 'task_alt' }, action: { url: 'revenueschedules/recognize-due/x' }, confirm: { message: 'Recognize all revenue periods that have ended?' } },\n      { name: 'cancel', display: 'Cancel', icon: { name: 'close', color: 'red' }, action: { url: 'revenueschedules?action=cancel', method: 'post', successMessage: 'Schedule cancelled' }, confirm: { message: 'Cancel this schedule? The deferral journal will be voided.' }, visible: x => x.status == 0 && x.recognizedCount == 0 }\n    ],\n    loadAction: { url: 'revenueschedules/all/x' },\n    pagination: { pageSize: 20 }, // Added: server-side pagination — one row per recognition period, so the table grows without bound\n    entityName: 'RevenueSchedule',\n  }\n\n  //--------------------------Cash Flow / Equity (C5)-------------------------\n\n  cashFlowTableConfig: TableConfig = {\n    minColumns: ['label', 'amount'],\n    columns: [\n      { name: 'section', type: 'text', alias: 'Section' },\n      { name: 'label', type: 'text', alias: 'Item' },\n      { name: 'amount', type: 'money', alias: 'Amount' }\n    ],\n    buttons: [],\n    loadAction: { url: 'reports/cash-flow' }\n  }\n\n  equityChangesTableConfig: TableConfig = {\n    minColumns: ['account', 'closing'],\n    columns: [\n      { name: 'account', type: 'text', alias: 'Equity Account' },\n      { name: 'opening', type: 'money', alias: 'Opening' },\n      { name: 'movements', type: 'money', alias: 'Movements' },\n      { name: 'closing', type: 'money', alias: 'Closing' }\n    ],\n    buttons: [],\n    loadAction: { url: 'reports/equity-changes' }\n  }\n\n  //--------------------------Bank Reconciliation (C4)-------------------------\n\n  // Reconcile button — onClick is wired by BankReconciliationComponent (opens the match screen)\n  bankReconcileButton: Button = { name: 'reconcile', display: 'Reconcile', icon: { name: 'rule', color: 'blue' },\n    onClick: () => {}\n  }\n\n  bankStatementImportsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'accountName', 'statusName'],\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'text', alias: 'Statement' },\n      { name: 'accountName', type: 'text', alias: 'Account' },\n      { name: 'statementFrom', type: 'date', alias: 'From' },\n      { name: 'statementTo', type: 'date', alias: 'To' },\n      { name: 'closingBalance', type: 'money', alias: 'Statement Balance' },\n      { name: 'matchedCount', type: 'number', alias: 'Matched' },\n      { name: 'lineCount', type: 'number', alias: 'Lines' },\n      { name: 'statusName', type: 'chip', alias: 'Status',\n        colors: [\n          { name: '#FFD54F', condition: x => x.status == 0 },\n          { name: '#A5D6A7', condition: x => x.status == 1 }\n        ]\n      }\n    ],\n    buttons: [this.bankReconcileButton],\n    loadAction: { url: 'bankstatementimports/all/x' },\n    entityName: 'BankStatementImport'\n  }\n\n  //--------------------------Fiscal Periods (C2)-------------------------\n\n  fiscalPeriodFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAccounts] },\n    title: 'Fiscal Period',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, alias: 'Name' },\n      { name: 'startDate', type: 'date', required: true, alias: 'Start Date' },\n      { name: 'endDate', type: 'date', required: true, alias: 'End Date' },\n      { name: 'isYearEnd', type: 'checkbox', alias: 'Year-End Period' },\n      { name: 'statusName', type: 'text', alias: 'Status', readonly: true, hideOnCreate: true } // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n    ],\n    loadAction: { url: 'fiscalperiods/id' },\n    heroField: 'fiscalPeriodID'\n  }\n\n  fiscalPeriodCloseButton: Button = { name: 'close', display: 'Close', icon: { name: 'lock_clock' },\n    action: { url: 'fiscalperiods?action=close', method: 'post', successMessage: 'Period closed' },\n    confirm: { message: 'Close this period? Postings and voids dated inside it will be blocked. Year-end periods post a closing journal to Retained Earnings.' },\n    visible: x => x.status == FiscalPeriodStatus.Open\n  }\n\n  fiscalPeriodReopenButton: Button = { name: 'reopen', display: 'Reopen', icon: { name: 'lock_open', color: 'orange' },\n    action: { url: 'fiscalperiods?action=reopen', method: 'post', successMessage: 'Period reopened' },\n    confirm: { message: 'Reopen this period? Any year-end closing journal will be voided.' },\n    visible: x => x.status == FiscalPeriodStatus.Closed\n  }\n\n  fiscalPeriodLockButton: Button = { name: 'lock', display: 'Lock', icon: { name: 'lock', color: 'red' },\n    action: { url: 'fiscalperiods?action=lock', method: 'post', successMessage: 'Period locked' },\n    confirm: { message: 'Lock this period permanently? Locked periods cannot be reopened.' },\n    visible: x => x.status == FiscalPeriodStatus.Closed\n  }\n\n  fiscalPeriodsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'statusName'],\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'text', alias: 'Period' },\n      { name: 'startDate', type: 'date', alias: 'Start' },\n      { name: 'endDate', type: 'date', alias: 'End' },\n      { name: 'isYearEnd', type: 'checkbox', alias: 'Year-End' },\n      { name: 'statusName', type: 'chip', alias: 'Status',\n        colors: [\n          { name: '#A5D6A7', condition: x => x.status == FiscalPeriodStatus.Open },\n          { name: '#FFD54F', condition: x => x.status == FiscalPeriodStatus.Closed },\n          { name: '#EF9A9A', condition: x => x.status == FiscalPeriodStatus.Locked }\n        ]\n      }\n    ],\n    buttons: [\n      { name: 'create', display: 'Create Period', dialog: true, action: { url: 'fiscalperiods?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'fiscalperiods?action=edit', method: 'post' }, visible: x => x.status == FiscalPeriodStatus.Open },\n      this.fiscalPeriodCloseButton,\n      this.fiscalPeriodReopenButton,\n      this.fiscalPeriodLockButton\n    ],\n    loadAction: { url: 'fiscalperiods/all/x' },\n    formConfig: this.fiscalPeriodFormConfig,\n    entityName: 'FiscalPeriod'\n  }\n\n  constructor() {\n    // Wire the Credit Note button into the invoice dialog after both configs exist (avoids forward reference)\n    this.invoiceDetailsDialogConfig.buttons!.push(this.invoiceCreditNoteButton);\n    // Changed: dropdown quick-add — currencyDetailsConfig is declared later in the file, so wire these selects here (avoids forward reference)\n    this.accountFormConfig.fields.find(f => f.name === 'currencyID').detailsConfig = this.currencyDetailsConfig;\n    this.invoicePaymentFormConfig.fields.find(f => f.name === 'currencyID').detailsConfig = this.currencyDetailsConfig;\n    // Changed: dropdown quick-add — taxRateDetailsConfig is declared after invoiceItemsFormConfig, so wire this select here too\n    this.invoiceItemsFormConfig.fields.find(f => f.name === 'taxRateID').detailsConfig = this.taxRateDetailsConfig;\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, TableConfig, DetailsDialogConfig, Button, StepConfig } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\nimport { InventoryService } from './inventory.service'; // Changed: Import for product detailsConfig reference\nimport { AccountingService } from './accounting.service'; // Changed: dropdown quick-add — currency config for currency selects\n\n// Changed: Sales service extracted from inventory.service.ts for Sales module\n@Injectable({\n  providedIn: 'root'\n})\nexport class SalesService {\n\n  private dataService = inject(DataServiceLib);\n  private inventoryService = inject(InventoryService); // Changed: Reference for product detailsConfig\n  private accountingService = inject(AccountingService); // Changed: dropdown quick-add — currency config for currency selects\n\n  //--------------------------Sales Order Items-------------------------\n\n  salesOrderItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSalesOrders] }, // Added: gate sales order item form by sales orders cap (parent entity)\n    title: 'Sales Order Item',\n    fixedTitle: true,\n    fields: [\n      { name: 'productID', type: 'select', alias: 'Product', required: true, loadAction: { url: 'products/list/x' }, detailsConfig: this.inventoryService.productDetailsConfig },\n      { name: 'quantity', type: 'number', alias: 'Quantity', required: true },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price', required: true },\n      { name: 'discount', type: 'money', alias: 'Discount' },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total', readonly: true },\n      { name: 'inventoryItemID', type: 'select', alias: 'Serial Number', loadAction: { url: 'inventoryitems/list/x' } }\n    ],\n    loadAction: { url: 'salesorderitems/id' }\n  }\n\n  salesOrderItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    // Added (delivered-order-lines-ui-gate): the three line buttons below are HIDDEN on a Delivered(2)/Cancelled(3) order, which on its own leaves the user staring at an uneditable list with nothing saying why or what to do instead. This is the same predicate as those buttons, reading config.parentData (the parent order), and the wording is the server's own from SalesOrderItemsController.CheckParentOrderOpen (lines 128 and 131) minus its \"record of account\" clause — same remedies, named in the same words, so the caption and a refusal toast can never contradict each other. The lines themselves stay listed and readable; only the writes are gone.\n    caption: (o) => o?.status === 2 ? 'Cannot change lines on a delivered order — void the sale, raise a credit note against its invoice, then capture a new order.' : o?.status === 3 ? 'Cannot change lines on a cancelled order. Capture a new order instead.' : '',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'quantity', type: 'number', alias: 'Quantity' },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price' },\n      { name: 'discount', type: 'money', alias: 'Discount' },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total' },\n      { name: 'serialNumber', type: 'text', alias: 'Serial Number' }\n    ],\n    buttons: [\n      // Added (delivered-order-lines-ui-gate): mirror the server refusal in SalesOrderItemsController.CheckParentOrderOpen. Boundary is Delivered(2)/Cancelled(3) ONLY — Confirmed(1) stays editable because SalesOrdersController.OwnsSubTotal keeps that window open. 'create' renders in the table header and its predicate receives config.parentData (the parent order, so .status); 'edit'/'delete' render in the row and receive the line, which now carries orderStatus from the controller projection. Optional chaining is required — the predicate is called before the record arrives.\n      { name: 'create', display: 'Add Item', dialog: true, hidden: (o) => o?.status === 2 || o?.status === 3, action: { url: 'salesorderitems?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, hidden: (r) => r?.orderStatus === 2 || r?.orderStatus === 3, action: { url: 'salesorderitems?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, hidden: (r) => r?.orderStatus === 2 || r?.orderStatus === 3, action: { url: 'salesorderitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'salesorderitems/x/x' }, loadCriteria: 'order', loadIDField: 'salesOrderID',\n    formConfig: this.salesOrderItemFormConfig\n  }\n\n  //--------------------------Sales Orders-------------------------\n\n  salesOrderFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSalesOrders] },\n    title: 'Sales Order',\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'orderInfo', type: 'section', alias: 'Order Information' },\n      { name: 'orderNumber', type: 'text', alias: 'Order #', readonly: true, section: 'orderInfo' },\n      { name: 'customerID', type: 'select', required: true, alias: 'Customer', section: 'orderInfo', loadAction: { url: 'customers/list/x' }, detailsConfig: this.dataService.customerDetailsConfig },\n      { name: 'orderDate', type: 'date', max: 'today', required: true, alias: 'Order Date', section: 'orderInfo' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'requiredDate', type: 'date', alias: 'Required Date', section: 'orderInfo' },\n      { name: 'quickProcess', type: 'section', alias: 'Quick Processing' },\n      { name: 'quickDelivery', type: 'checkbox', alias: 'Quick Delivery (Skip to Delivered)', section: 'quickProcess' },\n      { name: 'deliveredDate', type: 'date', max: 'today', alias: 'Delivery Date', section: 'quickProcess' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'paymentInfo', type: 'section', alias: 'Payment (For Delivery)', collapseOnView: true },\n      { name: 'paymentMethod', type: 'select', alias: 'Payment Method', section: 'paymentInfo', options: [{ name: 'Cash', value: 0 }, { name: 'Bank Transfer', value: 1 }, { name: 'Mobile Money', value: 2 }, { name: 'Card', value: 3 }, { name: 'Credit', value: 4 }, { name: 'Complementary', value: 5 }] },\n      { name: 'paymentReference', type: 'text', alias: 'Payment Reference', section: 'paymentInfo' },\n      { name: 'status', type: 'select', alias: 'Status', readonly: true, serverOwned: true, hideOnCreate: true, loadAction: { url: 'salesorders/list/status' } }, // Changed (CFW-1): SalesOrder.Status carries [ServerOwned]; serverOwned omits the key on create too — Draft is 0, exactly what the server's create-bind reset writes, and the create POST was re-driven to confirm no 400 (hideOnCreate had previously been added because an omitted status DID 400)\n      { name: 'totals', type: 'section', alias: 'Totals', collapseOnView: true },\n      { name: 'subTotal', type: 'money', alias: 'Sub Total', readonly: true, section: 'totals' },\n      { name: 'discount', type: 'money', alias: 'Discount', section: 'totals' },\n      { name: 'totalAmount', type: 'money', alias: 'Total Amount', readonly: true, section: 'totals' },\n      { name: 'additionalInfo', type: 'section', alias: 'Additional Information', collapseOnView: true },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'additionalInfo' }\n    ],\n    loadAction: { url: 'salesorders/id' },\n    heroField: 'salesOrderID'\n  }\n\n  salesOrderEditButton: Button = { name: 'edit', dialog: true, action: { url: 'salesorders?action=edit', method: 'post' } }\n  // Changed: colour was the Material palette name 'primary', which getButtonColor puts verbatim into\n  // [style.color] and which therefore computed to the inherited grey. 'blue' is the house CSS keyword, and it\n  // keeps 'green' meaning the terminal step (Mark Delivered, below).\n  salesOrderConfirmButton: Button = { name: 'confirm', display: 'Confirm Order', icon: { name: 'check_circle', color: 'blue' }, inDialog : true, action: { url: 'salesorders?action=confirm', method: 'post', successMessage: 'Order Confirmed' }, confirm: { message: 'Confirm this order?' }, visible: (row) => row.status === 0 }\n  salesOrderDeliverButton: Button = { name: 'deliver', display: 'Mark Delivered', icon: { name: 'local_shipping', color: 'green' }, inDialog : true, action: { url: 'salesorders?action=deliver', method: 'post', successMessage: 'Order Delivered' }, confirm: { message: 'Mark this order as delivered?' }, visible: (row) => row.status === 1 }\n\n  salesOrderDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.salesOrderFormConfig,\n    tableConfigs: [this.salesOrderItemsTableConfig],\n    heroField: 'salesOrderID',\n    buttons: [ this.salesOrderEditButton, this.salesOrderConfirmButton, this.salesOrderDeliverButton]\n  }\n\n  salesOrderViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.salesOrderDetailsConfig }\n\n  salesOrdersTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['orderNumber', 'displayCustomerName', 'orderDate'],\n    columns: [\n      { name: 'orderNumber', type: 'text', alias: 'Order #' },\n      { name: 'displayCustomerName', type: 'text', alias: 'Customer' },\n      { name: 'orderDate', type: 'date', alias: 'Order Date' },\n      { name: 'requiredDate', type: 'date', alias: 'Required Date' },\n      { name: 'deliveredDate', type: 'date', alias: 'Delivered Date' },\n      { name: 'status', type: 'text', alias: 'Status' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'pendingApproval', type: 'checkbox', alias: 'Pending' }\n    ],\n    buttons: [\n      { name: 'create', display: 'New Order', dialog: true, action: { url: 'salesorders?action=create', method: 'post' }, onSuccessButton: this.salesOrderViewButton},\n      { name: 'view', dialog: true, detailsConfig: this.salesOrderDetailsConfig },\n      { name: 'edit', dialog: true, detailsConfig: this.salesOrderDetailsConfig },\n      { name: 'delete', dialog: true, action: { url: 'salesorders?action=delete', method: 'post' } },\n      this.salesOrderConfirmButton,\n      this.salesOrderDeliverButton\n    ],\n    loadAction: { url: 'salesorders/all/x' },\n    formConfig: this.salesOrderFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — sales orders append continuously\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — orders are taken in front of the customer; create/edit queue offline\n    entityName: 'SalesOrder',\n  }\n\n  //--------------------------Sale Items-------------------------\n\n  saleItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSales] },\n    title: 'Sale Item',\n    fixedTitle: true,\n    fields: [\n      { name: 'productID', type: 'select', required: true, alias: 'Product', span: true, loadAction: { url: 'products/list/x' }, detailsConfig: this.inventoryService.productDetailsConfig, // Changed: dropdown quick-add\n        onSelectChange: (selectedProductId: number, formData: any, option?: any) => {\n          if (option && option.sellingPrice) {\n            formData.unitPrice = option.sellingPrice;\n          }\n        }\n      },\n      { name: 'quantity', type: 'number', required: true, alias: 'Quantity' },\n      { name: 'unitPrice', type: 'money', required: true, alias: 'Unit Price' },\n      { name: 'discount', type: 'money', alias: 'Discount', hideOnCreate: true },\n      { name: 'inventoryItemID', type: 'select', alias: 'Serial Number', loadAction: { url: 'inventoryitems/list/serialized' } }\n    ],\n    loadAction: { url: 'saleitems/id' }\n  }\n\n  saleItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'quantity', type: 'number', alias: 'Quantity' },\n      { name: 'unitPrice', type: 'money', alias: 'Unit Price' },\n      { name: 'discount', type: 'money', alias: 'Discount' },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total' },\n      { name: 'serialNumber', type: 'text', alias: 'Serial Number' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'saleitems?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'saleitems?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'saleitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'saleitems/x/x' }, loadCriteria: 'sale', loadIDField: 'saleID',\n    formConfig: this.saleItemFormConfig\n  }\n\n  //--------------------------Sales-------------------------\n\n  saleFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSales] },\n    title: 'Sale',\n    fixedTitle: true,\n    alertConfig: {\n      compact: true,\n      sticky : true,\n      messages: [\n        { message: 'Please add sale items and click complete to finalise the sale', type: 'success',\n          visible: (x: any) => x.paymentStatus === 0\n        }\n      ]\n    },\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'saleInfo', type: 'section', alias: 'Sale Information' },\n      { name: 'saleDate', type: 'date', max: 'today', required: true, alias: 'Sale Date', section: 'saleInfo', infoMessage: 'Date when the sale was completed' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'customerID', type: 'select', required: true, alias: 'Customer', section: 'saleInfo', loadAction: { url: 'customers/list/x' }, detailsConfig: this.dataService.customerDetailsConfig },\n      { name: 'timing', type: 'select', required: true, alias: 'Transaction Type', section: 'saleInfo', loadAction: { url: 'sales/list/timing' }, defaultFirstValue : true, infoMessage: 'Cash Sale (pay now) or Credit Sale (pay later)' },\n      { name: 'currencyID', type: 'select', alias: 'Currency', section: 'saleInfo', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, detailsConfig: this.accountingService.currencyDetailsConfig, infoMessage: 'Currency for this sale (defaults to base currency)' }, // Changed: dropdown quick-add\n      { name: 'paymentMethod', type: 'select', required: true, alias: 'Payment Method', section: 'saleInfo', defaultFirstValue: true, infoMessage: 'Method of payment used for this sale', requiredCondition: x => x.timing === 0, hidden: x => x.timing === 1,\n        options: [\n          { name: 'Cash', value: 0 },\n          { name: 'Bank Transfer', value: 1 },\n          { name: 'Mobile Money', value: 2 },\n          { name: 'Card', value: 3 },\n          { name: 'Complementary', value: 5 }\n        ],\n      },\n      { name: 'multipleProducts', type: 'checkbox', alias: 'Multiple Products', defaultValue: false, hideOnExists: true, infoMessage: 'Check this box if you want to add multiple products to this sale' },\n      { name: 'saleType', type: 'select', required: true, alias: 'Sale Type', section: 'saleInfo', options: [{ name: 'Quick Sale', value: 0 }, { name: 'From Order', value: 1 }], defaultFirstValue: true, hideOnCreate: true, infoMessage: 'Select if this is a quick sale or created from an order' },\n      { name: 'quickSaleItem', type: 'section', alias: 'Quick Sale Item', hidden: x => x.multipleProducts === true || x.saleID },\n      { name: 'productID', type: 'select', required: true, alias: 'Product', section: 'quickSaleItem', span: true, loadAction: { url: 'products/list/x' }, hidden: x => x.multipleProducts === true, detailsConfig: this.inventoryService.productDetailsConfig, // Changed: dropdown quick-add\n        onSelectChange: (selectedProductId: number, formData: any, option?: any) => {\n          if (option && option.sellingPrice) {\n            formData.unitPrice = option.sellingPrice;\n          }\n        }\n      },\n      { name: 'quantity', type: 'number', required: true, alias: 'Quantity', section: 'quickSaleItem', defaultValue: 1, hidden: x => x.multipleProducts === true, infoMessage: 'Quantity of the product' },\n      { name: 'unitPrice', type: 'money', required: true, alias: 'Unit Price', section: 'quickSaleItem', hidden: x => x.multipleProducts === true, infoMessage: 'Price per unit' },\n      { name: 'totals', type: 'section', alias: 'Totals', collapseOnView: true, hideOnCreate: true },\n      { name: 'subTotal', type: 'money', alias: 'Sub Total', readonly: true, section: 'totals', infoMessage: 'Total before tax and discounts' },\n      { name: 'taxAmount', type: 'money', alias: 'Tax Amount', section: 'totals', infoMessage: 'Tax amount applied to the sale' },\n      { name: 'discount', type: 'money', alias: 'Discount', section: 'totals', infoMessage: 'Discount amount applied to the sale' },\n      { name: 'totalAmount', type: 'money', alias: 'Total Amount', readonly: true, section: 'totals', infoMessage: 'Final amount after tax and discounts' },\n      { name: 'additionalInfo', type: 'section', alias: 'Additional Information', collapseOnView: true },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'additionalInfo', infoMessage: 'Additional notes or comments about this sale' },\n      { name: 'paymentReference', type: 'text', alias: 'Payment Reference', section: 'additionalInfo', infoMessage: 'Transaction reference number or payment receipt', hidden: x => x.timing === 1 },\n    ],\n    loadAction: { url: 'sales/id' },\n    heroField: 'saleID'\n  }\n\n  saleStepConfig: StepConfig = {\n    valueField: 'paymentStatus',\n    sticky: true,\n    steps: [\n      { name: 'Unpaid', value: 0, icon: 'hourglass_empty' },\n      { name: 'Paid', value: 1, icon: 'check_circle' },\n      { name: 'Partial', value: 2, icon: 'payment' }\n    ]\n  }\n\n  salePaymentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSales] },\n    title: 'Record Payment',\n    fixedTitle: true,\n    fields: [\n      { name: 'saleID', type: 'number', hidden: true },\n      { name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true }, // Changed (NFD-3): max: 'today' REMOVED — a post-dated payment instrument is ordinary business, so a future payment date is a valid answer; verified the server (InvoiceService.RecordPayment) does not reject one either. Pinned by payment-date-uncapped-guard.spec.ts.\n      { name: 'method', type: 'select', alias: 'Payment Method', required: true, defaultValue: 1, loadAction: { url: 'invoicepayments/list/methods' } },\n      { name: 'currencyID', type: 'select', alias: 'Currency', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, detailsConfig: this.accountingService.currencyDetailsConfig, infoMessage: 'Currency for this payment (defaults to base currency)' }, // Changed: dropdown quick-add\n      { name: 'totalAmount', type: 'text', alias: 'Total Amount', readonly: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'amount', type: 'money', alias: 'Amount', required: true, span: true },\n      { name: 'paymentReferenceTemp', type: 'text', alias: 'Reference', span: true }\n    ],\n  }\n\n  salePaymentCreateButton: Button = { name: 'edit', action: { url: 'sales?action=record-payment', method: 'post', successMessage: 'Payment recorded successfully' } };\n\n  salePaymentDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.salePaymentFormConfig,\n    heroField: 'saleID',\n    mode: 'edit',\n    seedDefaults: true, // Added: CAPTURE dialog on mode:'edit' (posts sales?action=record-payment). VERIFIED NO-OP TODAY, same reason as the invoice dialog: SalesController.cs:98 projects Method = InvoicePaymentMethod.Bank onto the sale row, so `method` arrives populated and the only-empty guard skips it. Kept as the declared fallback\n    buttons: [this.salePaymentCreateButton]\n  }\n\n  saleRecordPaymentButton: Button = { name: 'record-payment', display: 'Record Payment', inDialog: true, dialog: true, icon: { name: 'payment', color: 'blue' }, detailsConfig: this.salePaymentDetailsConfig, visible: x => x.timing === 1 && x.paymentStatus !== 1 }\n\n  salePaymentsTableConfig: TableConfig = {\n    tabTitle: 'Payment History',\n    showFilter: false,\n    minColumns: ['paymentDate', 'amount', 'methodName'],\n    columns: [\n      { name: 'paymentDate', type: 'date', alias: 'Date' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'methodName', type: 'text', alias: 'Method' },\n      { name: 'reference', type: 'text', alias: 'Reference' }\n    ],\n    loadAction: { url: 'invoicepayments/x/x' }, loadCriteria: 'invoice', loadIDField: 'invoiceID',\n    hidden: (x: any) => x.timing !== 1\n  }\n\n  saleDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.saleFormConfig,\n    tableConfigs: [this.saleItemsTableConfig, this.salePaymentsTableConfig],\n    heroField: 'saleID',\n    stepConfig: this.saleStepConfig,\n    buttons: [\n        { name: 'complete', display: 'Complete Sale', color: 'green', inDialog: true, action: { url: 'sales?action=complete', method: 'post' }, confirm: { message: 'Complete this sale? This will reduce inventory and create accounting entries.' }, visible: x => x.timing === 0 && x.paymentStatus !== 1 },\n        this.saleRecordPaymentButton\n      ]\n  }\n\n  saleViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.saleDetailsConfig }\n  saleCreateButton: Button = { name: 'create', display: 'Quick Sale', dialog: true, action: { url: 'sales?action=create', method: 'post' } };\n  saleVoidButton: Button = { name: 'void', display: 'Void', icon: { name: 'undo', color: 'red' }, confirm: { message: 'Caution: Voiding this sale will reverse all inventory transactions and void accounting entries. This action cannot be undone.' }, action: { url: 'sales?action=void', method: 'post', successMessage: 'Sale voided successfully' }, visible: (row) => !row.deleted };\n\n  salesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['saleNumber', 'displayCustomerName', 'totalAmount'],\n    columns: [\n      { name: 'saleDate', type: 'date', alias: 'Date' },\n      { name: 'displayCustomerName', type: 'text', alias: 'Customer' },\n      { name: 'detailsDisplay', type: 'text', alias: 'Details' }, // Changed: Renamed from productsDisplay/Products\n      { name: 'timingName', type: 'text', alias: 'Payment' },\n      { name: 'paymentStatus', type: 'icon', alias: 'Status', detailsConfig: this.saleDetailsConfig,\n        icons: [\n          { name: 'article', color: '#9E9E9E', condition: (x: any) => x.paymentStatus === 0, tip: 'Unpaid' },\n          { name: 'inventory_2', color: '#2196F3', condition: (x: any) => x.paymentStatus === 2, tip: 'Partial' },\n          { name: 'check_circle', color: '#4CAF50', condition: (x: any) => x.paymentStatus === 1, tip: 'Paid' }\n        ]\n      },\n      { name: 'subTotal', type: 'money', alias: 'Sub Total' },\n      { name: 'taxAmount', type: 'money', alias: 'Tax' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' }\n    ],\n    buttons: [\n      this.saleViewButton,\n      this.saleRecordPaymentButton,\n      this.saleCreateButton,\n      this.saleVoidButton\n    ],\n    loadAction: { url: 'sales/all/x' },\n    formConfig: this.saleFormConfig,\n    pagination: { pageSize: 15 }, // Added: server-side pagination — sales are wide money rows (customer join, line totals, payment state) and the highest-volume grid in sales\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — sales are captured at the point of sale, where the connection is least reliable\n    entityName: 'Sale',\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, TableConfig, DetailsDialogConfig, Button, StepConfig, PurchaseStatus, TileConfig } from '../classes/Classes'; // Changed: InventoryReceiptStatus → PurchaseStatus\nimport { DataServiceLib } from './datalib.service';\nimport { InventoryService } from './inventory.service';\nimport { AccountingService } from './accounting.service'; // Changed: dropdown quick-add — currency config for currency selects\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class PurchasingService {\n\n  private dataService = inject(DataServiceLib);\n  private inventoryService = inject(InventoryService);\n  private accountingService = inject(AccountingService); // Changed: dropdown quick-add — currency config for currency selects\n\n  // Changed: Updated references from inventoryReceiptDetailsConfig to purchaseDetailsConfig\n  constructor() {\n    this.purchaseDetailsConfig.tableConfigs!.push(this.receiptsTableConfig); // Added: Receipts tab in purchase details\n    this.purchaseDetailsConfig.tableConfigs!.push(this.supplierPaymentsTableConfig);\n    this.purchaseDetailsConfig.buttons!.push(this.supplierRecordPaymentButton);\n  }\n\n  //--------------------------Purchase Orders-------------------------\n\n  private paymentTypeOptions = [\n    { value: 0, name: 'Cash' },\n    { value: 1, name: 'Bank' }\n  ];\n\n  supplierPurchaseOrderItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSupplierPurchaseOrders] }, // Changed (menucap-1 M2): cap38 -> cap47. SupplierPurchaseOrderItemsController.cs:16 gates this data on cap47, and the menu entry is drawn on cap47 (datalib.service.ts:586-588) — this form was the only side saying cap38, so a cap47 holder the API would serve was refused by the front end\n    title: 'PO Item',\n    fixedTitle: true,\n    fields: [\n      { name: 'productID', type: 'select', alias: 'Product', required: true, loadAction: { url: 'products/list/x' }, detailsConfig: this.inventoryService.productDetailsConfig },\n      { name: 'orderedQuantity', type: 'number', alias: 'Quantity', required: true },\n      { name: 'estimatedUnitCost', type: 'money', alias: 'Est. Unit Cost', required: true },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total', readonly: true, hideOnCreate: true }\n    ],\n    loadAction: { url: 'supplierpurchaseorderitems/id' }\n  }\n\n  supplierPurchaseOrderItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'orderedQuantity', type: 'number', alias: 'Ordered' },\n      { name: 'receivedQuantity', type: 'number', alias: 'Received' },\n      { name: 'remainingQuantity', type: 'number', alias: 'Remaining' },\n      { name: 'estimatedUnitCost', type: 'money', alias: 'Est. Cost' },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total' },\n      { name: 'isFullyReceived', type: 'checkbox', alias: 'Complete', icon: { name: 'check_circle', color: 'green' } }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'supplierpurchaseorderitems?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'supplierpurchaseorderitems?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'supplierpurchaseorderitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'supplierpurchaseorderitems/x/x' },\n    loadCriteria: 'po',\n    loadIDField: 'supplierPurchaseOrderID',\n    formConfig: this.supplierPurchaseOrderItemFormConfig\n  }\n\n  supplierPurchaseOrderFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSupplierPurchaseOrders] }, // Changed (menucap-1 M2): cap38 -> cap47, matching SupplierPurchaseOrdersController.cs:17 and the cap47 menu entry. The other six capInventoryReceipts gates in this file are purchases/receipts/payments and correctly match their own cap38 controllers\n    title: 'Purchase Order',\n    fixedTitle: true,\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'poInfo', type: 'section', alias: 'Purchase Order Information' },\n      { name: 'poNumber', type: 'text', alias: 'PO Number', readonly: true, hideOnCreate: true, section: 'poInfo' },\n      { name: 'supplierID', type: 'select', required: true, alias: 'Supplier', section: 'poInfo', loadAction: { url: 'suppliers/list/x' }, detailsConfig: this.dataService.supplierDetailsConfig },\n      { name: 'orderDate', type: 'date', max: 'today', required: true, alias: 'Order Date', section: 'poInfo' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'expectedDeliveryDate', type: 'date', alias: 'Expected Delivery', section: 'poInfo' },\n      { name: 'totals', type: 'section', alias: 'Totals', hideOnCreate: true, collapseOnView: true },\n      { name: 'totalAmount', type: 'money', alias: 'Total Amount', readonly: true, section: 'totals' },\n      { name: 'totalReceivedAmount', type: 'money', alias: 'Received Amount', readonly: true, section: 'totals' },\n      { name: 'remainingAmount', type: 'money', alias: 'Remaining', readonly: true, section: 'totals' },\n      { name: 'additionalInfo', type: 'section', alias: 'Additional Information', collapseOnView: true },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'additionalInfo' }\n    ],\n    loadAction: { url: 'supplierpurchaseorders/id' },\n    heroField: 'supplierPurchaseOrderID'\n  }\n\n  receiveGoodsFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReceipts] }, // Added: gate receive goods form by purchasing cap\n    title: 'Receive Goods',\n    multiColumn: true,\n    fields: [\n      { name: 'supplierPurchaseOrderID', type: 'number', alias: 'PO ID', readonly: true, hidden: true },\n      { name: 'poNumber', type: 'text', alias: 'PO Number', readonly: true },\n      { name: 'supplierID', type: 'number', alias: 'Supplier ID', readonly: true, hidden: true },\n      { name: 'supplierName', type: 'text', alias: 'Supplier', readonly: true },\n      { name: 'purchaseDate', type: 'date', max: 'today', required: true, alias: 'Purchase Date' }, // Changed: receiptDate → purchaseDate // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'paymentType', type: 'select', required: true, alias: 'Payment Type', options: this.paymentTypeOptions },\n      { name: 'supplierInvoiceNumber', type: 'text', alias: 'Supplier Invoice #' },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true }\n    ]\n  }\n\n  receiveGoodsDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.receiveGoodsFormConfig,\n    buttons: []\n  }\n\n  supplierPurchaseOrderEditButton: Button = { name: 'edit', dialog: true, action: { url: 'supplierpurchaseorders?action=edit', method: 'post' } }\n  supplierPurchaseOrderConfirmButton: Button = { name: 'confirm', display: 'Confirm PO', inDialog: true, icon: { name: 'check_circle', color: 'blue' }, action: { url: 'supplierpurchaseorders?action=confirm', method: 'post', successMessage: 'PO Confirmed' }, confirm: { message: 'Confirm this purchase order? Items will be locked.' }, visible: (po: any) => po.statusName === 'Draft' }\n  supplierPurchaseOrderCancelButton: Button = { name: 'cancel', display: 'Cancel PO', inDialog: true, icon: { name: 'cancel', color: 'red' }, action: { url: 'supplierpurchaseorders?action=cancel', method: 'post', successMessage: 'PO Cancelled' }, confirm: { message: 'Cancel this purchase order?' }, visible: (po: any) => po.statusName !== 'FullyReceived' && po.statusName !== 'PartiallyReceived' }\n\n  supplierPurchaseOrderReceiveButton: Button = {\n    name: 'receive',\n    display: 'Receive Goods',\n    inDialog: true,\n    icon: { name: 'inventory_2', color: 'green' },\n    dialog: true,\n    detailsConfig: this.receiveGoodsDetailsConfig,\n    action: { url: 'purchases?action=create', method: 'post' }, // Changed: inventoryreceipts → purchases\n    visible: (po: any) => po.statusName === 'Confirmed' || po.statusName === 'PartiallyReceived'\n  }\n\n  supplierPurchaseOrderDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.supplierPurchaseOrderFormConfig,\n    tableConfigs: [this.supplierPurchaseOrderItemsTableConfig],\n    heroField: 'supplierPurchaseOrderID',\n    buttons: [this.supplierPurchaseOrderEditButton, this.supplierPurchaseOrderConfirmButton, this.supplierPurchaseOrderReceiveButton, this.supplierPurchaseOrderCancelButton]\n  }\n\n  supplierPurchaseOrderViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.supplierPurchaseOrderDetailsConfig }\n\n  supplierPurchaseOrdersTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['poNumber', 'supplierName', 'orderDate'],\n    columns: [\n      { name: 'poNumber', type: 'text', alias: 'PO #' },\n      { name: 'supplierName', type: 'text', alias: 'Supplier' },\n      { name: 'orderDate', type: 'date', alias: 'Order Date' },\n      { name: 'expectedDeliveryDate', type: 'date', alias: 'Expected Delivery' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'totalReceivedAmount', type: 'money', alias: 'Received' },\n      { name: 'remainingAmount', type: 'money', alias: 'Remaining' },\n      { name: 'statusName', type: 'chip', alias: 'Status', colors: [{ name: '#E0E0E0', condition: x => x.statusName == 'Draft' }, { name: '#BBDEFB', condition: x => x.statusName == 'Confirmed' }, { name: '#FFE0B2', condition: x => x.statusName == 'PartiallyReceived' }, { name: '#C8E6C9', condition: x => x.statusName == 'FullyReceived' }, { name: '#FFCDD2', condition: x => x.statusName == 'Cancelled' }] }\n    ],\n    buttons: [\n      { name: 'create', display: 'New Purchase Order', dialog: true, action: { url: 'supplierpurchaseorders?action=create', method: 'post' }, onSuccessButton: this.supplierPurchaseOrderViewButton },\n      { name: 'view', dialog: true, detailsConfig: this.supplierPurchaseOrderDetailsConfig },\n      { name: 'delete', dialog: true, action: { url: 'supplierpurchaseorders?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'supplierpurchaseorders/all/x' },\n    formConfig: this.supplierPurchaseOrderFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — purchase orders append continuously\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — POs are raised on supplier visits as well as at the desk\n    entityName: 'SupplierPurchaseOrder',\n  }\n\n  //--------------------------Purchases (renamed from Inventory Receipts)-------------------------\n\n  // Changed: Renamed from inventoryReceiptItemFormConfig to purchaseItemFormConfig\n  purchaseItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReceipts] }, // Added: gate purchase item form by purchasing cap (parent)\n    title: 'Purchase Item', // Changed: \"Receipt Item\" → \"Purchase Item\"\n    fixedTitle: true,\n    fields: [\n      { name: 'productID', type: 'select', alias: 'Product', required: true, span: true,\n        loadAction: { url: 'products/list/x' },\n        detailsConfig: this.inventoryService.productDetailsConfig, infoMessage: 'Product being received'\n      },\n      { name: 'quantity', type: 'number', alias: 'Quantity', required: true, infoMessage: 'Number of units received' },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost', required: true, infoMessage: 'Cost per unit' },\n      { name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, loadAction: { url: 'products/list/tax-rates' }, detailsConfig: this.accountingService.taxRateDetailsConfig, infoMessage: 'VAT rate on this purchase line — claimable input VAT (B3)' }, // Changed: dropdown quick-add\n      { name: 'isTaxInclusive', type: 'checkbox', alias: 'Cost includes Tax', infoMessage: 'If checked, the unit cost already includes VAT' }, // Changed: Tax-inclusive flag\n      { name: 'serialNumbers', type: 'text', alias: 'Serial Numbers (comma-separated)', infoMessage: 'Comma-separated list of serial numbers for tracked items' }\n    ],\n    loadAction: { url: 'purchaseitems/id' } // Changed: inventoryreceiptitems → purchaseitems\n  }\n\n  // Changed: Renamed from inventoryReceiptItemsTableConfig to purchaseItemsTableConfig\n  purchaseItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'quantity', type: 'number', alias: 'Quantity' },\n      { name: 'unitName', type: 'text', alias: 'Unit' },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost' },\n      { name: 'taxAmount', type: 'money', alias: 'VAT' }, // Changed: Input VAT column (B3)\n      { name: 'lineTotal', type: 'money', alias: 'Line Total' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'purchaseitems?action=create', method: 'post' } }, // Changed: inventoryreceiptitems → purchaseitems\n      { name: 'edit', dialog: true, action: { url: 'purchaseitems?action=edit', method: 'post' } }, // Changed: inventoryreceiptitems → purchaseitems\n      { name: 'delete', dialog: true, action: { url: 'purchaseitems?action=delete', method: 'post' } } // Changed: inventoryreceiptitems → purchaseitems\n    ],\n    loadAction: { url: 'purchaseitems/x/x' }, loadCriteria: 'purchase', loadIDField: 'purchaseID', // Changed: inventoryreceiptitems → purchaseitems, receipt → purchase, inventoryReceiptID → purchaseID\n    formConfig: this.purchaseItemFormConfig // Changed: inventoryReceiptItemFormConfig → purchaseItemFormConfig\n  }\n\n  // Changed: Renamed from inventoryReceiptFormConfig to purchaseFormConfig\n  purchaseFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReceipts] },\n    title: 'Purchase', // Changed: \"Inventory Receipt\" → \"Purchase\"\n    alertConfig: {\n      compact: true,\n      messages: [\n      { message: 'Please capture the products purchased and click complete to proceed', type: 'success',\n        visible: (x: any) => x.status === PurchaseStatus.Draft || x.status === PurchaseStatus.Confirmed // Changed: InventoryReceiptStatus → PurchaseStatus, Receiving → Confirmed\n      }]\n    },\n    fixedTitle: true,\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'purchaseInfo', type: 'section', alias: 'Purchase Information' }, // Changed: receiptInfo → purchaseInfo\n\n      { name: 'purchaseDate', type: 'date', max: 'today', required: true, alias: 'Purchase Date', section: 'purchaseInfo', infoMessage: 'Date goods were purchased' }, // Changed: receiptDate → purchaseDate, receiptInfo → purchaseInfo // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'supplierID', type: 'select', required: true, alias: 'Supplier', section: 'purchaseInfo', // Changed: receiptInfo → purchaseInfo\n        loadAction: { url: 'suppliers/list/x' }, detailsConfig: this.dataService.supplierDetailsConfig, infoMessage: 'Supplier providing the goods'\n      },\n      { name: 'timing', type: 'select', required: true, alias: 'Transaction Type', section: 'purchaseInfo', // Changed: receiptInfo → purchaseInfo\n        loadAction: { url: 'purchases/list/timing' }, defaultFirstValue: true, // Changed: inventoryreceipts → purchases\n        infoMessage: 'Cash Purchase (pay now) or Credit Purchase (pay later)'\n      },\n      { name: 'currencyID', type: 'select', alias: 'Currency', section: 'purchaseInfo', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, detailsConfig: this.accountingService.currencyDetailsConfig, infoMessage: 'Currency for this purchase (defaults to base currency)' }, // Changed: dropdown quick-add\n\n      { name: 'paymentType', type: 'select', required: true, alias: 'Payment Method', section: 'purchaseInfo', defaultFirstValue: true, // Changed: receiptInfo → purchaseInfo\n        options: this.paymentTypeOptions, infoMessage: 'Payment method used for this purchase',\n        hidden: x => x.timing === 1,\n        requiredCondition: x => x.timing === 0\n      },\n\n      { name: 'purchaseNumber', type: 'text', alias: 'Purchase Number', readonly: true, hideOnCreate: true, section: 'purchaseInfo', infoMessage: 'Auto-generated unique purchase identifier' }, // Changed: receiptNumber → purchaseNumber\n      { name: 'poNumber', type: 'text', alias: 'PO Number', hideOnCreate: true, section: 'purchaseInfo', infoMessage: 'Linked purchase order if receiving against a PO', // Changed: receiptInfo → purchaseInfo\n        hidden: (row) => !row.supplierPurchaseOrderID,\n      },\n      { name: 'multipleProducts', type: 'checkbox', alias: 'Multiple Products', defaultValue: false, hideOnExists: true, infoMessage: 'Check this box if you want to add multiple products to this purchase' }, // Changed: receipt → purchase\n\n      { name: 'quickPurchaseItem', type: 'section', alias: 'Quick Purchase Item',\n        hidden: x => x.multipleProducts === true || x.purchaseID // Changed: inventoryReceiptID → purchaseID\n      },\n      { name: 'productID', type: 'select', required: true, alias: 'Product', section: 'quickPurchaseItem', span: true,\n        loadAction: { url: 'products/list/x' },\n        hidden: x => x.multipleProducts === true,\n        onSelectChange: (selectedProductId: number, formData: any, option?: any) => {\n          if (option && option.costPrice) {\n            formData.unitCost = option.costPrice;\n          }\n        },\n        detailsConfig: this.inventoryService.productDetailsConfig, infoMessage: 'Product being purchased'\n      },\n      { name: 'quantity', type: 'number', required: true, alias: 'Quantity', section: 'quickPurchaseItem',\n        hidden: x => x.multipleProducts === true, infoMessage: 'Number of units purchased'\n      },\n      { name: 'unitCost', type: 'money', required: true, alias: 'Unit Cost', section: 'quickPurchaseItem',\n        hidden: x => x.multipleProducts === true, infoMessage: 'Cost per unit'\n      },\n\n      { name: 'totals', type: 'section', alias: 'Totals', hideOnCreate: true, collapseOnView: true },\n      { name: 'totalAmount', type: 'money', alias: 'Total Amount', readonly: true, serverOwned: true, section: 'totals', infoMessage: 'Total value of all items' }, // Changed (CFW-1): Purchase.TotalAmount carries [ServerOwned] and is recomputed by PurchasesController.CalculateTotalAmount on both write paths\n      { name: 'dueDate', type: 'date', alias: 'Due Date', readonly: true, section: 'totals', hidden: (x: any) => x.timing !== 1, infoMessage: 'Payment due date (auto-set to purchase date + 30 days)' }, // Changed: receipt date → purchase date\n      { name: 'outstandingAmount', type: 'money', alias: 'Outstanding', readonly: true, section: 'totals', hidden: (x: any) => x.timing !== 1, infoMessage: 'Amount still owed to supplier' },\n\n      { name: 'additionalInfo', type: 'section', alias: 'Additional Information', collapseOnView: true },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'additionalInfo', infoMessage: 'Additional notes about this purchase' }, // Changed: receipt → purchase\n      { name: 'supplierInvoiceNumber', type: 'text', alias: 'Supplier Invoice #', section: 'additionalInfo', infoMessage: 'Invoice number from supplier' },\n      { name: 'supplierFiscalInvoiceNumber', type: 'text', alias: 'Fiscal Invoice #', section: 'additionalInfo', infoMessage: 'Fiscal (tax) invoice number — required as input-VAT evidence' }, // Added: Phase 2 compliance\n      { name: 'supplierFiscalInvoiceDate', type: 'date', max: 'today', alias: 'Fiscal Invoice Date', section: 'additionalInfo', infoMessage: 'Date on the supplier fiscal invoice' }, // Added: Phase 2 compliance // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n    ],\n    loadAction: { url: 'purchases/id' }, // Changed: inventoryreceipts → purchases\n    heroField: 'purchaseID' // Changed: inventoryReceiptID → purchaseID\n  }\n\n\n  // Changed: Renamed from inventoryReceiptEditButton to purchaseEditButton\n  purchaseEditButton: Button =\n  { name: 'edit', dialog: true,\n    action: { url: 'purchases?action=edit', method: 'post' }, // Changed: inventoryreceipts → purchases\n    visible: (x: any) => x.status !== PurchaseStatus.Completed // Changed: InventoryReceiptStatus → PurchaseStatus\n  }\n\n  // Changed: Renamed from inventoryReceiptCompleteButton to purchaseCompleteButton\n  purchaseCompleteButton: Button =\n    { name: 'complete', display: 'Complete Purchase', inDialog: true, // Changed: \"Complete Receipt\" → \"Complete Purchase\"\n      icon: { name: 'check_circle', color: 'green' },\n      action: { url: 'purchases?action=complete', method: 'post', successMessage: 'Purchase Completed' }, // Changed: inventoryreceipts → purchases, \"Receipt Completed\" → \"Purchase Completed\"\n      confirm: { message: 'Complete this purchase? Inventory will be updated and purchase will become read-only.' }, // Changed: receipt → purchase\n      visible: (x: any) => x.status !== PurchaseStatus.Completed // Changed: InventoryReceiptStatus → PurchaseStatus\n    }\n\n  // Changed: Renamed from inventoryReceiptStepConfig to purchaseStepConfig\n  purchaseStepConfig: StepConfig = {\n    valueField: 'status',\n    sticky: true,\n    steps: [\n      { name: 'Draft', value: PurchaseStatus.Draft, icon: 'article' }, // Changed: InventoryReceiptStatus → PurchaseStatus\n      { name: 'Confirmed', value: PurchaseStatus.Confirmed, icon: 'inventory_2' }, // Changed: \"Receiving\" → \"Confirmed\"\n      { name: 'Completed', value: PurchaseStatus.Completed, icon: 'check_circle' } // Changed: InventoryReceiptStatus → PurchaseStatus\n    ]\n  }\n\n  // Changed: Renamed from inventoryReceiptDetailsConfig to purchaseDetailsConfig\n  purchaseDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.purchaseFormConfig, // Changed: inventoryReceiptFormConfig → purchaseFormConfig\n    tableConfigs: [this.purchaseItemsTableConfig], // Changed: inventoryReceiptItemsTableConfig → purchaseItemsTableConfig\n    heroField: 'purchaseID', // Changed: inventoryReceiptID → purchaseID\n    stepConfig: this.purchaseStepConfig, // Changed: inventoryReceiptStepConfig → purchaseStepConfig\n    buttons: [this.purchaseEditButton, this.purchaseCompleteButton] // Changed: inventoryReceiptEditButton → purchaseEditButton, etc.\n  }\n\n  // Changed: Renamed from inventoryReceiptViewButton to purchaseViewButton\n  purchaseViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.purchaseDetailsConfig }\n  // Changed: Renamed from inventoryQuickPurchaseButton\n  quickPurchaseButton: Button = { name: 'create', display: 'Quick Purchase', dialog: true, action: { url: 'purchases?action=create', method: 'post' } }; // Changed: inventoryreceipts → purchases\n\n  // Changed: Renamed from inventoryReceiptsTableConfig to purchasesTableConfig\n  purchasesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['purchaseNumber', 'supplierName', 'purchaseDate'], // Changed: receiptNumber → purchaseNumber, receiptDate → purchaseDate\n    columns: [\n      { name: 'purchaseDate', type: 'date', alias: 'Date' }, // Changed: receiptDate → purchaseDate\n      { name: 'supplierName', type: 'text', alias: 'Supplier' },\n      { name: 'detailsDisplay', type: 'text', alias: 'Details' }, // Changed: Renamed from productsDisplay/Products\n      { name: 'timingName', type: 'text', alias: 'Payment' },\n      { name: 'status', type: 'icon', alias: 'Status', detailsConfig: this.purchaseDetailsConfig, // Changed: inventoryReceiptDetailsConfig → purchaseDetailsConfig\n        icons: [\n          { name: 'article', color: '#9E9E9E', condition: (x: any) => x.status === PurchaseStatus.Draft, tip: 'Draft' }, // Changed: InventoryReceiptStatus → PurchaseStatus\n          { name: 'inventory_2', color: '#2196F3', condition: (x: any) => x.status === PurchaseStatus.Confirmed, tip: 'Confirmed' }, // Changed: Receiving → Confirmed\n          { name: 'check_circle', color: '#4CAF50', condition: (x: any) => x.status === PurchaseStatus.Completed, tip: 'Completed' } // Changed: InventoryReceiptStatus → PurchaseStatus\n        ]\n      },\n\n      { name: 'totalAmount', type: 'money', alias: 'Total Value' },\n      { name: 'outstandingAmount', type: 'money', alias: 'Outstanding', hidden: (x: any) => x?.timing !== 1 }\n    ],\n    buttons: [\n      { name: 'view', icon: { name: 'launch' }, dialog: true, detailsConfig: this.purchaseDetailsConfig }, // Changed: inventoryReceiptDetailsConfig → purchaseDetailsConfig\n      this.quickPurchaseButton, // Changed: inventoryQuickPurchaseButton → quickPurchaseButton\n      { name: 'delete', dialog: true, icon: { name: 'delete_forever', color: 'red' }, action: { url: 'purchases?action=delete', method: 'post' }, confirm: { message: 'CAUTION: Deleting this purchase will reverse all inventory additions, any sales of this inventory, and all related accounting transactions. This action cannot be undone. Are you sure you want to proceed?' } }, // Changed: inventoryreceipts → purchases, \"receipt\" → \"purchase\"\n    ],\n    loadAction: { url: 'purchases/all/x' }, // Changed: inventoryreceipts → purchases\n    formConfig: this.purchaseFormConfig, // Changed: inventoryReceiptFormConfig → purchaseFormConfig\n    pagination: { pageSize: 15 }, // Added: server-side pagination — purchases are wide money rows (supplier join, line totals, payments)\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added: offline capture — purchases are captured as goods arrive, often at the gate\n    entityName: 'Purchase', // Changed: \"InventoryReceipt\" → \"Purchase\"\n  }\n\n  //--------------------------Receipts (Goods Confirmation)-------------------------\n\n  // Added: Receipt item form for goods received\n  receiptItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReceipts] }, // Added: gate receipt item form by purchasing cap (parent)\n    title: 'Receipt Item',\n    fixedTitle: true,\n    fields: [\n      { name: 'purchaseItemID', type: 'select', alias: 'Purchase Item', required: true, loadAction: { url: 'purchaseitems/list/x' } },\n      { name: 'productID', type: 'select', alias: 'Product', required: true, span: true, loadAction: { url: 'products/list/x' }, detailsConfig: this.inventoryService.productDetailsConfig },\n      { name: 'receivedQuantity', type: 'number', alias: 'Received Qty', required: true },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost', required: true },\n      { name: 'serialNumbers', type: 'text', alias: 'Serial Numbers (comma-separated)' }\n    ],\n    loadAction: { url: 'receiptitems/id' }\n  }\n\n  // Added: Receipt items table — shows what was physically received\n  receiptItemsTableConfig: TableConfig = {\n    tabTitle: 'Items',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'productName', type: 'text', alias: 'Product' },\n      { name: 'receivedQuantity', type: 'number', alias: 'Received' },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost' },\n      { name: 'lineTotal', type: 'money', alias: 'Line Total' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Item', dialog: true, action: { url: 'receiptitems?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'receiptitems?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'receiptitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'receiptitems/x/x' }, loadCriteria: 'receipt', loadIDField: 'receiptID',\n    formConfig: this.receiptItemFormConfig\n  }\n\n  // Added: Receipt form for goods confirmation\n  receiptFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReceipts] }, // Added: gate receipt form by purchasing cap\n    title: 'Receipt',\n    fixedTitle: true,\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'receiptInfo', type: 'section', alias: 'Receipt Information' },\n      { name: 'purchaseID', type: 'number', hidden: true },\n      { name: 'receiptNumber', type: 'text', alias: 'Receipt #', readonly: true, hideOnCreate: true, section: 'receiptInfo' },\n      { name: 'purchaseNumber', type: 'text', alias: 'Purchase #', readonly: true, section: 'receiptInfo' },\n      { name: 'supplierName', type: 'text', alias: 'Supplier', readonly: true, section: 'receiptInfo' },\n      { name: 'receivedDate', type: 'date', max: 'today', required: true, alias: 'Received Date', section: 'receiptInfo' }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'statusName', type: 'text', alias: 'Status', readonly: true, hideOnCreate: true, section: 'receiptInfo' },\n      { name: 'notes', type: 'text', alias: 'Notes', span: true, section: 'receiptInfo' }\n    ],\n    loadAction: { url: 'receipts/id' },\n    heroField: 'receiptID'\n  }\n\n  // Added: Receipt complete button\n  receiptCompleteButton: Button = { name: 'complete', display: 'Complete Receipt', inDialog: true, icon: { name: 'check_circle', color: 'green' }, action: { url: 'receipts?action=complete', method: 'post', successMessage: 'Receipt Completed — Inventory Updated' }, confirm: { message: 'Complete this receipt? Inventory will be increased.' }, visible: (x: any) => x.statusName === 'Draft' }\n\n  // Added: Receipt edit button\n  receiptEditButton: Button = { name: 'edit', dialog: true, action: { url: 'receipts?action=edit', method: 'post' }, visible: (x: any) => x.statusName === 'Draft' }\n\n  // Added: Receipt details dialog with items table and complete button\n  receiptDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.receiptFormConfig,\n    tableConfigs: [this.receiptItemsTableConfig],\n    heroField: 'receiptID',\n    buttons: [this.receiptEditButton, this.receiptCompleteButton]\n  }\n\n  // Added: Receipt view button\n  receiptViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.receiptDetailsConfig }\n\n  // Added: Receipts table — shows goods receipts for a purchase (tab in purchase details)\n  // Changed (WS-1 sweep 2): now OFFLINE. The earlier skip here blamed the read registry — one url per entity, so only the first purchase opened in a session could match. That gap is closed (read PREFIXes, ng-space 1e04b17): `loadCriteria: 'purchase'` registers the stem `receipts/purchase/`, so every parent matches and each keeps its own cache entry. Receipting is a receiving-bay act away from a desk and Receipt IS ISync, so it qualifies on merit now the mechanism exists.\n  // Still NOT paginated, and that is separate from offline: one purchase carries a handful of receipts, so paging would cost a round trip and buy nothing.\n  receiptsTableConfig: TableConfig = {\n    tabTitle: 'Receipts',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'receiptNumber', type: 'text', alias: 'Receipt #' },\n      { name: 'receivedDate', type: 'date', alias: 'Received' },\n      { name: 'statusName', type: 'chip', alias: 'Status', colors: [{ name: '#E0E0E0', condition: x => x.statusName === 'Draft' }, { name: '#C8E6C9', condition: x => x.statusName === 'Completed' }] },\n      { name: 'detailsDisplay', type: 'text', alias: 'Details' } // Changed: Renamed from productsDisplay/Products\n    ],\n    buttons: [\n      { name: 'create', display: 'New Receipt', dialog: true, action: { url: 'receipts?action=create', method: 'post' } },\n      { name: 'view', dialog: true, detailsConfig: this.receiptDetailsConfig },\n      { name: 'delete', dialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'receipts?action=delete', method: 'post' }, confirm: { message: 'Delete this receipt? Inventory changes will be reversed.' } }\n    ],\n    loadAction: { url: 'receipts/x/x' }, loadCriteria: 'purchase', loadIDField: 'purchaseID',\n    offline: { enabled: true, queue: { create: true, edit: true } }, // Added (WS-1 sweep 2): create/edit queue to the outbox; delete stays false (library default) because deleting a receipt reverses inventory server-side. `Complete` is a workflow action (`receipts?action=complete`) and matchMutation only parses create|edit|delete, so completing a receipt stays online-only\n    formConfig: this.receiptFormConfig\n  }\n\n  //--------------------------Supplier Payments-------------------------\n\n  supplierPaymentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capInventoryReceipts] },\n    title: 'Record Payment',\n    fixedTitle: true,\n    fields: [\n      { name: 'purchaseID', type: 'number', hidden: true }, // Changed: inventoryReceiptID → purchaseID\n      { name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true }, // Changed (NFD-2, Arbiter 2026-08-19): max: 'today' REMOVED — deliberately uncapped. A payment may legitimately carry a future date (post-dated cheque), so the future IS a valid answer here. Not method-conditioned: uncapped for every payment method.\n      { name: 'method', type: 'select', alias: 'Payment Method', required: true, defaultValue: 2, loadAction: { url: 'supplierpayments/list/methods' } },\n      { name: 'currencyID', type: 'select', alias: 'Currency', loadAction: { url: 'currencies/list/x' }, defaultFirstValue: true, detailsConfig: this.accountingService.currencyDetailsConfig, infoMessage: 'Currency for this payment (defaults to base currency)' }, // Changed: dropdown quick-add\n      { name: 'outstandingAmount', type: 'text', alias: 'Outstanding', readonly: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text. spa-label rendered this through its DEFAULT branch (no format/suffix/size declared), which is {{value}} plain — identical to what spa-text shows — so the on-screen value is unchanged and only the field style differs.\n      { name: 'amount', type: 'money', alias: 'Amount', required: true, span: true },\n      { name: 'reference', type: 'text', alias: 'Reference', span: true }\n    ],\n  }\n\n  supplierPaymentCreateButton: Button = { name: 'edit', action: { url: 'supplierpayments?action=create', method: 'post', successMessage: 'Payment Recorded' } }\n\n  supplierPaymentCreateDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.supplierPaymentFormConfig,\n    heroField: 'purchaseID', // Changed: inventoryReceiptID → purchaseID\n    mode: 'edit',\n    seedDefaults: true, // Added: CAPTURE dialog on mode:'edit' (posts supplierpayments?action=create). This is the one payment dialog where the flag actually DOES something: unlike Invoices and Sales, PurchasesController projects no payment defaults (only PaymentType), so `method` genuinely arrives empty and defaultValue:2 finally renders\n    buttons: [this.supplierPaymentCreateButton]\n  }\n\n  supplierRecordPaymentButton: Button = { name: 'record-payment', display: 'Record Payment', dialog: true, icon: { name: 'payment', color: 'blue' },\n    detailsConfig: this.supplierPaymentCreateDetailsConfig,\n    visible: (x: any) => x.timing === 1 && x.status === PurchaseStatus.Completed && x.outstandingAmount > 0 // Changed: InventoryReceiptStatus → PurchaseStatus\n  }\n\n  // Changed (WS-1 sweep 2): still NOT offline and still NOT paginated, but the read-registry gap is no longer the reason — that is closed. It is skipped now because this table has NOTHING TO QUEUE: its only button is a void, which is a server-side ledger reversal, and payments are recorded from the parent purchase row (supplierRecordPaymentButton), not from here. Paging is omitted separately: a purchase carries only a few payments.\n  supplierPaymentsTableConfig: TableConfig = {\n    tabTitle: 'Payments',\n    hidden: (x: any) => x.timing !== 1, // Changed: Hide Payments tab for Immediate purchases (only show for Deferred/Credit)\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'paymentDate', type: 'date', alias: 'Date' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'methodName', type: 'text', alias: 'Method' },\n      { name: 'reference', type: 'text', alias: 'Reference' }\n    ],\n    buttons: [\n      { name: 'delete', dialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'supplierpayments?action=delete', method: 'post' }, confirm: { message: 'Void this payment? The accounting transaction will be reversed.' } }\n    ],\n    loadAction: { url: 'supplierpayments/x/x' }, loadCriteria: 'purchase', loadIDField: 'purchaseID', // Changed: receipt → purchase, inventoryReceiptID → purchaseID\n    formConfig: this.supplierPaymentFormConfig\n  }\n\n  //--------------------------AP Aging Report-------------------------\n\n  apAgingTileConfig: TileConfig = {\n    tiles: [\n      { name: 'current', alias: 'Current', color: '#4CAF50', icon: 'check_circle', info: 'Not yet due' },\n      { name: 'days30', alias: '1-30 Days', color: '#FFC107', icon: 'schedule', info: '1-30 days overdue' },\n      { name: 'days60', alias: '31-60 Days', color: '#FF9800', icon: 'warning', info: '31-60 days overdue' },\n      { name: 'days90', alias: '61-90 Days', color: '#F44336', icon: 'error', info: '61-90 days overdue' },\n      { name: 'days90Plus', alias: '90+ Days', color: '#B71C1C', icon: 'dangerous', info: 'Over 90 days overdue' },\n      { name: 'total', alias: 'Total Outstanding', color: '#9E9E9E', icon: 'account_balance_wallet', info: 'Total outstanding amount' }\n    ],\n  }\n\n  apAgingBaseTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['purchaseNumber', 'supplierName', 'outstandingAmount'], // Changed: receiptNumber → purchaseNumber\n    columns: [\n      { name: 'purchaseNumber', type: 'text', alias: 'Purchase #', detailsConfig: this.purchaseDetailsConfig }, // Changed: receiptNumber → purchaseNumber, inventoryReceiptDetailsConfig → purchaseDetailsConfig\n      { name: 'supplierName', type: 'text', alias: 'Supplier' },\n      { name: 'purchaseDate', type: 'date', alias: 'Purchase Date' }, // Changed: receiptDate → purchaseDate\n      { name: 'dueDate', type: 'date', alias: 'Due Date' },\n      { name: 'daysOverdue', type: 'number', alias: 'Days Overdue' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'paidAmount', type: 'money', alias: 'Paid' },\n      { name: 'outstandingAmount', type: 'money', alias: 'Outstanding' }\n    ],\n    buttons: [\n      { name: 'view', dialog: true, detailsConfig: this.purchaseDetailsConfig }, // Changed: inventoryReceiptDetailsConfig → purchaseDetailsConfig\n      this.supplierRecordPaymentButton,\n    ]\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, DetailsDialogConfig, Button, TableConfig } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\nimport { InventoryService } from './inventory.service';\n\n// Service for managing production/manufacturing configurations\n@Injectable({\n  providedIn: 'root'\n})\nexport class ProductionService {\n\n  private dataService = inject(DataServiceLib);\n  private inventoryService = inject(InventoryService);\n\n  // ==================== PRODUCTION RECIPES ====================\n\n  recipeItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capProductionRecipes] }, // Added: gate recipe item form by production recipes cap (parent entity)\n    title: 'Recipe Item',\n    fixedTitle: true,\n    fields: [\n      { name: 'productionRecipeItemID', type: 'number', alias: 'ID', hidden: true },\n      { name: 'productionRecipeID', type: 'number', alias: 'Recipe ID', hidden: true },\n      { name: 'rawMaterialProductID', type: 'select', alias: 'Raw Material', required: true, loadAction: { url: 'products/list/x' }, detailsConfig: this.inventoryService.productDetailsConfig },\n      { name: 'requiredQuantity', type: 'number', alias: 'Required Quantity', required: true }\n    ],\n    loadAction: { url: 'productionrecipeitems/id' },\n    heroField: 'productionRecipeItemID'\n  }\n\n  recipeItemsTableConfig: TableConfig = {\n    tabTitle: 'Materials',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    minColumns: ['rawMaterialName', 'requiredQuantity', 'estimatedCost'],\n    columns: [\n      { name: 'rawMaterialName', type: 'text', alias: 'Raw Material' },\n      { name: 'requiredQuantity', type: 'number', alias: 'Quantity' },\n      { name: 'estimatedCost', type: 'money', alias: 'Est. Cost' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Material', dialog: true, action: { url: 'productionrecipeitems?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'productionrecipeitems?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'productionrecipeitems?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'productionrecipeitems/x/x' }, loadCriteria: 'recipe', loadIDField: 'productionRecipeID',\n    formConfig: this.recipeItemFormConfig\n  }\n\n  recipeFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capProductionRecipes] },\n    title: 'Production Recipe',\n    fixedTitle: true,\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'productionRecipeID', type: 'number', alias: 'Recipe ID', hidden: true },\n      { name: 'recipeInfo', type: 'section', alias: 'Recipe Information' },\n      { name: 'finishedProductID', type: 'select', alias: 'Finished Product', required: true, section: 'recipeInfo', loadAction: { url: 'products/list/x' }, detailsConfig: this.inventoryService.productDetailsConfig },\n      { name: 'recipeName', type: 'text', alias: 'Recipe Name', required: true, section: 'recipeInfo' },\n      { name: 'yieldQuantity', type: 'number', alias: 'Yield Quantity', required: true, section: 'recipeInfo' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', section: 'recipeInfo' },\n      { name: 'notes', type: 'text', alias: 'Notes', nullable: true, span: true, section: 'recipeInfo' },\n      { name: 'costInfo', type: 'section', alias: 'Cost Information', collapsed: true, hideOnCreate: true },\n      { name: 'estimatedCost', type: 'money', alias: 'Total Cost', readonly: true, section: 'costInfo' },\n      { name: 'estimatedCostPerUnit', type: 'money', alias: 'Cost Per Unit', readonly: true, section: 'costInfo' }\n    ],\n    loadAction: { url: 'productionrecipes/id' },\n    heroField: 'productionRecipeID'\n  }\n\n  recipeDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.recipeFormConfig,\n    heroField: 'productionRecipeID',\n    tableConfigs: [this.recipeItemsTableConfig],\n    buttons: [\n      { name: 'edit', dialog: true, action: { url: 'productionrecipes?action=edit', method: 'post' } }\n    ]\n  }\n\n  recipeViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.recipeDetailsConfig }\n  recipeCreateButton: Button = { name: 'create', display: 'Create Recipe', dialog: true, \n    action: { url: 'productionrecipes?action=create', method: 'post' },\n    onSuccessButton: this.recipeViewButton\n  }\n\n  recipesTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['recipeName', 'finishedProductName', 'yieldQuantity'],\n    flatButtons: true,\n    columns: [\n      { name: 'productionRecipeID', type: 'number', alias: 'ID' },\n      { name: 'recipeName', type: 'text', alias: 'Recipe Name' },\n      { name: 'finishedProductName', type: 'text', alias: 'Finished Product' },\n      { name: 'yieldQuantity', type: 'number', alias: 'Yield' },\n      { name: 'estimatedCost', type: 'money', alias: 'Est. Cost' },\n      { name: 'estimatedCostPerUnit', type: 'money', alias: 'Cost/Unit' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' }\n    ],\n    buttons: [\n      this.recipeCreateButton,\n      this.recipeViewButton,\n      { name: 'delete', dialog: true, action: { url: 'productionrecipes?action=delete', method: 'post' } }\n    ],\n    loadAction: { url: 'productionrecipes/all/x' },\n    formConfig: this.recipeFormConfig,\n    realTime: true,\n    entityName: 'ProductionRecipe'\n  }\n\n  // ==================== PRODUCTION ORDERS ====================\n\n  orderItemFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capProductionOrders] }, // Added: gate order item form by production orders cap (parent entity)\n    title: 'Order Item',\n    fixedTitle: true,\n    fields: [\n      { name: 'productionOrderItemID', type: 'number', alias: 'ID', hidden: true },\n      { name: 'productionOrderID', type: 'number', alias: 'Order ID', hidden: true },\n      { name: 'rawMaterialProductID', type: 'number', alias: 'Raw Material ID', hidden: true },\n      { name: 'rawMaterialName', type: 'text', alias: 'Raw Material', readonly: true },\n      { name: 'requiredQuantity', type: 'number', alias: 'Required', readonly: true },\n      { name: 'allocatedQuantity', type: 'number', alias: 'Allocated', readonly: true },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost', readonly: true },\n      { name: 'totalCost', type: 'money', alias: 'Total Cost', readonly: true }\n    ],\n    loadAction: { url: 'productionorderitems/id' },\n    heroField: 'productionOrderItemID'\n  }\n\n  orderItemsTableConfig: TableConfig = {\n    tabTitle: 'Materials Used',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    minColumns: ['rawMaterialName', 'allocatedQuantity', 'totalCost'],\n    columns: [\n      { name: 'rawMaterialName', type: 'text', alias: 'Raw Material' },\n      { name: 'requiredQuantity', type: 'number', alias: 'Required' },\n      { name: 'allocatedQuantity', type: 'number', alias: 'Allocated' },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost' },\n      { name: 'totalCost', type: 'money', alias: 'Total Cost' }\n    ],\n    buttons: [\n      { name: 'view', dialog: true }\n    ],\n    loadAction: { url: 'productionorderitems/x/x' }, loadCriteria: 'order', loadIDField: 'productionOrderID',\n    formConfig: this.orderItemFormConfig\n  }\n\n  orderFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capProductionOrders] },\n    title: 'Production Order',\n    fixedTitle: true,\n    alertConfig: {\n      compact: true,\n      sticky: true,\n      messages: [\n        { message: 'Click Complete to process production and consume materials', type: 'success',  // Changed: content to message\n          visible: (x: any) => x.statusName === 'Draft'\n        }\n      ]\n    },\n    multiColumn: true,\n    includeAudit: true,\n    fields: [\n      { name: 'productionOrderID', type: 'number', alias: 'Order ID', hidden: true },\n      { name: 'orderInfo', type: 'section', alias: 'Order Information' },\n      { name: 'productionOrderNumber', type: 'text', alias: 'Order Number', readonly: true, section: 'orderInfo', hideOnCreate: true },\n      { name: 'productionRecipeID', type: 'select', alias: 'Recipe', required: true, section: 'orderInfo', loadAction: { url: 'productionrecipes/list/x' }, detailsConfig: this.recipeDetailsConfig },\n      { name: 'plannedQuantity', type: 'number', alias: 'Planned Quantity', required: true, section: 'orderInfo' },\n      { name: 'productionDate', type: 'date', alias: 'Production Date', required: true, section: 'orderInfo' },\n      { name: 'notes', type: 'text', alias: 'Notes', nullable: true, span: true, section: 'orderInfo' },\n      { name: 'statusInfo', type: 'section', alias: 'Status', collapsed: true, hideOnCreate: true },\n      { name: 'statusName', type: 'text', alias: 'Status', readonly: true, section: 'statusInfo' },\n      { name: 'actualQuantity', type: 'number', alias: 'Actual Quantity', readonly: true, section: 'statusInfo' },\n      { name: 'totalCost', type: 'money', alias: 'Total Cost', readonly: true, section: 'statusInfo' }\n    ],\n    loadAction: { url: 'productionorders/id' },\n    heroField: 'productionOrderID'\n  }\n\n  orderDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.orderFormConfig,\n    heroField: 'productionOrderID',\n    tableConfigs: [this.orderItemsTableConfig],\n    buttons: [\n      { name: 'edit', dialog: true, action: { url: 'productionorders?action=edit', method: 'post' }, visible: (x: any) => x.statusName === 'Draft' },\n      { name: 'complete', display: 'Complete', icon: { name: 'check', color: 'green' }, inDialog: true, dialog: true, \n        action: { url: 'productionorders?action=complete', method: 'post', successMessage: 'Production order completed successfully' }, \n        confirm: { message: 'Complete this production order? Materials will be consumed and finished goods will be added to inventory.' },\n        visible: (x: any) => x.statusName === 'Draft' \n      },\n      { name: 'cancel', display: 'Cancel', icon: { name: 'close', color: 'red' }, inDialog: true, dialog: true, \n        action: { url: 'productionorders?action=cancel', method: 'post', successMessage: 'Production order cancelled' }, \n        confirm: { message: 'Cancel this production order?' },\n        visible: (x: any) => x.statusName === 'Draft' \n      }\n    ]\n  }\n\n  orderViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.orderDetailsConfig }\n  orderCreateButton: Button = { name: 'create', display: 'Create Order', dialog: true, \n    action: { url: 'productionorders?action=create', method: 'post' },\n    onSuccessButton: this.orderViewButton\n  }\n\n  // Added (WS-1 sweep 2): paginated but deliberately NOT offline — ProductionOrder does not implement ISync, so a queued write has no sync tokens. A shop-floor offline case is arguable, but enabling it needs a migration in the owning context, not a config line. Same for recipes and both item tabs in this file.\n  ordersTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['productionOrderNumber', 'finishedProductName', 'plannedQuantity'],\n    flatButtons: true,\n    columns: [\n      { name: 'productionOrderID', type: 'number', alias: 'ID' },\n      { name: 'productionOrderNumber', type: 'text', alias: 'Order #' },\n      { name: 'recipeName', type: 'text', alias: 'Recipe' },\n      { name: 'finishedProductName', type: 'text', alias: 'Product' },\n      { name: 'plannedQuantity', type: 'number', alias: 'Planned' },\n      { name: 'actualQuantity', type: 'number', alias: 'Actual' },\n      { name: 'productionDate', type: 'date', alias: 'Date' },\n      { name: 'totalCost', type: 'money', alias: 'Total Cost' },\n      { name: 'unitCost', type: 'money', alias: 'Unit Cost' },\n      { name: 'statusName', type: 'icon', alias: 'Status', \n        icons: [\n          { name: 'edit', color: 'primary', condition: (x: any) => x.statusName === 'Draft', tip: 'Draft' }, \n          { name: 'check_circle', color: 'green', condition: (x: any) => x.statusName === 'Completed', tip: 'Completed' }, \n          { name: 'cancel', color: 'red', condition: (x: any) => x.statusName === 'Cancelled', tip: 'Cancelled' }\n        ] \n      }\n    ],\n    buttons: [\n      this.orderCreateButton,\n      this.orderViewButton,\n      { name: 'delete', dialog: true, action: { url: 'productionorders?action=delete', method: 'post' }, visible: (x: any) => x.statusName === 'Draft' }\n    ],\n    loadAction: { url: 'productionorders/all/x' },\n    formConfig: this.orderFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — production orders append continuously\n    entityName: 'ProductionOrder',\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, TableConfig, Button, DetailsDialogConfig } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class PayrollService {\n\n  private dataService = inject(DataServiceLib);\n\n  //--------------------------Salary Components (child of SalaryStructure)-------------------------\n\n  salaryComponentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSalaryStructures] }, // Added: gate salary component form by salary structures cap (parent module)\n    title: 'Salary Component',\n    fixedTitle: true,\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'componentType', alias: 'Type', type: 'select', loadAction: { url: 'salarycomponents/list/component-type' }, required: true },\n      { name: 'calculationMethod', alias: 'Calculation', type: 'select', loadAction: { url: 'salarycomponents/list/calculation-method' }, required: true },\n      { name: 'sortOrder', alias: 'Sort Order', type: 'number', defaultValue: 0 },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true },\n    ],\n    loadAction: { url: 'salarycomponents/id' },\n    heroField: 'salaryComponentID',\n  }\n\n  salaryComponentsTableConfig: TableConfig = {\n    tabTitle: 'Components',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'text' },\n      { name: 'componentTypeName', type: 'text', alias: 'Type' },\n      { name: 'calculationMethodName', type: 'text', alias: 'Calculation' },\n      { name: 'sortOrder', type: 'text', alias: 'Order' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'salarycomponents?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'salarycomponents?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'salarycomponents?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'salarycomponents/x/x' }, loadCriteria: 'structure', loadIDField: 'salaryStructureID',\n    formConfig: this.salaryComponentFormConfig,\n  }\n\n  //--------------------------Salary Structures-------------------------\n\n  editSalaryStructureButton: Button = { name: 'edit', dialog: true, inDialog: true, action: { url: 'salarystructures?action=edit', method: 'post' } };\n\n  salaryStructureFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSalaryStructures] }, // Added: gate salary structure form by salary structures cap\n    title: 'Salary Structure',\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'description', type: 'text-area', rows: 2, span: true },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true },\n    ],\n    loadAction: { url: 'salarystructures/id' },\n    heroField: 'salaryStructureID',\n    includeAudit: true,\n  }\n\n  salaryStructuresTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'componentCount', 'employeeCount'],\n    columns: [\n      { name: 'name', type: 'text' },\n      { name: 'description', type: 'text' },\n      { name: 'componentCount', type: 'text', alias: 'Components' },\n      { name: 'employeeCount', type: 'text', alias: 'Employees' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'salarystructures?action=create', method: 'post' } },\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.salaryStructureFormConfig,\n          heroField: 'salaryStructureID',\n          buttons: [this.editSalaryStructureButton],\n          tableConfigs: [this.salaryComponentsTableConfig],\n        }\n      },\n      { name: 'edit', dialog: true, action: { url: 'salarystructures?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'salarystructures?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'salarystructures/all/x' },\n    formConfig: this.salaryStructureFormConfig,\n    realTime: true,\n    entityName: 'SalaryStructure'\n  }\n\n  //--------------------------Statutory Deduction Bands (child of StatutoryDeductionType)-------------------------\n\n  statutoryDeductionBandFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capStatutoryDeductions] }, // Added: gate statutory deduction band form by statutory deductions cap (parent)\n    title: 'Tax Band',\n    fixedTitle: true,\n    fields: [\n      { name: 'validFrom', type: 'date', alias: 'Valid From', required: true },\n      { name: 'bandMin', type: 'money', alias: 'Minimum', required: true },\n      { name: 'bandMax', type: 'money', alias: 'Maximum' },\n      { name: 'rate', type: 'number', alias: 'Rate %', required: true },\n      { name: 'fixedAmount', type: 'money', alias: 'Fixed Amount' },\n    ],\n    loadAction: { url: 'statutorydeductionbands/id' },\n    heroField: 'statutoryDeductionBandID',\n  }\n\n  statutoryDeductionBandsTableConfig: TableConfig = {\n    tabTitle: 'Tax Bands',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'validFrom', type: 'date', alias: 'Valid From' },\n      { name: 'bandMin', type: 'money', alias: 'Min' },\n      { name: 'bandMax', type: 'money', alias: 'Max' },\n      { name: 'rate', type: 'text', alias: 'Rate %' },\n      { name: 'fixedAmount', type: 'money', alias: 'Fixed Amount' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'statutorydeductionbands?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'statutorydeductionbands?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'statutorydeductionbands?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'statutorydeductionbands/x/x' }, loadCriteria: 'type', loadIDField: 'statutoryDeductionTypeID',\n    formConfig: this.statutoryDeductionBandFormConfig,\n  }\n\n  //--------------------------Statutory Deduction Types-------------------------\n\n  editStatutoryDeductionTypeButton: Button = { name: 'edit', dialog: true, inDialog: true, action: { url: 'statutorydeductiontypes?action=edit', method: 'post' } };\n\n  statutoryDeductionTypeFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capStatutoryDeductions] }, // Added: gate statutory deduction type form by statutory deductions cap\n    title: 'Statutory Deduction Type',\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'category', type: 'select', loadAction: { url: 'statutorydeductiontypes/list/deduction-category' }, required: true },\n      { name: 'referencedDeductionTypeID', alias: 'Referenced Deduction', type: 'select', loadAction: { url: 'statutorydeductiontypes/list/x' }, nullable: true, infoMessage: 'For levies calculated as % of another deduction' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true },\n    ],\n    loadAction: { url: 'statutorydeductiontypes/id' },\n    heroField: 'statutoryDeductionTypeID',\n    includeAudit: true,\n  }\n\n  statutoryDeductionTypesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['name', 'categoryName', 'bandCount'],\n    columns: [\n      { name: 'name', type: 'text' },\n      { name: 'categoryName', type: 'text', alias: 'Category' },\n      { name: 'referencedDeductionTypeName', type: 'text', alias: 'Referenced Deduction' },\n      { name: 'bandCount', type: 'text', alias: 'Bands' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'statutorydeductiontypes?action=create', method: 'post' } },\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.statutoryDeductionTypeFormConfig,\n          heroField: 'statutoryDeductionTypeID',\n          buttons: [this.editStatutoryDeductionTypeButton],\n          tableConfigs: [this.statutoryDeductionBandsTableConfig],\n        }\n      },\n      { name: 'edit', dialog: true, action: { url: 'statutorydeductiontypes?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'statutorydeductiontypes?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'statutorydeductiontypes/all/x' },\n    formConfig: this.statutoryDeductionTypeFormConfig,\n    realTime: true,\n    entityName: 'StatutoryDeductionType'\n  }\n\n  //--------------------------Payslip Lines (child of Payslip)-------------------------\n\n  payslipLineFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capPayrollRuns] }, // Added: gate payslip line form by payroll runs cap (parent)\n    title: 'Payslip Line',\n    fixedTitle: true,\n    fields: [\n      { name: 'componentName', type: 'text', alias: 'Component', required: true },\n      { name: 'componentType', alias: 'Type', type: 'select', loadAction: { url: 'salarycomponents/list/component-type' }, required: true },\n      { name: 'amount', type: 'money', alias: 'Amount', required: true },\n      { name: 'isStatutory', type: 'checkbox', alias: 'Statutory' },\n      { name: 'sortOrder', alias: 'Sort Order', type: 'number', defaultValue: 0 },\n    ],\n    loadAction: { url: 'paysliplines/id' },\n    heroField: 'payslipLineID',\n  }\n\n  payslipLinesTableConfig: TableConfig = {\n    tabTitle: 'Payslip Lines',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'componentName', type: 'text', alias: 'Component' },\n      { name: 'componentTypeName', type: 'text', alias: 'Type' },\n      { name: 'isStatutory', type: 'checkbox', alias: 'Statutory' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'sortOrder', type: 'text', alias: 'Order' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Line', dialog: true, action: { url: 'paysliplines?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'paysliplines?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'paysliplines?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'paysliplines/x/x' }, loadCriteria: 'payslip', loadIDField: 'payslipID',\n    formConfig: this.payslipLineFormConfig,\n  }\n\n  //--------------------------Payslips (child of PayrollRun, also used in employee details)-------------------------\n\n  payslipFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capPayrollRuns] }, // Added: gate payslip form by payroll runs cap (parent)\n    title: 'Payslip',\n    fixedTitle: true,\n    fields: [\n      { name: 'employeeName', alias: 'Employee', type: 'text', readonly: true },\n      { name: 'grossPay', alias: 'Gross Pay', type: 'money', readonly: true, serverOwned: true }, // Changed (CFW-1): Payslip.GrossPay carries [ServerOwned] — PayrollService.RecalculatePayslipTotals owns all three\n      { name: 'totalDeductions', alias: 'Deductions', type: 'money', readonly: true, serverOwned: true }, // Changed (CFW-1): [ServerOwned]\n      { name: 'netPay', alias: 'Net Pay', type: 'money', readonly: true, serverOwned: true }, // Changed (CFW-1): [ServerOwned]\n      { name: 'statusName', alias: 'Status', type: 'text', readonly: true },\n    ],\n    loadAction: { url: 'payslips/id' },\n    heroField: 'payslipID',\n  }\n\n  payslipsChildTableConfig: TableConfig = {\n    tabTitle: 'Payslips',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'employeeName', type: 'text', alias: 'Employee' },\n      { name: 'grossPay', type: 'money', alias: 'Gross Pay' },\n      { name: 'totalDeductions', type: 'money', alias: 'Deductions' },\n      { name: 'netPay', type: 'money', alias: 'Net Pay' },\n      { name: 'statusName', type: 'text', alias: 'Status' },\n    ],\n    buttons: [\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.payslipFormConfig,\n          heroField: 'payslipID',\n          tableConfigs: [this.payslipLinesTableConfig],\n        }\n      },\n    ],\n    loadAction: { url: 'payslips/x/x' }, loadCriteria: 'run', loadIDField: 'payrollRunID',\n    formConfig: this.payslipFormConfig,\n  }\n\n  // Employee Payslip History (child table in Employee details)\n  employeePayslipHistoryTableConfig: TableConfig = {\n    tabTitle: 'Payslip History',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'grossPay', type: 'money', alias: 'Gross Pay' },\n      { name: 'totalDeductions', type: 'money', alias: 'Deductions' },\n      { name: 'netPay', type: 'money', alias: 'Net Pay' },\n      { name: 'statusName', type: 'text', alias: 'Status' },\n    ],\n    buttons: [\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.payslipFormConfig,\n          heroField: 'payslipID',\n          tableConfigs: [this.payslipLinesTableConfig],\n        }\n      },\n    ],\n    loadAction: { url: 'payslips/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n    formConfig: this.payslipFormConfig,\n  }\n\n  //--------------------------Employee Salary Components (child of Employee)-------------------------\n\n  employeeSalaryComponentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capEmployees] }, // Added: gate employee salary component form by employees cap (parent entity)\n    title: 'Salary Component',\n    fixedTitle: true,\n    fields: [\n      { name: 'salaryComponentID', alias: 'Component', type: 'select', loadAction: { url: 'salarycomponents/list/x' }, required: true },\n      { name: 'value', type: 'money', alias: 'Value', required: true },\n    ],\n    loadAction: { url: 'employeesalarycomponents/id' },\n    heroField: 'employeeSalaryComponentID',\n  }\n\n  employeeSalaryComponentsTableConfig: TableConfig = {\n    tabTitle: 'Salary Components',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'componentName', type: 'text', alias: 'Component' },\n      { name: 'componentType', type: 'text', alias: 'Type' },\n      { name: 'calculationMethod', type: 'text', alias: 'Calculation' },\n      { name: 'value', type: 'money', alias: 'Value' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'employeesalarycomponents?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'employeesalarycomponents?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'employeesalarycomponents?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'employeesalarycomponents/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n    formConfig: this.employeeSalaryComponentFormConfig,\n  }\n\n  //--------------------------Commission Configs-------------------------\n\n  // Added (Phase 5): a commission rule is a parent with tier children, which is the two-step create shape —\n  // the create dialog captures the rule itself, then the details dialog opens with the Tiers tab. Extracted\n  // before detailsConfig so it can be referenced without a forward reference.\n  editCommissionConfigButton: Button = { name: 'edit', dialog: true, inDialog: true, action: { url: 'commissionconfigs?action=edit', method: 'post' } };\n\n  commissionConfigFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capCommissionConfigs] }, // Added: gate commission config form by commission configs cap\n    title: 'Commission Config',\n    // Added (Phase 5): the two rules that make a config silently earn nothing, said out loud rather than left to\n    // be discovered when a period pays 0.00. Both mirror refusals CommissionRuleEvaluator already makes.\n    alertConfig: {\n      compact: true,\n      messages: [\n        { message: 'This rule is scoped to nobody — set an employee, a position, or tick Applies To All Employees, or it can never resolve', type: 'critical',\n          visible: (x: any) => !!x.commissionConfigID && !x.employeeID && !x.positionID && !x.appliesToAllEmployees\n        },\n        { message: 'Per-distance rates read trip mileage, which is only captured when Tyre Management is enabled — this rule will compute 0.00 until it is', type: 'warn',\n          visible: (x: any) => x.basis === 4\n        },\n      ]\n    },\n    fields: [\n      { name: 'name', type: 'text', required: true, hint: 'How this arrangement is referred to, e.g. \"Drivers 5% of load value\"' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true },\n\n      // Changed (Phase 5): who the rule resolves to. ResolveRules is a ladder — employee rules win, then position\n      // rules, then the tenant-wide rule — and the levels do NOT stack, so only one level is offered at a time.\n      { name: 'scope', type: 'section', alias: 'Scope', collapseOnView: true },\n      { name: 'employeeID', type: 'select', alias: 'Employee', section: 'scope', nullable: true, loadAction: { url: 'employees/list/x' }, requiredCondition: (x: any) => !x.positionID && !x.appliesToAllEmployees, hint: 'Leave empty to scope by position or across the whole company' },\n      { name: 'positionID', type: 'select', alias: 'Position', section: 'scope', nullable: true, loadAction: { url: 'positions/list/x' }, hidden: (x: any) => x.employeeID > 0, hint: 'Everyone holding this position, e.g. every Driver' },\n      { name: 'appliesToAllEmployees', type: 'checkbox', alias: 'Applies To All Employees', section: 'scope', hidden: (x: any) => x.employeeID > 0 || x.positionID > 0 },\n      { name: 'priority', type: 'number', alias: 'Priority', section: 'scope', defaultValue: 0, hint: 'Higher wins when two rules resolve at the same level' },\n      { name: 'customerID', type: 'select', alias: 'Only For Customer', section: 'scope', nullable: true, loadAction: { url: 'customers/list/x' }, hideOnCreate: true },\n      { name: 'serviceItemID', type: 'select', alias: 'Only For Service', section: 'scope', nullable: true, loadAction: { url: 'serviceitems/list/x' }, hideOnCreate: true },\n      { name: 'selfSourcedOnly', type: 'checkbox', alias: 'Self Sourced Loads Only', section: 'scope', hidden: (x: any) => x.basis === 1 || x.basis === 4, infoMessage: 'Pays the person recorded as Sourced By on the load rather than the driver who carried it. Load-level bases only — a trip has no sourcer.' }, // Changed (Phase 6, browser pass): the hyphen is gone on purpose — every alias is piped through Core.camelToWords, which inserts a space before each capital, so \"Self-Sourced\" rendered as \"Self- Sourced\" on screen\n\n      // Changed (Phase 5): Basis is what the engine actually measures. MetricType below is the superseded column,\n      // kept in step so old rows stay coherent, but nothing computes from it any more.\n      { name: 'rateAndTiers', type: 'section', alias: 'Rate & Tiers' },\n      { name: 'basis', type: 'select', alias: 'Basis', section: 'rateAndTiers', required: true, defaultValue: 1, loadAction: { url: 'commissionconfigs/list/basis' },\n        onSelectChange: (value: any, data: any) => {\n          data.metricType = (value === 2 || value === 5) ? 2 : 1; // keep the superseded MetricType consistent with Basis\n          if (value === 1 || value === 4) { data.earnEvent = 1; data.selfSourcedOnly = false; } // trip-level bases: the engine skips any other earn event, and has no sourcer to pay\n        }\n      },\n      { name: 'rateType', alias: 'Rate Type', type: 'select', section: 'rateAndTiers', loadAction: { url: 'commissionconfigs/list/rate-type' }, required: true },\n      { name: 'rate', type: 'number', alias: 'Rate', section: 'rateAndTiers', required: true, suffix: '%', hidden: (x: any) => x.rateType !== 2, hint: 'Percentage of the measured value. Used for any part of the metric no tier band covers.' },\n      { name: 'rate', type: 'number', alias: 'Rate', section: 'rateAndTiers', required: true, hidden: (x: any) => x.rateType === 2, hint: 'Amount per unit measured. Used for any part of the metric no tier band covers.' },\n      { name: 'metricType', type: 'select', hidden: true, defaultValue: 1 }, // superseded by Basis; posted only so existing rows keep a valid legacy value\n\n      // Changed (Phase 5): hidden on create because a money input cannot post \"empty\" — it posts 0, and a Maximum\n      // of 0 caps every period to nothing. Set deliberately on the saved rule instead of by accident on a new one.\n      { name: 'limits', type: 'section', alias: 'Limits', collapseOnView: true, hideOnCreate: true },\n      { name: 'minimumAmount', type: 'money', alias: 'Minimum Per Period', section: 'limits', hideOnCreate: true, clearContent: true, hint: 'Guaranteed floor. Leave empty for none.' },\n      { name: 'maximumAmount', type: 'money', alias: 'Maximum Per Period', section: 'limits', hideOnCreate: true, clearContent: true, hint: 'Cap. Leave empty for uncapped — a cap of 0 pays nothing.' },\n\n      // Changed (Phase 5): same reason — a date input posts today, and an Effective From of today silently drops\n      // every load earned earlier in the same month.\n      { name: 'timing', type: 'section', alias: 'Timing', collapseOnView: true },\n      { name: 'earnEvent', alias: 'Earned When', type: 'select', section: 'timing', required: true, defaultValue: 1, loadAction: { url: 'commissionconfigs/list/earn-event' }, readonlyCondition: (x: any) => x.basis === 1 || x.basis === 4, hint: 'Trip-level bases earn on completion only' },\n      { name: 'effectiveFrom', type: 'date', alias: 'Effective From', section: 'timing', hideOnCreate: true, clearContent: true, hint: 'Empty means the rule has always applied. Work before this date is excluded.' },\n      { name: 'effectiveTo', type: 'date', alias: 'Effective To', section: 'timing', hideOnCreate: true, clearContent: true, hint: 'Empty means the rule is open-ended' },\n    ],\n    loadAction: { url: 'commissionconfigs/id' },\n    heroField: 'commissionConfigID',\n    includeAudit: true,\n  }\n\n  //--------------------------Commission Config Tiers (child of CommissionConfig)-------------------------\n\n  commissionConfigTierFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capCommissionConfigs] }, // Added: a tier is gated by its parent rule's cap\n    title: 'Tier Band',\n    fixedTitle: true,\n    fields: [\n      { name: 'thresholdFrom', alias: 'From', type: 'number', required: true, defaultValue: 0, hint: 'Metric value where this band starts' },\n      { name: 'thresholdTo', alias: 'To', type: 'number', hint: 'Leave as 0 for the top, open-ended band' },\n      { name: 'rate', type: 'number', alias: 'Rate', required: true, hint: 'Applied only to the portion of the metric inside this band' },\n    ],\n    loadAction: { url: 'commissionconfigtiers/id' },\n    heroField: 'commissionConfigTierID',\n  }\n\n  commissionConfigTiersTableConfig: TableConfig = {\n    tabTitle: 'Tiers',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    noDataMessage: 'No bands — the flat rate on the rule applies to the whole metric',\n    columns: [\n      { name: 'thresholdFrom', type: 'number', alias: 'From' },\n      { name: 'thresholdTo', type: 'number', alias: 'To',\n        icons: [{ name: 'all_inclusive', color: 'grey', tip: 'Open-ended top band', condition: (row: any) => row?.isOpenEnded }]\n      },\n      { name: 'rate', type: 'number', alias: 'Rate' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Add Band', dialog: true, action: { url: 'commissionconfigtiers?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'commissionconfigtiers?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'commissionconfigtiers?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'commissionconfigtiers/x/x' }, loadCriteria: 'config', loadIDField: 'commissionConfigID',\n    formConfig: this.commissionConfigTierFormConfig,\n  }\n\n  // Added (Phase 5): defined AFTER the tiers table and BEFORE the view/create buttons, per the two-step create pattern\n  commissionConfigDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.commissionConfigFormConfig,\n    heroField: 'commissionConfigID',\n    buttons: [this.editCommissionConfigButton],\n    tableConfigs: [this.commissionConfigTiersTableConfig],\n  }\n\n  viewCommissionConfigButton: Button = { name: 'view', dialog: true, detailsConfig: this.commissionConfigDetailsConfig };\n  createCommissionConfigButton: Button = { name: 'create', display: 'Create', dialog: true, onSuccessButton: this.viewCommissionConfigButton, action: { url: 'commissionconfigs?action=create', method: 'post' } };\n\n  commissionConfigsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['scopeName', 'name', 'rate'],\n    columns: [\n      { name: 'scopeName', type: 'text', alias: 'Applies To', // Changed (Phase 5): employeeName is blank on a position or company-wide rule, which read as an unassigned rule\n        colors: [{ name: 'red', condition: (row: any) => !row?.employeeID && !row?.positionID && !row?.appliesToAllEmployees }]\n      },\n      { name: 'name', type: 'text' },\n      { name: 'basisName', type: 'text', alias: 'Basis' }, // Changed (Phase 5): Basis replaced MetricType as what the engine measures\n      { name: 'rateTypeName', type: 'text', alias: 'Rate Type' },\n      { name: 'rate', type: 'text', alias: 'Rate' },\n      { name: 'tierCount', type: 'text', alias: 'Tiers' },\n      { name: 'earnEventName', type: 'text', alias: 'Earned When' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' },\n    ],\n    buttons: [\n      this.createCommissionConfigButton,\n      this.viewCommissionConfigButton,\n      { name: 'edit', dialog: true, action: { url: 'commissionconfigs?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'commissionconfigs?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'commissionconfigs/all/x' },\n    formConfig: this.commissionConfigFormConfig,\n    realTime: true,\n    entityName: 'CommissionConfig'\n  }\n\n  // Employee commission configs child table\n  employeeCommissionConfigsTableConfig: TableConfig = {\n    tabTitle: 'Commission Configs',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'text' },\n      { name: 'basisName', type: 'text', alias: 'Basis' }, // Changed (Phase 5): matches the main list\n      { name: 'rateTypeName', type: 'text', alias: 'Rate Type' },\n      { name: 'rate', type: 'text', alias: 'Rate' },\n      { name: 'tierCount', type: 'text', alias: 'Tiers' },\n      { name: 'isActive', type: 'checkbox', alias: 'Active' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, onSuccessButton: this.viewCommissionConfigButton, action: { url: 'commissionconfigs?action=create', method: 'post' } }, // Changed (Phase 5): the tiers tab is only reachable through the details dialog, so a rule created here opens into it too\n      this.viewCommissionConfigButton,\n      { name: 'edit', dialog: true, action: { url: 'commissionconfigs?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'commissionconfigs?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'commissionconfigs/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n    formConfig: this.commissionConfigFormConfig,\n  }\n\n  //--------------------------Commission Entries-------------------------\n\n  // Added (Phase 5): the approval gate, bound to the status CommissionEntriesController exposes\n  // (1=Draft, 2=Approved, 3=Paid, 4=Reversed). Only Approved entries are payable — Draft is a proposal and\n  // Paid is settled — and the server refuses BOTH transitions on an entry that has reached a payslip line,\n  // so isPaid is tested here too rather than trusting status alone.\n  // Changed (Phase 6, browser pass): the colours were 'primary' and 'warn' — Angular Material PALETTE names.\n  // ButtonService.getButtonColor returns button.icon.color verbatim into [style.color], which needs a CSS colour,\n  // so both computed to the inherited grey rgb(68,71,78) while edit rendered rgb(64,80,181) and delete rgb(244,67,54).\n  // The button that authorises money was visually indistinguishable from every other icon in the row.\n  // Added (Phase 6): `inDialog` is what puts a button in the details dialog's footer — Core.setupButtons filters\n  // extraButtons on it, so without it the two gates existed on the row and vanished the moment the entry was\n  // opened to read its breakdown. It is ignored by the row renderer, so one object serves both places and the\n  // gate cannot drift between them.\n  approveCommissionEntryButton: Button = { name: 'approve', display: 'Approve', inDialog: true, icon: { name: 'check_circle', color: 'green' }, action: { url: 'commissionentries?action=approve', method: 'post', successMessage: 'Approved' }, confirm: { message: 'Approve this commission entry so it can be paid on a payslip?' }, visible: (row: any) => row?.status === 1 && !row?.isPaid };\n  returnCommissionEntryButton: Button = { name: 'return', display: 'Return to Draft', inDialog: true, icon: { name: 'undo', color: 'orange' }, action: { url: 'commissionentries?action=return', method: 'post', successMessage: 'Returned to Draft' }, confirm: { message: 'Return this entry to Draft? It will not be picked up by a payroll run until it is approved again.' }, visible: (row: any) => row?.status === 2 && !row?.isPaid };\n\n  commissionEntryFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capCommissionEntries] }, // Added: gate commission entry form by commission entries cap\n    title: 'Commission Entry',\n    fields: [\n      { name: 'employeeID', type: 'select', alias: 'Employee', loadAction: { url: 'employees/list/x' }, required: true, readonlyCondition: (x: any) => x.isPaid },\n      { name: 'periodYear', alias: 'Year', type: 'number', required: true, readonlyCondition: (x: any) => x.isPaid },\n      { name: 'periodMonth', alias: 'Month', type: 'number', required: true, readonlyCondition: (x: any) => x.isPaid },\n      { name: 'metricValue', alias: 'Metric Value', type: 'number', required: true, readonlyCondition: (x: any) => x.isPaid },\n      { name: 'commissionAmount', alias: 'Commission Amount', type: 'money', required: true, readonlyCondition: (x: any) => x.isPaid }, // Changed (Phase 5): a settled figure is history — the payslip line it paid is already out\n      { name: 'statusName', alias: 'Status', type: 'text', readonly: true, hideOnCreate: true }, // Added (Phase 5): the gate itself, so an entry that pays nothing reads as Draft rather than as a bug\n\n      // Changed: sectioned — who earned what for which period is the entry; where it came from is provenance,\n      // read only when a figure is being queried\n      { name: 'source', type: 'section', alias: 'Source & Description', collapseOnView: true },\n      { name: 'description', type: 'text', span: true, section: 'source' },\n      { name: 'sourceType', alias: 'Source Type', type: 'text', section: 'source' },\n      { name: 'sourceReference', alias: 'Source Reference', type: 'text', section: 'source' },\n    ],\n    loadAction: { url: 'commissionentries/id' },\n    heroField: 'commissionEntryID',\n    includeAudit: true,\n  }\n\n  //--------------------------Commission Entry Lines (child of CommissionEntry)-------------------------\n\n  // Added (Phase 6): the breakdown that makes a total explainable. Deliberately has NO buttons — a line is\n  // generated evidence and the header amount is the sum of these rows, so hand-editing one would make the\n  // breakdown disagree with what payroll actually paid. CommissionEntryLinesController refuses the writes\n  // server-side too; this is the same refusal said in the UI rather than only when a POST comes back.\n  commissionEntryLinesTableConfig: TableConfig = {\n    tabTitle: 'Lines',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    noDataMessage: 'No breakdown — this entry was entered by hand rather than generated from trips',\n    columns: [\n      { name: 'eventDate', type: 'date', alias: 'Earned On' },\n      { name: 'sourceDescription', type: 'text', alias: 'Source', // Changed (Phase 6): an adjustment line is the floor/cap correction, not a trip — it has no source to open\n        icons: [{ name: 'tune', color: 'grey', tip: 'Adjustment — the rule\\'s minimum or maximum moved the total, this is the difference', condition: (row: any) => row?.isAdjustment }]\n      },\n      { name: 'sourceType', type: 'text', alias: 'Type' },\n      { name: 'metricValue', type: 'text', alias: 'Measured' },\n      { name: 'rateApplied', type: 'text', alias: 'Rate' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n    ],\n    buttons: [],\n    loadAction: { url: 'commissionentrylines/x/x' }, loadCriteria: 'entry', loadIDField: 'commissionEntryID',\n  }\n\n  // Added (Phase 6): defined AFTER the lines table and BEFORE the view button, per the two-step create pattern.\n  // The approve/return buttons are the SAME objects the table row uses, so the gate cannot drift between the\n  // two places it is offered — both read status and isPaid, and the server refuses both on a settled entry.\n  commissionEntryDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.commissionEntryFormConfig,\n    heroField: 'commissionEntryID',\n    buttons: [this.approveCommissionEntryButton, this.returnCommissionEntryButton],\n    tableConfigs: [this.commissionEntryLinesTableConfig],\n  }\n\n  viewCommissionEntryButton: Button = { name: 'view', dialog: true, detailsConfig: this.commissionEntryDetailsConfig };\n\n  commissionEntriesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['employeeName', 'commissionAmount', 'statusName'],\n    columns: [\n      { name: 'employeeName', type: 'text', alias: 'Employee' },\n      { name: 'periodYear', type: 'text', alias: 'Year' },\n      { name: 'periodMonth', type: 'text', alias: 'Month' },\n      { name: 'metricValue', type: 'text', alias: 'Metric Value' },\n      { name: 'commissionAmount', type: 'money', alias: 'Amount', // Changed (Phase 5): a 0.00 entry is legitimate (per-km with mileage off, or a clawback netting out) but it must never sit silently\n        icons: [{ name: 'error_outline', color: 'orange', tip: 'This entry computed to nothing. Per-distance rules read trip mileage, which needs Tyre Management enabled; a credit-settled invoice is also not treated as paid.', condition: (row: any) => row?.commissionAmount === 0 }]\n      },\n      { name: 'statusName', type: 'text', alias: 'Status', // Changed (Phase 5): the approval gate — a Draft entry is invisible to payroll, which otherwise reads as commission being ignored\n        colors: [\n          { name: 'grey', condition: (row: any) => row?.status === 1 },\n          { name: 'green', condition: (row: any) => row?.status === 2 },\n          { name: 'red', condition: (row: any) => row?.status === 4 },\n        ]\n      },\n      { name: 'isPaid', type: 'checkbox', alias: 'Paid' }, // Changed (Phase 5): settled on a payslip line and no longer changeable, by either side\n      { name: 'description', type: 'text' },\n      { name: 'sourceType', type: 'text', alias: 'Source' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'commissionentries?action=create', method: 'post' } },\n      this.viewCommissionEntryButton, // Added (Phase 6): the only way to the breakdown — a figure with no reachable explanation is what this phase exists to remove\n      this.approveCommissionEntryButton,\n      this.returnCommissionEntryButton,\n      { name: 'edit', dialog: true, action: { url: 'commissionentries?action=edit', method: 'post' }, visible: (row: any) => !row?.isPaid }, // Changed (Phase 5): mirrors the SalaryAdvance guard — a settled entry is not editable\n      { name: 'delete', dialog: true, action: { url: 'commissionentries?action=delete', method: 'post' }, visible: (row: any) => !row?.isPaid }, // Changed (Phase 5): deleting a paid entry would orphan the payslip line that settled it\n    ],\n    loadAction: { url: 'commissionentries/all/x' },\n    formConfig: this.commissionEntryFormConfig,\n    realTime: true,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — one row per commission event — append-only and never purged\n    entityName: 'CommissionEntry',\n  }\n\n  // Employee commission entries child table\n  employeeCommissionEntriesTableConfig: TableConfig = {\n    tabTitle: 'Commission History',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'periodYear', type: 'text', alias: 'Year' },\n      { name: 'periodMonth', type: 'text', alias: 'Month' },\n      { name: 'metricValue', type: 'text', alias: 'Metric Value' },\n      { name: 'commissionAmount', type: 'money', alias: 'Amount',\n        icons: [{ name: 'error_outline', color: 'orange', tip: 'This entry computed to nothing — see the entry for why', condition: (row: any) => row?.commissionAmount === 0 }]\n      },\n      { name: 'statusName', type: 'text', alias: 'Status' }, // Changed (Phase 5): same gate as the main list — Draft never reaches a payslip\n      { name: 'isPaid', type: 'checkbox', alias: 'Paid' },\n      { name: 'description', type: 'text' },\n      { name: 'sourceType', type: 'text', alias: 'Source' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'commissionentries?action=create', method: 'post' } },\n      this.viewCommissionEntryButton, // Added (Phase 6): same breakdown, reached from the employee's own history\n      this.approveCommissionEntryButton,\n      this.returnCommissionEntryButton,\n      { name: 'edit', dialog: true, action: { url: 'commissionentries?action=edit', method: 'post' }, visible: (row: any) => !row?.isPaid }, // Changed (Phase 5): mirrors the main list's settled guard\n      { name: 'delete', dialog: true, action: { url: 'commissionentries?action=delete', method: 'post' }, visible: (row: any) => !row?.isPaid },\n    ],\n    loadAction: { url: 'commissionentries/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n    formConfig: this.commissionEntryFormConfig,\n  }\n\n  //--------------------------Salary Advances-------------------------\n\n  salaryAdvanceFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSalaryAdvances] }, // Added: gate salary advance form by salary advances cap\n    title: 'Salary Advance',\n    fields: [\n      { name: 'employeeID', type: 'select', alias: 'Employee', loadAction: { url: 'employees/list/x' }, required: true },\n      { name: 'amount', type: 'money', required: true },\n      { name: 'advanceDate', alias: 'Advance Date', type: 'date', required: true },\n      { name: 'reason', type: 'text' },\n    ],\n    loadAction: { url: 'salaryadvances/id' },\n    heroField: 'salaryAdvanceID',\n    includeAudit: true,\n  }\n\n  salaryAdvancesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['employeeName', 'amount', 'statusDisplay'],\n    columns: [\n      { name: 'employeeName', type: 'text', alias: 'Employee' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'advanceDate', type: 'date', alias: 'Date' },\n      { name: 'reason', type: 'text' },\n      { name: 'statusDisplay', type: 'text', alias: 'Status' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'salaryadvances?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'salaryadvances?action=edit', method: 'post' }, visible: (row: any) => !row?.isDeducted },\n      { name: 'delete', dialog: true, action: { url: 'salaryadvances?action=delete', method: 'post' }, visible: (row: any) => !row?.isDeducted },\n    ],\n    loadAction: { url: 'salaryadvances/all/x' },\n    formConfig: this.salaryAdvanceFormConfig,\n    realTime: true,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — advances append every pay cycle\n    entityName: 'SalaryAdvance',\n  }\n\n  // Employee salary advances child table\n  employeeSalaryAdvancesTableConfig: TableConfig = {\n    tabTitle: 'Salary Advances',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'advanceDate', type: 'date', alias: 'Date' },\n      { name: 'reason', type: 'text' },\n      { name: 'statusDisplay', type: 'text', alias: 'Status' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'salaryadvances?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'salaryadvances?action=edit', method: 'post' }, visible: (row: any) => !row?.isDeducted },\n      { name: 'delete', dialog: true, action: { url: 'salaryadvances?action=delete', method: 'post' }, visible: (row: any) => !row?.isDeducted },\n    ],\n    loadAction: { url: 'salaryadvances/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n    formConfig: this.salaryAdvanceFormConfig,\n  }\n\n  //--------------------------Overtime Entries-------------------------\n\n  overtimeEntryFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capOvertimeEntries] }, // Added: gate overtime entry form by overtime entries cap\n    title: 'Overtime Entry',\n    fields: [\n      { name: 'employeeID', type: 'select', alias: 'Employee', loadAction: { url: 'employees/list/x' }, required: true },\n      { name: 'overtimeDate', alias: 'Date', type: 'date', required: true },\n      { name: 'hours', type: 'number', required: true },\n      { name: 'overtimeType', alias: 'Overtime Type', type: 'select', loadAction: { url: 'overtimeentries/list/overtime-type' }, required: true },\n      { name: 'hourlyRate', alias: 'Hourly Rate', type: 'money', required: true },\n      { name: 'amount', type: 'money', alias: 'Amount', readonly: true, serverOwned: true }, // Changed (CFW-1): OvertimeEntry.Amount carries [ServerOwned] — MEASURED storing a forged 77777 before Phase 4\n    ],\n    loadAction: { url: 'overtimeentries/id' },\n    heroField: 'overtimeEntryID',\n    includeAudit: true,\n  }\n\n  overtimeEntriesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['employeeName', 'hours', 'amount'],\n    columns: [\n      { name: 'employeeName', type: 'text', alias: 'Employee' },\n      { name: 'overtimeDate', type: 'date', alias: 'Date' },\n      { name: 'hours', type: 'text', alias: 'Hours' },\n      { name: 'overtimeTypeName', type: 'text', alias: 'Type' },\n      { name: 'hourlyRate', type: 'money', alias: 'Hourly Rate' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'overtimeentries?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'overtimeentries?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'overtimeentries?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'overtimeentries/all/x' },\n    formConfig: this.overtimeEntryFormConfig,\n    realTime: true,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — overtime entries append every pay cycle\n    entityName: 'OvertimeEntry',\n  }\n\n  // Employee overtime entries child table\n  employeeOvertimeHistoryTableConfig: TableConfig = {\n    tabTitle: 'Overtime History',\n    showFilter: false,\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'overtimeDate', type: 'date', alias: 'Date' },\n      { name: 'hours', type: 'text', alias: 'Hours' },\n      { name: 'overtimeTypeName', type: 'text', alias: 'Type' },\n      { name: 'hourlyRate', type: 'money', alias: 'Hourly Rate' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'overtimeentries?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'overtimeentries?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'overtimeentries?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'overtimeentries/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n    formConfig: this.overtimeEntryFormConfig,\n  }\n\n  //--------------------------Payroll Runs-------------------------\n\n  // Action buttons with status-based visibility\n  submitPayrollButton: Button = { name: 'submit', display: 'Submit', inDialog: true, action: { url: 'payrollruns?action=submit', method: 'post' }, visible: (row: any) => row?.status === 1 }; // Changed: null-check row to prevent TypeError when dialog renders before row data loads\n  postPayrollButton: Button = { name: 'post', display: 'Post', inDialog: true, action: { url: 'payrollruns?action=post', method: 'post' }, visible: (row: any) => row?.status === 2 }; // Changed: null-check row\n  markPaidButton: Button = { name: 'paid', display: 'Mark Paid', inDialog: true, action: { url: 'payrollruns?action=paid', method: 'post' }, visible: (row: any) => row?.status === 3 }; // Changed: null-check row\n  // Added (Phase 5): recalculate is how a late commission approval or a corrected salary structure reaches an\n  // open run. DRAFT ONLY — the server refuses it at Submitted, Posted and Paid, and a button that exists and\n  // always fails teaches people the product is broken. It discards and rebuilds the run's payslips, hence the confirm.\n  recalculatePayrollButton: Button = { name: 'recalculate', display: 'Recalculate', inDialog: true, action: { url: 'payrollruns?action=recalculate', method: 'post', successMessage: 'Payslips rebuilt' }, confirm: { message: 'Rebuild this run\\'s payslips from current salary structures and approved commission? The existing payslips are discarded.' }, visible: (row: any) => row?.status === 1 };\n\n  payrollRunFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capPayrollRuns] }, // Added: gate payroll run form by payroll runs cap\n    title: 'Payroll Run',\n    fields: [\n      { name: 'periodYear', alias: 'Year', type: 'number', required: true },\n      { name: 'periodMonth', alias: 'Month', type: 'number', required: true },\n      { name: 'payDate', alias: 'Pay Date', type: 'date', required: true },\n      { name: 'description', type: 'text-area', rows: 2, span: true },\n    ],\n    loadAction: { url: 'payrollruns/id' },\n    heroField: 'payrollRunID',\n    includeAudit: true,\n  }\n\n  // Added (WS-1 sweep 2): payroll is deliberately OUT of the offline sweep in full — no payroll entity implements ISync (a queued write would carry no RowVersion/ClientRef), and a payroll run is a month-end back-office act at a desk, never a field capture. The same reasoning covers every config in this file, which is why it is stated once here rather than nineteen times.\n  payrollRunsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['periodYear', 'totalGrossPay', 'statusName'],\n    columns: [\n      { name: 'periodYear', type: 'text', alias: 'Year' },\n      { name: 'periodMonth', type: 'text', alias: 'Month' },\n      { name: 'payDate', type: 'date', alias: 'Pay Date' },\n      { name: 'payslipCount', type: 'text', alias: 'Payslips' },\n      { name: 'totalGrossPay', type: 'money', alias: 'Gross Pay' },\n      { name: 'totalNetPay', type: 'money', alias: 'Net Pay' },\n      { name: 'statusName', type: 'text', alias: 'Status' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'payrollruns?action=create', method: 'post' } },\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.payrollRunFormConfig,\n          heroField: 'payrollRunID',\n          buttons: [this.recalculatePayrollButton, this.submitPayrollButton, this.postPayrollButton, this.markPaidButton],\n          tableConfigs: [this.payslipsChildTableConfig],\n        }\n      },\n      { name: 'edit', dialog: true, action: { url: 'payrollruns?action=edit', method: 'post' }, visible: (row: any) => row?.status === 1 }, // Changed: null-check row\n      { name: 'delete', dialog: true, action: { url: 'payrollruns?action=delete', method: 'post' }, visible: (row: any) => row?.status === 1 }, // Changed: null-check row\n    ],\n    loadAction: { url: 'payrollruns/all/x' },\n    formConfig: this.payrollRunFormConfig,\n    entityName: 'PayrollRun'\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, TableConfig, Button, DetailsDialogConfig } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service'; // Added: for capability references\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class LoansService {\n\n  private dataService = inject(DataServiceLib); // Added: for capability references\n\n  // ========== LOAN PRODUCTS BUTTONS ==========\n  \n  loanProductCreateButton: Button = { name: 'create', display: 'Create Product', dialog: true, action: { url: 'loanproducts?action=create', method: 'post' } };\n  loanProductEditButton: Button = { name: 'edit', dialog: true, action: { url: 'loanproducts?action=edit', method: 'post' } };\n  loanProductDeleteButton: Button = { name: 'delete', action: { url: 'loanproducts?action=delete', method: 'post' } };\n\n  // ========== LOAN PRODUCTS ==========\n  \n  // Loan Product Form Configuration\n  loanProductFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capLoanProducts] }, // Added: gate loan product form by loan products cap\n    title: 'Loan Product',\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'description', type: 'text', alias: 'Description', span : true },\n      { name: 'interestMethod', type: 'select', alias: 'Interest Calculation Method', required: true, options: [{ name: 'Flat Rate', value: 0 }, { name: 'Reducing Balance', value: 1 }] },\n\n      // Changed: sectioned — the product's name and interest method identify it; the five bounds are set once\n      // when the product is designed and only re-read when it is being changed\n      { name: 'bounds', type: 'section', alias: 'Amount, Rate & Term Limits', collapseOnView: true },\n      { name: 'minAmount', type: 'money', alias: 'Minimum Amount', required: true, section: 'bounds' },\n      { name: 'maxAmount', type: 'money', alias: 'Maximum Amount', required: true, section: 'bounds' },\n      { name: 'defaultInterestRate', type: 'number', alias: 'Interest Rate (%)', required: true, min: 0, max: 100, section: 'bounds' },\n      { name: 'minTermMonths', type: 'number', alias: 'Minimum Term (Months)', required: true, min: 1, section: 'bounds' },\n      { name: 'maxTermMonths', type: 'number', alias: 'Maximum Term (Months)', required: true, min: 1, section: 'bounds' },\n    ],\n    loadAction: { url: 'loanproducts/id' },\n    heroField: 'loanProductID'\n  };\n\n  loanProductTableConfig: TableConfig = {\n    showFilter: true,\n    columns: [\n      { name: 'name', alias: 'Product Name' },\n      { name: 'interestMethodName', alias: 'Interest Method' },\n      { name: 'minAmount', type: 'money', alias: 'Min Amount' },\n      { name: 'maxAmount', type: 'money', alias: 'Max Amount' },\n\n      { name: 'minInterestRate', alias: 'Min Rate (%)' },\n      { name: 'maxInterestRate', alias: 'Max Rate (%)' },\n      { name: 'minTermMonths', alias: 'Min Term' },\n      { name: 'maxTermMonths', alias: 'Max Term' },\n      { name: 'loanCount', alias: 'Active Loans' },\n    ],\n    loadAction: { url: 'loanproducts/all' },\n    formConfig: this.loanProductFormConfig,\n    buttons: [this.loanProductCreateButton, this.loanProductEditButton, this.loanProductDeleteButton],\n    realTime: true,\n    entityName: 'LoanProduct'\n  };\n\n  // ========== LOANS BUTTONS ==========\n\n  loanCreateButton: Button = { name: 'create', display: 'New Loan', dialog: true, action: { url: 'loans?action=create', method: 'post' } };\n  loanEditButton: Button = { name: 'edit', dialog: true, action: { url: 'loans?action=edit', method: 'post' } };\n  loanDisburseButton: Button = { name: 'disburse', display: 'Disburse', action: { url: 'loans?action=disburse', method: 'post' }, confirm: { message: 'Are you sure you want to disburse this loan?' }, visible: (x: any) => x.canDisburse };\n\n  // ========== LOANS ==========\n\n  // Loan Application Form Configuration\n  loanFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capLoansMain] }, // Added: gate loan application form by loans cap\n    title: 'Loan Application',\n    fields: [\n      { name: 'loanType', type: 'select', alias: 'Loan Type', required: true, defaultFirstValue: true,\n        options: [\n          { name: 'Customer Loan', value: 0 }, \n          { name: 'Employee Loan', value: 1 }\n        ] \n      },\n      { name: 'customerID', type: 'select', alias: 'Customer', required: true, detailsConfig: this.dataService.customerDetailsConfig, // Changed: dropdown quick-add\n        loadAction: { url: 'customers/list/x' },\n        hidden: (x: any) => x.loanType == 1\n      },\n      { name: 'employeeID', type: 'select', alias: 'Employee', required: true, \n        loadAction: { url: 'employees/list/x' }, \n        hidden: (x: any) => x.loanType == 0 \n      },\n      { name: 'loanProductID', type: 'select', alias: 'Loan Product', loadAction: { url: 'loanproducts/list/x' } },\n      { name: 'principalAmount', type: 'money', alias: 'Principal Amount', required: true },\n\n      // Changed: sectioned — who is borrowing how much stays up top, the rate/term mechanics group together\n      { name: 'terms', type: 'section', alias: 'Interest & Term', collapseOnView: true },\n      { name: 'interestRate', type: 'number', alias: 'Annual Interest Rate (%)', required: true, min: 0, max: 100, section: 'terms' },\n      { name: 'monthlyInterestRate', type: 'number', alias: 'Monthly Interest Rate (%)', required: true, min: 0, max: 100, section: 'terms' },\n      { name: 'termMonths', type: 'number', alias: 'Term (Months)', required: true, min: 1, max: 120, section: 'terms' },\n      { name: 'disbursementDate', type: 'date', alias: 'Disbursement Date', required: true, section: 'terms' },\n    ],\n    loadAction: { url: 'loans/id' },\n    heroField: 'loanID'\n  };\n\n  // ========== LOAN SCHEDULES ==========\n\n  // Loan Schedule Table Configuration (for display within loan details)\n  loanScheduleTableConfig: TableConfig = {\n    columns: [\n      { name: 'installmentNumber', alias: '#' },\n      { name: 'dueDate', type: 'date', alias: 'Due Date' },\n      { name: 'principalAmount', type: 'money', alias: 'Principal' },\n      { name: 'interestAmount', type: 'money', alias: 'Interest' },\n      { name: 'totalAmount', type: 'money', alias: 'Total' },\n      { name: 'paidAmount', type: 'money', alias: 'Paid' },\n      { name: 'outstandingAmount', type: 'money', alias: 'Outstanding' },\n      { name: 'statusName', alias: 'Status', colors: [{ name: 'green', condition: (x: any) => x.status == 3 }, { name: 'red', condition: (x: any) => x.status == 2 }] },\n    ],\n    loadAction: { url: 'loanschedules/loan' },\n    minColumns: ['installmentNumber', 'dueDate', 'totalAmount', 'statusName']\n  };\n\n  // Loan Details Configuration\n  loanDetailsConfig: DetailsDialogConfig = {\n    formConfig: {\n      title: 'Loan Details',\n      // Changed: sectioned — sixteen read-only fields buried the schedule and payment tabs. Who/what/how much\n      // is still owed stays on screen; the terms, the totals and the progress counters fold away.\n      fields: [\n        { name: 'customerName', type: 'text', alias: 'Customer' },\n        { name: 'productName', type: 'text', alias: 'Product' },\n        { name: 'statusName', type: 'text', alias: 'Status' },\n        { name: 'outstandingBalance', type: 'money', alias: 'Outstanding Balance' },\n\n        { name: 'terms', type: 'section', alias: 'Loan Terms', collapseOnView: true },\n        { name: 'principalAmount', type: 'money', alias: 'Principal Amount', section: 'terms' },\n        { name: 'interestRate', type: 'number', alias: 'Annual Interest Rate (%)', required: true, min: 0, max: 100, section: 'terms' },\n        { name: 'monthlyInterestRate', type: 'number', alias: 'Monthly Interest Rate (%)', required: true, min: 0, max: 100, section: 'terms' },\n        { name: 'termMonths', type: 'number', alias: 'Term (Months)', section: 'terms' },\n        { name: 'disbursementDate', type: 'date', alias: 'Disbursement Date', section: 'terms' },\n        { name: 'maturityDate', type: 'date', alias: 'Maturity Date', section: 'terms' },\n\n        { name: 'balances', type: 'section', alias: 'Balances', collapseOnView: true },\n        { name: 'totalAmountDue', type: 'money', alias: 'Total Amount Due', section: 'balances' },\n        { name: 'totalPaidAmount', type: 'money', alias: 'Total Paid', section: 'balances' },\n        { name: 'totalInterest', type: 'money', alias: 'Total Interest', section: 'balances' },\n\n        { name: 'progress', type: 'section', alias: 'Repayment Progress', collapseOnView: true },\n        { name: 'scheduleCount', type: 'number', alias: 'Total Installments', section: 'progress' },\n        { name: 'paymentCount', type: 'number', alias: 'Payments Made', section: 'progress' },\n        { name: 'overdueCount', type: 'number', alias: 'Overdue Installments', section: 'progress' },\n      ],\n      loadAction: { url: 'loans/id' }\n    },\n    heroField: 'loanID',\n    tableConfigs: [\n      {\n        ...this.loanScheduleTableConfig,\n        tabTitle: 'Payment Schedule',\n        loadAction: { url: 'loanschedules/loan/x' },\n        loadCriteria: 'loan',\n        loadIDField: 'loanID'\n      },\n      {\n        tabTitle: 'Payment History',\n        showFilter: true,\n        columns: [\n          { name: 'paymentDate', type: 'date', alias: 'Date' },\n          { name: 'amount', type: 'money', alias: 'Amount' },\n          { name: 'principalPaid', type: 'money', alias: 'Principal' },\n          { name: 'interestPaid', type: 'money', alias: 'Interest' },\n          { name: 'methodName', alias: 'Method' },\n          { name: 'reference', alias: 'Reference' },\n        ],\n        loadAction: { url: 'loanpayments/loan/x' },\n        loadCriteria: 'loan',\n        loadIDField: 'loanID',\n        minColumns: ['paymentDate', 'amount']\n      }\n    ]\n  };\n\n  loanViewButton: Button = { name: 'view', display: 'View', dialog: true, detailsConfig: this.loanDetailsConfig };\n\n  // Loans Table Configuration\n  // Added (WS-1 sweep 2): paginated but deliberately NOT offline — Loan does not implement ISync, and loan origination and repayment capture are desk-bound back-office acts. Covers the whole file.\n  loanTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    columns: [\n      { name: 'borrowerType', alias: 'Type', colors: [{ name: 'blue', condition: (x: any) => x.employeeID > 0 }, { name: 'green', condition: (x: any) => x.customerID > 0 }] },\n      { name: 'borrowerName', alias: 'Borrower' },\n      { name: 'productName', alias: 'Product' },\n      { name: 'interestMethodName', alias: 'Method' },\n      { name: 'principalAmount', type: 'money', alias: 'Principal' },\n      { name: 'displayRate', alias: 'Rate (%)' },\n      { name: 'termMonths', alias: 'Term' },\n      { name: 'disbursementDate', type: 'date', alias: 'Disbursed' },\n      { name: 'outstandingBalance', type: 'money', alias: 'Outstanding' },\n      { name: 'statusName', alias: 'Status', colors: [{ name: 'green', condition: (x: any) => x.status == 2 }, { name: 'red', condition: (x: any) => x.status == 3 }, { name: 'orange', condition: (x: any) => x.status == 1 }] },\n    ],\n    loadAction: { url: 'loans/all/x' },\n    minColumns: ['borrowerName', 'principalAmount', 'statusName'],\n    formConfig: this.loanFormConfig,\n    buttons: [this.loanViewButton, this.loanCreateButton, this.loanEditButton, this.loanDisburseButton ],\n    pagination: { pageSize: 20 }, // Added: server-side pagination — the loan book only grows\n    entityName: 'Loan',\n  };\n\n  // ========== LOAN PAYMENTS BUTTONS ==========\n\n  loanPaymentCreateButton: Button = { name: 'create', display: 'Record Payment', dialog: true, action: { url: 'loanpayments?action=create', method: 'post' } };\n\n  // ========== LOAN PAYMENTS ==========\n\n  // Loan Payment Form Configuration\n  loanPaymentFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capLoanPayments] }, // Added: gate loan payment form by loan payments cap\n    title: 'Loan Payment',\n    fields: [\n      { name: 'loanID', type: 'select', alias: 'Loan', required: true, loadAction: { url: 'loans/list/x' } },\n      { name: 'amount', type: 'money', alias: 'Payment Amount', required: true },\n      { name: 'paymentDate', type: 'date', alias: 'Payment Date', required: true }, // Changed (NFD-2, Arbiter 2026-08-19): max: 'today' REMOVED — deliberately uncapped. A payment may legitimately carry a future date (post-dated cheque), so the future IS a valid answer here. Not method-conditioned: uncapped for every payment method.\n      { name: 'method', type: 'select', alias: 'Payment Method', required: true, options: [{ name: 'Cash', value: 0 }, { name: 'Bank Transfer', value: 1 }, { name: 'Mobile Money', value: 2 }, { name: 'Cheque', value: 3 }, { name: 'Card', value: 4 }] },\n      { name: 'reference', type: 'text', alias: 'Reference Number' },\n    ],\n    heroField: 'loanPaymentID'\n  };\n\n  loanPaymentTableConfig: TableConfig = {\n    showFilter: true,\n    columns: [\n      { name: 'paymentDate', type: 'date', alias: 'Date' },\n      { name: 'customerName', alias: 'Customer' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'principalPaid', type: 'money', alias: 'Principal' },\n      { name: 'interestPaid', type: 'money', alias: 'Interest' },\n      { name: 'methodName', alias: 'Method' },\n      { name: 'reference', alias: 'Reference' },\n    ],\n    loadAction: { url: 'loanpayments/all/x' },\n    minColumns: ['paymentDate', 'customerName', 'amount'],\n    formConfig: this.loanPaymentFormConfig,\n    buttons: [this.loanPaymentCreateButton],\n    pagination: { pageSize: 20 }, // Added: server-side pagination — one row per repayment across every loan — the largest table in the module\n    entityName: 'LoanPayment',\n  };\n}\n","// Quiet Loading — silent-request plumbing.\n// A request carrying TIN_SILENT_REQUEST is skipped by LoaderInterceptor's in-flight bookkeeping, so it never\n// raises the global scrim. Everything else about the request (bearer token, 401 refresh, error dialogs) is\n// untouched — this is deliberately NOT the interceptor's URL whitelist, which also bypasses error handling.\nimport { HttpContext, HttpContextToken } from '@angular/common/http';\n\nexport const TIN_SILENT_REQUEST = new HttpContextToken<boolean>(() => false);\n\n// Returns a context carrying the silent flag; returns the caller's context (or undefined) untouched when the\n// request is not silent, so non-quiet callers build byte-for-byte the same request they always did.\nexport function silentContext(silent?: boolean, context?: HttpContext): HttpContext | undefined {\n  if (!silent) {\n    return context;\n  }\n  return (context ?? new HttpContext()).set(TIN_SILENT_REQUEST, true);\n}\n\n// True when the request was marked silent by silentContext().\nexport function isSilentRequest(context: HttpContext | undefined | null): boolean {\n  return !!context?.get(TIN_SILENT_REQUEST);\n}\n","// ───────────────────────────────────────────────────────────────────────────\n// tin-spa runtime app settings — assets/appsettings.json\n//\n// Mirrors ASP.NET Core configuration on the frontend: a deployed, server-editable\n// `assets/appsettings.json` is read at startup (before Angular bootstraps), and if it\n// declares an \"Environment\" (e.g. \"Production\"), `assets/appsettings.{Environment}.json`\n// is loaded on top of it — same file names, same layering as the backend. Changing a\n// value is a file edit on the server, never a rebuild: the same build artifact is\n// promoted through SIT/UAT/PROD.\n//\n// Consuming apps call the loader in main.ts, before bootstrapModule:\n//\n//   loadTinSpaAppSettings().then(() =>\n//     platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err)));\n//\n// The loaded settings are then visible to DI factories via getTinSpaAppSettings().\n// provideTinSpaRuntime() consumes them automatically (see tinspa-runtime.ts): values in\n// the file override the code-declared runtime config. The file is OPTIONAL — apps that\n// don't ship one keep their code-declared config unchanged.\n//\n// Everything in this file is public-by-design SPA configuration (client IDs, authorities,\n// redirect URIs). Secrets never belong here — they stay in the backend's appsettings.\n// ───────────────────────────────────────────────────────────────────────────\n\n/** \"Msal\" section — PascalCase keys to match backend appsettings conventions. */\nexport interface TinSpaMsalSettings {\n  ClientId?: string;\n  Authority?: string;\n  /** Optional — when omitted or empty, tin-spa falls back to `${window.location.origin}/login`. */\n  RedirectUri?: string;\n}\n\nexport interface TinSpaAppSettings {\n  /** Selects the overlay file, exactly like ASPNETCORE_ENVIRONMENT selects\n   * appsettings.{Environment}.json on the backend. Set per server, e.g. \"SIT\", \"UAT\", \"Production\". */\n  Environment?: string;\n  /** Enable/disable Microsoft SSO per environment (overrides the code-declared runtime flag). */\n  MicrosoftAuth?: boolean;\n  /** Enable/disable Google sign-in per environment. */\n  GoogleAuth?: boolean;\n\n  /** Routing strategy per environment: true = path routing (/home), false = hash routing (/#/home).\n   * Overrides the code-declared `pathRouting`. Path routing needs a server rewrite rule (IIS\n   * URL Rewrite / SPA fallback) so deep links resolve to index.html — which is exactly why this\n   * has to be per-environment: the same build is promoted to servers configured differently. */\n  PathRouting?: boolean;\n\n  /** SignalR/real-time on or off per environment (overrides the code-declared `realTime`). */\n  RealTime?: boolean;\n\n  /** Offline capability on or off per environment (overrides the code-declared `offline`). */\n  Offline?: boolean;\n\n  /** Added: app-wide per-table defaults, tunable per environment without a rebuild. A table's own\n   * TableConfig value always wins over these; these only fill in what a table did not state.\n   * PageSize is offered as a number because tuning it per server is the main reason to expose it —\n   * e.g. a slow-link deployment dropping every unstated table to 10 rows a page. */\n  TableDefaults?: {\n    RealTime?: boolean;\n    RealTimeFallbackMs?: number; // Added: wait before a real-time table falls back to a refresh; a slow link may want longer than the 3000 default\n    Offline?: boolean;\n    Pagination?: boolean;\n    PageSize?: number;\n  };\n\n  Msal?: TinSpaMsalSettings;\n  /** Same key name the backend reads for token validation — the two MUST hold the same value,\n   * since the backend validates the Google id-token audience against its own GoogleClientID. */\n  GoogleClientID?: string;\n  /** Apps may add their own environment-specific sections. */\n  [key: string]: any;\n}\n\nconst LOG = '[tin-spa appsettings]';\n\nlet loadedSettings: TinSpaAppSettings | null = null;\n\n/** The settings loaded by loadTinSpaAppSettings(), or null when no file was found / loading failed. */\nexport function getTinSpaAppSettings(): TinSpaAppSettings | null {\n  return loadedSettings;\n}\n\n/** Overlay values win; plain objects merge recursively, scalars and arrays replace. */\nfunction deepMerge(base: any, overlay: any): any {\n  if (overlay === undefined) return base;\n  if (base === undefined) return overlay;\n  const isObj = (v: any) => v !== null && typeof v === 'object' && !Array.isArray(v);\n  if (!isObj(base) || !isObj(overlay)) return overlay;\n  const out: any = { ...base };\n  for (const key of Object.keys(overlay)) out[key] = deepMerge(base[key], overlay[key]);\n  return out;\n}\n\n/** null = file absent (fine for the base file, warned for a declared overlay); throws never. */\nasync function fetchSettingsFile(file: string, required: boolean): Promise<TinSpaAppSettings | null> {\n  // no-store: server admins edit these files in place — a cached copy would silently\n  // keep serving the old environment's values.\n  let response: Response;\n  try {\n    response = await fetch(`assets/${file}`, { cache: 'no-store' });\n  } catch (err) {\n    console.error(`${LOG} could not request assets/${file}:`, err);\n    return null;\n  }\n\n  if (!response.ok) {\n    if (required) {\n      console.warn(`${LOG} assets/${file} was not found (HTTP ${response.status}) — it is declared by the \"Environment\" setting, so it should exist. Using the base file only.`);\n    } else {\n      console.info(`${LOG} no assets/${file} found (HTTP ${response.status}) — runtime settings come from code only.`);\n    }\n    return null;\n  }\n\n  try {\n    return await response.json();\n  } catch (err) {\n    console.error(`${LOG} assets/${file} exists but is not valid JSON — its values are IGNORED. Fix the file syntax.`, err);\n    return null;\n  }\n}\n\n/**\n * Loads assets/appsettings.json (+ the appsettings.{Environment}.json overlay when the base file\n * declares an Environment) and caches the merged result for getTinSpaAppSettings().\n * Never rejects — a missing or broken file logs to the console and resolves null so the app\n * still boots with its code-declared configuration.\n */\nexport async function loadTinSpaAppSettings(): Promise<TinSpaAppSettings | null> {\n  if (typeof fetch === 'undefined') return null;\n\n  const base = await fetchSettingsFile('appsettings.json', false);\n  if (!base) return null;\n\n  let merged = base;\n  const env = typeof base.Environment === 'string' ? base.Environment.trim() : '';\n  if (env) {\n    const overlay = await fetchSettingsFile(`appsettings.${env}.json`, true);\n    if (overlay) merged = deepMerge(base, overlay);\n  }\n\n  loadedSettings = merged;\n  console.info(\n    `${LOG} loaded appsettings.json` +\n    (env ? ` + appsettings.${env}.json (Environment: ${env})` : ' (no Environment overlay declared)') +\n    ` — MicrosoftAuth: ${merged.MicrosoftAuth ?? 'not set'}, GoogleAuth: ${merged.GoogleAuth ?? 'not set'},` +\n    ` Msal.ClientId: ${merged.Msal?.ClientId ? 'present' : 'MISSING'}, GoogleClientID: ${merged.GoogleClientID ? 'present' : 'MISSING'},` +\n    // PathRouting is reported explicitly because getting it wrong produces a confusing failure: the\n    // app loads fine and only breaks on refresh/deep-link. \"not set\" here means the code default is\n    // in force, which is the first thing to check when an environment routes unexpectedly.\n    ` PathRouting: ${merged.PathRouting ?? 'not set (code default)'}`\n  );\n  return merged;\n}\n","// ───────────────────────────────────────────────────────────────────────────\n// tin-spa runtime configuration\n//\n// Centralises the \"which runtime behaviours does this app want\" decisions that used to be\n// scattered across each consuming app (routing strategy, real-time/SignalR, Microsoft SSO).\n//\n// A consuming app declares intent in ONE place:\n//\n//   providers: [\n//     provideTinSpaRuntime({\n//       pathRouting: false,    // hash routing (default) vs path routing\n//       realTime: false,       // SignalR on/off\n//       microsoftAuth: false,  // MSAL on/off (also requires HTTPS)\n//       msal: { clientId, authority, redirectUri },   // only if microsoftAuth is used\n//     }),\n//   ]\n//\n// The config is read live at startup — nothing is cached in localStorage. So when you change a\n// flag here and redeploy, every user picks up the new value on their next load.\n//\n// Changed: the code-declared config is no longer the only source. When the app ships an\n// assets/appsettings.json (loaded pre-bootstrap via loadTinSpaAppSettings(), see appsettings.ts),\n// its values OVERRIDE the code config:\n//     MicrosoftAuth → microsoftAuth\n//     PathRouting   → pathRouting        (added 20.11.15)\n//     RealTime      → realTime           (added 20.11.15)\n//     Offline       → offline            (added 20.11.15)\n//     Msal.{ClientId,Authority,RedirectUri} → msal\n// so SSO, the routing strategy and the real-time/offline switches are all per-environment\n// server-editable — one build artifact promoted through SIT/UAT/PROD, no rebuild.\n// Precedence: DEFAULTS < provideTinSpaRuntime(config) < assets/appsettings.json.\n//\n// A key is only honoured when the file declares it as a real boolean; anything else (absent,\n// string, null) falls through to the code-declared value. So provideTinSpaRuntime() stays the\n// DEFAULT for every environment, and appsettings.json is the per-server exception — which is the\n// behaviour a deployer expects, and it means shipping no appsettings.json changes nothing.\n// ───────────────────────────────────────────────────────────────────────────\nimport {\n  EnvironmentProviders, InjectionToken, Optional, Inject, makeEnvironmentProviders,\n} from '@angular/core';\nimport {\n  LocationStrategy, HashLocationStrategy, PathLocationStrategy, PlatformLocation, APP_BASE_HREF,\n} from '@angular/common';\nimport { MSAL_INSTANCE, MsalService } from '@azure/msal-angular';\nimport { IPublicClientApplication, PublicClientApplication, BrowserCacheLocation } from '@azure/msal-browser';\nimport { getTinSpaAppSettings } from './appsettings';\n\nexport interface TinSpaMsalConfig {\n  clientId: string;\n  authority: string;\n  redirectUri: string;\n}\n\n// Added: app-wide DEFAULTS for per-table behaviour. Previously every table had to opt into realTime,\n// offline and pagination individually, which meant setting the same flag on dozens of configs and made\n// \"most tables behave this way\" impossible to express. These invert that: declare the norm once for the\n// app, then a table only says something when it is an EXCEPTION.\n//\n// Precedence is component-wins: a TableConfig value ALWAYS beats the app default, including when it is\n// explicitly `false`. That is why the resolver tests `!== undefined` rather than truthiness — a table\n// must be able to opt OUT of an app-wide default, not just opt in.\nexport interface TinSpaTableDefaults {\n  /** Default for TableConfig.realTime. */\n  realTime?: boolean;\n  /** Default for TableConfig.realTimeFallbackMs — the wait before a real-time table falls back to a refresh. Library default 3000. */\n  realTimeFallbackMs?: number;\n  /** Default for TableConfig.offline. `true` is shorthand for { enabled: true }. */\n  offline?: any;\n  /** Default for TableConfig.pagination. `true` is shorthand for the library's default page size. */\n  pagination?: any;\n}\n\nexport interface TinSpaRuntimeConfig {\n  /** Use path routing (/home) instead of hash routing (/#/home). Default false (hash). */\n  pathRouting: boolean;\n  /** Enable real-time (SignalR) features. Default false (disabled). */\n  realTime: boolean;\n  /** Enable offline capability (TinSync: read cache + outbox + sync tray + connectivity indicator). Default false —\n   * apps that never use offline tables should leave this off so none of the offline machinery ever runs for them. */\n  offline?: boolean;\n  /** Enable Microsoft SSO (MSAL). Only activates in a secure context (HTTPS/localhost). Default false. */\n  microsoftAuth: boolean;\n  /** MSAL credentials — required only when microsoftAuth is used. */\n  msal?: TinSpaMsalConfig;\n  /** Added: app-wide defaults applied to every spa-table that does not state its own value. */\n  tableDefaults?: TinSpaTableDefaults;\n}\n\nconst DEFAULTS: TinSpaRuntimeConfig = {\n  pathRouting: false,\n  realTime: false,\n  offline: false,\n  microsoftAuth: false,\n  tableDefaults: {}, // Added: no table defaults unless the app declares them — preserves existing behaviour exactly\n};\n\nexport const TIN_SPA_RUNTIME_CONFIG = new InjectionToken<TinSpaRuntimeConfig>('TIN_SPA_RUNTIME_CONFIG', {\n  factory: () => DEFAULTS, // safe fallback if an app forgets to call provideTinSpaRuntime()\n});\n\n// ── DI factories ────────────────────────────────────────────────────────────\n\nexport function tinSpaLocationStrategyFactory(\n  platformLocation: PlatformLocation, baseHref: string, config: TinSpaRuntimeConfig,\n): LocationStrategy {\n  return config.pathRouting\n    ? new PathLocationStrategy(platformLocation, baseHref)\n    : new HashLocationStrategy(platformLocation, baseHref);\n}\n\n/** Overlays assets/appsettings.json values (when the app loaded one) onto the code-declared config. */\nexport function tinSpaRuntimeConfigFactory(codeConfig: TinSpaRuntimeConfig): TinSpaRuntimeConfig {\n  const settings = getTinSpaAppSettings();\n  if (!settings) return codeConfig;\n\n  const merged: TinSpaRuntimeConfig = { ...codeConfig };\n\n  // Each flag is overridden ONLY when the file declares an actual boolean. That is why these are\n  // `typeof === 'boolean'` tests rather than `??` or truthiness: an absent key must fall through to\n  // the code-declared value, and a key present as `false` must still win. `settings.X ?? code.X`\n  // would behave correctly for absent keys but silently accept a string \"true\" from a hand-edited\n  // file as a truthy override — these files are edited by server admins, not by a compiler.\n  if (typeof settings.MicrosoftAuth === 'boolean') merged.microsoftAuth = settings.MicrosoftAuth;\n\n  // Routing strategy per environment. Previously code-only, which forced every environment onto the\n  // same strategy and meant a server needing path routing required a rebuild — defeating the point\n  // of runtime appsettings. Note the consequence of getting this wrong: path routing without a\n  // server rewrite rule gives a working app that 404s on refresh and on every deep link.\n  if (typeof settings.PathRouting === 'boolean') merged.pathRouting = settings.PathRouting;\n\n  if (typeof settings.RealTime === 'boolean') merged.realTime = settings.RealTime;\n  if (typeof settings.Offline === 'boolean') merged.offline = settings.Offline;\n\n  // Added: per-environment override of the app-wide table defaults, same boolean-only discipline as above.\n  // TableDefaults.Pagination is deliberately allowed to be a number as well — a server admin tuning page\n  // size is the whole point of exposing it here, and \"PageSize: 15\" is what they will reach for.\n  if (settings.TableDefaults) {\n    const td = { ...(codeConfig.tableDefaults ?? {}) };\n    if (typeof settings.TableDefaults.RealTime === 'boolean') td.realTime = settings.TableDefaults.RealTime;\n    if (typeof settings.TableDefaults.RealTimeFallbackMs === 'number') td.realTimeFallbackMs = settings.TableDefaults.RealTimeFallbackMs; // Added: tunable per environment — a slow link may want a longer window than 3000\n\n    if (typeof settings.TableDefaults.Offline === 'boolean') td.offline = settings.TableDefaults.Offline;\n    if (typeof settings.TableDefaults.Pagination === 'boolean') td.pagination = settings.TableDefaults.Pagination;\n    if (typeof settings.TableDefaults.PageSize === 'number') td.pagination = { pageSize: settings.TableDefaults.PageSize };\n    merged.tableDefaults = td;\n  }\n  if (settings.Msal) {\n    merged.msal = {\n      clientId: settings.Msal.ClientId ?? codeConfig.msal?.clientId ?? '',\n      authority: settings.Msal.Authority ?? codeConfig.msal?.authority ?? '',\n      redirectUri: settings.Msal.RedirectUri ?? codeConfig.msal?.redirectUri ?? '',\n    };\n  }\n  return merged;\n}\n\nexport function tinSpaMsalInstanceFactory(config: TinSpaRuntimeConfig): IPublicClientApplication {\n  const wantsMsal = !!config.microsoftAuth;\n  const secure = typeof window === 'undefined' || window.isSecureContext;\n\n  // A credential is \"provided\" only if non-empty — appsettings.json ships empty strings as\n  // placeholders, and those must trigger the same diagnostics as a missing section.\n  const missing: string[] = [];\n  if (!config.msal?.clientId?.trim()) missing.push('ClientId');\n  if (!config.msal?.authority?.trim()) missing.push('Authority');\n\n  if (wantsMsal && missing.length) {\n    console.error(`[tin-spa] Microsoft SSO is enabled but its credentials are incomplete — missing: ${missing.join(', ')}. ` +\n      `Provide them in assets/appsettings.json under \"Msal\" (or in provideTinSpaRuntime({ msal })). Microsoft SSO is INACTIVE.`);\n  }\n  if (wantsMsal && !secure) {\n    console.warn('[tin-spa] microsoftAuth is enabled but the app is NOT running over HTTPS (secure context). Microsoft SSO is INACTIVE until served over HTTPS.');\n  }\n\n  const active = wantsMsal && !missing.length && secure;\n  if (!active) {\n    // Stub: MsalService's constructor calls instance.initializeWrapperLibrary(), so it must exist\n    // or the app crashes at bootstrap. loginPopup rejects so callers' error handlers report it.\n    return {\n      initializeWrapperLibrary: () => {},\n      initialize: () => Promise.resolve(),\n      getAllAccounts: () => [],\n      getActiveAccount: () => null,\n      loginPopup: () => Promise.reject(new Error(\n        !wantsMsal ? 'Microsoft login is disabled in app config.'\n          : missing.length ? `Microsoft login is not configured (missing: ${missing.join(', ')}).`\n          : 'Microsoft login requires HTTPS (a secure context).'\n      )),\n    } as unknown as IPublicClientApplication;\n  }\n\n  // RedirectUri rule: use the configured value when provided; otherwise fall back to\n  // `${origin}/login` — correct whenever each environment's own /login URL is registered\n  // on the app registration.\n  const redirectUri = config.msal!.redirectUri?.trim() || `${window.location.origin}/login`;\n  console.info(`[tin-spa] Microsoft SSO active — redirectUri: ${redirectUri}` +\n    (config.msal!.redirectUri?.trim() ? ' (configured)' : ' (not configured — derived from window.location.origin)'));\n\n  const pca = new PublicClientApplication({\n    auth: { ...config.msal!, redirectUri },\n    cache: { cacheLocation: BrowserCacheLocation.LocalStorage, storeAuthStateInCookie: false },\n  });\n  // MSAL v3 requires initialize() before any other API call. Kick it off now so it has\n  // normally completed by the time the user clicks a login button; callers still await\n  // initialize() themselves (it is idempotent) to close the race.\n  pca.initialize().catch(e => console.error('[tin-spa] MSAL initialize failed:', e));\n  return pca;\n}\n\n// ── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Wires up tin-spa runtime behaviours (routing strategy, real-time, MSAL) from a single config.\n * Add the result to your AppModule (or bootstrap) providers.\n */\nexport function provideTinSpaRuntime(config: Partial<TinSpaRuntimeConfig>): EnvironmentProviders {\n  const merged: TinSpaRuntimeConfig = { ...DEFAULTS, ...config };\n\n  return makeEnvironmentProviders([\n    // useFactory (not useValue): this function runs at module-import time, BEFORE main.ts has\n    // fetched assets/appsettings.json — the factory defers reading the file until injection.\n    { provide: TIN_SPA_RUNTIME_CONFIG, useFactory: () => tinSpaRuntimeConfigFactory(merged) },\n    {\n      provide: LocationStrategy,\n      useFactory: tinSpaLocationStrategyFactory,\n      deps: [PlatformLocation, [new Optional(), new Inject(APP_BASE_HREF)], TIN_SPA_RUNTIME_CONFIG],\n    },\n    // MSAL_INSTANCE is built lazily (when MsalService is first injected, i.e. on the login page),\n    // so it reads the config token rather than running at bootstrap.\n    { provide: MSAL_INSTANCE, useFactory: tinSpaMsalInstanceFactory, deps: [TIN_SPA_RUNTIME_CONFIG] },\n    MsalService,\n  ]);\n}\n","import { Injectable } from '@angular/core';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { MessageService } from './message.service';\n\n// Added: turns an HTTP failure into ONE friendly, non-technical message, and stops a burst of failures from\n// producing a wall of dialogs.\n//\n// Three problems this exists to solve, all previously visible to end users:\n//\n//  1. BLANK DIALOGS. The interceptor showed `error.error.Message`. When the backend is unreachable there is no\n//     JSON body at all — Angular puts a ProgressEvent on `error.error`, so `.Message` is undefined and the\n//     dialog rendered empty. The user saw \"Error\" and nothing else, which tells them nothing about whether it\n//     was their connection, their input, or a broken server.\n//\n//  2. TECHNICAL JARGON. The alternative branch showed raw server text. Statuses and stack traces are for the\n//     console, not for someone trying to capture a fuel receipt at a filling station.\n//\n//  3. DIALOG STORMS. Every failed request raised its own dialog. A dashboard firing 20 calls against a downed\n//     backend produced 20 dialogs — all blank, all saying the same nothing. Deduping is not cosmetic here: it\n//     is the difference between an app that looks broken and one that explains itself.\n\n// Added: 'appfailure' / 'appfailure-submit' cover a FOURTH problem, invisible to everything above.\n//\n//  4. HTTP 200 FAILURES. TinWeb's base controllers report application-level failures as\n//     `Ok(new RepoResponse { Success = false, Message = ... })` — status 200 with a failure body. Because the\n//     status is a success status, the HTTP interceptor never fires and none of `present()` above ever runs for\n//     them. Call sites handled these inline with `toast(\"Error: \" + apiResponse.message)`, so the user was NOT\n//     left in silence — but what they got was a 5-second snackbar at the bottom of the screen carrying raw\n//     server text like \"Error: Error processing request\" or \"Error: Invalid column name 'RequirePONumber'\".\n//\n//     Two things are wrong with that, and they are different problems needing different answers:\n//\n//       - The TEXT. \"Error processing request\" is the server's catch-all for an unhandled exception; \"Invalid\n//         column name\" is a leaked SQL fragment. Neither tells the user anything actionable, and both look\n//         alarming. These deserve the same friendly treatment the transport failures now get.\n//       - The SURFACE. Measured on a 1920x945 window with a create dialog open: the snackbar renders at\n//         y=891 — 569px BELOW the dialog's bottom edge — 312px wide, and lives exactly 5 seconds. It is not\n//         occluded (it draws above the modal backdrop), but it is far outside the region the user is looking\n//         at, and it is gone before a user who glanced at the form would ever notice it. Meanwhile the dialog\n//         stays open with the form still populated, so the obvious next move is to press Create again — which\n//         is how an opaque failure turns into a duplicate record.\n//\n//     A deliberate, human-authored message (\"Customer not found\", \"Invoice has no items\") has NEITHER problem:\n//     it is short, it is meaningful, and a non-blocking toast is the right weight for it. So this splits by\n//     what the message actually IS, rather than moving everything to a dialog — see classifyMessage().\n// Changed: added 'ratelimited'. A 429 previously had no branch at all in classify(), so it fell through to\n// 'unknown' — whose copy is \"Please try again\" — which is the one instruction a 429 forbids. Giving it its own\n// kind also gives it its own suppression key, so a burst of throttled calls yields one message, not a wall.\nexport type ApiErrorKind = 'network' | 'timeout' | 'ratelimited' | 'badrequest' | 'forbidden' | 'notfound' | 'server' | 'unavailable' | 'unknown' | 'appfailure' | 'appfailure-submit';\n\n// Added: what a 200-with-success:false message turns out to be. 'opaque' earns a dialog, 'business' stays a toast.\nexport type AppFailureClass = 'opaque' | 'business';\n\n// Added: where the failure happened. Only 'submit' is special — see presentAppFailure() for why it gets its own\n// dedupe key. 'load' (a table/tile fetching rows) and 'action' (a row button) share one.\nexport type AppFailureContext = 'submit' | 'load' | 'action';\n\nexport interface ApiErrorInfo {\n  kind: ApiErrorKind;\n  title: string;\n  message: string;\n  reference?: string; // Added: correlation code off a 5xx body — TinWeb's exception middleware now mints one, and quoting it is what makes the failure traceable in Logs\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ApiErrorService {\n\n  // One dialog per KIND per window. Keyed by kind rather than by URL on purpose: when the backend goes down,\n  // twenty different URLs fail for one single reason, and the user needs to be told that reason once.\n  private lastShownAt = new Map<ApiErrorKind, number>();\n\n  /** How long a given kind stays suppressed after being shown. The user described \"the same 10 seconds or so\". */\n  public suppressWindowMs = 10000;\n\n  // Added: submits dedupe over a much shorter window than background reads. Long enough to swallow a\n  // double-click or a duplicated emission, short enough that a user who reads the dialog, dismisses it and\n  // deliberately tries again is told again rather than met with silence.\n  public submitSuppressWindowMs = 1500;\n\n  constructor(private messageService: MessageService) { }\n\n  // Classification is by status code first, because that is the only signal that is reliable across browsers.\n  // `statusText === 'Unknown Error'` is kept as a secondary network signal since some browsers report a failed\n  // connection that way while still surfacing status 0.\n  classify(error: HttpErrorResponse): ApiErrorInfo {\n    const status = error?.status ?? 0;\n\n    // status 0 means the request never reached a server: offline, DNS failure, connection refused, CORS block.\n    // This is the single most common case for a field user and the one that was rendering blank.\n    if (status === 0 || error?.statusText === 'Unknown Error') {\n      return {\n        kind: 'network',\n        title: 'No connection',\n        message: `We couldn't reach the server. Please check your connection and try again.\\n\\n` + // Changed: \"internet connection\" → \"connection\" — on-premise/LAN installs have no internet in the path (owner directive 2026-08-18)\n                 `If your connection is working, the service may be temporarily unavailable — your work is not lost, and you can try again in a moment.`,\n      };\n    }\n\n    if (status === 408 || status === 504) {\n      return {\n        kind: 'timeout',\n        title: 'Taking too long',\n        message: `The server is taking longer than expected to respond.\\n\\nPlease wait a moment and try again.`,\n      };\n    }\n\n    // Added: 429 Too Many Requests. Before this branch existed a 429 reached the 'unknown' fall-through at the\n    // bottom of this method and told the user \"Please try again\" — inviting the exact retry the server just\n    // refused. On a token-bucket or sliding-window limiter every one of those retries extends the block rather\n    // than clearing it, so the friendly-sounding advice actively made the situation worse.\n    //\n    // Two further things this deliberately does NOT do:\n    //   * it does not read like the user's fault. A 429 is usually the app being chatty, or a shared office IP\n    //     hitting one limit for everyone — nothing the person at the keyboard did.\n    //   * it does not say \"contact your administrator\". This clears on its own; sending them to support for a\n    //     condition that resolves in under a minute wastes their time and support's.\n    // The one instruction is to WAIT, with a duration when the server told us one.\n    if (status === 429) {\n      return {\n        kind: 'ratelimited',\n        title: 'Busy right now',\n        message: `The server is handling more requests than it can take right now, so it has asked us to pause for a moment. Nothing was lost, and nothing is wrong with your work.\\n\\n` +\n                 `Please wait ${this.retryAfterText(error)} before trying that again — trying repeatedly makes the wait longer, not shorter.`,\n      };\n    }\n\n    if (status === 503) {\n      return {\n        kind: 'unavailable',\n        title: 'Service unavailable',\n        message: `The service is temporarily unavailable, usually because it is being updated.\\n\\nPlease try again in a few minutes.`,\n      };\n    }\n\n    // A 400 is almost never the user's doing — the app sent a payload the server rejected. Saying \"check your\n    // input\" would send them hunting for a mistake they did not make, so this points at support instead.\n    if (status === 400 || status === 422) {\n      return {\n        kind: 'badrequest',\n        title: 'Something went wrong',\n        message: `We couldn't complete that action because of a technical problem in the app — not anything you did wrong.\\n\\n` +\n                 `Please try again. If it keeps happening, contact your administrator so it can be looked into.`,\n      };\n    }\n\n    if (status === 403) {\n      return {\n        kind: 'forbidden',\n        title: 'Not allowed',\n        message: `You don't have permission to do that.\\n\\nIf you think you should, please contact your administrator.`,\n      };\n    }\n\n    if (status === 404) {\n      return {\n        kind: 'notfound',\n        title: 'Not found',\n        message: `We couldn't find what you were looking for. It may have been moved or deleted by someone else.\\n\\n` +\n                 `Try refreshing the page. If it keeps happening, contact your administrator.`,\n      };\n    }\n\n    if (status >= 500) {\n      return {\n        kind: 'server',\n        title: 'Something went wrong',\n        message: `The server ran into a problem while handling your request.\\n\\n` +\n                 `Please try again shortly. If it keeps happening, contact your administrator.`,\n      };\n    }\n\n    return {\n      kind: 'unknown',\n      title: 'Something went wrong',\n      message: `We couldn't complete that action.\\n\\nPlease try again. If it keeps happening, contact your administrator.`,\n    };\n  }\n\n  // Added: turns a Retry-After header into something a person can act on. RFC 9110 allows two forms — a delay\n  // in seconds (\"120\") or an HTTP-date (\"Wed, 21 Oct 2026 07:28:00 GMT\") — and both are handled because which\n  // one arrives depends on the proxy in front of the API, not on our own code.\n  //\n  // Seconds are rounded to the nearest 5 (and never below 5) rather than quoted exactly: \"wait about 30 seconds\"\n  // is followed, \"wait 27 seconds\" invites someone to watch a clock and retry one second early. When the header\n  // is missing or unparseable the phrasing stays deliberately vague — an honest approximation beats a precise\n  // number we invented, and a limiter we cannot see the window of is exactly when not to promise one.\n  private retryAfterText(error: HttpErrorResponse): string {\n    const seconds = this.retryAfterSeconds(error); // Changed: parsing moved to retryAfterSeconds() so the sync layer can share it — see below\n\n    if (!(seconds > 0)) return 'a minute or so';\n    if (seconds <= 90) return `about ${Math.max(5, Math.round(seconds / 5) * 5)} seconds`;\n\n    const minutes = Math.round(seconds / 60);\n    return `about ${minutes} minute${minutes === 1 ? '' : 's'}`;\n  }\n\n  // Added: the RAW parse, split out of retryAfterText() and made public so OfflineService can wait exactly as\n  // long as the server asked instead of guessing from an attempt count. It is deliberately ONE parser: the\n  // header has two legal forms (RFC 9110 delta-seconds and HTTP-date) and a second implementation of that would\n  // drift from this one the first time either is touched.\n  //\n  // Returns 0 — never a negative, never NaN — when the header is absent, malformed, or already in the past.\n  // Callers treat 0 as \"the server said nothing\", so a stale HTTP-date can never shorten a backoff to zero.\n  retryAfterSeconds(error: HttpErrorResponse): number {\n    const raw = (error?.headers?.get ? error.headers.get('Retry-After') : null)?.trim() ?? '';\n\n    let seconds = 0;\n    if (/^\\d+$/.test(raw)) {\n      seconds = parseInt(raw, 10);\n    } else if (raw) {\n      const at = Date.parse(raw);\n      if (!isNaN(at)) seconds = Math.round((at - Date.now()) / 1000);\n    }\n\n    return seconds > 0 ? seconds : 0;\n  }\n\n  /** True when this kind was already shown inside the suppression window — i.e. the user has already been told. */\n  // Changed: window is now a parameter (defaulting to the existing suppressWindowMs, so present() is unaffected)\n  // because a submit failure needs a much shorter one than a burst of background reads — see presentAppFailure().\n  private isSuppressed(kind: ApiErrorKind, windowMs: number = this.suppressWindowMs): boolean {\n    const last = this.lastShownAt.get(kind);\n    return last != null && (Date.now() - last) < windowMs;\n  }\n\n  // Presents at most ONE message per kind per window. The technical detail still goes to the console, where a\n  // developer wants it, so nothing is lost by keeping it out of the user's message.\n  //\n  // Changed: this comment used to read \"at most ONE dialog per kind\", and that stopped being true the moment\n  // 'ratelimited' gained its own branch below and went to a toast instead. What is uniform here is the\n  // SUPPRESSION — one message per kind per window — not the surface. The SURFACE is chosen per kind, and the\n  // 'ratelimited' block states the test for choosing it: a failure that is transient, self-clearing and\n  // presents the user with no decision to make does not earn a modal. Read that argument before adding a\n  // second exception; it is about weight, not about the specific status code.\n  present(error: HttpErrorResponse): ApiErrorInfo {\n    const info = this.classify(error);\n\n    // Added: a 5xx from TinWeb's exception middleware now carries \"(reference X)\" in its body Message —\n    // pull it out so the dialog can quote it as a footnote, exactly as presentAppFailure() does for the\n    // 200-with-success:false catch-alls. Only the 'server' kind can carry one; a transport failure has no\n    // body at all (error.error is a ProgressEvent), which extractReference() tolerates as null.\n    if (info.kind === 'server') {\n      const body: any = (error as any)?.error;\n      info.reference = this.extractReference(body?.Message ?? body?.message) ?? undefined;\n    }\n\n    console.error(`[tin-spa] API error (${info.kind})`, { status: error?.status, url: (error as any)?.url, reference: info.reference, error }); // Changed: log the reference so console and server log line tie together\n\n    if (this.isSuppressed(info.kind)) return info; // already told them — a second dialog adds nothing\n\n    this.lastShownAt.set(info.kind, Date.now());\n\n    // Changed: a 429 gets a TOAST, not the modal every other kind gets. It is the only kind here that is\n    // guaranteed transient and self-clearing — the server has already said, in Retry-After, exactly when it\n    // will stop refusing. A modal is the wrong weight for that in three specific ways:\n    //\n    //   * It BLOCKS. The user must dismiss a dialog to get back to work they were not prevented from doing —\n    //     nothing was rejected except one request, and the next one may well succeed.\n    //   * It DEMANDS a decision for a condition with no decision to make. The only correct action is to wait,\n    //     and waiting is what happens if the app says nothing at all.\n    //   * During an OFFLINE DRAIN it is actively wrong. The sync layer leaves the op queued and retries on its\n    //     own backoff, so a modal saying something went wrong directly contradicts the sync indicator in the\n    //     toolbar, which is showing work still pending and perfectly healthy.\n    //\n    // The suppression above is deliberately shared and applied BEFORE this branch: a burst of throttled calls —\n    // which is the normal shape of a 429, since whatever tripped the limit is usually firing repeatedly — still\n    // yields exactly ONE toast per window, not a stack of them.\n    //\n    // The toast text is NOT info.message. That is dialog copy: three sentences over two paragraphs, written to\n    // be read at leisure in a 600px box. This surface is a 5-second snackbar, so the copy is compressed to the\n    // three things that are load-bearing and nothing else — that the cause is the server and not them, roughly\n    // how long to leave it, and that their work survived. info.message is still returned unchanged for callers.\n    if (info.kind === 'ratelimited') {\n      this.messageService.toast(`The server is busy — please wait ${this.retryAfterText(error)} before trying again. Nothing was lost.`);\n      return info;\n    }\n\n    this.messageService.errorWithSubject(info.title, info.message, info.reference); // Changed: pass the reference through so the dialog renders the quiet footnote\n    return info;\n  }\n\n  //================ Application-level failures (HTTP 200 + success:false) ================\n\n  // Added: fragments that mark a message as machine-authored rather than human-authored. Matched\n  // case-insensitively against the whole message. The list is deliberately about IMPLEMENTATION LEAKS, not\n  // about severity — a leaked identifier is useless to the user however serious the underlying fault is.\n  private opaqueMarkers: string[] = [\n    // NOTE: matched as a SUBSTRING, never by equality. TinWeb's catch-all now appends a correlation code —\n    // \"Error processing request (reference K7M2QP4T)\" — so an equality test would classify every catch-all\n    // failure as a business message and show the raw text, which is worse than the behaviour this replaces.\n    'error processing request',   // TinWeb BaseController/BaseController2/BaseService catch-all — by far the most common\n    'invalid column name',        // SQL leaking through after a schema/migration drift\n    'sqlexception',\n    'object reference not set',\n    'an error occurred while',    // EF Core's standard preamble (\"...while updating the entries\")\n    'inner exception',\n    'stack trace',\n    'the underlying provider failed',\n    'index was outside the bounds',\n    'timeout expired',\n    'exception',                  // catches DbUpdateException, InvalidOperationException, ... by suffix\n\n    // Raw SqlException text.\n    //\n    // Changed: this block used to say \"TinCore's BaseRepository.SetErrorResp returns ex.InnerException.Message\n    // verbatim on HTTP 200 ... These never carry a correlation reference\". BOTH halves of that are now FALSE\n    // and were left standing after the backend was fixed underneath them. `BaseRepository.BuildSafeMessage`\n    // (`Sharp/TinCore/Repositories/BaseRepository.cs:382-400`, read 2026-08-09) now logs the real exception\n    // out-of-band and returns `ClassifyFailure(ex) + \" (reference X)\"` — a friendly sentence WITH a reference.\n    // So the schema leak this list was written against no longer comes from there, and the failures that\n    // reach us from there do carry a code. Believing the old comment would lead the next reader to delete\n    // these markers as obsolete, which is exactly the wrong conclusion — see below for why they still matter.\n    //\n    // These fragments are still LIVE, for two independent reasons, both verified rather than assumed:\n    //   1. Other server paths still return raw exception text on HTTP 200 and never went through\n    //      BaseRepository at all — e.g. `TinWeb/Services/Agent/AgentApiService.cs:391` and `:480` return\n    //      `ex.InnerException?.Message ?? ex.Message` verbatim, which for a bad foreign key is precisely\n    //      \"The INSERT statement conflicted with the FOREIGN KEY constraint ...\". The accounting services\n    //      leak the same way but one level UP — `InvoiceService:311/347/681/1007/1108`,\n    //      `CreditNoteService:184`, `RevenueScheduleService:95/248` return the OUTER `ex.Message`, which for a\n    //      DbUpdateException is \"An error occurred while updating the entries. See the inner exception for\n    //      details.\" That is why BOTH shapes are covered above: 'an error occurred while' and 'inner exception'\n    //      catch the outer form, the SQL phrases below catch the inner one. Neither list is redundant.\n    //   2. TinCore is consumed as a PACKAGE (`TinWeb.csproj` pins `TinCore 10.0.12`, the release that carries\n    //      this fix), so a consumer app on an older published TinCore still has the verbatim-`ex.Message`\n    //      behaviour. tin-spa ships to four SPAs that are not upgraded in step, and a classifier that assumes\n    //      the newest backend would leak schema on every one that lags. Their own APIs leak independently of\n    //      TinCore too — `Sharp/{Shift,Pulse,Piglet,Grip,Test}` carry ~39 hand-written `Message = ex.Message`\n    //      style returns that never touch BaseRepository at all.\n    //\n    // Two entries are kept WITHOUT a live producer, stated plainly rather than quietly: 'stack trace' and\n    // 'sqlexception' only appear in a full `ex.ToString()`, and no TinWeb/TinCore path puts one in a client\n    // Message today (checked 2026-08-09). They stay because a deny-list entry costs one `includes()` and the\n    // failure mode of removing one is a schema dump on a user's screen. Cheap insurance, not an oversight.\n    //\n    // Each fragment below is SQL Server's own wording. None of them can occur in a hand-authored message like\n    // \"Registration number already in use\" or \"Customer not found\", which is why they are matched as phrases\n    // rather than on single words such as \"duplicate\" or \"constraint\" that a human might legitimately write.\n    // Re-checked one by one against what the server produces today: none of the six friendly sentences\n    // `ClassifyFailure` can now return matches any marker here, so the fix upstream does not collide with\n    // this list — the good sentences stay 'business' and are shown, exactly as intended.\n    'statement conflicted with the',            // \"The INSERT statement conflicted with the FOREIGN KEY constraint ...\"\n    'foreign key constraint',\n    'unique key constraint',\n    'primary key constraint',\n    'check constraint',\n    'cannot insert the value null',\n    'string or binary data would be truncated',\n    'violation of ',                            // \"Violation of PRIMARY KEY constraint 'PK_...'\"\n    'duplicate key',                            // \"Cannot insert duplicate key row in object ...\"\n\n    // Added 2026-08-09, found by re-checking this list against the backend rather than against the old comment.\n    // `BaseRepository.ClassifyFailure` maps six recognisable SQL failures to genuinely useful sentences (\"A\n    // record with these details already exists.\", \"A required value is missing.\") — those are real business\n    // messages and correctly stay toasts. Its SEVENTH return is the unrecognised fall-through, and it is a\n    // different animal: \"Could not complete the operation. (reference X)\" is human-SHAPED but carries exactly\n    // as much information as \"Error processing request\" — which is the first entry in this list. It was being\n    // classified 'business' purely because it is grammatical.\n    //\n    // That misclassification cost the user the one thing that failure has going for it. `BuildSafeMessage`\n    // deliberately logs the real exception and mints a reference precisely BECAUSE it could not say what went\n    // wrong — so this is the case where quoting the code to support is the whole remedy. As a toast the code\n    // is stripped (uncopyable in 5 seconds, see presentAppFailure) and the user is left with a shrug. As a\n    // dialog it renders as the footnote the message dialog already has, which is where a reference belongs.\n    // Verified unique: this exact phrase occurs nowhere else in Sharp/** or in tin-spa, so it cannot shadow a\n    // hand-authored message.\n    'could not complete the operation',\n  ];\n\n  // Added: splits the server's message into 'opaque' (tells the user nothing, must not be shown raw) and\n  // 'business' (a deliberate sentence the backend author wrote for a human, genuinely worth reading).\n  //\n  // Written as a deny-list rather than an allow-list on purpose: business messages are open-ended and\n  // app-specific, so there is nothing to enumerate, whereas the ways a .NET exception leaks are few and stable.\n  // The consequence of the default is the safe one — an unrecognised message is treated as business and shown,\n  // so a real message is never swallowed; only recognisably technical text is replaced.\n  classifyMessage(message: string | null | undefined): AppFailureClass {\n    const text = this.stripReference(message); // Changed: classify the SENTENCE, not the sentence plus the server's appended \"(reference X)\" — see below\n\n    // Changed: the reference is removed before classifying for two concrete reasons, neither cosmetic.\n    // First, the length test at the bottom is a heuristic about human authorship, and a 22-character machine\n    // suffix should not push a 285-character human message over it. Second, a body that is ONLY \"(reference X)\"\n    // now strips to empty and falls into the line below rather than toasting a bare code at the user — which\n    // would be the blank-message failure this whole service exists to kill, in a new costume.\n    if (!text) return 'opaque'; // nothing to show — a blank toast is the very failure mode this service exists to kill\n\n    const lower = text.toLowerCase();\n\n    if (this.opaqueMarkers.some(marker => lower.includes(marker))) return 'opaque';\n\n    if (/\\bsystem\\.[a-z]/i.test(text)) return 'opaque';     // a .NET namespace (\"System.NullReferenceException\")\n    if (/\\bat\\s+[\\w.]+\\s*\\(/.test(text)) return 'opaque';   // a stack frame (\"at Namespace.Method(\")\n    // Changed: was `text.length > 300`, and it was a silent cliff. Length alone is not evidence of a dump, and\n    // this test was the ONLY marker here that can fire on text containing nothing technical whatsoever — so a\n    // deliberately-composed business refusal was replaced wholesale by \"We couldn't save that because of a\n    // technical problem.\" with no trace that anything had been dropped. The worst case measured on a real\n    // composed server message was 291 characters: NINE characters of headroom, and the next author to add a\n    // clause would have crossed it without ever seeing why.\n    //\n    // The four markers above are the ones that actually detect a dump, and they detect it by CONTENT: the\n    // opaqueMarkers deny-list (which already carries 'exception', 'stack trace', 'inner exception',\n    // 'object reference not set', 'sqlexception' and the constraint-violation family), the .NET-namespace test,\n    // and the stack-frame test. A genuine .NET dump cannot avoid all four — the type name alone trips\n    // 'exception' or /\\bsystem\\./ before length is ever consulted.\n    //\n    // Raised rather than deleted so a pathological multi-kilobyte body still has a backstop. 2000 is chosen to\n    // sit far above any composed human message (7x the worst one measured) and below a typical stack dump,\n    // and above 2000 characters the text is unreadable in a dialog anyway, so replacing it loses nothing.\n    if (text.length > 2000) return 'opaque';                // a body this long is a payload, not a sentence — see above\n\n    return 'business';\n  }\n\n  // Added: pulls TinWeb's correlation code out of a catch-all message. The backend writes the same code into\n  // its log line as \"[ref XXXXXXXX]\", so quoting it in the dialog is what lets support jump straight to the log\n  // row instead of hunting by timestamp.\n  //\n  // The alphabet is A-Z/2-9 with 0/O/1/I/L removed (they are misread down a phone line), and the code is 8\n  // characters — but the pattern accepts 6-12 so a future length change does not silently stop matching. The\n  // reference is only ever EXTRACTED here; the rest of the raw message is still discarded, never shown.\n  extractReference(message: string | null | undefined): string | null {\n    const match = (message ?? '').match(/\\breference\\s+([A-Z2-9]{6,12})\\b/i);\n    return match ? match[1].toUpperCase() : null;\n  }\n\n  // Added: the sibling to extractReference() — it takes the code OUT of the sentence. Nothing is lost by this,\n  // because extractReference() has already read the code off the same string and it still reaches the console\n  // line in presentAppFailure() and, where the surface can hold it, the dialog footnote.\n  //\n  // This exists because the backend changed shape. Every failure from BaseRepository.BuildSafeMessage and from\n  // TinWeb's controller catch-alls now ends in \"(reference XXXXXXXX)\", so the reference is no longer the rare\n  // case it was when this service was written — it is on the majority of application-level failures, including\n  // the friendly ones. In a DIALOG that code is an asset: the box stays open, it renders as a quiet footnote,\n  // and the user can copy it. In a 5-second toast it is the opposite. Nobody transcribes eight random\n  // characters from a snackbar before it fades, so all it does is push the words that DO matter — \"A record\n  // with these details already exists\" — further from the eye and make a helpful sentence read like a fault\n  // report. The rule this settles on: the reference belongs on surfaces that persist long enough to copy it.\n  //\n  // Deliberately requires the PARENTHESES rather than matching a bare \"reference XXXX\" anywhere in the text.\n  // Every server path that appends one — BaseRepository:399, BaseController:190/688, BaseController2:175/219,\n  // BaseService:112/134, ExceptionMiddleware — writes the parenthesised form, so requiring them costs nothing,\n  // and it means a hand-authored sentence that legitimately says \"quote reference on the invoice\" survives.\n  stripReference(message: string | null | undefined): string {\n    return (message ?? '')\n      .replace(/\\s*\\(\\s*reference\\s+[A-Z2-9]{6,12}\\s*\\)/gi, '')\n      .replace(/\\s{2,}/g, ' ')\n      .trim();\n  }\n\n  // Added: the sibling to present() for failures that arrive as HTTP 200 with success:false.\n  //\n  // Opaque  -> the friendly dialog, through the SAME lastShownAt suppression map present() uses, so a burst\n  //            (a dashboard firing twenty calls at a broken backend) still yields exactly one dialog.\n  // Business -> the existing toast, unchanged in weight. Short, meaningful, non-blocking.\n  //\n  // Why 'submit' gets its own dedupe key rather than sharing with loads: suppression exists to collapse a BURST\n  // of background calls that all failed for one reason. A create/edit submit is not part of a burst — it is one\n  // deliberate action, and it is the exact case where a missed message leads the user to press the button again\n  // and duplicate the record. Sharing a key would let unrelated background load failures suppress the dialog\n  // for the one interaction that most needs it. Keeping a (short) window on the submit key still collapses a\n  // double-click, while letting a genuine retry a few seconds later speak up again.\n  presentAppFailure(response: { message?: string } | null | undefined, context: AppFailureContext = 'action', url?: string): AppFailureClass {\n    const message = response?.message;\n    const failureClass = this.classifyMessage(message);\n\n    // Always log the raw response and URL, exactly as present() does — the developer loses nothing by the\n    // dialog being friendly, because the technical detail is right here.\n    const reference = this.extractReference(message); // Added: null for SqlException leaks and older backends, which never mint one\n\n    console.error(`[tin-spa] API failure (${failureClass}/${context})`, { url, message, reference, response }); // Changed: log the reference too, so the browser console and the server log line can be tied together\n\n    if (failureClass === 'business') {\n      // Changed: dropped the \"Error: \" prefix that every call site used to prepend. Verified nothing depends on\n      // it — no test in ng-space or any of the four consumer apps asserts on the literal \"Error: \". The prefix\n      // only ever restated what the red-tinted message already conveyed, and it pushed the useful words right.\n      //\n      // Changed: the toast now shows the message with \"(reference X)\" REMOVED. This is the same argument as the\n      // dropped prefix, one step further. Since TinCore 10.0.12 every BaseRepository failure — including the\n      // GOOD ones — arrives as `ClassifyFailure(ex) + \" (reference X)\"`, so a genuinely useful sentence now\n      // reads \"A record with these details already exists. (reference K7M2QP4T)\". Twenty-two characters of\n      // machine correlation sit where the eye stops, on a surface that lives five seconds and cannot be copied\n      // from, and they change how the sentence is READ: a helpful instruction starts to look like a fault\n      // report. The code is not lost — extractReference() has already read it off the same string and it is on\n      // the console line above, where the developer who can use it is looking.\n      //\n      // The surface, deliberately, is MessageService.toast EXACTLY AS IT IS — no new variant, no second\n      // argument, nothing added to the toast API. The toast surface belongs to WS-7 and the whole correction\n      // here is which characters are handed to it.\n      //\n      // Safe by construction: classifyMessage() strips the same suffix and returns 'opaque' when what remains\n      // is empty, so a body that was ONLY \"(reference X)\" never reaches this branch and this can never toast\n      // an empty string.\n      this.messageService.toast(this.stripReference(message));\n      return failureClass;\n    }\n\n    const kind: ApiErrorKind = context === 'submit' ? 'appfailure-submit' : 'appfailure';\n\n    if (this.isSuppressed(kind, context === 'submit' ? this.submitSuppressWindowMs : this.suppressWindowMs)) return failureClass;\n\n    this.lastShownAt.set(kind, Date.now());\n\n    // Copy matches classify() above: name the problem, absolve the user, say what to do next. The submit\n    // variant adds the two things that specifically stop a duplicate — that the data is still there, and that\n    // pressing the button again is not the fix.\n    // Changed: the reference is passed as its own argument rather than appended to the body, so the dialog can\n    // render it as a quiet footnote. It is omitted entirely when there isn't one — a SqlException leak and an\n    // older backend both arrive without a reference, and neither should show a dangling \"quote reference\" line.\n    if (context === 'submit') {\n      this.messageService.errorWithSubject(\n        'Not saved',\n        `We couldn't save that because of a technical problem — not anything you did wrong.\\n\\n` +\n        `Nothing was saved, and your details are still on the form, so you can try again without re-entering them.\\n\\n` +\n        `If it keeps happening, please contact your administrator rather than submitting repeatedly, as that can create duplicates.`,\n        reference ?? undefined\n      );\n    } else {\n      this.messageService.errorWithSubject(\n        'Something went wrong',\n        `We couldn't complete that action because of a technical problem — not anything you did wrong.\\n\\n` +\n        `Please try again. If it keeps happening, contact your administrator.`,\n        reference ?? undefined\n      );\n    }\n\n    return failureClass;\n  }\n\n  /** Clears suppression so the next failure speaks up again — call after a successful request or reconnect. */\n  reset() {\n    this.lastShownAt.clear();\n  }\n}\n","import { Injectable, Optional, Inject } from '@angular/core';\nimport * as signalR from '@microsoft/signalr';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport { TIN_SPA_RUNTIME_CONFIG, TinSpaRuntimeConfig } from '../runtime/tinspa-runtime';\n\n// Entity change event interface for real-time table updates\nexport interface EntityChangeEvent {\n  entityName: string;\n  data: any;\n}\n\n// Changed: Notification toast event from backend NotificationService\nexport interface NotificationEvent {\n  message: string;\n  category: string;\n  type: string;\n  sender: string;\n}\n\n// Added (GPS phase 4): the live vehicle position frame, exactly as the server broadcasts it on the\n// data_{tenantId} group. Six scalars and no entity payload — that is the whole point of it being its own\n// hub method rather than an EntityUpdated on Vehicle.\nexport interface VehiclePositionFrame {\n  vehicleID: number;\n  lat: number;\n  lng: number;\n  at: string;\n  speed?: number | null;\n  heading?: number | null;\n}\n\n// Changed: Consolidated SignalR service — single hub connection for both notifications and entity broadcasts\n@Injectable({ providedIn: 'root' })\nexport class SignalRService {\n  private hubConnection: signalR.HubConnection | null = null;\n  private notificationCount = new BehaviorSubject<number>(0);\n  notificationCount$ = this.notificationCount.asObservable();\n\n  private entityCreated = new Subject<EntityChangeEvent>();\n  private entityUpdated = new Subject<EntityChangeEvent>();\n  private entityDeleted = new Subject<EntityChangeEvent>();\n  entityCreated$ = this.entityCreated.asObservable();\n  entityUpdated$ = this.entityUpdated.asObservable();\n  entityDeleted$ = this.entityDeleted.asObservable();\n\n  // Added (GPS phase 4): the position stream. A plain Subject, so a page that is not showing a map pays\n  // nothing for it, and a page that is subscribes for exactly as long as it is open.\n  private vehiclePosition = new Subject<VehiclePositionFrame>();\n  vehiclePosition$ = this.vehiclePosition.asObservable();\n\n  // Changed: Observable for notification toast events from backend NotificationService\n  private notificationReceived = new Subject<NotificationEvent>();\n  notificationReceived$ = this.notificationReceived.asObservable();\n\n  // Changed: Agent chat message and typing indicator streams (renamed from assistant*)\n  private agentMessage = new Subject<any>();\n  private agentTyping = new Subject<boolean>();\n  agentMessage$ = this.agentMessage.asObservable();\n  agentTyping$ = this.agentTyping.asObservable();\n\n  // Callback for reconnection — notification count refresh (set by NotificationsService)\n  onReconnected: (() => void) | null = null;\n  // Changed: this comment used to read \"tables should reload (set by table components)\" and was WRONG in the way\n  // that costs the most — it described a behaviour nobody had built. The slot has been declared since 1edd335\n  // (2026-03-23) and is invoked on both reconnect paths below, but NOTHING HAS EVER ASSIGNED IT\n  // (`git log --all -G\"onDataReconnected\\s*=\\s*\\(\"` is empty), so reconnect never reloaded any table and the\n  // comment made that look intentional. Reconnect refresh now lives in TableComponent.setupReconnectRefresh(),\n  // which subscribes to dataHubConnected$ (and OfflineService.online$) per table — a single-slot callback cannot\n  // serve the N tables one page may hold, which is why it is not filled in here.\n  // KEPT, not deleted: it is a public field on a published library service, so removing it is a breaking change\n  // for any consumer that assigns it. It remains available as a general \"the data hub came back\" hook.\n  onDataReconnected: (() => void) | null = null;\n\n  // Changed: Single connection state observable — used by real-time table indicators\n  private dataHubConnected = new BehaviorSubject<boolean>(false);\n  dataHubConnected$ = this.dataHubConnected.asObservable();\n\n  private currentToken: string = ''; // Changed: Live token reference for SignalR reconnection\n\n  // Changed: real-time is now driven centrally by tin-spa runtime config (provideTinSpaRuntime).\n  constructor(\n    @Optional() @Inject(TIN_SPA_RUNTIME_CONFIG) private runtimeConfig: TinSpaRuntimeConfig | null,\n  ) {}\n\n  /** Effective real-time enablement: legacy E2E kill-switch wins, else the configured runtime flag. */\n  private realTimeEnabled(): boolean {\n    if (typeof localStorage !== 'undefined' && localStorage.getItem('disableRealTime') === 'true') return false; // legacy/E2E override\n    return this.runtimeConfig ? !!this.runtimeConfig.realTime : false;\n  }\n\n  /** Public: whether SignalR is the authoritative connection signal (used by OfflineService to pick SignalR vs ping). */\n  get isRealTime(): boolean { return this.realTimeEnabled(); }\n\n  // Changed: Single startConnection method handles both notification and entity change listeners\n  startConnection(hubUrl: string, token: string) {\n    // Real-time disabled (by config or override) -> do not connect.\n    if (!this.realTimeEnabled()) return;\n\n    this.currentToken = token; // Changed: Store token so it can be updated after refresh\n    if (this.hubConnection && this.hubConnection.state !== signalR.HubConnectionState.Disconnected) return;\n    if (this.hubConnection) this.stopConnection();\n\n    this.hubConnection = new signalR.HubConnectionBuilder()\n      .withUrl(hubUrl, { accessTokenFactory: () => this.currentToken }) // Changed: Use live reference so reconnections use the latest token\n      .withAutomaticReconnect([0, 2000, 5000, 10000, 30000, 60000, 60000, 60000, 60000, 60000]) // Changed: Extended retry policy for entity broadcast reliability\n      .build();\n\n    // Changed: Notification count listener (previously on separate notification hub)\n    this.hubConnection.on('ReceiveNotificationCount', (count: number) => {\n      this.notificationCount.next(count);\n    });\n\n    // Changed: Notification toast listener — receives full notification from backend NotificationService\n    this.hubConnection.on('ReceiveNotification', (event: NotificationEvent) => {\n      this.notificationReceived.next(event);\n    });\n\n    // Changed: Agent chat listeners for real-time message delivery (renamed from Assistant*)\n    this.hubConnection.on('ReceiveAgentMessage', (msg: any) => {\n      this.agentMessage.next(msg);\n    });\n\n    this.hubConnection.on('AgentTyping', (typing: boolean) => {\n      this.agentTyping.next(typing);\n    });\n\n    // Changed: Entity CRUD listeners (previously on separate data hub)\n    this.hubConnection.on('EntityCreated', (entityName: string, data: any) => {\n      this.entityCreated.next({ entityName, data });\n    });\n\n    this.hubConnection.on('EntityUpdated', (entityName: string, data: any) => {\n      this.entityUpdated.next({ entityName, data });\n    });\n\n    this.hubConnection.on('EntityDeleted', (entityName: string, data: any) => {\n      this.entityDeleted.next({ entityName, data });\n    });\n\n    // Added (GPS phase 4): live vehicle position frames. Deliberately a SEPARATE hub method from the\n    // Entity* trio and not routed through them — a position carries six scalars and must never trigger\n    // the table-reload machinery those events drive. The frame is emitted verbatim; mapping it to the\n    // map's MapPositionUpdate shape is the consumer's job, so this service stays free of map types.\n    this.hubConnection.on('VehiclePosition', (frame: VehiclePositionFrame) => {\n      this.vehiclePosition.next(frame);\n    });\n\n    // Changed: Single reconnect handler covers both notification refresh and table reload\n    this.hubConnection.onreconnected(() => {\n      this.dataHubConnected.next(true);\n      if (this.onReconnected) this.onReconnected();\n      if (this.onDataReconnected) this.onDataReconnected();\n    });\n\n    // Changed: Track disconnection state for connection indicator\n    this.hubConnection.onclose(() => {\n      this.dataHubConnected.next(false);\n      setTimeout(() => {\n        if (this.hubConnection?.state === signalR.HubConnectionState.Disconnected) {\n          this.hubConnection.start()\n            .then(() => this.dataHubConnected.next(true))\n            .catch(() => this.dataHubConnected.next(false));\n        }\n      }, 60000);\n    });\n    this.hubConnection.onreconnecting(() => this.dataHubConnected.next(false));\n\n    this.hubConnection.start()\n      .then(() => this.dataHubConnected.next(true))\n      .catch(err => {\n        this.dataHubConnected.next(false);\n        console.error('SignalR connection error:', err);\n      });\n  }\n\n  // Changed: Update the token used for SignalR reconnection (called after silent refresh)\n  updateToken(token: string) {\n    this.currentToken = token;\n  }\n\n  private forcingReconnect = false;\n\n  /**\n   * Reconnect the hub NOW if real-time is enabled and the connection isn't up. Driven by OfflineService\n   * connectivity (the ping heartbeat) so the real-time indicator recovers on the SAME signal that flips the\n   * offline indicator back to online — they stay married \"hand in glove\". Handles both states the built-in\n   * auto-reconnect leaves us in: Reconnecting (stuck waiting on a long backoff interval → interrupt and connect\n   * now) and Disconnected (auto-reconnect exhausted after a long outage → start fresh). Safe to call repeatedly.\n   */\n  reconnectIfNeeded() {\n    if (!this.realTimeEnabled()) return;\n    if (!this.hubConnection) return; // never started (pre-login) — startConnection() will build it\n    const State = signalR.HubConnectionState;\n    const state = this.hubConnection.state;\n    if (state === State.Connected || state === State.Connecting) return; // already good / initial connect in flight\n    if (this.forcingReconnect) return; // a forced reconnect is already underway\n\n    this.forcingReconnect = true;\n    const start = () => this.hubConnection!.start()\n      .then(() => {\n        this.dataHubConnected.next(true);\n        if (this.onReconnected) this.onReconnected();\n        if (this.onDataReconnected) this.onDataReconnected();\n      })\n      .catch(() => this.dataHubConnected.next(false))\n      .finally(() => { this.forcingReconnect = false; });\n\n    if (state === State.Reconnecting) {\n      this.hubConnection.stop().finally(start); // interrupt the backoff wait, then connect immediately\n    } else {\n      start(); // Disconnected\n    }\n  }\n\n  stopConnection() {\n    if (this.hubConnection) {\n      this.hubConnection.stop();\n      this.hubConnection = null;\n      this.dataHubConnected.next(false); // Changed: Mark disconnected on stop\n    }\n  }\n}\n","import { Injectable, NgZone, Optional, Inject } from '@angular/core';\nimport Dexie, { liveQuery, Table } from 'dexie';\nimport { BehaviorSubject, from, Observable, of, Subject, firstValueFrom, timeout, throwError } from 'rxjs';\nimport { catchError, map, tap } from 'rxjs/operators';\nimport { Action, ApiResponse, Button, Constants, FormConfig, OfflineConfig, OfflineOpStatus, TableConfig } from '../classes/Classes'; // Changed: Button — registerLookups now walks a button's detailsConfig form (two-step create)\nimport { HttpService } from './http.service';\nimport { AuthService } from './auth.service';\nimport { StorageService } from './storage.service';\nimport { MessageService } from './message.service';\nimport { ApiErrorService } from './api-error.service'; // Added: for its Retry-After parser — the drain must wait as long as the SERVER asked, not as long as it guessed\nimport { SignalRService } from './signalr.service';\nimport { TIN_SPA_RUNTIME_CONFIG, TinSpaRuntimeConfig } from '../runtime/tinspa-runtime';\n\n// TinSync — the single offline subsystem service. Merges the read cache, outbox store, connectivity\n// detection, and sync engine into one cohesive unit so the whole feature reads top-to-bottom.\n// Everything is inert until a TableConfig with `offline` registers: no IndexedDB is opened and no\n// connectivity work runs (except the toolbar indicator, which starts connectivity to show a status light).\n\n//---------------- Internal types ----------------\n\ninterface ResolvedOfflineConfig {\n  enabled: boolean;\n  cacheRows: number;\n  cacheLookups: boolean | string[];\n  lookupMaxAgeHours: number;\n  queue: { create: boolean; edit: boolean; delete: boolean };\n  maxQueueAgeHours: number;\n  readOnly: boolean;\n}\n\nexport interface OfflineEntry {\n  entity: string;       // URL entity segment, e.g. 'categories' — the cache/queue namespace\n  entityName: string;   // display/SignalR name, e.g. 'Category'\n  idField: string;      // entity id property on rows, e.g. 'categoryID'\n  config: ResolvedOfflineConfig;\n}\n\nexport interface OutboxOp {\n  seq?: number;                              // Dexie auto-increment — the strict FIFO order\n  opId: string;                              // stable per-op UUID, generated at enqueue\n  entity: string;\n  entityName: string;\n  url: string;                               // e.g. 'categories?action=create'\n  opAction: 'create' | 'edit' | 'delete';\n  payload: any;\n  clientRef?: string;                        // creates only — server-side idempotency key\n  targetId?: any;                            // edits/deletes of server rows\n  targetClientRef?: string;                  // edits/deletes of still-pending offline creates\n  refMap?: { [field: string]: string };      // FK field -> parent clientRef (server resolves via ClientRefs)\n  status: OfflineOpStatus;\n  attempts: number;\n  lastError?: string;\n  serverRecord?: any;                        // current server row, parked on conflict\n  maxAgeHours: number;\n  userId: string;\n  enqueuedAt: number;\n  syncedAt?: number;\n}\n\ninterface CachedRead {\n  url: string;      // relative URL — same key CallApi's in-memory cache uses\n  entity: string;\n  data: any;\n  savedAt: number;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class OfflineService {\n\n  //================ Connectivity (public) ================\n  online$ = new BehaviorSubject<boolean>(typeof navigator === 'undefined' ? true : navigator.onLine);\n  // Entities whose ops synced in the last drain — tables listen to refetch (push-then-pull)\n  drained$ = new Subject<string[]>();\n\n  //---------------- Dexie ----------------\n  private db: Dexie | null = null;\n  private reads!: Table<CachedRead, string>;\n  private outbox!: Table<OutboxOp, number>;\n  private meta!: Table<{ key: string, value: any }, string>;\n\n  //---------------- Registry ----------------\n  private entries = new Map<string, OfflineEntry>();\n  private readUrls = new Map<string, OfflineEntry>();\n  private readPrefixes: { prefix: string, entry: OfflineEntry }[] = [];\n  registered$ = new BehaviorSubject<boolean>(false);\n\n  //---------------- Runtime flags ----------------\n  private connectivityStarted = false;\n  private syncStarted = false;\n  private draining = false;\n  private backoffTimer: any = null;\n  // Added: how long the SERVER asked us to wait, in ms, from the Retry-After on the failure that just halted the\n  // drain — or null when it said nothing. Written by sendOp(), read once by drainLoop() on the very next line\n  // after it returns, so it is never stale: sendOp() clears it on entry, before any I/O.\n  private serverRetryAfterMs: number | null = null;\n  // Added: epoch ms before which no AUTOMATIC drain may send, set only when the SERVER stated a Retry-After.\n  // Never set from the guessed attempt-count backoff — a reconnect drain jumping a guess is harmless and useful;\n  // jumping an instruction is not.\n  private retryNotBefore = 0;\n  private periodicTimer: any = null;\n  private recoveryTimer: any = null;\n\n  constructor(\n    private httpService: HttpService,\n    private authService: AuthService,\n    private storage: StorageService,\n    private messageService: MessageService,\n    private apiErrorService: ApiErrorService, // Added: shares ONE Retry-After parser with the dialog/toast path\n    private signalR: SignalRService,\n    private zone: NgZone,\n    @Optional() @Inject(TIN_SPA_RUNTIME_CONFIG) private runtimeConfig: TinSpaRuntimeConfig | null,\n  ) { }\n\n  /** App-level gate: offline capability only runs when the app opts in via provideTinSpaRuntime({ offline: true }).\n   *  When off, register()/ensureConnectivity() no-op, so a consumer that never uses offline runs none of this. */\n  get enabled(): boolean { return !!this.runtimeConfig?.offline; }\n\n  get hasAny(): boolean { return this.entries.size > 0; }\n  get online(): boolean { return this.online$.value; }\n\n  // Added: \"this app is actively tracking connectivity AND currently believes it is offline.\"\n  //\n  // Deliberately NOT the same as `!online`. online$ is seeded from navigator.onLine at construction, and in an\n  // app that never opts into offline capability ensureConnectivity() returns early, so that seed is never\n  // corrected by a ping. A consumer whose page happened to load while navigator.onLine was false would then\n  // report `!online === true` FOREVER. Requiring connectivityStarted means this can only be true when a live\n  // ping heartbeat is the thing asserting it — i.e. when the offline indicator is genuinely up and the recovery\n  // poll is genuinely running, which is the state the interceptor's suppression is entitled to reason about.\n  get knownOffline(): boolean { return this.connectivityStarted && !this.online$.value; }\n\n  //================ Sync page view ================\n  // Live, display-ready outbox rows (summary + status label projected on) for the sync page's spa-table.\n  outboxView$(): Observable<any[]> {\n    return this.activeOps$().pipe(\n      map(ops => ops.map(op => ({ ...op, summary: this.summarize(op), statusLabel: this.statusLabel(op) })))\n    );\n  }\n\n  private summarize(op: OutboxOp): string {\n    const p = op.payload ?? {};\n    if (typeof p.name === 'string' && p.name) return p.name;\n    const firstString = Object.keys(p).map(k => p[k]).find(v => typeof v === 'string' && v.length > 0 && v.length < 60);\n    return firstString ?? (op.targetId != null ? `#${op.targetId}` : 'new record');\n  }\n\n  private statusLabel(op: OutboxOp): string {\n    switch (op.status) {\n      case 'failed': return 'Failed';\n      case 'conflict': return 'Conflict';\n      case 'stale': return 'Held';\n      case 'syncing': return 'Sending';\n      default: return 'Pending';\n    }\n  }\n\n  //================ Registry ================\n\n  // Called from TableComponent when a config with `offline` initializes; ONE entry per entity, but the\n  // entity's READ SURFACE is additive — see registerReads\n  register(config: TableConfig): OfflineEntry | null {\n    if (!this.enabled) return null; // app-level gate: ignore per-table offline flags when the app didn't opt in\n    const resolved = this.resolveConfig(config.offline);\n    if (!resolved || !config.loadAction?.url) return null;\n\n    const entity = config.loadAction.url.split('/')[0].split('?')[0];\n    const existing = this.entries.get(entity);\n    // Changed: a second table on an already-registered entity used to return here WITHOUT contributing its own\n    // url, so a nested detail tab (`receipts/purchase/5`) and a sibling grid (`invoices/customer-all/x`) could\n    // never enter the read seam at all — nothing cached, nothing served, and the Connection Error toast not\n    // suppressed either. It now registers its read surface against the existing entry. The ENTRY itself\n    // (idField, resolved offline config, outbox behaviour) still belongs to whichever table registered first,\n    // deliberately: two tables on one entity share one outbox, and a second, DIFFERING `offline` block on the\n    // same entity is a config smell to surface rather than something to merge silently.\n    // Changed: the second table now also contributes its LOOKUPS, not only its reads. Registering reads here\n    // (above) but not lookups left the same defect one level up, and it is decided by RENDER ORDER, which no\n    // config can control: whichever table claims the entity first is the only one whose form and button-dialog\n    // selects ever enter the read seam. The live shape, verified in shift-spa: `driver.service.ts:39` spreads\n    // `tripsTableConfig` onto `trips/driver/x` and FILTERS the buttons down to checkout/checkin/view, dropping\n    // the trip-create button whose `detailsConfig.formConfig` is the sole declarer of `allocTemplates/list/x`\n    // and `triptemplates/list/x`. Open a driver before the Trips grid and those two urls are never registered,\n    // never cached, and the offline create dialog opens with two EMPTY required selects — exactly the gap\n    // `registerButtonLookups` was added to close, defeated by the order the user happened to navigate in.\n    // `driverLoadsTableConfig:57` filters loads' buttons the same way.\n    //\n    // Safe by the same construction registerReads already relies on: registerLookups() dedupes on\n    // `readUrls.has(url)` so re-registering costs nothing, and it filters through `existing.config.cacheLookups`\n    // — the FIRST config's allowlist, deliberately, because the ENTRY (and therefore the offline contract for\n    // this entity) still belongs to whoever registered first. Additive only: a url can be gained here, never\n    // lost, and registration alone writes no storage — a cache entry appears only when the url is fetched\n    // online (handleOfflineRead).\n    if (existing) {\n      this.registerReads(config, existing);\n      this.registerLookups(config.formConfig, existing);\n      this.registerButtonLookups(config.buttons, existing);\n      this.startSync();\n      return existing;\n    }\n\n    const entry: OfflineEntry = {\n      entity,\n      entityName: config.entityName ?? entity,\n      idField: (config.formConfig?.heroField ?? config.heroField ?? entity.replace(/s$/, '') + 'ID') as string,\n      config: resolved,\n    };\n\n    this.entries.set(entity, entry);\n    if (!this.registered$.value) this.registered$.next(true);\n    this.registerReads(config, entry);\n    this.registerLookups(config.formConfig, entry);\n    this.registerButtonLookups(config.buttons, entry); // Added: the two-step-create dialog's form lives on a BUTTON, not on config.formConfig — see below\n\n    this.startSync();\n    return entry;\n  }\n\n  // Added: one table's whole read surface, registered against `entry`. Runs for the first table to claim an\n  // entity AND for every later one, which is what makes nested tabs and sibling grids addressable.\n  //\n  // ⚠️ MATCHING is by PREFIX; CACHE KEYING stays by full url. Conflating the two is the version of this change\n  // that looks correct and quietly corrupts the cache — the same failure P2 hit with paged chunks, one level\n  // up. `receipts/purchase/5` and `receipts/purchase/7` are DIFFERENT RESOURCES (different rows), unlike\n  // `?skip=&take=`, which is a window over ONE resource; a tile url is likewise a filtered subset of the grid.\n  // So a prefix lets them all MATCH, while each keeps its own cache entry — parent 7's tab can never be served\n  // parent 5's receipts, and a tile view can never be written over the full list's accumulated window.\n  // `cacheKey()` therefore still strips paging params and NOTHING ELSE; do not \"tidy\" it to strip the id\n  // segment. Key-space growth is bounded per parent visited (not per scroll gesture, which is why P2 rejected\n  // full-url keying for paging) and is capped again by pruneDynamicReads().\n  private registerReads(config: TableConfig, entry: OfflineEntry) {\n    // A child tab's url is rewritten per parent BEFORE this runs (`<entity>/<loadCriteria>/<id>` — TinCore.ts\n    // transformLoadUrl, detailsDialog.component.ts) and rewritten again after a keep-open create. So the id we\n    // happen to see is worthless; `loadCriteria` is the config-declared, stable stem, and covers the\n    // placeholder form (`.../x`) the table may have registered with before the parent resolved.\n    if (config.loadCriteria) this.addReadPrefix(`${entry.entity}/${config.loadCriteria}/`, entry);\n    if (config.formConfig?.loadAction?.url) this.addReadPrefix(config.formConfig.loadAction.url + '/', entry);\n\n    if (config.loadAction?.url) this.addReadUrl(config.loadAction.url, entry);\n    if (config.countAction?.url) this.addReadUrl(config.countAction.url, entry);\n    // Tile clicks REPLACE config.loadAction wholesale (TableComponent.tileClicked) with a url the registry was\n    // never handed, so a tile view on an offline table silently left the seam. Tile urls are declared in the\n    // config, so register them exactly — no wildcard needed. Same-entity guard because a tile may point at\n    // another endpoint entirely. tileConfig.loadAction (the COUNTS/summary call) is deliberately NOT\n    // registered: a cached aggregate is a stale number with nothing to say it is stale, which is the reason\n    // the Phase 2 sweep skipped every report grid.\n    config.tileConfig?.tiles?.forEach(t => {\n      const url = t.action?.url;\n      if (url && url.split('/')[0].split('?')[0] === entry.entity) this.addReadUrl(url, entry);\n    });\n  }\n\n  private addReadPrefix(prefix: string, entry: OfflineEntry) {\n    if (!this.readPrefixes.some(p => p.prefix === prefix && p.entry === entry)) this.readPrefixes.push({ prefix, entry });\n  }\n\n  // Skips a url one of this entry's own prefixes already covers, so revisiting parent after parent cannot grow\n  // the map — the per-parent url is matched by the stem, never accumulated.\n  private addReadUrl(url: string, entry: OfflineEntry) {\n    if (this.readUrls.has(url)) return;\n    if (this.readPrefixes.some(p => p.entry === entry && url.startsWith(p.prefix))) return;\n    this.readUrls.set(url, entry);\n  }\n\n  private registerLookups(formConfig: FormConfig | undefined, entry: OfflineEntry, depth: number = 0) {\n    if (!formConfig?.fields || depth > 1) return;\n    const allow = entry.config.cacheLookups;\n    if (allow === false) return;\n    formConfig.fields.forEach((field: any) => {\n      const url = field.loadAction?.url;\n      if (url && (allow === true || (Array.isArray(allow) && allow.includes(url)))) {\n        if (!this.readUrls.has(url)) this.readUrls.set(url, entry);\n      }\n      if (field.detailsConfig?.formConfig) this.registerLookups(field.detailsConfig.formConfig, entry, depth + 1);\n    });\n  }\n\n  // Added: the TWO-STEP CREATE gap. CLAUDE.md's documented pattern (Invoice, Sales/Purchase Order, Requisition,\n  // Production Recipe/Order, Trip, Rental, Bundle/Check Template, Checklist, Alloc Template — 12 entities) puts the\n  // real create form on `button.detailsConfig.formConfig`, NOT on `tableConfig.formConfig`. registerLookups only ever\n  // walked the latter, so those forms' selects were never in the read seam: the urls were fetched online and thrown\n  // away, and offline the dialog opened with every dropdown empty. Where a select is `required` that is not a\n  // degraded form, it is an UNSUBMITTABLE one — the write queue behind it was unreachable from the UI.\n  // (Observed, WS-1 trips/loads: opening Shift's trip-create dialog ONLINE cached vehicles/trailers/drivers — the\n  // three the TABLE form declares — and not triptemplates or allocTemplates, which only the BUTTON form declares.)\n  //\n  // ⚠️ BOUNDED DELIBERATELY, and the boundary is not arbitrary — it is \"does anything else already register this?\":\n  //  • BUTTON detailsConfig forms ARE walked. A dialog form is not a spa-table; nothing else ever registers it, so\n  //    if this does not, nothing does.\n  //  • detailsConfig.tableConfigs are NOT walked. A nested tab renders through <spa-table> (tabs.component.html),\n  //    so its TableComponent calls offline.register() itself and registers its own reads AND its own lookups under\n  //    its OWN entity, cacheLookups allowlist and cacheRows. Walking them here would re-register another entity's\n  //    lookups under THIS entity's allowlist — duplicate work, filtered by the wrong config.\n  //  • detailsConfig.buttons are NOT walked, and neither are column detailsConfigs: one level of button is what the\n  //    documented pattern needs, and each extra level multiplies the walk for configs that share dialogs anyway.\n  // Depth inside each form is unchanged — a button form enters registerLookups at depth 0, exactly like the table's\n  // own form, so its fields' quick-add (\"Add New\") forms still register and nothing deeper does.\n  // VOLUME: this only makes a url MATCHABLE; a cache entry is written solely when that url is actually fetched while\n  // online (handleOfflineRead), so a registered-but-never-opened dialog costs one Map entry and no storage. Buttons\n  // per table are single digits, and cacheLookups === false / an explicit allowlist still filter every url here.\n  private registerButtonLookups(buttons: Button[] | undefined, entry: OfflineEntry) {\n    buttons?.forEach(b => { if (b.detailsConfig?.formConfig) this.registerLookups(b.detailsConfig.formConfig, entry); });\n  }\n\n  // Added: CACHE KEY DECISION — a paged read is cached under its BASE url, i.e. with `skip`/`take` stripped,\n  // NOT under the full url. The paging window is a view parameter over one resource, not a different resource:\n  // keying by the full url would mint an unbounded number of IndexedDB entries (take varies per fetch — see\n  // TableComponent.fetchChunk), whose contents would drift apart from one another, and the entry the table\n  // asks for on a cold offline start (skip=0&take=<fetchSize>) is not guaranteed to be one that was ever\n  // written. One base-url entry holds the accumulated front-anchored window, capped at `cacheRows`, and is\n  // overwritten as the user pages — bounded storage and never self-inconsistent.\n  cacheKey(url: string): string {\n    const q = url.indexOf('?');\n    if (q < 0) return url;\n    const kept = url.substring(q + 1).split('&').filter(p => !/^(skip|take)=/.test(p));\n    return kept.length ? url.substring(0, q) + '?' + kept.join('&') : url.substring(0, q);\n  }\n\n  // Added: true when a read carries paging params — such a response is ONE CHUNK, not the whole window\n  isPagedRead(url: string): boolean {\n    return /[?&](skip|take)=/.test(url);\n  }\n\n  matchRead(url: string): OfflineEntry | null {\n    if (!this.hasAny) return null;\n    const exact = this.readUrls.get(url);\n    if (exact) return exact;\n    const prefixed = this.readPrefixes.find(p => url.startsWith(p.prefix));\n    if (prefixed) return prefixed.entry;\n\n    // Changed: registration stores the un-paged url (`customers/all/x`) but a paged table requests\n    // `customers/all/x?skip=0&take=25`, so the exact lookup above could never match and a paginated+offline\n    // table never entered the offline read seam at all — nothing was cached, nothing was served, and the\n    // Connection Error toast was not suppressed either (suppressesUrl routes through here). Retry on the base url.\n    const base = this.cacheKey(url);\n    if (base === url) return null;\n    const baseExact = this.readUrls.get(base);\n    if (baseExact) return baseExact;\n    const basePrefixed = this.readPrefixes.find(p => base.startsWith(p.prefix));\n    return basePrefixed ? basePrefixed.entry : null;\n  }\n\n  // Changed (O1): the grammar now accepts path segments before `?action=` — `transactions/dto?action=create`\n  // was failing the old `[^?/]+` on the slash alone, which made the WRITE half of the library's own\n  // offline-enabled transactions grid a silent no-op (accounting.service.ts:762 promises queueing it never did).\n  // The entity is the FIRST path segment, the same convention register() derives it from loadAction.url, so a\n  // bare `customers?action=create` resolves exactly as before. This deliberately does NOT admit the other\n  // grammar casualties: `checkactions?action=yes|no` (verbs stay create|edit|delete — mapping yes/no onto queue\n  // semantics is a design decision, not a parse), `pigmovements/move` / `pigtransactions/*` (no action grammar\n  // at all — queueing them needs a config surface declaring each custom endpoint's CRUD semantics), and the\n  // `<entity>/form?action=` family, which is refused one level up (CallApi's isFormData guard) because file\n  // uploads cannot queue. For those, a match here only ever yields the explicit 'File uploads require a\n  // connection' message instead of a raw connection error — nothing queues.\n  matchMutation(url: string): OfflineEntry | null {\n    if (!this.hasAny) return null;\n    const match = url.match(/^([^?]+)\\?action=(create|edit|delete)$/); // Changed: [^?/]+ -> [^?]+ — allow slashes in the path\n    if (!match) return null;\n    const entry = this.entries.get(match[1].split('/')[0]); // Changed: entity = first path segment (unchanged for slash-free urls)\n    if (!entry) return null;\n    return entry.config.queue[match[2] as 'create' | 'edit' | 'delete'] ? entry : null;\n  }\n\n  // Interceptor seam: suppress the 'Connection Error' toast for URLs the offline layer handles (plus the heartbeat)\n  suppressesUrl(absoluteUrl: string): boolean {\n    const relative = absoluteUrl.startsWith(this.httpService.apiUrl) ? absoluteUrl.substring(this.httpService.apiUrl.length) : absoluteUrl;\n    if (relative === 'ping') return true;\n    if (!this.hasAny) return false;\n    return !!(this.matchRead(relative) || this.matchMutation(relative));\n  }\n\n  private resolveConfig(offline: OfflineConfig | boolean | undefined): ResolvedOfflineConfig | null {\n    if (!offline) return null;\n    const cfg: OfflineConfig = offline === true ? { enabled: true } : offline;\n    if (!cfg.enabled) return null;\n    return {\n      enabled: true,\n      cacheRows: cfg.cacheRows ?? 500,\n      cacheLookups: cfg.cacheLookups ?? true,\n      lookupMaxAgeHours: cfg.lookupMaxAgeHours ?? 72,\n      queue: cfg.readOnly\n        ? { create: false, edit: false, delete: false }\n        : { create: cfg.queue?.create ?? true, edit: cfg.queue?.edit ?? true, delete: cfg.queue?.delete ?? false },\n      maxQueueAgeHours: cfg.maxQueueAgeHours ?? 72,\n      readOnly: cfg.readOnly ?? false,\n    };\n  }\n\n  //================ Store (Dexie) ================\n\n  // Added: how many changes this user has captured but not yet synced. Drives the sign-out warning — we never\n  // let someone walk away from unsynced work without telling them.\n  async pendingCount(): Promise<number> {\n    if (!this.enabled) return 0;\n    try {\n      return await this.ensureOpen().table('outbox').filter((op: any) => op.status !== 'synced').count();\n    } catch { return 0; }\n  }\n\n  // Added: what LOGOUT should call. Clears the cached reads (a shared device must not retain the previous\n  // user's records) but KEEPS the outbox: those are changes the user made and has not synced yet — possibly a\n  // whole day in the field — and they must outlive the session. The IndexedDB name is already per-user, so the\n  // queue stays invisible to anyone else and drains when its owner signs back in.\n  async clearCacheKeepOutbox(): Promise<void> {\n    if (!this.enabled) return;\n    try {\n      await this.ensureOpen().table('reads').clear();\n    } catch (e) {\n      console.warn('Offline cache clear failed', e);\n    }\n  }\n\n  // Destroys the outbox too — only for an explicit \"discard my unsynced changes\", never for a plain sign-out.\n  async deleteLocalData(): Promise<void> {\n    try {\n      if (this.db) {\n        const db = this.db;\n        this.db = null;\n        db.close();\n        await db.delete();\n        return;\n      }\n      // Not currently open — best-effort delete by recomputing this user's db name.\n      const tenant = this.storage.getPersistent(Constants.AUTH_TENANT_NAME) || 'default';\n      const user = this.authService.currentUser || 'anon';\n      const name = `tinspa_offline_${this.hash(this.httpService.apiUrl)}_${this.sanitize(tenant)}_${this.sanitize(user)}`;\n      await Dexie.delete(name);\n    } catch (e) {\n      console.warn('Offline data wipe failed', e);\n    }\n  }\n\n  private ensureOpen(): Dexie {\n    if (this.db) return this.db;\n    const tenant = this.storage.getPersistent(Constants.AUTH_TENANT_NAME) || 'default';\n    const user = this.authService.currentUser || 'anon';\n    const name = `tinspa_offline_${this.hash(this.httpService.apiUrl)}_${this.sanitize(tenant)}_${this.sanitize(user)}`;\n\n    const db = new Dexie(name);\n    db.version(1).stores({ reads: '&url, entity', outbox: '++seq, opId, entity, status, clientRef', meta: '&key' });\n    this.db = db;\n    this.reads = db.table('reads');\n    this.outbox = db.table('outbox');\n    this.meta = db.table('meta');\n    try { navigator.storage?.persist?.(); } catch { }\n    this.meta.put({ key: 'sentinel', value: Date.now() }).catch(() => { });\n    return db;\n  }\n\n  // Added: never write an entry that can never be read back. matchRead() is the SOLE read path\n  // (datalib.service.ts CallApi), so a url it does not match is unreachable the moment it is stored — the write\n  // silently succeeds, consumes the origin's storage quota, and leaves the store LOOKING populated while the UI\n  // refuses the view. That is worse than not caching it: it lies to the next person who dumps the store.\n  // How it happened (observed on Shift's Loads grid, WS-1): tileClicked REPLACES config.loadAction wholesale, and\n  // TableComponent.cachePagedWindow() then writes under the swapped url stamped with the TABLE's entity. Three of\n  // the four Loads tiles are same-entity so registerReads registered them; the fourth is `invoices/outstanding/x`,\n  // a FOREIGN entity the same-entity guard deliberately skips — so it was written and could never be served, seen\n  // offline as the blocking 'No connection' modal sitting on top of its own unreachable cached rows.\n  // The fix is the SMALL one on purpose: making it matchable instead would mean this table registering an entity it\n  // does not own, under another entity's cacheLookups/cacheRows and with none of that entity's queue semantics —\n  // a cross-entity read-caching feature, not a bug fix, and the same crossing registerReads' guard already declined.\n  // Guard, not silent tidy: every legitimate writer still passes. handleOfflineRead only calls this after matchRead\n  // matched (and cacheKey() only strips paging, which matchRead's own base-url fallback already tolerates);\n  // cachePagedWindow/applyRealTimeData write the table's registered url, or a per-parent/tile url a prefix covers.\n  putRead(url: string, entity: string, data: any, maxRows: number): Promise<any> {\n    if (!this.matchRead(url)) return Promise.resolve(null);\n    this.ensureOpen();\n    let stored = data;\n    if (Array.isArray(data)) stored = data.slice(0, url.includes('/list/') ? 1000 : maxRows);\n    return this.reads.put({ url, entity, data: stored, savedAt: Date.now() })\n      .then(r => { this.pruneDynamicReads(url); return r; }) // Added: keep prefix-matched urls bounded — see below\n      .catch(err => console.warn('Offline cache write failed', err));\n  }\n\n  // Added: a PREFIX-matched url is one of many — one per parent row opened, one per tile view — and nothing\n  // evicts the reads table before logout, so keep only the most recent few under each prefix. Explicitly\n  // registered urls (the top-level grid, its counts, cached lookups) are never candidates for eviction, and\n  // eviction is best-effort: it must never be able to fail a write. Storage per entry is already capped at\n  // cacheRows by putRead above, so this bounds the COUNT of entries, which prefix matching is what introduces.\n  private static readonly DYNAMIC_READS_PER_PREFIX = 20;\n  private async pruneDynamicReads(url: string) {\n    try {\n      if (this.readUrls.has(url)) return;\n      const p = this.readPrefixes.find(x => url.startsWith(x.prefix));\n      if (!p) return;\n      const rows = await this.reads.where('entity').equals(p.entry.entity).toArray();\n      const dynamic = rows\n        .filter(r => r.url.startsWith(p.prefix) && !this.readUrls.has(r.url))\n        .sort((a, b) => b.savedAt - a.savedAt);\n      const stale = dynamic.slice(OfflineService.DYNAMIC_READS_PER_PREFIX);\n      if (stale.length) await this.reads.bulkDelete(stale.map(r => r.url));\n    } catch { /* eviction is a nicety; a failure here must not surface as a failed cache write */ }\n  }\n\n  private getRead(url: string): Promise<CachedRead | undefined> {\n    this.ensureOpen();\n    try { return this.reads.get(url).catch(() => undefined); } catch { return Promise.resolve(undefined); }\n  }\n\n  //================ CallApi seam helpers (called by DataServiceLib) ================\n\n  // Reads: network-first with write-through; on verified-offline or network failure serve the cached copy.\n  handleOfflineRead(action: Action, entry: OfflineEntry, networkCall: () => Observable<ApiResponse>): Observable<ApiResponse> {\n    const key = this.cacheKey(action.url); // Changed: paged reads share the base url's single cache entry — see cacheKey\n    const paged = this.isPagedRead(action.url);\n\n    const serveCache = (): Observable<ApiResponse> => from(this.serveCachedRead(key)).pipe(\n      map(result => result\n        ? { success: true, message: 'success', data: result }\n        : { success: false, message: 'No offline data available yet for this view', data: null })\n    );\n    if (!this.online) return serveCache();\n    return networkCall().pipe(\n      tap((response: ApiResponse) => {\n        // Changed: a paged response is one CHUNK. An 'append' fetch returns only rows N..N+take, so writing it\n        // under the base key would replace the whole cached window with a mid-list slice. TableComponent writes\n        // the ACCUMULATED window instead (cachePagedWindow), which is what an offline reader actually needs.\n        if (paged) return;\n        if (response.success && response?.data) this.putRead(key, entry.entity, response.data, entry.config.cacheRows);\n      }),\n      catchError((err: any) => {\n        if (err?.status === 0) { this.reportNetworkFailure(); return serveCache(); }\n        return throwError(() => err);\n      })\n    );\n  }\n\n  // For '/list/' lookups, append pending offline creates as selectable 'cref:' options so offline forms can reference not-yet-synced parents\n  private async serveCachedRead(url: string): Promise<any | null> {\n    const saved = await this.getRead(url);\n    let data = saved?.data ?? null;\n    const listMatch = url.match(/^([^?/]+)\\/list\\//);\n    if (listMatch) {\n      const creates = await this.pendingCreates(listMatch[1]);\n      if (creates.length) {\n        const opts = creates.map(op => ({ name: `${op.payload?.name ?? 'New'} (pending)`, value: 'cref:' + op.clientRef }));\n        data = Array.isArray(data) ? [...opts, ...data] : opts;\n      }\n    }\n    return data;\n  }\n\n  // Persists a mutation and synthesizes a success ApiResponse so the existing dialog/refresh machinery works unchanged\n  enqueueOffline(action: Action, data: any, entry: OfflineEntry): Observable<ApiResponse> {\n    return from(this.enqueueMutation(action, data, entry)).pipe(\n      map(op => ({\n        success: true,\n        message: 'Saved offline — will be sent when connection is restored',\n        data: op ? { ...op.payload, _offline: { status: op.status, opId: op.opId, clientRef: op.clientRef ?? op.targetClientRef } } : data,\n      })),\n      catchError((err: any) => of({ success: false, message: 'Could not save offline: ' + (err?.message ?? 'storage error'), data: null }))\n    );\n  }\n\n  //================ Outbox writes ================\n\n  private async enqueueMutation(action: Action, data: any, entry: OfflineEntry): Promise<OutboxOp | null> {\n    this.ensureOpen();\n    const opAction = this.parseAction(action.url);\n    if (!opAction) throw new Error('Unsupported offline mutation: ' + action.url);\n\n    const payload = { ...data };\n    const marker = payload._offline;\n    delete payload._offline;\n\n    const refMap: { [field: string]: string } = {};\n    Object.keys(payload).forEach(k => {\n      if (typeof payload[k] === 'string' && payload[k].startsWith('cref:')) { refMap[k] = payload[k].substring(5); payload[k] = 0; }\n    });\n\n    const userId = this.authService.currentUser || 'anon';\n\n    if (opAction === 'edit' && marker?.clientRef) {\n      const createOp = await this.outbox.where('clientRef').equals(marker.clientRef).first();\n      if (createOp && createOp.status !== 'synced') {\n        createOp.payload = { ...createOp.payload, ...payload, clientRef: createOp.clientRef };\n        createOp.refMap = { ...createOp.refMap, ...refMap };\n        await this.outbox.put(createOp);\n        return createOp;\n      }\n    }\n    if (opAction === 'delete' && marker?.clientRef) {\n      const createOp = await this.outbox.where('clientRef').equals(marker.clientRef).first();\n      if (createOp && createOp.status !== 'synced') { await this.outbox.delete(createOp.seq!); return null; }\n    }\n\n    const targetId = opAction === 'create' ? undefined : payload[entry.idField];\n    if (opAction === 'edit' && targetId !== undefined) {\n      const existing = await this.outbox.where('entity').equals(entry.entity)\n        .and(op => op.opAction === 'edit' && op.targetId === targetId && (op.status === 'pending' || op.status === 'failed')).first();\n      if (existing) {\n        existing.payload = payload; existing.refMap = { ...existing.refMap, ...refMap }; existing.status = 'pending';\n        await this.outbox.put(existing);\n        return existing;\n      }\n    }\n\n    const op: OutboxOp = {\n      opId: crypto.randomUUID(), entity: entry.entity, entityName: entry.entityName, url: action.url, opAction, payload, targetId,\n      targetClientRef: marker?.clientRef, refMap: Object.keys(refMap).length ? refMap : undefined,\n      status: 'pending', attempts: 0, maxAgeHours: entry.config.maxQueueAgeHours, userId, enqueuedAt: Date.now(),\n    };\n    if (opAction === 'create') { op.clientRef = crypto.randomUUID(); op.payload = { ...payload, clientRef: op.clientRef }; }\n    await this.outbox.add(op);\n    return op;\n  }\n\n  //================ Live streams (cross-tab reactive) ================\n\n  pendingOpsFor$(entity: string): Observable<OutboxOp[]> {\n    this.ensureOpen();\n    return from(liveQuery(() => this.outbox.where('entity').equals(entity).and(op => op.status !== 'synced').sortBy('seq')));\n  }\n\n  activeOps$(): Observable<OutboxOp[]> {\n    this.ensureOpen();\n    return from(liveQuery(() => this.outbox.filter(op => op.status !== 'synced').sortBy('seq')));\n  }\n\n  private pendingCreates(entity: string): Promise<OutboxOp[]> {\n    this.ensureOpen();\n    return this.outbox.where('entity').equals(entity).and(op => op.opAction === 'create' && op.status !== 'synced').sortBy('seq');\n  }\n\n  private hasPending(): Promise<boolean> {\n    this.ensureOpen();\n    return this.outbox.where('status').equals('pending').count().then(c => c > 0);\n  }\n\n  //================ Connectivity ================\n\n  // Started by the sync engine (offline table registered) OR by the toolbar indicator (to show a status light).\n  // Uses SignalR's hub connection as the instant online signal when real-time is enabled; ping is the fallback/source of truth.\n  ensureConnectivity(): void {\n    if (!this.enabled) return; // app-level gate: no pinging/SignalR-watching when offline capability is off\n    if (this.connectivityStarted) return;\n    this.connectivityStarted = true;\n\n    if (typeof window !== 'undefined') {\n      window.addEventListener('offline', () => this.zone.run(() => this.setOffline()));\n      window.addEventListener('online', () => this.zone.run(() => this.verify()));\n    }\n\n    // SignalR hub state: connected => instantly online (+drain); disconnected => confirm via ping before declaring offline.\n    // When real-time is disabled the hub never connects, so this stays false and ping fully drives connectivity.\n    this.signalR.dataHubConnected$.subscribe(connected => this.zone.run(() => connected ? this.setOnline() : this.verify()));\n\n    this.verify();\n  }\n\n  reportNetworkFailure(): void { if (this.connectivityStarted) this.setOffline(); }\n\n  // Added: the statuses that mean \"an EDGE answered, but it could not reach the origin\". They are the exact\n  // shape of a device resuming from sleep: the gateway/CDN in front of the API is warm and replies instantly,\n  // while the origin (or the path to it) is not yet reachable. Treating these as proof of connectivity is what\n  // produced the owner's 2026-08-20 report — see verify() below.\n  private static readonly GATEWAY_UNREACHABLE_STATUSES = [408, 502, 503, 504];\n\n  // Changed: `err.status > 0` no longer means \"we are online\".\n  //\n  // The old heuristic was `if (err?.status > 0) this.setOnline()`, encoding \"we reached A server, therefore we\n  // have connectivity\". That is correct for 401/403/404/500 — an origin that answers at all is an origin that is\n  // alive, and the failure is about the request, not the network. It is FALSE for 408/502/503/504, which are\n  // precisely what a gateway returns when it CANNOT reach the origin. Those statuses prove the opposite of what\n  // the heuristic concluded from them.\n  //\n  // The cost of that one line was the whole defect. On unlocking a phone, the `online` event fires before the\n  // radio genuinely carries traffic; the ping hits the warm edge, gets 504, and the app declared itself ONLINE.\n  // setOnline() flips online$, which arms-and-fires TableComponent.setupReconnectRefresh() on every table on the\n  // page (table.component.ts:1659-1684) — non-silent GETs, hence the loader the user sees flash — and each of\n  // those hits the same unreachable origin, 504s, and raises the \"Taking too long\" modal on the FIRST failure.\n  //\n  // Worse, it left the page STALE as well as alarmed: the table consumes its arm before fetching\n  // (table.component.ts:1667-1668), and because online$ never returned to false nothing ever re-armed, so no\n  // second refresh could happen. Keeping online$ HONEST fixes that staleness here, with no change to\n  // table.component.ts at all — the arm simply survives until connectivity is genuinely proven.\n  //\n  // Note the rxjs TimeoutError from timeout(5000) needs no branch: it carries no `status`, so it already failed\n  // the `> 0` test and already called setOffline(). Only the gateway statuses were missing.\n  private verify(): void {\n    this.httpService.Get('ping').pipe(timeout(5000)).subscribe({\n      next: () => this.setOnline(),\n      error: (err: any) => {\n        const status = err?.status ?? 0;\n        const reachable = status > 0 && !OfflineService.GATEWAY_UNREACHABLE_STATUSES.includes(status); // Changed: a gateway timeout is NOT connectivity\n        if (reachable) this.setOnline(); else this.setOffline();\n      },\n    });\n  }\n\n  private setOnline(): void {\n    this.stopRecoveryPolling();\n    if (!this.online$.value) {\n      this.zone.run(() => this.online$.next(true)); // TS-20: re-enter Angular zone only on actual state flip (timer ticks run outside the zone)\n      if (this.syncStarted) setTimeout(() => this.zone.run(() => this.drain(true)), Math.floor(Math.random() * 5000)); // TS-20: drain (toasts/emissions) must run in-zone even when triggered from an out-of-zone timer path; jittered so a reconnecting fleet doesn't stampede. Changed: auto=true — a reconnect must not jump a server-stated Retry-After\n    }\n    // Marry the two: whenever ping confirms we're reachable, revive SignalR if its own auto-reconnect gave up.\n    // No-op when the hub is already connected, so this is safe to call on every online confirmation.\n    this.signalR.reconnectIfNeeded();\n  }\n\n  private setOffline(): void {\n    if (this.online$.value) this.zone.run(() => this.online$.next(false)); // TS-20: re-enter zone only on actual state flip\n    this.startRecoveryPolling();\n  }\n\n  // Added: the recovery schedule. Was a flat setInterval(verify, 30000).\n  //\n  // A flat 30s is the wrong shape for the case that actually dominates: a phone waking from sleep, whose radio\n  // settles in ONE TO FIVE SECONDS. Under the old timer a user who unlocked their device sat on stale content\n  // for up to half a minute after connectivity had genuinely returned — and once verify() started correctly\n  // reporting a resume 504 as offline (see above), that half-minute would have become the NEW visible symptom:\n  // no false modal, but a Day Book that stubbornly refused to refresh. Fixing verify() without this would have\n  // traded one complaint for another.\n  //\n  // The early steps cover the radio wake; the tail settles back on the original 30s so a genuinely long outage\n  // costs exactly what it always did. Deliberately capped rather than growing unboundedly — 30s remains the\n  // safety net it always was, and SignalR's own reconnect usually beats it when real-time is on.\n  private static readonly RECOVERY_BACKOFF_MS = [1000, 2000, 4000, 8000, 15000, 30000];\n  private recoveryStep = 0;\n\n  // Changed: a self-rescheduling setTimeout chain rather than setInterval, because the delay now varies per tick.\n  // stopRecoveryPolling() clears it identically, and the re-entrancy guard (`if (this.recoveryTimer)`) is kept so\n  // repeated setOffline() calls still cannot stack two chains.\n  private startRecoveryPolling(): void {\n    if (this.recoveryTimer || !this.connectivityStarted) return;\n    this.recoveryStep = 0; // a fresh outage always starts fast, however long the previous one ran\n    // TS-20: tick outside Angular zone so the recovery ping doesn't trigger a CD cycle every tick; verify()→setOnline/setOffline re-enter the zone only when online state flips\n    this.zone.runOutsideAngular(() => this.scheduleRecoveryTick());\n  }\n\n  private scheduleRecoveryTick(): void {\n    const backoff = OfflineService.RECOVERY_BACKOFF_MS;\n    const delay = backoff[Math.min(this.recoveryStep, backoff.length - 1)];\n    this.recoveryStep++;\n\n    // The handle is deliberately LEFT SET across the verify() call below, and that is load-bearing rather than\n    // untidy. verify()'s error path calls setOffline() → startRecoveryPolling(), whose only re-entrancy guard is\n    // `if (this.recoveryTimer) return`. Clearing the handle first therefore let that call start a SECOND chain\n    // (with the backoff step reset to 0), so every failed tick doubled the number of live chains and the ping\n    // rate ran away. Caught by resume-reconnect-grace.spec.ts — \"second retry lands ~2s after the first\" saw 4\n    // pings where it expected 2. Holding the handle keeps this chain the single owner of recovery polling.\n    this.recoveryTimer = setTimeout(() => {\n      this.verify();\n      // Re-arm only while still offline. A successful verify() calls setOnline() → stopRecoveryPolling(), which\n      // clears the handle and resets the step, so the chain ends there rather than resurrecting itself.\n      if (!this.online$.value) this.zone.runOutsideAngular(() => this.scheduleRecoveryTick());\n    }, delay);\n  }\n\n  private stopRecoveryPolling(): void {\n    if (this.recoveryTimer) { clearTimeout(this.recoveryTimer); this.recoveryTimer = null; } // Changed: clearTimeout — the chain is setTimeout-based now\n    this.recoveryStep = 0;\n  }\n\n  //================ Sync engine ================\n\n  private startSync(): void {\n    if (this.syncStarted) return;\n    this.syncStarted = true;\n    this.ensureConnectivity();\n    this.resetOrphans().catch(() => { });\n    // TS-20: tick outside Angular zone so an idle 60s outbox check doesn't trigger CD; only re-enter (zone.run(drain)) when there is actually pending work to apply\n    this.zone.runOutsideAngular(() => {\n      this.periodicTimer = setInterval(() => { if (this.online) this.hasPending().then(has => { if (has) this.zone.run(() => this.drain(true)); }); }, 60000); // Changed: auto=true — the 60s sweep must not jump a server-stated Retry-After\n    });\n    if (this.online) this.drain(true); // Changed: auto=true — sync starting up is the app's decision, not the user's\n  }\n\n  // Added: reclaim work parked by a previous session. The sync engine otherwise only starts when a page happens\n  // to register an offline table, so changes captured before a sign-out sat there until the user wandered back\n  // onto the right screen. Called on sign-in: if this user has anything pending, start syncing immediately.\n  async resumeQueue(): Promise<void> {\n    if (!this.enabled) return;\n    try {\n      this.ensureOpen(); // the outbox is per-user, so this resolves THIS user's parked work and nobody else's\n      if (await this.hasPending()) this.startSync();\n    } catch { /* nothing parked, or the store isn't available */ }\n  }\n\n  // Changed: `auto` marks a drain the APP decided to run (reconnect, the 60s sweep, sync start) as opposed to one\n  // the USER asked for. Only automatic drains are held back by a server-stated Retry-After — see retryNotBefore.\n  // It defaults to false so every EXTERNAL caller keeps today's behaviour untouched: the sync tray's \"Sync Now\"\n  // button (`sync.component.ts:29`) is a deliberate human action, and silently doing nothing when someone presses\n  // a button is precisely the quiet-failure shape this codebase keeps getting bitten by.\n  async drain(auto: boolean = false): Promise<void> {\n    if (this.draining || !this.online) return;\n\n    // Added: honouring Retry-After ONLY inside scheduleBackoff was not enough, and a 32-op drain proved it — the\n    // retry arrived 9.5s after a 429 that said 20. The backoff timer was armed correctly, but a connectivity flip\n    // (SignalR dropping and reconnecting is routine, and each flip schedules its own drain within 5s of coming\n    // back) simply ran a drain in front of it. The wait has to bind every automatic entry point, not just the one\n    // timer, or the app still hammers a server that told it exactly when to come back.\n    //\n    // Deliberately fail-open: this is in-memory only, so a reload forgets it — and that is correct, because a\n    // reload also forgets the backoff timer, and a gate that outlived its own timer could strand the queue.\n    if (auto && Date.now() < this.retryNotBefore) return;\n\n    this.draining = true;\n    const runner = () => this.drainLoop().finally(() => { this.draining = false; });\n    const locks: any = (navigator as any).locks;\n    if (locks?.request) {\n      try {\n        await locks.request('tinspa-outbox-drain', { ifAvailable: true }, async (lock: any) => { if (lock) await runner(); else this.draining = false; });\n      } catch { await runner(); }\n    } else { await runner(); }\n  }\n\n  private async drainLoop(): Promise<void> {\n    const syncedEntities = new Set<string>();\n    while (true) {\n      const op = await this.nextAutoOp();\n      if (!op) break;\n\n      op.status = 'syncing';\n      await this.outbox.put(op); // persisted BEFORE network I/O — crash recovery reverts to pending\n\n      const outcome = await this.sendOp(op);\n      if (outcome === 'transient') {\n        op.status = 'pending'; op.attempts++;\n        await this.outbox.put(op);\n        this.scheduleBackoff(op.attempts, this.serverRetryAfterMs); // Changed: pass the server's own Retry-After, which overrides the attempt-count guess when present\n        break; // strict FIFO: a transient failure halts the drain until backoff/reconnect\n      }\n      if (outcome === 'synced') syncedEntities.add(op.entity);\n      if (outcome === 'failed') {\n        this.messageService.toast(`Sync failed: ${op.entityName} ${op.opAction} — open the sync tray to review`);\n        if (op.clientRef) await this.cascadeFailure(op.clientRef, `${op.entityName} ${op.opAction} failed`);\n      }\n      if (outcome === 'conflict') this.messageService.toast(`Sync conflict: ${op.entityName} changed on the server — review in the sync tray`);\n    }\n    if (syncedEntities.size > 0) {\n      this.drained$.next(Array.from(syncedEntities));\n      this.messageService.toast('Offline changes synced');\n    }\n  }\n\n  private async sendOp(op: OutboxOp): Promise<'transient' | 'synced' | 'failed' | 'conflict'> {\n    const payload = { ...op.payload };\n    if (op.refMap && Object.keys(op.refMap).length) payload.clientRefs = JSON.stringify(op.refMap); // server resolves parent ClientRef -> real int FK\n\n    this.serverRetryAfterMs = null; // Added: cleared BEFORE the I/O, so a wait from a previous op can never leak into this one's backoff\n\n    let response: ApiResponse;\n    try {\n      response = await firstValueFrom(this.httpService.Post(op.url, payload));\n    } catch (err: any) {\n      const status = err?.status ?? 0;\n      if (status === 0 || status === 408 || status === 429 || status >= 500) {\n        if (status === 0) this.reportNetworkFailure();\n        // Added: the response headers were being thrown away here, and with them the one authoritative number in\n        // the whole exchange. A 429 (and a 503) may carry Retry-After — TinWeb's limiter always sends it, computed\n        // from the real window, and exposes it cross-origin — which is the server stating when it will stop\n        // refusing. Guessing from an attempt count instead means we either come back too early, get refused again\n        // and extend the block on a sliding window, or sit idle far longer than we needed to.\n        // Parsed by ApiErrorService so there is exactly ONE implementation of the two legal header forms.\n        const seconds = this.apiErrorService.retryAfterSeconds(err);\n        this.serverRetryAfterMs = seconds > 0 ? seconds * 1000 : null;\n        return 'transient';\n      }\n      return this.finishOp(op, 'failed', err?.message ?? `HTTP ${status}`);\n    }\n\n    if (response.success) return this.finishOp(op, 'synced');\n\n    const reason = response.reason ?? ''; // Changed: reason is now a typed ApiResponse field (shared IConcurrency conflict contract)\n    const notFound = reason === 'not_found' || response.message?.includes('not found');\n    if (reason === 'conflict') { op.serverRecord = response.data ?? null; return this.finishOp(op, 'conflict', response.message); }\n    if (notFound && op.opAction === 'delete') return this.finishOp(op, 'synced');                       // delete of already-deleted row — outcome achieved\n    if (notFound && op.opAction === 'edit') return this.finishOp(op, 'conflict', 'This record was deleted on the server');\n    return this.finishOp(op, 'failed', response.message);                                                 // validation/business failure — permanent\n  }\n\n  private async finishOp(op: OutboxOp, status: 'synced' | 'failed' | 'conflict', error?: string): Promise<'synced' | 'failed' | 'conflict'> {\n    op.status = status; op.lastError = error;\n    if (status === 'synced') op.syncedAt = Date.now();\n    await this.outbox.put(op);\n    return status;\n  }\n\n  private async nextAutoOp(): Promise<OutboxOp | undefined> {\n    this.ensureOpen();\n    const ops = await this.outbox.orderBy('seq').filter(op => op.status === 'pending').toArray();\n    for (const op of ops) {\n      if (Date.now() - op.enqueuedAt > op.maxAgeHours * 3600 * 1000) {\n        op.status = 'stale'; op.lastError = 'Held — too old to send automatically';\n        await this.outbox.put(op);\n        continue;\n      }\n      return op;\n    }\n    return undefined;\n  }\n\n  private async resetOrphans(): Promise<void> {\n    this.ensureOpen();\n    const orphans = await this.outbox.where('status').equals('syncing').toArray();\n    for (const op of orphans) { op.status = 'pending'; await this.outbox.put(op); } // safe: opId/ClientRef idempotency makes resend collide, not duplicate\n    const cutoff = Date.now() - 24 * 3600 * 1000;\n    await this.outbox.where('status').equals('synced').and(op => (op.syncedAt ?? 0) < cutoff).delete();\n  }\n\n  private async cascadeFailure(clientRef: string, reason: string): Promise<void> {\n    this.ensureOpen();\n    const dependents = await this.outbox.filter(op => op.status === 'pending' && !!op.refMap && Object.values(op.refMap).includes(clientRef)).toArray();\n    for (const op of dependents) { op.status = 'failed'; op.lastError = 'Blocked: ' + reason; await this.outbox.put(op); }\n  }\n\n  // Changed: takes the server's stated Retry-After (ms, null when it said nothing) and OVERRIDES the computed\n  // backoff with it. Full jitter is right when we are guessing — it spreads a thundering herd across a window we\n  // invented — but it is wrong once the server has told us the answer, because `random * cap` can return almost\n  // zero and send us straight back into a limiter that has not reset. When Retry-After is present we wait the\n  // whole of it, and jitter only the ADDITIONAL second, which keeps clients from returning in lockstep without\n  // ever returning early.\n  //\n  // Clamped to an hour to match the clamp TinWeb applies to the header it sends, so a broken proxy inventing a\n  // Retry-After of a year cannot strand the outbox. A stated wait LONGER than the old 5-minute cap is honoured\n  // rather than capped at 5 minutes: coming back before the server said to only earns another refusal.\n  private scheduleBackoff(attempts: number, serverRetryAfterMs: number | null = null): void {\n    if (this.backoffTimer) clearTimeout(this.backoffTimer);\n\n    let delay: number;\n    if (serverRetryAfterMs && serverRetryAfterMs > 0) {\n      delay = Math.min(serverRetryAfterMs, 3600000) + Math.floor(Math.random() * 1000); // obey the server, plus <=1s of de-sync jitter\n      this.retryNotBefore = Date.now() + delay; // Added: binds the reconnect and periodic drains too, not just this timer\n    } else {\n      const cap = Math.min(5000 * Math.pow(2, attempts), 300000); // exponential 5s·2^n capped 5min, full jitter\n      delay = Math.floor(Math.random() * cap);\n      this.retryNotBefore = 0; // a guessed backoff never blocks another trigger — only a server instruction does\n    }\n\n    // This timer IS the scheduled resume, so it lifts its own gate rather than being held by it — a millisecond of\n    // timer skew must not turn the wait into a permanent stall.\n    this.backoffTimer = setTimeout(() => { this.retryNotBefore = 0; this.drain(); }, delay);\n  }\n\n  //================ Sync-tray actions ================\n\n  async retryOp(opId: string): Promise<void> {\n    const op = await this.getOp(opId);\n    if (!op) return;\n    op.status = 'pending'; op.attempts = 0; op.enqueuedAt = Date.now(); this.retryNotBefore = 0; // Added: a deliberate user retry clears any server-stated wait, exactly as it clears attempts\n    await this.outbox.put(op);\n    this.drain();\n  }\n\n  discardOp(opId: string): Promise<any> { this.ensureOpen(); return this.outbox.where('opId').equals(opId).delete(); }\n\n  // keepMine re-arms the op with the fresh server RowVersion (explicit, informed overwrite); keepServer discards\n  async resolveConflict(opId: string, choice: 'keepServer' | 'keepMine'): Promise<void> {\n    const op = await this.getOp(opId);\n    if (!op) return;\n    if (choice === 'keepServer') { await this.discardOp(opId); return; }\n    if (op.serverRecord?.rowVersion) op.payload = { ...op.payload, rowVersion: op.serverRecord.rowVersion };\n    else delete op.payload.rowVersion;\n    op.status = 'pending'; op.attempts = 0; op.enqueuedAt = Date.now(); this.retryNotBefore = 0; // Added: same as retryOp — an informed, explicit choice is not an automatic drain\n    await this.outbox.put(op);\n    this.drain();\n  }\n\n  private getOp(opId: string): Promise<OutboxOp | undefined> { this.ensureOpen(); return this.outbox.where('opId').equals(opId).first(); }\n\n  //================ helpers ================\n\n  private parseAction(url: string): 'create' | 'edit' | 'delete' | null {\n    if (url.includes('?action=create')) return 'create';\n    if (url.includes('?action=edit')) return 'edit';\n    if (url.includes('?action=delete')) return 'delete';\n    return null;\n  }\n  private hash(v: string): string { let h = 0; for (let i = 0; i < v.length; i++) h = ((h << 5) - h + v.charCodeAt(i)) | 0; return Math.abs(h).toString(36); }\n  private sanitize(v: string): string { return v.replace(/[^a-zA-Z0-9_-]/g, '_').toLowerCase(); }\n}\n","// import { Core } from 'tin-core';\nimport { Injectable } from \"@angular/core\";\nimport { Core } from '../classes/TinCore';\nimport { LogLevel } from \"../classes/LibClasses\";\n\n@Injectable({\n  providedIn: \"root\",\n})\nexport class LogService {\n  constructor() { }\n\n  level: LogLevel = LogLevel.All;\n\n  logToConsole: boolean = true;\n\n  logToApi: boolean = false;\n\n  debug(msg: string, ...optionalParams: any[]) {\n    this.writeToLog(msg, LogLevel.Debug, optionalParams);\n  }\n\n  info(msg: string, ...optionalParams: any[]) {\n    this.writeToLog(msg, LogLevel.Info, optionalParams);\n  }\n\n  warn(msg: string, ...optionalParams: any[]) {\n    this.writeToLog(msg, LogLevel.Warn, optionalParams);\n  }\n\n  error(msg: string, ...optionalParams: any[]) {\n    this.writeToLog(msg, LogLevel.Error, optionalParams);\n  }\n\n  fatal(msg: string, ...optionalParams: any[]) {\n    this.writeToLog(msg, LogLevel.Fatal, optionalParams);\n  }\n\n  log(msg: string, ...optionalParams: any[]) {\n    this.writeToLog(msg, LogLevel.All, optionalParams);\n\n  }\n\n  private writeToLog(msg: string, level: LogLevel, params: any[]) {\n\n    if (this.shouldLog(level)) {\n\n      // Build log string\n      let value: string = Core.getFormatedDate(Date(), false).replace(\"T\", \" \");\n      // value += \" - Type: \" + LogLevel[this.level];\n      value += \" - Message: \" + msg;\n\n\n      if (params.length) {\n        value += \" - Extra Info: \" + this.formatParams(params);\n      }\n\n      // Log the value\n      if (this.logToConsole) {\n        console.log(value);\n      }\n\n      if (this.logToApi) {\n        //Call API post\n      }\n\n    }\n  }\n\n  private formatParams(params: any[]): string {\n\n    let ret: string = params.join(\",\");\n    // Is there at least one object in the array?\n    if (params.some((p) => typeof p == \"object\")) {\n      ret = \"\";\n      // Build comma-delimited string\n      for (let item of params) {\n        ret += JSON.stringify(item) + \",\";\n      }\n    }\n    return ret;\n  }\n\n  private shouldLog(level: LogLevel): boolean {\n\n    let ret: boolean = false;\n\n    if (\n      (level >= this.level && level !== LogLevel.Off) ||\n      this.level === LogLevel.All\n    ) {\n      ret = true;\n    }\n\n    return ret;\n  }\n}\n\n\n\n","import { MessageService } from './message.service';\nimport { Injectable, Injector } from '@angular/core';\nimport { OfflineService } from './offline.service'; // Changed: type-only use via lazy Injector to clear cached data on logout (avoids circular DI)\n\nimport { Router, ActivatedRoute } from '@angular/router';\nimport { BehaviorSubject } from 'rxjs';\nimport { StorageService } from './storage.service';\nimport { LogService } from './log.service';\nimport { Constants } from '../classes/Classes';\nimport { HttpService } from './http.service';\nimport { SocialAuthService, SocialUser } from '@abacritt/angularx-social-login';\nimport { Role } from '../classes/LibClasses';\n\n// Changed: tri-state refresh outcome — 'rejected' means the server explicitly refused the token (safe to clear),\n// 'network' means the request never got an answer (token may still be valid — keep it and retry later)\nexport type RefreshResult = 'success' | 'rejected' | 'network';\nimport { SignalRService } from './signalr.service'; // Changed: Added for stopping SignalR connection on logout\n\n@Injectable({\n  providedIn: 'root'\n})\n\nexport class AuthService {\n\n  private googleAuthInitialized = false;\n  private refreshPromise: Promise<RefreshResult> | null = null; // Changed: shared in-flight refresh — concurrent callers await the same result instead of getting a false failure\n  private refreshTimer: any = null; // Changed: Proactive token refresh timer\n\n  private socialUserSource = new BehaviorSubject<SocialUser | null>(null);\n  public socialUserObserv = this.socialUserSource.asObservable();\n\n  constructor(private _route: ActivatedRoute, private socialService: SocialAuthService, private storage: StorageService, public router: Router, private httpService: HttpService, private messageService: MessageService, private logService: LogService, private signalRService: SignalRService, private injector: Injector) { // Changed: Added SignalRService + Injector (Injector used to lazily reach OfflineService without circular DI)\n\n    this.initializeGoogleAuth();\n    this.initVisibilityRefresh(); // Changed: Refresh token when tab becomes visible after being hidden\n  }\n\n\n  private initializeGoogleAuth() {\n    if (this.googleAuthInitialized) {\n      return;\n    }\n    this.googleAuthInitialized = true;\n\n\n    this.socialService.authState.subscribe({\n      next: (socialUser: SocialUser) => {\n        this.socialUserSource.next(socialUser);\n      },\n      error: (error) => {\n\n        console.debug('Google Sign-In initialization error (expected if not using Google auth):', error?.message);\n      }\n    });\n  }\n\n  // Changed: Enhanced clearSession with optional server-side revocation\n  clearSession(revokeOnServer: boolean = false) {\n    if (revokeOnServer) {\n      // Changed: Revoke only this device's refresh token — other devices keep their sessions\n      const refreshToken = this.storage.getPersistent(Constants.AUTH_REFRESH_TOKEN);\n      if (refreshToken) {\n        this.httpService.Post('User/revoke', { refreshToken }).subscribe({\n          error: () => {} // Silently ignore errors during logout\n        });\n      }\n\n      // Changed: on explicit logout, wipe the offline CACHE so a shared device retains no prior-user records —\n      // but keep the outbox. Those are the user's own unsynced changes; deleting them here destroyed work\n      // (potentially a full day offline) with no warning. The IndexedDB is per-user, so the queue is invisible\n      // to anyone else and drains when its owner signs back in.\n      // Resolved lazily to avoid a circular dependency with OfflineService.\n      try { this.injector.get(OfflineService).clearCacheKeepOutbox(); } catch { /* offline layer not in use */ }\n    }\n\n    if (this.refreshTimer) { clearTimeout(this.refreshTimer); this.refreshTimer = null; } // Changed: Cancel proactive refresh timer\n    this.signalRService.stopConnection(); // Changed: Stop consolidated SignalR connection before clearing session\n    this.Updateloggedin(false);\n    this.UpdateAutoLogin(false);\n    this.UpdateRole(new Role());\n    this.UpdateToken(''); // Changed: Clear in-memory token\n    this.UpdateTokenExpire(''); // Changed: Clear in-memory token expiry\n    this.UpdateAuthType(''); // Added: back to UNKNOWN, so the next user on a shared device is never gated by the previous user's auth type. Storage is wiped by the clearAll/clearSessionData below\n\n    if (revokeOnServer) {\n      this.storage.clearAll(); // Changed: Full logout clears everything including refresh token\n    } else {\n      this.storage.clearSessionData(); // Changed: Session expired — preserve refresh token for \"remember me\"\n    }\n\n    this.socialService.signOut();\n\n  }\n\n  sessionExpired(){\n\n    this.clearSession(false) // Changed: Don't revoke on server, token just expired\n\n    // Changed: the path came from url.hash, which is EMPTY under HTML5 routing — every current app runs\n    // HTML5 routing, so the redirect target was always blank and the sign-back-in landed on the default page\n    // instead of the page the user was on. router.url is the in-app path under either routing mode.\n    let path = this.router.url.startsWith('/') ? this.router.url.substring(1) : this.router.url;\n    if (path.startsWith('login')) path = ''; // never bounce back into the login page itself\n\n    this.router.navigate([\"login\"], {\n      relativeTo: this._route,\n      queryParams: path ? { redirectTo: path } : {}, // Changed: an empty redirectTo must be ABSENT, not present-and-blank — a blank param overrides the saved last-route with nothing\n      queryParamsHandling: 'merge',\n      skipLocationChange: false\n    });\n\n  }\n\n  logoff() {\n    this.clearSession(true) // Changed: Revoke refresh tokens on explicit logout\n\n    this.router.navigate([\"login\"]);\n  }\n\n  //Logged in\n  private loggedin: boolean = false;\n  private loggedinSource = new BehaviorSubject(this.loggedin);\n  public loggedinObserv = this.loggedinSource.asObservable();\n  Updateloggedin(loggedin: boolean) {\n    this.loggedinSource.next(loggedin);\n    this.loggedin = loggedin;\n  }\n\n  //autoLogin\n  private autoLogin: boolean = false;\n  private autoLoginSource = new BehaviorSubject(this.autoLogin);\n  public autoLoginObserv = this.autoLoginSource.asObservable();\n  UpdateAutoLogin(autoLogin: boolean) {\n    this.autoLoginSource.next(autoLogin);\n    this.autoLogin = autoLogin;\n  }\n\n\n  //Token\n  private token: string = \"\";\n  public tokenSource = new BehaviorSubject(this.token);\n  public tokenObserv = this.tokenSource.asObservable();\n  UpdateToken(newToken: string) {\n    this.tokenSource.next(newToken);\n\n  }\n\n  //TokenExpire\n  private tokenExpire: string = \"\";\n  public tokenExpireSource = new BehaviorSubject(this.tokenExpire);\n  public tokenExpireObserv = this.tokenExpireSource.asObservable();\n  UpdateTokenExpire(newTokenExpire: string) {\n    this.tokenExpireSource.next(newTokenExpire);\n\n  }\n\n  //Current User\n  public currentUser: string = \"tnyagato\";\n  private currentUserSource = new BehaviorSubject(this.currentUser);\n  public currentUserObserv = this.currentUserSource.asObservable();\n  UpdateCurrentUser(newUser: string) {\n    this.currentUserSource.next(newUser.toLocaleLowerCase());\n    this.currentUser = newUser.toLocaleLowerCase();\n  }\n\n  //Line Manager\n  private islineManager: boolean = false;\n  private isLineManagerSource = new BehaviorSubject(this.islineManager);\n  public isLineManagerObserv = this.isLineManagerSource.asObservable();\n  UpdateIsLineManager(manager: boolean) {\n    this.isLineManagerSource.next(manager);\n  }\n\n  //Roles\n  private currentRole = new Role;\n  public currentRoleSource = new BehaviorSubject(this.currentRole);\n  public myRoleObserv = this.currentRoleSource.asObservable();\n  UpdateRole(role) {\n    this.currentRoleSource.next(role);\n  }\n\n  //Logged in FirstName\n  private loggedUserSource = new BehaviorSubject(\"tnyagato\");\n  public loggedUserFullName = this.loggedUserSource.asObservable();\n  updateLoggedUserFullName(userName: string) {\n    this.loggedUserSource.next(userName);\n  }\n\n  //TenantName\n  private tenantNameSource = new BehaviorSubject(\"Tenant Name\");\n  public tenantNameObserv = this.tenantNameSource.asObservable();\n  updateTenantName(tenantName: string) {\n    this.tenantNameSource.next(tenantName);\n  }\n\n  // Added: AuthType of the signed-in user. The server already returns it on login, social login AND refresh\n  // (UserController.cs:622, 780, 1026) — it was simply discarded. Empty string means UNKNOWN, which is not the\n  // same as non-local: see isLocalAuth below.\n  public currentAuthType: string = \"\";\n  private authTypeSource = new BehaviorSubject(this.currentAuthType);\n  public authTypeObserv = this.authTypeSource.asObservable();\n  UpdateAuthType(authType: string) {\n    this.currentAuthType = authType ?? \"\";\n    this.authTypeSource.next(this.currentAuthType);\n  }\n\n  // Added: FAILS OPEN, and that direction is deliberate. This gates surfaces that are only meaningful for\n  // password-backed accounts, so the two possible mistakes are not symmetric: showing password rules to an AD\n  // user is cosmetic, while HIDING them from a local user who must invent a password that will then be refused\n  // is a real block. So only a POSITIVELY KNOWN non-local type suppresses anything — an unknown type (a session\n  // restored from storage written before this key existed, or a server that omits the field) still shows.\n  // Compared case-insensitively because UserService.CanonicalAuthType (UserService.cs:52) only normalises the\n  // spelling on WRITE; rows stored before it landed can still read \"Local\".\n  isLocalAuth(): boolean {\n    return !this.currentAuthType || this.currentAuthType.toLowerCase() === 'local';\n  }\n\n\n  //Authorisation\n  isAuthorised(capName: string): boolean {\n\n    if (!this.currentRoleSource.value[capName]) {\n      // this.logService.info(`authorise: ${this.currentRoleSource.value.roleName} not authorised for ${capName}`);\n      this.router.navigate([\"home\"]);\n      this.messageService.toast(`Unauthorised: ${capName}`);\n\n      return false;\n    } else {\n      return true;\n    }\n\n  }\n\n  // Changed: Pure validation — no side effects. Callers handle refresh/redirect.\n  isValidToken(): boolean {\n    let tokenExpire: Date = new Date(this.tokenExpireSource.value);\n    let nowDate: Date = new Date();\n    return tokenExpire > nowDate;\n  }\n\n  // Changed: Centralized handler for storing all auth data from login/refresh response\n  applyLoginResponse(data: any, rememberMe: boolean) {\n    // Set storage mode: sessionStorage when not remembered, localStorage when remembered\n    this.storage.setSessionMode(!rememberMe);\n\n    // Store remember-me flag persistently (survives browser close)\n    this.storage.storePersistent(Constants.AUTH_REMEMBER_ME, rememberMe);\n\n    // Update in-memory state\n    this.Updateloggedin(true);\n    this.UpdateToken(data.token);\n    this.UpdateTokenExpire(data.expiration);\n    this.signalRService.updateToken(data.token); // Changed: Keep SignalR reconnection token in sync\n\n    // Added: a session becoming active reclaims any work this user parked before signing out, without waiting\n    // for them to open a page that registers an offline table. Lazy injection avoids a circular dependency.\n    try { this.injector.get(OfflineService).resumeQueue(); } catch { /* offline layer not in use */ }\n    this.UpdateRole(data.role);\n    this.updateLoggedUserFullName(data.firstName);\n    this.updateTenantName(data.tenantName);\n    if (data.userName) this.UpdateCurrentUser(data.userName); // Changed: Restore username after silent refresh\n    if (data.authType) this.UpdateAuthType(data.authType); // Added: this method is the ONLY place login and silentRefresh both land, so persisting here covers both paths at once. Guarded like userName above — a response that omits the field must leave the known value alone, never overwrite it with empty\n\n    // Store session data in active storage\n    this.storage.store(Constants.AUTH_TOKEN, data.token);\n    this.storage.store(Constants.AUTH_TOKEN_EXPIRE, data.expiration);\n    this.storage.store(Constants.AUTH_ROLES, JSON.stringify(data.role));\n    this.storage.store(Constants.AUTH_NAME, data.firstName);\n    this.storage.store(Constants.AUTH_TENANT_NAME, data.tenantName);\n    if (data.userName) this.storage.store(Constants.AUTH_USER, data.userName); // Changed: Persist username so checkAuthentication finds AUTH_USER after app restart\n    if (data.authType) this.storage.store(Constants.AUTH_TYPE, data.authType); // Added: survives a reload, so a direct-URL landing on a password surface knows the auth type before any request goes out\n\n    // Store refresh token persistently if provided (always in localStorage)\n    if (data.refreshToken) {\n      this.storage.storePersistent(Constants.AUTH_REFRESH_TOKEN, data.refreshToken);\n      this.storage.storePersistent(Constants.AUTH_REFRESH_TOKEN_EXPIRE, data.refreshTokenExpiry);\n    }\n\n    this.scheduleTokenRefresh(data.expiration); // Changed: Schedule proactive refresh before token expires\n  }\n\n  // Changed: Schedule a silent refresh 5 minutes before the access token expires\n  private scheduleTokenRefresh(expiration: string) {\n    if (this.refreshTimer) clearTimeout(this.refreshTimer); // Clear any existing timer\n\n    const expiresAt = new Date(expiration).getTime();\n    const now = Date.now();\n    const refreshIn = expiresAt - now - (5 * 60 * 1000); // 5 minutes before expiry\n\n    if (refreshIn <= 0) return; // Token already expired or about to — reactive refresh will handle it\n\n    this.refreshTimer = setTimeout(() => {\n      this.silentRefresh().then(result => {\n        // Changed: only a server rejection ends the session; a network blip retries in 2 minutes\n        if (result === 'rejected') this.sessionExpired();\n        else if (result === 'network') this.scheduleRetry();\n      });\n    }, refreshIn);\n  }\n\n  // Changed: retry a failed proactive refresh after a network error, while the access token may still be alive\n  private scheduleRetry() {\n    if (this.refreshTimer) clearTimeout(this.refreshTimer);\n    this.refreshTimer = setTimeout(() => {\n      this.silentRefresh().then(result => {\n        if (result === 'rejected') this.sessionExpired();\n        else if (result === 'network') this.scheduleRetry();\n      });\n    }, 2 * 60 * 1000);\n  }\n\n  // Changed: When tab becomes visible, check if token needs immediate refresh\n  private initVisibilityRefresh() {\n    document.addEventListener('visibilitychange', () => {\n      if (document.visibilityState !== 'visible') return;\n      if (!this.loggedin) return;\n\n      const expire = this.tokenExpireSource.value;\n      if (!expire) return;\n\n      const expiresAt = new Date(expire).getTime();\n      const now = Date.now();\n      const minutesLeft = (expiresAt - now) / 60000;\n\n      // If token expires in less than 10 minutes or is already expired, refresh immediately\n      if (minutesLeft < 10 && this.hasRefreshToken()) {\n        this.silentRefresh().then(result => {\n          // Changed: quiet redirect only on explicit server rejection — network errors keep the session and retry\n          if (result === 'rejected') this.sessionExpired();\n          else if (result === 'network') this.scheduleRetry();\n        });\n      }\n    });\n  }\n\n  // Changed: Non-destructive check — only returns true if token is genuinely valid (not expired)\n  hasValidSession(): boolean {\n    // Check in-memory state first\n    if (this.loggedin && this.tokenExpireSource.value) {\n      const tokenExpire = new Date(this.tokenExpireSource.value);\n      if (tokenExpire > new Date()) return true;\n    }\n\n    // Changed: Check localStorage for non-expired token (not just existence)\n    const localExpiry = localStorage.getItem(Constants.AUTH_TOKEN_EXPIRE);\n    if (localExpiry) {\n      try {\n        const expiry = new Date(JSON.parse(unescape(atob(localExpiry))));\n        if (expiry > new Date()) return true;\n      } catch { /* ignore parse errors */ }\n    }\n\n    // Changed: Check sessionStorage for non-expired token\n    const sessionExpiry = sessionStorage.getItem(Constants.AUTH_TOKEN_EXPIRE);\n    if (sessionExpiry) {\n      try {\n        const expiry = new Date(JSON.parse(unescape(atob(sessionExpiry))));\n        if (expiry > new Date()) return true;\n      } catch { /* ignore parse errors */ }\n    }\n\n    // Changed: Refresh token alone does NOT count as valid session — caller must handle refresh separately\n    return false;\n  }\n\n  // Changed: Check if a refresh token exists (for login page to attempt silent refresh)\n  hasRefreshToken(): boolean {\n    const refreshToken = this.storage.getPersistent(Constants.AUTH_REFRESH_TOKEN);\n    return refreshToken !== null;\n  }\n\n  // Shared entry point for any page that needs to auto-redirect authenticated users\n  // Returns true if session is active or was successfully restored via silent refresh\n  async tryRestoreSession(): Promise<boolean> {\n    if (this.hasValidSession()) return true;\n    if (this.hasRefreshToken()) return (await this.silentRefresh()) === 'success'; // Changed: silentRefresh now returns a tri-state result\n    return false;\n  }\n\n  // Changed: Silently refresh the JWT using the stored refresh token.\n  // Returns a shared promise — concurrent callers await the SAME in-flight refresh instead of\n  // being told it failed (the old boolean guard caused spurious logouts when guard/visibility/timer overlapped).\n  silentRefresh(): Promise<RefreshResult> {\n    if (this.refreshPromise) return this.refreshPromise;\n\n    const refreshToken = this.storage.getPersistent(Constants.AUTH_REFRESH_TOKEN);\n    if (!refreshToken) return Promise.resolve('rejected');\n\n    this.refreshPromise = new Promise<RefreshResult>((resolve) => {\n      this.httpService.Post('User/refresh', { refreshToken }).subscribe({\n        next: (response: any) => {\n          if (response.success) {\n            const rememberMe = this.storage.getPersistent(Constants.AUTH_REMEMBER_ME) ?? true;\n            this.applyLoginResponse(response.data, rememberMe);\n            resolve('success');\n          } else {\n            // Changed: Server explicitly rejected the token (revoked/expired) — safe to clear\n            const currentToken = this.storage.getPersistent(Constants.AUTH_REFRESH_TOKEN);\n            if (currentToken === refreshToken) {\n              this.storage.removePersistent(Constants.AUTH_REFRESH_TOKEN);\n              this.storage.removePersistent(Constants.AUTH_REFRESH_TOKEN_EXPIRE);\n              this.storage.removePersistent(Constants.AUTH_REMEMBER_ME);\n            }\n            resolve('rejected');\n          }\n        },\n        error: () => {\n          // Changed: Network error (device waking up, backend briefly down) — do NOT clear the refresh token.\n          // The token may still be valid; next visibility change or 401 interceptor will retry.\n          resolve('network');\n        }\n      });\n    }).finally(() => { this.refreshPromise = null; }) as Promise<RefreshResult>;\n\n    return this.refreshPromise;\n  }\n\n\n  // Changed: Returns Promise<boolean> to properly await refresh instead of optimistically returning true\n  checkAuthentication(): Promise<boolean> {\n\n    if (this.loggedin && this.isValidToken()) {\n      return Promise.resolve(true);\n    }\n\n    // Changed: Restore storage mode from persistent remember-me flag\n    const rememberMe = this.storage.getPersistent(Constants.AUTH_REMEMBER_ME);\n    if (rememberMe !== null) {\n      this.storage.setSessionMode(!rememberMe);\n    }\n\n    if (this.storage.hasKey(Constants.AUTH_USER)) {\n\n      this.Updateloggedin(true);\n\n      this.storage.get(Constants.AUTH_USER).then((resp: any) => {\n        this.UpdateCurrentUser(resp);\n        // Added: only now is the username known, and the offline store is keyed by it — so this is the earliest\n        // point a restored session can reclaim its own parked work. Doing it before this resolves would open the\n        // wrong (placeholder-named) store and silently find nothing to sync.\n        try { this.injector.get(OfflineService).resumeQueue(); } catch { /* offline layer not in use */ }\n      });\n\n      this.storage.get(Constants.AUTH_NAME).then((resp: any) => {\n        this.updateLoggedUserFullName(resp);\n      });\n\n      this.storage.get(Constants.AUTH_ROLES).then((resp) => {\n        let ret = JSON.parse(resp);\n\n        this.UpdateRole(ret);\n      });\n\n      this.storage.get(Constants.AUTH_TENANT_NAME).then((resp: any) => {\n        this.updateTenantName(resp);\n      });\n\n      // Added: restore the auth type on a cold start. This is the case the whole change exists for — reaching\n      // a password surface by typing its URL never replays login, so without this the flag is empty until the\n      // next silent refresh, which may be nearly an hour away.\n      this.storage.get(Constants.AUTH_TYPE).then((resp: any) => {\n        if (resp) this.UpdateAuthType(resp);\n      });\n\n      // Changed: Load token and check validity — if expired, await silentRefresh before allowing navigation\n      return this.storage.get(Constants.AUTH_TOKEN).then((token: any) => {\n        this.UpdateToken(token);\n        return this.storage.get(Constants.AUTH_TOKEN_EXPIRE);\n      }).then((expire: any) => {\n        this.UpdateTokenExpire(expire);\n\n        const tokenExpire = new Date(expire);\n        if (tokenExpire > new Date()) {\n          return true; // Token still valid\n        }\n\n        // Token expired — attempt silent refresh and wait for result\n        const refreshToken = this.storage.getPersistent(Constants.AUTH_REFRESH_TOKEN);\n        if (refreshToken) {\n          // Changed: tri-state — anything but success sends the user quietly to the login page.\n          // On 'network' the refresh token is preserved, so the login page can retry the restore.\n          return this.silentRefresh().then((result) => {\n            if (result !== 'success') {\n              this.sessionExpired();\n            }\n            return result === 'success';\n          });\n        }\n\n        this.sessionExpired();\n        return false;\n      });\n    }\n\n    // Changed: Check for persistent refresh token when no session data exists\n    const refreshToken = this.storage.getPersistent(Constants.AUTH_REFRESH_TOKEN);\n    if (refreshToken) {\n      // Changed: Wait for refresh to complete before deciding (tri-state result)\n      return this.silentRefresh().then((result) => {\n        if (result !== 'success') {\n          this.sessionExpired();\n        }\n        return result === 'success';\n      });\n    }\n\n    this.sessionExpired();\n    return Promise.resolve(false);\n  }\n}\n","\nimport { Injectable, Injector, inject } from '@angular/core'; // Changed: Injector — the library Getting Started / Day Book defaults resolve the entity services LAZILY, see below\nimport { Action, ApiResponse, AppConfig, AppConfigSection, Button, CacheConfig, CapItem, Column, DayBookColumnView, DayBookLane, DayBookSection, DayBookTableView, DetailsDialogConfig, FormConfig, RoleAccess, SetupStepAction, TableConfig } from '../classes/Classes'; // Changed: AppConfigSection for the App Configuration base sections; RoleAccess for the unlock button's Full gate // Changed (library defaults P5/P6): SetupStepAction, DayBookSection/Lane/ColumnView/TableView and Column type the two library defaults, so a wrong key or a behavioural override fails the BUILD rather than rendering blank\n// 🔴 THESE SEVEN IMPORTS ARE CIRCULAR BY CONSTRUCTION AND MUST STAY LAZY AT RUNTIME. Every one of these services\n// injects DataServiceLib itself, so a field-level `inject(AccountingService)` here would be a genuine Angular\n// circular dependency and would throw at construction. They are resolved through `injector.get(...)` INSIDE the\n// two getters instead, which runs long after both classes are constructed. The ES-module cycle is harmless for\n// the same reason — nothing at module-evaluation time touches the other module's bindings.\nimport { AccountingService } from './accounting.service';\nimport { InventoryService } from './inventory.service';\nimport { SalesService } from './sales.service';\nimport { PurchasingService } from './purchasing.service';\nimport { ProductionService } from './production.service';\nimport { PayrollService } from './payroll.service';\nimport { LoansService } from './loans.service';\nimport { BehaviorSubject, catchError, finalize, from, map, Observable, of, share, tap, throwError, timeout } from 'rxjs'; // Changed: added catchError/from/map/throwError for TinSync offline seams\nimport { HttpService } from './http.service';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { SignupData, User } from '../classes/LibClasses'; // Changed: Added SignupData import\nimport { AuthService } from './auth.service';\nimport { OfflineService, OfflineEntry } from './offline.service'; // Added: TinSync unified offline service\nimport { silentContext } from '../runtime/silent-request'; // Added: Quiet Loading — tags a call so the global scrim stays down\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class DataServiceLib {\n\n  private injector = inject(Injector); // Added (library defaults P5/P6): lazy resolution of the seven entity services — see the import block's note on why they cannot be injected directly\n\n  constructor(private httpService: HttpService, public router: Router, private route: ActivatedRoute, private authService: AuthService,\n    private offline: OfflineService) { // Changed: TinSync unified offline service (inert while no table registers)\n\n    this.appConfig.appName = \"App-Name\";\n    this.appConfig.logo = \"./assets/logo.png\"\n    this.appConfig.ADAuth = true;\n\n    this.appConfig.capItems = [this.capMultitenant, this.capAdmin, this.capHome];\n\n\n    this.capHome.name = \"cap1\";\n    this.capHome.display = \"Home\";\n    this.capHome.link = \"home\";\n    this.capHome.icon =\"home\";\n\n\n    this.capAdmin.name = \"cap2\";\n    this.capAdmin.display = \"Admin\";\n    this.capAdmin.icon = \"security\"\n    this.capAdmin.capSubItems = [this.capUsers, this.capRoles, this.capPasswordPolicy, this.capLogs, this.capSettings, this.capTenantReset]; // Changed (N8): Password Policy sits with Users and Roles — it is the rule those accounts' passwords are held to, and it is where an administrator goes looking for it. Changed (N22): capTenantReset joins them — it is an administrative permission and Admin is where an administrator goes to revoke it\n\n    this.capUsers.name = \"cap3\";\n    this.capUsers.display = \"Users\";\n    this.capUsers.link = \"home/admin/users\";\n    this.capUsers.icon = \"group\";\n\n    this.capRoles.name = \"cap4\"\n    this.capRoles.display = \"Roles\";\n    this.capRoles.link = \"home/admin/roles\";\n    this.capRoles.icon = \"work\";\n\n    this.capLogs.name = \"cap5\"\n    this.capLogs.display = \"Logs\";\n    this.capLogs.link = \"home/admin/logs\";\n    this.capLogs.icon = \"text_snippet\";\n\n    // Added (N8): the per-tenant password policy page.\n    //\n    // ── HOW cap89 WAS CHOSEN, and why NOT cap88 ────────────────────────────────────────────────────────────────\n    // Library capabilities live in the 1-86 range with cap87 taken by Unlock (TinWeb Contracts\\Capabilities.cs\n    // records the census and the rule: take the next number ABOVE the range in use, because a number VACATED by\n    // MigrationService.MigrateCapValues can still hold a stale true on some role). 88 is exactly such a number —\n    // shift-spa's own comment records capTripTemplates being \"Moved from cap88 to cap154\" — so reusing it would\n    // hand the Password Policy menu to whichever Shift roles still carry that old grant. A census on 2026-08-16\n    // across TinWeb, tin-spa and all five consumer apps found cap89-cap100 used by nothing at all. 89 it is.\n    //\n    // This gates the MENU ENTRY only. The authority to change the policy is PasswordConfigController's\n    // IsCurrentUserAdmin() test and stays there; whether that should become a capability instead is an open\n    // question for Tinashe and is deliberately NOT answered here. The two line up in practice either way:\n    // MigrateCapValues sets Cap31-Cap100 to Full for the Admin and Owner roles and None for every other role, so\n    // the people who can see this page are already the people the server will accept a save from.\n    this.capPasswordPolicy.name = \"cap89\"\n    this.capPasswordPolicy.display = \"Password Policy\";\n    this.capPasswordPolicy.link = \"home/admin/password-policy\";\n    this.capPasswordPolicy.icon = \"password\";\n\n    this.capSettings.name = \"cap6\"\n    this.capSettings.display = \"Settings\";\n    this.capSettings.link = \"home/admin/settings\";\n    this.capSettings.icon =\"settings\";\n\n    // Added: cap92 — gates the tenant reset (`POST appconfiguration/reset`, TinWeb eedc29c), which soft-deletes\n    // every Operational row for the current tenant. Like cap87 and cap90 it is a PERMISSION, not a page: no link,\n    // and showMenu = false keeps it out of every nav rendering, while the Roles screen — which does NOT filter on\n    // showMenu — still renders its access level.\n    // 🔴 THIS ENTRY IS THE ONLY WAY THE CAPABILITY CAN BE REVOKED. The seeded Admin and Owner roles hold every\n    // CapN at Full, so they hold cap92 from day one, and MigrateCapValues re-grants it on every multi-tenant boot\n    // (MigrationService.cs:275) — deny-by-default does not survive and role templates can only ever RAISE a level\n    // (SetupRoleService.cs:120-124). Without this entry a destructive tenant-wide capability would be ungrantable\n    // AND unrevokable from the Roles screen, repairable only by a direct database write.\n    // ⚠️ The server demands RoleAccess.Full (AppConfigurationControllerBase.cs:155), not Edit — the reset button\n    // sends Full too, and the two sides must not disagree.\n    this.capTenantReset.name = \"cap92\"\n    this.capTenantReset.display = \"Tenant Reset\";\n    this.capTenantReset.showMenu = false;\n\n\n    this.capMultitenant.name = \"cap7\"\n    this.capMultitenant.display = \"Multitenant\";\n    this.capMultitenant.icon = \"apartment\"\n    this.capMultitenant.capSubItems = [this.capTenants, this.capMembership, this.capPlans, this.capFeatures, this.capPlanFeatures]; // Changed: Moved Subscription & Billing to Admin — they are tenant-specific settings\n\n    this.capTenants.name = \"cap8\"\n    this.capTenants.display = \"Tenants\";\n    this.capTenants.link = \"home/tenancy/tenants\";\n\n    this.capMembership.name = \"cap9\"\n    this.capMembership.display = \"Membership\";\n    this.capMembership.link = \"home/tenancy/membership\";\n\n    this.capPlans.name = \"cap10\"\n    this.capPlans.display = \"Plans\";\n    this.capPlans.link = \"home/tenancy/plans\";\n\n    // Added: Feature registry capability\n    this.capFeatures.name = \"cap80\"\n    this.capFeatures.display = \"Features\";\n    this.capFeatures.link = \"home/tenancy/features\";\n    this.capFeatures.icon = \"extension\";\n\n    // Added: Plan-Feature mapping capability\n    this.capPlanFeatures.name = \"cap81\"\n    this.capPlanFeatures.display = \"Plan Features\";\n    this.capPlanFeatures.link = \"home/tenancy/plan-features\";\n    this.capPlanFeatures.icon = \"checklist\";\n\n    // Added: Subscription management capability\n    this.capSubscription.name = \"cap82\"\n    this.capSubscription.display = \"Subscription\";\n    this.capSubscription.link = \"home/tenancy/subscription\";\n    this.capSubscription.icon = \"card_membership\";\n\n    // Added: Billing & invoice history capability\n    this.capBilling.name = \"cap83\"\n    this.capBilling.display = \"Billing\";\n    this.capBilling.link = \"home/tenancy/billing\";\n    this.capBilling.icon = \"receipt_long\";\n\n    this.capGeneral.name = \"cap11\"\n    this.capGeneral.display = \"General\";\n    this.capGeneral.moduleKey = \"general\"; // Added (Setup v3): library module gating, assigned once here instead of per app\n    this.capGeneral.capSubItems = [\n      this.capNotifications,this.capApprovals,this.capCustomers, this.capSuppliers,\n      this.capCategories, this.capSubCategories, this.capBrands, this.capTasks, this.capSubscription, this.capBilling,\n      this.capReferenceData // Changed (cap90): sits beside Customers and Suppliers, two of the three registers it gates\n    ];\n\n    // Added: cap90 — gates the `list` route of the reference-data registers (products/tax-rates, customers,\n    // suppliers) via `AllowListWithoutCapability` on TinWeb's ProductsController, CustomersController and\n    // SuppliersController (TinWeb 9395832). Like cap87 it is a PERMISSION, not a page: no link, and\n    // showMenu = false keeps it out of every nav rendering, while the Roles screen — which does NOT filter on\n    // showMenu — still renders its access level. That is the whole reason this entry exists: without it cap90\n    // is invisible and ungrantable from the Roles screen, so an administrator could never repair a role that\n    // the per-boot template sync permanently skips (edited/renamed/hand-created roles, and the seeded\n    // \"Default\" role, which is not a template name).\n    // It is placed under General rather than Inventory because two of its three registers (Customers cap12,\n    // Suppliers cap14) live there, and the server checks it on the controllers, so one grant covers all three.\n    // Granted `RoleAccess.View` by all 19 role templates across the four setup providers.\n    this.capReferenceData.name = \"cap90\"\n    this.capReferenceData.display = \"Reference Data\";\n    this.capReferenceData.showMenu = false;\n\n    this.capCustomers.name = \"cap12\"\n    this.capCustomers.display = \"Customers\";\n    this.capCustomers.link = \"home/general/customers\";\n    this.capCustomers.icon = \"group\"\n\n    this.capCategories.name = \"cap13\"\n    this.capCategories.display = \"Categories\";\n    this.capCategories.link = \"home/general/categories\";\n    this.capCategories.icon = \"category\"\n\n    this.capSubCategories.name = \"cap43\" // Changed: Moved from cap13 to cap43 — resolve duplicate with capCategories\n    this.capSubCategories.display = \"Sub Categories\";\n    this.capSubCategories.link = \"home/general/subcategories\";\n    this.capSubCategories.icon = \"category\"\n\n    this.capBrands.name = \"cap14\"\n    this.capBrands.display = \"Brands\";\n    this.capBrands.link = \"home/general/brands\";\n    this.capBrands.icon = \"loyalty\"\n\n    // Added: GPT Cache capability\n    this.capGPTCaches.name = \"cap65\" // Changed: Moved from cap104 to cap65 — library range consolidation\n    this.capGPTCaches.display = \"GPT Cache\";\n    this.capGPTCaches.link = \"home/admin/gpt-caches\";\n    this.capGPTCaches.icon = \"memory\"\n\n    // Changed: capPreferences (cap66) is GONE — Preferences merged into each app's App Configuration page,\n    // which is gated by the app's own config capability. Apps link to it with their capAppConfiguration.\n\n    this.capSuppliers.name = \"cap15\"\n    this.capSuppliers.display = \"Suppliers\";\n    this.capSuppliers.link = \"home/general/suppliers\";\n    this.capSuppliers.icon = \"groups\"\n\n    this.capTasks.name = \"cap16\"\n    this.capTasks.display = \"Tasks\";\n    this.capTasks.moduleKey = \"tasks\"; // Added (Setup v3)\n    this.capTasks.link = \"home/general/tasks\";\n    this.capTasks.icon = \"check_box\"\n\n\n    this.capHR.name = \"cap17\"\n    this.capHR.display = \"HR\";\n    this.capHR.moduleKey = \"hr\"; // Added (Setup v3)\n    // Changed (menucap-1 M1): link REMOVED. cap17 is a GROUP cap and was the only group in this file carrying a link — it pointed at home/hr/employees, whose page gates on capEmployees cap18 (:907), so a role holding cap17 without cap18 saw an HR entry, clicked it, and hit no-access for a cap it was never shown. Its own child capEmployees (:218-220) already links there. Line kept as a comment: SetupModuleGuardTests.CapItemsModel:216 pins capHR's capSubItems at line 205\n    this.capHR.icon = \"diversity_3\"\n    this.capHR.capSubItems = [this.capDepartments, this.capPositions, this.capUnlock, this.capEmployees,] // Changed: capUnlock sits beside the two ILock entities it releases, so the grant is found where it is used\n\n    // Added: cap87 — releases the ILock protection (`POST /api/{entity}?action=unlock`, TinWeb 51f30e4). It is a\n    // PERMISSION, not a page: no link, and showMenu = false keeps it out of every nav rendering while the Roles\n    // screen (which does not filter on showMenu) still renders its access level. It lives under HR because the\n    // only two ILock entities today are Department (cap19) and Position (cap20), but the server checks it on the\n    // BASE controller, so a future ILock entity anywhere is covered by this one grant rather than a new column.\n    // Deliberately in NO role template — Owner/Admin hold it because they hold every cap; anyone else is granted\n    // it on purpose, which is the point of gating an irreversible action.\n    this.capUnlock.name = \"cap87\"\n    this.capUnlock.display = \"Unlock Records\";\n    this.capUnlock.showMenu = false;\n\n    this.capEmployees.name = \"cap18\"\n    this.capEmployees.display = \"Employees\";\n    this.capEmployees.link = \"home/hr/employees\";\n    this.capEmployees.icon = \"group\"\n\n    this.capDepartments.name = \"cap19\"\n    this.capDepartments.display = \"Departments\";\n    this.capDepartments.link = \"home/hr/departments\";\n    this.capDepartments.icon = \"business_center\"\n\n    this.capPositions.name = \"cap20\"\n    this.capPositions.display = \"Positions\";\n    this.capPositions.link = \"home/hr/positions\";\n    this.capPositions.icon = \"picture_in_picture_medium\"\n\n    // Changed: Added Payroll module sidebar section\n    this.capPayroll.name = \"cap72\" // Changed: Moved from cap110 to cap72 — library range consolidation\n    this.capPayroll.display = \"Payroll\";\n    this.capPayroll.moduleKey = \"payroll\"; // Added (Setup v3)\n    this.capPayroll.icon = \"payments\"\n    this.capPayroll.capSubItems = [this.capPayrollDashboard, this.capSalaryStructures, this.capStatutoryDeductions, this.capPayrollRuns, this.capCommissionConfigs, this.capCommissionEntries, this.capCommissionStatement, this.capSalaryAdvances, this.capOvertimeEntries] // Changed (Phase 6): commission statement sits directly under the entries it explains\n\n    this.capPayrollDashboard.name = \"cap72\"; // Changed: Reuses module cap number for dashboard visibility\n    this.capPayrollDashboard.display = \"Dashboard\";\n    this.capPayrollDashboard.link = \"home/payroll/dashboard\";\n    this.capPayrollDashboard.icon = \"dashboard\";\n\n    this.capSalaryStructures.name = \"cap73\" // Changed: Moved from cap111 to cap73 — library range consolidation\n    this.capSalaryStructures.display = \"Salary Structures\";\n    this.capSalaryStructures.link = \"home/payroll/salary-structures\";\n    this.capSalaryStructures.icon = \"account_tree\"\n\n    this.capStatutoryDeductions.name = \"cap74\" // Changed: Moved from cap112 to cap74 — library range consolidation\n    this.capStatutoryDeductions.display = \"Statutory Deductions\";\n    this.capStatutoryDeductions.link = \"home/payroll/statutory-deductions\";\n    this.capStatutoryDeductions.icon = \"gavel\"\n\n    this.capPayrollRuns.name = \"cap75\" // Changed: Moved from cap113 to cap75 — library range consolidation\n    this.capPayrollRuns.display = \"Payroll Runs\";\n    this.capPayrollRuns.link = \"home/payroll/runs\";\n    this.capPayrollRuns.icon = \"play_circle\"\n\n    // Changed: Added Commission Config sidebar item\n    this.capCommissionConfigs.name = \"cap76\"\n    this.capCommissionConfigs.display = \"Commission Config\";\n    this.capCommissionConfigs.link = \"home/payroll/commission-configs\";\n    this.capCommissionConfigs.icon = \"percent\"\n\n    // Changed: Added Commission Entries sidebar item\n    this.capCommissionEntries.name = \"cap77\"\n    this.capCommissionEntries.display = \"Commission Entries\";\n    this.capCommissionEntries.link = \"home/payroll/commission-entries\";\n    this.capCommissionEntries.icon = \"request_quote\"\n\n    // Added (Phase 6): the Driver Commission Statement — cap86, its own capability rather than cap77's, because\n    // it is the surface that GENERATES a period as well as reporting it, and because reading a whole period's\n    // commission across every driver is a wider grant than working one entry. Deliberately in NO role template:\n    // it is registered and reachable, and someone has to grant it on purpose.\n    this.capCommissionStatement.name = \"cap86\"\n    this.capCommissionStatement.display = \"Commission Statement\";\n    this.capCommissionStatement.link = \"home/payroll/commission-statement\";\n    this.capCommissionStatement.icon = \"receipt_long\"\n\n    // Changed: Added Salary Advances sidebar item\n    this.capSalaryAdvances.name = \"cap78\"\n    this.capSalaryAdvances.display = \"Salary Advances\";\n    this.capSalaryAdvances.link = \"home/payroll/salary-advances\";\n    this.capSalaryAdvances.icon = \"money_off\"\n\n    // Changed: Added Overtime sidebar item\n    this.capOvertimeEntries.name = \"cap79\"\n    this.capOvertimeEntries.display = \"Overtime\";\n    this.capOvertimeEntries.link = \"home/payroll/overtime-entries\";\n    this.capOvertimeEntries.icon = \"more_time\"\n\n    this.capApprovals.name = \"cap21\"\n    this.capApprovals.display = \"Approvals\";\n    this.capApprovals.moduleKey = \"approvals\"; // Added (Setup v3)\n    this.capApprovals.link = \"home/workflow/approvals\";\n    this.capApprovals.icon = \"rule\"\n\n    this.capApprovalsConfig.name = \"cap22\"\n    this.capApprovalsConfig.display = \"Approvals Config\";\n    this.capApprovalsConfig.link = \"home/workflow/approvals-config\";\n    this.capApprovalsConfig.icon = \"published_with_changes\"\n    this.capApprovalsConfig.capSubItems = [this.capSelfApproval]\n\n    this.capSelfApproval.name = \"cap23\"\n    this.capSelfApproval.display = \"Self Approvals\";\n    this.capSelfApproval.isBool = true;\n\n    this.capNotifications.name = \"cap24\"\n    this.capNotifications.display = \"Notifications\";\n    this.capNotifications.link = \"home/workflow/notifications\";\n    this.capNotifications.icon = \"notifications\"\n\n    this.capAppModels.name = \"cap25\"\n    this.capAppModels.display = \"App Models\";\n    this.capAppModels.link = \"home/workflow/appmodels\";\n    // this.capAppModels.icon = \"notifications\"\n\n    this.capNotificationsConfig.name = \"cap26\"\n    this.capNotificationsConfig.display = \"Notif Config\";\n    this.capNotificationsConfig.link = \"home/workflow/notifications-config\";\n\n    this.capAccounting.name = \"cap27\";\n    this.capAccounting.display = \"Accounting\";\n    this.capAccounting.moduleKey = \"accounting\"; // Added (Setup v3)\n    this.capAccounting.icon = \"account_balance\";\n    this.capAccounting.capSubItems = [ this.capAccountingDashboard, this.capAccounts, this.capTransactions, this.capAggregates, this.capReports, this.capVatReturn, this.capFiscalPeriods, this.capBankReconciliation, this.capTenantTransfers, this.capBudgets, this.capBudgetVsActual, this.capTransactionTypes, this.capTaxRates, this.capCurrencies, this.capStandingOrders]; // Changed: Added Bank Reconciliation (C4) after Fiscal Periods\n\n    this.capAccountingDashboard.name = \"cap27\"; // Changed: Reuses module cap number for dashboard visibility\n    this.capAccountingDashboard.display = \"Dashboard\";\n    this.capAccountingDashboard.link = \"home/accounting/dashboard\";\n    this.capAccountingDashboard.icon = \"dashboard\";\n\n    this.capAccounts.name = \"cap52\"; // Changed: Fixed conflict with capBrands (was cap14)\n    this.capAccounts.display = \"Accounts\";\n    this.capAccounts.link = \"home/accounting/accounts\";\n    this.capAccounts.icon = \"account_balance_wallet\";\n\n    this.capAggregates.name = \"cap57\"; // Added: Aggregates capability\n    this.capAggregates.display = \"Aggregates\";\n    this.capAggregates.link = \"home/accounting/aggregates\";\n    this.capAggregates.icon = \"bar_chart\";\n\n\n    this.capReports.name = \"cap48\"; // Changed: Moved from cap61 to cap48 — resolve duplicate with capSalesModule\n    this.capReports.display = \"Reports\";\n    this.capReports.link = \"home/accounting/reports\";\n    this.capReports.icon = \"assessment\";\n\n    // Changed: VAT return menu item (B2) — shares the Reports capability (cap48)\n    this.capVatReturn.name = \"cap48\";\n    this.capVatReturn.display = \"VAT Return\";\n    this.capVatReturn.link = \"home/accounting/vat-return\";\n    this.capVatReturn.icon = \"receipt_long\";\n\n    // Changed: Fiscal periods menu item (C2) — shares the Accounts capability (cap52)\n    this.capFiscalPeriods.name = \"cap52\";\n    this.capFiscalPeriods.display = \"Fiscal Periods\";\n    this.capFiscalPeriods.link = \"home/accounting/fiscal-periods\";\n    this.capFiscalPeriods.icon = \"event_repeat\";\n\n    // Changed: Bank reconciliation menu item (C4) — shares the Accounts capability (cap52)\n    this.capBankReconciliation.name = \"cap52\";\n    this.capBankReconciliation.display = \"Bank Reconciliation\";\n    this.capBankReconciliation.link = \"home/accounting/bank-reconciliation\";\n    this.capBankReconciliation.icon = \"rule\";\n\n    // Added: Budgets capability (cap85) — gates BudgetsController, BudgetLinesController, BudgetReportController\n    this.capBudgets.name = \"cap85\";\n    this.capBudgets.display = \"Budgets\";\n    this.capBudgets.link = \"home/accounting/budgets\";\n    this.capBudgets.icon = \"account_balance_wallet\";\n\n    // Added: Budget vs Actual report menu item — shares the Budgets capability (cap85, BudgetReportController)\n    this.capBudgetVsActual.name = \"cap85\";\n    this.capBudgetVsActual.display = \"Budget vs Actual\";\n    this.capBudgetVsActual.link = \"home/accounting/budget-vs-actual\";\n    this.capBudgetVsActual.icon = \"compare_arrows\";\n\n    this.capTaxRates.name = \"cap46\"; // Changed: Moved from cap60 to cap46 — resolve duplicate with capManufacturing\n    this.capTaxRates.display = \"Tax Rates\";\n    this.capTaxRates.link = \"home/accounting/tax-rates\";\n    this.capTaxRates.icon = \"percent\";\n\n    // Changed: Added Currencies to Accounting menu — feature exists but was missing from nav\n    this.capCurrencies.name = \"cap84\";\n    this.capCurrencies.display = \"Currencies\";\n    this.capCurrencies.link = \"home/accounting/currencies\";\n    this.capCurrencies.icon = \"currency_exchange\";\n\n    this.capStandingOrders.name = \"cap64\"; // Changed: Standing orders capability\n    this.capStandingOrders.display = \"Standing Orders\";\n    this.capStandingOrders.link = \"home/accounting/standing-orders\";\n    this.capStandingOrders.icon = \"schedule\";\n\n    // Added (N11): Organisation Transfers — cross-organisation money arrangements and transfers, shared page,\n    // sits in the ACCOUNTING menu by owner directive (2026-08-17). Replaces grip-spa's app-local page and its\n    // unrecorded cap111 (cap111 is in the consumer-app range and is Piglet's Treatments — the collision was\n    // only survivable because roles are per-app).\n    //\n    // ── HOW cap91 WAS CHOSEN — same rule as cap87/cap89/cap90 (TinWeb Contracts\\Capabilities.cs census) ──\n    // The census on 2026-08-17 (cap90's) found \"cap90\" and \"cap91\" used by NOTHING anywhere — backend,\n    // tin-spa, consumer apps, Kotlin. cap90 took Shared Reference Data, so 91 is the next number that is both\n    // free and NEVER-ASSIGNED (88 stays skipped — vacated numbers can hold stale grants). Like cap89 this\n    // gates the MENU ENTRY and the dialogs' security allow-lists; the server authority remains\n    // CrossTenantTransfersController's IsAdmin() test on every verb.\n    this.capTenantTransfers.name = \"cap91\";\n    this.capTenantTransfers.display = \"Organisation Transfers\";\n    this.capTenantTransfers.link = \"home/accounting/tenant-transfers\";\n    this.capTenantTransfers.icon = \"swap_horiz\";\n\n    // Changed: Fixed Assets is now its own top-level module\n    this.capFixedAssetsModule.name = \"cap70\";\n    this.capFixedAssetsModule.display = \"Fixed Assets\";\n    this.capFixedAssetsModule.moduleKey = \"fixed-assets\"; // Added (Setup v3)\n    this.capFixedAssetsModule.icon = \"precision_manufacturing\";\n    this.capFixedAssetsModule.capSubItems = [this.capFixedAssetsDashboard, this.capFixedAssets, this.capFixedAssetCategories];\n\n    this.capFixedAssetsDashboard.name = \"cap70\"; // Reuses module cap number for dashboard visibility\n    this.capFixedAssetsDashboard.display = \"Dashboard\";\n    this.capFixedAssetsDashboard.link = \"home/fixed-assets/dashboard\";\n    this.capFixedAssetsDashboard.icon = \"dashboard\";\n\n    this.capFixedAssets.name = \"cap70\";\n    this.capFixedAssets.display = \"Asset Register\";\n    this.capFixedAssets.link = \"home/fixed-assets/register\"; // Changed: Updated route\n    this.capFixedAssets.icon = \"precision_manufacturing\";\n\n    this.capFixedAssetCategories.name = \"cap71\";\n    this.capFixedAssetCategories.display = \"Depreciation Categories\"; // Changed: Renamed from Categories\n    this.capFixedAssetCategories.link = \"home/fixed-assets/depreciation-categories\"; // Changed: Updated route\n    this.capFixedAssetCategories.icon = \"category\";\n\n    this.capTransactionTypes.name = \"cap28\";\n    this.capTransactionTypes.display = \"Transaction Types\";\n    this.capTransactionTypes.link = \"home/accounting/transaction-types\";\n    this.capTransactionTypes.icon = \"category\";\n\n    this.capTransactions.name = \"cap29\";\n    this.capTransactions.display = \"Transactions\";\n    this.capTransactions.link = \"home/accounting/transactions\";\n    this.capTransactions.icon = \"receipt_long\";\n\n    this.capInvoicing.name = \"cap53\";\n    this.capInvoicing.display = \"Invoicing\";\n    this.capInvoicing.moduleKey = \"invoicing\"; // Added (Setup v3)\n    this.capInvoicing.icon = \"receipt_long\";\n    this.capInvoicing.capSubItems = [ this.capInvoiceDashboard, this.capQuotes, this.capAccountingInvoices, this.capCreditNotes, this.capReceipts, this.capRevenueSchedules, this.capAging, this.capAccountingOutstandingInvoices ]; // Changed: Added quotations (C10) before invoices\n\n    this.capInvoiceDashboard.name = \"cap53\"; // Changed: Reuses module cap number for dashboard visibility\n    this.capInvoiceDashboard.display = \"Dashboard\";\n    this.capInvoiceDashboard.link = \"home/accounting/invoice-dashboard\";\n    this.capInvoiceDashboard.icon = \"dashboard\";\n\n    this.capAccountingInvoices.name = \"cap53\";\n    this.capAccountingInvoices.display = \"Invoices\";\n    this.capAccountingInvoices.link = \"home/accounting/invoices\";\n    this.capAccountingInvoices.icon = \"receipt_long\";\n\n    // Changed: Credit notes menu item (B6) — shares the Invoices capability (cap53)\n    this.capCreditNotes.name = \"cap53\";\n    this.capCreditNotes.display = \"Credit Notes\";\n    this.capCreditNotes.link = \"home/accounting/credit-notes\";\n    this.capCreditNotes.icon = \"assignment_return\";\n\n    // Changed: Customer receipts menu item (C3) — shares the Invoices capability (cap53)\n    this.capReceipts.name = \"cap53\";\n    this.capReceipts.display = \"Receipts\";\n    this.capReceipts.link = \"home/accounting/receipts\";\n    this.capReceipts.icon = \"receipt\";\n\n    // Changed: Deferred revenue menu item (C7) — shares the Invoices capability (cap53)\n    this.capRevenueSchedules.name = \"cap53\";\n    this.capRevenueSchedules.display = \"Revenue Schedules\";\n    this.capRevenueSchedules.link = \"home/accounting/revenue-schedules\";\n    this.capRevenueSchedules.icon = \"schedule_send\";\n\n    // Changed: Quotations menu item (C10) — shares the Invoices capability (cap53)\n    this.capQuotes.name = \"cap53\";\n    this.capQuotes.display = \"Quotations\";\n    this.capQuotes.link = \"home/accounting/quotes\";\n    this.capQuotes.icon = \"request_quote\";\n\n    this.capAccountingOutstandingInvoices.name = \"cap54\";\n    this.capAccountingOutstandingInvoices.display = \"Statement\"; // Changed: Renamed from \"Outstanding Invoices\" to \"Statement\"\n    this.capAccountingOutstandingInvoices.link = \"home/accounting/statements\"; // Changed: Updated route path\n    this.capAccountingOutstandingInvoices.icon = \"account_balance_wallet\";\n\n    this.capAging.name = \"cap58\";\n    this.capAging.display = \"Aging Report\";\n    this.capAging.link = \"home/accounting/aging\";\n    this.capAging.icon = \"schedule\";\n\n    this.capLoans.name = \"cap30\";\n    this.capLoans.display = \"Loans\";\n    this.capLoans.moduleKey = \"loans\"; // Added (Setup v3)\n    this.capLoans.icon = \"payments\";\n    this.capLoans.capSubItems = [this.capLoanProducts, this.capLoansMain, this.capLoanPayments];\n\n    this.capLoanProducts.name = \"cap31\";\n    this.capLoanProducts.display = \"Loan Products\";\n    this.capLoanProducts.link = \"home/loans/products\";\n    this.capLoanProducts.icon = \"inventory\";\n\n    this.capLoansMain.name = \"cap32\";\n    this.capLoansMain.display = \"Loans\";\n    this.capLoansMain.link = \"home/loans/loans\";\n    this.capLoansMain.icon = \"account_balance\";\n\n    this.capLoanPayments.name = \"cap33\";\n    this.capLoanPayments.display = \"Payments\";\n    this.capLoanPayments.link = \"home/loans/payments\";\n    this.capLoanPayments.icon = \"payment\";\n\n    // Changed: Sales module — separate menu group for sales\n    this.capSalesModule.name = \"cap61\";\n    this.capSalesModule.display = \"Sales\";\n    this.capSalesModule.moduleKey = \"sales\"; // Added (Setup v3)\n    this.capSalesModule.icon = \"point_of_sale\";\n    this.capSalesModule.capSubItems = [this.capSalesDashboard, this.capSales, this.capSalesOrders]; // Changed: Added Dashboard to Sales submenu\n\n    this.capSalesDashboard.name = \"cap61\"; // Changed: Reuses module cap number for dashboard visibility\n    this.capSalesDashboard.display = \"Dashboard\";\n    this.capSalesDashboard.link = \"home/sales/dashboard\";\n    this.capSalesDashboard.icon = \"dashboard\";\n\n    // Changed: Purchasing module — separate menu group for purchasing\n    this.capPurchasingModule.name = \"cap62\";\n    this.capPurchasingModule.display = \"Purchasing\";\n    this.capPurchasingModule.moduleKey = \"purchasing\"; // Added (Setup v3)\n    this.capPurchasingModule.icon = \"shopping_cart\";\n    this.capPurchasingModule.capSubItems = [this.capPurchasingDashboard, this.capInventoryReceipts, this.capSupplierPurchaseOrders, this.capSupplierAging]; // Changed: Added Dashboard to Purchasing submenu\n\n    this.capPurchasingDashboard.name = \"cap62\"; // Changed: Reuses module cap number for dashboard visibility\n    this.capPurchasingDashboard.display = \"Dashboard\";\n    this.capPurchasingDashboard.link = \"home/purchasing/dashboard\";\n    this.capPurchasingDashboard.icon = \"dashboard\";\n\n    this.capInventory.name = \"cap34\";\n    this.capInventory.display = \"Inventory\";\n    this.capInventory.moduleKey = \"inventory\"; // Added (Setup v3)\n    this.capInventory.icon = \"inventory\";\n    this.capInventory.capSubItems = [this.capInventoryDashboard, this.capProducts, this.capServiceItems, // Changed: Dashboard moved to first position in sub-items\n      this.capBundleProducts, this.capInventoryStock, this.capInventoryTransactions, this.capInventoryItems,\n      this.capRequisitions, this.capInventoryAdjustments,\n      this.capInventoryReturns,\n    ];\n\n    // Changed: Manufacturing module — separate menu group for production\n    this.capManufacturing.name = \"cap60\";\n    this.capManufacturing.display = \"Manufacturing\";\n    this.capManufacturing.moduleKey = \"manufacturing\"; // Added (Setup v3)\n    this.capManufacturing.icon = \"factory\";\n    this.capManufacturing.capSubItems = [this.capProductionRecipes, this.capProductionOrders];\n\n    this.capInventoryDashboard.name = \"cap35\";\n    this.capInventoryDashboard.display = \"Dashboard\";\n    this.capInventoryDashboard.link = \"home/inventory/dashboard\";\n    this.capInventoryDashboard.icon = \"dashboard\";\n\n    this.capInventoryStock.name = \"cap51\"; // Changed: Added inventory stock cap item configuration\n    this.capInventoryStock.display = \"Inventory Stock\";\n    this.capInventoryStock.link = \"home/inventory/stock\";\n    this.capInventoryStock.icon = \"widgets\";\n\n    this.capProducts.name = \"cap36\";\n    this.capProducts.display = \"Products\";\n    this.capProducts.link = \"home/inventory/products\";\n    this.capProducts.icon = \"category\";\n\n    this.capServiceItems.name = \"cap59\"; // Added: Service items capability\n    this.capServiceItems.display = \"Services\";\n    this.capServiceItems.link = \"home/inventory/service-items\";\n    this.capServiceItems.icon = \"build\";\n\n    // ARBITER-RULED 2026-08-19 (bundle-products-menu-authority, supersedes the menucap-1 M3 PENDING-OWNER note): cap45 is a REAL costing authority and STAYS on this entry. The ruling wanted the menu gated on cap45 AND cap36, but a CapItem carries ONE cap as a plain string (Classes.ts:772) matched by equality everywhere (no-access.component.ts:66, roles.component.ts:240) — there is no conjunction and none was invented. Renaming this to cap36 was rejected: this line is cap45's ONLY declaration and the Roles screen renders solely from appConfig.capItems, so it would orphan the owner's 2026-08-18 grant (DefaultSetupProvider.cs:385, storekeeper cap45 View) and change no user's access, since every cap45 holder already has cap36 Full (DefaultSetupProvider.cs:372). The page/server gate stays cap36 (ProductsController, products/bundles/x). The real defect is that \"View not Full\" cannot bind while cap36 governs the requests — proper fix is cap45 as a SERVER gate on the bundle routes, queued to the Arbiter\n    this.capBundleProducts.name = \"cap45\"; // Changed: Moved from cap57 to cap45 — resolve duplicate with capAggregates\n    this.capBundleProducts.display = \"Bundle Products\";\n    this.capBundleProducts.link = \"home/inventory/bundle-products\";\n    this.capBundleProducts.icon = \"inventory_2\";\n\n    this.capInventoryItems.name = \"cap37\";\n    this.capInventoryItems.display = \"Inventory Items\";\n    this.capInventoryItems.link = \"home/inventory/items\";\n    this.capInventoryItems.icon = \"inventory_2\";\n\n    this.capSupplierPurchaseOrders.name = \"cap47\";\n    this.capSupplierPurchaseOrders.display = \"Purchase Orders\";\n    this.capSupplierPurchaseOrders.link = \"home/purchasing/orders\";\n    this.capSupplierPurchaseOrders.icon = \"shopping_bag\";\n\n    this.capInventoryReceipts.name = \"cap38\";\n    this.capInventoryReceipts.display = \"Purchases\"; // Changed: \"Receipts\" → \"Purchases\"\n    this.capInventoryReceipts.link = \"home/purchasing/purchases\"; // Changed: inventory-receipts → purchases\n    this.capInventoryReceipts.icon = \"receipt_long\";\n\n    this.capSupplierAging.name = \"cap63\"; // Changed: AP Aging capability\n    this.capSupplierAging.display = \"AP Aging\";\n    this.capSupplierAging.link = \"home/accounting/supplier-aging\";\n    this.capSupplierAging.icon = \"schedule\";\n\n    this.capSalesOrders.name = \"cap39\";\n    this.capSalesOrders.display = \"Sales Orders\";\n    this.capSalesOrders.link = \"home/sales/orders\";\n    this.capSalesOrders.icon = \"shopping_cart\";\n\n\n    this.capSales.name = \"cap50\";\n    this.capSales.display = \"Sales\";\n    this.capSales.link = \"home/sales/sales\";\n    this.capSales.icon = \"point_of_sale\";\n\n    this.capRequisitions.name = \"cap40\";\n    this.capRequisitions.display = \"Requisitions\";\n    this.capRequisitions.link = \"home/inventory/requisitions\";\n    this.capRequisitions.icon = \"request_quote\";\n\n    this.capInventoryAdjustments.name = \"cap41\";\n    this.capInventoryAdjustments.display = \"Adjustments\";\n    this.capInventoryAdjustments.link = \"home/inventory/adjustments\";\n    this.capInventoryAdjustments.icon = \"tune\";\n\n    this.capInventoryReturns.name = \"cap42\";\n    this.capInventoryReturns.display = \"Returns\";\n    this.capInventoryReturns.link = \"home/inventory/returns\";\n    this.capInventoryReturns.icon = \"keyboard_return\";\n\n    this.capInventoryTransactions.name = \"cap44\";\n    this.capInventoryTransactions.display = \"Transactions\";\n    this.capInventoryTransactions.link = \"home/inventory/transactions\";\n    this.capInventoryTransactions.icon = \"swap_horiz\";\n\n    this.capProductionRecipes.name = \"cap55\"; // Added: Production recipes capability\n    this.capProductionRecipes.display = \"Production Recipes\";\n    this.capProductionRecipes.link = \"home/manufacturing/production-recipes\";\n    this.capProductionRecipes.icon = \"description\";\n\n    this.capProductionOrders.name = \"cap56\"; // Added: Production orders capability\n    this.capProductionOrders.display = \"Production Orders\";\n    this.capProductionOrders.link = \"home/manufacturing/production-orders\";\n    this.capProductionOrders.icon = \"factory\";\n\n    // Default cache rule for list endpoints\n    this.cacheConfig.addRule('*/list/*', 5);\n\n    this.authService.myRoleObserv.subscribe((role: any) => {\n      this.myRole = role;\n    });\n  }\n\n\n  appConfig = new AppConfig();\n  private appConfigSource = new BehaviorSubject(this.appConfig);\n  public appConfigObserv = this.appConfigSource.asObservable();\n  UpdateAppConfig(config: AppConfig) {\n    this.appConfigSource.next(config);\n    this.appConfig = config;\n  }\n\n  // Added: the single place every dialog asks \"am I modern?\". Read at dialog-open time rather than cached at\n  // startup, because apps set appConfig in their own service constructor and an app could switch it at runtime.\n  // Anything other than 'modern' — including the property being absent on an older app's config — is the\n  // previous look, so opting in is a deliberate act and never an accident.\n  get modernDialogs(): boolean {\n    return this.appConfig?.dialogStyle === 'modern';\n  }\n\n  // Added: the single place the library asks \"may I name my own destructive prompts?\". Read at prompt time\n  // rather than cached, for the same reason as modernDialogs — an app assigns appConfig in its own service\n  // constructor. Absent means false, so naming is a deliberate act and never an accident: an untracked consumer\n  // that has never heard of this flag keeps getting \"Yes\" / \"No\" on every built-in delete confirmation.\n  get namedDestructiveActions(): boolean {\n    return this.appConfig?.namedDestructiveActions === true;\n  }\n\n  // Added: panel class for the overlay pane. Dialogs apply this so surface-level styling (radius, shadow,\n  // header band) can live in tin-styles.css, which every consumer app already loads globally — component CSS\n  // cannot reach the Material surface because it is an ancestor of the component's own view.\n  get dialogPanelClass(): string[] {\n    return this.modernDialogs ? ['tin-dialog-modern'] : [];\n  }\n\n  // Centralized cache configuration\n  cacheConfig = new CacheConfig();\n\n  //---------- App Configuration base sections ----------\n  // Added: the library half of the App Configuration page. These are singletons an app composes into its own\n  // appConfigurationConfig.sections — the same idiom as capItems menu composition — so the financial calendar\n  // (which used to be the whole Preferences page) is defined once and every app renders it identically.\n  // An app that registers no config at all falls back to configBaseSections, so it still gets this page.\n  configMonthOptions: any[] = [\n    { name: \"January\", value: 1 }, { name: \"February\", value: 2 }, { name: \"March\", value: 3 }, { name: \"April\", value: 4 },\n    { name: \"May\", value: 5 }, { name: \"June\", value: 6 }, { name: \"July\", value: 7 }, { name: \"August\", value: 8 },\n    { name: \"September\", value: 9 }, { name: \"October\", value: 10 }, { name: \"November\", value: 11 }, { name: \"December\", value: 12 }\n  ];\n  configDayOptions: any[] = Array.from({ length: 28 }, (_, i) => ({ name: `${i + 1}`, value: i + 1 })); // 28 — a period start beyond that does not exist in every month\n\n  configSectionFinancial: AppConfigSection = {\n    key: 'financial', title: 'Financial', icon: 'account_balance', hint: 'The currency and accounting calendar every report, period and statement is built on',\n    fields: [\n      { name: 'baseCurrencyID', alias: 'Base Currency', type: 'select', loadAction: { url: 'currencies/list' }, hint: 'Reporting currency — everything else converts to this' },\n      { name: 'firstMonthOfYear', alias: 'First Month of Year', type: 'select', options: this.configMonthOptions, hint: 'The month your financial year starts in' },\n      { name: 'firstDayOfMonth', alias: 'First Day of Month', type: 'select', options: this.configDayOptions, hint: 'The day accounting periods start on' },\n      { name: 'booksOpenFrom', alias: 'Books Open From', type: 'date', defaultValue: 'yearStart', hint: 'Anything before this date is a closed period' } // Changed: added defaultValue 'yearStart' so the form states the 1 January the server already falls back to, instead of rendering blank\n    ]\n  };\n\n  configBaseSections: AppConfigSection[] = [this.configSectionFinancial];\n\n  //---------- Library defaults: Getting Started step actions (Phase 5) ----------\n  // Added: the module-derived half of every app's Getting Started, authored ONCE. The server has always emitted\n  // these thirteen steps from DefaultSetupProvider.LibrarySteps(); until now every app restated the ACTIONS for\n  // them, which is why one app offered a create dialog on 'invoices' and another offered only a link. Precedent\n  // and idiom: configBaseSections above — a library singleton an app composes into its own config.\n  //\n  // 🔑 WHY THIS NEEDS NO APP DI, AND IT IS THE FACT THE WHOLE PHASE RESTS ON: every config spread below belongs\n  // to a tin-spa service (AccountingService, InventoryService, SalesService, PurchasingService, ProductionService,\n  // PayrollService, LoansService) or to this service itself. pulse-spa's own comment states the principle —\n  // \"every Pulse page is a library page, so its setup steps reuse the library's own create buttons and dialogs\".\n  // A library step points at a library page by construction; app-DOMAIN steps (vehicles, pigs, equipment) are not\n  // here and stay app-owned.\n  //\n  // 🔴 THE MERGE ORDER IS `{ ...libraryStepActions, ...appStepActions }` — THE APP WINS, PER KEY.\n  // That order is the contract and it is pinned by spec (datalib-library-defaults.spec.ts). It is what makes this\n  // a DEFAULT rather than a seizure: an app that needs different wording, an extra `import`, `seed: true`, or a\n  // different dialog restates that ONE key after the spread and keeps everything else. Spreading the app map\n  // first would make the library silently overwrite deliberate app choices, which is the opposite of the\n  // directive. Per the FSD's Best Practices, an app that overrides a key must say in a comment WHY the library's\n  // is wrong for it — that is a finding about the library, not a licence to fork.\n  //\n  // ⚠️ NO `import` HERE, DELIBERATELY. ImportConfig.entity is a per-API ImportRegistry key; an unregistered key\n  // opens a wizard that then fails. Registries are audited in Phase 7; until then imports stay app-declared.\n  // ⚠️ NO `seed: true` HERE either — Open Question 3 (does every app want \"Add examples\" on customers /\n  // suppliers / products?) is with the owner and it touches TENANT DATA. Shipping the default without seed keys\n  // is the route-and-proceed choice: an app that already offers them (test-spa) keeps them through the merge\n  // order above, and answering Q3 \"yes\" later is a one-line addition here that reaches all five apps at once.\n  // Answering it \"no\" costs nothing, because nothing was shipped.\n  // ⚠️ 'choose-modules' (the module picker card), 'users' (an invite flow, not an entity) and 'roles' (a template\n  // picker whose offer set is app-shaped) are NOT here. The first two carry no entity dialog in any app, and\n  // 'roles' is a core step, not a module-derived one.\n  //\n  // Q2 (does the library's wording win?) raises NO conflict at this layer and that is worth stating plainly:\n  // the wording below is the library's own, on library-authored defaults, and any app that wants different\n  // wording keeps it by overriding the key — the merge order settles it without needing Q2 answered.\n  get libraryStepActions(): { [key: string]: SetupStepAction } {\n    if (this.libraryStepActionsCache) return this.libraryStepActionsCache;\n    const accounting = this.injector.get(AccountingService);\n    const inventory = this.injector.get(InventoryService);\n    const sales = this.injector.get(SalesService);\n    const purchasing = this.injector.get(PurchasingService);\n    const production = this.injector.get(ProductionService);\n    const payroll = this.injector.get(PayrollService);\n    const loans = this.injector.get(LoansService);\n    return this.libraryStepActionsCache = {\n      'accounts': { button: { ...accounting.accountCreateButton, display: 'Add Account', detailsConfig: accounting.accountDetailsConfig }, link: 'home/accounting/accounts', view: { ...accounting.accountsTableConfig, tabTitle: 'Accounts' } },\n      'base-currency': { link: 'home/app-configuration' }, // a SETTING, not an entity — no dialog exists to open and none should be invented\n      'customers': { button: { ...this.customerCreateButton, detailsConfig: this.customerDetailsConfig }, link: 'home/general/customers', view: { ...this.customersTableConfig, tabTitle: 'Customers' } },\n      'suppliers': { button: { ...this.supplierCreateButton, detailsConfig: this.supplierDetailsConfig }, link: 'home/general/suppliers', view: { ...this.suppliersTableConfig, tabTitle: 'Suppliers' } },\n      'products': { button: { ...inventory.productCreateButton, display: 'Add Product', detailsConfig: inventory.productDetailsConfig }, link: 'home/inventory/products', view: { ...inventory.productsTableConfig, tabTitle: 'Products' } },\n      'employees': { button: { name: 'create', display: 'Add Employee', dialog: true, detailsConfig: { formConfig: this.employeeFormConfig, mode: 'create', buttons: this.employeesTableConfig.buttons.filter(x => x.name == 'create') } }, link: 'home/hr/employees', view: { ...this.employeesTableConfig, tabTitle: 'Employees' } },\n      'departments': { button: { name: 'create', display: 'Add Department', dialog: true, detailsConfig: { formConfig: this.departmentFormConfig, mode: 'create', buttons: this.departmentTableConfig.buttons.filter(x => x.name == 'create') } }, link: 'home/hr/departments', view: { ...this.departmentTableConfig, tabTitle: 'Departments' } },\n      'salary-structures': { button: { name: 'create', display: 'Add Structure', dialog: true, detailsConfig: { formConfig: payroll.salaryStructureFormConfig, mode: 'create', buttons: payroll.salaryStructuresTableConfig.buttons.filter(x => x.name == 'create') } }, link: 'home/payroll/salary-structures', view: { ...payroll.salaryStructuresTableConfig, tabTitle: 'Salary Structures' } },\n      'sales': { button: { ...sales.saleCreateButton, detailsConfig: { formConfig: sales.saleFormConfig, mode: 'create', buttons: [sales.saleCreateButton] } }, link: 'home/sales/sales', view: { ...sales.salesTableConfig, tabTitle: 'Sales' } }, // salesTableConfig is the page LIST; saleDetailsConfig is a single record\n      'purchases': { button: { ...purchasing.quickPurchaseButton, detailsConfig: { formConfig: purchasing.purchaseFormConfig, mode: 'create', buttons: [purchasing.quickPurchaseButton] } }, link: 'home/purchasing/purchases', view: { ...purchasing.purchasesTableConfig, tabTitle: 'Purchases' } },\n      'recipes': { button: { ...production.recipeCreateButton, detailsConfig: { ...production.recipeDetailsConfig, mode: 'create', buttons: [production.recipeCreateButton] } }, link: 'home/manufacturing/recipes', view: { ...production.recipesTableConfig, tabTitle: 'Recipes' } }, // two-step — onSuccessButton opens the recipe items tab\n      'invoices': { button: { name: 'create', display: 'Create Invoice', dialog: true, onSuccessButton: accounting.invoiceViewButton, detailsConfig: { formConfig: accounting.invoiceFormConfig, mode: 'create', buttons: accounting.invoicesTableConfig.buttons.filter(x => x.name == 'create') } }, link: 'home/accounting/invoices', view: { ...accounting.invoicesTableConfig, tabTitle: 'Invoices' } }, // two-step — onSuccessButton opens the invoice for its lines\n      'loan-products': { button: { ...loans.loanProductCreateButton, detailsConfig: { formConfig: loans.loanProductFormConfig, mode: 'create', buttons: [loans.loanProductCreateButton] } }, link: 'home/loans/loan-products', view: { ...loans.loanProductTableConfig, tabTitle: 'Loan Products' } }\n    };\n  }\n  private libraryStepActionsCache: { [key: string]: SetupStepAction } | null = null; // built once — every config it spreads is a singleton on a root service, so rebuilding per read would only churn objects\n\n  //---------- Library defaults: Day Book lanes and sections (Phase 6) ----------\n  // Added: somewhere for DefaultDayBookProvider's own rules to RENDER. The server has emitted eight module-gated\n  // rules across a money, work and stock lane for some time; a Day Book page is config-driven, so a rule with no\n  // section is payload and no page. That is the honest half of Piglet's refusal, and this closes it.\n  //\n  // Same merge order as libraryStepActions, and the same reason:\n  //   sections: [...this.data.libraryDayBookSections, ...this.appSections]\n  // — but sections are an ARRAY, so \"the app wins\" is not automatic the way a spread over a map is. Use\n  // libraryDayBookSection(key, overrides) to restate ONE library section without losing the rest, or simply\n  // filter the array. Both are pinned by spec.\n  //\n  // 🔴 NO NEW `TableConfig` IS AUTHORED FOR THE FIVE INJECTABLE SECTIONS. The three invoice cards and the two\n  // stock cards POINT AT the pages' own configs (AccountingService.invoicesTableConfig,\n  // InventoryService.productsTableConfig) and select a column snippet by name — the definitions, dialogs,\n  // capabilities and conditions stay on the page and arrive here by reference. That is the whole point of the\n  // config-injection seam and re-declaring them would recreate the duplication that initiative removed.\n  //\n  // ⚠️ The three that DO carry a small TableConfig — receipts, approvals, tasks — are not an exception to that\n  // rule, they are the documented REFUSALS of it, and moving them here is the de-duplication rather than a\n  // breach of it. All four adopting apps recorded the same three refusals independently:\n  //   • unallocatedReceipts vs customerReceiptsTableConfig — `reference` exists on both sides and MEANS\n  //     DIFFERENT THINGS (the receipt NUMBER on the book row, a separate Reference field on the page), so\n  //     injection would render the right value under the wrong heading; and the page's `allocate` button gates\n  //     on unallocatedAmount, which the row does not project.\n  //   • pendingApprovals vs receivedApprovalsTableConfig — exactly ONE of its eight columns (`message`) exists\n  //     on DayBookApprovalRow.\n  //   • tasksDue — there is NOTHING to point at: the tasks table config is declared inside\n  //     tin-spa/src/lib/pages/tasks/tasks.component.ts, not on an injectable service, so no consumer can reach\n  //     it, and the names disagree anyway. 🔵 Library backlog: a page config that lives in a component cannot be\n  //     single-sourced by anything.\n  // Three small configs written once here replace the same three written five times.\n  get libraryDayBookLanes(): DayBookLane[] {\n    return [\n      { key: 'money', label: 'Money', icon: 'payments' },\n      { key: 'work', label: 'Work', icon: 'checklist' },\n      { key: 'stores', label: 'Stores', icon: 'inventory', visible: (b: any) => b?.outOfStock !== undefined } // gated on KEY PRESENCE, not on a flag: DayBookController writes book[rule.Key] only after BOTH IsModuleOn and HasAnyCapability pass, so an absent key covers the module being off AND the user lacking cap36\n    ];\n  }\n\n  get libraryDayBookSections(): DayBookSection[] {\n    if (this.libraryDayBookSectionsCache) return this.libraryDayBookSectionsCache;\n    const accounting = this.injector.get(AccountingService);\n    const inventory = this.injector.get(InventoryService);\n    const invoiceExtras: Column[] = [{ name: 'dueDate', type: 'date-short', alias: 'Due' }, { name: 'total', type: 'money' }];\n    return this.libraryDayBookSectionsCache = [\n      // `buttons: []` is LOAD-BEARING on all three — omit it and the card inherits every row button of the\n      // invoices page (create/edit/delete/pdf/submit/record-payment); these are read-and-open cards.\n      // `invoiceNumber` is the win: the page declares it type:'button' onto invoiceDetailsDialogConfig, whose\n      // heroField is invoiceID, which DayBookMoneyRow carries — so the card can open the invoice it lists.\n      { key: 'draftInvoices', lane: 'money', listField: 'draftInvoices', tableConfig: accounting.invoicesTableConfig,\n        columns: this.libraryDayBookInvoiceView, extraColumns: invoiceExtras,\n        buttons: [],\n        overrides: { ...this.libraryDayBookChrome, minColumns: ['invoiceNumber', 'customerName', 'total'], sectionConfig: { title: 'Drafts to issue', icon: 'edit_note', chips: [{ text: 'not yet sent', color: '#607d8b' }] } }\n      },\n      { key: 'overdueInvoices', lane: 'money', listField: 'overdueInvoices', tableConfig: accounting.invoicesTableConfig,\n        columns: this.libraryDayBookInvoiceView, extraColumns: [...invoiceExtras, { name: 'daysOverdue', alias: 'Days Late' }], // daysOverdue LAST, after total — where every app already draws it\n        buttons: [],\n        overrides: { ...this.libraryDayBookChrome, minColumns: ['invoiceNumber', 'customerName', 'total'], sectionConfig: { title: 'Overdue — chase these', icon: 'warning_amber', chips: [{ text: 'past due', color: '#c62828' }] } }\n      },\n      { key: 'awaitingPayment', lane: 'money', listField: 'awaitingPayment', collapsed: true, tableConfig: accounting.invoicesTableConfig,\n        columns: this.libraryDayBookInvoiceView, extraColumns: invoiceExtras,\n        buttons: [],\n        overrides: { ...this.libraryDayBookChrome, minColumns: ['invoiceNumber', 'customerName', 'total'], sectionConfig: { title: 'Awaiting payment', icon: 'schedule' } }\n      },\n      { key: 'unallocatedReceipts', lane: 'money', listField: 'unallocatedReceipts', tableConfig: this.libraryDayBookReceiptsConfig },\n      { key: 'pendingApprovals', lane: 'work', listField: 'pendingApprovals', tableConfig: this.libraryDayBookApprovalsConfig },\n      { key: 'tasksDue', lane: 'work', listField: 'tasksDue', tableConfig: this.libraryDayBookTasksConfig },\n      // TWO stock cards, not one: a section binds ONE listField and the book carries outOfStock and lowStock as\n      // separate keys with different orderings. `available` is 0 on every out-of-stock row by definition, so a\n      // column of zeros is not drawn there; on low stock the three numbers ARE the point.\n      { key: 'outOfStock', lane: 'stores', listField: 'outOfStock', tableConfig: inventory.productsTableConfig,\n        columns: ['name', { column: 'sku', alias: 'SKU' }, 'categoryName'],\n        extraColumns: [{ name: 'minimumLevel', alias: 'Minimum' }], // book-only — the page's own column is minimumInventoryLevel and would read blank here\n        buttons: [{ button: 'view', display: 'Open the product', icon: { name: 'launch' }, tip: 'Opens this product without leaving the Day Book' }], // Changed (sweep-1, owner directive 2026-08-20): was inventory_2 + blue. A row VIEW is `launch` estate-wide (shift-spa, grip-spa, piglet's dayBookViewPig) and inventory_2 is ALSO this lane's own section glyph, so the action and the card it sat on wore the same icon for two different meanings. The blue is dropped with it — an action icon is not recoloured away from its siblings. test-spa was swept on 08-20; this is the library's own copy of the same demo config, missed then\n        overrides: { ...this.libraryDayBookChrome, minColumns: ['name', 'categoryName', 'minimumLevel'], sectionConfig: { title: 'Out of Stock', icon: 'remove_shopping_cart', chips: [{ text: 'nothing left to sell', color: '#c62828' }] } }\n      },\n      { key: 'lowStock', lane: 'stores', listField: 'lowStock', tableConfig: inventory.productsTableConfig,\n        columns: ['name', { column: 'sku', alias: 'SKU' }, 'categoryName'],\n        extraColumns: [{ name: 'available', alias: 'In Stock' }, { name: 'minimumLevel', alias: 'Minimum' }, { name: 'shortfall', alias: 'Short By' }],\n        buttons: [{ button: 'view', display: 'Open the product', icon: { name: 'launch' }, tip: 'Opens this product without leaving the Day Book' }], // Changed (sweep-1, owner directive 2026-08-20): was inventory_2 + blue. A row VIEW is `launch` estate-wide (shift-spa, grip-spa, piglet's dayBookViewPig) and inventory_2 is ALSO this lane's own section glyph, so the action and the card it sat on wore the same icon for two different meanings. The blue is dropped with it — an action icon is not recoloured away from its siblings. test-spa was swept on 08-20; this is the library's own copy of the same demo config, missed then\n        overrides: { ...this.libraryDayBookChrome, minColumns: ['name', 'available', 'shortfall'], sectionConfig: { title: 'Low Stock', icon: 'inventory_2', chips: [{ text: 'below the minimum you chose to hold', color: '#ef6c00' }] } }\n      }\n    ];\n  }\n  private libraryDayBookSectionsCache: DayBookSection[] | null = null;\n\n  // Added: the ONE library section an app wants on its own terms, without re-authoring it. Returns a SHALLOW COPY\n  // merged with the app's delta, so the app wins per property on exactly the same principle as the step-action\n  // merge order — a book whose lanes are named differently (test-spa's billing/collections) can re-lane a library\n  // section instead of restating it. Returns undefined for an unknown key rather than an empty card.\n  libraryDayBookSection(key: string, overrides?: Partial<DayBookSection>): DayBookSection | undefined {\n    const found = this.libraryDayBookSections.find(s => s.key == key);\n    return found ? { ...found, ...overrides } : undefined;\n  }\n\n  // The invoices PAGE filters; a Day Book section does not. Both identity columns are selected out of the page in\n  // the page's own order (invoiceNumber then customerName), which is the order every app's card already used, so\n  // nothing has to be re-declared to preserve it. An app whose Customer is a drill-in CHIP (pulse, grip, piglet)\n  // overrides `columns` to take invoiceNumber alone and re-declares the chip as its first extra — extras APPEND,\n  // so that is what keeps Customer in second place. Taking the page's plain text there would silently remove a\n  // working drill-in, which is why it is an app override and not the library default.\n  libraryDayBookInvoiceView: (string | DayBookColumnView)[] = [{ column: 'invoiceNumber', alias: 'Invoice' }, { column: 'customerName', alias: 'Customer' }];\n  libraryDayBookChrome: DayBookTableView = { showFilter: false, showFilterButton: false };\n  // 🔴 GETTERS, not field initializers, and the reason is mechanical: these three sit ABOVE customerDetailsConfig\n  // in this file, and a class field initializer that reads a field declared later captures `undefined` — silently,\n  // with no compile error and no runtime throw, producing a chip that never opens. Everything here is read lazily\n  // out of libraryDayBookSections, which is itself a getter, so by the time any of this runs the whole class is built.\n  get libraryDayBookReceiptsConfig(): TableConfig { return { columns: [{ name: 'reference', alias: 'Receipt' }, { name: 'partyName', type: 'chip' as const, alias: 'Customer', detailsConfig: this.customerDetailsConfig }, { name: 'date', alias: 'Received', type: 'date-short' as const }, { name: 'total', alias: 'Unallocated', type: 'money' as const }], minColumns: ['reference', 'partyName', 'total'], showFilter: false, showFilterButton: false, sectionConfig: { title: 'Receipts to allocate', icon: 'account_balance_wallet', chips: [{ text: 'unmatched cash', color: '#ef6c00' }] } }; }\n  get libraryDayBookApprovalsConfig(): TableConfig { return { columns: [{ name: 'entity', alias: 'Record' }, { name: 'message', alias: 'Request' }, { name: 'currentLevel', alias: 'Level' }, { name: 'raised', alias: 'Raised', type: 'date-short' as const }, { name: 'daysWaiting', alias: 'Days Waiting' }], minColumns: ['entity', 'message', 'daysWaiting'], showFilter: false, showFilterButton: false, sectionConfig: { title: 'Approvals waiting on you', icon: 'fact_check', chips: [{ text: 'blocking someone else', color: '#ef6c00' }] } }; }\n  get libraryDayBookTasksConfig(): TableConfig { return { columns: [{ name: 'title', alias: 'Task' }, { name: 'assignedTo', alias: 'Assigned To' }, { name: 'dueDate', alias: 'Due', type: 'date-short' as const }, { name: 'daysOverdue', alias: 'Days Late' }], minColumns: ['title', 'assignedTo', 'dueDate'], showFilter: false, showFilterButton: false, sectionConfig: { title: 'Tasks due', icon: 'task_alt' } }; }\n\n  myRole;\n\n  capHome = new CapItem;\n  capAdmin = new CapItem;\n  capUsers = new CapItem;\n  capRoles = new CapItem;\n  capLogs = new CapItem;\n  capSettings = new CapItem;\n  capPasswordPolicy = new CapItem; // Added (N8): the per-tenant password policy admin page\n  capTenantReset = new CapItem; // Added: cap92 — the tenant-reset gate, checked by AppConfigurationControllerBase rather than by any one screen\n\n  capMultitenant = new CapItem;\n  capTenants = new CapItem;\n  capMembership = new CapItem;\n  capPlans = new CapItem;\n  capFeatures = new CapItem; // Added: Feature registry capability property\n  capPlanFeatures = new CapItem; // Added: Plan-Feature mapping capability property\n  capSubscription = new CapItem; // Added: Subscription management capability property\n  capBilling = new CapItem; // Added: Billing & invoice history capability property\n\n  capGeneral = new CapItem;\n  capCustomers = new CapItem;\n  capCategories = new CapItem;\n  capSubCategories = new CapItem;\n  capBrands = new CapItem;\n  capGPTCaches = new CapItem; // Added: GPT Cache capability property\n\n  capSuppliers = new CapItem;\n  capTasks = new CapItem;\n\n  capHR = new CapItem;\n  capEmployees = new CapItem;\n  capDepartments = new CapItem;\n  capPositions = new CapItem;\n  capUnlock = new CapItem; // Added: cap87 — the ILock unlock gate, checked by the BASE controller rather than by any one screen\n  capReferenceData = new CapItem; // Added: cap90 — the reference-data read gate, checked by the controllers rather than by any one screen\n  capGrades = new CapItem;\n\n  capPayroll = new CapItem; // Changed: Added Payroll module sidebar items\n  capSalaryStructures = new CapItem;\n  capStatutoryDeductions = new CapItem;\n  capPayrollRuns = new CapItem;\n  capCommissionConfigs = new CapItem; // Changed: Added for Commission module\n  capCommissionEntries = new CapItem; // Changed: Added for Commission module\n  capCommissionStatement = new CapItem; // Added (Phase 6): Driver Commission Statement (cap86)\n  capSalaryAdvances = new CapItem; // Changed: Added for Salary Advance module\n  capOvertimeEntries = new CapItem; // Changed: Added for Overtime module\n\n  capApprovals = new CapItem;\n  capApprovalsConfig = new CapItem;\n  capNotifications = new CapItem;\n  capSelfApproval = new CapItem;\n  capAppModels = new CapItem;\n  capNotificationsConfig = new CapItem;\n\n  capAccountingOutstandingInvoices = new CapItem;\n  capAccounting = new CapItem;\n  capAccounts = new CapItem;\n  capAggregates = new CapItem; // Added: Capability for aggregates view\n  capReports = new CapItem; // Added: Capability for financial reports\n  capBudgets = new CapItem; // Added: Capability for budgets management (cap85)\n  capBudgetVsActual = new CapItem; // Added: Budget vs Actual report menu item (shares cap85 with budgets)\n  capAging = new CapItem; // Added: Capability for aging report\n  capTaxRates = new CapItem; // Changed: Capability for tax rates management\n  capStandingOrders = new CapItem; // Changed: Capability for standing orders management\n  capTenantTransfers = new CapItem; // Added (N11): Organisation Transfers — cross-organisation money, accounting menu\n  capFixedAssetsModule = new CapItem; // Changed: Top-level Fixed Assets module\n  capFixedAssetsDashboard = new CapItem; // Changed: Fixed Assets dashboard\n  capFixedAssets = new CapItem; // Changed: Asset Register (renamed from Fixed Assets)\n  capFixedAssetCategories = new CapItem; // Changed: Depreciation Categories\n  capCurrencies = new CapItem; // Changed: Capability for currencies management\n  capTransactionTypes = new CapItem;\n  capTransactions = new CapItem;\n  capAccountingInvoices = new CapItem;\n  capCreditNotes = new CapItem; // Changed: Credit notes page (B6, shares cap53 with invoices)\n  capVatReturn = new CapItem; // Changed: VAT return page (B2, shares cap48 with reports)\n  capFiscalPeriods = new CapItem; // Changed: Fiscal periods page (C2, shares cap52 with accounts)\n  capReceipts = new CapItem; // Changed: Customer receipts page (C3, shares cap53 with invoices)\n  capBankReconciliation = new CapItem; // Changed: Bank reconciliation page (C4, shares cap52 with accounts)\n  capRevenueSchedules = new CapItem; // Changed: Deferred revenue page (C7, shares cap53 with invoices)\n  capQuotes = new CapItem; // Changed: Quotations page (C10, shares cap53 with invoices)\n\n  capInvoicing = new CapItem; // Added: Capability for invoicing view\n\n  capLoans = new CapItem;\n  capLoanProducts = new CapItem;\n  capLoansMain = new CapItem;\n  capLoanPayments = new CapItem;\n\n  capInventory = new CapItem;\n  capInventoryDashboard = new CapItem;\n  capInventoryStock = new CapItem; // Changed: Added new cap item for inventory stock view\n  capProducts = new CapItem;\n  capServiceItems = new CapItem; // Added: Capability for service items\n  capBundleProducts = new CapItem; // Added: Capability for bundle products\n  capInventoryItems = new CapItem;\n  capSupplierPurchaseOrders = new CapItem;\n  capInventoryReceipts = new CapItem;\n  capSalesOrders = new CapItem;\n  capSales = new CapItem;\n  capRequisitions = new CapItem;\n  capInventoryAdjustments = new CapItem;\n  capInventoryReturns = new CapItem;\n  capInventoryTransactions = new CapItem;\n  capProductionRecipes = new CapItem; // Added: Capability for production recipes\n  capProductionOrders = new CapItem; // Added: Capability for production orders\n  capManufacturing = new CapItem; // Changed: Manufacturing module menu group\n  capSalesModule = new CapItem; // Changed: Sales module menu group\n  capPurchasingModule = new CapItem; // Changed: Purchasing module menu group\n  capAccountingDashboard = new CapItem; // Changed: Accounting dashboard menu item\n  capSalesDashboard = new CapItem; // Changed: Sales dashboard menu item\n  capPurchasingDashboard = new CapItem; // Changed: Purchasing dashboard menu item\n  capSupplierAging = new CapItem; // Changed: AP Aging capability property\n  capInvoiceDashboard = new CapItem; // Changed: Invoice dashboard menu item\n  capPayrollDashboard = new CapItem; // Changed: Payroll dashboard menu item\n\n  public tmpProfileuserName = \"\";\n\n\n  isProcessing = false;\n\n\n  //--------------------------Departmemts Form-------------------------\n  departmentFormConfig: FormConfig = {\n    security: { allow: [this.capDepartments] },\n    title : 'Department',\n    fields: [\n      { name: 'name', type: 'text', required: true },\n    ],\n    loadAction: { url: 'departments/id' },\n    heroField: 'departmentID',\n    includeAudit: true,\n  }\n\n  editDepartmentButton: Button = { name: 'edit', dialog: true, action: { url: 'departments?action=edit', method: 'post', successMessage: 'Edited Successfully' } }\n\n  // Added (N22): the tenant reset, offered at the foot of App Configuration. Like the unlock buttons the\n  // capability is passed as the OBJECT, not `.name` — datalib assigns \"cap92\" in the constructor, AFTER this\n  // initializer runs, so an eagerly-read name would be \"\" and gate nothing at all.\n  // `requiredAccess: Full` mirrors AppConfigurationControllerBase.cs:155 exactly. The server is the authority and\n  // it demands Full; a button gated any lower would render for people the endpoint then refuses.\n  // `requirePhrase: 'RESET'` mirrors ResetPhrase (AppConfigurationControllerBase.cs:129) and is compared ordinally\n  // and case-sensitively on both sides — see Confirm.requirePhrase on why nothing here may trim or case-fold.\n  // The URL is `configuration/reset`, matching the page's own `configuration/get` default: the endpoint is\n  // [HttpPost(\"reset\")] on the base and every app routes it as [Route(\"api/[controller]\")] ConfigurationController.\n  resetTenantButton: Button = { name: 'reset', display: 'Reset Organisation', tip: 'Delete every operational record in this organisation', icon: { name: 'restart_alt', color: '#c62828' }, capability: this.capTenantReset, requiredAccess: RoleAccess.Full, confirm: { message: 'This deletes every operational record in this organisation — transactions, documents and the day-to-day data built on top of your settings. Your configuration, users and roles are kept.', confirmLabel: 'Reset Organisation', cancelLabel: 'Keep my data', destructive: true, requirePhrase: 'RESET' }, action: { url: 'configuration/reset', method: 'post' } }\n\n  // Added: releases the lock on a locked Department row. `visible` reads the `locked` field the controller\n  // projects (DepartmentsController:41), so the button exists only where it can do something. The capability is\n  // passed as the OBJECT, not `.name` — datalib assigns \"cap87\" in the constructor, after this initializer runs,\n  // so an eagerly-read name would be \"\" and gate nothing. Full mirrors the server's own bar exactly.\n  unlockDepartmentButton: Button = { name: 'unlock', display: 'Unlock', tip: 'Unlock Record', icon: { name: 'lock_open' }, visible: x => x.locked, capability: this.capUnlock, requiredAccess: RoleAccess.Full, confirm: { message: 'Unlock this record? It will become editable and deletable.', confirmLabel: 'Unlock', cancelLabel: 'Keep locked' }, action: { url: 'departments?action=unlock', method: 'post' } }\n\n  departmentDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.departmentFormConfig,\n    heroField: 'departmentID',\n    buttons: [this.editDepartmentButton],\n  }\n\n\n  //--------------------------Positions Form-------------------------\n  positionFormConfig: FormConfig = {\n    security: { allow: [this.capPositions] },\n    title: 'Position',\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'description', type: 'text', },\n      { name: 'departmentID', alias: 'Department', type: 'select', loadAction: { url: 'departments/list/x' }, detailsConfig: this.departmentDetailsConfig },\n\n    ],\n    loadAction: { url: 'positions/id' },\n    heroField: 'positionID',\n    includeAudit: true,\n  }\n\n  editPositionButton: Button = { name: 'edit', dialog: true, action: { url: 'positions?action=edit', method: 'post', successMessage: 'Edited Successfully' } }\n\n  // Added: the Position twin of unlockDepartmentButton — same gate, same shape, its own URL. `locked` is projected at PositionsController:42\n  unlockPositionButton: Button = { name: 'unlock', display: 'Unlock', tip: 'Unlock Record', icon: { name: 'lock_open' }, visible: x => x.locked, capability: this.capUnlock, requiredAccess: RoleAccess.Full, confirm: { message: 'Unlock this record? It will become editable and deletable.', confirmLabel: 'Unlock', cancelLabel: 'Keep locked' }, action: { url: 'positions?action=unlock', method: 'post' } }\n\n  positionDetailsConfig : DetailsDialogConfig = {\n    formConfig : this.positionFormConfig,\n    heroField : 'positionID',\n    buttons: [this.editPositionButton],\n  }\n\n\n\n  //--------------------------Employees-------------------------\n\n  genders = [\n    { name: 'Male', value: 1 },\n    { name: 'Female', value: 2 }\n  ]\n\n  // Changed: sectioned — 17 fields pushed the five child tabs below the fold on view. Who/where/what-status\n  // stays ungrouped at the top; everything read only occasionally folds away once the employee exists.\n  employeeFormConfig: FormConfig = {\n    security : {allow : [this.capEmployees]},\n    fields: [\n      // Changed: required -> requiredCondition so an employee can be saved under a single name (a mononym), matching the API rule \"at least a first name or a last name\". Each name is demanded only while the other is blank, so neither can be left off together and the asterisk drops away as soon as one is typed\n      { name: 'firstName', type: 'text', requiredCondition: x => !x?.lastName?.toString().trim() },\n      { name: 'lastName', type: 'text', requiredCondition: x => !x?.firstName?.toString().trim() },\n      { name: 'departmentID', alias: 'Department', type: 'select', loadAction : { url : 'departments/list/x'}, detailsConfig: this.departmentDetailsConfig },\n      { name: 'positionID', alias: 'Position', type: 'select', loadAction: { url: 'positions/list/x' }, masterField: 'departmentID', detailsConfig: this.positionDetailsConfig },\n      { name: 'employmentStatus', alias: 'Employment Status', type: 'select', loadAction: { url: 'employees/list/employment-status' } },\n      { name: 'activeStatus', alias: 'Active Status', type: 'select', loadAction: { url: 'employees/list/active-status' } },\n\n      { name: 'personal', type: 'section', alias: 'Personal Details', collapseOnView: true },\n      { name: 'nationalID', type: 'text', alias: 'National ID', required: true, section: 'personal' },\n      { name: 'gender', alias: 'Gender', type: 'select', options: this.genders, required: true, section: 'personal' },\n      { name: 'dateOfBirth', type: 'date', max: 'today', alias: 'Date of Birth', required: true, defaultValue: '', section: 'personal' }, // Changed: defaultValue '' suppresses TinCore's type-default that pre-filled this with TODAY; a birth date can never be today, and required:true HID the bug because the auto-filled value already satisfied the required check // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'passportNumber', type: 'text', alias: 'Passport Number', section: 'personal' },\n      { name: 'phone', type: 'text', section: 'personal' },\n      { name: 'email', type: 'text', section: 'personal' },\n      { name: 'address', type: 'text-area', rows: 2, span: true, section: 'personal' },\n\n      { name: 'employment', type: 'section', alias: 'Employment & Payroll', collapseOnView: true },\n      { name: 'employmentDate', type: 'date', alias: 'Employment Date', required: true, section: 'employment' },\n      { name: 'salaryStructureID', alias: 'Salary Structure', type: 'select', loadAction: { url: 'salarystructures/list/x' }, nullable: true, section: 'employment' }, // Changed: Added for payroll salary structure assignment\n      { name: 'userName', type: 'select', alias: 'User', loadAction: { url: 'user/list/x' }, optionDisplay: 'name', optionValue: 'value', nullable : true, infoMessage : 'Related user account', section: 'employment' },\n\n      { name: 'notes', type: 'section', alias: 'Notes', collapseOnView: true },\n      { name: 'note', type: 'text-area', rows: 2, span: true, section: 'notes' },\n    ],\n    loadAction: { url: 'employees/id' },\n    heroField: 'employeeID',\n    includeAudit : true,\n  }\n\n  // Changed: Added edit button for employee details dialog\n  editEmployeeButton: Button = { name: 'edit', dialog: true, inDialog: true, action: { url: 'employees?action=edit', method: 'post' } };\n\n  // Changed (WS-1 Phase 3, the CACHE half): the sweep-2 note below is now ACTED ON. Employee still does not implement ISync, which is exactly why this is `readOnly` and not a queue — nothing here can be captured offline, so nothing should pretend to queue. `readOnly: true` resolves to queue { create:false, edit:false, delete:false } (offline.service.ts resolveConfig) while leaving the read cache and the lookup registration on, which is the whole point: registering this config puts employeeFormConfig's six selects (departments/list/x, positions/list/x, employees/list/employment-status, employees/list/active-status, salarystructures/list/x, user/list/x) into the read seam, so the employee dialog COMPOSES with no network instead of opening six empty dropdowns. Pagination was already here.\n  employeesTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'departmentName', 'positionName'],\n    flatButtons: true,\n    logResponse : false, // TS-21: disabled shipped default response logging\n    columns: [\n      { name: 'name', type: 'text' },\n      { name: 'genderName', type: 'text', alias: 'Gender' },\n      { name: 'departmentName', type: 'text', alias: 'Department' },\n      { name: 'positionName', type: 'text', alias: 'Position' },\n      { name: 'salaryStructureName', type: 'text', alias: 'Salary Structure' }, // Changed: Added for payroll display\n      { name: 'employmentStatusName', type: 'text', alias: 'Employment Status' },\n      { name: 'activeStatusName', type: 'text', alias: 'Active Status' },\n      { name: 'isLinked', type: 'checkbox', alias: 'Linked' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'employees?action=create', method: 'post' } },\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.employeeFormConfig,\n          heroField: 'employeeID',\n          buttons: [this.editEmployeeButton],\n          tableConfigs: [\n            // Changed: Employee salary components child table\n            {\n              tabTitle: 'Salary Components',\n              showFilter: false,\n              elevation: 'none',\n              flatButtons: true,\n              columns: [\n                { name: 'componentName', type: 'text', alias: 'Component' },\n                { name: 'componentType', type: 'text', alias: 'Type' },\n                { name: 'calculationMethod', type: 'text', alias: 'Calculation' },\n                { name: 'value', type: 'money', alias: 'Value' },\n              ],\n              buttons: [\n                { name: 'create', display: 'Create', dialog: true, action: { url: 'employeesalarycomponents?action=create', method: 'post' } },\n                { name: 'edit', dialog: true, action: { url: 'employeesalarycomponents?action=edit', method: 'post' } },\n                { name: 'delete', dialog: true, action: { url: 'employeesalarycomponents?action=delete', method: 'post' } },\n              ],\n              loadAction: { url: 'employeesalarycomponents/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n              formConfig: {\n                title: 'Salary Component',\n                fixedTitle: true,\n                fields: [\n                  { name: 'salaryComponentID', alias: 'Component', type: 'select', loadAction: { url: 'salarycomponents/list/x' }, required: true },\n                  { name: 'value', type: 'money', alias: 'Value', required: true },\n                ],\n                loadAction: { url: 'employeesalarycomponents/id' },\n                heroField: 'employeeSalaryComponentID',\n              },\n            },\n            // Changed: Employee payslip history child table\n            {\n              tabTitle: 'Payslip History',\n              showFilter: false,\n              elevation: 'none',\n              flatButtons: true,\n              columns: [\n                { name: 'grossPay', type: 'money', alias: 'Gross Pay' },\n                { name: 'totalDeductions', type: 'money', alias: 'Deductions' },\n                { name: 'netPay', type: 'money', alias: 'Net Pay' },\n                { name: 'statusName', type: 'text', alias: 'Status' },\n              ],\n              buttons: [\n                { name: 'view', dialog: true },\n              ],\n              loadAction: { url: 'payslips/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n            },\n            // Changed: Employee commission configs child table\n            {\n              tabTitle: 'Commission Configs',\n              showFilter: false,\n              elevation: 'none',\n              flatButtons: true,\n              columns: [\n                { name: 'name', type: 'text' },\n                { name: 'metricTypeName', type: 'text', alias: 'Metric Type' },\n                { name: 'rateTypeName', type: 'text', alias: 'Rate Type' },\n                { name: 'rate', type: 'text', alias: 'Rate' },\n                { name: 'isActive', type: 'checkbox', alias: 'Active' },\n              ],\n              buttons: [\n                { name: 'create', display: 'Create', dialog: true, action: { url: 'commissionconfigs?action=create', method: 'post' } },\n                { name: 'edit', dialog: true, action: { url: 'commissionconfigs?action=edit', method: 'post' } },\n                { name: 'delete', dialog: true, action: { url: 'commissionconfigs?action=delete', method: 'post' } },\n              ],\n              loadAction: { url: 'commissionconfigs/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n              formConfig: {\n                title: 'Commission Config',\n                fixedTitle: true,\n                fields: [\n                  { name: 'name', type: 'text', required: true },\n                  { name: 'metricType', alias: 'Metric Type', type: 'select', loadAction: { url: 'commissionconfigs/list/metric-type' }, required: true },\n                  { name: 'rateType', alias: 'Rate Type', type: 'select', loadAction: { url: 'commissionconfigs/list/rate-type' }, required: true },\n                  { name: 'rate', type: 'number', required: true },\n                  { name: 'isActive', alias: 'Active', type: 'checkbox' },\n                ],\n                loadAction: { url: 'commissionconfigs/id' },\n                heroField: 'commissionConfigID',\n              },\n            },\n            // Changed: Employee salary advances child table\n            {\n              tabTitle: 'Salary Advances',\n              showFilter: false,\n              elevation: 'none',\n              flatButtons: true,\n              columns: [\n                { name: 'amount', type: 'money', alias: 'Amount' },\n                { name: 'advanceDate', type: 'date', alias: 'Date' },\n                { name: 'reason', type: 'text' },\n                { name: 'statusDisplay', type: 'text', alias: 'Status' },\n              ],\n              buttons: [\n                { name: 'create', display: 'Create', dialog: true, action: { url: 'salaryadvances?action=create', method: 'post' } },\n                { name: 'edit', dialog: true, action: { url: 'salaryadvances?action=edit', method: 'post' }, visible: (row: any) => !row?.isDeducted },\n                { name: 'delete', dialog: true, action: { url: 'salaryadvances?action=delete', method: 'post' }, visible: (row: any) => !row?.isDeducted },\n              ],\n              loadAction: { url: 'salaryadvances/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n              formConfig: {\n                title: 'Salary Advance',\n                fixedTitle: true,\n                fields: [\n                  { name: 'amount', type: 'money', required: true },\n                  { name: 'advanceDate', alias: 'Advance Date', type: 'date', max: 'today', required: true }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n                  { name: 'reason', type: 'text' },\n                ],\n                loadAction: { url: 'salaryadvances/id' },\n                heroField: 'salaryAdvanceID',\n              },\n            },\n            // Changed: Employee overtime history child table\n            {\n              tabTitle: 'Overtime History',\n              showFilter: false,\n              elevation: 'none',\n              flatButtons: true,\n              columns: [\n                { name: 'overtimeDate', type: 'date', alias: 'Date' },\n                { name: 'hours', type: 'text', alias: 'Hours' },\n                { name: 'overtimeTypeName', type: 'text', alias: 'Type' },\n                { name: 'hourlyRate', type: 'money', alias: 'Hourly Rate' },\n                { name: 'amount', type: 'money', alias: 'Amount' },\n              ],\n              buttons: [\n                { name: 'create', display: 'Create', dialog: true, action: { url: 'overtimeentries?action=create', method: 'post' } },\n                { name: 'edit', dialog: true, action: { url: 'overtimeentries?action=edit', method: 'post' } },\n                { name: 'delete', dialog: true, action: { url: 'overtimeentries?action=delete', method: 'post' } },\n              ],\n              loadAction: { url: 'overtimeentries/x/x' }, loadCriteria: 'employee', loadIDField: 'employeeID',\n              formConfig: {\n                title: 'Overtime Entry',\n                fixedTitle: true,\n                fields: [\n                  { name: 'overtimeDate', alias: 'Date', type: 'date', max: 'today', required: true }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n                  { name: 'hours', type: 'number', required: true },\n                  { name: 'overtimeType', alias: 'Overtime Type', type: 'select', loadAction: { url: 'overtimeentries/list/overtime-type' }, required: true },\n                  { name: 'hourlyRate', alias: 'Hourly Rate', type: 'money', required: true },\n                  { name: 'amount', type: 'money', alias: 'Amount', readonly: true, serverOwned: true }, // Changed (CFW-1): OvertimeEntry.Amount carries [ServerOwned] — the employee-details copy of the overtime form, same entity, same flag\n                ],\n                loadAction: { url: 'overtimeentries/id' },\n                heroField: 'overtimeEntryID',\n              },\n            },\n          ],\n        }\n      },\n      { name: 'edit', dialog: true, action: { url: 'employees?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'employees?action=delete', method: 'post' } },\n    ],\n    loadAction: { url: 'employees/all/x' },\n    formConfig: this.employeeFormConfig,\n    realTime: true,\n    pagination: { pageSize: 25 }, // Added: server-side pagination — long reference list — scanned and searched rather than read end to end\n    offline: { enabled: true, readOnly: true }, // Added (WS-1 Phase 3): read cache only — Employee is not ISync so nothing can queue; the value is that the grid reads and the dialog's six selects survive with no network\n    entityName: 'Employee', // Changed: Match backend entity name for SignalR broadcasts\n  }\n\n\n  //--------------------------Positions-------------------------\n  positionsTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'text' },\n      { name: 'description', type: 'text' },\n      { name: 'departmentName', type: 'chip', detailsConfig: this.departmentDetailsConfig, alias: 'Department' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'positions?action=create', method: 'post' } },\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.positionFormConfig ,\n          heroField: 'positionID',\n          buttons: [this.editPositionButton],\n          tableConfigs: [\n            {\n              ...this.employeesTableConfig,\n              loadAction: { url: 'employees/x/x' }, loadCriteria: 'position', loadIDField: 'positionID',\n              columns: this.employeesTableConfig.columns.filter(x => ['departmentName', 'positionName'].includes(x.name) == false),\n              tabTitle: 'Employees',\n              elevation: 'none',\n            }\n          ],\n        }\n      },\n      this.editPositionButton,\n      { name: 'delete', dialog: true, action: { url: 'positions?action=delete', method: 'post' } },\n      this.unlockPositionButton, // Added: last, beside delete — hidden on every unlocked row, so the action column is unchanged for normal data\n    ],\n    loadAction: { url: 'positions/all/x' },\n    formConfig: this.positionFormConfig,\n    realTime: true,\n    entityName: 'Position' // Changed: Match backend entity name for SignalR broadcasts\n  }\n\n\n  //--------------------------Departments-------------------------\n\n  departmentTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name'],\n    flatButtons: true,\n    columns: [\n      // { name: 'departmentID', type: 'number', alias: 'ID' },\n      { name: 'name', type: 'text' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'departments?action=create', method: 'post' } },\n      {\n        name: 'view',\n        dialog: true,\n        detailsConfig: {\n          formConfig: this.departmentFormConfig,\n          heroField: 'departmentID',\n          buttons: [this.editDepartmentButton],\n          tableConfigs: [\n            {\n              ...this.employeesTableConfig,\n              loadAction: { url: 'employees/x/x' }, loadCriteria: 'department', loadIDField: 'departmentID',\n              columns: this.employeesTableConfig.columns.filter(x => ['departmentName', 'positionName'].includes(x.name) == false),\n              tabTitle: 'Employees',\n              elevation: 'none',\n            },\n            {\n              ...this.positionsTableConfig,\n              loadAction: { url: 'positions/x/x' }, loadCriteria: 'department', loadIDField: 'departmentID',\n              tabTitle: 'Positions',\n              elevation: 'none',\n\n            }\n          ],\n        }\n      },\n      this.editDepartmentButton,\n      { name: 'delete', dialog: true, action: { url: 'departments?action=delete', method: 'post' } },\n      this.unlockDepartmentButton, // Added: last, beside delete — hidden on every unlocked row, so the action column is unchanged for normal data\n    ],\n    loadAction: { url: 'departments/all/x' },\n    formConfig: this.departmentFormConfig,\n    realTime: true,\n    entityName: 'Department' // Changed: Match backend entity name for SignalR broadcasts\n  }\n\n\n  //--------------------------Contact Persons-------------------------\n  contactPersonFormConfig: FormConfig = {\n    title: 'Contact Person',\n    includeAudit: true,\n    fields: [\n      { name: 'name', type: 'text', span : true },\n      { name: 'mobile', type: 'text' },\n      { name: 'email', type: 'text' },\n      { name: 'contactMethods', type: 'composite', span: true, subfields :[\n        { name: 'canCall', type: 'checkbox', alias: 'Call' },\n        { name: 'canSMS', type: 'checkbox', alias: 'SMS' },\n        { name: 'canWhatsApp', type: 'checkbox', alias: 'WhatsApp' }\n      ] },\n\n    ],\n    reset: true\n  };\n\n  contactPersonTableConfig: TableConfig = {\n    tabTitle: 'Contacts',\n    showFilter: true,\n    minColumns: ['name', 'contactMethods'],\n    elevation: 'none',\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'text', },\n      { name: 'mobile', type: 'text' },\n      { name: 'email', type: 'text' },\n      {\n        name: 'contactMethods',\n        type: 'icon',\n        icons: [\n          { name: 'call', color: 'green', condition: x => x.canCall, tip: 'Available for Calls' },\n          { name: 'sms', color: 'green', condition: x => x.canSMS, tip: 'Available for SMS' },\n          { name: 'forum', color: 'green', condition: x => x.canWhatsApp, tip: 'Available on WhatsApp' }\n        ]\n      }\n    ],\n    buttons: [\n      { name: 'create', display: 'Add', dialog: true, action: { url: 'contactpersons?action=create', method: 'post' }, confirm: { message: 'Add contact person?' } },\n      { name: 'edit', dialog: true, action: { url: 'contactpersons?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'contactpersons?action=delete', method: 'post' } }\n    ],\n    formConfig: this.contactPersonFormConfig,\n    offline: { enabled: true, queue: { create: true, edit: true, delete: true } }, // Added: contacts queue offline — created before their parent exists, so this exercises the ClientRefs FK-resolution path\n    realTime: true, // Added: refresh when another user changes a contact\n    entityName: 'ContactPerson' // Added: matches backend typeof(ContactPerson).Name for SignalR broadcasts\n  };\n\n\n  //--------------------------Customers-------------------------\n  customerFormConfig: FormConfig = {\n    security: { allow: [this.capCustomers] },\n    includeAudit: true,\n    title : 'Customer',\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'phone', type: 'text' },\n      { name: 'contactPerson', type: 'text' },\n      { name: 'email', type: 'text' },\n      { name: 'address', type: 'text-area', rows: 2, span: true },\n      { name: 'customerTenantID', alias: 'Customer Tenant', type: 'text-single', loadAction: { url: 'tenants/list/x' }, strict : true , nullable: true }, // Changed: no longer required — CustomerTenantID is nullable on the model (IsLinked is the optional B2B link), and a required server-loaded lookup made offline create impossible\n\n      // Added: statutory and trading terms — the details that are agreed once with the customer and\n      // then govern how every document to them must be raised. Grouped away from contact details\n      // because nobody edits these day to day, but getting them wrong invalidates an invoice.\n      { name: 'tradingTerms', type: 'section', alias: 'Statutory & Trading Terms', collapseOnView: true }, // Changed: agreed once, so it folds away on an existing customer and leaves the contacts tab in view\n      { name: 'vatNumber', type: 'text', alias: 'VAT Number', hint: 'ZIMRA VAT registration — required on a tax invoice' }, // Added: Phase 2 compliance — customer VAT registration number\n      { name: 'tin', type: 'text', alias: 'TIN', hint: 'Taxpayer Identification Number' }, // Added: Phase 2 compliance — taxpayer identification number\n      { name: 'requirePONumber', type: 'checkbox', alias: 'Requires a PO number', hint: 'This customer rejects an invoice that does not quote their own order number' }, // Added: moved off the tenant-wide AppConfiguration — PO discipline is a term of the trading relationship\n    ],\n    loadAction: { url: 'customers/id' },\n    heroField: 'customerID',\n\n    reset: true,\n  }\n\n  customerCreateButton : Button = { name: 'create', display: 'Create', dialog: true, action: { url: 'customers?action=create', method: 'post' } }\n  customerEditButton: Button = { name: 'edit', dialog: true, action: { url: 'customers?action=edit', method: 'post' } }\n\n  customerDetailsConfig: DetailsDialogConfig = {\n    formConfig : this.customerFormConfig,\n    heroField : 'customerID',\n    tableConfigs: [\n      {\n        ...this.contactPersonTableConfig,\n        loadAction: { url: 'contactpersons/customer/x' },\n        loadCriteria: 'customer',\n        loadIDField: 'customerID',\n        createConfig: { navigationProperty: 'contactPersons' } // Added: one-step create — contacts added during customer creation are held locally and POSTed with the customer in a single payload\n      }\n    ],\n    buttons: [\n      this.customerCreateButton,\n      this.customerEditButton\n    ]\n  };\n\n  // Added: one-step create button — carries detailsConfig so the Contacts tab renders inside the CREATE dialog\n  // (local/in-memory rows). Declared after customerDetailsConfig to avoid a forward reference.\n  customerCreateWithContactsButton: Button = { name: 'create', display: 'Create', dialog: true, detailsConfig: this.customerDetailsConfig, action: { url: 'customers?action=create', method: 'post' } }\n\n  customersTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name'],\n    flatButtons: true,\n    logResponse: false, // TS-21: disabled shipped default response logging\n    maxButtonsCount: 3,\n    collapseButtons : true,\n\n    columns: [\n\n      { name: 'name', type: 'text' },\n      { name: 'phone', type: 'text' },\n      { name: 'contactPerson', type: 'text' },\n      { name: 'isLinked', type: 'checkbox', alias: 'Linked' },\n\n    ],\n\n    buttons: [\n      this.customerCreateWithContactsButton, // Changed: one-step create — Contacts tab lives in the create dialog\n      { name: 'view', dialog: true, detailsConfig: this.customerDetailsConfig },\n      { name: 'edit', dialog: true, detailsConfig: this.customerDetailsConfig },\n      { name: 'delete', dialog: true, action: { url: 'customers?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'customers/all/x' },\n    formConfig: this.customerFormConfig,\n    realTime: true,\n    offline: { enabled: true, queue: { create: true, edit: true, delete: true } }, // Added: reads served from cache offline, writes queued and drained on reconnect; RowVersion catches conflicting edits\n    pagination: { pageSize: 25 }, // Added: server-side pagination — long reference list — scanned and searched rather than read end to end\n    entityName: 'Customer', // Changed: Match backend typeof(Customer).Name for SignalR broadcasts\n  }\n\n\n  //--------------------------Customer Purchase Orders-------------------------\n  // Orders the CUSTOMER issues to us, against which we bill. Distinct from the supplier purchase\n  // order (Purchasing), which is one WE issue when buying — hence the fully-qualified names on both\n  // sides, so \"purchase order\" is never ambiguous in code or on screen.\n  // Entirely optional: a cash-based customer is invoiced with no order at all. Recording one simply\n  // makes \"how much of this order is still unbilled\" answerable, and lets over-billing be spotted.\n  customerPurchaseOrderFormConfig: FormConfig = {\n    security: { allow: [this.capCustomers] },\n    includeAudit: true,\n    title: 'Customer Purchase Order',\n    fields: [\n      { name: 'customerID', alias: 'Customer', type: 'text-single', loadAction: { url: 'customers/list/x' }, required: true, strict: true, detailsConfig: this.customerDetailsConfig }, // Changed: dropdown quick-add\n      { name: 'poNumber', type: 'text', alias: 'Order Number', required: true, hint: 'Exactly as the customer wrote it — this is the field they reconcile on' },\n      { name: 'poDate', type: 'date', max: 'today', alias: 'Order Date', required: true }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'amount', type: 'number', alias: 'Order Value (excl tax)', hint: 'Leave 0 if the order arrived without a total — billing is never blocked, it just cannot be checked against a value' },\n      { name: 'status', type: 'select', options: [{ id: 0, name: 'Open' }, { id: 1, name: 'Closed' }, { id: 2, name: 'Cancelled' }] },\n\n      // Changed: sectioned — who/what/how much stays up top; the customer's own paperwork references are\n      // captured once and read only when a query comes back on the order\n      { name: 'orderReferences', type: 'section', alias: 'References & Validity', collapseOnView: true },\n      { name: 'expiryDate', type: 'date', alias: 'Expires', nullable: true, defaultValue: '', section: 'orderReferences' }, // Changed: defaultValue '' stops TinCore pre-filling TODAY — a customer order that expires the day it is captured is wrong by construction, and nullable:true already says the intended default is EMPTY\n      { name: 'reference', type: 'text', alias: 'Their Reference', hint: 'Requisition, contract or job-card number. Two orders can share one — it is not unique', section: 'orderReferences' },\n      { name: 'notes', type: 'text-area', rows: 2, span: true, section: 'orderReferences' },\n    ],\n    loadAction: { url: 'customerpurchaseorders/id' },\n    heroField: 'customerPurchaseOrderID',\n    reset: true,\n  }\n\n  customerPurchaseOrdersTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['poNumber', 'customerName', 'amountRemaining'],\n    flatButtons: true,\n    maxButtonsCount: 3,\n    collapseButtons: true,\n\n    columns: [\n      { name: 'poNumber', type: 'text', alias: 'Order' },\n      { name: 'customerName', type: 'text', alias: 'Customer' },\n      { name: 'poDate', type: 'date', alias: 'Dated' },\n      { name: 'amount', type: 'number', alias: 'Value' },\n      { name: 'amountBilled', type: 'number', alias: 'Billed' },\n      \n      { name: 'lineCount', type: 'number', alias: 'Lines' },\n      {\n        name: 'amountRemaining', type: 'chip', alias: 'Left to bill',\n        colors: [\n          { name: '#EF9A9A', condition: x => x.isOverBilled }, // billed past what the customer authorised\n          { name: '#A5D6A7', condition: x => !x.isOverBilled && x.amountRemaining > 0 },\n          { name: '#E0E0E0', condition: x => !x.isOverBilled && x.amountRemaining <= 0 } // fully consumed, nothing left to bill\n        ]\n      },\n      { name: 'status', type: 'text' },\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Record Order', dialog: true, action: { url: 'customerpurchaseorders?action=create', method: 'post' } },\n      { name: 'view', dialog: true },\n      { name: 'edit', dialog: true, action: { url: 'customerpurchaseorders?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'customerpurchaseorders?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'customerpurchaseorders/all/x' },\n    formConfig: this.customerPurchaseOrderFormConfig,\n    pagination: { pageSize: 20 }, // Added: server-side pagination — customer POs append with every order received\n    entityName: 'CustomerPurchaseOrder',\n  }\n\n  //--------------------------Suppliers-------------------------\n  supplierFormConfig: FormConfig = {\n    security: { allow: [this.capSuppliers] },\n    includeAudit: true,\n    title: 'Supplier',\n    fields: [\n      { name: 'name', type: 'text', required: true },\n      { name: 'phone', type: 'text' },\n      { name: 'contactPerson', type: 'text' },\n      { name: 'email', type: 'text' },\n      { name: 'address', type: 'text-area', rows: 2, span: true },\n\n      // Changed: sectioned to mirror the customer form — the statutory registrations are captured once and\n      // then only matter at payment time, so they fold away and leave the contacts tab in view\n      { name: 'tradingTerms', type: 'section', alias: 'Statutory & Tax Clearance', collapseOnView: true },\n      { name: 'vatNumber', type: 'text', alias: 'VAT Number', section: 'tradingTerms' }, // Added: Phase 2 compliance — supplier VAT registration number\n      { name: 'tin', type: 'text', alias: 'TIN', section: 'tradingTerms' }, // Added: Phase 2 compliance — taxpayer identification number\n      { name: 'taxClearanceNumber', type: 'text', alias: 'Tax Clearance # (ITF263)', infoMessage: 'Payments withhold 30% when clearance is missing or expired', section: 'tradingTerms' }, // Added: Phase 2 compliance — ITF263 clearance\n      { name: 'taxClearanceExpiry', type: 'date', alias: 'Tax Clearance Expiry', defaultValue: '', infoMessage: 'Payments withhold 30% when clearance is missing or expired', section: 'tradingTerms' }, // Changed: defaultValue '' stops TinCore pre-filling TODAY — an expiry read off someone else's ITF263 certificate can never default to today, and a silent today silently marks the supplier as expiring now, which withholds 30% of their payment\n    ],\n\n    loadAction: { url: 'suppliers/id' },\n    heroField: 'supplierID',\n  }\n\n  supplierCreateButton : Button = { name: 'create', display: 'Create', dialog: true, action: { url: 'suppliers?action=create', method: 'post' } }\n  supplierEditButton : Button = { name: 'edit', dialog: true, action: { url: 'suppliers?action=edit', method: 'post' } }\n\n  supplierDetailsConfig: DetailsDialogConfig = {\n    formConfig : this.supplierFormConfig,\n    heroField : 'supplierID',\n    tableConfigs: [\n      {\n        ...this.contactPersonTableConfig,\n        loadAction: { url: 'contactpersons/supplier/x' },\n        loadCriteria: 'supplier',\n        loadIDField: 'supplierID',\n        createConfig: { navigationProperty: 'contactPersons' } // Added: one-step create — contacts POST with the supplier in a single payload\n      }\n    ],\n    buttons : [\n      this.supplierCreateButton,\n      this.supplierEditButton,\n    ]\n  };\n\n  // Added: one-step create button — carries detailsConfig so the Contacts tab renders inside the CREATE dialog\n  supplierCreateWithContactsButton: Button = { name: 'create', display: 'Create', dialog: true, detailsConfig: this.supplierDetailsConfig, action: { url: 'suppliers?action=create', method: 'post' } }\n\n  suppliersTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name'],\n    flatButtons: true,\n    columns: [\n      { name: 'name', type: 'text' },\n      { name: 'phone', type: 'text' },\n      { name: 'contactPerson', type: 'text' },\n    ],\n\n    buttons: [\n      this.supplierCreateWithContactsButton, // Changed: one-step create — Contacts tab lives in the create dialog\n      { name: 'view', dialog: true, detailsConfig: this.supplierDetailsConfig },\n      { name: 'edit', dialog: true,  detailsConfig: this.supplierDetailsConfig },\n      { name: 'delete', dialog: true, action: { url: 'suppliers?action=delete', method: 'post' } },\n\n    ],\n\n    loadAction: { url: 'suppliers/all/x' },\n    formConfig: this.supplierFormConfig,\n    allowUserKeepOpen: true, // Added: for testing — propagates to Create dialog (which has no detailsConfig of its own)\n    keepOpenBehavior: 'reset', // Added: for testing — reset form after create so user can capture next supplier\n    realTime: true, // Changed: Enabled for SignalR testing\n    offline: { enabled: true, queue: { create: true, edit: true, delete: true } }, // Added: reads served from cache offline, writes queued and drained on reconnect; RowVersion catches conflicting edits\n    pagination: { pageSize: 25 }, // Added: server-side pagination — long reference list — scanned and searched rather than read end to end\n    entityName: 'Supplier', // Changed: Match backend entity name for SignalR broadcasts\n  }\n\n\n  //--------------------------GPT Caches-------------------------\n  gptCachesFormConfig: FormConfig = {\n    security: { allow: [this.capGPTCaches] },\n    title: 'GPT Cache',\n    fields: [\n      { name: 'methodName', type: 'text', required: true, alias: 'Method Name', span: true },\n      { name: 'requestText', type: 'text-area', required: true, alias: 'Request Text', span: true, rows: 4 },\n      { name: 'responseJson', type: 'text-area', required: true, alias: 'Response JSON', span: true, rows: 4 },\n\n      // Changed: sectioned — the cached request/response is what anyone opens this for; the identifiers and\n      // usage counters are diagnostics, so they fold away\n      { name: 'cacheDiagnostics', type: 'section', alias: 'Identifiers & Usage', collapseOnView: true },\n      { name: 'gptCacheID', type: 'number', readonly: true, alias: 'ID', section: 'cacheDiagnostics' },\n      { name: 'requestHash', type: 'text', readonly: true, alias: 'Request Hash', span: true, section: 'cacheDiagnostics' },\n      { name: 'matchCount', type: 'number', alias: 'Match Count', section: 'cacheDiagnostics' },\n      { name: 'hitCount', type: 'number', alias: 'Hit Count', section: 'cacheDiagnostics' },\n      { name: 'createdDate', type: 'datetime', readonly: true, alias: 'Created', section: 'cacheDiagnostics' },\n      { name: 'updatedDate', type: 'datetime', readonly: true, alias: 'Updated', section: 'cacheDiagnostics' }\n    ],\n    loadAction: { url: 'gptcaches/id' },\n    heroField: 'gptCacheID',\n  }\n\n\n  gptCachesTableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['methodName', 'requestText', 'hitCount'],\n    columns: [\n      { name: 'methodName', alias: 'Method' },\n      { name: 'requestText', alias: 'Request', maxLength: 100 },\n      { name: 'responseJson', alias: 'Response', maxLength: 100 },\n      { name: 'requestHash', alias: 'Hash', maxLength: 20 },\n      { name: 'matchCount', type: 'number', alias: 'Matches', icon: { name: 'verified', color: 'green', condition: (x: any) => x.matchCount > 3 } },\n      { name: 'hitCount', type: 'number', alias: 'Hits', icon: { name: 'trending_up', color: 'blue', condition: (x: any) => x.hitCount > 10 } },\n      { name: 'createdDate', type: 'datetime', alias: 'Created' },\n      { name: 'updatedDate', type: 'datetime', alias: 'Updated' }\n    ],\n    buttons: [\n      { name: 'view', dialog: true, tip: 'View Cache Details' },\n      { name: 'edit', dialog: true,  action: { url: 'gptcaches?action=edit', method: 'post' }, tip: 'Edit Cache' },\n      { name: 'delete', confirm: { message: 'Are you sure you want to delete this cache entry?' }, action: { url: 'gptcaches?action=delete', method: 'post' }, tip: 'Delete Cache' }\n    ],\n    loadAction: { url: 'gptcaches/all/x' },\n    formConfig: this.gptCachesFormConfig\n  }\n\n\n  //--------------------------Notifications-------------------------\n\n  notificationOptions = [\n    { name: 'UI Only', value: 1 },\n    { name: 'UI + Email', value: 3 },\n    // { name: 'UI + Email + SMS', value: 7 },\n    { name: 'UI + WhatsApp', value: 9 },\n    { name: 'UI + Telegram', value: 17 },\n    { name: 'UI + Telegram + WhatsApp', value: 25 },\n    { name: 'UI + Push', value: 33 }, // Changed: Added Push=32 channel combination\n    { name: 'UI + Email + Push', value: 35 }, // Changed: Added Email+Push combination\n    { name: 'All Channels', value: 63 } // Changed: Updated from 31 to 63 to include Push=32\n  ]\n\n\n\n  //--------------------------Approvals-------------------------\n\n\n  approvalHistoryFormConfig : FormConfig = {\n    security: { allow: [this.capApprovals] }, // Added: gate approval history form by approvals cap\n    title: 'Approval History',\n    fields: [\n      { name: 'levelName', type: 'text', readonly: true, alias: 'Level' },\n      { name: 'statusName', type: 'text', readonly: true, alias: 'Status' },\n      { name: 'comments', type: 'text-area', readonly: true, span: true, rows: 3, copyContent: true },\n    ],\n    includeAudit: true\n  }\n\n  //Approval History\n  approvalHistoryTableConfig: TableConfig = {\n    tabTitle: 'Trail',\n    elevation: 'none',\n    minColumns: ['createdDate', 'levelName', 'statusName'],\n    flatButtons: true,\n    showFilter : true,\n    columns: [\n      { name: 'createdDate', type: 'datetime', alias : 'Date' },\n      { name: 'levelName', type: 'text', alias: 'Level' },\n      {\n        name: 'statusName', type: 'text', alias: 'Status',\n        colors: [\n          { name: '#90A4AE', condition: x => x.status === 0 },\n          { name: '#66BB6A', condition: x => x.status === 1 },\n          { name: '#F44336', condition: x => x.status === 2 }\n        ]\n      },\n      { name: 'comments', type: 'text', },\n      { name: 'createdByName', type: 'monogram', alias: 'By' }, // Changed: monogram — the row still carries the full name, so filter/sort are untouched\n\n    ],\n    buttons: [\n      { name: 'view', dialog: true }\n    ],\n\n    formConfig : this.approvalHistoryFormConfig,\n\n    loadAction: { url: 'approvalhistory/approval/x' },\n    loadCriteria: 'approval',\n    loadIDField: 'approvalID'\n  };\n\n\n\n  //approvals form\n  approvalFormConfig: FormConfig = {\n    security: { allow: [this.capApprovals] }, // Added: gate approval form by approvals cap\n    title: 'Approval',\n    fields: [\n      { name: 'blank', type: 'blank', span: true },\n      { name: 'statusName', type: 'text', alias: 'Status', span: true, readonly: true }, // Changed (label-ngspace-1, owner 2026-08-22): type label -> read-only text; readonly:true ADDED — spa-label was never editable, and this form is not a create form, so testReadOnly returns true here and the field stays locked.\n      { name: 'message', type: 'text-area', required: true, span: true, rows: 3 },\n\n    ],\n    loadAction: { url: 'approvals/id' },\n    heroField: 'approvalID'\n  };\n\n\n\n\n  // approval action dialog\n  approvalActionFormConfig: FormConfig = {\n    security: { allow: [this.capApprovals] }, // Added: gate approval action form by approvals cap\n    title: 'Approval Action',\n    fixedTitle: true,\n    fields: [\n      {\n        name: 'comments', type: 'text-area', required: false, span: true, rows: 3,\n        infoMessage: 'Enter your comments about this approval action. This will be visible in the approval history.'\n      }\n    ]\n  };\n\n  approveActionDetailsConfig: DetailsDialogConfig = {\n    formConfig: {\n      ...this.approvalActionFormConfig,\n      fields: [\n        {\n          name: 'comments', type: 'text-area', required: false, span: true, rows: 3,\n          infoMessage: 'Enter your comments about this approval action. This will be visible in the approval history.'\n        }\n      ],\n    },\n    mode: 'edit',\n    buttons: [\n      { name: 'edit', display: 'Approve', color: 'green', action: { url: 'approve', method: 'post' } } //url preconfigured to be dynamic\n    ]\n  };\n\n  declineActionDetailsConfig: DetailsDialogConfig = {\n    formConfig: {...this.approvalActionFormConfig,\n      fields: [\n        {\n          name: 'comments', type: 'text-area', required: true, span: true, rows: 3,\n          infoMessage: 'Enter your comments about this approval action. This will be visible in the approval history.',\n          hint : 'Decline comment is required !'\n        }\n      ],\n    },\n    mode: 'edit',\n    buttons: [\n      { name: 'edit', display: 'Decline', color: 'red', action: { url: 'decline', method: 'post' } } //url preconfigured to be dynamic\n    ]\n  }\n\n\n\n  approveButton: Button = {\n    name: 'approve', tip: 'Approve Request', dialog: true, inDialog: true, icon: { name: 'done' }, color: 'green', detailsConfig: this.approveActionDetailsConfig, ignorePendingApproval: true,\n    visible: x => x && x.canAction && (!x.isMyApprovalRequest || this.myRole[this.capSelfApproval.name]),\n  }\n\n  declineButton: Button = {\n    name: 'decline', tip: 'Decline Request', dialog: true, inDialog: true, icon: { name: 'close' }, color: 'red', detailsConfig: this.declineActionDetailsConfig, ignorePendingApproval: true,\n    visible: x => x && x.canAction && (!x.isMyApprovalRequest || this.myRole[this.capSelfApproval.name]),\n  }\n\n  cancelButton: Button = {\n    name: 'cancel', tip: 'Cancel Approval', inDialog: true, icon: { name: 'cancel' }, color: 'red', action: { url: 'cancel', method: 'post', }, ignorePendingApproval: true, //url preconfigured to be dynamic\n    confirm: { message: 'Cancel approval request? This will revert changes and stop the approval process.' },\n    visible: x => x && x.canCancel\n  }\n\n  approvalDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.approvalFormConfig,\n    heroField: 'approvalID',\n    tableConfigs: [this.approvalHistoryTableConfig],\n\n    stepConfig: {\n      steps: [],\n      loadAction: { url: `approvals/steps/{id}` },\n      loadIDField: 'approvalID',\n      valueField: 'currentLevel'\n    },\n\n    buttons : [\n      this.approveButton,\n      this.declineButton,\n      this.cancelButton\n    ]\n\n  };\n\n\n  viewApprovalButton: Button = {\n    name: 'info', tip: 'Approval Information', dialog: true, icon: { name: 'info',  }, detailsConfig: this.approvalDetailsConfig, ignorePendingApproval: true,\n    visible: x => x.canAction || x.canCancel\n  }\n\n\n  //received approvals\n  receivedApprovalsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['message', 'statusName'],\n    minButtons: ['view', 'approve', 'decline'],\n    flatButtons: true,\n    greyOut: (x) => x.isGreyedOut,\n    // logResponse: true,\n    collapseButtons: true,\n    columns: [\n      { name: 'createdDate', type: 'datetime', alias: 'Date' },\n      { name: 'createdByName', alias: 'Request By', type: 'monogram' }, // Changed: monogram\n      { name: 'message', type: 'text' },\n      {\n        name: 'typeName', alias: 'Type', type: 'chip',\n        colors: [\n          { name: '#66BB6A', condition: x => x.type === 0 },\n          { name: 'orange', condition: x => x.type === 1 },\n          { name: '#F44336', condition: x => x.type === 2 }\n        ]\n      },\n      {\n        name: 'statusName', alias: 'Status', type: 'chip', detailsConfig: this.approvalDetailsConfig,\n        colors: [\n          { name: '#90A4AE', condition: x => x.status === 0 },\n          { name: '#66BB6A', condition: x => x.status === 1 },\n          { name: '#F44336', condition: x => x.status === 2 }\n        ]\n      },\n      {\n        name: 'currentLevelName', type: 'text', alias: 'Current Level',\n        icons: [\n          { name: 'done', color: '#66BB6A', condition: x => x.status === 'Approved', tip: 'Approved' },\n          { name: 'close', color: '#F44336', condition: x => x.status === 'Declined', tip: 'Declined' },\n          { name: 'schedule', color: '#FFC107', condition: x => x.status === 'Pending', tip: 'Pending' }\n        ]\n      },\n      { name: 'updatedByName', alias: 'Actioned By', type: 'monogram' }, // Changed: monogram\n      { name: 'updatedDateDisplay', type: 'datetime', alias: 'Actioned Date' },\n    ],\n\n    buttons: [\n      this.viewApprovalButton,\n      this.approveButton,\n      this.declineButton,\n      this.cancelButton,\n    ],\n\n    loadAction: { url: 'approvals/all/x' }\n  };\n\n\n  //send approvals\n  sentApprovalsTableConfig: TableConfig = {\n    ...this.receivedApprovalsTableConfig,\n    buttons: [\n      this.viewApprovalButton,\n      this.cancelButton,\n    ],\n    loadAction: { url: 'approvals/sent/x' }\n  };\n\n\n  //---------------------------Other code\n\n  private listCache: { [key: string]: any } = {};\n  private cacheTimestamps: { [key: string]: number } = {};\n  private ongoingRequests: { [key: string]: Observable<ApiResponse> } = {};\n\n  // Changed: Quiet Loading — optional call-time `options.silent` suppresses the global scrim for this ONE call.\n  // It is an argument rather than a mutation of `action` on purpose: Actions live on long-lived config\n  // singletons shared between the main page and every dialog clone, so writing silence into one would leak it\n  // into surfaces that never opted in. `action.silent` remains available for a genuinely always-silent action.\n  public CallApi(action: Action, data: any = '', options?: { silent?: boolean } ) {\n\n\n    if (!action?.url) {\n      console.warn('Invalid action or missing URL');\n      return of({ success: false, message: 'Invalid action configuration' });\n    }\n\n    // console.log(\"calling\", action);\n\n    const silent = options?.silent !== undefined ? !!options.silent : !!action.silent; // Added: call-time flag wins over the action's own\n\n    if (!action.method || action.method === 'get') {\n      // Changed: TinSync offline read seam — registered URLs persist to IndexedDB and are served from it when the network is down\n      const offlineReadEntry = this.offline.hasAny ? this.offline.matchRead(action.url) : null;\n      if (offlineReadEntry) {\n        return this.offline.handleOfflineRead(action, offlineReadEntry, () => this.handleCachedCall(action, silent)); // Changed: carry silence into the network fallback\n      }\n      return this.handleCachedCall(action, silent); // Changed: carry silence to the HTTP layer\n    } else if (action.method === 'post') {\n\n      // Changed: TinSync offline write seam — registered CRUD mutations queue locally while offline instead of failing\n      if (this.offline.hasAny && this.isCrudAction(action.url) && !this.offline.online) {\n        const mutationEntry = this.offline.matchMutation(action.url);\n        if (mutationEntry) {\n          if (action.isFormData) {\n            return of({ success: false, message: 'File uploads require a connection' });\n          }\n          return this.offline.enqueueOffline(action, data, mutationEntry);\n        }\n      }\n\n      let request: Observable<ApiResponse>;\n\n      // Changed: silent context threaded through every POST shape (undefined when not silent — request unchanged)\n      if (action.isFormData) {\n        request = this.httpService.Post_FormData(action.url, data, silentContext(silent)) as Observable<ApiResponse>;\n      } else if (action.url === 'approve' || action.url === 'decline' || action.url === 'cancel') {\n        request = this.httpService.Post(`${data.endpoint}/approve?action=${action.url}`, data, silentContext(silent));\n      } else {\n        request = this.httpService.Post(action.url, data, silentContext(silent));\n      }\n\n      // Invalidate cache after successful CRUD operations\n      return request.pipe(\n        tap((response: ApiResponse) => {\n          if (response.success && this.isCrudAction(action.url)) {\n            const entityName = this.extractEntityName(action.url);\n            if (entityName) {\n              console.log('Invalidating cache for:', entityName);\n              this.invalidateListCache(entityName);\n            }\n          }\n        }),\n        catchError(err => {\n          // Changed: TinSync — a registered mutation dying mid-flight on a network error is queued instead of lost\n          if (err?.status === 0 && this.offline.hasAny && !action.isFormData) {\n            const entry = this.offline.matchMutation(action.url);\n            if (entry) {\n              this.offline.reportNetworkFailure();\n              return this.offline.enqueueOffline(action, data, entry);\n            }\n          }\n          return throwError(() => err);\n        })\n      );\n    } else {\n      return this.httpService.Post(action.url, data, silentContext(silent)); // Changed: silence honoured on the fallback branch too\n    }\n\n  }\n\n  private isCrudAction(url: string): boolean {\n    return url.includes('?action=create') ||\n           url.includes('?action=edit') ||\n           url.includes('?action=delete');\n  }\n\n  private extractEntityName(url: string): string | null {\n    const match = url.match(/^([^?]+)/);\n    return match ? match[1] : null;\n  }\n\n  // Changed: `silent` decides whether the GET this method ends up issuing raises the global scrim.\n  // NOTE: dedupe is by URL only, so a silent caller can legitimately join an already-in-flight NOISY request for\n  // the same URL (and vice versa). The first caller's scrim behaviour wins for that shared call — acceptable,\n  // because both callers are waiting on the identical response and the quiet surface still renders its own state.\n  private handleCachedCall(action: Action, silent: boolean = false): Observable<ApiResponse> {\n    const cacheKey = this.generateCacheKey(action.url);\n    \n    // Check if we should use cache\n    if (!action.skipCache && this.isCacheValid(cacheKey, action)) {\n      // TS-21: removed per-cache-hit console.log('Using cache', ...)\n      return of({\n        success: true,\n        message: 'success',\n        data: this.listCache[cacheKey]\n      });\n    }\n\n    // Check if there's an ongoing request for the same URL\n    if (this.ongoingRequests[cacheKey]) {\n      // TS-21: removed per-hit console.log('Using ongoing request for', ...)\n      return this.ongoingRequests[cacheKey];\n    }\n\n    // Determine cache duration\n    const cacheDuration = this.getCacheDuration(action);\n    \n    // Only cache if duration is specified or it's a list endpoint\n    if (cacheDuration > 0) {\n      // Create and store the ongoing request\n      this.ongoingRequests[cacheKey] = this.httpService.Get(action.url, silentContext(silent)).pipe( // Changed: silent context\n        timeout(60000), // 1 minute timeout for waiting requests\n        tap((response: ApiResponse) => {\n          if (response.success && response?.data) {\n            this.listCache[cacheKey] = response.data;\n            this.cacheTimestamps[cacheKey] = Date.now(); // Use current time when response is received\n          }\n        }),\n        finalize(() => {\n          delete this.ongoingRequests[cacheKey];\n        }),\n        share() \n      );\n\n      return this.ongoingRequests[cacheKey];\n    } else {\n      // No caching - clear any existing cache for this key\n      if (this.listCache[cacheKey]) {\n        delete this.listCache[cacheKey];\n        delete this.cacheTimestamps[cacheKey];\n      }\n      // Changed: TS-13 — dedupe concurrent identical GETs even when not caching. Previously every uncached GET\n      // (table /all/x, form /id, tile, count) hit the network independently; register a shared in-flight request\n      // so simultaneous callers share one HTTP call (result is NOT cached — cleared on completion).\n      this.ongoingRequests[cacheKey] = this.httpService.Get(action.url, silentContext(silent)).pipe( // Changed: silent context\n        finalize(() => { delete this.ongoingRequests[cacheKey]; }),\n        share()\n      );\n      return this.ongoingRequests[cacheKey];\n    }\n  }\n\n  private generateCacheKey(url: string): string {\n    return url; // URL already includes query params\n  }\n\n  private isCacheValid(cacheKey: string, action: Action): boolean {\n    if (!this.listCache[cacheKey] || !this.cacheTimestamps[cacheKey]) {\n      return false;\n    }\n\n    const cacheDuration = this.getCacheDuration(action);\n    const currentTime = Date.now();\n    const cacheAge = currentTime - this.cacheTimestamps[cacheKey];\n    \n    return cacheAge < (cacheDuration * 60 * 1000); \n  }\n\n  private getCacheDuration(action: Action): number {\n    // If explicitly specified in action, use that\n    if (action.cacheDurationMinutes !== undefined) {\n      return action.cacheDurationMinutes;\n    }\n    \n    // Check centralized cache config\n    const configuredDuration = this.cacheConfig.getDuration(action.url);\n    if (configuredDuration !== null) {\n      return configuredDuration;\n    }\n    \n    // No caching by default\n    return 0;\n  }\n\n  public ClearCache(): void {\n    this.listCache = {};\n    this.cacheTimestamps = {};\n\n\n    Object.keys(this.ongoingRequests).forEach(key => {\n      delete this.ongoingRequests[key];\n    });\n  }\n\n  public invalidateListCache(entityUrl: string): void {\n    Object.keys(this.listCache).forEach(key => {\n      if (key.includes(entityUrl)) {\n        delete this.listCache[key];\n        delete this.cacheTimestamps[key];\n        delete this.ongoingRequests[key];\n      }\n    });\n  }\n\n\n  public CheckWelcomed(path: string = 'home/admin/welcome') {\n    this.CallApi({ url: 'tenants/welcome/x' }).subscribe((x) => { // Changed: controller is TenantsController (plural) — the singular URL 404'd and LoaderInterceptor rethrows, so this next-only subscribe never ran and the welcome redirect never fired at all\n      if (!x.data) {\n        this.Navigate(path)\n      }\n    })\n  }\n\n\n\n  public Navigate(path: string) {\n    this.router.navigate([path]);\n  }\n\n  public NavigateWithValue(path: string, value : string){\n    this.router.navigate([path], {\n      queryParams: { v: value },\n      queryParamsHandling: 'merge',\n      skipLocationChange: false\n    });\n  }\n\n  public GetNavigationValue(){\n    if (this.route.snapshot.queryParams[\"v\"] != undefined) {\n      return this.route.snapshot.queryParams[\"v\"]\n    }else{\n      return \"\";\n    }\n  }\n\n  public tmpAccountID;\n\n\n\n  //Users\n  public GetUser() {\n    return this.httpService.Get(\"User/all/x\");\n  }\n\n  public RegisterAccount(u) {\n    return this.httpService.Post(\"User/register\", u);\n  }\n\n  public GetUserByID(val: string) {\n    return this.httpService.Get(`User/id/${val}`);\n  }\n\n  public UpdateUser(profile) {\n    return this.httpService.Post(\"User/edit\", profile);\n  }\n\n  public UnlockUser(user) {\n    return this.httpService.Post(\"User/unlock\", user);\n  }\n\n  public LockUser(user) {\n    return this.httpService.Post(\"User/lock\", user);\n  }\n\n  public DeleteUser(user) {\n    return this.httpService.Post(\"User/delete\", user);\n  }\n\n  public Login(u: User) {\n    return this.httpService.Post(\"User/login\", u);\n  }\n\n  // Added: BehaviorSubject to pass signup data from login redirect to signup page\n  private pendingSignupSource = new BehaviorSubject<SignupData | null>(null);\n  public pendingSignup$ = this.pendingSignupSource.asObservable();\n\n  // Added: Store pending signup data when login returns signup_required\n  public SetPendingSignup(data: SignupData) {\n    this.pendingSignupSource.next(data);\n  }\n\n  // Added: Clear pending signup data after consumption\n  public ClearPendingSignup() {\n    this.pendingSignupSource.next(null);\n  }\n\n  // Added: Submit signup to backend\n  public Signup(data: SignupData) {\n    return this.httpService.Post(\"User/signup\", data);\n  }\n\n  public ChangePassword(u) {\n    return this.httpService.Post(\"User/changepassword-self\", u);\n  }\n\n  public ChangePasswordAdmin(u) {\n    return this.httpService.Post(\"User/changepassword-admin\", u);\n  }\n\n  public SelfReset(u: User): Observable<any> {\n    return this.httpService.Post(\"Basic/SelfReset\", u);\n  }\n\n\n  //Roles\n\n  public PostRole(role, action: string) {\n    return this.httpService.Post(`Role?action=${action}`, role);\n  }\n\n  public PutRole(role) {\n    return this.httpService.Put(\"Role\", role);\n  }\n\n  public GetRole(by: string, val: string) {\n    return this.httpService.Get(\"Role/all/x\");\n  }\n\n\n\n  //Logs\n  public GetLog(by: string, val: string) {\n    return this.httpService.Get(\"Log/all/x\");\n  }\n\n\n  //Settings\n  public GetSetting(by: string, val: string) {\n    return this.httpService.Get(\"Setting/all/x\");\n  }\n\n  public UpdateSetting(setting, action: string) {\n    return this.httpService.Post(`Setting?action=${action}`, setting);\n  }\n\n}\n","import { Component, OnInit, Inject, Optional } from '@angular/core';\nimport { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { DataServiceLib } from '../../services/datalib.service'; // Added: reads appConfig.dialogStyle\n\n\n// Added (N22 / FSD-3): the ONE comparison that decides whether a typed confirmation phrase counts. Exported as a\n// free function, not a method, for two reasons: it is the thing the specs must pin, and the monogram component\n// established that convention here (pure function + plain Jasmine, no TestBed), which keeps the assertions on the\n// RULE rather than on a rendered fixture.\n//\n// 🔴 ORDINAL AND CASE-SENSITIVE, DELIBERATELY, and it must stay that way. This is the browser half of the server\n// check at TinWeb/Controllers/General/AppConfigurationControllerBase.cs:159:\n//     if (!string.Equals(request?.Phrase, ResetPhrase, StringComparison.Ordinal))\n// A plain === on the raw strings is exactly StringComparison.Ordinal. Anything friendlier here — .trim(), a\n// .toLowerCase(), a localeCompare — makes the button ENABLE on text the server will then REJECT, so the user\n// types something the dialog accepted and gets a flat \"Reset not confirmed\" from the API with nothing on screen\n// explaining why. The two halves must agree on what counts as confirmation or the gate is worse than none.\nexport function phraseSatisfied(typed: any, required: any): boolean {\n  // An absent/blank requirement means this dialog is not phrase-gated at all — nothing to satisfy, so it passes.\n  // This is what keeps the option OPT-IN: every existing caller supplies nothing and is never gated.\n  if (required == null || String(required).length === 0) return true;\n  return typed === required; // Ordinal, case-sensitive, no normalisation of any kind. See above.\n}\n\n@Component({\n    selector: 'lib-app-message',\n    templateUrl: './messageDialog.component.html',\n    styleUrls: ['./messageDialog.component.css'],\n    standalone: false\n})\n\nexport class messageDialog implements OnInit {\n\n  // Changed: DataServiceLib is injected @Optional() so the dialog still renders (as classic) if it is ever\n  // constructed outside an app that provides it — a test harness, or a consumer that opens it directly.\n  // It is injected into the COMPONENT rather than into MessageService on purpose: MessageService is what opens\n  // this dialog, and having it depend on DataServiceLib would risk a service-level cycle. A component is a leaf.\n  constructor(private dialogRef: MatDialogRef<messageDialog>, @Inject(MAT_DIALOG_DATA) public data,\n    @Optional() private dataService: DataServiceLib) { }\n\n\n  ngOnInit() {\n\n    this.messageType = this.data.type\n    this._messageSubject = this.data.subject;\n    this._messageDetails = this.data.details;\n    this._messageReference = this.data.reference; // Added: optional backend correlation code for this failure\n    this._confirmLabel = this.data.confirmLabel; // Added: optional caller-supplied action label for the affirmative button\n    this._cancelLabel = this.data.cancelLabel; // Added: optional caller-supplied label for the dismissive button\n    this._okLabel = this.data.okLabel; // Added: optional caller-supplied label for the acknowledge button\n    this.destructive = this.data.destructive === true; // Added: strict true — an absent flag must never colour a prompt as dangerous\n    this._requirePhrase = this.data.requirePhrase; // Added: optional caller-supplied phrase the user must type verbatim to enable the affirmative button\n\n    // Added: resolve the style once, at open time. The panel class carries surface-level styling (radius,\n    // shadow) that component CSS cannot reach, because the Material surface is an ancestor of this view.\n    this.modern = !!this.dataService?.modernDialogs;\n    if (this.modern) this.dialogRef.addPanelClass('tin-dialog-modern');\n\n  }\n\n  messageType;\n  _messageSubject;\n  _messageDetails;\n  _messageReference; // Added: undefined for every caller that does not supply one\n  modern = false; // Added: appConfig.dialogStyle === 'modern'; false keeps the long-standing presentation\n\n  // Added: this confirmation destroys or undoes something. Drives COLOUR ONLY — never the labels, never the ids,\n  // never whether the buttons exist. Default false, so a caller that says nothing renders exactly as before.\n  //\n  // Why colour has to key off this rather than off button position: the classic style hardcodes `color: green`\n  // on the affirmative button and `color: red` on the dismissive one, an assumption that only holds while the\n  // buttons read \"Yes\" and \"No\" and the affirmative answer is the harmless one. The moment the affirmative\n  // button is NAMED — \"Delete\" — that mapping renders a green Delete beside a red Keep, i.e. it points the\n  // user at the destructive action and warns them off the safe one. Destructiveness is a property of the\n  // ACTION, so that is what the colour must follow.\n  destructive = false;\n\n  // Added: for a destructive confirm the icon becomes a warning rather than the neutral question mark. The\n  // question mark is right for \"Switch organisation?\"; it is too quiet for \"Delete this shelter?\".\n  get iconName(): string { return this.isConfirm && this.destructive ? 'warning_amber' : this.spec.icon; }\n\n  // Added: per-type presentation. Kept as a lookup rather than scattered *ngIf branches so a new type is one\n  // entry here instead of an edit in three places — the old template hardcoded its heading per type, which is\n  // exactly how the caller-supplied subject came to be silently dropped for errors.\n  private static readonly TYPES: any = {\n    error:   { icon: 'error_outline',    title: 'Something went wrong' },\n    warning: { icon: 'warning_amber',    title: 'Please check this' },\n    info:    { icon: 'info_outline',     title: 'Information' },\n    success: { icon: 'check_circle_outline', title: 'Done' },\n    confirm: { icon: 'help_outline',     title: 'Just confirming' },\n  };\n\n  private get spec() { return messageDialog.TYPES[this.messageType] ?? messageDialog.TYPES.info; }\n\n  // Changed: the caller's subject now wins for EVERY type. Previously the heading was hardcoded per type and\n  // the subject was only rendered for 'info', so a friendly title like \"No connection\" never appeared on an\n  // error — the user saw the bare word \"Error\" instead.\n  get title(): string {\n    return (this._messageSubject && String(this._messageSubject).trim()) ? this._messageSubject : this.spec.title;\n  }\n\n  // Added: splits the body into paragraphs on blank lines. The messages themselves already separate \"what\n  // happened\" from \"what to do next\" that way, but the old template rendered the whole thing as one run of\n  // text — which is precisely why nobody read past the first line. The first paragraph is styled as a lead,\n  // the rest as supporting detail, so the eye gets somewhere to land.\n  // Changed: cached — this getter feeds an *ngFor and was re-splitting the body into a NEW array on every\n  // change-detection cycle. The details are set once when the dialog opens, so the cache keys off the source.\n  private paragraphSource: any = undefined;\n  private paragraphCache: string[] = [];\n\n  get paragraphs(): string[] {\n    if (this._messageDetails !== this.paragraphSource) {\n      this.paragraphSource = this._messageDetails;\n      const raw = this._messageDetails == null ? '' : String(this._messageDetails);\n      const parts = raw.split(/\\n\\s*\\n/).map(p => p.trim()).filter(p => p.length > 0);\n      this.paragraphCache = parts.length ? parts : [raw.trim()].filter(p => p.length > 0);\n    }\n    return this.paragraphCache;\n  }\n\n  // Added: the correlation code, normalised and only returned when there is genuinely one to show. Returning\n  // null rather than '' matters — the template hides the whole line on falsy, so an older backend that sends no\n  // reference renders exactly as before instead of leaving an empty \"quote reference\" sentence dangling.\n  get reference(): string | null {\n    const ref = this._messageReference == null ? '' : String(this._messageReference).trim();\n    return ref.length ? ref : null;\n  }\n\n  get isConfirm(): boolean { return this.messageType === 'confirm'; }\n\n  // Added: per-call button labels, so a caller that KNOWS what it is confirming can name the action (\"Delete\",\n  // \"Discard\", \"Post\") instead of the generic \"Yes\". Only the caller has that knowledge — the dialog is handed a\n  // sentence, never an intent — so this is the only place the distinction can come from.\n  // ⚠️ The DEFAULTS ARE DELIBERATELY UNCHANGED (\"Yes\" / \"No\" / \"OK\") and must stay that way:\n  //   1. the owner reverted a hardcoded relabel (\"Cancel\" / \"Yes, continue\") on 2026-08-06 — these are the\n  //      most-clicked buttons in the app and the original wording is what everybody here reads;\n  //   2. 51 E2E assertions across piglet-spa (38) and shift-spa (13) select these buttons by their literal TEXT\n  //      via getByRole('button', { name: 'Yes' }), not by id, so a default change is a suite-wide breakage;\n  //   3. untracked consumers outside this workspace adopt library changes only when they opt in.\n  // Opting in is therefore per call site, never global.\n  _confirmLabel; // Added: undefined for every existing caller\n  _cancelLabel; // Added: undefined for every existing caller\n  _okLabel; // Added: undefined for every existing caller\n\n  private label(value, fallback: string): string {\n    return (value && String(value).trim()) ? String(value).trim() : fallback;\n  }\n\n  get confirmLabel(): string { return this.label(this._confirmLabel, 'Yes'); }\n\n  get cancelLabel(): string { return this.label(this._cancelLabel, 'No'); }\n\n  get okLabel(): string { return this.label(this._okLabel, 'OK'); }\n\n  // Added: heading for the CLASSIC branch. The original template hardcoded one word per type and only rendered\n  // the caller's subject for 'info'; here the subject still wins when supplied, so the \"No connection\" fix\n  // survives in classic mode too — this restores the old LOOK, not the old bug. The per-type words are the\n  // originals (\"Confirm\" / \"Information\" / \"Error\"), with the two newer types given the obvious equivalents.\n  private static readonly CLASSIC_HEADINGS: any = {\n    error: 'Error', warning: 'Warning', info: 'Information', success: 'Success', confirm: 'Confirm',\n  };\n\n  get classicHeading(): string {\n    if (this._messageSubject && String(this._messageSubject).trim()) return this._messageSubject;\n    return messageDialog.CLASSIC_HEADINGS[this.messageType] ?? 'Information';\n  }\n\n  // Added (N22 / FSD-3): the phrase the caller demands, and what the user has actually typed so far.\n  // ⚠️ BOTH DEFAULT TO \"no gate\": _requirePhrase is undefined for every one of the existing callers, so\n  // requiresPhrase is false, no input renders, confirmDisabled is false and the dialog behaves EXACTLY as it\n  // does today. That is the whole opt-in contract — untracked consumers outside this workspace adopt library\n  // changes only when they ask for them, and this one is invisible until a caller passes requirePhrase.\n  _requirePhrase; // Added: undefined for every existing caller\n  typedPhrase = ''; // Added: the raw typed text, NEVER trimmed or case-folded — see phraseSatisfied above\n\n  // Added: a phrase gate exists only for a CONFIRM carrying a non-empty phrase. Guarding on isConfirm as well\n  // matters: an error or info dialog has no affirmative button to gate, so a stray requirePhrase on one of\n  // those must not render an input the user cannot act on.\n  get requiresPhrase(): boolean {\n    return this.isConfirm && this._requirePhrase != null && String(this._requirePhrase).length > 0;\n  }\n\n  // Added: the phrase as a string, for the template's prompt and the input's aria-label.\n  get requiredPhrase(): string { return this._requirePhrase == null ? '' : String(this._requirePhrase); }\n\n  // Added: THE GATE. False whenever there is no phrase to type, so every existing caller's affirmative button\n  // is enabled exactly as before; true until the typed text ordinally equals the phrase.\n  get confirmDisabled(): boolean {\n    return this.requiresPhrase && !phraseSatisfied(this.typedPhrase, this.requiredPhrase);\n  }\n\n  // Added: bound with (input) rather than [(ngModel)] on purpose — this component's module (tin-spa.module.ts)\n  // imports SpaMatModule, which brings MatFormFieldModule and MatInputModule, but it does NOT import FormsModule.\n  // Reaching for ngModel here would mean adding a module import for one field and risking every consumer's build.\n  onPhraseInput(event: any) {\n    this.typedPhrase = event?.target?.value ?? ''; // Raw value. No trim — the server does not trim either.\n  }\n\n  response(resp: string) {\n\n    // Added: belt and braces. The template already disables the affirmative button, but a disabled button is a\n    // DOM state and this method is public — anything that reaches it directly (a test, a keyboard path, a future\n    // caller) must not be able to confirm a phrase-gated dialog that was never satisfied.\n    if (resp === 'yes' && this.confirmDisabled) return;\n\n    // Added: a phrase-gated confirm closes with the TYPED TEXT alongside the answer, because the caller has to\n    // forward that text to the server, which re-validates it independently (AppConfigurationControllerBase.cs:159).\n    // Sending the text the user actually typed — rather than the phrase the caller already knew — is what makes\n    // the request an assertion about the user instead of about the code.\n    // 🔴 The richer shape is returned ONLY when a phrase was demanded. Every existing caller passes no phrase and\n    // still receives the bare 'yes' / 'no' STRING it has always received, so no existing `result === 'yes'` check\n    // anywhere — including in untracked consumer apps and the 51 E2E assertions — can be broken by this change.\n    if (this.requiresPhrase) {\n      this.dialogRef.close({ response: resp, phrase: this.typedPhrase });\n      return;\n    }\n\n    this.dialogRef.close(resp);\n\n  }\n\n};\n","<!-- Changed: two presentations behind one component. `modern` (appConfig.dialogStyle === 'modern') renders the\n     structured layout; anything else renders the long-standing look, so an app that never opts in still gets a\n     familiar dialog. Changed: classic is a SUPPORTED escape hatch, not frozen legacy — it is expected to render\n     the same information as modern, and its three rendering bugs were repaired on 2026-08-06. Button ids\n     (btnYes / btnNo / btnOK) are identical in BOTH branches — existing E2E specs select on them and must not\n     care which style is active. -->\n\n<ng-container *ngIf=\"modern; else classic\">\n\n  <!-- Rebuilt from a hardcoded per-type heading plus one undifferentiated paragraph into a structured layout —\n       icon chip, real title, lead paragraph, supporting detail. The type drives colour via a single class on\n       the root, so adding a type is one entry in the component rather than three template branches. -->\n  <!-- Changed: `tin-msg--destructive` re-points the single --tin-accent variable at the warn red. Because every\n       accented part (the top rule, the icon disc, the primary button) already reads from that one variable, the\n       whole dialog turns to a warning in one class instead of three overrides — and the affirmative button, which\n       is the thing the user is about to press, can no longer come out purple or green on a \"Delete\". -->\n  <div class=\"tin-msg\" [ngClass]=\"'tin-msg--' + messageType\" [class.tin-msg--destructive]=\"isConfirm && destructive\">\n\n    <div class=\"tin-msg__head\">\n      <!-- The icon carries the type at a glance. It sits in a soft tinted disc rather than on a saturated\n           banner: the intent is to inform, not to alarm someone who has usually done nothing wrong. -->\n      <div class=\"tin-msg__icon\">\n        <mat-icon>{{ iconName }}</mat-icon>\n      </div>\n      <h2 class=\"tin-msg__title\">{{ title }}</h2>\n    </div>\n\n    <mat-dialog-content class=\"tin-msg__body\">\n      <!-- First paragraph is the lead (what happened); the rest is supporting detail (what to do next).\n           Splitting on blank lines is what gives the eye somewhere to land — the old single run of text is\n           why nobody read past the first line. -->\n      <p *ngFor=\"let p of paragraphs; let first = first\" class=\"tin-msg__p\" [class.tin-msg__p--lead]=\"first\">{{ p }}</p>\n\n      <!-- The backend's correlation code. Deliberately the quietest thing in the dialog — the user does not\n           need to act on it, they only need to be able to read it out if they call support, at which point it\n           turns a \"something broke this morning\" report into one log row. Hidden entirely when absent. -->\n      <p class=\"tin-msg__ref\" *ngIf=\"reference\">If you contact your administrator, quote reference <span class=\"tin-msg__ref-code\">{{ reference }}</span>.</p>\n\n      <!-- Added (N22 / FSD-3): the typed-phrase gate. Renders ONLY when the caller passed requirePhrase, so every\n           existing confirm is byte-identical to before. The instruction names the phrase in a <strong> rather than\n           leaving it in the sentence, because the user has to reproduce it EXACTLY — case included — and the one\n           thing they must copy should be the one thing they cannot miss. No new colour or font is introduced: the\n           prompt reuses the body paragraph treatment and the field is a stock Material outline field. -->\n      <div class=\"tin-msg__phrase\" *ngIf=\"requiresPhrase\">\n        <p class=\"tin-msg__phrase-prompt\">To confirm, type <strong class=\"tin-msg__phrase-word\">{{ requiredPhrase }}</strong> below. This is case-sensitive.</p>\n        <mat-form-field appearance=\"outline\" class=\"tin-msg__phrase-field\">\n          <input id=\"txtConfirmPhrase\" matInput type=\"text\" autocomplete=\"off\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" [attr.aria-label]=\"'Type ' + requiredPhrase + ' to confirm'\" [value]=\"typedPhrase\" (input)=\"onPhraseInput($event)\" cdkFocusInitial>\n        </mat-form-field>\n      </div>\n    </mat-dialog-content>\n\n    <mat-dialog-actions class=\"tin-msg__actions\">\n      <!-- Changed: labels reverted to \"No\" / \"Yes\" (owner's call, 2026-08-06). The redesign had shipped them as\n           \"Cancel\" / \"Yes, continue\"; these are the most-clicked buttons in the app and the original wording is\n           what everybody here reads. Text only — the ids btnNo / btnYes are untouched and identical to the\n           classic branch, so every E2E selector (#btnYes) and every caller is unaffected.\n           Changed: the literal text is now {{ confirmLabel }} / {{ cancelLabel }} / {{ okLabel }}, which STILL\n           render \"Yes\" / \"No\" / \"OK\" unless the caller passes a label. A caller that knows it is confirming a\n           destructive action can name it (\"Delete\") so it no longer reads identically to a harmless one. -->\n      <!-- Changed: on a DESTRUCTIVE confirm the initial focus moves to the SAFE button. The affirmative button is\n           still #btnYes in the same position with the same click handler — only the keyboard default changes, so\n           hitting Enter on reflex now keeps the record instead of destroying it. Every E2E locator clicks #btnYes\n           explicitly (helpers/form.helper.ts acceptConfirmIfPresent uses page.locator('#btnYes')), so none of them\n           depend on which button holds focus. The colour comes from tin-msg--destructive on the root, not from\n           anything here — the primary button reads --tin-accent either way. -->\n      <ng-container *ngIf=\"isConfirm; else modernAcknowledge\">\n        <button id=\"btnNo\" mat-button class=\"tin-msg__btn-quiet\" [class.tin-msg__btn-safe]=\"destructive\" (click)=\"response('no')\" [attr.cdkFocusInitial]=\"destructive ? '' : null\">{{ cancelLabel }}</button>\n        <!-- Changed (N22 / FSD-3): [disabled] is bound to confirmDisabled, which is FALSE for every caller that\n             passes no requirePhrase — so this button's enabled state is unchanged for all 23 existing call sites. -->\n        <button id=\"btnYes\" mat-flat-button class=\"tin-msg__btn-primary\" [disabled]=\"confirmDisabled\" (click)=\"response('yes')\" [attr.cdkFocusInitial]=\"destructive ? null : ''\">{{ confirmLabel }}</button>\n      </ng-container>\n      <ng-template #modernAcknowledge>\n        <button id=\"btnOK\" mat-flat-button class=\"tin-msg__btn-primary\" (click)=\"response('ok')\" cdkFocusInitial>{{ okLabel }}</button>\n      </ng-template>\n    </mat-dialog-actions>\n\n  </div>\n\n</ng-container>\n\n\n<!-- Classic: the original LOOK, kept deliberately as the escape hatch (owner's call, 2026-08-06 — retire was\n     recommended and declined). It is the original markup plus FIXES, never style changes, because reverting a\n     bug alongside a look would be a regression. It renders the same INFORMATION as the modern branch, in its\n     own visual language:\n       1. the caller's subject is used as the heading when one was supplied. The old template hardcoded the\n          heading per type and rendered the subject for 'info' only, which is why a friendly title like\n          \"No connection\" showed up as the bare word \"Error\".\n       2. 'warning' and 'success' are handled. They did not exist when this markup was written, so they would\n          otherwise fall through every branch and render an empty dialog.\n       3. 'error' now has an icon; the reference line is no longer trapped in the error-only branch; and the\n          body renders real paragraphs instead of one collapsed run of text.\n     ⚠️ Anything added to the modern branch above has to be considered here too — that omission is exactly how\n     the three bugs in 3. got here. -->\n\n<ng-template #classic>\n  <div class=\"tin-msg-classic\">\n\n    <h2>\n      <div class=\"tin-between\">\n        <mat-label>{{ classicHeading }}</mat-label>\n        <!-- Added: the missing 'error' icon. Every other type had one; error — the type that most needs a cue —\n             rendered its heading beside empty flex space. Colour matches the modern branch's error accent\n             (#c62828) so the two presentations agree on what \"error\" looks like. -->\n        <mat-icon *ngIf=\"messageType=='error'\" style=\"color: #c62828;\">error</mat-icon>\n        <!-- Changed: a destructive confirm shows a red warning instead of the neutral question mark, matching the\n             modern branch. Same #c62828 as the error icon beside it, so the two styles agree on what danger looks\n             like. A plain confirm (\"Switch organisation?\") is unchanged. -->\n        <mat-icon *ngIf=\"messageType=='confirm' && destructive\" style=\"color: #c62828;\">warning</mat-icon>\n        <mat-icon *ngIf=\"messageType=='confirm' && !destructive\">question_mark</mat-icon>\n        <mat-icon *ngIf=\"messageType=='info'\" style=\"color: steelblue;\">info</mat-icon>\n        <mat-icon *ngIf=\"messageType=='warning'\" style=\"color: #ef6c00;\">warning</mat-icon>\n        <mat-icon *ngIf=\"messageType=='success'\" style=\"color: #2e7d32;\">check_circle</mat-icon>\n      </div>\n    </h2>\n\n    <mat-dialog-content>\n\n      <!-- Changed: was `{{ _messageDetails }}` rendered raw, so the blank-line-separated paragraphs the messages\n           are actually written in (api-error.service.ts) collapsed into one undifferentiated run of text. That\n           collapse is the original complaint that started WS-7 and it was still live here. Now renders the same\n           `paragraphs` split the modern branch uses — same information, classic's own plain markup. -->\n      <div *ngIf=\"messageType=='error'\">\n        <p class=\"tin-msg-classic__p\" *ngFor=\"let p of paragraphs\">{{ p }}</p>\n      </div>\n\n      <div *ngIf=\"messageType!='error'\" class=\"alert alert-secondary\" role=\"alert\">\n        <p class=\"tin-msg-classic__p\" *ngFor=\"let p of paragraphs\">{{ p }}</p>\n      </div>\n\n      <!-- Changed: lifted OUT of the error-only branch above. The reference is a correlation code, not an\n           error-specific field — a warning or info that carried one used to drop it silently. -->\n      <div class=\"tin-msg-classic__ref\" *ngIf=\"reference\">Reference: {{ reference }}</div>\n\n      <!-- Added (N22 / FSD-3): the classic branch's half of the typed-phrase gate. Added here DELIBERATELY and at\n           the same time as the modern one — the comment at the top of this template records that omitting classic\n           is exactly how three rendering bugs got here, and a gate that renders in one style but not the other\n           would be worse than a cosmetic miss: classic would show a phrase-gated confirm with a permanently\n           disabled Yes and no input to enable it, i.e. an unusable dialog. Classic's own plain markup, same\n           information. -->\n      <div class=\"tin-msg-classic__phrase\" *ngIf=\"requiresPhrase\">\n        <p class=\"tin-msg-classic__p\">To confirm, type <strong>{{ requiredPhrase }}</strong> below. This is case-sensitive.</p>\n        <mat-form-field class=\"tin-msg-classic__phrase-field\">\n          <input id=\"txtConfirmPhrase\" matInput type=\"text\" autocomplete=\"off\" spellcheck=\"false\" autocapitalize=\"off\" autocorrect=\"off\" [attr.aria-label]=\"'Type ' + requiredPhrase + ' to confirm'\" [value]=\"typedPhrase\" (input)=\"onPhraseInput($event)\" cdkFocusInitial>\n        </mat-form-field>\n      </div>\n\n    </mat-dialog-content>\n\n    <mat-dialog-actions>\n\n      <!-- Changed: same caller-supplied labels as the modern branch, defaulting identically to \"Yes\" / \"No\" /\n           \"OK\". Classic is expected to render the same INFORMATION as modern in its own visual language, so a\n           caller that names its action must be honoured here too — otherwise the next person to pass a label\n           would silently get \"Yes\" on every untracked consumer still running classic. Colours and ids untouched. -->\n      <!-- ⚠️ Changed: THE COLOUR NOW FOLLOWS THE ACTION, NOT THE BUTTON'S POSITION. This markup hardcoded\n           `color: green` on the affirmative button and `color: red` on the dismissive one. That mapping is only\n           correct while the buttons read \"Yes\" and \"No\" and the affirmative answer is the harmless one — the\n           green was never saying \"this is safe\", it was saying \"this is the Yes\". Name the action and the\n           assumption inverts: a confirm offering \"Keep\" / \"Delete\" rendered a GREEN Delete next to a RED Keep,\n           colouring the destructive action as the go-ahead and the safe one as the danger. That is the single\n           reason the labels and the colours had to ship as one change rather than two.\n           Destructive: affirmative red (#c62828, the same red the error icon uses), dismissive neutral — no\n           colour at all, so the red is the only thing on the dialog asking for attention.\n           Non-destructive: green/red exactly as before, byte for byte, for every caller that passes nothing.\n           ids btnYes / btnNo and the click handlers are untouched in both cases. -->\n      <!-- Changed (N22 / FSD-3): same [disabled]=\"confirmDisabled\" as the modern branch, false unless a phrase was demanded. -->\n      <!-- Changed (owner, 2026-08-18): the inline colour is dropped WHILE the button is disabled. This binding\n           sets the text colour with the specificity of an inline style, which outranks Material's disabled\n           treatment — so on a requirePhrase confirm the classic branch rendered a full-strength red \"Reset\n           Organisation\" that looked pressable over an empty input, the same defect the modern branch had.\n           Handing the colour back to null lets Material grey it natively; the moment the phrase is typed the\n           red returns. Colour still follows the ACTION, never the position, exactly as the note above requires. -->\n      <button id=\"btnYes\" mat-stroked-button [style.color]=\"confirmDisabled ? null : (destructive ? '#c62828' : 'green')\" *ngIf=\"isConfirm\" [disabled]=\"confirmDisabled\" (click)=\"response('yes')\" [attr.cdkFocusInitial]=\"destructive ? null : ''\">{{ confirmLabel }}</button>\n\n      <button id=\"btnNo\" mat-stroked-button [style.color]=\"destructive ? null : 'red'\" *ngIf=\"isConfirm\" (click)=\"response('no')\" [attr.cdkFocusInitial]=\"destructive ? '' : null\">{{ cancelLabel }}</button>\n\n      <button id=\"btnOK\" mat-stroked-button *ngIf=\"!isConfirm\" color=\"primary\" (click)=\"response('ok')\" cdkFocusInitial>{{ okLabel }}</button>\n\n    </mat-dialog-actions>\n\n  </div>\n</ng-template>\n","import { Injectable } from \"@angular/core\";\nimport { MatSnackBar } from \"@angular/material/snack-bar\";\nimport { MatDialog } from \"@angular/material/dialog\";\nimport { messageDialog } from \"../components/message/messageDialog.component\";\nimport { Observable, of } from 'rxjs';\nimport { mergeMap } from 'rxjs/operators';\n\n@Injectable({\n  providedIn: \"root\",\n})\nexport class MessageService {\n  constructor(private snackBar: MatSnackBar, public dialog: MatDialog) { }\n\n  public toast(msg: string) {\n    this.snackBar.open(msg, \"OK\", { duration: 5000 });\n  }\n\n  public info(details: string) {\n\n    let type = \"info\";\n\n    const dialogRef = this.dialog.open(messageDialog, {\n      width: \"600px\",\n      data: { type, details },\n    });\n\n  }\n\n  public infoWithSubject(subject: string, details: string) {\n\n    let type = \"info\";\n\n    const dialogRef = this.dialog.open(messageDialog, {\n      width: \"600px\",\n      data: { type, subject, details },\n    });\n\n  }\n\n  public error(details: string) {\n\n    let type = \"error\";\n    // Changed: was `let subject: \"\";` — a type annotation with no initialiser, so `subject` was always\n    // undefined and the dialog rendered with no heading. Now an explicit empty string.\n    let subject = \"\";\n\n    // Changed: guard against an empty body. Callers used to pass `error.error.Message`, which is undefined\n    // whenever the response has no JSON body (a downed backend gives a ProgressEvent), producing a dialog\n    // that said nothing at all. A generic line is always better than a blank box.\n    const body = details && String(details).trim() ? details : \"Something went wrong. Please try again, and contact your administrator if it keeps happening.\";\n\n    const dialogRef = this.dialog.open(messageDialog, {\n      width: \"600px\",\n      data: { type, subject, details: body },\n    });\n\n  }\n\n  // Added: error dialog with a heading, so a friendly title (\"No connection\") can sit above the explanation.\n  // Changed: optional `reference` — the backend's correlation code for this failure, rendered as a quiet line\n  // under the body rather than mixed into it. Optional and last, so every existing two-argument call is\n  // unaffected and simply renders no reference line.\n  public errorWithSubject(subject: string, details: string, reference?: string) {\n\n    let type = \"error\";\n\n    const dialogRef = this.dialog.open(messageDialog, {\n      width: \"600px\",\n      data: { type, subject, details, reference },\n    });\n\n  }\n\n  // Added: warning — for something the user should look at but which is not a failure. Distinct from error so\n  // a recoverable situation is not dressed up in the same red as a broken one.\n  public warning(details: string, subject?: string) {\n\n    let type = \"warning\";\n\n    const dialogRef = this.dialog.open(messageDialog, {\n      width: \"600px\",\n      data: { type, subject, details },\n    });\n\n  }\n\n  // Added: success — completes the set, so a confirmation does not have to borrow the 'info' styling.\n  public success(details: string, subject?: string) {\n\n    let type = \"success\";\n\n    const dialogRef = this.dialog.open(messageDialog, {\n      width: \"600px\",\n      data: { type, subject, details },\n    });\n\n  }\n\n  // Changed: optional `confirmLabel` / `cancelLabel`, appended last so all 23 existing call sites are unaffected\n  // and keep rendering \"Yes\" / \"No\". Supply confirmLabel to name the action being confirmed — confirm('Delete this\n  // shelter?', 'Delete') — so a destructive prompt stops reading identically to a harmless one. Only the caller\n  // knows the intent; the dialog is handed a sentence.\n  // ⚠️ Do NOT change the defaults to make every confirm read better: piglet-spa (38) and shift-spa (13) select\n  // these buttons by their literal text via getByRole('button', { name: 'Yes' }), and the owner reverted a\n  // hardcoded relabel on 2026-08-06. Opt in per call site.\n  // Changed: optional `destructive`, appended last so every existing call — including the three-argument ones\n  // added with the labels — is unaffected. It drives COLOUR only: the affirmative button turns warn-red and the\n  // dismissive one goes neutral, because the classic style hardcodes green on the affirmative button and a\n  // GREEN \"Delete\" beside a RED \"Keep\" tells the user precisely the opposite of the truth.\n  // Added (N22 / FSD-3): optional `requirePhrase`, appended LAST so all existing call sites — including the\n  // three- and four-argument ones added with the labels and the destructive flag — are untouched and keep\n  // behaving identically. Supply it and the dialog grows an input, and the affirmative button stays DISABLED\n  // until the typed text ordinally equals the phrase (see phraseSatisfied in messageDialog.component.ts).\n  //\n  // 🔴 THE RETURN SHAPE CHANGES ONLY WHEN YOU PASS A PHRASE. Without it, afterClosed still emits the bare\n  // 'yes' / 'no' STRING every caller has always received. WITH a phrase, it emits { response, phrase } instead,\n  // because the caller has to forward the TYPED TEXT to the server, which re-validates it independently\n  // (TinWeb AppConfigurationControllerBase.cs:159) — the browser gate is UX only and any direct API caller\n  // never sees it. Since only a new opt-in caller can pass a phrase, no existing `result === 'yes'` check\n  // anywhere — in this repo, in the 51 E2E assertions, or in an untracked consumer app — can be affected.\n  public confirm(msg: string, confirmLabel?: string, cancelLabel?: string, destructive?: boolean, requirePhrase?: string): Observable<any> {\n\n    let type = \"confirm\";\n    let subject = \"\";\n    let details = msg\n\n    const dialogRef = this.dialog.open(messageDialog, {\n      width: \"400px\",\n      data: { type, subject, details, confirmLabel, cancelLabel, destructive, requirePhrase },\n      disableClose: !!requirePhrase, // Added: a phrase-gated confirm should not be dismissible by a stray backdrop click mid-typing; the No button is still the way out\n    });\n\n    return dialogRef.afterClosed().pipe(mergeMap((result) => {\n\n      return of(result);\n\n    }\n\n    ));\n\n  }\n\n\n}\n","import { Injectable } from '@angular/core';\n// import * as FileSaver from 'file-saver';\n// import * as XLSX from 'xlsx';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class ExportService {\n\n  constructor() { }\n\n  // fileType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';\n  // fileExtension = '.xlsx';\n\n  // public exportExcel(jsonData: any[], fileName: string): void {\n\n  //   const ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet(jsonData);\n  //   const wb: XLSX.WorkBook = { Sheets: { 'data': ws }, SheetNames: ['data'] };\n  //   const excelBuffer: any = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });\n  //   this.saveExcelFile(excelBuffer, fileName);\n  // }\n\n  // private saveExcelFile(buffer: any, fileName: string): void {\n  //   const data: Blob = new Blob([buffer], { type: this.fileType });\n  //   FileSaver.saveAs(data, fileName + this.fileExtension);\n  // }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class LoaderService {\n\n  public isLoading = new BehaviorSubject(false);\n  constructor() { }\n}\n","// InjectionToken for the default details dialog component\n// This breaks the circular dependency by allowing components to use the dialog without importing it directly\nimport { InjectionToken } from '@angular/core';\n\nexport const DETAILS_DIALOG_COMPONENT = new InjectionToken<any>('DetailsDialogComponent');\n\n// Added: same treatment for the import wizard. Its review step now renders a spa-table, so a direct\n// import in DialogService would close the cycle import-dialog -> table -> dialog.service -> import-dialog,\n// which ng-packagr's partial compilation cannot resolve via remote scoping (NG3003).\nexport const IMPORT_DIALOG_COMPONENT = new InjectionToken<any>('ImportDialogComponent');\n\n// Added: same treatment again for the read-only table dialog. spa-table-dialog renders a spa-table, so a direct\n// import in DialogService would close the identical cycle table-dialog -> table -> dialog.service -> table-dialog\n// (NG3003). The wizard above is the precedent, not a coincidence: ANY component hosting spa-table must arrive here.\nexport const TABLE_DIALOG_COMPONENT = new InjectionToken<any>('TableDialogComponent');\n","// DocumentService — the authorized fetch half of the document pipeline.\n//\n// Every document byte in the estate comes through here, and here goes through the app's own API. Documents\n// used to be fetched browser-direct from an Azure container marked PublicAccessType.Blob: world-readable by\n// URL, no capability check, no audit, no tenant scoping. The server side of that hole is closed (the\n// authorized stream GET <entity>/document/{id}/{fileName}); this is the client that consumes it.\n//\n// Three things it is responsible for, and nothing else — rendering belongs to the viewer components:\n//   1. Fetching a document's bytes with the bearer token attached (via HttpService -> LoaderInterceptor).\n//   2. Saying what kind of document it is, so the right renderer mounts.\n//   3. Object-URL LIFECYCLE. Every URL it hands out is tracked and must be released; an unrevoked object URL\n//      pins its entire blob in memory for the lifetime of the document, so a long viewing session leaks.\n\nimport { Injectable, OnDestroy } from '@angular/core';\nimport { HttpErrorResponse, HttpResponse } from '@angular/common/http';\nimport { Observable, from, of, throwError } from 'rxjs';\nimport { catchError, map, switchMap } from 'rxjs/operators';\nimport { HttpService } from './http.service';\nimport { silentContext } from '../runtime/silent-request';\nimport { DocumentKind, DocumentError, LoadedDocument } from '../classes/DocumentClasses';\n\n// Extension -> kind. Mirrors the server's Web.ContentTypeFor list so the two cannot disagree about what is\n// renderable. Legacy binary .doc/.xls are deliberately NOT 'word'/'excel': mammoth and SheetJS cannot read\n// OLE2, so claiming they are renderable would produce a broken stage instead of an honest fallback.\nconst KIND_BY_EXTENSION: { [extension: string]: DocumentKind } = {\n  pdf: 'pdf',\n  jpg: 'image', jpeg: 'image', png: 'image', gif: 'image', webp: 'image', bmp: 'image',\n  docx: 'word',\n  xlsx: 'excel',\n  txt: 'text', csv: 'text',\n  doc: 'unsupported', xls: 'unsupported'\n};\n\n@Injectable({ providedIn: 'root' })\nexport class DocumentService implements OnDestroy {\n\n  constructor(private http: HttpService) { }\n\n  // Every object URL this service has created and not yet revoked.\n  private issuedUrls = new Set<string>();\n\n  // Fetches one document's bytes from the authorized stream and wraps them in an object URL.\n  // Errors with a DocumentError — never with a bare HttpErrorResponse and never silently, because a viewer\n  // that renders an empty stage on a refusal looks exactly like a broken document.\n  fetchDocument(streamUrl: string, fileName: string, silent = true): Observable<LoadedDocument> {\n\n    // Silent by default: the viewer shows its own skeleton while streaming, so raising the global scrim over\n    // the whole app for a document fetch would be a second, contradictory loading indicator.\n    const context = silentContext(silent);\n\n    return this.http.Get_Blob(streamUrl, context).pipe(\n      map((response: HttpResponse<Blob>) => this.toLoadedDocument(response, fileName)),\n      catchError((error: HttpErrorResponse) => this.toDocumentError(error, fileName).pipe(\n        switchMap((documentError: DocumentError) => throwError(() => documentError))\n      ))\n    );\n  }\n\n  // Substitutes {placeholders} into a stream/list URL from a value bag, reusing the pattern established at\n  // viewer.component.ts:45-53. An unmatched placeholder is left ALONE rather than blanked, so a\n  // misconfiguration shows up as a visible 404 on a literal '{keyField}' instead of silently collapsing to a\n  // URL that addresses the wrong row.\n  resolveUrl(template: string, values: { [key: string]: any }): string {\n    if (!template) {\n      return '';\n    }\n\n    if (template.indexOf('{') < 0) {\n      return template;\n    }\n\n    return template.replace(/\\{(\\w+)\\}/g, (match, name) => {\n      const value = values ? values[name] : undefined;\n      // Each segment is encoded: a file name legitimately contains spaces, '#' and '&', all of which would\n      // otherwise truncate or corrupt the path.\n      return value !== undefined && value !== null && value !== '' ? encodeURIComponent(String(value)) : match;\n    });\n  }\n\n  // What renderer does this file need? Driven by extension, because the stream's declared content type comes\n  // from the same server-side extension map — asking the byte stream would not be independent evidence.\n  kindFor(fileName: string): DocumentKind {\n    if (!fileName || typeof fileName !== 'string') {\n      return 'unsupported';\n    }\n\n    const dot = fileName.lastIndexOf('.');\n    if (dot < 0 || dot === fileName.length - 1) {\n      return 'unsupported';\n    }\n\n    return KIND_BY_EXTENSION[fileName.substring(dot + 1).toLowerCase()] ?? 'unsupported';\n  }\n\n  // Releases ONE object URL. Safe to call twice — the second call is a no-op rather than an error, because a\n  // viewer that both swaps a document and is then destroyed would otherwise double-revoke.\n  release(objectUrl: string): void {\n    if (!objectUrl || !this.issuedUrls.has(objectUrl)) {\n      return;\n    }\n\n    URL.revokeObjectURL(objectUrl);\n    this.issuedUrls.delete(objectUrl);\n  }\n\n  // Releases every outstanding object URL. The viewer calls this on destroy; the service calls it on its own\n  // teardown as the backstop.\n  releaseAll(): void {\n    this.issuedUrls.forEach(url => URL.revokeObjectURL(url));\n    this.issuedUrls.clear();\n  }\n\n  // True while an object URL is still live. Exists for the specs — leaks are otherwise unobservable.\n  isIssued(objectUrl: string): boolean {\n    return this.issuedUrls.has(objectUrl);\n  }\n\n  private toLoadedDocument(response: HttpResponse<Blob>, fileName: string): LoadedDocument {\n    const blob = response.body ?? new Blob([]);\n    const objectUrl = URL.createObjectURL(blob);\n    this.issuedUrls.add(objectUrl);\n\n    return {\n      fileName: fileName,\n      kind: this.kindFor(fileName),\n      // The server sends an explicit content type alongside X-Content-Type-Options: nosniff. Fall back to the\n      // blob's own type, then to octet-stream — never guess a renderable type we were not told.\n      contentType: response.headers?.get('Content-Type') ?? blob.type ?? 'application/octet-stream',\n      size: blob.size,\n      objectUrl: objectUrl,\n      blob: blob\n    };\n  }\n\n  // 🔴 Branches on HTTP STATUS, not on response.Success. The stream's success body is raw bytes rather than a\n  // RepoResponse, so there is no Success flag to read — and a 200 carrying refusal JSON would be\n  // indistinguishable from a 200 carrying a PDF.\n  //\n  // The refusal body is JSON but arrives as a BLOB, because the request asked for responseType 'blob' and\n  // that applies to the error body too. Reading it therefore takes an async text() decode, which is why this\n  // returns an Observable rather than a plain value.\n  private toDocumentError(error: HttpErrorResponse, fileName: string): Observable<DocumentError> {\n    const status = error?.status ?? 0;\n\n    const reason: DocumentError['reason'] =\n      status === 403 ? 'denied' :\n      status === 404 ? 'missing' :\n      status === 401 ? 'unauthenticated' :\n      status === 0 ? 'network' : 'failed';\n\n    const fallback =\n      reason === 'denied' ? 'You do not have permission to view this document.' :\n      reason === 'missing' ? 'Document not found' :\n      reason === 'unauthenticated' ? 'Please sign in to view this document.' :\n      reason === 'network' ? 'Could not reach the server to load this document.' :\n      'This document could not be loaded.';\n\n    return this.serverMessage(error).pipe(\n      map((message: string | null) => ({\n        status: status,\n        reason: reason,\n        message: message && message.trim() !== '' ? message : fallback,\n        fileName: fileName\n      }))\n    );\n  }\n\n  // Recovers the server's own RepoResponse.Message out of the blob error body. Returns null on anything\n  // unexpected so the caller uses its phrased fallback — a decode failure must never become the user's\n  // error message.\n  private serverMessage(error: HttpErrorResponse): Observable<string | null> {\n    const body = error?.error;\n\n    if (!(body instanceof Blob) || body.size === 0) {\n      return of(typeof body?.Message === 'string' ? body.Message : null);\n    }\n\n    return from(body.text()).pipe(\n      map((text: string) => {\n        try {\n          const parsed = JSON.parse(text);\n          return typeof parsed?.Message === 'string' ? parsed.Message\n            : typeof parsed?.message === 'string' ? parsed.message : null;\n        } catch {\n          return null;\n        }\n      }),\n      catchError(() => of(null))\n    );\n  }\n\n  ngOnDestroy(): void {\n    this.releaseAll();\n  }\n}\n","// The full-bleed document viewer.\n//\n// It replaces viewerDialog, which rendered a 60vh iframe inside a dialog whose own sizing contradicted\n// itself (minWidth 95% AND maxWidth 80vw — the max wins), always drew a document-picker column even when\n// there was exactly one document, resolved URLs through ./assets/ or a PUBLIC Azure container, and\n// window.open()-downloaded anything that was not a PDF or a JPEG.\n//\n// Structure follows mapDialog.component, which is this house's existing answer to the same brief: no\n// mat-dialog-title, no mat-dialog-content, no mat-dialog-actions. Those three bands were the bezel problem.\n// The panel padding reset lives in tin-styles.css under .spa-doc-viewer-panel, because Material renders the\n// dialog panel into an overlay container OUTSIDE this component's view encapsulation.\n//\n// 🔴 OBJECT-URL LIFECYCLE IS THIS COMPONENT'S RESPONSIBILITY. Every URL DocumentService hands out pins its\n// entire blob in memory until it is revoked, and the leak is invisible in the browser. The rule here:\n// release the outgoing document on every swap, releaseAll() on destroy.\n\nimport { Component, Inject, HostListener, OnInit, OnDestroy, ChangeDetectorRef, SecurityContext } from '@angular/core';\nimport { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { DocumentService } from '../../services/document.service';\nimport { DocumentKind, DocumentError, LoadedDocument, DocumentViewerData } from '../../classes/DocumentClasses';\n// Type-only imports. `import type` is ERASED at compile time and emits no require/import, so it does NOT\n// pull mammoth or exceljs into this chunk — the runtime import stays the dynamic one inside loadRenderer().\nimport type { ExcelSheet } from './renderers/excelRenderer';\n\n// How the image renderer is currently sized. 'fit' shows the whole page, 'width' fills the stage\n// horizontally (the reading default for tall scans), 'actual' is 1:1.\ntype ZoomMode = 'fit' | 'width' | 'actual';\n\n@Component({\n  selector: 'spa-document-viewer-dialog',\n  templateUrl: './documentViewerDialog.component.html',\n  styleUrls: ['./documentViewerDialog.component.css'],\n  standalone: false\n})\nexport class DocumentViewerDialogComponent implements OnInit, OnDestroy {\n\n  constructor(\n    public dialogRef: MatDialogRef<DocumentViewerDialogComponent>,\n    private documentService: DocumentService,\n    private sanitizer: DomSanitizer,\n    private cdr: ChangeDetectorRef,\n    @Inject(MAT_DIALOG_DATA) public data: DocumentViewerData\n  ) { }\n\n  // 🔴 THE PICKER RULE. Bound with *ngIf, so at one document the rail is not in the DOM at all. CSS-hiding\n  // it would still leave its box in the layout and would still be found by anything walking the tree.\n  showPicker = false;\n\n  documents: string[] = [];\n  index = 0;\n  title = '';\n  downloadable = true;\n\n  // A plain field rather than a getter — template-bound getters that allocate are banned in this library\n  // (they caused a real livelock).\n  // Changed: 'fallback' added as a state of its own. It used to be inferred in the template as\n  // \"ready AND not pdf AND not image\", which stopped being true the moment word and excel became renderable\n  // and would have silently swallowed a FAILED word/excel render into the same panel as a legacy .doc.\n  state: 'loading' | 'ready' | 'fallback' | 'error' | 'empty' = 'loading';\n\n  fileName = '';\n  kind: DocumentKind = 'unsupported';\n\n  // Set alongside `kind` at load time, never derived in the template — the toolbar used to hard-code a\n  // two-way ternary that called everything that was not an image a PDF.\n  icon = 'description';\n\n  objectUrl = '';\n  safeUrl: SafeResourceUrl = null;\n  sizeLabel = '';\n\n  // The toolbar's second line, assembled once per load. A plain field, never a getter — see the ban on\n  // template-bound allocating getters in this library.\n  meta = '';\n\n  // Changed: the skeleton's caption. Loading a 4 MB spreadsheet has two distinct waits — the stream, then the\n  // parse — and a caption that still says \"Loading\" through a five-second parse reads as a hang.\n  stageLabel = '';\n\n  // Word. 🔴 ALREADY SANITIZED by the time it is assigned — see renderWordDocument(). It is bound with\n  // [innerHTML], which sanitizes again; both, deliberately, because the source is an uploaded file.\n  wordHtml = '';\n  wordWarnings: string[] = [];\n\n  // Excel.\n  sheets: ExcelSheet[] = [];\n  activeSheet = 0;\n  sheetTruncated = false;\n\n  // The honest fallback panel, now reached for two DIFFERENT reasons that must not read the same: a legacy\n  // format nothing can render inline (.doc/.xls — expected, not a fault), and a renderer that tried and\n  // failed (unexpected — say so rather than implying the format is unsupported).\n  fallbackTitle = '';\n  fallbackText = '';\n\n  errorTitle = '';\n  errorMessage = '';\n  errorIcon = 'error_outline';\n\n  zoom: ZoomMode = 'fit';\n  toolbarVisible = true;\n\n  private hideTimer: any = null;\n  private loadToken = 0;\n\n  ngOnInit(): void {\n    this.documents = (this.data?.documents ?? []).filter(name => typeof name === 'string' && name.trim() !== '');\n    this.title = this.data?.title ?? '';\n    this.downloadable = this.data?.downloadable !== false;\n    this.showPicker = this.documents.length > 1;\n\n    if (this.documents.length === 0) {\n      this.state = 'empty';\n      return;\n    }\n\n    const requested = this.documents.indexOf(this.data?.fileName ?? '');\n    this.load(requested >= 0 ? requested : 0);\n    this.armAutoHide();\n  }\n\n  // Fetches one document through the authorized stream. Everything the stage renders is set here rather\n  // than derived in the template, so a change-detection pass never re-computes or re-allocates it.\n  load(next: number): void {\n    if (next < 0 || next >= this.documents.length) return;\n\n    // The outgoing document's object URL goes NOW, not when the new one arrives — a fast click through a\n    // ten-document set would otherwise hold ten blobs at once.\n    this.releaseCurrent();\n\n    this.index = next;\n    this.fileName = this.documents[next];\n    this.kind = this.documentService.kindFor(this.fileName);\n    this.icon = iconFor(this.kind);\n    this.state = 'loading';\n    this.stageLabel = 'Loading ' + this.fileName;\n    this.zoom = 'fit';\n    this.resetRendered();\n\n    // Guards against an out-of-order response: a slow first document must not overwrite the stage after\n    // the user has already moved on to a second one.\n    const token = ++this.loadToken;\n\n    const url = this.documentService.resolveUrl(this.data.streamUrl, { ...(this.data.values ?? {}), fileName: this.fileName });\n\n    this.documentService.fetchDocument(url, this.fileName).subscribe({\n      next: (document: LoadedDocument) => {\n        if (token !== this.loadToken) { this.documentService.release(document.objectUrl); return; }\n        this.objectUrl = document.objectUrl;\n        this.kind = document.kind;\n        this.icon = iconFor(this.kind);\n        this.sizeLabel = formatSize(document.size);\n        this.meta = buildMeta(this.title, this.index, this.documents.length, this.sizeLabel);\n        // <object data> is a RESOURCE_URL context, which Angular will not accept unsanitized even for a\n        // blob: URL this component created itself moments ago. Bypassed once per load, never in a getter.\n        this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(document.objectUrl);\n\n        // Changed: PDF and image are ready the moment the bytes are here. Word and Excel need a second,\n        // asynchronous step — fetching the renderer chunk and parsing — so they stay in 'loading' with a\n        // different caption rather than flashing an empty stage.\n        if (document.kind === 'word' || document.kind === 'excel') {\n          this.loadRenderer(document, token);\n        } else if (document.kind === 'pdf' || document.kind === 'image') {\n          this.state = 'ready';\n        } else {\n          this.showFallback('This format cannot be shown inline',\n            legacyOf(this.fileName)\n              ? `${this.fileName} is in the older ${legacyOf(this.fileName)} format, which no browser can render. Save a copy to open it in Word or Excel.`\n              : `${this.fileName} has no inline preview. You can still save a copy.`);\n        }\n\n        this.cdr.markForCheck();\n      },\n      error: (failure: DocumentError) => {\n        if (token !== this.loadToken) return;\n        this.showError(failure);\n        this.cdr.markForCheck();\n      }\n    });\n  }\n\n  // 🔴 THE LAZY-LOAD SEAM, AND THE WHOLE REASON PHASE 5 IS SHAPED THIS WAY.\n  //\n  // These two `import()` calls are the ONLY references to the renderer files anywhere in the library, which\n  // is what lets the bundler split them — and mammoth (~200 KB) and exceljs (~1 MB) with them — into chunks\n  // that are fetched the first time somebody opens a .docx or an .xlsx and never otherwise. The regression\n  // this prevents is recorded at tin-spa.module.ts:42: ngx-doc-viewer shipped mammoth into the INITIAL\n  // bundle of every consumer app, including the three that have never rendered a Word document.\n  //\n  // Consequences, so nobody \"tidies\" them away:\n  //   · The renderers are FUNCTIONS, not Angular components. A non-standalone component must be listed in\n  //     tin-spa.module.ts `declarations`, which is a static import, which undoes all of the above.\n  //   · `import type { ExcelSheet }` at the top of this file is erased at compile time and emits nothing.\n  //     Turning it into a value import would statically bind the chunk and silently re-merge it.\n  private loadRenderer(loaded: LoadedDocument, token: number): void {\n    this.stageLabel = loaded.kind === 'excel' ? 'Reading the workbook' : 'Preparing the document';\n\n    const rendered = loaded.kind === 'word'\n      ? import('./renderers/wordRenderer').then(module => module.renderWord(loaded.blob).then(result => () => this.applyWord(result)))\n      : import('./renderers/excelRenderer').then(module => module.renderExcel(loaded.blob).then(result => () => this.applyExcel(result)));\n\n    rendered.then(apply => {\n      // The same out-of-order guard the fetch uses. A slow 4 MB workbook must not paint over a document the\n      // user has already moved past — and this path is SLOWER than the fetch, so the window is wider.\n      if (token !== this.loadToken) return;\n      apply();\n      this.cdr.markForCheck();\n    }).catch(failure => {\n      if (token !== this.loadToken) return;\n      // A renderer that throws is NOT the same thing as a format we never supported, and the panel must not\n      // claim it is. A corrupt or password-protected file lands here.\n      this.showFallback('This document could not be read',\n        `${this.fileName} could not be opened for preview${failure?.message ? ' (' + failure.message + ')' : ''}. Save a copy to open it in its own application.`);\n      this.cdr.markForCheck();\n    });\n  }\n\n  private applyWord(result: { html: string; warnings: string[]; hasContent: boolean }): void {\n    if (!result.hasContent) {\n      this.showFallback('Nothing to preview', `${this.fileName} converted to an empty document — it may contain only images or embedded objects. Save a copy to see it in full.`);\n      return;\n    }\n\n    // 🔴 EXPLICIT SANITISATION of HTML derived from an uploaded file. `sanitize` STRIPS script tags, event\n    // handler attributes and javascript: URLs and returns the safe remainder — it is the opposite of\n    // bypassSecurityTrustHtml, which is what a careless reading of \"pass it through DomSanitizer\" produces.\n    // [innerHTML] sanitizes a second time in the template; that is belt and braces, not redundancy to remove.\n    this.wordHtml = this.sanitizer.sanitize(SecurityContext.HTML, result.html) ?? '';\n    this.wordWarnings = result.warnings;\n    this.state = 'ready';\n  }\n\n  private applyExcel(result: { sheets: ExcelSheet[]; hasContent: boolean }): void {\n    if (!result.hasContent) {\n      this.showFallback('Nothing to preview', `${this.fileName} has no readable cells. Save a copy to open it in Excel.`);\n      return;\n    }\n\n    this.sheets = result.sheets;\n    this.activeSheet = 0;\n    this.sheetTruncated = result.sheets[0]?.truncated === true;\n    this.state = 'ready';\n  }\n\n  selectSheet(index: number): void {\n    if (index < 0 || index >= this.sheets.length) return;\n    this.activeSheet = index;\n    this.sheetTruncated = this.sheets[index].truncated;\n    this.wake();\n  }\n\n  private showFallback(title: string, text: string): void {\n    this.state = 'fallback';\n    this.fallbackTitle = title;\n    this.fallbackText = text;\n  }\n\n  private resetRendered(): void {\n    this.wordHtml = '';\n    this.wordWarnings = [];\n    this.sheets = [];\n    this.activeSheet = 0;\n    this.sheetTruncated = false;\n    this.fallbackTitle = '';\n    this.fallbackText = '';\n  }\n\n  next(): void { if (this.documents.length > 1) this.load((this.index + 1) % this.documents.length); }\n  previous(): void { if (this.documents.length > 1) this.load((this.index - 1 + this.documents.length) % this.documents.length); }\n\n  setZoom(mode: ZoomMode): void { this.zoom = mode; }\n\n  close(): void { this.dialogRef.close(); }\n\n  // Saves the blob that is ALREADY in memory. It deliberately does not re-request anything: the object URL\n  // is the only handle to these bytes the browser is ever given.\n  download(): void {\n    if (!this.objectUrl) return;\n\n    const link = document.createElement('a');\n    link.href = this.objectUrl;\n    link.download = this.fileName;\n    link.click();\n  }\n\n  // A designed refusal, never a blank stage. An empty stage on a 403 is indistinguishable from a broken\n  // document, which is the exact silent-failure shape this codebase keeps producing.\n  private showError(failure: DocumentError): void {\n    this.state = 'error';\n    this.objectUrl = '';\n    this.safeUrl = null;\n\n    this.errorTitle =\n      failure?.reason === 'denied' ? 'You cannot open this document' :\n      failure?.reason === 'missing' ? 'This document is no longer here' :\n      failure?.reason === 'unauthenticated' ? 'Your session has ended' :\n      failure?.reason === 'network' ? 'The server could not be reached' :\n      'This document could not be opened';\n\n    // The server's OWN words, when it sent any. DocumentService already prefers them over its fallbacks.\n    this.errorMessage = failure?.message ?? '';\n\n    this.errorIcon =\n      failure?.reason === 'denied' ? 'lock' :\n      failure?.reason === 'missing' ? 'search_off' :\n      failure?.reason === 'unauthenticated' ? 'person_off' :\n      failure?.reason === 'network' ? 'cloud_off' : 'error_outline';\n  }\n\n  retry(): void { this.load(this.index); }\n\n  @HostListener('document:keydown', ['$event'])\n  onKey(event: KeyboardEvent): void {\n    if (event.key === 'ArrowRight') { this.next(); this.wake(); }\n    else if (event.key === 'ArrowLeft') { this.previous(); this.wake(); }\n    // Changed: Escape is handled HERE rather than left to Material's overlay dispatcher. Measured in the\n    // browser: with a PDF on the stage, Escape did NOT close the dialog. The browser's built-in PDF viewer\n    // inside <object> is a separate embedded document, so focus sits outside the CDK overlay and the\n    // dispatcher never sees the key. close() on a dialog that Material also closes is a no-op, so handling\n    // it in both places is safe.\n    else if (event.key === 'Escape') { this.close(); }\n  }\n\n  // The toolbar recedes while the document is being read and returns the moment the pointer moves. It is\n  // never hidden while the stage is not showing a document — a floating bar is the only chrome an error\n  // or empty state has.\n  wake(): void {\n    this.toolbarVisible = true;\n    this.armAutoHide();\n  }\n\n  holdToolbar(): void {\n    if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; }\n    this.toolbarVisible = true;\n  }\n\n  private armAutoHide(): void {\n    if (this.hideTimer) clearTimeout(this.hideTimer);\n\n    // 🔴 NEVER auto-hide over a PDF. Measured in the browser: the toolbar hid on idle and then would NOT\n    // come back, because the browser's own PDF viewer inside <object> is a separate embedded document that\n    // swallows pointer events — no mousemove ever reaches this component, so the only chrome (including\n    // Close) was gone for good. The PDF renderer carries its own toolbar anyway; ours stays put beside it.\n    if (this.kind === 'pdf') { this.toolbarVisible = true; return; }\n\n    this.hideTimer = setTimeout(() => {\n      if (this.state === 'ready') {\n        this.toolbarVisible = false;\n        this.cdr.markForCheck();\n      }\n    }, 2800);\n  }\n\n  private releaseCurrent(): void {\n    if (this.objectUrl) this.documentService.release(this.objectUrl);\n    this.objectUrl = '';\n    this.safeUrl = null;\n  }\n\n  ngOnDestroy(): void {\n    if (this.hideTimer) clearTimeout(this.hideTimer);\n    // Backstop as well as the swap-time release: a dialog closed mid-fetch still has a URL outstanding.\n    this.documentService.releaseAll();\n  }\n}\n\n// Joins only the parts that exist, so a single untitled document does not print stray separators. Exported\n// so a spec can pin the single-document case, which is the one the fragment version got wrong.\nexport function buildMeta(title: string, index: number, count: number, sizeLabel: string): string {\n  const parts: string[] = [];\n  if (title) parts.push(title);\n  if (count > 1) parts.push(`${index + 1} of ${count}`);\n  if (sizeLabel) parts.push(sizeLabel);\n  return parts.join(' · ');\n}\n\n// The older binary Office formats, named so the fallback panel can say WHICH one rather than the useless\n// \"unsupported\". Returns null for anything else. Exported for the specs.\nexport function legacyOf(fileName: string): string | null {\n  const lower = (fileName ?? '').toLowerCase();\n  if (lower.endsWith('.doc')) return 'Word 97-2003 (.doc)';\n  if (lower.endsWith('.xls')) return 'Excel 97-2003 (.xls)';\n  return null;\n}\n\n// The toolbar's document glyph. A field set at load time would need resetting in five places; this is a\n// pure function of one argument called once per kind, and the template calls it on a plain field — it\n// allocates nothing, which is what the ban on template-bound getters is actually about.\nexport function iconFor(kind: DocumentKind): string {\n  if (kind === 'image') return 'image';\n  if (kind === 'word') return 'article';\n  if (kind === 'excel') return 'table_chart';\n  if (kind === 'pdf') return 'picture_as_pdf';\n  return 'description';\n}\n\n// Exported for the specs. Kept out of the template — a getter that formats on every change-detection pass\n// is exactly the allocating-getter pattern this library banned.\nexport function formatSize(bytes: number): string {\n  if (!bytes || bytes < 0) return '';\n  if (bytes < 1024) return bytes + ' B';\n  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(0) + ' KB';\n  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';\n}\n","<!-- No mat-dialog-title, no mat-dialog-content, no mat-dialog-actions. The document IS the dialog.\n     Those three bands cost ~140px of vertical chrome in the component this replaces, around an iframe that\n     was itself hard-capped at 60vh. The only chrome here floats ON the stage. -->\n<div class=\"spa-doc\" (mousemove)=\"wake()\">\n\n  <!-- THE STAGE. Dark by design in both themes: a document reader makes the page the bright focal object\n       and lets everything around it recede. This is the one surface that does not follow the app theme. -->\n  <div class=\"spa-doc-stage\">\n\n    <!-- Loading. A skeleton shaped like a page, not a spinner in a void — it tells you what is coming. -->\n    <div class=\"spa-doc-skeleton\" *ngIf=\"state === 'loading'\">\n      <div class=\"spa-doc-sheet-ghost\">\n        <span class=\"spa-doc-line spa-doc-line-title\"></span>\n        <span class=\"spa-doc-line\"></span>\n        <span class=\"spa-doc-line\"></span>\n        <span class=\"spa-doc-line spa-doc-line-short\"></span>\n        <span class=\"spa-doc-line\"></span>\n        <span class=\"spa-doc-line spa-doc-line-short\"></span>\n      </div>\n      <!-- Changed: the caption is a field now. A .xlsx has two waits — the stream, then fetching the renderer\n           chunk and parsing it — and a caption still reading \"Loading\" through a five-second parse looks like\n           a hang. It says \"Reading the workbook\" for the second one. -->\n      <p class=\"spa-doc-skeleton-label\">{{ stageLabel }}</p>\n    </div>\n\n    <!-- PDF. <object> on an object URL, so the browser's own viewer renders it with no pdf.js bundle, no\n         public URL and no CSP argument. <embed> is the fallback for engines that ignore <object>. -->\n    <div class=\"spa-doc-pdf\" *ngIf=\"state === 'ready' && kind === 'pdf'\">\n      <object [data]=\"safeUrl\" type=\"application/pdf\" class=\"spa-doc-object\">\n        <!-- safeUrl, NOT the raw objectUrl. [attr.src] on <embed> is a RESOURCE_URL context too, and Angular\n             rejects a raw string there — measured in the browser as\n             \"NG0904: unsafe value used in a resource URL context\" on every PDF open. The <object> above still\n             rendered, so the only visible symptom was a console error, which is exactly how it would have\n             shipped unnoticed. -->\n        <embed [attr.src]=\"safeUrl\" type=\"application/pdf\" class=\"spa-doc-object\" />\n      </object>\n    </div>\n\n    <!-- Images. The stage scrolls when the image is larger than it; the sheet keeps the page metaphor. -->\n    <div class=\"spa-doc-image-wrap\" *ngIf=\"state === 'ready' && kind === 'image'\"\n         [class.spa-doc-zoom-fit]=\"zoom === 'fit'\"\n         [class.spa-doc-zoom-width]=\"zoom === 'width'\"\n         [class.spa-doc-zoom-actual]=\"zoom === 'actual'\">\n      <img [src]=\"objectUrl\" [alt]=\"fileName\" class=\"spa-doc-image\" draggable=\"false\" />\n    </div>\n\n    <!-- WORD (.docx), converted by mammoth in a LAZY chunk. The stage stays dark and the document is a real\n         sheet of paper on it — the same page metaphor the image renderer uses, at a measured reading width\n         rather than stretched across a 1900px monitor. -->\n    <div class=\"spa-doc-scroll\" *ngIf=\"state === 'ready' && kind === 'word'\">\n      <article class=\"spa-doc-sheet\">\n        <!-- 🔴 ALREADY sanitized in the component with DomSanitizer.sanitize(SecurityContext.HTML, …).\n             [innerHTML] sanitizes again. Both, on purpose: this HTML comes out of a file a user uploaded. -->\n        <div class=\"spa-doc-word\" [innerHTML]=\"wordHtml\"></div>\n      </article>\n      <!-- mammoth's own conversion warnings, shown rather than swallowed. A .docx that lost its footnotes\n           should say so; silently rendering 90% of a document is the failure shape this codebase repeats. -->\n      <p class=\"spa-doc-note\" *ngIf=\"wordWarnings.length > 0\">\n        <mat-icon class=\"spa-doc-note-icon\">info</mat-icon>\n        <span>Some formatting could not be converted ({{ wordWarnings.length }} note{{ wordWarnings.length > 1 ? 's' : '' }}). Save a copy for the original.</span>\n      </p>\n    </div>\n\n    <!-- EXCEL (.xlsx), read by exceljs in a LAZY chunk. Sheet tabs sit at the bottom where a spreadsheet\n         keeps them; the grid scrolls INSIDE its own container so a 60-column sheet never scrolls the page. -->\n    <div class=\"spa-doc-excel\" *ngIf=\"state === 'ready' && kind === 'excel'\">\n      <div class=\"spa-doc-grid-scroll\">\n        <table class=\"spa-doc-grid\">\n          <tbody>\n            <tr *ngFor=\"let row of sheets[activeSheet].rows; let r = index\" [class.spa-doc-grid-head]=\"r === 0\">\n              <th class=\"spa-doc-grid-gutter\" scope=\"row\">{{ r + 1 }}</th>\n              <td *ngFor=\"let cell of row\" [class.spa-doc-grid-num]=\"cell.numeric\" [title]=\"cell.text\">{{ cell.text }}</td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n\n      <p class=\"spa-doc-note spa-doc-note-inline\" *ngIf=\"sheetTruncated\">\n        <mat-icon class=\"spa-doc-note-icon\">visibility_off</mat-icon>\n        <span>This sheet is larger than the preview shows. Save a copy for the whole workbook.</span>\n      </p>\n\n      <!-- The tab strip renders for a single sheet too: it is the only place the sheet's NAME appears, and a\n           one-sheet workbook with no label reads as though the viewer lost something. -->\n      <div class=\"spa-doc-tabs\">\n        <button type=\"button\" class=\"spa-doc-tab\" *ngFor=\"let sheet of sheets; let i = index\"\n                [class.spa-doc-tab-on]=\"i === activeSheet\" (click)=\"selectSheet(i)\" [title]=\"sheet.name\">\n          <span>{{ sheet.name }}</span>\n        </button>\n      </div>\n    </div>\n\n    <!-- THE HONEST FALLBACK — legacy .doc/.xls, an unknown type, or a renderer that tried and failed. It says\n         which, and it downloads the bytes ALREADY in memory rather than the legacy viewer's window.open(). -->\n    <div class=\"spa-doc-panel\" *ngIf=\"state === 'fallback'\">\n      <mat-icon class=\"spa-doc-panel-icon\">{{ icon }}</mat-icon>\n      <h2 class=\"spa-doc-panel-title\">{{ fallbackTitle }}</h2>\n      <p class=\"spa-doc-panel-text\">{{ fallbackText }}</p>\n      <button type=\"button\" class=\"spa-doc-action spa-doc-action-primary\" *ngIf=\"downloadable\" (click)=\"download()\">\n        <mat-icon>download</mat-icon><span>Save a copy</span>\n      </button>\n    </div>\n\n    <!-- A refusal, designed. The server's own message is shown rather than a generic phrase. -->\n    <div class=\"spa-doc-panel\" *ngIf=\"state === 'error'\">\n      <mat-icon class=\"spa-doc-panel-icon spa-doc-panel-icon-alert\">{{ errorIcon }}</mat-icon>\n      <h2 class=\"spa-doc-panel-title\">{{ errorTitle }}</h2>\n      <p class=\"spa-doc-panel-text\">{{ errorMessage }}</p>\n      <button type=\"button\" class=\"spa-doc-action\" (click)=\"retry()\">\n        <mat-icon>refresh</mat-icon><span>Try again</span>\n      </button>\n    </div>\n\n    <div class=\"spa-doc-panel\" *ngIf=\"state === 'empty'\">\n      <mat-icon class=\"spa-doc-panel-icon\">folder_open</mat-icon>\n      <h2 class=\"spa-doc-panel-title\">Nothing to show</h2>\n      <p class=\"spa-doc-panel-text\">There are no documents attached to this record yet.</p>\n    </div>\n\n    <!-- THE TOOLBAR. One slim floating bar, auto-hiding on idle while a document is on screen. It overlays\n         the stage rather than sitting in a band above it, so it costs the document no height at all. -->\n    <div class=\"spa-doc-toolbar\" [class.spa-doc-toolbar-hidden]=\"!toolbarVisible\"\n         (mouseenter)=\"holdToolbar()\" (mouseleave)=\"wake()\">\n\n      <div class=\"spa-doc-identity\">\n        <!-- Changed: a field, not a two-way ternary that called every non-image a PDF. Word and Excel now\n             have glyphs of their own, and a fallback is no longer mislabelled. -->\n        <mat-icon class=\"spa-doc-identity-icon\">{{ icon }}</mat-icon>\n        <div class=\"spa-doc-identity-text\">\n          <span class=\"spa-doc-name\" [title]=\"fileName\">{{ fileName }}</span>\n          <!-- Composed in TS, not assembled from conditional fragments here. The fragment version printed\n               \"Doc Fixture Product · · 28 KB\" for a single document, because the separator before the size\n               was unconditional while the \"n of m\" part between the two separators was not. -->\n          <span class=\"spa-doc-meta\">{{ meta }}</span>\n        </div>\n      </div>\n\n      <div class=\"spa-doc-controls\">\n\n        <ng-container *ngIf=\"documents.length > 1\">\n          <button type=\"button\" class=\"spa-doc-icon\" (click)=\"previous()\" title=\"Previous document (←)\" aria-label=\"Previous document\">\n            <mat-icon>chevron_left</mat-icon>\n          </button>\n          <button type=\"button\" class=\"spa-doc-icon\" (click)=\"next()\" title=\"Next document (→)\" aria-label=\"Next document\">\n            <mat-icon>chevron_right</mat-icon>\n          </button>\n          <span class=\"spa-doc-divider\"></span>\n        </ng-container>\n\n        <!-- Zoom applies to the image renderer; the browser's PDF viewer carries its own. -->\n        <ng-container *ngIf=\"state === 'ready' && kind === 'image'\">\n          <button type=\"button\" class=\"spa-doc-icon\" [class.spa-doc-icon-on]=\"zoom === 'fit'\" (click)=\"setZoom('fit')\" title=\"Fit page\" aria-label=\"Fit page\">\n            <mat-icon>fit_screen</mat-icon>\n          </button>\n          <button type=\"button\" class=\"spa-doc-icon\" [class.spa-doc-icon-on]=\"zoom === 'width'\" (click)=\"setZoom('width')\" title=\"Fit width\" aria-label=\"Fit width\">\n            <mat-icon>width_normal</mat-icon>\n          </button>\n          <button type=\"button\" class=\"spa-doc-icon\" [class.spa-doc-icon-on]=\"zoom === 'actual'\" (click)=\"setZoom('actual')\" title=\"Actual size\" aria-label=\"Actual size\">\n            <mat-icon>crop_free</mat-icon>\n          </button>\n          <span class=\"spa-doc-divider\"></span>\n        </ng-container>\n\n        <!-- Changed: 'fallback' included. The bytes are in memory in that state too — it is the ONE state\n             where saving a copy is the only thing the user can do, so it must not be the state that hides\n             the button. -->\n        <button type=\"button\" class=\"spa-doc-icon\" *ngIf=\"downloadable && (state === 'ready' || state === 'fallback')\" (click)=\"download()\" title=\"Save a copy\" aria-label=\"Save a copy\">\n          <mat-icon>download</mat-icon>\n        </button>\n\n        <button type=\"button\" class=\"spa-doc-icon spa-doc-icon-close\" (click)=\"close()\" title=\"Close (Esc)\" aria-label=\"Close document viewer\">\n          <mat-icon>close</mat-icon>\n        </button>\n\n      </div>\n    </div>\n\n  </div>\n\n  <!-- 🔴 THE PICKER RAIL — rendered ONLY when the set holds more than one document. With a single document\n       this element does not exist in the DOM; it is not hidden with CSS. That is the acceptance criterion. -->\n  <aside class=\"spa-doc-rail\" *ngIf=\"showPicker\">\n    <p class=\"spa-doc-rail-title\">Documents<span class=\"spa-doc-rail-count\">{{ documents.length }}</span></p>\n    <div class=\"spa-doc-rail-list\">\n      <button type=\"button\" class=\"spa-doc-rail-item\" *ngFor=\"let name of documents; let i = index\"\n              [class.spa-doc-rail-item-on]=\"i === index\" (click)=\"load(i)\" [title]=\"name\">\n        <mat-icon class=\"spa-doc-rail-icon\">description</mat-icon>\n        <span class=\"spa-doc-rail-name\">{{ name }}</span>\n      </button>\n    </div>\n  </aside>\n\n</div>\n","import { Injectable, Inject, Optional } from '@angular/core';\nimport { MatDialog, MatDialogRef } from '@angular/material/dialog';\nimport { Observable } from 'rxjs';\nimport { AlertMessage, AlertConfig, Button, Column, DetailsDialogConfig, TableConfig, ImportConfig, TableDialogConfig } from '../classes/Classes'; // Changed: TableDialogConfig — openTableDialog's payload\n// import { DetailsDialog } from '../components/table/detailsDialog.component';\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';\nimport { Core, DetailsDialogProcessor } from '../classes/TinCore'; // Changed (treat-5): Core.getClone — the create branch now deep-clones like view/edit, see openConfiguredDetailsDialog\nimport { DETAILS_DIALOG_COMPONENT, IMPORT_DIALOG_COMPONENT, TABLE_DIALOG_COMPONENT } from './dialog-component.token'; // Changed: also take the import wizard and the read-only table dialog by token\n// Removed (Phase 7, BREAKING): viewerDialog is deleted along with openViewerDialog() below.\nimport { DocumentViewerDialogComponent } from '../components/document-viewer/documentViewerDialog.component'; // Added: the full-bleed replacement — safe to import directly, its template contains no <spa-table>\nimport { DocumentViewerData } from '../classes/DocumentClasses'; // Added: openDocumentViewer's payload\n// Changed: ImportDialogComponent is no longer imported here — its review step renders a spa-table, and the\n// direct import closed a compile cycle (NG3003). It arrives through IMPORT_DIALOG_COMPONENT instead.\n// Added: TableDialogComponent is absent for the SAME reason — it renders a spa-table too, so it arrives through\n// TABLE_DIALOG_COMPONENT. The rule, stated once: no component whose template contains <spa-table> is ever\n// imported into this file.\nimport { DataServiceLib } from './datalib.service'; // Added: reads appConfig.dialogStyle for the modern panel class\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class DialogService {\n  private smallScreen = false;\n\n  constructor(\n    private dialog: MatDialog,\n    private breakpointObserver: BreakpointObserver,\n    @Optional() @Inject(DETAILS_DIALOG_COMPONENT) private defaultDialogComponent: any, // Changed: Inject default dialog component\n    @Optional() @Inject(IMPORT_DIALOG_COMPONENT) private importDialogComponent: any, // Added: import wizard by token, see dialog-component.token.ts\n    @Optional() @Inject(TABLE_DIALOG_COMPONENT) private tableDialogComponent: any, // Added: read-only table dialog by token, same NG3003 reason\n    @Optional() private dataService: DataServiceLib // Added: appConfig.dialogStyle. @Optional so this service still works if it is ever constructed without the app's data service\n  ) {\n    // Detect screen size changes\n    this.breakpointObserver.observe([\"(max-width: 600px)\"]).subscribe((result: BreakpointState) => {\n      this.smallScreen = result.matches;\n    });\n  }\n\n  openDetailsDialog<T>( config: DetailsDialogConfig, dialogComponent: new (...args: any[]) => T  ): {\n    afterClosed: Observable<any>,\n    inputChange: Observable<any>,\n    dialogRef: MatDialogRef<T>\n  } {\n    const hasTables = config.tableConfigs?.length > 0;\n\n    const dialogOptions = {\n      width: config.options?.width ? config.options?.width : (this.smallScreen ? '900px' : (hasTables ? '90%' : '900px')),\n      height: config.options?.height ? config.options?.height : (hasTables ? '90%' : 'auto'),\n      // Changed (owner, 2026-08-20): MOBILE ONLY — leave a small equal gutter each side so the page behind\n      // peeks through and the surface still reads as a dialog rather than a full-screen takeover. His\n      // screenshot was a phone-width Create Customer dialog flush against both edges. On a 390px phone the\n      // requested 900px width loses to maxWidth, so maxWidth was what pinned it edge-to-edge.\n      // 8px per side (16px total): he suggested \"~5px\" and delegated the exact figure — 8px is the estate's\n      // base spacing unit and reads as deliberate inset, where 5px reads as a rendering slip. It costs 4% of\n      // a 390px viewport, which honours \"mobile width is precious\", and stays well under the dialog's own\n      // top/bottom breathing room so the proportions still read as a dialog.\n      // Desktop/large screens keep '100vw' EXACTLY as before — byte-identical, they already have side space.\n      maxWidth: this.smallScreen ? 'calc(100vw - 16px)' : '100vw',\n      maxHeight: '92vh', // Changed: cap dialog height so tall auto-height (no-table) forms scroll instead of overflowing off-screen\n      data: config\n    };\n\n    const dialogRef = this.dialog.open(dialogComponent, dialogOptions);\n\n    return {\n      afterClosed: dialogRef.afterClosed(),\n      inputChange: (dialogRef.componentInstance as any).inputChange,\n      dialogRef: dialogRef\n    };\n  }\n\n  openConfiguredDetailsDialog<T>( button: Button, row: any, dialogComponent: new (...args: any[]) => T ): Observable<any> {\n\n    // const button = column ? { name: column.name, dialog: true, detailsConfig: column.detailsConfig } : config.buttons?.find(b => b.name === buttonName);\n\n    // console.log('button', button);\n\n    if (!button || !button.dialog) {\n      return new Observable(observer => {\n        observer.next({ action: 'doAction', name: button.name, row: row });\n        observer.complete();\n      });\n    }\n\n    let config = button.detailsConfig;\n\n    //approval message\n    if (row?.pendingApproval && !['Approval', 'Approval Action'].includes(config?.formConfig.title)) { //if pending and not the actual view approval dialog //&& config?.formConfig.title != 'Approval'\n      let approvalAlerts: AlertConfig = { messages: [{ type: 'info', message: 'Waiting for approval', hidden: x => !x.pendingApproval }] }  // Changed: content to message\n      if (!config.formConfig.alertConfig){\n        config.formConfig.alertConfig = approvalAlerts;\n      }\n      else if (config.formConfig.alertConfig.messages.filter(x => x.message === approvalAlerts.messages[0].message).length === 0) {  // Changed: content to message\n        config.formConfig.alertConfig.messages.push(approvalAlerts.messages[0]);\n      }\n    }\n\n\n\n    let dialogConfig: DetailsDialogConfig = {\n      formConfig: config.formConfig,\n      buttons: config.buttons,\n      details: row,\n      stepConfig : config.stepConfig\n      // heroField : config.heroField,\n\n    };\n\n    // Added: the one-step-create machinery below (createConfig tab filtering, heroField, local rows) was gated on the\n    // button being LITERALLY named 'create'. A table resolves its create button by name (table.component.ts newModel ->\n    // getButton('create')), so a table can only ever have ONE button named 'create' — which made a SECOND one-go create\n    // button on the same table impossible to express. A button that declares detailsConfig.mode = 'create' is stating the\n    // same intent explicitly, so it now takes the same path. Purely additive and verified inert for every existing config:\n    // every `mode: 'create'` in the library today sits on a button that is already named 'create' (including the four\n    // spread ones — saleCreateButton, quickPurchaseButton, recipeCreateButton, loanProductCreateButton), so no existing\n    // dialog changes branch. Line 128 below already honoured detailsConfig.mode for the form; this aligns the rest with it.\n    const isCreate = button.name === 'create' || button.detailsConfig?.mode === 'create';\n\n\n\n\n    if (button.detailsConfig) {\n      // Changed: one-step create — tabs marked with createConfig survive into the create dialog as local (in-memory) tables;\n      // they are cloned + stripped of server plumbing (loadAction/countAction fire against unresolved parent IDs otherwise)\n      // Changed (treat-5): the CREATE branch was a SHALLOW spread of button.detailsConfig, so formConfig,\n      // formConfig.fields and every field OBJECT inside it remained the app service's SINGLETONS. Everything this\n      // method and the dialog then wrote to them persisted for the rest of the session, on the app's own config.\n      // The measured symptom: opening piglet's \"Treat pigs with this medication\" dialog from a Medications ROW ran\n      // DetailsDialogProcessor.handleFormMode, which resolves {token} loadAction URLs against detailsConfig.details.\n      // A medication row has no penID, so the pigIDs field's 'pigs/list/bypen-{penID}' was rewritten on the SHARED\n      // field object — and the Health page's own Record Treatment dialog, which passes details:null and had been\n      // working seconds earlier, was broken for the rest of the session. Order-dependent, so it read as random.\n      // The fix is not a new mechanism: the view/edit branch on the same line has ALWAYS deep-cloned, via\n      // processDetailsConfig -> Core.getClone. This gives the create branch the same isolation from the same helper.\n      // Core.getClone (deepClone2) returns functions BY REFERENCE (`typeof value !== 'object'` short-circuits), so\n      // hidden/disabled predicates and onClick handlers survive identically — which is exactly why the already-proven\n      // view/edit path can carry them. createTabs is now derived from the CLONE, so the stripping spread below no\n      // longer reads the singleton's tableConfigs either.\n      const createBase = isCreate ? Core.getClone(button.detailsConfig) : null;\n      const createTabs = isCreate\n        ? createBase.tableConfigs?.filter(tc => tc.createConfig).map(tc => ({ ...tc, loadAction: undefined, countAction: undefined, searchConfig: null, tileConfig: null, elevation: 'none' as const, realTime: false, offline: undefined, pagination: undefined }))\n        : undefined;\n      dialogConfig = isCreate ? {...createBase, tableConfigs : createTabs?.length ? createTabs : undefined, stepConfig : undefined, details: row} : DetailsDialogProcessor.processDetailsConfig({ ...button.detailsConfig }, row); // Changed: Merge row data into create mode for pre-filling fields (e.g., group header actions)\n    }else{\n      dialogConfig = DetailsDialogProcessor.processDetailsConfig({...dialogConfig}, row);\n    }\n\n\n\n    if (button.detailsConfig && button.detailsConfig.mode) {\n      dialogConfig.formConfig.mode = button.detailsConfig.mode;\n    } else {\n      dialogConfig.formConfig.mode = button.name === 'create' ? 'create' : (button.name === 'edit' ? 'edit' : 'view');\n    }\n\n\n\n    if (isCreate) { // Changed: see the isCreate note above — a button declaring detailsConfig.mode 'create' gets the create hero fields too\n      dialogConfig.heroField = config.heroField;\n      dialogConfig.heroValue = config.heroValue;\n    }\n\n\n\n    // GR-1: apps may now send translatable updatedByName + updatedDate instead of the pre-composed updatedByDetails\n    // string (which forced full-entity-graph loads on the server). Compose the footer here so both payload shapes work.\n    if (row && !row.updatedByDetails && (row.updatedByName || row.updatedDate) && dialogConfig.formConfig.includeAudit === true) {\n      const namePart = (row.updatedByName || '').trim();\n      const datePart = row.updatedDate\n        ? new Date(row.updatedDate).toLocaleString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).replace(',', '')\n        : '';\n      row.updatedByDetails = `Last updated by ${namePart} on ${datePart}.`;\n    }\n\n    if (row?.updatedByDetails && dialogConfig.formConfig.includeAudit === true && !dialogConfig.formConfig.fields.some(f => f.name === 'updatedByDetails')) {\n      dialogConfig.formConfig.fields.push(\n        { name: 'updatedByDetails', type: 'string', span: true, readonly: true, size: '12px',}\n      );\n    }\n\n    const dialogResult = this.openDetailsDialog(dialogConfig, dialogComponent);\n\n    return new Observable(observer => {\n      dialogResult.afterClosed.subscribe(result => {\n        observer.next(result);\n        observer.complete();\n      });\n\n      dialogResult.inputChange.subscribe(change => {\n        observer.next({ action: 'inputChange', change: change });\n      });\n    });\n  }\n\n  // Changed: Added method to open details dialog using the default component (breaks circular dependencies)\n  openDefaultDetailsDialog(button: Button, row: any, nestingLevel: number = 0): Observable<any> { // Changed: Added nestingLevel parameter to propagate nesting depth\n    if (!this.defaultDialogComponent) {\n      console.error('Default dialog component not provided. Ensure DETAILS_DIALOG_COMPONENT is provided in the module.');\n      return new Observable(observer => {\n        observer.error('Default dialog component not configured');\n        observer.complete();\n      });\n    }\n    // Changed: Set nestingLevel on the button's detailsConfig before opening\n    if (button.detailsConfig) {\n      button.detailsConfig.nestingLevel = nestingLevel;\n    }\n    return this.openConfiguredDetailsDialog(button, row, this.defaultDialogComponent);\n  }\n\n  // Changed: Open details dialog using the token-injected default component (avoids circular imports)\n  openDefaultDialog(config: DetailsDialogConfig): { afterClosed: Observable<any>, inputChange: Observable<any>, dialogRef: MatDialogRef<any> } {\n    if (!this.defaultDialogComponent) {\n      console.error('Default dialog component not provided. Ensure DETAILS_DIALOG_COMPONENT is provided in the module.');\n      return { afterClosed: new Observable(), inputChange: new Observable(), dialogRef: null as any };\n    }\n    return this.openDetailsDialog(config, this.defaultDialogComponent);\n  }\n\n  // Removed (Phase 7, BREAKING): openViewerDialog(fileName, fileNames, path) is DELETED along with the\n  // viewerDialog component it opened. It resolved documents by concatenating appConfig.docsBaseUrl with a\n  // folder path into a PUBLIC storage URL and dropped the result into an iframe — there is no honest shim\n  // onto openDocumentViewer, which streams bytes through the app's OWN authorized route and therefore needs\n  // a streamUrl the old signature never carried. Callers migrate to openDocumentViewer below.\n\n  // Added: open the full-bleed document viewer — the supported way to open a document from code.\n  //\n  // 🔴 THE SIZING IS THE POINT AND IT IS WHY THIS IS ITS OWN METHOD. The deleted openViewerDialog set\n  // minWidth:'95%' AND maxWidth:'80vw' — those contradict, the max wins, and the dialog could therefore\n  // never reach 95% no matter what the caller asked for. It then put a 60vh iframe inside that 80vw box.\n  // Reusing openDetailsDialog would not help either: its maxWidth/maxHeight are hardcoded inside it and\n  // dialogOptions carries only width/height, so a caller cannot lift the cap from outside.\n  openDocumentViewer(data: DocumentViewerData): MatDialogRef<DocumentViewerDialogComponent> {\n    // On a phone the dialog IS the screen. On desktop it stops just short of the edges so the app behind\n    // still reads as context rather than being replaced outright — the same rule openMapDialog follows.\n    const phone = typeof window !== 'undefined' && window.innerWidth < 600;\n\n    return this.dialog.open(DocumentViewerDialogComponent, {\n      data: data,\n      // The panel class carries the Material padding/height resets; without it the surface's own ~24px\n      // padding puts the document back inside a bezel. See tin-styles.css.\n      panelClass: ['spa-doc-viewer-panel', ...this.modernPanelClass],\n      width: phone ? '100vw' : '96vw',\n      height: phone ? '100vh' : '94vh',\n      maxWidth: phone ? '100vw' : '96vw',\n      maxHeight: phone ? '100vh' : '94vh',\n      autoFocus: false,\n      restoreFocus: true\n    });\n  }\n\n  // Added: [] when the app has not opted in, so Material receives no extra class and every dialog opened through\n  // this service renders exactly as it did before.\n  private get modernPanelClass(): string[] {\n    return this.dataService?.dialogPanelClass ?? [];\n  }\n\n  // Added: open the generic AI-assisted data import wizard. Returns afterClosed('success' on committed import).\n  openImportDialog(config: ImportConfig): Observable<any> {\n    const dialogRef = this.dialog.open(this.importDialogComponent, { // Changed: token-provided component\n      // Changed (owner, 2026-08-20): mobile keeps a small equal gutter each side — see openDetailsDialog above\n      // for the measurement and the reason 8px per side was chosen. Desktop ('80%' / '100vw') is unchanged.\n      width: this.smallScreen ? 'calc(100vw - 16px)' : '80%',\n      maxWidth: this.smallScreen ? 'calc(100vw - 16px)' : '100vw',\n      maxHeight: '92vh',\n      panelClass: this.modernPanelClass, // Added: modern surface treatment when the app opts in\n      data: config\n    });\n    return dialogRef.afterClosed();\n  }\n\n  // Added: open a READ-ONLY list of an entity in a dialog (spa-table-dialog). config.config is the entity own\n  // TableConfig, spread by the caller — which is what keeps the read on that entity capability-gated list\n  // endpoint (e.g. customers/all/x) instead of a setup/* route that is only [Authorize]-gated. The dialog\n  // component hardens the config it receives; read-only is not left to the caller to remember.\n  // Mirrors openImportDialog above, including the token indirection it exists for.\n  openTableDialog(config: TableDialogConfig): Observable<any> {\n    if (!this.tableDialogComponent) {\n      // Loud, not silent. A missing provider used to be the classic quiet failure here: the click does nothing,\n      // no error, and the button looks broken rather than unconfigured.\n      console.error('Table dialog component not provided. Ensure TABLE_DIALOG_COMPONENT is provided in the module.');\n      return new Observable(observer => { observer.error('Table dialog component not configured'); observer.complete(); });\n    }\n\n    const dialogRef = this.dialog.open(this.tableDialogComponent, {\n      // Changed (owner, 2026-08-20): mobile keeps a small equal gutter each side — see openDetailsDialog above.\n      // Desktop unchanged.\n      width: this.smallScreen ? 'calc(100vw - 16px)' : '80%',\n      maxWidth: this.smallScreen ? 'calc(100vw - 16px)' : '100vw',\n      maxHeight: '92vh', // same cap as every other dialog opened here, so a long list scrolls instead of running off-screen\n      panelClass: this.modernPanelClass,\n      data: config\n    });\n    return dialogRef.afterClosed();\n  }\n\n  openPrintDialog(htmlContent: any) {\n    // Create hidden iframe for silent printing\n    const iframe = document.createElement('iframe');\n    iframe.style.position = 'absolute';\n    iframe.style.width = '0';\n    iframe.style.height = '0';\n    iframe.style.border = 'none';\n    iframe.style.visibility = 'hidden';\n    // Changed: sandbox the print frame WITHOUT allow-scripts so any injected <script> / event handlers\n    // in the print content cannot execute. allow-same-origin lets us write content and call print();\n    // allow-modals permits the browser print dialog.\n    iframe.setAttribute('sandbox', 'allow-same-origin allow-modals');\n\n    document.body.appendChild(iframe);\n    \n    if (iframe.contentWindow) {\n      iframe.contentWindow.document.open();\n      iframe.contentWindow.document.write(htmlContent);\n      iframe.contentWindow.document.close();\n      \n      // Wait for content to load, then print silently\n      iframe.onload = () => {\n        setTimeout(() => {\n          if (iframe.contentWindow) {\n            iframe.contentWindow.print();\n            // Remove iframe after printing\n            setTimeout(() => {\n              document.body.removeChild(iframe);\n            }, 1000);\n          }\n        }, 250);\n      };\n    }\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { FormConfig, TableConfig, DetailsDialogConfig, Button, TileConfig } from '../classes/Classes';\nimport { AssetStatus } from '../classes/LibClasses';\nimport { DataServiceLib } from './datalib.service'; // Added: for capability references\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class AssetsService {\n\n  private dataService = inject(DataServiceLib); // Added: for capability references\n\n  //--------------------------Depreciation Categories-------------------------\n\n  categoryFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capFixedAssetCategories] }, // Added: gate depreciation category form by categories cap\n    title: 'Depreciation Category',\n    includeAudit: true,\n    heroField: 'depreciationCategoryID',\n    fields: [\n      { name: 'identity', type: 'section' },\n      { name: 'name', type: 'text', section: 'identity', required: true },\n      { name: 'description', type: 'text', section: 'identity' },\n      { name: 'defaults', type: 'section', alias: 'Depreciation Defaults', collapseOnView: true },\n      { name: 'defaultDepreciationMethod', alias: 'Depreciation Method', type: 'select', section: 'defaults', required: true, loadAction: { url: 'depreciationcategories/list/depreciation-methods' }, defaultValue: 0 },\n      { name: 'defaultUsefulLifeMonths', alias: 'Useful Life (Months)', type: 'number', section: 'defaults', required: true, defaultValue: 60 },\n      { name: 'defaultResidualValuePercent', alias: 'Residual Value %', type: 'number', section: 'defaults', required: true, defaultValue: 10 },\n    ],\n  }\n\n  categoryCreateButton: Button = { name: 'create', display: 'Create Category', dialog: true, action: { url: 'depreciationcategories?action=create', method: 'post' } }\n  categoryEditButton: Button = { name: 'edit', display: 'Edit', icon: { name: 'edit' }, dialog: true, action: { url: 'depreciationcategories?action=edit', method: 'post' } }\n\n  categoryDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.categoryFormConfig,\n    tableConfigs: [],\n    heroField: 'depreciationCategoryID',\n    buttons: [this.categoryCreateButton, this.categoryEditButton]\n  }\n\n  categoryTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'defaultDepreciationMethodName', 'assetCount'],\n    columns: [\n      { name: 'name', type: 'button', detailsConfig: this.categoryDetailsConfig },\n      { name: 'defaultDepreciationMethodName', alias: 'Method', type: 'text' },\n      { name: 'defaultUsefulLifeMonths', alias: 'Useful Life (Mo)', type: 'number' },\n      { name: 'defaultResidualValuePercent', alias: 'Residual %', type: 'number' },\n      { name: 'assetCount', alias: 'Assets', type: 'number' },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create Category', dialog: true, detailsConfig: this.categoryDetailsConfig, action: { url: 'depreciationcategories?action=create', method: 'post' } },\n      { name: 'delete', display: 'Delete', icon: { name: 'delete', color: 'red' }, action: { url: 'depreciationcategories?action=delete', method: 'post' }, confirm: { message: 'Delete this category?' } },\n    ],\n    loadAction: { url: 'depreciationcategories/all/x' },\n    entityName: 'DepreciationCategory'\n  }\n\n  //--------------------------Fixed Assets-------------------------\n\n  assetFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capFixedAssets] }, // Added: gate fixed asset form by asset register cap\n    title: 'Fixed Asset',\n    includeAudit: true,\n    heroField: 'fixedAssetID',\n    fields: [\n      { name: 'identity', type: 'section' },\n      { name: 'assetNumber', alias: 'Asset #', type: 'text', section: 'identity', readonly: true, hideOnCreate: true },\n      { name: 'name', type: 'text', section: 'identity', required: true },\n      { name: 'depreciationCategoryID', alias: 'Category', type: 'select', section: 'identity', required: true, loadAction: { url: 'depreciationcategories/list/x' }, detailsConfig: this.categoryDetailsConfig },\n      { name: 'description', type: 'text', section: 'identity' },\n      { name: 'acquisition', type: 'section', collapseOnView: true },\n      { name: 'acquisitionDate', alias: 'Acquisition Date', type: 'date', max: 'today', section: 'acquisition', required: true }, // Added (NFD-1): max: 'today' — this date records something that has ALREADY happened, so the future is not a valid answer; DateBounds resolves the token at render time, never at build time. Back-dating stays allowed.\n      { name: 'acquisitionCost', alias: 'Cost', type: 'money', section: 'acquisition', required: true },\n      { name: 'depreciation', type: 'section', collapsedCondition: (x: any) => x.fixedAssetID > 0, hideOnCreate: true },\n      { name: 'depreciationMethod', alias: 'Depreciation Method', type: 'select', section: 'depreciation', hideOnCreate: true, loadAction: { url: 'fixedassets/list/depreciation-methods' } },\n      { name: 'usefulLifeMonths', alias: 'Useful Life (Months)', type: 'number', section: 'depreciation', hideOnCreate: true },\n      { name: 'residualValue', alias: 'Residual Value', type: 'money', section: 'depreciation', hideOnCreate: true },\n      { name: 'tracking', type: 'section', collapsedCondition: (x: any) => x.fixedAssetID > 0 },\n      { name: 'location', type: 'text', section: 'tracking' },\n      { name: 'serialNumber', alias: 'Serial Number', type: 'text', section: 'tracking' },\n      { name: 'assetTag', alias: 'Asset Tag', type: 'text', section: 'tracking' },\n      { name: 'valuation', type: 'section', collapsedCondition: (x: any) => x.fixedAssetID > 0, hideOnCreate: true },\n      { name: 'statusName', alias: 'Status', type: 'text', section: 'valuation', readonly: true, hideOnCreate: true },\n      { name: 'netBookValueDisplay', alias: 'Net Book Value', type: 'text', section: 'valuation', readonly: true, hideOnCreate: true },\n      { name: 'accumulatedDepreciation', alias: 'Accum. Depreciation', type: 'text', section: 'valuation', readonly: true, hideOnCreate: true },\n    ],\n    loadAction: { url: 'fixedassets/id' },\n  }\n\n  depreciationEntriesTableConfig: TableConfig = {\n    tabTitle: 'Depreciation History',\n    showFilter: false,\n    columns: [\n      { name: 'periodDate', alias: 'Period', type: 'date' },\n      { name: 'amountDisplay', alias: 'Amount', type: 'text' },\n      { name: 'accumulatedAmountDisplay', alias: 'Accumulated', type: 'text' },\n      { name: 'netBookValueDisplay', alias: 'NBV', type: 'text' },\n      { name: 'entryDate', alias: 'Posted', type: 'date' },\n    ],\n    buttons: [],\n    loadAction: { url: 'depreciationentries/{fixedAssetID}/x' }, loadCriteria: 'asset', loadIDField: 'fixedAssetID',\n  }\n\n  assetCreateButton: Button = { name: 'create', display: 'Create Asset', dialog: true, action: { url: 'fixedassets?action=create', method: 'post' } }\n  assetEditButton: Button = { name: 'edit', display: 'Edit', icon: { name: 'edit' }, dialog: true, action: { url: 'fixedassets?action=edit', method: 'post' }, visible: x => x.status == AssetStatus.Draft }\n  assetActivateButton: Button = { name: 'activate', display: 'Activate', icon: { name: 'check_circle', color: 'green' }, action: { url: 'fixedassets?action=activate', method: 'post' }, confirm: { message: 'Activate this asset? This will post the acquisition journal entry.' }, visible: x => x.status == AssetStatus.Draft }\n  assetDepreciateButton: Button = { name: 'depreciate', display: 'Depreciate', icon: { name: 'trending_down', color: 'orange' }, action: { url: 'fixedassets?action=depreciate', method: 'post' }, confirm: { message: 'Post depreciation for current period?' }, visible: x => x.status == AssetStatus.Active }\n\n  disposeFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capFixedAssets] }, // Added: gate asset disposal form by asset register cap\n    title: 'Dispose Asset',\n    fixedTitle: true,\n    fields: [\n      { name: 'disposalType', alias: 'Disposal Type', type: 'select', required: true, loadAction: { url: 'fixedassets/list/disposal-types' }, defaultValue: 0 }, // Kept: reviewed as dead config and it is NOT. disposeFormConfig has exactly ONE consumer — assetDisposeButton — and that is a CAPTURE dialog (it posts fixedassets?action=dispose), not a true edit, so this default belongs to the same class as the other five. Measured on test-spa: the record reaches the form with disposalType already 0, which makes the default redundant TODAY rather than dead — but it is the declared fallback for a required select that Sale Amount is gated on (`hidden: x => x.disposalType !== 0`), so deleting it would silently rest that gate on an unstated server/select detail\n      { name: 'disposalAmount', alias: 'Sale Amount', type: 'money', defaultValue: 0, hidden: x => x.disposalType !== 0 },\n    ]\n  }\n\n  assetDisposeButton: Button = { name: 'dispose', display: 'Dispose', inDialog: true, icon: { name: 'delete_forever', color: 'red' }, dialog: true, detailsConfig: { formConfig: this.disposeFormConfig, heroField: 'fixedAssetID', mode: 'edit', seedDefaults: true, buttons: [{ name: 'dispose', display: 'Dispose Asset', inDialog: true, action: { url: 'fixedassets?action=dispose', method: 'post', successMessage: 'Asset disposed' }, confirm: { message: 'Dispose this asset? Accumulated depreciation is written off and a disposal journal is posted. This cannot be undone.' } }] }, visible: x => x?.status == AssetStatus.Active || x?.status == AssetStatus.FullyDepreciated } // Changed: added inDialog so the button survives TinCore.setupButtons' `&& x.inDialog` filter (TinCore.ts:832) and renders in the asset details footer — without it Dispose was unreachable from anywhere in the shipped UI, the same defect fixed on requisitionSubmitButton. Changed: confirm on the inner footer button — Activate and Depreciate both confirm and neither is irreversible, whereas DisposeAsset posts a write-off, a gain/loss journal and a sale transaction with no un-dispose action in the controller. Changed: `x?.` guard on the predicate to match the house style (16 existing uses) — Core.resolveVisibility already passes `data ?? {}`, so this is defence in depth, not a live fix\n\n  assetDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.assetFormConfig,\n    tableConfigs: [this.depreciationEntriesTableConfig],\n    heroField: 'fixedAssetID',\n    buttons: [this.assetCreateButton, this.assetEditButton, this.assetActivateButton, this.assetDepreciateButton, this.assetDisposeButton]\n  }\n\n  assetTileConfig: TileConfig = {\n    clickable: true,\n    headerPosition: 'top', // Added (WS-1 tile sweep): 4+ tiles do not fit the inline header band beside the buttons and filter — render them in their own full-width row above it, as loads/inventory stock already do\n    tiles: [\n      { name: 'draft', alias: 'Draft', color: '#FFC107', icon: 'edit_note', style: 'icon', info: 'Awaiting activation', action: { url: 'fixedassets/draft/x' } }, // Changed: footer -> info, and style: 'icon' added, so this page renders the same hint line as every other tiled page. tiles.component.html:98-104 prints `tile.footer ?? tile.info` either way, but it only draws the steelblue ⓘ glyph when `info` is the property set — measured in the running app, this register showed 0 footer icons while Equipment showed 4 and the fixed-assets DASHBOARD showed 7. Counted across tin-spa + grip-spa: 110 icon tiles use `info`, 8 use `footer`, and 4 of those 8 were these. `style: 'icon'` is inert in the template (it branches on `tile.icon`) but every other icon tile in the estate declares it\n      { name: 'active', alias: 'Active', color: '#4CAF50', icon: 'check_circle', style: 'icon', info: 'In service and depreciating', action: { url: 'fixedassets/active/x' } }, // Changed: footer -> info + style, same reason\n      { name: 'fullyDepreciated', alias: 'Fully Depreciated', color: '#2196F3', icon: 'trending_down', style: 'icon', info: 'Zero net book value' }, // Changed: footer -> info + style, same reason. Wording unchanged — it states the financial meaning rather than restating the alias\n      { name: 'disposed', alias: 'Disposed', color: '#9E9E9E', icon: 'delete_forever', style: 'icon', info: 'Sold or retired' }, // Changed: footer -> info + style, same reason. Wording tracks the fixed-assets DASHBOARD's `info` text for the same four states so the register and the dashboard read as one system, minus the redundant noun — every row on this page is already an asset\n    ],\n    loadAction: { url: 'fixedassets/summary/x' }\n  }\n\n  // Added (WS-1 sweep 2): paginated but deliberately NOT offline — FixedAsset does not implement ISync, and the asset register is maintained by finance at a desk. Its tiles now render above the header (4 tiles).\n  assetsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['assetNumber', 'name', 'statusName'],\n    columns: [\n      { name: 'assetNumber', alias: 'Asset #', type: 'button', detailsConfig: this.assetDetailsConfig },\n      { name: 'name', type: 'text' },\n      { name: 'categoryName', alias: 'Category', type: 'text' },\n      { name: 'acquisitionDate', alias: 'Acquired', type: 'date' },\n      { name: 'acquisitionCostDisplay', alias: 'Cost', type: 'text' },\n      { name: 'netBookValueDisplay', alias: 'NBV', type: 'text' },\n      { name: 'depreciationMethodName', alias: 'Method', type: 'text' },\n      { name: 'statusName', alias: 'Status', type: 'chip',\n        colors: [\n          { name: '#FFCC80', condition: x => x.status == AssetStatus.Draft },\n          { name: '#A5D6A7', condition: x => x.status == AssetStatus.Active },\n          { name: '#90CAF9', condition: x => x.status == AssetStatus.FullyDepreciated },\n          { name: '#BDBDBD', condition: x => x.status == AssetStatus.Disposed },\n        ]\n      },\n    ],\n    buttons: [\n      { name: 'create', display: 'Create Asset', dialog: true, detailsConfig: this.assetDetailsConfig, action: { url: 'fixedassets?action=create', method: 'post' } },\n      this.assetActivateButton,\n      this.assetDepreciateButton,\n      { name: 'delete', display: 'Delete', icon: { name: 'delete', color: 'red' }, action: { url: 'fixedassets?action=delete', method: 'post' }, confirm: { message: 'Delete this asset?' }, visible: x => x.status == AssetStatus.Draft },\n    ],\n    loadAction: { url: 'fixedassets/all/x' },\n    tileConfig: this.assetTileConfig,\n    pagination: { pageSize: 25 }, // Added: server-side pagination — the asset register is a long reference list\n    entityName: 'FixedAsset',\n  }\n}\n","// Quiet Loading — the one place the opt-in is resolved.\n// A per-config `quietLoading` ALWAYS wins, including an explicit `false`, which is why this tests\n// `!== undefined` rather than truthiness: that is what lets a single table/tile/dialog opt OUT of an app that\n// turned the feature on app-wide. Same shape as table.component.ts's effRealTime/effPagination resolvers, but\n// the app default comes from AppConfig (where dialogStyle/resumeLastRoute live) rather than the\n// runtime token.\nexport interface QuietLoadingHost {\n  quietLoading?: boolean;\n}\n\nexport function resolveQuietLoading(config: QuietLoadingHost | null | undefined, appDefault: boolean | undefined): boolean {\n  return config?.quietLoading !== undefined ? !!config.quietLoading : !!appDefault;\n}\n\n// ---------------------------------------------------------------------------\n// THE ANTI-FLICKER CONTRACT (FSD D2) — one pair of numbers, shared by every surface.\n//\n// These were duplicated as private constants in table, tiles and detailsDialog. They must agree: a page shows\n// a table, its tiles and a dialog together, and if the three disagreed on when to paint you would get exactly\n// the staggered flicker the contract exists to prevent. One definition, three consumers.\n//\n// QUIET_DELAY_MS — nothing paints until a read has been outstanding this long.\n//   Raised from 150ms to 300ms on 2026-08-05. The feature is for MANAGING A WAIT; when there is no wait it\n//   should be invisible. On localhost, on a LAN, or on a fast internet API, reads land in roughly 5-150ms, and\n//   at a 150ms threshold some of those were still crossing the line and flashing a bar or a shimmer for a\n//   moment — which is busier and more distracting than simply showing the data. 300ms sits just past the point\n//   where a person starts to perceive a delay as a delay (Nielsen's ~0.1s \"instantaneous\" band, with headroom),\n//   so a fast response now paints NOTHING AT ALL and only genuinely slow reads get the treatment.\n//\n// QUIET_MIN_MS — once something HAS painted, it stays this long so it cannot strobe.\n//   Lowered from 350ms to 300ms in the same pass to cap the worst case. The pathological response is one that\n//   lands just after the threshold: at 305ms it now costs about 605ms of visible placeholder rather than 655ms.\n// ---------------------------------------------------------------------------\nexport const QUIET_DELAY_MS = 300;\nexport const QUIET_MIN_MS = 300;\n","import { Injectable } from '@angular/core';\nimport { Button, RoleAccess, TableConfig } from '../classes/Classes';\nimport { AuthService } from './auth.service';\nimport { Core } from '../classes/TinCore';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class ButtonService {\n\n  constructor(private authService: AuthService) { }\n\n  getButton(buttons: Button[], name: string): Button | null {\n    return buttons?.find(x => x.name === name) || null;\n  }\n\n  getConfirmMessage(button: Button, row: any): string {\n    if (!button?.confirm) {\n      return '';\n    }\n  \n    // Return dynamic message if func is provided\n    if (button.confirm.func) {\n      // Changed: same defence as testDisabled below — `func` is consumer-supplied and dereferences the row, so a\n      // caller that raises a confirmation before the record has settled throws here and takes the whole\n      // confirmation with it, which is worse than a console message: the prompt never opens.\n      return button.confirm.func(row ?? {});\n    }\n  \n    // Return static message\n    return button.confirm.message;\n  }\n\n  // Added: the built-in action names the library is willing to recognise as destructive ON ITS OWN, and the\n  // action word each one puts on the button. Deliberately only these two. They are the names the library\n  // GENERATES a confirmation for without the config asking (table.deleteModel and detailsDialog.delete both\n  // fall back to a sentence composed HERE), so they are the only ones where naming the action cannot\n  // be expressed at the call site. Everything else — void, cancel, discard, reverse — must pass its own label\n  // through `confirm.confirmLabel`, because only the app knows whether its 'cancel' button cancels an order or\n  // just closes something, and guessing wrong puts the wrong verb on the button that destroys data.\n  private static readonly DESTRUCTIVE_ACTIONS: { [name: string]: string } = { 'delete': 'Delete', 'remove': 'Remove' };\n\n  // Added: where a row's human identity is read from, in probe order, when the library composes a prompt about it.\n  // `name` and `description` lead because they are the SAME two, in the same order, that\n  // TableConfigService.resolveIdentityColumn already committed to (table-config.service.ts) — a row should\n  // identify itself the same way in a delete prompt as it does under the locked-row cue. The rest are the shapes\n  // that convention only catches via a Column alias, which is not available from a bare row: people carry\n  // fullName, documents carry title or reference.\n  //\n  // Deliberately ABSENT: the ID/PK. \"Are you sure you want to delete 1042?\" names the record to a developer and\n  // to nobody else — which is why resolveIdentityColumn has an includeIdColumn:false arm, and why this probe has\n  // no id step at all. Also absent: the entity/class name. \"Delete this PigTransaction?\" names the TABLE, not the\n  // row, and reads worse than declining to name it.\n  private static readonly NAME_FIELDS = ['name', 'fullName', 'displayName', 'title', 'description', 'reference', 'code'];\n\n  // The longest name that still reads as one sentence in the dialog; past this the prompt wraps and the action\n  // word falls out of the user's first fixation.\n  private static readonly MAX_NAME_LENGTH = 60;\n\n  // Added: a row's display name, or '' when it genuinely has none. Only strings and numbers qualify — an object\n  // or an array would interpolate as \"[object Object]\", which is the same class of defect as the empty gap this\n  // exists to close.\n  getRecordName(row: any, identityField?: string): string {\n    if (!row) return '';\n\n    const read = (field: string): string => {\n      if (!field) return '';\n      const value = row[field];\n      if (typeof value !== 'string' && typeof value !== 'number') return '';\n      return value.toString().trim();\n    };\n\n    // A caller that resolved the identity from the CONFIG knows better than any probe of the row can: it can\n    // honour a declared TableConfig.identityColumn, and it can follow a column aliased 'Name' back to the real\n    // property behind it. This is the seam for that wiring.\n    const preferred = read(identityField);\n    if (preferred) return this.truncateName(preferred);\n\n    for (const field of ButtonService.NAME_FIELDS) {\n      const value = read(field);\n      if (value) return this.truncateName(value);\n    }\n\n    return '';\n  }\n\n  private truncateName(name: string): string {\n    return name.length > ButtonService.MAX_NAME_LENGTH\n      ? name.slice(0, ButtonService.MAX_NAME_LENGTH).replace(/\\s+$/, '') + '…'\n      : name;\n  }\n\n  // Added: the sentence the library composes for a destructive button that carries no confirm message of its own.\n  //\n  // This is the defect the method was extracted to fix. Every prompt of this shape had read \"Are you sure you want\n  // to delete ?\" — with a gap where the record's name belongs — since 8b832be (Apr 2025). The gap was never a\n  // failed lookup: the string was a template literal with NOTHING interpolated into it, the spacing carried over\n  // verbatim from the terser `DELETE ?` it replaced. No name was ever read, in any app, on any row. Composing the\n  // sentence here rather than at the call sites is what stops the three copies of that literal drifting again.\n  //\n  // With no name to show the floor is \"this record\" — not new phrasing invented for the fallback, but the wording\n  // the explicit confirm messages across the estate already use, so the floor reads like the rest of the product.\n  private buildDestructiveMessage(actionName: string, row: any, identityField?: string): string {\n    const recordName = this.getRecordName(row, identityField);\n    // No space before the '?' in EITHER arm — \"delete Volvo ?\" would be the same defect wearing a name.\n    return `Are you sure you want to ${actionName} ${recordName || 'this record'}?`;\n  }\n\n  // Added: resolves a confirmation's message, button labels and destructiveness in ONE place, so the four call\n  // sites that raise a confirmation (table.deleteModel, table.doAction, detailsDialog.delete,\n  // detailsDialog.executeAction) cannot drift apart on it — they already drifted once on the fallback message.\n  //\n  // `allowNamedDestructive` is the app-level opt-in (appConfig.namedDestructiveActions), passed in rather than\n  // read here so this service keeps its single AuthService dependency and does not take one on DataServiceLib.\n  //\n  // Precedence, and why: an EXPLICIT label or flag in the config always wins, because it is a deliberate\n  // statement of intent by the app. Only when the config is silent does the app-level flag allow the library to\n  // infer destructiveness from the action name — and with the flag absent (every untracked consumer, and test-spa,\n  // which is deliberately the unflagged control) nothing is inferred at all, so the prompt renders \"Yes\" / \"No\"\n  // exactly as it does today.\n  //\n  // ⚠️ Correcting a claim this comment used to make: that unflagged prompt is NOT \"green/red\". All five apps set\n  // appConfig.dialogStyle 'modern', and the modern branch of messageDialog.component.html (:17-56) renders the\n  // affirmative as a FILLED mat-flat-button reading --tin-accent — #5e35b1 purple on a plain confirm, #c62828 red\n  // once destructive — with a colourless dismissive. Green and red button TEXT exists only in the `classic` branch\n  // (:141-145), which no app ships. There is no green anywhere in the shipped look.\n  //\n  // ⚠️ `allowNamedDestructive` gates the LABELS and the colour ONLY. It has never gated the message, which is why\n  // the empty-gap defect below showed on all five apps and not just the four that opt in.\n  getConfirmOptions(button: Button, row: any, fallbackMessage?: string, allowNamedDestructive?: boolean, identityField?: string):\n    { message: string, confirmLabel?: string, cancelLabel?: string, destructive: boolean, requirePhrase?: string } {\n\n    const confirm = button?.confirm;\n    const actionWord = ButtonService.DESTRUCTIVE_ACTIONS[button?.name];\n\n    // Message precedence:\n    //   1. what the CONFIG said — an explicit message or func is a deliberate statement, never overridden.\n    //   2. whatever the caller offered as a default. Kept above the composed sentence so an external caller that\n    //      passes a real message still gets it; the three call sites that used to pass a BROKEN literal here\n    //      (\"Are you sure you want to delete ?\") no longer pass anything, so they now fall through to 3.\n    //   3. the library's own composed sentence, which names the record.\n    //   4. a generic question, so a confirm can NEVER render with an empty body — the same defect as the gap,\n    //      reached by a button declaring `confirm: {}` with no message and a name the library will not guess a\n    //      verb for (an archive, a cancel, a disable). It is the floor, not a guess at the action.\n    const message = this.getConfirmMessage(button, row)\n      || fallbackMessage\n      || (actionWord ? this.buildDestructiveMessage(button.name, row, identityField) : '')\n      || 'Are you sure you want to continue?';\n\n    // An explicit `destructive` wins either way — including an explicit false, which is how an app says \"this\n    // button is called delete but it is not destroying anything, leave it alone\".\n    const destructive = confirm?.destructive !== undefined\n      ? confirm.destructive === true\n      : (allowNamedDestructive === true && !!actionWord);\n\n    // Added (N22): requirePhrase is returned on BOTH paths, and is never inferred. A phrase gate is only ever\n    // opted into explicitly by the config — unlike the labels and the colour, nothing about a button's NAME may\n    // conjure one, because a prompt the user cannot dismiss without typing is a cost you choose deliberately.\n    if (!destructive) {\n      return { message, confirmLabel: confirm?.confirmLabel, cancelLabel: confirm?.cancelLabel, destructive: false, requirePhrase: confirm?.requirePhrase };\n    }\n\n    // Naming the SAFE button matters as much as naming the destructive one: \"Keep\" states what happens if you\n    // press it, where \"No\" only answers a question the user has to re-read the sentence to reconstruct.\n    return {\n      message,\n      confirmLabel: confirm?.confirmLabel || actionWord || 'Delete',\n      cancelLabel: confirm?.cancelLabel || 'Keep',\n      destructive: true,\n      requirePhrase: confirm?.requirePhrase\n    };\n  }\n\n  // Added (N22): the confirm dialog has TWO close shapes and every call site needs both, so the unwrapping lives\n  // here once instead of being re-derived at four sites. Without a phrase the dialog still emits the bare 'yes' /\n  // 'no' string; with one it emits { response, phrase }, because the typed text must reach the server.\n  // 🔑 The bare-string test is kept FIRST and intact — that is the path all 51 E2E assertions and every existing\n  // button take, and it must not become dependent on the new one.\n  confirmAccepted(result: any): boolean {\n    return result === 'yes' || result?.response === 'yes';\n  }\n\n  // Added (N22): the typed phrase, or undefined when no gate was demanded. Returned verbatim — never trimmed or\n  // case-folded — so what the server re-validates is exactly what the user typed and what the dialog matched.\n  confirmPhrase(result: any): string | undefined {\n    return result && typeof result === 'object' ? result.phrase : undefined;\n  }\n\n  getButtonProperties(button: Button, row: any, config: TableConfig): {\n    color: string,\n    icon: string,\n    disabled: boolean,\n    visible: boolean,\n    tip: string\n  } {\n    return {\n      color: this.getButtonColor(button, row),\n      icon: this.getIcon(button, config),\n      disabled: this.testDisabled(button, row),\n      visible: this.testVisible(button, row, config),\n      tip: button.tip || button.name\n    };\n  }\n\n  getButtonColor(button: Button, row: any): string {\n    if (this.testDisabled(button, row)) return 'lightgray';\n\n    if (button?.color) return button.color;\n    if (button.icon?.color) return button.icon.color;\n\n    const colorMap = {\n      'delete': '#F44336',\n      'create': 'green'\n    };\n\n    return colorMap[button.name] || '#4050B5';\n  }\n\n\n\n  // isButtonVisible(button: Button, row: any, isLoadComplete: boolean): boolean {\n  //   if (!isLoadComplete) return false;\n  //   return this.testVisible(button,row);\n  // }\n\n  getTitleAction(mode: string, buttons: Button[]): string {\n    const modeMap = {\n      'view': 'View',\n      'edit': buttons?.find(b => b.name === 'edit')?.display || 'Edit',\n      'create': buttons?.find(b => b.name === 'create')?.display || 'Create'\n    };\n    return modeMap[mode] || '';\n  }\n\n  isTabVisible(tableConfig: TableConfig, details: any): boolean {\n    return Core.isItemVisible(tableConfig, details); // Changed: unified visible/hidden replaces hideTabCondition\n  }\n\n  getIcon(button: Button, config: TableConfig | null): string {\n    if (button.icon) {\n      return button.icon.name;\n    }\n    return config ? this.getDefaultIcon(button.name, config.flatButtons) : this.getDefaultIcon(button.name, true);\n  }\n\n  testDisabled(button: Button, row: any, config?: TableConfig): boolean {\n\n    // Check standard locking/approval rules\n    if ((button.name === 'edit' || button.name === 'delete') && row?.locked) return true;\n    if (row?.pendingApproval && !button.ignorePendingApproval && button.name != 'view') return true;\n\n    // Check form access if detailsConfig exists\n    if (button.detailsConfig?.formConfig) {\n      const access = Core.getFormAccess(button.detailsConfig.formConfig, this.authService.currentRoleSource.value);\n      if (!this.hasRequiredAccess(access, button.name)) return true;\n    }\n\n    // Check form access levels from table config\n    if (['create', 'edit', 'view', 'delete'].includes(button.name) && config?.formConfig) {\n      const access = Core.getFormAccess(config.formConfig, this.authService.currentRoleSource.value);\n      if (!this.hasRequiredAccess(access, button.name)) return true;\n    }\n\n    // Check button-specific disabled rules\n    // Changed: never hand a consumer predicate an undefined record — the same defence Core.resolveVisibility\n    // (TinCore.ts) already applies to `visible`/`hidden`, applied here to the one predicate it did not reach.\n    // A details dialog computes its button VMs from ngOnInit BEFORE loadAction has returned the record, so `row`\n    // is genuinely undefined on that first pass. A config written the natural way — `disabled: x => x.openTaskCount > 0`\n    // — then threw a TypeError out of this call (observed live on shift-spa's Loads and Work Orders dialogs), and\n    // because detailsDialog.rebuildButtonVMs builds the VMs inside an Array.map, the throw aborted the map, skipped\n    // the extraButtonVMs/editButtonVM assignment, and killed the rest of ngOnInit — including the initAction\n    // backend check that follows it. An empty object reads every property as undefined, which is exactly what\n    // \"the record has not arrived\" means, and is what a `x?.`-guarded predicate already saw.\n    return button.disabled ? button.disabled(row ?? {}) : false;\n  }\n\n  getVisibleButtons(buttons: Button[], row: any, tableConfig?: TableConfig): Button[] {\n    return buttons.filter(button => this.testVisible(button, row, tableConfig));\n  }\n\n  // Added: the opt-in capability gate, on its own. Mirrors the server's real rule — a NAMED capability at a\n  // NAMED level — because that is what BaseController checks (CustomActionAccess: Edit on the controller's own\n  // CapabilityName). Reads the same role object the configs already read by hand: dataService.myRole is fed\n  // from authService.myRoleObserv (datalib.service.ts:569), which is currentRoleSource.asObservable() — one\n  // source, not a second way to read a role. A button that names no capability returns true immediately, so\n  // every existing button is untouched.\n  hasCapability(button: Button): boolean {\n    if (!button?.capability) return true;\n\n    const capName = typeof button.capability === 'string' ? button.capability : button.capability.name; // resolved HERE, not at config-build time — datalib assigns CapItem.name after the configs are constructed\n    if (!capName) return true; // an unresolved capability must not gate anything — a silent deny is worse than the status quo\n\n    const level: RoleAccess = this.authService.currentRoleSource.value?.[capName] ?? RoleAccess.None;\n    return level >= (button.requiredAccess ?? RoleAccess.Edit); // Edit is BaseController.CustomActionAccess's floor\n  }\n\n  testVisible(button: Button, row: any, tableConfig?: TableConfig): boolean {\n\n\n    if (!Core.isItemVisible(button, row)) { // Changed: unified visible/hidden (boolean | condition), hidden wins\n      return false;\n    }\n\n    if (!this.hasCapability(button)) { // Added: opt-in capability gate — no-op unless the config names one\n      return false;\n    }\n\n    const currentRole = this.authService.currentRoleSource.value;\n\n    // Check if button has detailsConfig with form restrictions\n    if (button.detailsConfig?.formConfig?.security) {\n      const access = Core.getFormAccess(button.detailsConfig.formConfig, currentRole);\n      if (!this.hasRequiredAccess(access, button.name)) {\n        return false;\n      }\n    }\n\n    // For create/edit/view buttons, check table's formConfig\n    if (['create', 'edit', 'view', 'delete'].includes(button.name) && tableConfig?.formConfig?.security) {\n      const access = Core.getFormAccess(tableConfig.formConfig, currentRole);\n      if (!this.hasRequiredAccess(access, button.name)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  private hasRequiredAccess(access: RoleAccess, buttonName: string): boolean {\n    switch (buttonName) {\n      case 'view':\n        return access >= RoleAccess.View;\n      case 'edit':\n        return access >= RoleAccess.Edit;\n      case 'create':\n        return access >= RoleAccess.Create;\n      case 'delete':\n        return access >= RoleAccess.Full;\n      default:\n        return true; // Custom buttons don't require specific access\n    }\n  }\n\n  private getDefaultColor(buttonName: string): string {\n    switch (buttonName) {\n      case 'delete': return '#F44336';\n      case 'create': return 'green';\n      default: return '#4050B5';\n    }\n  }\n\n  private getDefaultIcon(buttonName: string, flatButtons: boolean): string {\n    switch (buttonName) {\n      case 'view':\n        return 'launch'; // Changed: the view action is now ALWAYS 'launch' in both flat and non-flat toolbars (owner directive) — was flatButtons ? 'open_in_new' : 'pageview', which put a magnifier-over-page on every non-flat grid and a near-miss box-arrow on flat ones, so two different icons meant \"view\" side by side on the same Day Book page\n      case 'edit': return 'edit';\n      case 'delete': return 'delete';\n      case 'create': return 'add';\n      default: return 'more_horiz';\n    }\n  }\n\n  getCreateButton(buttons: Button[]): Button | undefined {\n    return buttons?.find(button => button?.name === 'create');\n  }\n\n  isFormButton(button: Button): boolean {\n\n    if (button?.action?.url?.includes('/form') || button?.action?.isFormData) {\n      button.action.isFormData = true;\n      return true;\n    }\n\n    return false;\n\n  }\n\n\n\n}\n","// table-config.service.ts\nimport { Injectable } from '@angular/core';\nimport { Button, Column, TableConfig } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\nimport { Core } from '../classes/TinCore';\nimport { AuthService } from './auth.service';\n\n// Added: the two axes on which the table's identity consumers legitimately differ. Everything else about\n// \"which column identifies this row\" is shared, so a difference now has to be stated here to exist at all.\nexport interface IdentityScope {\n  scope?: string[] // column names actually rendered; omit to consider every column in the config\n  includeIdColumn?: boolean // false stops at name/description — the TinSync icons never hosted on a bare id\n}\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class TableConfigService {\n\n  constructor(private dataService: DataServiceLib, private authService: AuthService) { }\n\n  setColumns(config: TableConfig, smallScreen: boolean): string[] {\n\n    if (!config?.columns) {\n      return [];\n    }\n\n    let visibleColumns = this.getVisibleColumns(config);\n\n\n    let columnNames;\n\n    if (smallScreen && config.minColumns) {\n      columnNames = config.minColumns.filter(col => visibleColumns.some(x => x.name === col) );\n    }\n    else{\n      columnNames = visibleColumns.map(({ name }) => name);\n    }\n\n    // Add action column only if there are visible buttons\n    const hasVisibleButtons = this.getDisplayedButtons(config.buttons, smallScreen, config)?.length > 0;\n\n    if (hasVisibleButtons) {\n      columnNames.push('action');\n    }\n\n    return columnNames;\n  }\n\n  getVisibleColumns(config: TableConfig): Column[] {\n    return config.columns.filter(column =>\n      Core.isItemVisible(column, config.parentData) // Changed: unified visible/hidden replaces hiddenCondition\n    );\n  }\n\n  getActionsWidth(buttons: Button[], smallScreen: boolean, config: TableConfig): string {\n\n    // Changed: Width based on maxButtonsCount (More button now included in that count when overflow exists)\n    const filteredButtons = buttons?.filter(x => x.name != 'create' && !x.inHeader) ?? [];\n    const maxButtons = config?.maxButtonsCount ?? 3;\n\n    let size: number;\n\n    if (smallScreen) {\n      size = config?.minButtons?.length ?? 1;\n    }\n    else {\n      // Changed: Use min of actual buttons or maxButtonsCount\n      size = Math.min(filteredButtons.length, maxButtons);\n    }\n\n    // Changed: 40px per button (32px icon + 8px spacing) + 20px padding\n    return `${size * 40 + 20}px`;\n  }\n\n  getDisplayedButtons(buttons: Button[], isSmallScreen: boolean, config: TableConfig): Button[] {\n\n    let hasCRUD = buttons?.some(x => x.name === 'create' || x.name === 'edit' || x.name === 'delete');\n\n    // DELIBERATE, LOAD-BEARING MUTATION — do NOT \"fix\" this by copying the array before unshifting.\n    // `buttons` is `config.buttons` BY REFERENCE (table.component.ts updateTableConfiguration passes it straight in),\n    // so rendering a table permanently adds these framework buttons to the caller's raw config. That is the ONLY route\n    // by which Approve/Decline/Cancel reach a details-dialog footer: table.component.ts open() passes\n    // `buttons: this.config.buttons` on the no-per-button-detailsConfig fallback, TinCore.initializeConfigs passes\n    // `detailsConfig.buttons` through unmerged, and TinCore.setupButtons builds the footer by filtering `inDialog`\n    // (approve/decline/cancel carry it; viewApprovalButton does not, so it is table-only). Copy instead of mutate and\n    // approvals silently vanish from every such dialog across five apps. See the matching note in table.component.ts open().\n    // The guard is an IDENTITY check against the `providedIn: 'root'` DataLibService singleton, so re-renders cannot duplicate.\n    if (buttons && hasCRUD && !buttons?.includes(this.dataService.approveButton)) {\n      // Add approval buttons to beginning of array\n      buttons?.unshift(this.dataService.cancelButton);\n      buttons?.unshift(this.dataService.declineButton);\n      buttons?.unshift(this.dataService.approveButton);\n      buttons?.unshift(this.dataService.viewApprovalButton);\n    }\n\n    return buttons?.filter(x => x.name !== 'create' && !x.inHeader);\n\n  }\n\n  hasTableAccess(config: TableConfig): boolean {\n    if (!config?.formConfig) {\n      return true;\n    }\n    return Core.hasFormAccess(config.formConfig, this.authService.currentRoleSource.value);\n  }\n\n  //---------------- The identifying column (one definition, shared) ----------------\n\n  // Added: THE single answer to \"which column names the thing this row IS\". Three separate pieces of the table\n  // had grown their own version of that question — the TinSync status icons, the locked-row cue, and the\n  // clickable-identity work that needs it next — and three answers that drift is exactly how a lock lands on one\n  // column while the drill-in lands on another. It is now decided in one place.\n  //\n  // Resolution order:\n  //   1. config.identityColumn === false  -> null. The author states these rows are not entities (aggregate,\n  //      report and summary grids). That is positive knowledge, not a missing value, so nothing decorates them.\n  //   2. config.identityColumn is a name  -> that column, matched on Column.name, case-insensitively.\n  //   3. otherwise the shipped convention -> first present of name, description, the id/PK.\n  //\n  // What is deliberately NOT a step: \"the column typed button or chip that carries a detailsConfig\". That shape\n  // reads like a declaration and is not one — it is equally the shape of a NAVIGATIONAL column pointing at a\n  // RELATED entity. On the trips grid it would name `vehicleName`, making a trip identify itself by its vehicle.\n  // Inferring identity from column shape was measured at 47.8% disagreement against the identities authors had\n  // already declared in code, so it is not done here at all. An author who means it writes identityColumn.\n  resolveIdentityColumn(config: TableConfig, options: IdentityScope = {}): Column | null {\n    const columns = config?.columns ?? [];\n\n    // scope = the column names actually on screen. An EMPTY array means \"nothing is rendered\" and must resolve to\n    // null; only an OMITTED scope means \"consider every column in the config\". The distinction is load-bearing —\n    // the locked-row cue passes displayedColumns, which is legitimately empty before the first breakpoint lands.\n    const inScope = options.scope ? columns.filter(c => options.scope.includes(c.name)) : columns;\n    if (!inScope.length) return null;\n\n    if (config.identityColumn === false) return null;\n\n    if (config.identityColumn) {\n      const declared = config.identityColumn.toLowerCase();\n      return inScope.find(c => c.name?.toLowerCase() === declared) ?? null; // out of scope (cut by minColumns on a phone) is a real null, never a fallthrough to the convention — a declared identity that is not on this screen means there is no identity on this screen\n    }\n\n    // name/description match on name OR alias, case-insensitively. Both existing consumers already did it this\n    // way, and the alias arm is load-bearing: 4 configs carry a column named e.g. `departmentTitle` aliased 'Name'.\n    const isNamed = (c: Column, target: string) => (c.name?.toLowerCase() === target) || (c.alias?.toLowerCase() === target);\n    const named = inScope.find(c => isNamed(c, 'name')) ?? inScope.find(c => isNamed(c, 'description'));\n    if (named || options.includeIdColumn === false) return named ?? null;\n\n    const idNames = this.identityIdColumnNames(config);\n    return inScope.find(c => idNames.includes(c.name?.toLowerCase())) ?? null;\n  }\n\n  // The PK is resolved the same way OfflineService resolves idField (offline.service.ts:169) — heroField first,\n  // then the entity-derived '<singular>ID' — plus a bare 'id'. Deliberately NOT \"any column ending in id\": that\n  // matches real business columns (Paid, Valid) and would hang a cue off an unrelated cell.\n  private identityIdColumnNames(config: TableConfig): string[] {\n    const hero = (config.formConfig?.heroField ?? config.heroField ?? '').toString().toLowerCase();\n    const entity = (config.entityName || this.deriveEntityName(config) || '').toLowerCase().replace(/[-_\\s]/g, '');\n    return [hero, 'id', entity ? entity.replace(/s$/, '') + 'id' : ''].filter(x => !!x);\n  }\n\n  // Moved here from TableComponent, behaviour and reasoning both unchanged, so the entity token the identity\n  // resolver uses and the one SignalR subscribes with cannot drift apart. TableComponent now delegates to this.\n  // Derives the entity name from the loadAction URL (e.g. 'products/all/x' -> 'Product').\n  deriveEntityName(config: TableConfig): string {\n    const url = config?.loadAction?.url || '';\n    const segment = url.split('/')[0]; // First URL segment (e.g. 'products')\n    if (!segment) return '';\n    const name = segment.charAt(0).toUpperCase() + segment.slice(1); // Capitalize\n    // <consonant>ies -> y BEFORE the bare trailing-'s' strip. Stripping one 's' turned 'categories' into\n    // 'Categorie' and 'overtimeentries' into 'Overtimeentrie'.\n    // The LIVE consequence is realTimeEntityName (table.component.ts): tables on -ies urls subscribed to SignalR\n    // as \"Categorie\"/\"Countrie\"/\"Overtimeentrie\" while the server broadcasts typeof(TEntity).Name — \"Category\",\n    // \"Country\", \"OvertimeEntry\" — so those tables received NO live create/update/delete at all. Verified on a\n    // live stack: the wire carries \"Category\" and this function now returns \"Category\" for 'categories'.\n    // The locked-row cue reads the same token via identityIdColumnNames(), but that defect is LATENT, not active:\n    // heroField is tried first and rescues the configs that have one, and the rest carry no PK column for a\n    // correct singulariser to find. So this repairs real-time; it does not change any lock host today.\n    // The rule is deliberately narrow. The estate's 181 url segments were enumerated before writing this and the\n    // other \"obvious\" plural rules are net-negative here: a general '-es' strip would turn 'purchases' into\n    // 'Purcha' and BREAK the SignalR match it makes CORRECTLY today, and a '-ches' strip would take 'gptcaches'\n    // further from 'GptCache', not closer. A wider singulariser must be justified against that list, not against\n    // English. '-sses' matches no segment today ('addresses' is not a table url yet) and is here so the next one\n    // does not tempt anyone into the aggressive strip that breaks the two above.\n    if (/[^aeiouAEIOU]ies$/.test(name)) return name.slice(0, -3) + 'y'; // categories -> Category, countries -> Country\n    if (/sses$/.test(name)) return name.slice(0, -2); // addresses -> Address; never matches 'purchases' ('ases')\n    return name.endsWith('s') ? name.slice(0, -1) : name; // Remove trailing 's' for singular\n  }\n\n  getVisibleTableConfigs(tableConfigs: TableConfig[]): TableConfig[] {\n    if (!tableConfigs) return [];\n    return tableConfigs.filter(config => this.hasTableAccess(config));\n  }\n}\n","// Service to centralize tab management logic across spa-tabs and spa-tabs-internal components\nimport { Injectable } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { TableConfig, ApiResponse, Action } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\nimport { ButtonService } from './button.service';\nimport { TableConfigService } from './table-config.service';\nimport { resolveQuietLoading } from '../runtime/quiet-loading'; // Added: Quiet Loading — shared config-over-app precedence resolver\n\n// Changed: Interface to track original index alongside visible tab config\nexport interface VisibleTab {\n  config: TableConfig;\n  originalIndex: number;\n}\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class TabService {\n\n  constructor(\n    private dataService: DataServiceLib,\n    private buttonService: ButtonService,\n    private tableConfigService: TableConfigService\n  ) { }\n\n  // Replace {propertyName} placeholders in URL with values from parentData\n  private transformCountUrl(url: string, parentData?: any): string {\n    if (!parentData || !url || !url.includes('{')) return url; // Changed: Only process if URL contains placeholders\n    return url.replace(/\\{(\\w+)\\}/g, (match, propName) => {\n      const value = parentData[propName];\n      return value !== undefined && value !== null ? String(value) : match;\n    });\n  }\n\n  // Added: a nested tab already declares how its rows are filtered — loadCriteria + loadIDField against the\n  // parent record — so its count endpoint is derivable rather than restated on every config. An explicit\n  // countAction always wins, and a tab with no parent filter (no loadCriteria/loadIDField) gets no badge, as before.\n  private derivedCountActions = new WeakMap<TableConfig, Action>();\n\n  getCountAction(config: TableConfig): Action | undefined {\n    if (!config) return undefined;\n    if (config.countAction) return config.countAction;\n    if (!config.loadAction?.url || !config.loadCriteria || !config.loadIDField) return undefined;\n\n    let derived = this.derivedCountActions.get(config);\n    if (!derived) {\n      // loadAction.url is rewritten in place to \"entity/criteria/id\" once the parent loads, so only the entity\n      // segment is dependable here; the id stays a placeholder for transformCountUrl to fill.\n      const entity = config.loadAction.url.split('/')[0];\n      derived = { url: `${entity}/${config.loadCriteria}-count/{${config.loadIDField}}` };\n      this.derivedCountActions.set(config, derived);\n    }\n\n    return derived;\n  }\n\n  // Added: resolved count URL for a tab — public so hosts can tell when the parent record finally supplies the id\n  resolveCountUrl(config: TableConfig, parentData?: any): string {\n    const countAction = this.getCountAction(config);\n    return countAction?.url ? this.transformCountUrl(countAction.url, parentData) : '';\n  }\n\n  // Initialize tab counts and reload subjects for all tabs\n  // Changed: eagerIndex is the tab opened on load — its own grid reports the same number through totalChange,\n  // so fetching a count for it would be a second request for a figure already on its way.\n  // Changed: fetchCounts lets a host opt out of this eager pass and drive every fetch itself, so it can record\n  // exactly which URLs were requested. Defaults to true, so any existing caller behaves as it always did.\n  initializeTabs(tableConfigs: TableConfig[], parentData?: any, eagerIndex?: number, fetchCounts: boolean = true): {\n    tabCounts: { [index: number]: number },\n    tableReloads: { [index: number]: Subject<boolean> }\n  } {\n    const tabCounts: { [index: number]: number } = {};\n    const tableReloads: { [index: number]: Subject<boolean> } = {};\n\n    tableConfigs.forEach((config, index) => {\n      const countAction = this.getCountAction(config); // Changed: derived when the tab did not declare one\n      if (fetchCounts && countAction && !this.gridPublishesOwnTotal(config, index, eagerIndex)) {\n        this.loadTabCount(index, countAction, tabCounts, parentData, this.isQuiet(config)); // Changed: Pass parentData for URL placeholder replacement; Quiet Loading — resolve silence from the tab's own config\n      }\n      tableReloads[index] = new Subject<boolean>();\n    });\n\n    return { tabCounts, tableReloads };\n  }\n\n  // Added: only a tab that renders a real grid reports its own total — a custom tabTemplate never does, so it\n  // still needs the count call even when it is the one opened on load.\n  // Changed (was skipEagerCount): renamed for what it actually asserts, and made public so the host can apply\n  // the same rule. The caller must ALSO be sure that grid is mounted — see TabsComponent.gridWillReport().\n  gridPublishesOwnTotal(config: TableConfig, index: number, eagerIndex?: number): boolean {\n    return eagerIndex !== undefined && index === eagerIndex && !!config.loadAction && !config.tabTemplate;\n  }\n\n  // Added (Quiet Loading, FSD D6): a tab badge is a READ. When the tab's table (or the app) is quiet, fetch it\n  // silently so opening a details dialog never flashes the scrim just to number a tab. The TableConfig's own\n  // quietLoading always wins, including an explicit false — same precedence as every other quiet surface.\n  private isQuiet(config: TableConfig): boolean {\n    return resolveQuietLoading(config, this.dataService.appConfig?.quietLoading);\n  }\n\n  // Load count for a specific tab\n  loadTabCount(\n    tabIndex: number,\n    countAction: any,\n    tabCounts: { [index: number]: number },\n    parentData?: any, // Changed: Accept parentData for URL placeholder replacement\n    quiet?: boolean, // Added: Quiet Loading — fetch the badge silently (optional, so existing external callers are unchanged)\n    onSettled?: (succeeded: boolean) => void // Added: lets the host know a badge did NOT arrive, so it can be requested again rather than staying blank forever\n  ): void {\n    // Changed: Transform URL by replacing {propertyName} placeholders with parentData values\n    const transformedUrl = this.transformCountUrl(countAction.url, parentData);\n    if (transformedUrl?.includes('{')) { onSettled?.(false); return; } // Added: parent record not loaded yet — firing with the raw {id} placeholder makes the API drop the parent filter and answer with a GLOBAL count (the stale badge bug)\n    const transformedAction = { ...countAction, url: transformedUrl };\n    // Changed (Quiet Loading): `undefined` is identical to omitting the argument, so a non-quiet badge builds the same request it always did\n    this.dataService.CallApi(transformedAction, '', quiet ? { silent: true } : undefined).subscribe({\n      // Changed: an unsuccessful response used to leave the badge silently blank with nothing recording that it\n      // had failed, so it was never asked for again. Both outcomes now report through onSettled.\n      //\n      // DELIBERATELY SILENT to the USER (WS-6 Phase 4 triage), and this one is already solved better than a\n      // dialog could solve it. A tab-count badge is decoration on a tab strip that may hold a dozen tabs, all\n      // counting at once against the same backend — converting would turn one outage into a dozen suppressed\n      // duplicates of a message about a number. The failure is not swallowed: onSettled(false) hands it to the\n      // host, which re-requests the badge. Reporting to the code that can FIX it beats reporting to a person\n      // who cannot.\n      next: (apiResponse: ApiResponse) => {\n        if (apiResponse.success) {\n          tabCounts[tabIndex] = apiResponse.data;\n        }\n        onSettled?.(!!apiResponse.success);\n      },\n      error: (err) => { onSettled?.(false); throw err; } // Changed: settle first, then rethrow so the failure is still reported exactly as it was before this handler existed\n    });\n  }\n\n  // Refresh count for a specific tab\n  refreshTabCount(\n    index: number,\n    tableConfigs: TableConfig[],\n    tabCounts: { [index: number]: number },\n    parentData?: any, // Changed: Accept parentData for URL placeholder replacement\n    onSettled?: (succeeded: boolean) => void // Added: passed through to loadTabCount so the host can retry a badge that did not arrive\n  ): void {\n    const config = tableConfigs[index];\n    const countAction = this.getCountAction(config); // Changed: derived when the tab did not declare one\n    if (countAction) {\n      this.loadTabCount(index, countAction, tabCounts, parentData, this.isQuiet(config), onSettled); // Changed: Pass parentData; Quiet Loading — silent when this tab is quiet\n    }\n  }\n\n  // Handle tab change - mark tab as loaded for lazy loading\n  handleTabChange(\n    selectedIndex: number,\n    activeTabsLoaded: { [index: number]: boolean }\n  ): void {\n    if (!activeTabsLoaded[selectedIndex]) {\n      activeTabsLoaded[selectedIndex] = true;\n    }\n  }\n\n  // Determine if tab data should be loaded (lazy loading logic)\n  shouldLoadTabData(index: number, activeTabsLoaded: { [index: number]: boolean }): boolean {\n    return activeTabsLoaded[index] || index === 0; // Always load first tab immediately\n  }\n\n  // Check if badge should be shown for a tab\n  // Changed: a tab whose count is derived (or adopted from its own grid total) badges too, so the test is the\n  // resolved number rather than the presence of a hand-written countAction\n  shouldShowBadge(index: number, tableConfigs: TableConfig[], tabCounts: { [index: number]: number }): boolean {\n    return tabCounts[index] !== undefined;\n  }\n\n  // Get count for a specific tab\n  getTabCount(index: number, tabCounts: { [index: number]: number }): number | undefined {\n    return tabCounts[index];\n  }\n\n  // Get title for a tab\n  getTabTitle(config: TableConfig): string {\n    return config.tabTitle || 'Untitled';\n  }\n\n  // Check if tab is visible based on access control and visibility conditions\n  isTabVisible(tblConfig: TableConfig, parentData?: any): boolean {\n    // Check table access permissions\n    if (!this.tableConfigService.hasTableAccess(tblConfig)) {\n      return false;\n    }\n\n    // Check button-based visibility conditions\n    return this.buttonService.isTabVisible(tblConfig, parentData);\n  }\n\n  // Changed: Returns visible tabs with original indices to fix count badge mismatch when middle tabs are hidden\n  getVisibleTabs(tableConfigs: TableConfig[], parentData?: any): VisibleTab[] {\n    if (!tableConfigs) return [];\n\n    return tableConfigs\n      .map((config, index) => ({ config, originalIndex: index }))\n      .filter(tab => this.isTabVisible(tab.config, parentData));\n  }\n}\n","// Subscription feature-checking service for plan-based feature gating\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { HttpService } from './http.service';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class SubscriptionService {\n\n  // Enabled feature keys for the current tenant's plan\n  private enabledFeaturesSource = new BehaviorSubject<string[]>([]);\n  public enabledFeatures$ = this.enabledFeaturesSource.asObservable();\n\n  // Whether features have been loaded from the server\n  private featuresLoaded = false;\n\n  constructor(private httpService: HttpService) { }\n\n  // Fetch enabled features from backend — call after login\n  loadFeatures() {\n    this.httpService.Get('subscriptions/features').subscribe({\n      next: (response: any) => {\n        if (response && Array.isArray(response)) {\n          this.enabledFeaturesSource.next(response);\n          this.featuresLoaded = true;\n        }\n      },\n      error: () => {\n        // Silently fail — features remain empty, all gating checks return false\n        this.enabledFeaturesSource.next([]);\n        this.featuresLoaded = true;\n      }\n    });\n  }\n\n  // Check if a specific feature key is enabled for the current tenant's plan\n  isFeatureEnabled(featureKey: string): boolean {\n    if (!featureKey) return true; // No feature restriction\n    return this.enabledFeaturesSource.value.includes(featureKey);\n  }\n\n  // Check if a module (by capName mapping) is enabled — used by nav-menu filtering\n  isModuleEnabled(featureKey: string): boolean {\n    if (!featureKey) return true; // No feature restriction on this module\n    return this.enabledFeaturesSource.value.includes(featureKey);\n  }\n\n  // Clear features on logout\n  clearFeatures() {\n    this.enabledFeaturesSource.next([]);\n    this.featuresLoaded = false;\n  }\n\n  // Whether features have been loaded (useful for guards to wait)\n  get loaded(): boolean {\n    return this.featuresLoaded;\n  }\n}\n","import { Component, Inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MAT_SNACK_BAR_DATA, MatSnackBarRef } from '@angular/material/snack-bar';\n\n// Payload the UpdateService hands the prompt: which button the user pressed is reported back through the snackbar ref\nexport interface UpdatePromptResult { reload: boolean; }\n\n// Persistent PWA \"new version available\" prompt. Two explicit choices — the bar never dismisses itself,\n// so a slow page load or a covering loader can no longer eat the user's only chance to reload.\n@Component({\n  selector: 'spa-update-prompt',\n  standalone: true,\n  imports: [CommonModule, MatButtonModule, MatIconModule],\n  templateUrl: './update-prompt.component.html',\n  styleUrls: ['./update-prompt.component.css']\n})\nexport class UpdatePromptComponent {\n\n  constructor(\n    public snackRef: MatSnackBarRef<UpdatePromptComponent>,\n    @Inject(MAT_SNACK_BAR_DATA) public data: { message: string }\n  ) { }\n\n  reload() { this.snackRef.dismissWithAction(); } // dismissWithAction() fires onAction() — the service reloads there\n  later() { this.snackRef.dismiss(); } // plain dismiss — the service re-offers the update after a quiet interval\n}\n","<div class=\"update-prompt\">\n  <mat-icon class=\"update-prompt-icon\">system_update_alt</mat-icon>\n  <span class=\"update-prompt-message\">{{ data.message }}</span>\n  <span class=\"update-prompt-actions\">\n    <button mat-button class=\"update-prompt-later\" (click)=\"later()\">Later</button>\n    <button mat-flat-button color=\"primary\" class=\"update-prompt-reload\" (click)=\"reload()\">Reload</button>\n  </span>\n</div>\n","import { Injectable } from '@angular/core';\nimport { SwUpdate, VersionReadyEvent } from '@angular/service-worker';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { filter } from 'rxjs/operators';\nimport { UpdatePromptComponent } from '../components/update-prompt/update-prompt.component';\n\n// PWA update detection service — prompts user to reload when a new version is deployed\n@Injectable({ providedIn: 'root' })\nexport class UpdateService {\n\n  // Changed: how long to wait before re-offering the update after the user chose \"Later\". Was not\n  // possible before — the old prompt auto-expired and was then gone for the rest of the session.\n  rePromptMs = 10 * 60 * 1000; // public so a spec can shorten it — fakeAsync is unavailable in this karma setup\n\n  private promptOpen = false; // Added: guards against stacking a second bar over one already showing\n  private rePromptTimer: any = null;\n  private stylesInjected = false;\n\n  // Added: these two rules must be GLOBAL — the snackbar panel is rendered into the CDK overlay container,\n  // outside the component's view encapsulation, so update-prompt.component.css cannot reach it. They are\n  // injected here rather than added to tin-styles.css so the fix is self-contained in the files it owns.\n  private static readonly promptStyles = `\nbody.spa-update-prompt-open .cdk-overlay-container { z-index: 2147483647 !important; }\n.spa-update-prompt-panel .mdc-snackbar__surface { min-width: 320px; max-width: min(560px, 92vw); }\n`;\n\n  constructor(private swUpdate: SwUpdate, private snackBar: MatSnackBar) {\n    if (!this.swUpdate.isEnabled) return; // Guard: service worker may not be available in dev\n    this.listenForUpdates();\n  }\n\n  private listenForUpdates() {\n    this.swUpdate.versionUpdates\n      .pipe(filter((e): e is VersionReadyEvent => e.type === 'VERSION_READY'))\n      .subscribe(() => this.promptForReload());\n  }\n\n  // Changed: was an inline snackBar.open('A new version is available.', 'Reload', { duration: 10000 }).\n  // The 10s timer was the defect — a mid-load page (or the loader overlay, which sits at z-index\n  // 2147483647 and swallows clicks) could consume the whole window before the user reached Reload, and\n  // the only prompt of the session was then lost silently. This prompt has NO duration: it stays until\n  // the user chooses. That removes the race entirely rather than widening it.\n  promptForReload() {\n    if (this.promptOpen) return;\n    this.promptOpen = true;\n    this.clearRePrompt();\n    this.injectStyles();\n    // Lifts the overlay container to the loader's own z-index. The loader lives inside app-root while the\n    // CDK overlay container is appended to <body> after it, so on equal z-index the prompt paints on top —\n    // verified by hit-testing in test-spa: with this class the Reload button is topmost under a visible\n    // loader, without it the loader is. Removed again on dismiss so nothing else inherits the escape hatch.\n    document.body.classList.add('spa-update-prompt-open');\n\n    const snack = this.snackBar.openFromComponent(UpdatePromptComponent, {\n      data: { message: 'A new version is available.' },\n      panelClass: 'spa-update-prompt-panel',\n      horizontalPosition: 'center',\n      verticalPosition: 'bottom'\n      // no `duration` — deliberate: this prompt requires a user decision\n    });\n\n    snack.onAction().subscribe(() => window.location.reload()); // Reload to activate new version\n\n    snack.afterDismissed().subscribe(result => {\n      this.promptOpen = false;\n      document.body.classList.remove('spa-update-prompt-open');\n      if (!result.dismissedByAction) this.scheduleRePrompt(); // \"Later\" — offer it again rather than losing it\n    });\n  }\n\n  private injectStyles() {\n    if (this.stylesInjected || document.getElementById('spa-update-prompt-styles')) { this.stylesInjected = true; return; }\n    const style = document.createElement('style');\n    style.id = 'spa-update-prompt-styles';\n    style.textContent = UpdateService.promptStyles;\n    document.head.appendChild(style);\n    this.stylesInjected = true;\n  }\n\n  // Added: the update is still pending after \"Later\", so re-offer it instead of dropping it for the session\n  private scheduleRePrompt() {\n    this.clearRePrompt();\n    this.rePromptTimer = setTimeout(() => this.promptForReload(), this.rePromptMs);\n  }\n\n  private clearRePrompt() {\n    if (this.rePromptTimer) { clearTimeout(this.rePromptTimer); this.rePromptTimer = null; }\n  }\n\n  // Manual update check — call from AppComponent.ngOnInit()\n  checkForUpdate() {\n    if (this.swUpdate.isEnabled) this.swUpdate.checkForUpdate();\n  }\n}\n","// PushNotificationService: Requests push permission, creates browser subscription, saves to backend\nimport { Injectable } from '@angular/core';\nimport { HttpService } from './http.service';\n\n@Injectable({ providedIn: 'root' })\nexport class PushNotificationService {\n\n  private vapidPublicKey = '';\n\n  constructor(private httpService: HttpService) {}\n\n  // Called from AppComponent.ngOnInit() after user is authenticated\n  init() {\n    if (!('serviceWorker' in navigator) || !('PushManager' in window)) return;\n    this.fetchVapidKeyAndSubscribe();\n  }\n\n  private fetchVapidKeyAndSubscribe() {\n    this.httpService.Get('pushsubscription/vapid-key').subscribe((res: any) => {\n      if (!res?.success || !res?.data) return;\n      this.vapidPublicKey = res.data;\n      this.requestPermissionAndSubscribe();\n    });\n  }\n\n  private requestPermissionAndSubscribe() {\n    Notification.requestPermission().then(permission => {\n      if (permission !== 'granted') return;\n      this.subscribe();\n    });\n  }\n\n  private subscribe() {\n    navigator.serviceWorker.ready.then(registration => {\n      registration.pushManager.subscribe({\n        userVisibleOnly: true,\n        applicationServerKey: this.urlBase64ToUint8Array(this.vapidPublicKey).buffer as ArrayBuffer\n      }).then(sub => this.saveSubscription(sub))\n        .catch(err => console.error('Push subscription failed:', err));\n    });\n  }\n\n  private saveSubscription(subscription: PushSubscription) {\n    const sub = subscription.toJSON();\n    this.httpService.Post('pushsubscription/subscribe', {\n      endpoint: sub.endpoint,\n      p256dh: sub.keys!['p256dh'],\n      auth: sub.keys!['auth'],\n      deviceName: navigator.userAgent.substring(0, 200)\n    }).subscribe();\n  }\n\n  // Convert VAPID public key from URL-safe base64 to Uint8Array\n  private urlBase64ToUint8Array(base64String: string): Uint8Array {\n    const padding = '='.repeat((4 - base64String.length % 4) % 4);\n    const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');\n    const raw = window.atob(base64);\n    return Uint8Array.from([...raw].map(c => c.charCodeAt(0)));\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { DataServiceLib } from './datalib.service';\nimport { ApiResponse } from '../classes/Classes';\nimport { SignalRService } from './signalr.service'; // Changed: Added for real-time notification count\nimport { MessageService } from './message.service'; // Changed: Added for in-app push toast display\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class NotificationsService {\n\n  private notificationCount = new BehaviorSubject<number>(0);\n  notificationCount$ = this.notificationCount.asObservable();\n\n  constructor(private dataService: DataServiceLib, private signalRService: SignalRService, private messageService: MessageService) {\n    // Changed: Subscribe to real-time SignalR count updates\n    this.signalRService.notificationCount$.subscribe(count => {\n      this.notificationCount.next(count);\n    });\n\n    // Changed: Wire reconnection callback to refresh count via HTTP\n    this.signalRService.onReconnected = () => this.loadNotifications();\n\n    // Changed: Listen for push messages forwarded from service worker\n    this.listenForPushMessages();\n  }\n\n  // Changed: Intercept push events when the app is in the foreground\n  private listenForPushMessages() {\n    if (!('serviceWorker' in navigator)) return;\n    navigator.serviceWorker.addEventListener('message', (event) => {\n      if (event.data && event.data.type === 'PUSH_RECEIVED') {\n        this.messageService.toast(event.data.body || 'New notification');\n        this.refreshCount();\n      }\n    });\n  }\n\n  // Changed: Uncommented HTTP poll for initial count on login\n  loadNotifications() {\n    this.dataService.CallApi({ url: 'notifications/count/x' }).subscribe((apiResponse: ApiResponse) => {\n      // DELIBERATELY SILENT (WS-6 Phase 4 triage). This is THE poll of the set, and the one where converting\n      // would be most obviously wrong: it runs on login, on signup, on every visit to the notifications page,\n      // on every push message forwarded from the service worker, and — the decisive one — from\n      // signalRService.onReconnected. A flapping SignalR connection reconnects repeatedly, so a dialog here\n      // would fire once per reconnect for as long as the network is unhappy. That is the dialog storm this\n      // whole channel exists to prevent, arriving from the inside. A stale unread badge costs the user nothing.\n      if (apiResponse.success) {\n        this.notificationCount.next(apiResponse.data);\n      }\n    });\n  }\n\n  refreshCount() {\n    this.loadNotifications();\n  }\n}\n","// Frontend service for Agent chat — state management, API calls, and SignalR subscriptions (renamed from AssistantService)\nimport { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { DataServiceLib } from './datalib.service';\nimport { SignalRService } from './signalr.service';\nimport { ApiErrorService } from './api-error.service'; // Added: the two chat calls a user actually asks for report; the widget's own startup loads deliberately do not (WS-6 Phase 4)\n\n// Message interface for UI rendering (renamed from AssistantMessage)\nexport interface AgentMessage {\n  conversationId?: number;\n  role: 'user' | 'assistant';\n  content: string;\n  intent?: string;\n  createdDate: Date;\n  pending?: boolean; // Changed: voice/photo placeholder shown until the backend returns what it heard or saw\n  divider?: boolean; // Changed: not a message — a rendered boundary between conversations\n}\n\n// Conversation summary for list view\nexport interface ConversationSummary {\n  conversationID: number;\n  title: string;\n  appName: string;\n  createdDate: Date;\n  lastActivityDate?: Date; // Changed: real recency, so the switcher orders by when a thread was last used\n}\n\n// Changed: the structured half of a reply. The agent has always known it was holding a half-built Customer\n// with two fields missing; until now that only existed as prose inside the message text, so the UI could not\n// show it. Everything here is optional — a plain answer carries no session state at all.\nexport interface AgentSessionInfo {\n  sessionType?: string;\n  modelName?: string;\n  missingFields?: string[];\n  conversationID?: number;\n  newConversation?: boolean;\n  notice?: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class AgentService { // Changed: Renamed from AssistantService\n\n  private messages = new BehaviorSubject<AgentMessage[]>([]);\n  private conversations = new BehaviorSubject<ConversationSummary[]>([]);\n  private typing = new BehaviorSubject<boolean>(false);\n  private isOpen = new BehaviorSubject<boolean>(false);\n  private currentConversationId = new BehaviorSubject<number | null>(null);\n  private greeting = new BehaviorSubject<string>('');\n  private suggestedQuestions = new BehaviorSubject<string[]>([]);\n  private sessionInfo = new BehaviorSubject<AgentSessionInfo | null>(null); // Changed: what the agent is in the middle of\n\n  messages$ = this.messages.asObservable();\n  conversations$ = this.conversations.asObservable();\n  typing$ = this.typing.asObservable();\n  isOpen$ = this.isOpen.asObservable();\n  currentConversationId$ = this.currentConversationId.asObservable();\n  greeting$ = this.greeting.asObservable();\n  suggestedQuestions$ = this.suggestedQuestions.asObservable();\n  sessionInfo$ = this.sessionInfo.asObservable();\n\n  constructor(\n    private dataService: DataServiceLib,\n    private signalRService: SignalRService,\n    private apiErrorService: ApiErrorService // Changed: injected for loadMessages and deleteConversation only\n  ) {\n    this.initListeners();\n  }\n\n  // App name derived from the existing appConfig\n  get appName(): string {\n    return this.dataService.appConfig.appName || 'App';\n  }\n\n  // Agent name derived from appConfig (changed from assistantName)\n  get agentName(): string {\n    return `${this.appName} Agent`;\n  }\n\n  // Subscribe to SignalR events for real-time message delivery\n  private initListeners() {\n    // Changed: SignalR is the SECOND path to a reply, not the only one. It still matters — a turn started on\n    // the phone should appear on the desktop — but it now goes through the same deduping append as the HTTP\n    // answer, so the common case (both arrive) shows one bubble rather than two.\n    this.signalRService.agentMessage$.subscribe(msg => { // Changed: was assistantMessage$\n      if (msg && msg.content) {\n        this.addAssistantMessage(msg.content);\n      }\n    });\n\n    this.signalRService.agentTyping$.subscribe(typing => { // Changed: was assistantTyping$\n      this.typing.next(typing);\n    });\n  }\n\n  // Load agent config (greeting + suggested questions) from backend\n  loadConfig() {\n    this.dataService.CallApi({ url: `agent/config/${this.appName}` }).subscribe(res => { // Changed: was assistant/config\n      // DELIBERATELY SILENT (WS-6 Phase 4 triage). Greeting text and suggested-question chips are decoration\n      // on a chat window that works perfectly without them — the user can still type. Nothing they can see is\n      // wrong, so there is nothing truthful to tell them.\n      if (res.success && res.data) {\n        this.greeting.next(res.data.greeting || '');\n        this.suggestedQuestions.next(res.data.suggestedQuestions || []);\n      }\n    });\n  }\n\n  // Load user's conversation list\n  loadConversations() {\n    this.dataService.CallApi({ url: 'agent/conversations' }).subscribe(res => { // Changed: was assistant/conversations\n      // DELIBERATELY SILENT (WS-6 Phase 4 triage), and this was the closest call in the sweep — an empty\n      // thread list IS a false statement about the user's own history. It stays silent because of WHEN it\n      // fires: agent.component.ts:212 calls it from the widget's ngOnInit, so it runs on every app-shell load\n      // whether or not anyone opens the chat. Converting would put a dialog in front of every user of the app\n      // for a list none of them had asked to see. loadMessages() below — which only ever runs because someone\n      // clicked a specific thread — is the one that reports, and it covers the same outage the moment the\n      // list is actually used.\n      if (res.success) {\n        this.conversations.next(res.data || []);\n      }\n    });\n  }\n\n  // Load messages for a specific conversation\n  loadMessages(conversationId: number) {\n    this.currentConversationId.next(conversationId);\n    this.dataService.CallApi({ url: `agent/conversations/${conversationId}/messages` }).subscribe(res => { // Changed: was assistant/conversations\n      // CONVERTED (WS-6 Phase 4 triage). Unlike everything else in this service, this only runs because the\n      // user clicked a named conversation in the switcher. Failing left the thread pane holding the PREVIOUS\n      // conversation's messages under the new conversation's id — so the next thing they typed would have\n      // been sent into a thread they were not looking at.\n      if (!res.success) this.apiErrorService.presentAppFailure(res, 'load', `agent/conversations/${conversationId}/messages`);\n      if (res.success) {\n        this.messages.next((res.data || []).map((m: any) => ({\n          conversationId: m.conversationID,\n          role: m.role,\n          content: m.content,\n          intent: m.intent,\n          createdDate: new Date(m.createdDate)\n        })));\n      }\n    });\n  }\n\n  // Send a message — optimistically add user message, then POST to backend\n  sendMessage(text: string) {\n    if (!text.trim()) return;\n\n    // Optimistic: add user message immediately\n    const current = this.messages.value;\n    this.messages.next([...current, { role: 'user', content: text, createdDate: new Date() }]);\n\n    // Changed: the HTTP response is now the AUTHORITATIVE reply. It used to be discarded entirely and the\n    // answer was expected to arrive over SignalR — so with the hub down, or real-time switched off, the\n    // server answered and the user saw nothing at all. The request that asked the question is the one that\n    // carries the answer; SignalR is now only a cross-device echo, deduped on arrival.\n    this.dataService.CallApi(\n      { url: 'agent/message', method: 'post' }, // Changed: was assistant/message\n      { text, appName: this.appName }\n    ).subscribe({\n      next: (res: any) => {\n        this.typing.next(false);\n\n        const reply = res?.data?.message;\n        if (reply) this.addAssistantMessage(reply);\n\n        this.applySessionInfo(res?.data?.sessionInfo);\n      },\n      error: () => {\n        this.typing.next(false);\n        this.addAssistantMessage('Sorry, that could not be sent. Please check your connection and try again.');\n      }\n    });\n  }\n\n  // Changed: one place that appends an assistant reply, so the HTTP answer and the SignalR echo of the same\n  // answer cannot both land. Matching on content against the last few messages rather than an id because the\n  // two paths carry no shared identifier — and the failure being prevented (the same answer shown twice) is\n  // more annoying than the rare case this suppresses (a genuine identical repeat).\n  private addAssistantMessage(content: string) {\n    const recent = this.messages.value.slice(-4);\n    if (recent.some(m => m.role === 'assistant' && m.content === content)) return;\n\n    this.messages.next([...this.messages.value, {\n      role: 'assistant',\n      content,\n      createdDate: new Date()\n    }]);\n  }\n\n  // Changed: keeps the widget's idea of \"what am I in the middle of\" in step with the server's, and draws the\n  // boundary when a conversation rolls over so the user can see why the agent stopped referring to earlier\n  // messages. Without a visible line, a rollover looks like the agent simply forgetting.\n  private applySessionInfo(info: AgentSessionInfo | null | undefined) {\n    if (!info) {\n      this.sessionInfo.next(null);\n      return;\n    }\n\n    if (info.newConversation) {\n      if (info.conversationID) this.currentConversationId.next(info.conversationID);\n      this.messages.next([...this.messages.value, {\n        role: 'assistant',\n        content: 'New conversation',\n        createdDate: new Date(),\n        divider: true\n      }]);\n      this.loadConversations();\n    }\n\n    // A finished operation reports no session type — that is the signal to clear the banner\n    this.sessionInfo.next(info.sessionType ? info : null);\n  }\n\n  // Transcribe a recording WITHOUT invoking the agent — backs the composer's Stop button, so the user can\n  // review and edit what was heard before deciding to send.\n  transcribeOnly(audio: Blob, fileName: string) {\n    const form = new FormData();\n    form.append('audio', audio, fileName);\n    return this.dataService.CallApi({ url: 'agent/transcribe', method: 'post', isFormData: true }, form);\n  }\n\n  // One hands-free spoken turn: audio in, spoken answer out, in a single round trip. The reply comes back\n  // twice over — replyText verbatim for the transcript panel, spokenText as actually voiced — because a long\n  // list is summarised before it is spoken.\n  voiceTurn(audio: Blob, fileName: string) {\n    const form = new FormData();\n    form.append('audio', audio, fileName);\n    form.append('appName', this.appName);\n    return this.dataService.CallApi({ url: 'agent/voice-turn', method: 'post', isFormData: true }, form);\n  }\n\n  // Puts what was heard into the conversation thread, so a spoken turn reads like a typed one. Only the user\n  // side is added here — the agent's reply arrives over SignalR exactly as it does for a typed message, and\n  // adding it here as well would show it twice.\n  appendSpokenMessage(text: string) {\n    if (!text || !text.trim()) return;\n    this.messages.next([...this.messages.value, { role: 'user', content: text.trim(), createdDate: new Date() }]);\n  }\n\n  // Send a composed message — any combination of a staged photo, a voice clip and typed text, in one go.\n  // A placeholder user bubble goes up immediately and is swapped for the derived text when the backend\n  // replies, which also keeps it above the assistant's answer (that arrives over SignalR mid-request).\n  sendComposed(photo: Blob | null, photoName: string, audio: Blob | null, audioName: string, caption: string = '') {\n    const hasPhoto = !!(photo && photo.size);\n    const hasAudio = !!(audio && audio.size);\n    if (!hasPhoto && !hasAudio && !caption.trim()) return;\n\n    const placeholder: AgentMessage = {\n      role: 'user',\n      content: caption.trim() || (hasAudio ? 'Voice note…' : 'Photo…'),\n      createdDate: new Date(),\n      pending: true\n    };\n\n    this.messages.next([...this.messages.value, placeholder]);\n    this.typing.next(true);\n\n    const form = new FormData();\n    if (hasPhoto) form.append('photo', photo!, photoName);\n    if (hasAudio) form.append('audio', audio!, audioName);\n    form.append('text', caption.trim());\n    form.append('appName', this.appName);\n\n    this.dataService.CallApi({ url: 'agent/media', method: 'post', isFormData: true }, form).subscribe({\n      next: (res: any) => {\n        this.typing.next(false);\n\n        if (res?.success && res.data?.inputText) {\n          this.replaceMessage(placeholder, { ...placeholder, content: res.data.inputText, pending: false });\n          return;\n        }\n\n        // Nothing usable came back — drop the placeholder and say why\n        this.removeMessage(placeholder);\n        this.messages.next([...this.messages.value, {\n          role: 'assistant',\n          content: res?.message || 'Sorry, I could not process that. Please try again.',\n          createdDate: new Date()\n        }]);\n      },\n      error: () => {\n        this.typing.next(false);\n        this.removeMessage(placeholder);\n        this.messages.next([...this.messages.value, {\n          role: 'assistant',\n          content: 'Sorry, that could not be sent. Please check your connection and try again.',\n          createdDate: new Date()\n        }]);\n      }\n    });\n  }\n\n  // Changed: kept so existing callers of the single-attachment API keep working\n  sendMedia(file: Blob, fileName: string, kind: 'voice' | 'photo', caption: string = '') {\n    if (kind === 'voice') this.sendComposed(null, '', file, fileName, caption);\n    else this.sendComposed(file, fileName, null, '', caption);\n  }\n\n  // Swap a message in place so its position in the thread is preserved\n  private replaceMessage(target: AgentMessage, updated: AgentMessage) {\n    const msgs = this.messages.value.slice();\n    const index = msgs.indexOf(target);\n    if (index < 0) return;\n    msgs[index] = updated;\n    this.messages.next(msgs);\n  }\n\n  private removeMessage(target: AgentMessage) {\n    this.messages.next(this.messages.value.filter(m => m !== target));\n  }\n\n  // Start a new conversation — only when user explicitly clicks \"New conversation\"\n  newConversation() {\n    this.messages.next([]);\n    this.currentConversationId.next(null);\n    this.dataService.CallApi(\n      { url: 'agent/conversations', method: 'post' },\n      { appName: this.appName }\n    ).subscribe(res => {\n      // DELIBERATELY SILENT (WS-6 Phase 4 triage). The UI has already done the thing the user asked for —\n      // messages cleared, id nulled, a blank thread on screen — before this call is even made. All the server\n      // round trip adds is a pre-allocated id, and sendMessage() creates one anyway when there is none. So a\n      // failure here changes nothing the user can see or do.\n      if (res.success && res.data) {\n        this.currentConversationId.next(res.data.conversationID);\n      }\n    });\n  }\n\n  // Delete a conversation\n  deleteConversation(id: number) {\n    this.dataService.CallApi({ url: `agent/conversations/${id}/delete`, method: 'post' }).subscribe(res => { // Changed: was agent/conversations/${id}, which is DELETE-only on the API — this POST hit a 405 every time and the conversation was never deleted\n      // CONVERTED (WS-6 Phase 4 triage). A delete the user pressed. Failing left the conversation sitting in\n      // the list exactly as it was, which reads as \"the button did nothing\" — and the answer to a button that\n      // did nothing is to press it again. Note the comment on the URL below: this endpoint has already been\n      // wrong once (a 405 on every call), and it was silence that let that survive.\n      if (!res.success) this.apiErrorService.presentAppFailure(res, 'action', `agent/conversations/${id}/delete`);\n      if (res.success) {\n        this.loadConversations();\n        if (this.currentConversationId.value === id) {\n          this.messages.next([]);\n          this.currentConversationId.next(null);\n        }\n      }\n    });\n  }\n\n  // Changed: Load the most recent conversation's messages on first open\n  private hasLoadedInitial = false;\n\n  // Toggle chat window open/closed\n  toggle() {\n    const opening = !this.isOpen.value;\n    this.isOpen.next(opening);\n    if (opening && !this.hasLoadedInitial) {\n      this.hasLoadedInitial = true;\n      this.restoreLastConversation(); // Changed: Load previous chat on first open\n    }\n  }\n  open() {\n    this.isOpen.next(true);\n    if (!this.hasLoadedInitial) {\n      this.hasLoadedInitial = true;\n      this.restoreLastConversation();\n    }\n  }\n  close() { this.isOpen.next(false); }\n\n  // Changed: Fetch conversation list and load the most recent one's messages\n  private restoreLastConversation() {\n    this.dataService.CallApi({ url: 'agent/conversations' }).subscribe(res => {\n      if (res.success && res.data?.length > 0) {\n        this.conversations.next(res.data);\n        const latest = res.data[0]; // Backend returns ordered by CreatedDate desc\n        this.currentConversationId.next(latest.conversationID);\n        this.loadMessages(latest.conversationID);\n      }\n    });\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { Router, NavigationEnd } from '@angular/router';\nimport { filter } from 'rxjs/operators';\n\n// Declare gtag as a global function\ndeclare let gtag: Function;\n\n@Injectable({ providedIn: 'root' })\nexport class AnalyticsService {\n\n  private initialized = false;\n\n  constructor(private router: Router) {}\n\n  // Changed: Accept production flag and measurement ID — only loads GA in production\n  init(production: boolean, measurementId: string) {\n    if (!production || !measurementId || this.initialized) return; // Changed: Skip GA on non-production environments\n    this.initialized = true;\n    this.loadGtagScript(measurementId); // Changed: Dynamically inject gtag script\n    this.router.events.pipe(\n      filter(event => event instanceof NavigationEnd)\n    ).subscribe((event: NavigationEnd) => {\n      const url = event.urlAfterRedirects || event.url;\n      // Strip hash prefix so GA sees clean paths (e.g. /home/invoices instead of #/home/invoices)\n      const pagePath = url.replace(/^#/, '') || '/';\n      this.sendPageView(pagePath);\n    });\n  }\n\n  // Changed: Dynamically load the gtag.js script and configure the measurement ID\n  private loadGtagScript(measurementId: string) {\n    const script = document.createElement('script');\n    script.async = true;\n    script.src = `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;\n    document.head.appendChild(script);\n\n    (window as any).dataLayer = (window as any).dataLayer || [];\n    (window as any).gtag = function() { (window as any).dataLayer.push(arguments); };\n    gtag('js', new Date());\n    gtag('config', measurementId, { send_page_view: false }); // Changed: Disable auto page_view — route tracking sends them\n  }\n\n  // Send page_view event to GA4\n  private sendPageView(pagePath: string) {\n    if (typeof gtag === 'function') {\n      gtag('event', 'page_view', {\n        page_path: pagePath,\n        page_location: window.location.origin + pagePath\n      });\n    }\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable, of } from 'rxjs'; // Changed (F3): of — ensureModules() answers synchronously when there is nothing to wait for\nimport { catchError, map, shareReplay, tap } from 'rxjs/operators'; // Added (F3): ensureModules() pipeline\nimport { DataServiceLib } from './datalib.service';\nimport { ApiResponse, SetupModule, SetupPresetSelection, SetupRoleTemplate, SetupStatus } from '../classes/Classes'; // Changed: SetupPresetSelection — the apply POST body item for the notification preset picker\nimport { ApiErrorService } from './api-error.service'; // Added: loadStatus is page-driven and must report; the two badge loads around it deliberately stay silent (WS-6 Phase 4)\n\n// Setup readiness (\"Getting Started\") service — NotificationsService mirror without SignalR.\n// Dormant unless appConfig.setupConfig.enabled; API failures leave count at 0 so the badge stays hidden.\n// v2 adds the module catalog (drives step + nav-menu gating) and predefined role templates.\n@Injectable({\n  providedIn: 'root'\n})\nexport class SetupService {\n\n  private pendingCount = new BehaviorSubject<number>(0);\n  pendingCount$ = this.pendingCount.asObservable();\n\n  private status = new BehaviorSubject<SetupStatus | null>(null);\n  status$ = this.status.asObservable();\n\n  // Added (v2): module catalog — empty means the app has no module concept (nothing is ever hidden)\n  private modules = new BehaviorSubject<SetupModule[]>([]);\n  modules$ = this.modules.asObservable();\n\n  private modulesLoaded = false; // Added (F3): a guard must be able to tell \"the catalog is genuinely empty\" from \"it has not been fetched yet\"\n  private modulesInFlight: Observable<SetupModule[]> | null = null; // Added (F3): de-dupes concurrent guard activations on a deep route\n\n  constructor(private dataService: DataServiceLib, private apiErrorService: ApiErrorService) { } // Changed: injected for loadStatus only\n\n  get enabled(): boolean {\n    return !!this.dataService.appConfig?.setupConfig?.enabled;\n  }\n\n  // Lightweight badge count — called on login and nav-menu init\n  loadCount() {\n    if (!this.enabled) return;\n    this.dataService.CallApi({ url: 'setup/count', skipCache: true }).subscribe({\n      next: (apiResponse: ApiResponse) => {\n        // DELIBERATELY SILENT (WS-6 Phase 4 triage). A badge count, fired from login and from nav-menu init.\n        // Failing leaves the badge hidden, which is the same thing it shows when there is genuinely nothing\n        // pending — and \"you have no setup left\" is a harmless thing to under-report for a moment, because\n        // the Getting Started PAGE itself reports properly (see loadStatus below). A dialog on nav init would\n        // fire on every shell load for every user of an app whose SetupController is having a bad day.\n        if (apiResponse.success) this.pendingCount.next(apiResponse.data);\n      },\n      error: () => { } // Backend without SetupController — keep badge hidden\n    });\n  }\n\n  // Full step catalog — called by the Getting Started page and after step actions\n  loadStatus() {\n    if (!this.enabled) return;\n    this.dataService.CallApi({ url: 'setup/status', skipCache: true }).subscribe({\n      next: (apiResponse: ApiResponse) => {\n        // CONVERTED, unlike its two neighbours in this file, and the difference is who asked. This one has\n        // exactly two callers — setup-guide.component.ts ngOnInit and refresh() from that same page — so it\n        // only ever runs because someone opened Getting Started or just completed a step there. Failing left\n        // the page rendering an empty checklist, which reads as \"there is nothing to set up\" to the one user\n        // who is by definition new and has no way to know better. (WS-6 Phase 4 triage)\n        if (!apiResponse.success) this.apiErrorService.presentAppFailure(apiResponse, 'load', 'setup/status');\n        if (apiResponse.success) {\n          this.status.next(apiResponse.data);\n          this.pendingCount.next(apiResponse.data?.pending ?? 0);\n          this.modules.next(apiResponse.data?.modules ?? []); // Added (v2): status carries the module catalog too\n          this.modulesLoaded = true; // Added (F3): status carries the catalog, so a Getting Started visit satisfies ensureModules() too\n        }\n      },\n      error: () => { }\n    });\n  }\n\n  // Added (v2): module catalog alone — called on nav init so menu gating works without visiting the page\n  loadModules() {\n    if (!this.enabled) return;\n    this.dataService.CallApi({ url: 'setup/modules', skipCache: true }).subscribe({\n      next: (apiResponse: ApiResponse) => {\n        // DELIBERATELY SILENT (WS-6 Phase 4 triage). Nav-menu init, and isModuleEnabled() below FAILS OPEN by\n        // design — an empty catalog hides nothing, so a failure here makes the app MORE visible, never less.\n        // There is no user-facing loss to report. It also runs on every shell init, which is precisely where\n        // a dialog becomes a wall.\n        if (apiResponse.success) this.modules.next(apiResponse.data ?? []);\n        this.modulesLoaded = true; // Added (F3): answered either way — a failed load leaves the catalog empty, and empty means \"hide nothing\"\n      },\n      error: () => { this.modulesLoaded = true; } // Changed (F3): a backend without module support must not leave every later ensureModules() re-requesting\n    });\n  }\n\n  // Added (F3): awaitable catalog for moduleGuard. Reading the BehaviorSubject at route-resolution time is not\n  // enough — on a deep link or an F5 the catalog has not arrived yet, so a guard would read empty and fail open on\n  // exactly the path it exists to protect. Fails open on every unhappy path (setup disabled, no SetupController,\n  // 401, error) because hiding working functionality is the worse error, matching isModuleEnabled below and the\n  // server's ModuleCatalog.IsEnabled. shareReplay collapses the several child activations of one deep route into\n  // a single setup/modules request.\n  ensureModules(): Observable<boolean> {\n    if (!this.enabled || this.modulesLoaded) return of(true);\n    if (!this.modulesInFlight) {\n      this.modulesInFlight = this.dataService.CallApi({ url: 'setup/modules', skipCache: true }).pipe(\n        map((apiResponse: ApiResponse) => (apiResponse.success ? apiResponse.data ?? [] : [])),\n        tap((mods: SetupModule[]) => { this.modules.next(mods); this.modulesLoaded = true; this.modulesInFlight = null; }),\n        catchError(() => { this.modulesLoaded = true; this.modulesInFlight = null; return of([] as SetupModule[]); }),\n        shareReplay(1)\n      ) as Observable<SetupModule[]>;\n    }\n    return this.modulesInFlight.pipe(map(() => true));\n  }\n\n  // Added (F3): the refusal toast names the module, not the key — falls back to the key for an app whose route\n  // declares a key the server's catalog does not carry\n  moduleTitle(key: string): string {\n    return this.modules.value?.find(m => m.key === key)?.title ?? key;\n  }\n\n  // Added (v2): nav-menu gate — unknown keys and apps without modules always pass (fail open)\n  isModuleEnabled(key: string): boolean {\n    if (!key) return true;\n    const mods = this.modules.value;\n    if (!mods || mods.length === 0) return true;\n    const mod = mods.find(m => m.key === key);\n    return !mod || mod.enabled;\n  }\n\n  // Added (v2): toggle a module (or 'confirm' the selection) — server persists onto app configuration\n  setModule(key: string, enabled: boolean): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/module', method: 'post', skipCache: true }, { key, enabled }) as Observable<ApiResponse>;\n  }\n\n  // Added (v2): predefined role templates for the roles step\n  loadRoleTemplates(): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/roletemplates', skipCache: true }) as Observable<ApiResponse>;\n  }\n\n  // Added (v2): create tenant roles from the selected templates\n  createRoles(keys: string[]): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/roles', method: 'post', skipCache: true }, { keys }) as Observable<ApiResponse>;\n  }\n\n  // Added (presets): the notification rules on offer for this tenant, plus the roles the picker chooses a\n  // recipient from. skipCache like every other setup call — Exists is stamped per request and a cached\n  // catalogue would re-offer rules the user just created.\n  loadNotificationPresets(): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/notificationpresets', skipCache: true }) as Observable<ApiResponse>;\n  }\n\n  // Added (presets): create notification rules from the ticked presets. Create-only server-side — unticking a\n  // rule that already exists deletes nothing, so this can never undo a deliberate user choice.\n  applyNotificationPresets(items: SetupPresetSelection[], includeEmail: boolean): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/notifications', method: 'post', skipCache: true }, { items, includeEmail }) as Observable<ApiResponse>;\n  }\n\n  // Added (presets P4): the approval rules on offer, plus the roles that can ACTUALLY approve — the backend filters\n  // that list to roles somebody is a member of, because since SEC-10 only a member of the level's role can release a\n  // held record, so offering an empty role would build a config nobody could action.\n  loadApprovalPresets(): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/approvalpresets', skipCache: true }) as Observable<ApiResponse>;\n  }\n\n  // Added (presets P4): create approval rules from the ticked presets. Create-only server-side, exactly like the\n  // notification apply. No includeEmail — an approval request is always in-app (an approver who misses it leaves\n  // records held), so the body deliberately carries items alone.\n  applyApprovalPresets(items: SetupPresetSelection[]): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/approvals', method: 'post', skipCache: true }, { items }) as Observable<ApiResponse>;\n  }\n\n  // Added (seed seam): the example-data offers this tenant's steps can make. skipCache like every other setup\n  // call, and here it is not optional — wouldCreate, existing and applied are stamped per REQUEST, so a cached\n  // catalogue would keep offering rows the user has just created and keep the counts wrong.\n  loadSeedOffers(): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/seedoffers', skipCache: true }) as Observable<ApiResponse>;\n  }\n\n  // Added (seed seam): apply ONE offer, plus whatever that offer declares it needs first — the server walks the\n  // dependency chain, so the caller sends a single key. A POST, not a GET, and the server requires Edit: the two\n  // seed buttons this replaces are both writes reachable by a View-only user, and that is not carried forward.\n  applySeedOffer(key: string): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/seed', method: 'post', skipCache: true }, { key }) as Observable<ApiResponse>;\n  }\n\n  // Added (seed-all): fill every area that is still empty, in ONE request. The client sends no list — the server\n  // loops the SAME offer catalogue, applies only the offers whose own area still has something to add, and skips\n  // anything the user lacks Edit on. Deliberately NOT a client-side loop over applySeedOffer(): that would put the\n  // judgement about what counts as \"empty\" in the browser, which is exactly where the demo-data card's one global\n  // sentinel already went wrong, and it would produce one audit entry and one toast per area.\n  applySeedAll(): Observable<ApiResponse> {\n    return this.dataService.CallApi({ url: 'setup/seed-all', method: 'post', skipCache: true }, {}) as Observable<ApiResponse>;\n  }\n\n  refresh() {\n    this.loadStatus();\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { DataServiceLib } from './datalib.service';\nimport { ApiResponse } from '../classes/Classes';\n\n// Added: the app-wide App Configuration record, loaded once and shared. Apps used to each solve this\n// themselves — Shift kept a copy in localStorage that went stale the moment anyone saved on another\n// device, and Grip had no frontend access to its own config at all. Anything that needs a config flag\n// (nav gating, unit suffixes, module-dependent columns) subscribes to config$; spa-app-configuration\n// refreshes it after every save, so a saved change reaches those subscribers immediately.\n@Injectable({\n  providedIn: 'root'\n})\nexport class ConfigService {\n\n  private config = new BehaviorSubject<any>({});\n  config$ = this.config.asObservable();\n\n  get value(): any {\n    return this.config.value;\n  }\n\n  private loaded = false;\n\n  // Added: one attempt at a time. Two callers racing on login used to be harmless only because the latch below\n  // swallowed the second; with the latch corrected they would both hit the wire, so dedupe explicitly instead.\n  private inFlight = false;\n\n  // Added: the bound. Retrying is CALLER-DRIVEN — there is no timer and no resubscribe here, so a retry only\n  // ever happens because something asked again. This cap stops a chatty caller (a component that loads on every\n  // navigation) from turning a genuinely down API into one request per navigation, forever.\n  private failedAttempts = 0;\n  private static readonly maxFailedAttempts = 3;\n\n  constructor(private dataService: DataServiceLib) { }\n\n  // Called on login/bootstrap — the backend creates the row on first read, so this never comes back empty\n  load(force = false) {\n    // Changed: `loaded` was set HERE, before the request, and every failure was swallowed — so the FIRST attempt\n    // won the session outright. shift-spa fired one on the login screen (AuthService seeds currentRoleSource with\n    // a truthy `new Role`, and a BehaviorSubject replays its seed synchronously), it 401'd with an empty bearer\n    // token, and every later authenticated caller returned early forever. The app then ran on an empty config —\n    // every flag false, ~70 call sites — while the database said otherwise. Only a page reload masked it, which\n    // is why it survived: silent-restore replays the 401'd request, a fresh interactive login does not.\n    if (force) this.failedAttempts = 0; // an explicit refresh is a deliberate act (the App Configuration page just saved), so it is allowed past the cap\n    if (this.loaded && !force) return;\n    if (this.inFlight && !force) return;\n    if (this.failedAttempts >= ConfigService.maxFailedAttempts && !force) return;\n    this.inFlight = true;\n    this.dataService.CallApi({ url: 'configuration/get', skipCache: true }).subscribe({\n      next: (apiResponse: ApiResponse) => {\n        this.inFlight = false;\n        // DELIBERATELY SILENT (WS-6 Phase 4 triage). This runs on login/bootstrap, before the user has asked\n        // for anything, and greeting someone with an error dialog the instant they sign in, for an app that then\n        // works, is a worse lie than saying nothing. The error callback below absorbs the transport case likewise.\n        // Changed: the old comment claimed everything downstream FAILS OPEN. It does not. Config flags are read as\n        // `!!config.enableX` and the database defaults are TRUE, so an empty config reads FALSE and HIDES things —\n        // fail-CLOSED. Staying silent is still right; latching the failure was not. Retry stays possible instead.\n        if (apiResponse.success) {\n          this.loaded = true; // Changed: only a response that actually carried a config counts as loaded\n          this.failedAttempts = 0;\n          this.config.next(apiResponse.data || {});\n        }\n        else this.failedAttempts++; // Added: a refusal (401/403 shaped as success:false) is a failure, not a loaded config\n      },\n      error: () => {\n        // an app without a ConfigurationController simply keeps the empty object — and after maxFailedAttempts\n        // stops asking, so the 404 costs three requests a session rather than one, and never more\n        this.inFlight = false;\n        this.failedAttempts++;\n      }\n    });\n  }\n\n  refresh() {\n    this.load(true);\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs';\nimport { CapItem, Constants } from '../classes/Classes'; // Changed: CapItem — the saved route is validated against the menu the current role can see\nimport { DataServiceLib } from './datalib.service';\nimport { StorageService } from './storage.service';\n\n// Resume-last-route: remembers the page a user was last on and lands them back there on the next\n// login/session resume, instead of always dumping them on the default start page.\n// Opt-in per app via AppConfig.resumeLastRoute (off by default, like keepSignedIn).\n// Stored persistently (survives browser close) and keyed BY USER, so a shared device never\n// resumes one person into another person's last page.\n@Injectable({ providedIn: 'root' })\nexport class LastRouteService {\n\n  private started = false;\n\n  // Transient/parameterised routes must never be resumed into: a record may be gone, and\n  // change-password/setup are one-shot detours, not places to live.\n  private excluded = ['home/user/change-password', 'home/setup'];\n\n  constructor(private router: Router, private storage: StorageService, private dataService: DataServiceLib) { }\n\n  get enabled(): boolean { return !!this.dataService.appConfig?.resumeLastRoute; }\n\n  // The signed-in user, read from storage rather than AuthService.currentUser — currentUser is hydrated\n  // asynchronously and still holds its placeholder default during a session resume, which would key the\n  // saved route under the wrong user and silently lose it.\n  private async user(): Promise<string | null> {\n    const name = await this.storage.get(Constants.AUTH_USER);\n    return name ? String(name).toLowerCase() : null;\n  }\n\n  // Started once from the nav shell (which only exists while signed in) — records every completed navigation\n  start(): void {\n    if (!this.enabled || this.started) return;\n    this.started = true;\n\n    this.router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(async (e: any) => {\n      const route = this.normalize(e.urlAfterRedirects || e.url);\n      if (!route) return;\n      const user = await this.user();\n      if (user) this.save(user, route);\n    });\n  }\n\n  // Landing target for a resumed session: the saved route, or null to fall back to the caller's default\n  async resolve(): Promise<string | null> {\n    if (!this.enabled) return null;\n    const user = await this.user();\n    if (!user) return null;\n    const map = this.storage.getPersistent(Constants.LAST_ROUTE) || {};\n    const route = map[user];\n    if (!this.isResumable(route)) return null;\n    // Changed: a page the role can no longer open (capability revoked, menu item retired) must not be resumed —\n    // drop it so the next visit goes straight to the default page instead of re-testing a dead entry\n    if (!(await this.allowed(route))) { await this.clear(); return null; }\n    return route;\n  }\n\n  // Added: single navigation entry point for callers resuming a session. Falls back to the app's default page\n  // when the saved route no longer exists — without this a removed route falls through the app's wildcard\n  // route (which redirects back to the landing page) and the user bounces instead of landing anywhere.\n  async navigateTo(target: string, fallback: string = 'home'): Promise<void> {\n    if (!target || target === fallback) { this.router.navigate([fallback]); return; }\n    const ok = await this.router.navigate([target]).catch(() => false);\n    const landed = this.strip(this.router.url);\n    if (ok && (landed === target || landed.startsWith(target + '/'))) return;\n    await this.clear(); // stale entry — never send anyone here again\n    this.router.navigate([fallback]);\n  }\n\n  // Explicit logoff drops only this user's entry — other users on the device keep theirs\n  async clear(): Promise<void> {\n    const user = await this.user();\n    if (!user) return;\n    const map = this.storage.getPersistent(Constants.LAST_ROUTE) || {};\n    delete map[user];\n    this.storage.storePersistent(Constants.LAST_ROUTE, map);\n  }\n\n  private save(user: string, route: string): void {\n    const map = this.storage.getPersistent(Constants.LAST_ROUTE) || {};\n    map[user] = route;\n    this.storage.storePersistent(Constants.LAST_ROUTE, map);\n  }\n\n  // Strip the leading slash and any query/fragment so what we store matches what router.navigate expects\n  private normalize(url: string): string | null {\n    const route = this.strip(url); // Changed: share the stripping with navigateTo's landed-URL check\n    return this.isResumable(route) ? route : null;\n  }\n\n  // Added: url → bare route (no leading slash, no query, no fragment)\n  private strip(url: string): string {\n    return (url || '').split('?')[0].split('#')[0].replace(/^\\//, '');\n  }\n\n  // Only real, landable pages under home — never the bare shell, never a one-shot detour\n  private isResumable(route: string): boolean {\n    if (!route || !route.startsWith('home/')) return false;\n    return !this.excluded.some(x => route.startsWith(x));\n  }\n\n  // Added: the signed-in user's capability map, read from storage for the same reason as user() —\n  // AuthService.myRole is still empty this early in a session resume (the landing page has no auth guard)\n  private async role(): Promise<any> {\n    try { return JSON.parse(await this.storage.get(Constants.AUTH_ROLES)); } catch { return null; }\n  }\n\n  // Added: a route is resumable only while it still maps to a menu page this role can open. Retired pages lose\n  // their cap item, revoked pages lose their role flag — both land the user on the default page instead.\n  private async allowed(route: string): Promise<boolean> {\n    const items = this.flatten(this.dataService.appConfig?.capItems);\n    if (!items.length) return true; // no menu configured — nothing to validate against, stay permissive\n    const match = items\n      .filter(x => x.link && x.link.length > 'home'.length && (route === x.link || route.startsWith(x.link + '/')))\n      .sort((a, b) => b.link.length - a.link.length)[0]; // longest link wins: 'home/trips' beats the bare 'home'\n    if (!match) return false; // not a menu destination (removed page, or a transient detour) — do not resume\n    const role = await this.role();\n    return role ? !!role[match.name] : true; // unreadable role must not disable the feature — the page still guards itself\n  }\n\n  // Added: cap items nest (group → sub items), so flatten the whole tree before matching a link\n  private flatten(items: CapItem[] | undefined): CapItem[] {\n    return (items || []).reduce((all: CapItem[], x) => all.concat(x, this.flatten(x.capSubItems)), []);\n  }\n}\n","// Tenant transfer service — page/table/form configs for cross-organisation money arrangements.\n//\n// Moved (N11) from grip-spa into tin-spa: the backend is shared library code (TinWeb\n// CrossTenantTransfersController), so the page belongs to the library too — all four apps now get it, gated\n// by cap91 and routed under Accounting (owner directive 2026-08-17: \"defined in the accounting module and menu\").\n// The design commentary from the Grip original carries over verbatim where it still applies.\n//\n// The backend for this is DELIBERATELY NOT a BaseController: TenantLink and TenantTransfer sit outside\n// ITenant so BOTH parties can read the same row, so there is no `?action=list` and no generic CRUD. Every\n// action here is an explicit verb, and the whole authority model lives server-side in\n// CrossTenantTransferService. Consequences:\n//   1. Every loadAction is a plain GET returning RepoResponse.Data.\n//   2. `revoke` is POST crosstenanttransfers/links/{id}/revoke — a PATH parameter, so it is an onClick\n//      handler that builds the url itself. Same for decline, which needs only a confirmation.\n//   3. Accept and Send Money DO need input, so those are real dialogs with their own formConfig.\n//\n// N11 additions on top of the Grip original:\n//   • CROSS-APPLICATION — the propose dialog asks WHICH application first; the organisation list then loads\n//     from that application via the {applicationCode} placeholder (select-common re-fetches on change).\n//   • The transfers caption now states that a cross-application receiver's journal lives in the other\n//     application, correlated by the shared Reference.\nimport { Injectable, inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { Button, DetailsDialogConfig, FormConfig, TableConfig } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\nimport { MessageService } from './message.service';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class TenantTransferService {\n\n  private dataService = inject(DataServiceLib);\n  private messageService = inject(MessageService); // decline/revoke confirm from an onClick handler — a pure-onClick row button is terminal in table.component.actionClicked, so the framework confirm never runs for it\n\n  // Added: the two tables are one story — Send Money is a button on the ARRANGEMENTS table, so a successful\n  // action there must also refresh the Transfers list underneath. The page component wires these.\n  transfersReload = new Subject<boolean>();\n\n  // Changed (N11): which side is \"me\" is now computed SERVER-SIDE (GetLinks projects iAmSender/iAmReceiver)\n  // — a client-side tenant-id comparison can collide across applications, because a cross-app link carries a\n  // foreign id from a different database. The client just reads the flags.\n  private isPending = (x: any) => x?.status === 'Pending';\n  private iAmReceiver = (x: any) => !!x?.iAmReceiver; // the ONLY side that may accept\n  private iAmSender = (x: any) => !!x?.iAmSender; // the ONLY side that may send\n\n  // --------------------------Arrangements (the handshake)-------------------------\n\n  proposeFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTenantTransfers] }, // capability gate — the server refuses these verbs to a non-admin anyway, so the dialog should not offer them either\n    title: 'Propose an arrangement',\n    alertConfig: {\n      compact: true,\n      messages: [\n        { type: 'info', message: 'The other organisation must accept before any money can move. You cannot send to an organisation that has not agreed to receive from you.' },\n        { type: 'warn', message: 'An arrangement is ONE-WAY. It lets YOU send to them. For money to come back the other way, they must propose a separate arrangement to you.' },\n      ]\n    },\n    fields: [\n      // Added (N11): application first, then that application's organisations. The {applicationCode}\n      // placeholder makes the second select re-fetch whenever the first changes.\n      { name: 'applicationCode', type: 'select', alias: 'Application', required: true, span: true, loadAction: { url: 'crosstenanttransfers/applications' }, optionDisplay: 'name', optionValue: 'code', hint: 'Which system the other organisation uses' },\n      { name: 'toTenantID', type: 'select', alias: 'Organisation', required: true, span: true, loadAction: { url: 'crosstenanttransfers/counterparties?application={applicationCode}' }, optionDisplay: 'name', optionValue: 'tenantID', hint: 'Who you want to be able to send money to' },\n      { name: 'accountID', type: 'select', alias: 'Your funding account', span: true, loadAction: { url: 'accounts/list/x' }, nullable: true, hint: 'The account the money leaves. Leave blank to use Bank Account.' },\n      { name: 'note', type: 'text-area', alias: 'Note', rows: 2, span: true, hint: 'Shown to the other organisation when they decide whether to accept' },\n    ]\n  }\n\n  // 🔴 The dialog's SUBMIT button is resolved by NAME ('create') — see the two-step-create ordering rule.\n  proposeSubmitButton: Button = { name: 'create', display: 'Propose', action: { url: 'crosstenanttransfers/links/propose', method: 'post', successMessage: 'Proposed. It is now waiting for the other organisation to accept.' } }\n\n  proposeDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.proposeFormConfig,\n    mode: 'create',\n    buttons: [this.proposeSubmitButton]\n  }\n\n  proposeButton: Button = { name: 'propose', display: 'Propose Arrangement', icon: { name: 'handshake' }, inHeader: true, dialog: true, detailsConfig: this.proposeDetailsConfig }\n\n  acceptFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTenantTransfers] },\n    title: 'Accept this arrangement',\n    alertConfig: {\n      compact: true,\n      messages: [\n        { type: 'info', message: 'Accepting lets the other organisation send money INTO your books. It does not let you send money to them — that would be a separate arrangement, proposed by you.' },\n      ]\n    },\n    fields: [\n      { name: 'accept', type: 'checkbox', hidden: true, defaultValue: true },\n      { name: 'accountID', type: 'select', alias: 'Your receiving account', span: true, loadAction: { url: 'accounts/list/x' }, nullable: true, hint: 'Where incoming money lands. Leave blank to use Bank Account.' },\n    ]\n  }\n\n  acceptSubmitButton: Button = { name: 'create', display: 'Accept Arrangement', action: { url: 'crosstenanttransfers/links/respond', method: 'post', successMessage: 'Accepted. Money can now flow to you over this arrangement.' } }\n\n  acceptDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.acceptFormConfig,\n    mode: 'create', // create merges the clicked row over the generated model, which is how tenantLinkID reaches the DTO\n    buttons: [this.acceptSubmitButton]\n  }\n\n  acceptButton: Button = { name: 'accept', display: 'Accept', icon: { name: 'check_circle' }, color: 'primary', dialog: true, detailsConfig: this.acceptDetailsConfig, visible: (x: any) => this.isPending(x) && this.iAmReceiver(x) }\n\n  declineButton: Button = { name: 'decline', display: 'Decline', icon: { name: 'block' }, visible: (x: any) => this.isPending(x) && this.iAmReceiver(x),\n    onClick: (row: any, reload?: () => void) => {\n      this.messageService.confirm(`Decline the arrangement proposed by ${row?.tenantAName}? They will not be able to send you money.`, 'Decline', 'Keep it open', true).subscribe(result => {\n        if (result !== 'yes') return;\n        this.dataService.CallApi({ url: 'crosstenanttransfers/links/respond', method: 'post' }, { tenantLinkID: row.tenantLinkID, accept: false }).subscribe((response: any) => {\n          this.messageService.toast(response?.success ? 'Declined' : (response?.message || 'Could not decline this arrangement'));\n          if (response?.success && reload) reload();\n        });\n      });\n    }\n  }\n\n  revokeButton: Button = { name: 'revoke', display: 'Revoke', icon: { name: 'link_off' }, visible: (x: any) => (x?.status === 'Pending' || x?.status === 'Accepted'),\n    onClick: (row: any, reload?: () => void) => {\n      this.messageService.confirm(`Revoke the arrangement between ${row?.tenantAName} and ${row?.tenantBName}? No further transfers can be sent over it. Transfers already made are not reversed.`, 'Revoke', 'Keep it', true).subscribe(result => {\n        if (result !== 'yes') return;\n        // The id is a PATH segment here, and Action.url is used literally on a POST — built at click time\n        this.dataService.CallApi({ url: `crosstenanttransfers/links/${row.tenantLinkID}/revoke`, method: 'post' }, {}).subscribe((response: any) => {\n          this.messageService.toast(response?.success ? 'Revoked' : (response?.message || 'Could not revoke this arrangement'));\n          if (response?.success && reload) reload();\n        });\n      });\n    }\n  }\n\n  // --------------------------Sending money-------------------------\n\n  transferFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTenantTransfers] },\n    title: 'Send money',\n    alertConfig: {\n      messages: [\n        { type: 'warn', message: 'There is NO balance check. This will post even if it takes the funding account negative.' },\n        { type: 'info', message: 'The money leaves immediately and sits in your \"Cross-Tenant Transfers in Transit\" account until a background worker posts the receiving side. Nothing clears that balance afterwards — there is no settlement step, so the asset stays on your books and a matching \"Due to\" liability stays on theirs.' },\n      ]\n    },\n    fields: [\n      { name: 'amount', type: 'money', alias: 'Amount', required: true, span: true, min: 0.01, hint: 'Must be greater than zero, and both organisations must share a base currency' },\n      { name: 'description', type: 'text-area', alias: 'Description', rows: 2, span: true, hint: 'Appears on the journal on BOTH sides' },\n      // Date deliberately NOT offered — the server defaults it to today; see the Grip original's note.\n    ]\n  }\n\n  transferSubmitButton: Button = { name: 'create', display: 'Send', action: { url: 'crosstenanttransfers', method: 'post', successMessage: 'Sent. It is in transit until the receiving side posts.' } }\n\n  transferDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.transferFormConfig,\n    mode: 'create',\n    buttons: [this.transferSubmitButton]\n  }\n\n  transferButton: Button = { name: 'send-money', display: 'Send Money', icon: { name: 'payments' }, color: 'primary', dialog: true, detailsConfig: this.transferDetailsConfig, visible: (x: any) => x?.status === 'Accepted' && this.iAmSender(x) }\n\n  // --------------------------Tables-------------------------\n\n  linksTableConfig: TableConfig = {\n    sectionConfig: {\n      title: 'Arrangements',\n      icon: 'handshake',\n      collapsible: false,\n      caption: 'An arrangement is a one-way agreement. Only the Sender may move money over it, and only after the Receiver has accepted. For money to travel the other way, the other organisation must propose its own arrangement back to you.',\n      chips: [\n        { text: 'waiting for you to accept', color: '#FFA726', visible: (rows: any) => (rows || []).some((x: any) => this.isPending(x) && this.iAmReceiver(x)) },\n        { text: 'waiting on them', color: '#90A4AE', visible: (rows: any) => (rows || []).some((x: any) => this.isPending(x) && this.iAmSender(x)) },\n      ]\n    },\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['tenantAName', 'tenantBName', 'status'],\n    identityColumn: 'tenantAName',\n    noDataMessage: 'No arrangements yet. Propose one to another organisation to open a money channel to it.',\n    columns: [\n      { name: 'tenantAName', type: 'chip', alias: 'Sender', icons: [{ name: 'north_east', color: '#42A5F5', condition: (x: any) => this.iAmSender(x), tip: 'This is you — you are the side that may send over this arrangement' }] },\n      { name: 'tenantBName', type: 'chip', alias: 'Receiver', icons: [{ name: 'south_west', color: '#7E57C2', condition: (x: any) => this.iAmReceiver(x), tip: 'This is you — you may only receive over this arrangement, never send' }] },\n      // Added (N11): which application the other side lives in — same-app rows show a quiet dash via the server value\n      { name: 'tenantBApplicationCode', type: 'text', alias: 'Application' },\n      { name: 'status', type: 'chip', alias: 'Status',\n        colors: [\n          { name: '#FFA726', condition: (x: any) => x.status === 'Pending' },\n          { name: '#81C784', condition: (x: any) => x.status === 'Accepted' },\n          { name: '#90A4AE', condition: (x: any) => x.status === 'Declined' },\n          { name: '#E57373', condition: (x: any) => x.status === 'Revoked' }\n        ],\n        icons: [\n          { name: 'hourglass_top', color: '#FFA726', condition: (x: any) => this.isPending(x) && this.iAmReceiver(x), tip: 'Waiting for YOU — only the receiving organisation can accept this' },\n        ]\n      },\n      { name: 'tenantABaseCurrency', type: 'text', alias: 'Currency',\n        icons: [{ name: 'error_outline', color: '#E57373', condition: (x: any) => !!x.tenantBBaseCurrency && x.tenantABaseCurrency !== x.tenantBBaseCurrency, tip: 'The two organisations use different base currencies, so transfers over this arrangement will be refused' }]\n      },\n      { name: 'proposedBy', type: 'text', alias: 'Proposed by' },\n      { name: 'note', type: 'text', alias: 'Note', maxLength: 40 },\n    ],\n    buttons: [this.proposeButton, this.acceptButton, this.declineButton, this.transferButton, this.revokeButton],\n    loadAction: { url: 'crosstenanttransfers/links' }\n  }\n\n  transfersTableConfig: TableConfig = {\n    sectionConfig: {\n      title: 'Transfers',\n      icon: 'swap_horiz',\n      collapsible: false,\n      caption: 'Each transfer is a real double-entry posting on both sides. There is no settlement step: the sender keeps an \"in transit\" asset and the receiver keeps a \"Due to\" liability, and neither ever clears. For a transfer to another application, the receiving journal lives in that application — the shared Reference is the correlation.',\n      chips: [\n        { text: 'money in transit', color: '#FFA726', visible: (rows: any) => (rows || []).some((x: any) => x.status === 'Queued') },\n        { text: 'a transfer failed', color: '#E57373', visible: (rows: any) => (rows || []).some((x: any) => x.status === 'Failed') },\n      ]\n    },\n    showFilter: true,\n    flatButtons: true,\n    minColumns: ['reference', 'amount', 'status'],\n    identityColumn: 'reference',\n    noDataMessage: 'No transfers yet. Send money over an accepted arrangement and it will appear here.',\n    columns: [\n      { name: 'reference', type: 'chip', alias: 'Reference' },\n      { name: 'fromTenantName', type: 'text', alias: 'From' },\n      { name: 'toTenantName', type: 'text', alias: 'To' },\n      { name: 'toApplicationCode', type: 'text', alias: 'Application' }, // Added (N11)\n      { name: 'date', type: 'date-short', alias: 'Date' },\n      { name: 'amount', type: 'money', alias: 'Amount' },\n      { name: 'status', type: 'chip', alias: 'Status',\n        colors: [\n          { name: '#FFA726', condition: (x: any) => x.status === 'Queued' },\n          { name: '#81C784', condition: (x: any) => x.status === 'Completed' },\n          { name: '#E57373', condition: (x: any) => x.status === 'Failed' }\n        ],\n        icons: [\n          { name: 'flight_takeoff', color: '#FFA726', condition: (x: any) => x.status === 'Queued', tip: 'In transit — it has LEFT the sender and sits in their in-transit account. A background worker posts the receiving side. Refresh to watch it land.' },\n          { name: 'error_outline', color: '#E57373', condition: (x: any) => x.status === 'Failed', tip: 'The receiving side could not be posted. The money is stranded in the sender\\'s in-transit account — see the Error column.' },\n        ]\n      },\n      { name: 'description', type: 'text', alias: 'Description', maxLength: 40 },\n      { name: 'error', type: 'text', alias: 'Error', maxLength: 60 },\n    ],\n    loadAction: { url: 'crosstenanttransfers' }\n  }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { catchError, map, shareReplay } from 'rxjs/operators';\nimport { ApiResponse } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\n\n// Added: ONE source for the wording of the password rule. Three surfaces used to each carry their own\n// hard-coded copy of the sentences — spa-users' change-password dialog, the change-password page, and the\n// Password Policy admin card — and two of the three had drifted from the rule the server actually enforces:\n// both said \"At least 2 lowercase letters (a-z)\" while PasswordConfig has always required 1. That is the\n// worst possible place for a stale copy, because the user reads it at the exact moment they are refused.\n//\n// Worse than the wrong number: none of the three read PasswordConfig at all, so a tenant who configured a\n// policy was shown a description of a different one. The admin card was the only surface that generated its\n// sentences from the row the server validates against, so its generator is what moved here — the copies now\n// call it instead of restating it. A fourth copy is the thing this file exists to prevent.\nexport interface PasswordRequirement {\n  text: string;\n  required: boolean;\n}\n\nexport interface PasswordPolicyDescription {\n  requirements: PasswordRequirement[];\n  effectiveLength: number;\n  // True only when the character-class minimums add up to MORE than the configured minimum length, i.e. when the\n  // number that actually binds is not the one the \"At least N characters long\" line already states. Without this,\n  // a caller that shows the effective length unconditionally repeats itself on every ordinary policy.\n  effectiveLengthBinds: boolean;\n  weakerThanDefault: boolean;\n}\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class PasswordPolicyService {\n\n  private dataService = inject(DataServiceLib);\n\n  // The legacy rule, expressed as the counts PasswordConfig stores. It is also that entity's own set of property\n  // defaults, so a row created by first-read reproduces exactly what the estate enforced before the table existed.\n  // Used for two things and no others: stating when a tenant has moved BELOW it, and as the fallback wording when\n  // the configured policy cannot be read.\n  static readonly LegacyDefaults = { minLength: 8, minUpperCase: 1, minLowerCase: 1, minNumericChars: 1, minSpecialChars: 1 };\n\n  // One request per session, shared. `passwordconfig/get` is cheap, but the change-password page and the users\n  // dialog can both be reached in a session and neither needs its own round trip.\n  private inFlight: Observable<PasswordPolicyDescription> | null = null;\n\n  //---------- The rule, in words ----------\n\n  // Pure and synchronous: the same five integers always produce the same sentences. The admin card calls this on\n  // every keystroke while the policy is being typed, so it must not fetch anything.\n  describe(config: any): PasswordPolicyDescription {\n    const c = config || {};\n    const length = this.count(c.minLength);\n    const upper = this.count(c.minUpperCase);\n    const lower = this.count(c.minLowerCase);\n    const numeric = this.count(c.minNumericChars);\n    const special = this.count(c.minSpecialChars);\n\n    const requirements: PasswordRequirement[] = [\n      { text: length ? `At least ${length} ${this.plural(length, 'character')} long` : 'No minimum length', required: length > 0 },\n      { text: upper ? `At least ${upper} uppercase ${this.plural(upper, 'letter')} (A-Z)` : 'No uppercase letter required', required: upper > 0 },\n      { text: lower ? `At least ${lower} lowercase ${this.plural(lower, 'letter')} (a-z)` : 'No lowercase letter required', required: lower > 0 },\n      { text: numeric ? `At least ${numeric} ${this.plural(numeric, 'number')} (0-9)` : 'No number required', required: numeric > 0 },\n      { text: special ? `At least ${special} special ${this.plural(special, 'character')} (! ? @ #)` : 'No special character required', required: special > 0 }\n    ];\n\n    // The four class minimums are counted INSIDE the length, so their sum is a floor under the length in its own\n    // right and can sit above the configured minimum length. Stating the number that actually binds is a plain\n    // statement of arithmetic, not a rule of its own — without it, \"minimum length 4\" with four classes of 2 reads\n    // as a 4-character policy when nothing shorter than 8 can ever pass.\n    const effectiveLength = Math.max(length, upper + lower + numeric + special);\n\n    const d = PasswordPolicyService.LegacyDefaults;\n    const weakerThanDefault = length < d.minLength || upper < d.minUpperCase || lower < d.minLowerCase || numeric < d.minNumericChars || special < d.minSpecialChars;\n\n    return { requirements, effectiveLength, effectiveLengthBinds: effectiveLength > length, weakerThanDefault };\n  }\n\n  // The sentences a user must MEET, as plain strings — the shape spa-form's alertConfig wants. Rules switched off\n  // (a minimum of 0) are dropped rather than listed as \"No number required\": on the admin page stating the\n  // negative is informative because someone is choosing it, but in a refusal panel it is noise.\n  requirementLines(config: any): string[] {\n    return this.describe(config).requirements.filter(r => r.required).map(r => r.text);\n  }\n\n  //---------- The configured policy ----------\n\n  // `passwordconfig/get` creates the row on first read with the legacy defaults, so a successful call never yields\n  // zeros. It IS gated by [Authorize] (measured: 401 without a bearer token) — which is fine for every caller here,\n  // since changing a password already requires being signed in.\n  getDescription(): Observable<PasswordPolicyDescription> {\n    if (!this.inFlight) {\n      this.inFlight = this.dataService.CallApi({ url: 'passwordconfig/get', skipCache: true }).pipe(\n        // FALLS BACK TO THE LEGACY WORDING, never to nothing. A blank rule list is worse than a stale one: the\n        // user is being asked to invent a password with no stated constraint, and will then be refused by a rule\n        // that was never shown. The legacy defaults are also what the server falls back to when it cannot resolve\n        // a configured policy, so the fallback text and the fallback enforcement agree.\n        map((apiResponse: ApiResponse) => this.describe(apiResponse?.success ? apiResponse.data : PasswordPolicyService.LegacyDefaults)),\n        catchError(() => of(this.describe(PasswordPolicyService.LegacyDefaults))),\n        shareReplay(1)\n      );\n    }\n    return this.inFlight;\n  }\n\n  // Re-read on the next ask. The admin page saved a new policy, so the sentences the other surfaces cached are\n  // now the previous rule.\n  refresh(): void {\n    this.inFlight = null;\n  }\n\n  // A blank or half-typed box must read as 0 here rather than NaN — the admin summary is live while it is typed\n  private count(value: any): number {\n    const n = Number(value);\n    return isFinite(n) && n > 0 ? Math.floor(n) : 0;\n  }\n\n  private plural(n: number, word: string): string {\n    return n === 1 ? word : word + 's';\n  }\n\n}\n","// Field load indicator — the spinning refresh icon a form field shows while its loadAction is in flight.\n//\n// The suffix refresh icon already exists on every field that loads options from the backend, but it only surfaces\n// on hover, so a user waiting on a slow reference list gets no cue at all. This holds that icon VISIBLE and spins\n// it (.tin-spin, the same class the table/filter refresh button uses) for the duration of the read.\n//\n// It honours the same anti-flicker contract as the table, tiles and details-dialog skeletons\n// (runtime/quiet-loading.ts): a list that lands in a few milliseconds paints nothing at all, and once the spinner\n// HAS painted it is held long enough that it cannot strobe. Shared by every field type with a loadAction\n// (select, select-multi, text-single, text-multi) so the four surfaces cannot drift apart.\nimport { QUIET_DELAY_MS, QUIET_MIN_MS } from './quiet-loading';\n\nexport class FieldLoadIndicator {\n\n  // The only thing templates bind — a plain property, never an allocating getter\n  spinning = false;\n\n  private inFlight = 0;\n  private delayTimer: any;\n  private minTimer: any;\n  private shownAt = 0;\n\n  // Call as the request leaves. Counts concurrent reads so an overlapping refresh cannot stop the spin early.\n  begin(): void {\n    this.inFlight++;\n\n    // A fresh read supersedes the minimum-display hold left over from the previous one — cleared BEFORE the\n    // guard below, otherwise a pending hold would hide the icon while this new read is still running.\n    clearTimeout(this.minTimer);\n    this.minTimer = null;\n\n    if (this.spinning || this.delayTimer) return; // already spinning, or already counting down to it\n\n    this.delayTimer = setTimeout(() => {\n      this.delayTimer = null;\n      this.spinning = true;\n      this.shownAt = Date.now();\n    }, QUIET_DELAY_MS);\n  }\n\n  // Call when the request lands, succeeds OR fails — wire it through finalize() so an error never leaves it spinning.\n  settle(): void {\n    this.inFlight = Math.max(0, this.inFlight - 1);\n    if (this.inFlight > 0) return; // another read is still running, keep spinning\n\n    clearTimeout(this.delayTimer); // landed inside the delay window: nothing ever painted, nothing to hide\n    this.delayTimer = null;\n\n    if (!this.spinning) return;\n\n    const held = Date.now() - this.shownAt;\n    if (held >= QUIET_MIN_MS) {\n      this.spinning = false;\n      return;\n    }\n\n    this.minTimer = setTimeout(() => {\n      this.minTimer = null;\n      this.spinning = false;\n    }, QUIET_MIN_MS - held);\n  }\n\n  // Call from the host's ngOnDestroy so a field torn down mid-read leaves no timer behind\n  destroy(): void {\n    clearTimeout(this.delayTimer);\n    clearTimeout(this.minTimer);\n    this.delayTimer = null;\n    this.minTimer = null;\n    this.spinning = false;\n    this.inFlight = 0;\n  }\n}\n","// One mechanism for the resting placeholder of every picker-shaped field, so the affordance is derived\n// from the field's own display label per COMPONENT TYPE and no config in any consumer app has to say it.\n// The verb tells the user what the control accepts: type it, pick it from a list, or pick it from a calendar.\nexport type PlaceholderKind = 'enter' | 'enter-or-select' | 'select' | 'pick';\n\nconst VERBS: Record<PlaceholderKind, string> = {\n  'enter': 'Enter',\n  'enter-or-select': 'Enter or select',\n  'select': 'Select',\n  'pick': 'Pick'\n};\n\n// An explicit placeholder always wins — deliberate copy (\"Choose roles\") is never clobbered by the convention.\n// Only an empty/absent placeholder is derived, and a blank display yields nothing rather than a dangling verb.\n// Changed (rop-1): READ-ONLY suppresses the placeholder entirely, ahead of every other rule including an\n// explicit one. A placeholder is an INVITATION TO TYPE; on a view-only dialog there is nothing to type into,\n// so \"Enter Name\" on an empty read-only field states an affordance that does not exist and reads like data\n// that failed to load. Blank is the honest rendering: it says the field is empty and nothing can be captured.\n// The suppression is unconditional because an explicit placeholder is just as misleading as a derived one —\n// \"Choose roles\" on a locked field is no more actionable than \"Select Roles\".\nexport function derivePlaceholder(kind: PlaceholderKind, display: string, explicit?: string, readonly?: boolean): string {\n  if (readonly === true) return '';\n  if (explicit != null && explicit.trim() !== '') return explicit;\n  const label = (display ?? '').trim();\n  if (label === '') return '';\n  return `${VERBS[kind]} ${label}`;\n}\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { MessageService } from '../../services/message.service';\n\n@Component({\n    selector: 'spa-suffix',\n    templateUrl: './suffix.component.html',\n    styleUrls: ['./suffix.component.css'],\n    standalone: false\n})\nexport class SuffixComponent implements OnInit {\n\n  constructor(private messageService: MessageService) { }\n\n  ngOnInit(): void {\n  }\n\n  @Input() label: string;\n  @Input() infoMessage: string;\n  @Input() copyContent: boolean = false;\n\n  @Input() isHovered: boolean = false;\n  @Input() clearContent: boolean = false;\n  // Added: this component had NO notion of readonly at all, so the clear X rendered and mutated on a locked\n  // field in every one of the 10 field types that render it. Gated in the template AND here: the template\n  // stops the click, this stops any other caller, and a write affordance that is wrong to offer is also\n  // wrong to honour. Copy is untouched — it reads.\n  @Input() readonly: boolean = false;\n  @Input() value;\n\n  @Output() infoClick = new EventEmitter<void>();\n  @Output() copyClick = new EventEmitter<string>();\n  @Output() clearClick = new EventEmitter<void>();\n  @Output() valueChange = new EventEmitter();\n\n  onInfoClick(event: MouseEvent): void {\n    event.stopPropagation();\n    if (this.infoMessage) {\n      this.messageService.info(this.infoMessage);\n    }\n    this.infoClick.emit();\n  }\n\n  onCopyClick(event: MouseEvent): void {\n    event.stopPropagation();\n    if (this.value) {\n      navigator.clipboard.writeText(this.value).then(() => {\n        this.messageService.toast('Copied');\n      });\n    }\n    this.copyClick.emit(this.value);\n  }\n\n  onClearClick(event: MouseEvent): void {\n    event.stopPropagation();\n    if (this.readonly) { return; } // Added: never write through a locked field, whatever route reached here\n\n    // Changed: was `this.value = ''`. Every parent binds [(value)]=\"value\", so this writes straight into the\n    // parent's own value BEFORE clearClick runs. For date/datetime — which had no (clearClick) at all until\n    // this change — that write was the ONLY effect, and '' is not what an emptied field means: an int property\n    // receiving a JSON \"\" fails model binding, and a double receiving \"\" 400s. A user-cleared control emits\n    // null, never '' and never a sentinel. Parents that own a clear() still overwrite this a line later.\n    this.value = null;\n    this.valueChange.emit(this.value);\n    this.clearClick.emit();\n  }\n}\n","<label *ngIf=\"label\">&nbsp; {{label}}</label>\n<button mat-icon-button *ngIf=\"copyContent && isHovered\" (click)=\"onCopyClick($event)\" matTooltip=\"Copy Content\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\n  <mat-icon class=\"tinyIcon\">content_copy</mat-icon>\n</button>\n<button mat-icon-button *ngIf=\"clearContent && isHovered && !readonly\" (click)=\"onClearClick($event)\" matTooltip=\"Clear Content\" matTooltipPosition=\"above\" style=\"opacity: 1;\"><!-- Changed: `&& !readonly` — the X is the one affordance here that WRITES, and it rendered and fired on a locked field, so a view-only dialog could still be emptied. Copy above is deliberately NOT gated: reading a locked value is exactly what a view dialog is for. -->\n  <mat-icon class=\"tinyIcon\">close</mat-icon>\n</button>\n<button mat-icon-button *ngIf=\"infoMessage\" (click)=\"onInfoClick($event)\" [matTooltip]=\"infoMessage\" matTooltipPosition=\"above\" style=\"opacity: 1;margin-right: 2px;\">\n  <mat-icon class=\"tinyIcon\" style=\"color: steelblue;\">info</mat-icon>\n</button>\n","import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; // Changed: OnDestroy to release the load indicator's timers; OnChanges + SimpleChanges so the opt-in refetchOnChange can tell a loadAction URL CHANGE from the many other input mutations that also fire ngOnChanges\nimport { FormControl } from '@angular/forms';\nimport { MessageService } from '../../services/message.service';\nimport { Action, ApiResponse } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Added: Core.parseMultiValue — the shared multi-value contract this component's private parser became\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: routes a failed loadAction through the shared classify + dedupe path (WS-6 Phase 3)\nimport { OfflineService } from '../../services/offline.service'; // Added (WS-1 Phase 3): read-only — the component asks whether the network is down so a failed option load can say so on the field instead of toasting\nimport { finalize } from 'rxjs/operators'; // Added: settle the load indicator on success AND error\nimport { FieldLoadIndicator } from '../../runtime/field-load-indicator'; // Added: shared spinning-refresh state for loadAction fields\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-select-multi',\n    templateUrl: './select-multi.component.html',\n    // Changed (WS-1 Phase 3): styleUrls added. The .css file already existed but was EMPTY and was never referenced\n    // by this decorator, so the component had no styles of its own at all — the identical omission text-multi had,\n    // and unlike select-common and text-single which already declared theirs. Wiring it cannot regress anything\n    // (there was nothing in the file to start applying), and it is what lets the offline state be tinted here with\n    // the SAME rule the rest of the family uses rather than by reaching into a global stylesheet for a\n    // one-control concern.\n    styleUrls: ['./select-multi.component.css'],\n    standalone: false\n})\nexport class SelectMultiComponent implements OnInit, OnChanges, OnDestroy { // Changed: OnDestroy; OnChanges now DECLARED — the method was always called by Angular, but it took no arguments and so could not see which input changed\n  constructor(private messageService: MessageService, private dataService: DataServiceLib, private apiErrorService: ApiErrorService, private offline: OfflineService) { } // Changed: injected ApiErrorService so a failed option load is no longer silent; added OfflineService (WS-1 Phase 3) — root-provided and already a DataServiceLib dependency, so no new graph — used only to tell an offline cache miss from a server failure\n\n  @Input() display = \"\";\n  @Input() value = \"\";\n  @Output() valueChange = new EventEmitter<string>();\n  @Input() readonly = false;\n  @Input() required = true;\n  @Input() hint = \"\";\n  @Input() options: any[] = [];\n  @Input() optionDisplay = \"name\";\n  @Input() optionValue = \"value\";\n  @Input() infoMessage: string;\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n  @Input() nullable = false;\n  @Input() placeholder = \"\";\n  @Input() width = \"100%\";\n  @Input() suffix: string;\n\n  @Input() loadAction: Action;\n  @Input() selectAll = false; // Changed: auto-select all options when no value is set\n\n  // Added: opt-in. When false (the default, and the state of every existing caller) this component behaves exactly\n  // as it did — one fetch in ngOnInit, never again. When true, a change to the RESOLVED loadAction URL re-runs the\n  // fetch. See refetchForNewUrl() for the ordering, which is the part that actually matters.\n  @Input() refetchOnChange = false;\n\n  control = new FormControl([]);\n  selectedValues: any[] = [];\n\n  // Added: a multi-select is still a PLAIN select — it is picked from, never typed into — so it takes \"Select {label}\".\n  // Moved out of ngOnInit (see select-common) so the @Input stays pristine and an explicit override is recognisable.\n  get computedPlaceholder(): string { return derivePlaceholder('select', this.display, this.placeholder, this.readonly); }\n\n  ngOnInit() {\n    if (this.readonly) {\n      this.control.disable();\n    }\n    // Always load data if loadAction is provided to ensure fresh data after cache expiration\n    if (this.loadAction){\n      this.getData(this.loadAction);\n    }else{\n      this.initializeValues();\n    }\n\n  }\n\n  ngOnChanges(changes?: SimpleChanges) {\n\n    if (this.readonly) {\n      this.control.disable();\n    } else {\n      this.control.enable();\n    }\n\n    // Added (refetchOnChange): the whole defect in one place. This method always re-ran initializeValues() and\n    // NEVER re-ran getData(), so a {placeholder} loadAction URL that resolved to a different value after the user\n    // picked a parent kept the option set fetched at dialog open. Gated on the opt-in flag AND on the resolved url\n    // genuinely differing, so with the flag absent not one existing caller reaches a line that did not run before.\n    // Mirrors spa-select's own ngOnChanges (select.component.ts), which has had exactly this re-fetch all along —\n    // this brings the multi to parity rather than inventing a mechanism.\n    const change = changes?.['loadAction'];\n    if (this.refetchOnChange && change && !change.firstChange && change.currentValue\n        && change.previousValue?.url !== change.currentValue?.url) {\n      this.refetchForNewUrl(change.currentValue);\n      return; // the reload owns the selection from here — falling through to initializeValues would re-seat the STALE value against the STALE options\n    }\n\n    this.initializeValues();\n  }\n\n  // Added (refetchOnChange): the ordering is the point, and each step is load-bearing.\n  // 1. Options are emptied FIRST. They belong to the previous parent; leaving them up means the panel shows the\n  //    old pen's pigs while the new pen's request is in flight.\n  // 2. The selection is cleared AND the cleared value is PUBLISHED to the parent. This is the safety property: if\n  //    the new fetch fails, the form is left holding nothing rather than the previous parent's ids, which would be\n  //    posted silently. An invisible wrong-selection is the failure this whole change exists to remove.\n  // 3. selectAll is NOT re-applied here — it cannot be, there is nothing to select yet. It re-applies by itself\n  //    when the response lands, because getData()'s success path calls initializeValues() and by then `value` is\n  //    empty, so parseMultiValue yields [] and the selectAll branch is the one taken. That is precisely why the\n  //    clear in step 2 has to happen before the fetch and not after it: initializeValues() takes the\n  //    `requested.length > 0` branch on a stale value and would leave the new options with nothing ticked.\n  // The publish is deferred through publishAutoSelection for the NG0100 reason already documented there — this\n  // runs inside the parent's change-detection pass, so writing data[field.name] synchronously is the same\n  // ExpressionChangedAfterItHasBeenChecked shape the selectAll emit had.\n  private refetchForNewUrl(action: Action): void {\n    this.options = [];\n    this.selectedValues = [];\n    this.control.setValue([]);\n    this.value = '';\n    this.publishAutoSelection();\n    this.getData(action);\n  }\n\n  private initializeValues() {\n    // Changed: the private toValueList is gone — its body moved to Core.parseMultiValue, THE multi-value\n    // contract. It was correct here and still re-implemented by every consumer downstream, because a private\n    // component member is not reusable; publishing it is the whole point. Behaviour is byte-for-byte identical.\n    const requested = Core.parseMultiValue(this.value);\n\n    if (requested.length > 0) { // Changed: gate on the parsed request, not on truthiness of a raw value that may be an array\n      const values = requested.filter(v => this.options?.some(opt => opt[this.optionValue]?.toString() === v)); // Changed: same \"drop values not in options\" rule, expressed without the map-to-null round trip\n\n      this.selectedValues = values;\n      this.control.setValue(values);\n    } else if (this.selectAll && this.options?.length > 0) {\n      // Changed: auto-select all options when selectAll is true and no value is set\n      const allValues = this.options.map(opt => opt[this.optionValue]?.toString());\n      this.selectedValues = allValues;\n      this.control.setValue(allValues);\n      this.publishAutoSelection(); // Changed: was this.updateValue() — see publishAutoSelection for why the emit cannot happen here\n    } else {\n      this.selectedValues = [];\n      this.control.setValue([]);\n    }\n  }\n\n  // Added: initializeValues runs from ngOnChanges/ngOnInit — inside the parent's change-detection pass.\n  // Emitting valueChange there writes the parent's bound property after its bindings were already checked,\n  // which is exactly what NG0100 ExpressionChangedAfterItHasBeenCheckedError reports. It fired on every\n  // selectAll open, independently of the array crash above. Deferring by one microtask moves the parent\n  // write into the next turn. Same idiom as day-book.component.ts's showLoading.\n  // Only the AUTOMATIC selection defers — selectionChange() still emits synchronously, because a user\n  // click is not inside a checked pass and callers rely on the value being current when they read it.\n  private publishAutoSelection(): void {\n    Promise.resolve().then(() => { if (!this.destroyed) this.updateValue(); });\n  }\n\n  private destroyed = false; // Added: a field torn down before the microtask runs must not emit into a dead parent\n\n  selectionChange(event: any): void {\n    this.selectedValues = event.value || [];\n    this.updateValue();\n  }\n\n  private updateValue(): void {\n    this.value = this.selectedValues.join(';');\n    this.valueChange.emit(this.value);\n  }\n\n  getOptionDisplay(value: any): string {\n    const option = this.options?.find(opt =>\n      opt[this.optionValue]?.toString() === value?.toString()\n    );\n    return option ? option[this.optionDisplay] : value;\n  }\n\n  compareWith(v1: any, v2: any): boolean {\n    return v1?.toString() === v2?.toString();\n  }\n\n  clear(): void {\n    this.selectedValues = [];\n    this.control.setValue([]);\n    this.value = '';\n    this.valueChange.emit(this.value);\n  }\n\n  copyValues(): void {\n    navigator.clipboard.writeText(this.value).then(() => {\n      this.messageService.toast('Copied');\n    });\n  }\n\n\n  isHovered = false;\n\n  // Added (WS-1 Phase 3, offline forms): true when this multi-select's options could not be resolved because\n  // there is no connection AND nothing was cached for its url. Identical in cause and in treatment to\n  // spa-select-common's, spa-text-single's and spa-text-multi's flag of the same name — deliberately the SAME\n  // state, the SAME sentence and the SAME mark, because two different messages for one condition is worse than\n  // one imperfect message. This is the fourth control of the family and the one that completes it.\n  // The failure is the most deceptive of the four: a multi-select with no options renders as a perfectly\n  // healthy-looking field whose panel is simply empty, indistinguishable from a genuine empty list — and on a\n  // `required` multi-select (or a `strict` one, as the live notifications config is) the form then cannot be\n  // submitted with nothing on screen saying why.\n  // NOT an @Input, unlike spa-select-common: nothing wraps or subclasses this component. It has no base class,\n  // no subclass anywhere in the repo, and is declared/exported once by tin-spa.module and rendered directly by\n  // form.component.html, option.component.html and title-actions.component.html — the instance that fetches is\n  // the instance that draws. select-common needed the binding only because spa-select/spa-select-lite WRAP it\n  // as well as extending it.\n  optionsUnavailableOffline = false;\n\n  // Added (WS-1 Phase 3): the offline-unavailable notice OUTRANKS the configured hint — it is the one of the two\n  // that says the control in front of you cannot do its job. Reuses the mat-hint line this template ALREADY\n  // renders, and the field already sets subscriptSizing=\"dynamic\", so the line appears and disappears without\n  // moving the form. No new component, layout or copy surface enters the library. The sentence is character for\n  // character the siblings' — it is not re-worded here, on purpose.\n  get computedHint(): string {\n    if (this.optionsUnavailableOffline) return \"No connection — this list wasn't saved for offline use\";\n    return this.hint;\n  }\n\n  // Added: drives the suffix refresh icon — held visible and spinning while the loadAction is in flight\n  readonly loadIndicator = new FieldLoadIndicator();\n  @Output() hoverChange = new EventEmitter<boolean>();\n  onMouseEnter(): void {\n    this.isHovered = true;\n    this.hoverChange.emit(true);\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n    this.hoverChange.emit(false);\n  }\n\n  refresh(event: MouseEvent): void {\n    event.stopPropagation();\n    if (!this.loadAction) {\n      return;\n    }\n\n    const refreshAction = {\n      ...this.loadAction,\n      forceRefresh: true\n    };\n\n    this.getData(refreshAction);\n  }\n\n  getData(action: Action) {\n    if (!action) return;\n\n    // Added: a URL still holding an unresolved {placeholder} has no id to fetch against — decline until the parent\n    // field is set, and let ngOnChanges re-fetch once it resolves. Character for character the guard\n    // select-common.getData() already carries, and for the same reason.\n    // This is a NO-OP for every pre-existing caller: form.component.ts's resolveLoadAction substituted '' for an\n    // unresolved token, so no '{' could survive into a bound action. It only becomes reachable for a field that\n    // opts into refetchOnChange, which is what makes resolveLoadAction leave the token in place.\n    // 🔑 Declining here is what fixes the SILENT half of the defect. 'pigs/list/bypen-' (empty id) does not fail:\n    // PigsController's `bypen-` branch requires an int, so a bare prefix falls through to base.GetList and answers\n    // 200 with EVERY active pig, rendered behind blank labels — which selectAll then ticks. An empty list is a\n    // visible failure; that is an invisible one.\n    if (action.url?.includes('{')) return;\n\n    this.loadIndicator.begin(); // Added: arm the spinning refresh icon (only paints if the read outlives the anti-flicker delay)\n\n    this.dataService.CallApi(action).pipe(\n      finalize(() => this.loadIndicator.settle()) // Added: stop the spin whether the read succeeded or failed\n    ).subscribe({\n      next: (apiResponse: ApiResponse) => {\n        if (apiResponse.success) {\n          this.optionsUnavailableOffline = false; // Added: a later successful load clears the offline notice (reconnect, or the manual refresh icon)\n          this.options = apiResponse.data;\n          this.initializeValues();\n        } else if (this.isOfflineCacheMiss()) {\n          // Added (WS-1 Phase 3): the offline read seam answers a cache miss with HTTP-200 `success:false` and the\n          // message 'No offline data available yet for this view' (offline.service.ts serveCachedRead), which\n          // classifyMessage correctly reads as a business message and toasts. That is the WRONG surface for this\n          // one case: the failure is not the server's, it is per-FIELD, and the toast is deduped across the form\n          // so several dead lookups speak once and namelessly. Mark the field instead.\n          // This url reaches the seam on the same terms as its siblings': registerLookups walks `formConfig.fields`\n          // and registers any `field.loadAction.url` with no reference to the field's TYPE, so a `select-multi`\n          // lookup is registered exactly as a `select` or `text-multi` one would be.\n          this.markOptionsUnavailableOffline();\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Added: was a silent no-op — a multi-select that failed to load looked identical to one with no options; 'load' dedupes with the page's other loads\n        }\n      },\n      // Added (WS-1 Phase 3): the OTHER offline shape, and the one this control actually meets today. A lookup url\n      // the registry never matched does not reach the read seam at all — it goes to the wire and dies as status 0.\n      // The interceptor has already spoken for that (loader-interceptor.service.ts shows the connection dialog for\n      // exactly the urls the offline layer does NOT suppress), so this adds no second message; it only marks the\n      // field, so once the dialog is dismissed the form still says which lookups are empty and why. Non-network\n      // errors keep their previous behaviour to the letter — there was no error callback here AT ALL before, so\n      // an error of any kind simply vanished; they are now at least logged and go no further.\n      error: (err: any) => {\n        if (err?.status === 0) { this.markOptionsUnavailableOffline(); return; }\n        console.error('[tin-spa] select-multi loadAction failed', { url: action.url, err });\n      }\n    });\n  }\n\n  // Added: a cache miss served by the offline layer arrives as success:false with a network we know is down.\n  // Both halves are required — `online === false` alone would claim any 200-level failure was an offline one.\n  private isOfflineCacheMiss(): boolean {\n    return !!this.offline && this.offline.enabled && !this.offline.online;\n  }\n\n  private markOptionsUnavailableOffline(): void {\n    this.optionsUnavailableOffline = true;\n  }\n\n  ngOnDestroy() {\n    this.destroyed = true; // Added: suppresses a deferred selectAll emit that lands after teardown\n    this.loadIndicator.destroy(); // Added: clear any pending delay/hold timer on a field torn down mid-read\n  }\n}\n","<!-- Changed (WS-1 Phase 3): one class added — no structural change. It tints the hint line the field already renders. Same treatment as spa-select-common, spa-text-single and spa-text-multi; see the .css for why the state is spoken on the field rather than in a toast. -->\n<!-- Changed (placeholder conventions): floatLabel=\"always\" — with the default 'auto' Material hides the placeholder behind the resting label, so \"Select X\" could never be seen in the empty state the convention is FOR. spa-select-common has always floated for this reason; this brings the multi to parity. -->\n<mat-form-field floatLabel=\"always\" [class.spa-options-unavailable]=\"optionsUnavailableOffline\" [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n  <mat-label>{{display}}</mat-label>\n  <mat-select [formControl]=\"control\" [required]=\"required\" multiple [placeholder]=\"computedPlaceholder\" [compareWith]=\"compareWith\" (selectionChange)=\"selectionChange($event)\">\n    <mat-option *ngIf=\"nullable\" [value]=\"null\">None</mat-option>\n    <mat-option *ngFor=\"let option of options\" [value]=\"option[optionValue]\">\n      {{option[optionDisplay]}}\n    </mat-option>\n  </mat-select>\n  <!-- Changed (WS-1 Phase 3): the hint now reads computedHint, and — the part that matters — it is GATED on computedHint too, not on hint.\n       This differs from spa-select-common and spa-text-single only because the surface differs: those bind [hintLabel], which renders whenever\n       it is non-empty, whereas this template renders an explicit <mat-hint> behind an *ngIf. Left gated on `hint` the offline notice would have\n       been invisible at the ONLY live target in the estate: notifications.component.ts's roleIDs field declares no `hint` at all, so\n       form.component.html's [hint]=\"field.hint\" binds undefined and the *ngIf never opens. It would likewise never appear in the filter/option\n       context, where option.component.html binds [loadAction] but never binds [hint] — the exact context where a lookup can fail with nothing\n       else on screen to explain it. Both surfaces render the same .mat-mdc-form-field-hint element, so the copied css rule is unchanged. -->\n  <mat-hint *ngIf=\"computedHint\">{{computedHint}}</mat-hint>\n  <div matSuffix class=\"suffix-icons\">\n    <!-- Added (WS-1 Phase 3): the house's own offline mark, the same cloud_off spa-offline-indicator, spa-select-common, spa-text-single and spa-text-multi already use, so the state is recognisable without reading — which is what carries it at phone width, where the hint line has least room. The refresh button below is left exactly as it was and stays reachable on purpose: it is the one action that fixes this once the connection is back, and getData() clears the flag on the first successful load. -->\n    <mat-icon *ngIf=\"optionsUnavailableOffline\" class=\"tinyIcon spa-options-unavailable-icon\" [matTooltip]=\"computedHint\" matTooltipPosition=\"above\">cloud_off</mat-icon>\n    <!-- Changed: the icon now also shows while loading (not hover-only), and spins — same .tin-spin idiom as the table/filter refresh button -->\n    <button mat-icon-button *ngIf=\"loadAction && (isHovered || loadIndicator.spinning)\" (click)=\"refresh($event)\" [matTooltip]=\"loadIndicator.spinning ? 'Loading' : 'Refresh'\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" [class.tin-spin]=\"loadIndicator.spinning\" color=\"primary\">cached</mat-icon>\n    </button>\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\">\n    </spa-suffix>\n  </div>\n</mat-form-field>\n","import { Component, Input, OnChanges, SimpleChanges, TemplateRef } from '@angular/core';\nimport { ChecklistAction, ChecklistConfig, ChecklistItem } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore';\n\n// Added (v2-1): one folded sub-tier inside the checklist. Materialized — never a getter returning a\n// filter(), which is the allocating pattern this library has livelocked on (see the PresetRow comments in\n// setup-guide.component.ts). `done`/`total` are what the band says about itself while shut, and `complete`\n// is what earns it the crossing-off.\ninterface ChecklistSection { name: string; items: ChecklistItem[]; done: number; total: number; complete: boolean; collapsed: boolean; summary: string; }\n\n// Added: spa-checklist — flat collapsible checklist matching the module-grid design language (thin 1px\n// borders on the host card, no elevation, no panel background). Replaces mat-accordion in the Getting\n// Started page; reusable anywhere a to-do list is needed. Single-expand semantics; an optional item\n// template projects custom content (e.g. the role-template picker) into the expanded body.\n@Component({\n    selector: 'spa-checklist',\n    templateUrl: './checklist.component.html',\n    styleUrls: ['./checklist.component.css'],\n    standalone: false\n})\nexport class ChecklistComponent implements OnChanges {\n  @Input() config: ChecklistConfig;\n  @Input() itemTemplate: TemplateRef<any>; // view-level override for config.itemTemplate\n\n  expandedKey = '';\n\n  // Changed: materialized — a getter returning .filter() allocated a new array on every change-detection\n  // cycle while feeding the *ngFor of checklist rows.\n  items: ChecklistItem[] = [];\n\n  // Added (v2-1): the sub-tier. EMPTY means \"render flat\", and that is the default rather than a fallback —\n  // see buildSections for the two conditions that keep it empty.\n  sections: ChecklistSection[] = [];\n\n  // Added (GS P4): the seed this component has already adopted. The parent rebuilds its ChecklistConfig on EVERY\n  // refresh() — a module toggle, a dialog close, a seed, an import — so `changes['config']` fires constantly with\n  // an identical expandedKey inside it. Remembering what was last adopted is what separates \"the parent has a NEW\n  // opinion\" from \"the parent handed me the same opinion again\".\n  private seededKey: string | null = null;\n\n  // Added (v2-1): remembered open/shut per sub-section, held HERE rather than in the parent. The parent replaces\n  // its ChecklistConfig wholesale on every refresh(), so a `collapsed` living on the config would be reset by\n  // every module toggle and seed — the identical hazard buildModuleGroups/buildPresetGroups each carry a cascade\n  // for. Keyed by section name, which is unique within one checklist.\n  private sectionState: { [name: string]: boolean } = {};\n\n  ngOnChanges(changes: SimpleChanges): void {\n    // Changed (GS P4): the seed is adopted only when it actually CHANGES. It used to be re-applied on every new\n    // config object, which silently threw away whatever the user had opened: expand a step, toggle a module, and\n    // the refresh() slammed it shut and jumped back to the first incomplete step. That is a real defect on its own\n    // and it is fatal to anything collapsible living INSIDE an expanded step, which the preset sections now are.\n    // The auto-advance the original line was written for still works — when a step completes, the parent's\n    // firstIncomplete moves, the seed is a different key, and this adopts it.\n    if (changes['config']) {\n      const seed = this.config?.expandedKey || '';\n      if (seed !== this.seededKey) { this.expandedKey = seed; this.seededKey = seed; }\n    }\n    this.buildItems(); // Added: recompute only when inputs actually change\n  }\n\n  private buildItems() {\n    this.items = (this.config?.items || []).filter(x => Core.isItemVisible(x, x));\n    this.buildSections();\n  }\n\n  // Added (v2-1): the third tier — \"the main one, then I toggle the next one, drilling deeper and deeper\".\n  //\n  // 🔑 IT STAYS OFF UNLESS IT EARNS ITS PLACE. Two conditions keep `sections` empty, and both are deliberate:\n  //   1. no item declares a section — every existing consumer, unchanged;\n  //   2. the items resolve to exactly ONE section — a single band wrapping the whole list would be a header\n  //      repeating the category header directly above it, with a \"3 of 3\" counter beside it. That is the same\n  //      defect the module picker closed when it rejected one section per module (setup-guide sectionOf()) and\n  //      the preset sections inherited. One tier of chrome for one group is not a drill-down, it is a lid.\n  //\n  // Order is the ITEMS' order, never alphabetical: the backend orders setup steps deliberately and a sub-tier\n  // that reshuffles them would break the sequence the whole page is built on.\n  private buildSections() {\n    const names: string[] = [];\n    this.items.forEach(i => { const n = i.section || ''; if (n && !names.includes(n)) names.push(n); });\n    if (names.length < 2) { this.sections = []; return; }\n\n    // Does ANY section hold the expanded step? This is asked once, before the map, and it is what stops two\n    // sections opening at the same time. Caught by checklist.component.spec.ts: with the expanded step in the\n    // SECOND section, the first was still opening on its `index > 0` default, so the page revealed two bands at\n    // once — which is precisely the \"bit by bit\" the tier exists to produce, undone by its own fallback.\n    // When the page has positioned the reader somewhere, that position is the ONLY thing that decides.\n    const positioned = !!this.expandedKey && this.items.some(i => i.key === this.expandedKey && !!i.section);\n\n    this.sections = names.map((name, index) => {\n      const items = this.items.filter(i => (i.section || '') === name);\n      const done = items.filter(i => i.complete).length;\n      // The cascade, same shape and same reason as buildModuleGroups in setup-guide.component.ts: this runs on\n      // every rebuild, so what the user has open must survive it. What this user chose wins, then the seed.\n      // The SEED opens the section holding the expanded step — the one the page has positioned you on — and\n      // shuts the rest. A section that is entirely finished starts shut whatever its index, because a folded\n      // done band is exactly the \"bit by bit\" reveal this tier exists for.\n      const holdsExpanded = !!this.expandedKey && items.some(i => i.key === this.expandedKey);\n      const complete = items.length > 0 && done === items.length;\n      return {\n        name, items, done, total: items.length, complete,\n        // What this user chose wins; then the seed. The seed: if the page has positioned the reader on a step,\n        // that step's section is the one open and every other is shut. Otherwise the first unfinished section\n        // opens and the rest stay shut — a finished section is never the one you are shown first.\n        collapsed: this.sectionState[name] ?? (positioned ? !holdsExpanded : (complete || index > 0)),\n        summary: this.sectionSummary(items)\n      };\n    });\n  }\n\n  // What a shut band still says about itself: what is LEFT, named — because a column of identical closed\n  // headers is a worse list than the one it replaced. Capped at two titles so it stays one line on a phone;\n  // the tail is counted, never dropped. Same rule and same cap as presetSummary in setup-guide.component.ts.\n  private sectionSummary(items: ChecklistItem[]): string {\n    const left = items.filter(i => !i.complete);\n    if (left.length === 0) return 'All done here';\n    const names = left.slice(0, 2).map(i => i.title);\n    return left.length > names.length ? `${names.join(' · ')} + ${left.length - names.length} more` : names.join(' · ');\n  }\n\n  toggleSection(section: ChecklistSection) {\n    section.collapsed = !section.collapsed;\n    this.sectionState[section.name] = section.collapsed;\n  }\n\n  get template(): TemplateRef<any> | null {\n    return this.itemTemplate || this.config?.itemTemplate || null;\n  }\n\n  toggle(item: ChecklistItem) {\n    this.expandedKey = this.expandedKey === item.key ? '' : item.key;\n  }\n\n  isExpanded(item: ChecklistItem): boolean {\n    return this.expandedKey === item.key;\n  }\n\n  isDisabled(act: ChecklistAction, item: ChecklistItem): boolean {\n    return act.disabled ? act.disabled(item) : false;\n  }\n}\n","<!-- Added: flat bordered checklist items — lie directly on the host card, border-only highlighting -->\n<!-- Changed (v2-1): the list has TWO shapes now, and the row itself is identical in both. `sections` is empty\n     unless the items actually declare more than one (checklist.component.ts buildSections), so every existing\n     consumer keeps the flat list exactly as it was. The row markup lives in ONE template, projected into both\n     branches — two copies of a row this dense is how the two would silently drift apart. -->\n<div class=\"cl-list\" *ngIf=\"config\">\n\n  <!-- FLAT: the original list, unchanged -->\n  <ng-container *ngIf=\"!sections.length\">\n    <ng-container *ngFor=\"let item of items\">\n      <ng-container *ngTemplateOutlet=\"rowTpl; context: { $implicit: item }\"></ng-container>\n    </ng-container>\n  </ng-container>\n\n  <!-- SECTIONED: one more fold between the category and the rows — \"the main one, then I toggle the next one\".\n       Same band idiom as the module and preset sections on the page above: the whole strip is a real <button>,\n       so Enter/Space work without a keydown handler, and aria-expanded/aria-controls sit on the control where a\n       screen reader looks for them. -->\n  <div class=\"cl-section\" *ngFor=\"let section of sections; let si = index\"\n       [class.closed]=\"section.collapsed\" [class.complete]=\"section.complete\">\n    <button type=\"button\" class=\"cl-sub-head tin-disc-row\" (click)=\"toggleSection(section)\"\n            [attr.aria-expanded]=\"!section.collapsed\" [attr.aria-controls]=\"'cl-section-' + si\">\n      <span class=\"tin-disc\" [class.open]=\"!section.collapsed\"><mat-icon>chevron_right</mat-icon></span>\n      <!-- A finished band is CROSSED OUT, never greyed — the owner's rule, and the same treatment its rows get.\n           Grey reads as \"taken away from you\", and these stay adjustable. -->\n      <span class=\"cl-sub-name\" [class.done]=\"section.complete\">{{ section.name }}</span>\n      <span class=\"cl-sub-count\" [class.done]=\"section.complete\">{{ section.done }} of {{ section.total }}</span>\n    </button>\n    <!-- What a shut band still says: what is LEFT here, or that nothing is. Shown only while shut — open, the\n         rows themselves say it, and repeating them there would be noise. -->\n    <div class=\"cl-sub-summary\" *ngIf=\"section.collapsed\">{{ section.summary }}</div>\n    <!-- 🔴 display:none, NOT *ngIf (ruling of 2026-08-12, the same one the module and preset sections follow):\n         the rows stay MOUNTED, so the band's count and summary are LIVE rather than a blank that fills in once\n         you open it, and a band you shut keeps whichever step was expanded inside it. -->\n    <div class=\"cl-sub-body\" [id]=\"'cl-section-' + si\">\n      <ng-container *ngFor=\"let item of section.items\">\n        <ng-container *ngTemplateOutlet=\"rowTpl; context: { $implicit: item }\"></ng-container>\n      </ng-container>\n    </div>\n  </div>\n</div>\n\n<!-- THE ROW. One definition, both branches. -->\n<ng-template #rowTpl let-item>\n  <div class=\"cl-item\" [class.expanded]=\"isExpanded(item)\" [class.complete]=\"item.complete\">\n    <button type=\"button\" class=\"cl-head\" (click)=\"toggle(item)\" [attr.aria-expanded]=\"isExpanded(item)\">\n      <mat-icon class=\"cl-state\" [class.done]=\"item.complete\" [class.required]=\"!item.complete && !item.optional\">{{ item.complete ? 'check_circle' : 'radio_button_unchecked' }}</mat-icon>\n      <span class=\"cl-title\" [class.done]=\"item.complete\">{{ item.title }}</span>\n      <span class=\"cl-meta\">\n        <span class=\"cl-pill\" *ngIf=\"item.progressText\">{{ item.progressText }}</span>\n        <span class=\"cl-optional\" *ngIf=\"item.optional && !item.complete\">Optional</span>\n        <mat-icon class=\"cl-chevron\">expand_more</mat-icon>\n      </span>\n    </button>\n    <div class=\"cl-body\">\n      <div class=\"cl-body-inner\">\n        <p class=\"cl-description\" *ngIf=\"item.description\">{{ item.description }}</p>\n        <ng-container *ngIf=\"template\" [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ $implicit: item }\"></ng-container>\n        <!-- Changed (P2): every action label is wrapped in .cl-btn-text so a phone can DROP it and leave the icon.\n             `has-icon` is bound to act.icon — the icon the HOST set — never to a rendered fallback, so an action\n             without one keeps its label and never collapses to a blank square. Same guard as tbl-section-btn-text.\n             The label is not lost: matTooltip and aria-label both carry it once the text is gone. -->\n        <div class=\"cl-actions\" *ngIf=\"item.actions?.length\">\n          <ng-container *ngFor=\"let act of item.actions\">\n            <button mat-flat-button color=\"primary\" *ngIf=\"act.primary\" [disabled]=\"isDisabled(act, item)\" [matTooltip]=\"act.display || ''\" [attr.aria-label]=\"act.display\" (click)=\"act.onClick(item)\"><mat-icon *ngIf=\"act.icon\">{{ act.icon }}</mat-icon><span class=\"cl-btn-text\" [class.has-icon]=\"!!act.icon\">{{ act.display }}</span></button> <!-- Changed (P2): icon + droppable label + tooltip/aria -->\n            <span class=\"cl-break\" *ngIf=\"act.primary && !act.icon && (item.actions?.length || 0) > 2\"></span> <!-- Changed (P2): the zero-height flex break now fires only in the case it was written for — a LABELLED primary competing with TWO OR MORE escapes (Create + Import + Go to page). An icon primary needs no line of its own, and a labelled primary with a single icon escape beside it fits one line at 393px; forcing a break there left one small chip stranded on a row of its own. -->\n            <button mat-stroked-button color=\"primary\" class=\"cl-secondary\" *ngIf=\"!act.primary && act.type === 'import'\" [disabled]=\"isDisabled(act, item)\" [matTooltip]=\"act.display || 'Import from Excel'\" [attr.aria-label]=\"act.display || 'Import from Excel'\" (click)=\"act.onClick(item)\"><mat-icon>{{ act.icon || 'upload_file' }}</mat-icon><span class=\"cl-btn-text\" [class.has-icon]=\"!!act.icon\">{{ act.display || 'Import from Excel' }}</span></button> <!-- Changed (P2): has-icon reads act.icon, NOT the upload_file fallback — an existing consumer that never set an icon keeps its label, so no default is flipped -->\n            <button mat-stroked-button color=\"primary\" class=\"cl-secondary\" *ngIf=\"!act.primary && act.type !== 'import'\" [disabled]=\"isDisabled(act, item)\" [matTooltip]=\"act.display || 'Go to page'\" [attr.aria-label]=\"act.display || 'Go to page'\" (click)=\"act.onClick(item)\"><mat-icon *ngIf=\"act.icon\">{{ act.icon }}</mat-icon><span class=\"cl-btn-text\" [class.has-icon]=\"!!act.icon\">{{ act.display || 'Go to page' }}</span></button> <!-- Changed (P2): gains the icon it never rendered, plus the droppable label -->\n          </ng-container>\n        </div>\n      </div>\n    </div>\n  </div>\n</ng-template>\n","import { Component, OnInit, inject } from '@angular/core';\nimport { Observable } from 'rxjs'; // Added (presets P4): each picker carries its own load/apply calls as functions\nimport { Button, ChecklistAction, ChecklistConfig, ChecklistItem, SetupModule, SetupPreset, SetupPresetRole, SetupPresetSelection, SetupRoleTemplate, SetupSeedOffer, SetupStatus, SetupStep, SetupStepAction } from '../../classes/Classes'; // Changed (seed seam): SetupSeedOffer — the example-data rows a step can offer\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { SetupService } from '../../services/setup.service';\nimport { DialogService } from '../../services/dialog.service';\nimport { MessageService } from '../../services/message.service'; // Added: confirm + toast for the Demo Data card\nimport { ApiResponse } from '../../classes/Classes'; // Added: Demo Data seed/remove responses\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: a module toggle that snapped back, an empty role picker and a raw demo-data toast all needed classifying (WS-6 Phase 4)\nimport { Core } from '../../classes/TinCore'; // Added (GS Phase 5): Core.parseMultiValue — THE ';'-joined multi-value contract spa-select-multi emits, parsed with the same function the control itself uses\n\n// Added (presets): the library step keys the pickers attach to. They come from PresetCatalog and are identical in\n// all five apps, so a picker needs no per-app setupConfig entry (unlike roleTemplates, whose step key is\n// app-chosen). Kept as named constants rather than literals sprinkled through the class.\nconst NOTIFICATION_PRESETS_STEP = 'notification-presets';\nconst APPROVAL_PRESETS_STEP = 'approval-presets'; // Added (presets P4) — PresetCatalog.StepApprovals\n// Added (presets): the placeholder PresetCatalog authors into every Effect sentence, marking where the role\n// select is embedded. Splitting on it is the ONLY thing the UI does to that sentence.\nconst PRESET_ROLE_TOKEN = '{role}';\n\n// Added (presets): one rendered preset row — the preset plus its effect sentence already split around the role\n// token. Materialized at load time, never recomputed in a template binding (a split() per change-detection pass\n// is the allocating-getter pattern this page has already been burned by).\n// Changed (GS Phase 5): + roleAria. The native <select> carried an aria-label naming its own rule (\"Who to tell —\n// New customer added\"); spa-select-multi's accessible name is its mat-label, which is the SHORT one (\"Who to tell\")\n// and is repeated identically on every row. Naming the wrapping role=\"group\" restores what the rule was — and it is\n// materialized here, with before/after, because building it in a binding is the allocating-getter pattern above.\ninterface PresetRow { preset: SetupPreset; before: string; after: string; roleAria: string; }\n\n// Added (seed seam): one rendered example-data row. Same rule as PresetRow above and for the same reason — the\n// two derived strings are computed ONCE at load, never in a template binding. `alsoAdds` is the prerequisite\n// sentence (\"Also adds: product categories\"), `hereAlready` is the live count of what is in that area already,\n// which is what turns the row from a blind button into a decision the user can make.\ninterface SeedRow { offer: SetupSeedOffer; alsoAdds: string; hereAlready: string; actionLabel: string; }\n\n// Added (seed-all): one line of the bottom Demo data card's per-area report. The card used to say ONE thing about\n// the WHOLE system (\"Demo data already exists\"), because TinWebDemoSeedService sentinels on a single customer\n// named \"Example: …\". `state` is this area's own answer — what is already here and what a fill would add — which\n// is the difference between an all-or-nothing switch and \"populate the areas that don't have data\". Materialized\n// at load, never computed in a binding, for the reason SeedRow and PresetRow above already record.\ninterface DemoArea { offer: SetupSeedOffer; label: string; state: string; }\n\n// Added (presets P4): ONE preset picker — its state and the handful of strings/calls that differ between domains.\n// The notification picker and the approval picker are the SAME rows, the SAME grouping, the SAME toggle, apply and\n// recount code, differing only in what is in this object. Copy-pasting the Phase 2 block for approvals was the\n// alternative and is how the two would silently drift apart — they sit one above the other on the same page, so\n// any divergence reads as a bug. Everything domain-specific is DATA here, never a second branch of logic.\ninterface PresetPicker {\n  stepKey: string;                                // which checklist step this picker renders inside\n  defaultGroup: string;                           // section name for a preset the backend left ungrouped\n  emptyText: string;                              // shown instead of the rows when no role can be chosen\n  doneText: string;                               // replaces the effect line on an already-configured row\n  roleAria: string;                               // aria-label prefix — now names the role field's group, see PresetRow\n  roleLabel: string;                              // Added (GS Phase 5): the field's own visible label, short enough to read at 393px\n  roleNone: string;                               // Added (GS Phase 5): what the sentence says where the roles go when none are chosen\n  showEmail: boolean;                             // the page-level email channel line (notifications only)\n  buttonLabel: (count: number) => string;         // primary action label, count included\n  toastLabel: (created: number) => string;        // post-apply confirmation, worded at the call site\n  loadUrl: string;                                // for failure classification only\n  applyUrl: string;\n  load: () => Observable<any>;\n  apply: (items: SetupPresetSelection[]) => Observable<any>;\n  presets: SetupPreset[];\n  roles: SetupPresetRole[];\n  // Changed (GS P4): a preset section now carries its own open/shut state and the line it shows while shut —\n  // the same two fields, cascade and summary rule the module sections took in P3. `summary` is materialized for\n  // the reason every list on this page is: a template-bound getter building a string per change-detection pass.\n  groups: { name: string, rows: PresetRow[], on: number, total: number, collapsed: boolean, summary: string }[];\n  selected: { [key: string]: boolean };\n  // Changed (GS Phase 5): the single `role: number` per preset becomes the ';'-joined id string spa-select-multi\n  // both reads and emits — ONE source of truth, in the control's own wire format, so nothing has to be converted\n  // to render it. `roleNames` is that same choice spelled out for the effect sentence, materialized beside it and\n  // updated in the SAME place, because two maps that drift apart is the only real risk in carrying both.\n  roleValue: { [key: string]: string };\n  roleNames: { [key: string]: string };\n  count: number;\n  loaded: boolean;                                // \"not fetched yet\" vs \"this app offers none\" — rows stay hidden until we know\n  applying: boolean;\n  action: ChecklistAction;                        // ONE stable object whose label is mutated as ticks change\n}\n\n// Getting Started page — renders the per-app setup readiness catalog (top-down groups, no wizard).\n// Step actions come from appConfig.setupConfig.stepActions (create dialog Button, route link, Excel\n// import wizard, or the predefined role-template picker). v2 adds the module picker: optional modules\n// toggle on/off, hiding their step groups and (via CapItem.moduleKey) their menus app-wide.\n@Component({\n    selector: 'spa-setup-guide',\n    templateUrl: './setup-guide.component.html',\n    styleUrls: ['./setup-guide.component.css'],\n    standalone: false\n})\nexport class SetupGuideComponent implements OnInit {\n  dataService = inject(DataServiceLib);\n  setupService = inject(SetupService);\n  private dialogService = inject(DialogService);\n  private messageService = inject(MessageService); // Added: Demo Data card\n  private apiErrorService = inject(ApiErrorService); // Added: routes this page's four unhandled failures through the shared classifier\n\n  status: SetupStatus | null = null;\n  // Changed (fusion, 2026-08-18): a category group is now COLLAPSIBLE, the way the Day Book's lane groups and\n  // this page's own module and preset sections already are. It was the only tier on the page that could not fold:\n  // an <h2>, a counter, and a permanently open checklist. Everything added here is materialized for the same\n  // reason the module sections are — a template-bound getter building these per change-detection pass is the\n  // allocating pattern this library has livelocked on before.\n  // Changed (v2-1): + `icon`. The header is now a Day Book SUBCARD (.tbl-section-header: disc, icon, title,\n  // caption, badges) and that shape has an icon slot. A CATEGORY has no icon in the backend — buildGroups derives\n  // the name from the step's `category` string and nothing else — so it is taken from the first step in the\n  // category, which is real data rather than a per-app table this component would have to invent and five apps\n  // would have to maintain. Same reasoning that settled categoryAbout below.\n  groups: { name: string, completed: number, total: number, config: ChecklistConfig, collapsed: boolean, done: number, todo: number, optional: number, chips: { key: string, label: string, optional: boolean }[], about: string, icon: string }[] = []; // Changed: each group carries a spa-checklist config instead of raw steps\n  // Added (fusion): remembered open/shut per CATEGORY, under its OWN key. Deliberately not sharing\n  // `tin-setup-module-sections`: a category (\"Company Setup\") and a module group (\"Finance\") are different\n  // namespaces, and one shared key would make unrelated sections collapse each other — the exact hazard the\n  // preset sections were given their own key for.\n  private categorySectionState: { [name: string]: boolean } = {};\n  modules: SetupModule[] = [];\n  // Added (v3): the picker now carries the whole library catalog, not just a handful of app modules, so a flat\n  // grid of 20+ cards was unreadable. Materialized (never a template-bound getter returning a new array).\n  // Changed (P3): each section now carries its own open/shut state and the summary it shows while shut.\n  // `summary` is materialized here for the reason every other list on this page is — a template-bound getter\n  // building a string per change-detection pass is the allocating pattern this library has already livelocked on.\n  moduleGroups: { name: string, modules: SetupModule[], enabled: number, total: number, collapsed: boolean, summary: string }[] = [];\n  // Added (P3): remembered open/shut per section, so a returning user's choice outlives the visit. Same shape and\n  // same failure handling as the Day Book's `tin-daybook-groups` (day-book.component.ts :102) — a corrupt or\n  // absent entry falls back to the first-open seed rather than throwing on load.\n  private moduleSectionState: { [name: string]: boolean } = {};\n  // Added (GS P4): the SAME remembered-state idiom for the preset sections, under its OWN localStorage key and\n  // keyed per picker as well as per section. Both are load-bearing: since P4 a preset section is named after a\n  // MODULE GROUP, so \"Finance\" now appears in the module card AND in both pickers — one shared key would make\n  // three unrelated sections collapse each other.\n  private presetSectionState: { [key: string]: boolean } = {};\n  togglingKey = ''; // module key with an in-flight toggle — disables its card until the server answers\n  roleTemplates: SetupRoleTemplate[] = [];\n  selectedTemplates: { [key: string]: boolean } = {};\n  creatingRoles = false;\n\n  // Added (seed seam): example-data offers, keyed by the step they render inside. The MAP is what the template\n  // indexes — indexing returns the same array reference every change-detection pass, where a filter() in the\n  // template would allocate a new one per pass (the banned pattern that livelocked this library once already).\n  seedRowsByStep: { [key: string]: SeedRow[] } = {};\n  seedingKey = ''; // offer key with an in-flight apply — disables its button until the server answers\n\n  // Added (2026-08-19, owner): which seed offers are OPEN. Empty on construction and never seeded from anything —\n  // that emptiness IS the \"collapsed by default\" requirement, so do not prime it from `applied`, from an\n  // expandedKey, or from storage. It survives a refresh() only because the component instance does, which is what\n  // stops an offer the reader deliberately opened from slamming shut when a step elsewhere ticks over.\n  private openSeedKeys = new Set<string>();\n\n  isSeedOpen(offer: SetupSeedOffer): boolean { return this.openSeedKeys.has(offer.key); }\n\n  toggleSeed(offer: SetupSeedOffer) {\n    if (this.openSeedKeys.has(offer.key)) this.openSeedKeys.delete(offer.key); else this.openSeedKeys.add(offer.key);\n  }\n\n  // Added (seed-all): the SAME offers, reported area by area for the Demo data card at the foot of the page.\n  // One list, two readers — a second fetch with its own idea of what is empty is how the two would drift.\n  demoAreas: DemoArea[] = [];\n  demoPending = 0;    // areas with something left to add; materialized so the template binds a number, not a filter()\n  seedingAll = false;\n\n  // Added (presets): picker state. `groups` is materialized (same rule as moduleGroups above); selected/role are\n  // plain maps keyed by preset key so a reload never clobbers a manual choice.\n  // Changed (presets P4): one object per domain instead of a field per domain — see PresetPicker above.\n  includeEmail = false; // notifications only; approvals are always in-app\n\n  notificationPicker: PresetPicker = {\n    stepKey: NOTIFICATION_PRESETS_STEP,\n    defaultGroup: 'Notifications',\n    // A notification addressed to nobody is inert, so with no roles we ask for roles instead of offering ticks\n    emptyText: 'Create your team roles first — a notification needs somebody to go to.',\n    doneText: 'Edit or remove it in Notif Config.',\n    roleAria: 'Who to tell — ',\n    roleLabel: 'Who to tell',\n    roleNone: 'nobody yet',\n    showEmail: true,\n    buttonLabel: count => count === 0 ? 'Turn on notifications' : count === 1 ? 'Turn on 1 notification' : `Turn on ${count} notifications`,\n    toastLabel: created => created > 0 ? `${created} notification${created === 1 ? '' : 's'} turned on` : 'No new notifications were turned on',\n    loadUrl: 'setup/notificationpresets',\n    applyUrl: 'setup/notifications',\n    load: () => this.setupService.loadNotificationPresets(),\n    apply: items => this.setupService.applyNotificationPresets(items, this.includeEmail),\n    presets: [], roles: [], groups: [], selected: {}, roleValue: {}, roleNames: {}, count: 0, loaded: false, applying: false,\n    action: { type: 'custom', display: 'Turn on notifications', primary: true, disabled: () => this.notificationPicker.count === 0 || this.notificationPicker.applying, onClick: () => this.applyPresets(this.notificationPicker) } // Changed (P2): DELIBERATELY no icon — buttonLabel() rewrites this display to \"Turn on 3 notifications\", so the label IS the tick feedback. It is also alone on its row, so there is no space to win by dropping it\n  };\n\n  approvalPicker: PresetPicker = {\n    stepKey: APPROVAL_PRESETS_STEP,\n    defaultGroup: 'Sign-off',\n    // 🔴 NOT \"create your team roles first\". The backend offers only roles somebody is actually a MEMBER of, because\n    // since SEC-10 only a member of the approver role can release a held record — so this list is empty in TWO\n    // different situations: no roles at all, and roles that nobody has been added to. Naming only the first would be\n    // flatly wrong in the second, and would send a user who already has roles off to create duplicates of them.\n    emptyText: 'Nobody can approve anything yet — sign-off goes to a role, and only the people in that role can release a held record. Create your roles and add your team to one first.',\n    doneText: 'Edit or remove it in Approvals Config.',\n    roleAria: 'Who approves — ',\n    roleLabel: 'Who approves',\n    roleNone: 'nobody yet',\n    showEmail: false, // an approval request is always in-app; an approver who misses it leaves records held\n    buttonLabel: count => count === 0 ? 'Turn on sign-off' : count === 1 ? 'Require sign-off for 1 action' : `Require sign-off for ${count} actions`,\n    toastLabel: created => created > 0 ? `Sign-off turned on for ${created} action${created === 1 ? '' : 's'}` : 'No new sign-off rules were added',\n    loadUrl: 'setup/approvalpresets',\n    applyUrl: 'setup/approvals',\n    load: () => this.setupService.loadApprovalPresets(),\n    apply: items => this.setupService.applyApprovalPresets(items),\n    presets: [], roles: [], groups: [], selected: {}, roleValue: {}, roleNames: {}, count: 0, loaded: false, applying: false,\n    action: { type: 'custom', display: 'Turn on sign-off', primary: true, disabled: () => this.approvalPicker.count === 0 || this.approvalPicker.applying, onClick: () => this.applyPresets(this.approvalPicker) } // Changed (P2): DELIBERATELY no icon — same reason as notifications; the display becomes \"Require sign-off for 4 actions\" and that count is the whole feedback loop\n  };\n\n  // Both pickers, in render order. Everything below iterates this rather than naming a domain.\n  pickers: PresetPicker[] = [this.notificationPicker, this.approvalPicker];\n\n  get title(): string {\n    return this.dataService.appConfig?.setupConfig?.title || 'Getting Started';\n  }\n\n  ngOnInit(): void {\n    // Added (P3): read the remembered section state BEFORE the first status arrives, so the first build already\n    // honours it and no section is drawn open and then snapped shut a frame later.\n    // ⚠️ Both stores below are keyed by section NAME, and a section name IS a module group (see `sectionOf`). That\n    // coupling has a cost nobody has paid yet: if what a section is were ever redefined — one per module instead of\n    // per group, or a group merely renamed backend-side — every stored entry is orphaned in place. Nothing throws\n    // and nothing clears, so each returning user silently reverts to the first-open seed and loses the sections\n    // they had shut. A change of that kind needs a key migration or a bumped key name, not only the one-line edit.\n    try { this.moduleSectionState = JSON.parse(localStorage.getItem('tin-setup-module-sections') || '{}') || {}; } catch { this.moduleSectionState = {}; }\n    // Added (GS P4): same read, same moment, same failure handling — before the first status arrives, so a section\n    // is never drawn open and snapped shut a frame later.\n    try { this.presetSectionState = JSON.parse(localStorage.getItem('tin-setup-preset-sections') || '{}') || {}; } catch { this.presetSectionState = {}; }\n    // Added (fusion): same read, same moment, same failure handling — before the first status arrives, so a\n    // category is never drawn open and snapped shut a frame later.\n    try { this.categorySectionState = JSON.parse(localStorage.getItem('tin-setup-category-sections') || '{}') || {}; } catch { this.categorySectionState = {}; }\n    this.setupService.status$.subscribe(status => {\n      this.status = status;\n      this.modules = (status?.modules || []).slice().sort((a, b) => a.order - b.order);\n      this.buildModuleGroups(); // Added (v3)\n      // Added (v2-1): seed the picker's fold ONCE, from the server's answer. A tenant that has already\n      // confirmed arrives with the picker shut and the checklist open — the state the gate hands over to —\n      // rather than with the picker open, which would put the decision they already made back at the top of\n      // the page. Seeded once and only once: after that it is the user's own toggle, and a refresh() (a\n      // module flip, a dialog close, a seed) must never re-shut a card they just opened.\n      if (!this.modulesSeeded && this.status) { this.modulesCollapsed = this.modulesConfirmed; this.modulesSeeded = true; }\n      this.buildGroups();\n      if (this.hasRoleTemplatesStep()) this.loadRoleTemplates();\n      if (this.hasSeedStep() || this.showDemoData) this.loadSeedOffers(); // Changed (seed-all): the Demo data card reports per area from the same offers, so an app with the card but no seed: true step still needs them\n      // Added (presets): only load a picker when the backend actually serves its step. The approvals step is gated\n      // on the approvals module, so turning that module off makes the step — and this call — disappear with it.\n      this.pickers.forEach(picker => { if (this.hasPresetsStep(picker)) this.loadPresets(picker); });\n    });\n    this.setupService.loadStatus();\n  }\n\n  // Group steps by category preserving backend order; auto-expand the first incomplete step\n  private buildGroups() {\n    const steps = this.status?.steps || [];\n    const names: string[] = [];\n    steps.forEach(s => { if (!names.includes(s.category)) names.push(s.category); });\n    const firstIncomplete = steps.find(s => !s.complete); // Changed: expandedKey now travels inside each group's ChecklistConfig\n    this.groups = names.map(name => {\n      const groupSteps = steps.filter(s => s.category === name);\n      const done = groupSteps.filter(s => s.complete).length;\n      const outstanding = groupSteps.filter(s => !s.complete);\n      // Changed (fusion): the open/shut cascade, copied in SHAPE from buildModuleGroups below because the hazard\n      // is identical — buildGroups() runs on EVERY status$ emission (a toggle, a dialog close, a seed, an import)\n      // and replaces these objects wholesale. Seeding `collapsed` from the default alone would slam every group\n      // the user opened shut on the next refresh, intermittently and invisibly.\n      // What is on screen NOW wins, then what this user saved, and only then the seed.\n      const previous = this.groups.find(g => g.name === name);\n      // The SEED, and it is deliberately NOT the Day Book's \"first one open\". Getting Started is a SEQUENCE with a\n      // live position: the group holding the first incomplete step is the one waiting for you, so that is the one\n      // that opens. Everything already finished collapses into a card with a full ring — which is the owner's\n      // \"an easy visual for someone to see this I have completed\", raised to the category tier.\n      const holdsFirstIncomplete = !!firstIncomplete && groupSteps.some(s => s.key === firstIncomplete.key);\n      return {\n        name,\n        completed: done,\n        total: groupSteps.length,\n        config: { items: this.sectionItems(groupSteps), expandedKey: firstIncomplete?.key || '' },\n        collapsed: previous?.collapsed ?? this.categorySectionState[name] ?? !holdsFirstIncomplete,\n        done,\n        todo: outstanding.filter(s => s.required).length,\n        optional: outstanding.filter(s => !s.required).length,\n        // one chip per OUTSTANDING step — a shut group's chips are the way straight into the work, exactly as the\n        // Day Book's collapsed lane chips are. A finished group shows none, and says so instead.\n        chips: outstanding.map(s => ({ key: s.key, label: s.title, optional: !s.required })),\n        about: this.categoryAbout(groupSteps),\n        icon: this.categoryIcon(groupSteps)\n      };\n    });\n  }\n\n  // Added (v2-1): the THIRD collapse tier — \"the main one, then I toggle the next one, drilling deeper and\n  // deeper\". This stamps each step with the section it belongs to; spa-checklist does the folding, and it\n  // renders NO sub-tier at all unless the stamping yields more than one section (checklist.component.ts\n  // buildSections), so a category that resolves to a single band stays exactly as flat as it is today.\n  //\n  // 🔑 THE SECTION IS THE MODULE'S GROUP, NOT THE MODULE. That distinction is the whole design and it is\n  // settled precedent, not a new idea: buildPresetGroups made exactly this choice in GS P4 (\"the section NAMES\n  // now come from the module the preset belongs to, so these read Foundation / Finance / Supply Chain\"), and\n  // sectionOf() closed the module-per-section question for the same reason. Grouping by MODULE here would give\n  // Start Operating five bands of exactly one step each — a \"1 of 1\" counter under a header repeating the row\n  // beneath it, which is the defect both of those rulings already rejected.\n  //\n  // A step with no module is library-core and always visible (SetupStep.Module: \"null steps are always\n  // visible\"), so it cannot borrow a group from anywhere — it gets its own leading band.\n  private sectionItems(steps: SetupStep[]): ChecklistItem[] {\n    return steps.map(s => ({ ...this.toItem(s), section: this.sectionForStep(s) }));\n  }\n\n  private sectionForStep(step: SetupStep): string {\n    if (!step.module) return 'Essentials';\n    const mod = this.modules.find(m => m.key === step.module);\n    // A module the catalog does not carry (an app that ships a step for a module it never declares) falls back\n    // to its own key rather than being silently swept into Essentials, which would be a lie about what it is.\n    return mod?.group || mod?.title || step.module;\n  }\n\n  // Added (fusion): the \"what is this\" tooltip. A CATEGORY has no description in the backend — buildGroups derives\n  // the name from the step's `category` string and nothing else — so this is synthesised from the steps it holds\n  // rather than invented. Chosen over adding a server-side description: no cross-repo change, it works for every\n  // consumer app immediately, and guessing prose for five apps' categories would be worse than a factual list.\n  // Changed (v2-1): capped at THREE titles, not four. This string is no longer a tooltip you hover for — it is\n  // the subcard's permanent caption on a single ellipsised line, so a fourth title did not fit at 1200px and\n  // the line ended \"+ 4 ...\" — the sentence's own tail counter truncated by the CSS ellipsis, which reads as a\n  // rendering fault rather than a summary. Three fit, and the tail is still counted rather than dropped.\n  private categoryAbout(steps: SetupStep[]): string {\n    const titles = steps.slice(0, 3).map(s => s.title);\n    const tail = steps.length > titles.length ? ` + ${steps.length - titles.length} more` : '';\n    return `${steps.length} ${steps.length === 1 ? 'step' : 'steps'}: ${titles.join(', ')}${tail}`;\n  }\n\n  // Added (v2-1): the subcard's section icon, taken from the steps the category holds.\n  //\n  // 🔴 A TICK OR AN EMPTY CIRCLE IS NEVER THE SECTION ICON, and this guard is the whole reason the method\n  // exists. The owner's instruction was to strip \"the circles AND the check mark that sit in the title\", and\n  // taking simply the first step's icon walked straight back into it: AccountCreatedStep (DefaultSetupProvider\n  // .cs:393) sets Icon = \"check_circle\", it is ORDER 1, so it is the first step of the company-setup category\n  // in every app — and Company Setup was rendering a check circle in its title row, which is the exact glyph\n  // that was just removed from it. Skipping the tick-shaped glyphs picks the next real symbol (tune, for the\n  // choose-modules step) and the meaning improves as well as the look: a section icon should say what the\n  // section IS, and \"check_circle\" says only \"something in here is done\", which the badges already say.\n  private categoryIcon(steps: SetupStep[]): string {\n    const tickLike = /check|radio_button|circle/i;\n    return steps.find(s => !!s.icon && !tickLike.test(s.icon))?.icon || 'checklist';\n  }\n\n  // Added (fusion): open/shut one category and remember it. Deliberately NOT an accordion — as with the module\n  // sections, the requirement is a sensible starting state, not that only one may ever be open.\n  toggleCategory(group: { name: string, collapsed: boolean }) {\n    group.collapsed = !group.collapsed;\n    this.categorySectionState[group.name] = group.collapsed;\n    try { localStorage.setItem('tin-setup-category-sections', JSON.stringify(this.categorySectionState)); } catch { /* private mode — the page still works, the choice just will not outlive the visit */ }\n  }\n\n  // Added (fusion): a chip on a shut group opens the group AND expands the step it names — the Day Book's\n  // \"a chip is a way in\" (day-book.component.html goTo). The config object is REPLACED rather than mutated:\n  // spa-checklist adopts a new seed from ngOnChanges(changes['config']), which a mutation would never fire.\n  goToStep(group: { collapsed: boolean, config: ChecklistConfig }, key: string) {\n    group.collapsed = false;\n    group.config = { ...group.config, expandedKey: key };\n  }\n\n  // Added (GS P4): the identity behind the *ngFor above. Category names are unique within the page and stable\n  // across a rebuild, so this keeps each spa-checklist instance alive through a refresh() instead of replacing it.\n  trackByGroup(index: number, group: { name: string }) { return group.name; }\n\n  // Map a backend step to a checklist item — actions resolve from appConfig.setupConfig.stepActions\n  private toItem(step: SetupStep): ChecklistItem {\n    return { key: step.key, title: step.title, description: step.description, complete: step.complete, optional: !step.required, progressText: step.target > 1 ? this.progressLabel(step) : undefined, actions: this.buildActions(step), data: step };\n  }\n\n  // Standardized action set: primary (Create dialog or Go to page), Import from Excel, secondary Go to page\n  private buildActions(step: SetupStep): ChecklistAction[] {\n    const act = this.getAction(step);\n    const actions: ChecklistAction[] = [];\n    const picker = this.pickerFor(step); // Changed (presets P4): whichever picker owns this step, if any\n    // Added (fusion): the choose-modules step is the RECEIPT of a decision made in the \"Your modules\" card at the\n    // top of the page, not the place the decision is made — the picker reshapes the very checklist this step lives\n    // in (turning a module off removes its steps and can remove a whole category group), so it cannot be nested\n    // inside it without a control that can delete its own container. What was missing was not proximity but a\n    // STATED RELATIONSHIP: nothing on screen connected the two. This action is that connection, and it reuses the\n    // scroll-and-focus mechanism the seed offers already use rather than inventing one.\n    if (step.key === 'choose-modules' && this.modules.length > 0) {\n      actions.push({ type: 'custom', display: 'Choose modules', icon: 'tune', primary: true, onClick: () => this.scrollToModules() });\n    } else if (this.hasRoleTemplates(step)) {\n      actions.push({ type: 'custom', display: 'Create selected roles', primary: true, disabled: () => this.selectedTemplateCount === 0 || this.creatingRoles, onClick: () => this.createSelectedRoles() }); // Changed (P2): DELIBERATELY given NO icon, so it keeps its label on a phone. It is disabled until templates are ticked, and a disabled Material button takes no pointer events — so an icon-only version would be a grey square whose tooltip cannot open, saying nothing about what it is waiting for\n    } else if (picker) {\n      actions.push(picker.action); // Added (presets): the same object every rebuild, so the mutated count label survives a status refresh\n    } else if (act.button) {\n      actions.push({ type: 'create', display: this.primaryLabel(step), icon: act.button?.icon?.name || 'add', primary: true, onClick: () => this.doPrimary(step) }); // Changed: filled primary only for create dialogs — a bare link is never promoted to a filled button. Changed (P2): takes the app's own configured button icon when there is one, so a step that already has a symbol keeps it and only the rest fall back to 'add'\n    }\n    if (this.hasView(step)) actions.push({ type: 'view', display: 'View', icon: 'launch', onClick: () => this.doView(step) }); // Changed: 'visibility' (the eye) -> 'launch', so this View matches every other view action in the estate — the eye read as a show/hide toggle, which is what text-mask actually uses it for. Added (P7): inserted HERE, not appended. buildActions pushes primary -> import -> link, so appending View last would read Add . Import . Go to page . View; the asked-for order is Add . View . Import . Go to page, and it is right on the merits too — View is a READ affordance belonging beside the create it qualifies, while Go to page stays last as the escape hatch off the page\n    if (this.hasImport(step)) actions.push({ type: 'import', display: 'Import from Excel', icon: 'upload_file', onClick: () => this.doImport(step) });\n    if (act.link || step.link) actions.push({ type: 'link', display: act.linkDisplay || 'Go to page', icon: 'arrow_forward', onClick: () => this.navigate(step) }); // Changed: exactly ONE \"Go to page\" per step (was duplicated as filled+secondary on import+link steps), outlined style. Changed (P2): arrow_forward — this navigates WITHIN the app, so it is not open_in_new\n    if (this.hasSeed(step)) actions.push({ type: 'seed', display: 'Examples', icon: 'science', onClick: () => this.doSeed(step) }); // Added (P6 / task 6.5): LAST, after Go to page, because that is the order 6.5 states in as many words — \"Add · View · Import · Go to page · Seed\". It reads right too: this is the only action on the row that offers FAKE records, so it sits furthest from the four that deal in real ones. NEVER \"Seed\": this chip WRITES NOTHING, it only takes you to the offer block, and a chip named for a verb it does not perform is the same defect as a button whose mechanism was removed. ⚠️ \"Examples\" and not the better-reading \"Example data\" for a MEASURED reason — at 1920 the row's widest step (\"Add Product\") leaves this chip 142px: \"Example data\" is 156 and wraps the row to 88px, \"Examples\" is 132 and holds it at 40px. THIS ROW IS NOW FULL — a sixth action, or a primary label longer than \"Add Product\", wraps it\n    return actions;\n  }\n\n  getAction(step: SetupStep): SetupStepAction {\n    return this.dataService.appConfig?.setupConfig?.stepActions?.[step.key] || {};\n  }\n\n  hasDialog(step: SetupStep): boolean {\n    return !!this.getAction(step).button;\n  }\n\n  hasAction(step: SetupStep): boolean {\n    return this.hasDialog(step) || !!(this.getAction(step).link || step.link);\n  }\n\n  primaryLabel(step: SetupStep): string {\n    const button = this.getAction(step).button;\n    return button ? (button.display || 'Create') : 'Go to page';\n  }\n\n  progressLabel(step: SetupStep): string {\n    return `${step.current > step.target ? step.target : step.current} of ${step.target}`;\n  }\n\n  // Primary CTA — open the create dialog when configured, otherwise navigate to the entity page\n  doPrimary(step: SetupStep) {\n    const act = this.getAction(step);\n    if (act.button) {\n      this.dialogService.openDefaultDetailsDialog({ ...act.button }, {}).subscribe(result => {\n        if (!result) return; // Added: Escape/backdrop dismissal closes with undefined. This one never threw (it already read through `?.`) but it fell on through to refresh() on every dismissal — a dismissal changes nothing, so it must not recount either.\n        if (result.action === 'inputChange') return; // Changed: an input change is not a close — nothing to recount or follow up\n        this.setupService.refresh(); // Recount after the dialog closes so progress advances immediately\n        this.openSuccessButton(act.button!, result); // Added: complete CLAUDE.md's Two-Step Create Pattern from this page too\n      });\n    } else {\n      this.navigate(step);\n    }\n  }\n\n  // Added: second step of the two-step create. `onSuccessButton` was honoured only by spa-table, so a header\n  // created here (Trip, Work Order, Check Template, Make, Rental...) saved and closed without ever offering the\n  // child-items dialog. Mirrors table.component.ts exactly, including the offline guard — a pending offline row\n  // has no server ID yet, so there is nothing to reopen.\n  private openSuccessButton(button: Button, result: any) {\n    const created = result?.data?.data;\n    if (result?.message !== 'success' || !button.onSuccessButton || !created || created._offline) return;\n    this.dialogService.openDefaultDetailsDialog({ ...button.onSuccessButton }, created).subscribe(() => this.setupService.refresh());\n  }\n\n  navigate(step: SetupStep) {\n    const act = this.getAction(step);\n    this.dataService.Navigate(act.link || step.link);\n  }\n\n  // Added (fusion): the other half of the link — take the user to the picker and leave the focus there, so a\n  // keyboard user arrives at the control and not merely at the scroll position. Same shape as the seed-offer\n  // scroll target (P6). Guarded on the element existing: an app with no modules never renders the card.\n  scrollToModules() {\n    const card = document.getElementById('setup-modules-card');\n    if (!card) return;\n    card.scrollIntoView({ behavior: 'smooth', block: 'start' });\n    const first = card.querySelector('.module-section-head') as HTMLElement | null;\n    if (first) setTimeout(() => first.focus(), 400); // after the smooth scroll settles, or the browser cancels it\n  }\n\n  //---------- Modules (v2) ----------\n\n  // Added (v3): group the catalog for display — the app's own modules first (backend orders them below 100),\n  // then the library groups. Modules from a backend that predates grouping have no group and fall into\n  // \"Your modules\", which renders exactly like the old flat list.\n  // Added (P3): what a module section IS, as ONE expression. DECIDED — a section is the backend's GROUP, which is\n  // what ships. One section per MODULE was considered and rejected: it would produce 13-21 sections holding\n  // exactly ONE card each (Shift 21 modules across 7 groups, Grip 20/7, Piglet 18/7, Test 15/6, Pulse 13/6), every\n  // one carrying a \"1 of 1\" counter and a summary repeating the header directly above it. Closed — do not reopen.\n  private sectionOf(mod: SetupModule): string {\n    return mod.group || 'Your modules';\n  }\n\n  private buildModuleGroups() {\n    const names: string[] = [];\n    this.modules.forEach(m => { const name = this.sectionOf(m); if (!names.includes(name)) names.push(name); });\n    this.moduleGroups = names.map((name, index) => {\n      const groupModules = this.modules.filter(m => this.sectionOf(m) === name);\n      // Changed (P3): the open/shut cascade, and the whole reason this phase is not a one-liner. buildModuleGroups\n      // runs on EVERY status$ emission — every refresh() from a module toggle, a dialog close, a seed or an import —\n      // and it replaces these objects wholesale. Seeding `collapsed` from the default alone would slam every section\n      // the user opened shut on the next refresh, intermittently and invisibly. The Day Book's cascade is the fix:\n      // what is on screen NOW wins, then what this user saved, and only then the first-open seed.\n      const previous = this.moduleGroups.find(g => g.name === name);\n      return {\n        name, modules: groupModules,\n        enabled: groupModules.filter(m => m.enabled).length,\n        total: groupModules.length,\n        // Changed (v3, owner): the seed is now GATE-AWARE, and it deliberately amends the all-collapsed rule\n        // for the pre-confirmation view ONLY. While the gate is shut this card is the entire page and the first\n        // thing a new tenant ever sees, so the first group opens showing its coloured module cards — a column of\n        // identical shut bands is a poor first impression of a product whose modules are the product. Only the\n        // FIRST, so it invites rather than floods. Once confirmed the whole card is optional, so every section\n        // seeds shut (the owner's item 3), and the cascade above still means what is on screen now, and what\n        // this user saved, both outrank the seed.\n        collapsed: previous?.collapsed ?? this.moduleSectionState[name] ?? (this.gateOpen || index > 0),\n        summary: this.moduleSummary(groupModules)\n      };\n    });\n  }\n\n  // Added (P3): what a shut section still says about itself. The count beside it already answers \"how many\"; this\n  // answers \"of what\" — because a column of identical closed headers is a worse page than the long list it\n  // replaced, and the requirement is that a collapsed section carries a REAL summary. Naming the modules that are\n  // on is also the only thing that distinguishes a section which is done from one that has not been touched, which\n  // is the \"does this need me\" question you are asking while scanning. Capped at three names so a 9-module section\n  // stays one line on a phone; the tail is counted rather than dropped.\n  private moduleSummary(modules: SetupModule[]): string {\n    const on = modules.filter(m => m.enabled);\n    if (on.length === 0) return `Nothing on yet — ${modules.length} to choose from`;\n    const names = on.slice(0, 3).map(m => m.title);\n    return on.length > names.length ? `${names.join(' · ')} + ${on.length - names.length} more` : names.join(' · ');\n  }\n\n  // Added (P3): open/shut one section and remember it. Deliberately NOT an accordion — the requirement is that the\n  // first section is open and the rest are shut, not that only one may ever be open.\n  toggleModuleSection(group: { name: string, collapsed: boolean }) {\n    group.collapsed = !group.collapsed;\n    this.moduleSectionState[group.name] = group.collapsed;\n    localStorage.setItem('tin-setup-module-sections', JSON.stringify(this.moduleSectionState));\n  }\n\n  // Optimistic toggle — flip locally, persist, revert on failure; success refreshes steps + menus\n  toggleModule(mod: SetupModule) {\n    if (mod.core || this.togglingKey) return;\n    const target = !mod.enabled;\n    mod.enabled = target;\n    this.recountModuleGroups(); // Added (v3): the group's \"n of m on\" counter follows the optimistic flip\n    this.togglingKey = mod.key;\n    this.setupService.setModule(mod.key, target).subscribe({\n      next: resp => {\n        this.togglingKey = '';\n        if (resp.success) this.setupService.refresh();\n        // Changed: the optimistic revert stays exactly as it was — it is correct and must not be lost — but it\n        // was the ONLY feedback. A switch the user flipped silently flipping itself back is not a failure\n        // message, it is a glitch: the likeliest reading is that the click missed, so they flip it again.\n        else { mod.enabled = !target; this.recountModuleGroups(); this.apiErrorService.presentAppFailure(resp, 'action', 'setup/module'); }\n      },\n      error: () => { this.togglingKey = ''; mod.enabled = !target; this.recountModuleGroups(); }\n    });\n  }\n\n  // Cards hold the same SetupModule references, so only the counters need recomputing\n  // Changed (P3): the shut section's summary is recomputed with the counter, off the same optimistic flip. Without\n  // this a section you collapsed after turning something on would keep describing the modules that WERE on.\n  private recountModuleGroups() {\n    this.moduleGroups.forEach(g => { g.enabled = g.modules.filter(m => m.enabled).length; g.summary = this.moduleSummary(g.modules); });\n  }\n\n  // Confirms the current selection as reviewed — completes the choose-modules step without a toggle.\n  //\n  // Changed (v2-1, owner): it now asks first, and the reason is precise — \"a new user will click confirm\n  // without having actually chosen; the dialog makes them see what they decided\". The COUNT is the whole\n  // point of the sentence: it is the one fact that turns a reflex click into a decision, because a user who\n  // has touched nothing sees the number the defaults gave them and can go back. It is the house confirm\n  // (messageService.confirm), not a new dialog component — nothing here needs a typed phrase or a\n  // destructive colour, and a second confirm idiom on this page would be the change rather than the feature.\n  confirmModules() {\n    if (this.togglingKey) return;\n    const n = this.enabledModuleCount;\n    // Never \"1 modules\". The wording is composed here rather than server-side because it describes the state\n    // of a control on THIS page — unlike the effect/notice sentences, which stay the catalogue's.\n    const question = n === 1\n      ? 'You have selected 1 module — proceed?'\n      : `You have selected ${n} modules — proceed?`;\n    this.messageService.confirm(question, 'Proceed').subscribe(answer => {\n      if (answer !== 'yes') return; // messageDialog answers with the literal 'yes'\n      this.togglingKey = 'confirm';\n      this.setupService.setModule('confirm', true).subscribe({\n        next: () => {\n          this.togglingKey = '';\n          // The other half of the gate: the moment the selection is adopted, the picker FOLDS. His words —\n          // \"they can still go back and make adjustments... but we take that away by collapsing it so they\n          // focus on the next items\". It is set here and not derived from modulesConfirmed, so a returning\n          // user who deliberately opens the card again keeps it open.\n          this.modulesCollapsed = true;\n          // Added (v3, owner item 3): and every section inside it shuts with it, now and on every return visit.\n          // The saved state is cleared rather than kept because the folds made while the gate was shut belong to\n          // the GATE view — a group the user opened to read it during a one-time decision must not still be the\n          // open one months later, when the card is an optional aside. Anything opened AFTER this point persists\n          // normally through toggleModuleSection.\n          this.moduleGroups.forEach(g => g.collapsed = true);\n          this.moduleSectionState = {};\n          localStorage.removeItem('tin-setup-module-sections');\n          this.setupService.refresh();\n        },\n        error: () => this.togglingKey = ''\n      });\n    });\n  }\n\n  // Added (v2-1): what the confirm counts. Core modules are locked on and are genuinely part of the selection\n  // the user is adopting, so they count — a sentence that said \"3 modules\" while eight were about to be\n  // switched on would be the confirm lying about its own effect, which is the one thing it exists to prevent.\n  get enabledModuleCount(): number {\n    return this.modules.filter(m => m.enabled).length;\n  }\n\n  get modulesConfirmed(): boolean {\n    const step = this.status?.steps?.find(s => s.key === 'choose-modules');\n    return !step || step.complete;\n  }\n\n  //---------- The gate (v2-1) ----------\n  // 🔑 THE PAGE DOES NOT EXIST UNTIL THE MODULES ARE CONFIRMED. Owner directive: on first load ONLY the\n  // \"Your modules\" card renders, expanded; Company Setup and every other section are hidden ENTIRELY. This is\n  // not decoration — the module picker RESHAPES the checklist below it (turning a module off removes its steps\n  // and can remove a whole category group), so a first-time user reading and part-answering a checklist that\n  // is about to be rebuilt underneath them is doing work that may vanish. Confirming first is the only order\n  // in which the rest of the page is stable enough to be worth reading. It is also the \"reveal the\n  // functionality bit by bit\" the whole iteration is for.\n  //\n  // ⚠️ It is deliberately gated on `modulesConfirmed` — the SERVER's answer, read off the choose-modules step —\n  // and never on a local flag. A returning tenant who confirmed months ago must never meet this gate again,\n  // and DefaultSetupProvider.cs:135 sets ModulesConfirmed on ANY interaction with the picker, so the gate\n  // opens for anyone who has ever touched it, not only for someone who pressed this exact button.\n  //\n  // An app with NO module catalog renders no picker at all (`modules.length > 0` on the card), and\n  // modulesConfirmed is `true` when there is no choose-modules step — so such an app is never gated. That is\n  // the correct behaviour and it is why the getter tests the step rather than the card.\n  get gateOpen(): boolean {\n    return this.modules.length === 0 || this.modulesConfirmed;\n  }\n\n  // Added (v2-1): the picker's own fold. Starts OPEN — before confirmation it is the only thing on the page,\n  // and it is what the user is there to do.\n  modulesCollapsed = false;\n  private modulesSeeded = false; // see ngOnInit — the fold is seeded from the server exactly once\n\n  toggleModulesCard() {\n    // Never foldable while it is the only card on screen: a shut picker on a gated page is a blank page.\n    if (!this.gateOpen) return;\n    this.modulesCollapsed = !this.modulesCollapsed;\n  }\n\n  // What the shut picker still says about itself — the same job the category chips and the module-section\n  // summaries do, capped and counted the same way (moduleSummary above), so it is one idiom on the page.\n  get modulesSummary(): string {\n    const on = this.modules.filter(m => m.enabled);\n    if (on.length === 0) return 'Nothing on yet';\n    const names = on.slice(0, 3).map(m => m.title);\n    return on.length > names.length ? `${names.join(' · ')} + ${on.length - names.length} more` : names.join(' · ');\n  }\n\n  //---------- Excel import (v2) ----------\n\n  hasImport(step: SetupStep): boolean {\n    return !!this.getAction(step).import;\n  }\n\n  doImport(step: SetupStep) {\n    const act = this.getAction(step);\n    if (!act.import) return;\n    this.dialogService.openImportDialog({ ...act.import }).subscribe(result => {\n      if (result === 'success') this.setupService.refresh(); // Committed import — recount immediately\n    });\n  }\n\n  //---------- Predefined roles (v2) ----------\n\n  hasRoleTemplates(step: SetupStep): boolean {\n    return !!this.getAction(step).roleTemplates;\n  }\n\n  private hasRoleTemplatesStep(): boolean {\n    return (this.status?.steps || []).some(s => this.getAction(s).roleTemplates);\n  }\n\n  private loadRoleTemplates() {\n    this.setupService.loadRoleTemplates().subscribe({\n      next: resp => {\n        if (!resp.success) { this.apiErrorService.presentAppFailure(resp, 'load', 'setup/roles'); return; } // Changed: was a bare `return`. The picker then rendered zero templates, which reads as \"this app ships no predefined roles\" — a completely different statement from \"we could not fetch them\"\n        this.roleTemplates = resp.data || [];\n        // Preselect everything not yet created — the common case is \"give me all of these\"\n        this.roleTemplates.forEach(t => { if (this.selectedTemplates[t.key] === undefined) this.selectedTemplates[t.key] = !t.exists; });\n      },\n      error: () => { }\n    });\n  }\n\n  get selectedTemplateCount(): number {\n    return this.roleTemplates.filter(t => !t.exists && this.selectedTemplates[t.key]).length;\n  }\n\n  // Added: whole-row toggle for the restyled picker (state-icon rows replaced the checkboxes)\n  toggleTemplate(tpl: SetupRoleTemplate) {\n    if (tpl.exists) return;\n    this.selectedTemplates[tpl.key] = !this.selectedTemplates[tpl.key];\n  }\n\n  //---------- Example data (seed seam) ----------\n  // Seeding lives HERE and not on a working page, because getting started is exactly when someone needs a few rows\n  // to look at. Three things make this different from the demo-data card at the foot of the page:\n  //   1. it is SCOPED — an offer seeds its own step's area and nothing else;\n  //   2. it is DEPENDENCY-AWARE — the server applies whatever the offer declares it needs first, and the row says\n  //      so in plain words BEFORE the click;\n  //   3. it is EXPLICITLY example data — the notice is on the row and repeated in the confirm, so nobody can add\n  //      it without knowing that is what they are doing.\n  // ⚠️ Accounting seeding is deliberately NOT here and must never be moved here. It is not optional and it is not\n  // a choice — the Transaction Types button and the automatic financial seeds stay exactly as they are.\n\n  //---------- View (P7) ----------\n  // A read-only look at what is already captured, without leaving the page. The config is the ENTITY OWN\n  // TableConfig, declared per app — never derived from the step. That is what keeps the read on the entity\n  // capability-gated list endpoint (customers/all/x) rather than a setup/* route, every one of which is\n  // [Authorize]-only with no capability check. Deriving it from the step would have leaked exactly that.\n\n  hasView(step: SetupStep): boolean {\n    // The two exclusions are structural, not stylistic. A role-template step and a preset picker step are this\n    // page ICON-LESS primaries, and .cl-break (checklist.component.html:24) fires on\n    // primary && !icon && actions.length > 2 — so a View action there would push them over that threshold and\n    // add a line break they do not have today. They are also not entity steps, so there is no list to show.\n    // Guarding here rather than trusting every app never to declare it makes that impossible, not merely unlikely.\n    return !!this.getAction(step).view && !this.hasRoleTemplates(step) && !this.pickerFor(step);\n  }\n\n  doView(step: SetupStep) {\n    const act = this.getAction(step);\n    if (!act.view) return;\n    // tabTitle is REUSED as the dialog title rather than adding a parallel property — it already means \"what to\n    // call this table when it is not on its own page\". Falls back to the step title.\n    // The spread is not cosmetic: spa-table-dialog hardens the config it receives, and it must never harden the\n    // shared object the app declared once and every other surface reuses.\n    this.dialogService.openTableDialog({ title: act.view.tabTitle || step.title, config: { ...act.view } });\n  }\n\n  //---------- Example data (seed seam) ----------\n\n  // Changed (P6): was dead code — declared, never called. It is now the gate on the Example data action, and it\n  // deliberately tests TWO things rather than the config flag alone. `seed: true` only means the app ASKED for\n  // offers; whether the server actually returned any for this step is a separate fact, and the block below only\n  // renders on that second one (`seedRowsByStep[key]`, setup-guide.component.html). Gating the chip on the flag\n  // alone would put a button on the row whose destination does not exist — it would scroll nowhere and look like\n  // nothing happened, which is the exact defect this page has already been bitten by once.\n  hasSeed(step: SetupStep): boolean {\n    return !!this.getAction(step).seed && (this.seedRowsByStep[step.key]?.length || 0) > 0;\n  }\n\n  // The offers block is rendered ABOVE this row, not below it: checklist.component.html projects the step template\n  // BEFORE .cl-actions. Measured on 4200 at 1920x889 — block top 1603 / height 210, actions row top 1825. So this\n  // scrolls BACKWARDS to something the reader has already passed, which is why `block: 'nearest'` and not 'start':\n  // the block is usually still partly on screen and yanking the page when nothing was hidden reads as a glitch.\n  // Focus is the part that carries real weight — it lands the caret on the counted, described button inside the\n  // block, so a keyboard or screen-reader user is put ON the control rather than merely near it. Nothing is\n  // written here; the block's own button stays the only thing that seeds, so nobody ever seeds blind.\n  // Changed (2026-08-19): the offers are now shut by default, so this must OPEN this step's offers before it can\n  // scroll to or focus anything inside them — .seed-action does not exist in the DOM while the fold is closed, and\n  // without this the \"Example data\" action would have silently stopped landing focus anywhere. Opening here is not\n  // a contradiction of the default: the reader has just explicitly asked for example data, which is the one moment\n  // the explanation is what they came for. The focus is deferred a tick so *ngIf has rendered the body first.\n  doSeed(step: SetupStep) {\n    (this.seedRowsByStep[step.key] || []).forEach(row => this.openSeedKeys.add(row.offer.key));\n    setTimeout(() => {\n      const el = document.getElementById('seed-offers-' + step.key); // same id the block declares; `?.` matches landing.component.ts\n      const smooth = !window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches; // a jump, not a glide, when the operator has asked for less motion — same test as day-book.component.ts\n      el?.scrollIntoView({ behavior: smooth ? 'smooth' : 'auto', block: 'nearest' });\n      (el?.querySelector('.seed-action:not([disabled])') as HTMLElement | null)?.focus({ preventScroll: true }); // preventScroll: focus must not fight the scroll above. Absent when every offer is already applied — then the scroll alone is the whole answer, and the block says \"Added\"\n    });\n  }\n\n  private hasSeedStep(): boolean {\n    return (this.status?.steps || []).some(s => this.getAction(s).seed);\n  }\n\n  private loadSeedOffers() {\n    this.setupService.loadSeedOffers().subscribe({\n      next: resp => {\n        // Same reasoning as loadRoleTemplates and loadPresets: a bare return renders no offers, which reads as\n        // \"this app has no example data to give you\" — a completely different statement from \"we could not fetch it\".\n        if (!resp.success) { this.apiErrorService.presentAppFailure(resp, 'load', 'setup/seedoffers'); return; }\n        this.buildSeedRows(resp.data || []);\n      },\n      error: () => { }\n    });\n  }\n\n  // Materialize once per load. Offers with no stepKey are PREREQUISITES — they exist so another offer can declare\n  // them, they render nowhere, and dropping them here is what keeps them invisible.\n  private buildSeedRows(offers: SetupSeedOffer[]) {\n    const byStep: { [key: string]: SeedRow[] } = {};\n    offers.filter(o => !!o.stepKey).forEach(offer => {\n      const rows = byStep[offer.stepKey] || (byStep[offer.stepKey] = []);\n      rows.push({ offer, alsoAdds: this.seedAlsoAdds(offer), hereAlready: this.seedHereAlready(offer), actionLabel: this.seedActionLabel(offer) });\n    });\n    this.seedRowsByStep = byStep;\n\n    // Changed (seed-all): the Demo data card gets EVERY offer, prerequisites included. A step row hides a\n    // prerequisite on purpose (nobody should have to think about product categories to get products), but the card\n    // is a report on the whole system, and an area quietly filled by somebody else's dependency is still an area\n    // that changed. Order is the server's catalogue order, untouched.\n    this.demoAreas = offers.map(offer => ({ offer, label: this.demoAreaLabel(offer), state: this.demoAreaState(offer) }));\n    this.demoPending = offers.filter(o => !o.applied).length;\n\n    // Added (P6): rebuild the rows now that the offers have landed. buildActions() runs inside buildGroups(), which\n    // fires from the status$ subscription BEFORE this HTTP call returns — so an Example data action gated on real\n    // offers would be computed as false on first load and never appear again, because nothing else rebuilds. The\n    // template escapes this by reading seedRowsByStep directly; a baked-in `actions` array cannot.\n    // Safe to repeat: buildGroups() is what every refresh() already does, and the expandedKey it recomputes is\n    // identical (same status, same firstIncomplete), so checklist.component.ts's seededKey guard sees no change and\n    // does not re-seed — whatever the reader had open stays open.\n    this.buildGroups();\n  }\n\n  // Added (seed-all): a PREREQUISITE offer's Name is deliberately a sentence FRAGMENT server-side (\"product\n  // categories\"), because on a step row it is only ever read inside \"…also adds product categories\". This card is\n  // the one place a prerequisite is listed as a row of its own, where a lowercase fragment beside three capitalised\n  // sentences reads as a rendering fault. Only the first letter is raised — the wording stays the server's, so this\n  // does not become a second place where copy is authored. Materialized at load, never computed in a binding.\n  private demoAreaLabel(offer: SetupSeedOffer): string {\n    const name = offer.name || '';\n    return name.charAt(0).toUpperCase() + name.slice(1);\n  }\n\n  // What this ONE area says about itself: what is already in it, and what a fill would add. Numbers only — every\n  // SENTENCE on this page is the server's (effect, sampleNotice), and this must not become a second place where\n  // wording is authored. It always names what it counts; a bare number was removed from the Day Book on that ruling.\n  private demoAreaState(offer: SetupSeedOffer): string {\n    const here = offer.existing === 1 ? '1 record here' : `${offer.existing} records here`;\n    if (offer.applied) return here;\n    return offer.existing === 0 ? `empty — adds ${offer.wouldCreate}` : `${here} — adds ${offer.wouldCreate}`;\n  }\n\n  // The prerequisites this click would ALSO create. The server sends only the ones not already there, so the\n  // sentence is true at the moment it is read — \"it will also add X\" about something already present is a lie.\n  private seedAlsoAdds(offer: SetupSeedOffer): string {\n    const includes = offer.includes || [];\n    return includes.length === 0 ? '' : `Also adds ${includes.join(', ')} — these cannot exist without them.`;\n  }\n\n  // The live count of what is in this area already, real records or example ones. This is the decision-support\n  // half: somebody with four customers already does not want three more invented ones. It always says WHAT it\n  // counts — a bare number was removed from the Day Book on exactly that ruling.\n  private seedHereAlready(offer: SetupSeedOffer): string {\n    if (offer.applied || !offer.existing) return '';\n    return offer.existing === 1 ? '1 record is already in this list' : `${offer.existing} records are already in this list`;\n  }\n\n  // The button says HOW MANY, because a button that says only \"Seed\" is asking for blind consent. wouldCreate is\n  // the server's live count of rows that do not exist yet, so the number on the button is the number that lands.\n  private seedActionLabel(offer: SetupSeedOffer): string {\n    if (offer.wouldCreate === 1) return 'Add 1 example record';\n    return offer.wouldCreate > 1 ? `Add ${offer.wouldCreate} example records` : 'Add example data';\n  }\n\n  // The confirm is where the example-data notice becomes unavoidable — \"you don't want to just add without someone\n  // knowing that this is what they are doing\". Every sentence in it is the SERVER'S, none is composed here: the\n  // effect, the prerequisite line and the standing notice are all authored in the catalogue, so the wording is\n  // correctable in one place for all five apps. Blank lines are real paragraph breaks in the message dialog.\n  applySeedOffer(offer: SetupSeedOffer) {\n    if (offer.applied || this.seedingKey) return;\n\n    const alsoAdds = (offer.includes || []).length > 0 ? `\\n\\nIt will also add: ${offer.includes.join(', ')}.` : '';\n    this.messageService.confirm(`${offer.effect}${alsoAdds}\\n\\n${offer.sampleNotice}`, 'Add example data').subscribe(answer => {\n      if (answer !== 'yes') return; // messageDialog answers with the literal 'yes'\n      this.seedingKey = offer.key;\n      this.setupService.applySeedOffer(offer.key).subscribe({\n        next: resp => {\n          this.seedingKey = '';\n          if (!resp.success) { this.apiErrorService.presentAppFailure(resp, 'action', 'setup/seed'); return; } // never the server's own words on a failure\n          const created = resp.data || 0;\n          // Deliberately NOT a triumphant message when nothing was written. An affordance that reports success and\n          // creates nothing is this codebase's signature bug; the server reports that case as a failure, and this\n          // line covers the honest \"it was all already here\" one.\n          this.messageService.toast(created > 0 ? `${created} example record${created === 1 ? '' : 's'} added — look for “Example: ”` : 'Those example records are already here');\n          this.loadSeedOffers(); // re-reads applied / wouldCreate / existing so the row comes back in its new state\n          this.setupService.refresh(); // seeded rows move the step's own count\n        },\n        error: () => this.seedingKey = ''\n      });\n    });\n  }\n\n  //---------- Preset pickers (notifications, sign-off) ----------\n  // ONE code path, driven by the PresetPicker objects above. Tick a row, pick who it goes to, apply. Both backends\n  // are create-only and skip anything already configured, so neither can overwrite a rule the user has since\n  // edited, nor resurrect one they deleted.\n\n  // Which picker (if any) renders inside this step. Called from the template, so it must stay cheap and must\n  // return the SAME object each pass — find() over a two-element array returning an existing reference does.\n  pickerFor(step: SetupStep): PresetPicker | undefined {\n    return step ? this.pickers.find(p => p.stepKey === step.key) : undefined;\n  }\n\n  private hasPresetsStep(picker: PresetPicker): boolean {\n    return (this.status?.steps || []).some(s => s.key === picker.stepKey);\n  }\n\n  private loadPresets(picker: PresetPicker) {\n    picker.load().subscribe({\n      next: (resp: any) => {\n        // Same reasoning as loadRoleTemplates: a bare return renders an empty picker, which reads as \"this app\n        // offers no presets\" — a completely different statement from \"we could not fetch them\".\n        if (!resp.success) { this.apiErrorService.presentAppFailure(resp, 'load', picker.loadUrl); return; }\n        picker.loaded = true;\n        picker.presets = resp.data?.presets || [];\n        picker.roles = resp.data?.roles || [];\n        picker.presets.forEach(p => {\n          if (picker.selected[p.key] === undefined) picker.selected[p.key] = !p.exists; // preselect what is not yet configured; the undefined guard preserves a manual untick across a reload\n          if (picker.roleValue[p.key] === undefined && p.roleID) picker.roleValue[p.key] = String(p.roleID); // the server-resolved default, kept unless the user changes it\n          // Changed (presets P4): fall back to the FIRST offered role when the server could resolve none. A <select>\n          // with no selected option still DISPLAYS its first one, so without this the row showed a role it had not\n          // stored — the tick then submitted nothing while the screen said otherwise. Reachable whenever the\n          // onboarding user holds no role of their own, which is exactly when nothing else can be resolved. Every\n          // offered role is a legitimate choice (for sign-off the backend has already filtered to actionable ones),\n          // so the worst case is a default the user changes — never a control that lies about what it will do.\n          if (picker.roleValue[p.key] === undefined && picker.roles.length > 0) picker.roleValue[p.key] = String(picker.roles[0].value);\n          this.setRoleNames(picker, p.key); // Added (GS Phase 5): the sentence's role names, materialized with the seed rather than in a binding\n        });\n        this.buildPresetGroups(picker);\n      },\n      error: () => { }\n    });\n  }\n\n  // Materialize the rows once per load: group in catalogue order and split each Effect sentence around the\n  // {role} token. The sentence itself is authored in PresetCatalog server-side — this only cuts it in two so the\n  // select can sit in the gap. Nothing here composes wording. That is why the approval sentences can carry their\n  // own caveat about a deferred notification without this component knowing such a caveat exists.\n  private buildPresetGroups(picker: PresetPicker) {\n    const names: string[] = [];\n    picker.presets.forEach(p => { const name = p.group || picker.defaultGroup; if (!names.includes(name)) names.push(name); });\n    picker.groups = names.map((name, index) => {\n      const rows = picker.presets.filter(p => (p.group || picker.defaultGroup) === name).map(p => this.toPresetRow(picker, p));\n      // Changed (GS P4): the open/shut cascade, and the reason this is not a one-liner. buildPresetGroups runs from\n      // loadPresets, which the status$ subscription calls on EVERY refresh() — a module toggle, a dialog close, an\n      // import, an apply — and it replaces these objects wholesale. A `collapsed` seeded from the default alone\n      // would slam shut every section the user opened, intermittently and invisibly. Identical cascade to\n      // buildModuleGroups: what is on screen NOW wins, then what this user saved, and only then the first-open seed.\n      const previous = picker.groups.find(g => g.name === name);\n      return {\n        name, rows, on: 0, total: rows.length,\n        collapsed: previous?.collapsed ?? this.presetSectionState[this.presetSectionKey(picker, name)] ?? index > 0,\n        summary: ''  // filled by recountPresets below, which is also what keeps it live afterwards\n      };\n    });\n    this.recountPresets(picker);\n  }\n\n  // Added (GS P4): the storage key. Section name alone is NOT unique — since the sections are named after module\n  // groups, \"Finance\" is a section in the notification picker, in the sign-off picker and in the module card.\n  private presetSectionKey(picker: PresetPicker, name: string): string {\n    return `${picker.stepKey}::${name}`;\n  }\n\n  // Added (GS P4): what a shut preset section still says about itself, matching the treatment P3 settled on for the\n  // module sections — the count beside it answers \"how many\", this answers \"of what\", because a column of identical\n  // closed bands is a worse page than the list it replaces. Capped at TWO names, not P3's three, for one measured\n  // reason: a module title is two words (\"Fixed Assets\") while a preset name is a whole sentence (\"When a sale is\n  // recorded\"), so three of them wrap to three lines on a phone. The tail is counted, never dropped, and \"on\" means\n  // exactly what the counter beside it means — already configured, plus what is ticked to be turned on.\n  private presetSummary(picker: PresetPicker, rows: PresetRow[]): string {\n    const on = rows.filter(r => r.preset.exists || picker.selected[r.preset.key]);\n    if (on.length === 0) return `Nothing on yet — ${rows.length} to choose from`;\n    const names = on.slice(0, 2).map(r => r.preset.name);\n    return on.length > names.length ? `${names.join(' · ')} + ${on.length - names.length} more` : names.join(' · ');\n  }\n\n  // Added (GS P4): open/shut one preset section and remember it. Deliberately not an accordion, same as the module\n  // sections — the rule is \"the first is open and the rest are shut\", not \"only one may ever be open\".\n  togglePresetSection(picker: PresetPicker, group: { name: string, collapsed: boolean }) {\n    group.collapsed = !group.collapsed;\n    this.presetSectionState[this.presetSectionKey(picker, group.name)] = group.collapsed;\n    localStorage.setItem('tin-setup-preset-sections', JSON.stringify(this.presetSectionState));\n  }\n\n  private toPresetRow(picker: PresetPicker, preset: SetupPreset): PresetRow {\n    const parts = (preset.effect || '').split(PRESET_ROLE_TOKEN);\n    // No token (an app author wrote a sentence without one) → the whole sentence leads and the field follows it.\n    // Still a server sentence, still not composed here.\n    return { preset, before: parts[0], after: parts.length > 1 ? parts.slice(1).join(PRESET_ROLE_TOKEN) : '', roleAria: picker.roleAria + preset.name };\n  }\n\n  // Added (GS Phase 5): the role choice, spelled out for the effect sentence. Called from the ONE place the choice\n  // can change and from the load seed, never from a binding — `picker.roleNames[key]` is then a plain property read\n  // in the template, which is the rule this page learned the hard way (a getter that allocates per change-detection\n  // pass caused a real livelock, see the PresetRow/DemoArea comments above).\n  // Joined with \"and\" rather than commas alone because this string lands INSIDE a server-authored sentence — the\n  // whole point of the effect line is that reading it is reading the configuration, and \"Notify Manager, Accountant\n  // when a sale is recorded\" does not read as English. Unknown ids (a role deleted since the catalogue was fetched)\n  // are dropped, so the sentence can never name something that is not on the list underneath it.\n  private setRoleNames(picker: PresetPicker, key: string) {\n    const ids = Core.parseMultiValue(picker.roleValue[key]);\n    const names = ids.map(id => picker.roles.find(r => String(r.value) === id)?.name).filter(n => !!n) as string[];\n    if (names.length === 0) { picker.roleNames[key] = picker.roleNone; return; }\n    picker.roleNames[key] = names.length === 1 ? names[0] : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`;\n  }\n\n  // Counters + button label. \"on\" counts what will be on after applying: already configured plus newly ticked.\n  private recountPresets(picker: PresetPicker) {\n    // Changed (GS P4): the summary is recomputed here beside the counter, off the same tick. A shut section that\n    // kept describing the presets that WERE on would be exactly the stale-blank the collapse ruling forbids.\n    picker.groups.forEach(g => { g.on = g.rows.filter(r => r.preset.exists || picker.selected[r.preset.key]).length; g.summary = this.presetSummary(picker, g.rows); });\n    // Changed (presets P4): the count now requires a chosen role, matching EXACTLY what applyPresets submits. It\n    // previously counted ticks alone, so with no selectable role the button read \"Turn on 3 notifications\", was\n    // enabled, and applied nothing — the failure mode this feature must not have. Where roles exist the server\n    // always stamps a default, so nothing changes for the ordinary case.\n    // Changed (GS Phase 5): \"has a role\" becomes \"has AT LEAST ONE role\". roleValue is the ';'-joined id string, so\n    // a non-empty string IS one-or-more roles and the test stays a plain truthiness check — no parse, no allocation,\n    // and still EXACTLY the filter applyPresets submits, which is the property that matters here.\n    picker.count = picker.presets.filter(p => !p.exists && picker.selected[p.key] && !!picker.roleValue[p.key]).length;\n    picker.action.display = picker.buttonLabel(picker.count);\n  }\n\n  // Whole-row toggle, mirroring toggleTemplate — a configured row is inert, never untickable\n  togglePreset(picker: PresetPicker, preset: SetupPreset) {\n    if (preset.exists) return;\n    picker.selected[preset.key] = !picker.selected[preset.key];\n    this.recountPresets(picker);\n  }\n\n  // Changed (GS Phase 5): takes spa-select-multi's emission verbatim — the ';'-joined id string — and stores it as\n  // it stands. The control's click/keydown are stopped in the template, as the native select's were, so choosing a\n  // role never reaches the row's own toggle.\n  setPresetRoles(picker: PresetPicker, preset: SetupPreset, value: string) {\n    picker.roleValue[preset.key] = value || '';\n    this.setRoleNames(picker, preset.key); // the sentence follows the choice, in the same breath\n    this.recountPresets(picker); // a row emptied of roles drops OUT of the count, and one given a role joins it\n  }\n\n  toggleIncludeEmail() {\n    this.includeEmail = !this.includeEmail;\n  }\n\n  applyPresets(picker: PresetPicker) {\n    // A preset with no role would create a rule addressed to nobody — or, for sign-off, a config nobody could\n    // release — so it is never submitted\n    // Changed (GS Phase 5): sends BOTH forms. roleIDs carries the whole choice; roleID keeps carrying the first of\n    // them, so this payload is still understood in full by a server that predates the plural field — the backwards\n    // compatibility runs in both directions, not just the server's.\n    const items: SetupPresetSelection[] = picker.presets.filter(p => !p.exists && picker.selected[p.key] && !!picker.roleValue[p.key]).map(p => {\n      const ids = Core.parseMultiValue(picker.roleValue[p.key]).map(id => Number(id));\n      return { key: p.key, roleID: ids[0], roleIDs: ids };\n    });\n    if (items.length === 0 || picker.applying) return;\n    picker.applying = true;\n    picker.apply(items).subscribe({\n      next: (resp: any) => {\n        picker.applying = false;\n        if (!resp.success) { this.apiErrorService.presentAppFailure(resp, 'action', picker.applyUrl); return; } // never the server's own words on a failure\n        this.messageService.toast(picker.toastLabel(resp.data || 0)); // call-site wording, like the Demo Data card\n        this.loadPresets(picker); // re-reads Exists so the applied rows come back as Configured\n        this.setupService.refresh(); // the step's count moves with the new configs\n      },\n      error: () => picker.applying = false\n    });\n  }\n\n  //---------- Demo data ----------\n  // Added: seed/remove example records. This used to sit on each app's hand-written App Configuration page,\n  // which is where a user looking for it would never think to look — filling the system with example data is\n  // an onboarding act, not a setting. All five apps expose the same two endpoints, so the library owns it and\n  // an app opts in with setupConfig.demoData.\n  demoBusy = false;\n\n  get showDemoData(): boolean {\n    return !!this.dataService.appConfig?.setupConfig?.demoData;\n  }\n\n  seedDemoData() {\n    this.runDemoAction('demo-data/seed', 'This creates example records across the system so you can explore it. Continue?', 'Demo data seeded successfully');\n  }\n\n  removeDemoData() {\n    this.runDemoAction('demo-data/remove', 'This permanently deletes every example record created by demo data. Continue?', 'Demo data removed successfully');\n  }\n\n  // Added (seed-all): \"scroll right to the bottom where they seed demo data and it just populates everything for\n  // them ON AREAS THAT DON'T HAVE DATA\". That last clause is the whole feature and it did not exist — seedDemoData()\n  // above asks demo-data/seed, which asks ONE global sentinel (a customer named \"Example: …\") and, once it is\n  // there, seeds nothing further no matter how many other areas are still empty. This asks each area instead.\n  //\n  // 🔴 seedDemoData() is deliberately KEPT, not replaced. The offer catalogue covers the areas it declares; the\n  // app-specific demo datasets (pigs, equipment, trips) still only come from demo-data/seed. Retiring that button\n  // before an offer exists for every one of those areas would take away the only way to seed them — the same\n  // mistake as removing a seed button before its replacement works.\n  //\n  // Every sentence in the confirm is the SERVER'S: each area's own effect line and the standing example-data\n  // notice, both authored in the catalogue so all five apps read the same words and one edit corrects them all.\n  seedAll() {\n    if (this.seedingAll || this.demoBusy) return;\n\n    const pending = this.demoAreas.filter(area => !area.offer.applied);\n    if (pending.length === 0) return;\n\n    const effects = pending.map(area => `• ${area.offer.effect}`).join('\\n');\n    this.messageService.confirm(`${effects}\\n\\n${pending[0].offer.sampleNotice}`, 'Fill the empty areas').subscribe(answer => {\n      if (answer !== 'yes') return; // messageDialog answers with the literal 'yes'\n      this.seedingAll = true;\n      this.setupService.applySeedAll().subscribe({\n        next: resp => {\n          this.seedingAll = false;\n          // The server reports \"some areas advertised rows and wrote none\" as a FAILURE on purpose, so this must\n          // not toast a success over it. Never the server's own words on a failure — the shared classifier decides.\n          if (!resp.success) { this.apiErrorService.presentAppFailure(resp, 'action', 'setup/seed-all'); this.loadSeedOffers(); return; }\n          const created = resp.data || 0;\n          this.messageService.toast(created > 0 ? `${created} example record${created === 1 ? '' : 's'} added — look for “Example: ”` : 'Every area already has data');\n          this.loadSeedOffers(); // re-reads applied / wouldCreate / existing so every area line comes back in its new state\n          this.setupService.refresh(); // seeded rows move the step counts\n        },\n        error: () => this.seedingAll = false\n      });\n    });\n  }\n\n  private runDemoAction(url: string, question: string, success: string) {\n    if (this.demoBusy) return;\n    this.messageService.confirm(question).subscribe(answer => {\n      if (answer !== 'yes') return; // messageDialog answers with the literal 'yes'\n      this.demoBusy = true;\n      this.dataService.CallApi({ url, method: 'post' }, {}).subscribe({\n        next: (response: ApiResponse) => {\n          this.demoBusy = false;\n          // Changed: the SUCCESS path deliberately stays a toast — `success` is a real human sentence written\n          // at the call site (\"Demo data seeded successfully\") and a non-blocking toast is the right weight\n          // for it. Only the FAILURE branch moves: it was toasting `response.message`, i.e. the server's own\n          // words, so seeding against a schema-behind database put \"Invalid column name\" on screen.\n          if (response.success) { this.messageService.toast(success); this.setupService.refresh(); } // seeded/removed records move the step counts\n          else this.apiErrorService.presentAppFailure(response, 'action', url);\n        },\n        error: () => this.demoBusy = false\n      });\n    });\n  }\n\n  createSelectedRoles() {\n    const keys = this.roleTemplates.filter(t => !t.exists && this.selectedTemplates[t.key]).map(t => t.key);\n    if (keys.length === 0 || this.creatingRoles) return;\n    this.creatingRoles = true;\n    this.setupService.createRoles(keys).subscribe({\n      next: resp => {\n        this.creatingRoles = false;\n        if (resp.success) {\n          this.loadRoleTemplates(); // refresh the Created chips\n          this.setupService.refresh();\n        } else {\n          this.apiErrorService.presentAppFailure(resp, 'action', 'setup/roles'); // Added: was silent. The Created chips simply never appeared, so the user's read is \"the roles were created but the page did not refresh\" — and the next thing they do is assign people to roles that do not exist\n        }\n      },\n      error: () => this.creatingRoles = false\n    });\n  }\n}\n","<div class=\"setup-page\" *ngIf=\"status\">\n\n  <!-- Hero: overall readiness + celebration state at 100% -->\n  <mat-card class=\"setup-hero\" [class.celebrate]=\"status.percent === 100\">\n    <div class=\"hero-content\" *ngIf=\"status.percent < 100\">\n      <div class=\"hero-text\">\n        <h1>{{ title }}</h1>\n        <p>Complete these steps to get your system ready for day-to-day operation.</p>\n        <span class=\"hero-counter\">{{ status.completed }} of {{ status.total }} steps completed</span>\n      </div>\n      <div class=\"hero-progress\">\n        <span class=\"hero-percent\">{{ status.percent }}%</span>\n        <mat-progress-bar mode=\"determinate\" [value]=\"status.percent\"></mat-progress-bar>\n      </div>\n    </div>\n    <!-- Changed (gs-percent-required-only): the gauge now measures REQUIRED steps only, so 100% no longer means\n         \"nothing left on the page\" — optional steps can still be outstanding underneath. Saying \"All setup steps\n         are complete\" in that state would be plainly untrue against the list the user is looking at, so the\n         celebration splits in two. Same card, same icon, same tone: only the sentence changes, and the second\n         variant points DOWN the page instead of closing the subject off. -->\n    <div class=\"hero-content celebration\" *ngIf=\"status.percent === 100\">\n      <mat-icon class=\"celebrate-icon\">celebration</mat-icon>\n      <div class=\"hero-text\" *ngIf=\"status.completed >= status.total\">\n        <h1>You're all set!</h1>\n        <p>All setup steps are complete — your system is ready to operate.</p>\n      </div>\n      <div class=\"hero-text\" *ngIf=\"status.completed < status.total\">\n        <h1>You're set up</h1>\n        <p>Everything required is done — your system is ready to operate. The optional extras below are there whenever you want them.</p>\n        <span class=\"hero-counter\">{{ status.completed }} of {{ status.total }} steps completed</span>\n      </div>\n    </div>\n  </mat-card>\n\n  <!-- Module picker (v2): choose what the business uses; optional modules toggle steps + menus -->\n  <!-- Changed (fusion, 2026-08-18): gains a stable id so the \"Choose your modules\" step further down the page can\n       scroll here and put focus on the picker. The step is the RECEIPT of this decision; this card is where the\n       decision is made, and until now nothing on screen said so. -->\n  <!-- Changed (v2-1): the picker is a FOLDING card with the same Day Book subcard head as every other section\n       on the page, and it is the gate — see `gateOpen` in the component. Removed with it: the \"Not confirmed\n       yet\" pill the owner asked to drop (\"he does not want it\"). It is not replaced by anything, and it does\n       not need to be: before confirmation this card is the ONLY thing on the page, which states the same fact\n       far more strongly than a pill ever did. -->\n  <mat-card class=\"setup-modules setup-group\" id=\"setup-modules-card\" *ngIf=\"modules.length > 0\" [class.closed]=\"modulesCollapsed\">\n    <h2 class=\"group-heading\">\n      <button type=\"button\" class=\"group-header tin-disc-row\" (click)=\"toggleModulesCard()\"\n              [attr.aria-expanded]=\"!modulesCollapsed\" aria-controls=\"setup-modules-body\"\n              [class.group-header-static]=\"!gateOpen\">\n        <!-- While the gate is shut the card cannot fold — a shut picker on a gated page is a blank page — so it\n             shows no disclosure marker, exactly as a non-collapsible spa-table section shows none\n             (table.component.html:11). An affordance that does nothing is worse than no affordance. -->\n        <span class=\"tin-disc\" *ngIf=\"gateOpen\" [class.open]=\"!modulesCollapsed\"><mat-icon>chevron_right</mat-icon></span>\n        <mat-icon class=\"group-icon\">tune</mat-icon>\n        <span class=\"group-text\">\n          <span class=\"group-name\">Your modules</span>\n          <!-- KEPT verbatim, on his instruction. It is the one sentence that says the cards are tappable. -->\n          <span class=\"group-caption\">Tap a module to turn it on or off — you can change this anytime.</span>\n        </span>\n        <span class=\"group-badges\">\n          <span class=\"gb gb-done\">{{ enabledModuleCount }} on</span>\n        </span>\n      </button>\n    </h2>\n    <div class=\"group-chips modules-chips\" *ngIf=\"modulesCollapsed\"><span class=\"group-chip-summary\">{{ modulesSummary }}</span></div>\n    <div class=\"group-body\" id=\"setup-modules-body\">\n    <!-- Changed (v3): grouped — the picker now carries the whole library catalog, so cards sit under their\n         group heading (the app's own modules first). A backend without groups yields one unnamed group,\n         which renders as the original flat grid. -->\n    <!-- Changed (P3): the section head is a real <button>, so the whole band is the target and Enter/Space work\n         without a keydown handler. `aria-expanded` and `aria-controls` are on the control, which is where a screen\n         reader looks for them. The grid is hidden with display:none, NOT *ngIf — the ruling of 2026-08-12, and the\n         same choice tenant-settings.component.css :69 makes: the cards stay mounted, so the count and the summary\n         a shut section shows are LIVE, never a blank that fills in once you open it. It also means a section you\n         shut keeps whatever state is inside it. -->\n    <div class=\"module-section\" *ngFor=\"let mgroup of moduleGroups; let mi = index\" [class.closed]=\"mgroup.collapsed\">\n      <!-- Changed (2026-08-17, owner): a shut band \"looks flat… like plain text going downwards… nothing\n           attracts someone to see that there are more details when they expand\". The disclosure marker moves to\n           the LEFT of the name — where reading starts — and the trailing chevron goes, so there is one\n           affordance rather than one nobody saw. -->\n      <button type=\"button\" class=\"module-section-head tin-disc-row\" (click)=\"toggleModuleSection(mgroup)\"\n              [attr.aria-expanded]=\"!mgroup.collapsed\" [attr.aria-controls]=\"'module-grid-' + mi\">\n        <span class=\"tin-disc\" [class.open]=\"!mgroup.collapsed\"><mat-icon>chevron_right</mat-icon></span>\n        <span class=\"module-section-name\">{{ mgroup.name }}</span>\n        <span class=\"module-section-count\">{{ mgroup.enabled }} of {{ mgroup.total }} on</span>\n      </button>\n      <!-- What a shut section still says about itself: which modules are on, or that none are. Shown only while\n           shut — open, the cards themselves say it, and repeating them there would be noise. -->\n      <div class=\"module-section-summary\" *ngIf=\"mgroup.collapsed\">{{ mgroup.summary }}</div>\n      <div class=\"module-grid\" [id]=\"'module-grid-' + mi\">\n        <div class=\"module-card\" *ngFor=\"let mod of mgroup.modules\"\n             [class.enabled]=\"mod.enabled\" [class.core]=\"mod.core\" [class.busy]=\"togglingKey === mod.key\"\n             (click)=\"toggleModule(mod)\">\n          <div class=\"module-head\">\n            <mat-icon class=\"module-icon\">{{ mod.icon || 'extension' }}</mat-icon>\n            <mat-icon class=\"module-state\" [class.on]=\"mod.enabled\">{{ mod.enabled ? 'check_circle' : 'radio_button_unchecked' }}</mat-icon>\n          </div>\n          <div class=\"module-title\">{{ mod.title }}</div>\n          <div class=\"module-description\">{{ mod.description }}</div>\n          <span class=\"module-chip\" *ngIf=\"mod.core\">Always on</span>\n        </div>\n      </div>\n    </div>\n    <div class=\"module-actions\" *ngIf=\"!modulesConfirmed\">\n      <!-- Changed (v3, owner): the label carries FORWARD MOTION, and the trailing arrow is the visual half of\n           it. The old \"Confirm selection\" described the click and stopped there; on a page where this button is\n           the ONLY thing on screen, nothing said that pressing it reveals the rest. \"Continue\" plus an arrow\n           pointing out of the card is the smallest thing that says \"this is step one of more\". -->\n      <button mat-flat-button color=\"primary\" class=\"module-confirm\" [disabled]=\"togglingKey !== ''\" (click)=\"confirmModules()\">\n        <!-- ⚠️ `iconPositionEnd` is REQUIRED and is not cosmetic. MatButton's template carries TWO\n             <ng-content select=\"mat-icon\"> slots and content projection fills the FIRST match regardless of\n             source order — so an icon written after the label still renders BEFORE it. Measured here: the\n             arrow came out on the left of \"Confirm & continue\" until this attribute was added. -->\n        <span>Confirm &amp; continue</span><mat-icon iconPositionEnd class=\"module-confirm-arrow\">arrow_forward</mat-icon>\n      </button>\n      <!-- Changed (v2-1, owner): the hint no longer names \"Choose your modules\" and no longer mentions Company\n           Setup at ALL. Both were removed on instruction, and the reason is the gate: at the moment this\n           sentence is read, Company Setup does not exist on the page yet, so pointing at it named something\n           the reader cannot see. The sentence now describes only this card and what pressing the button does. -->\n      <!-- Changed (v3, owner): \"…the modules you want to proceed\", and then the INTENT — \"we need you to do\n           this part first before the next item\". The second clause is the whole point of the edit: it is the\n           only sentence that tells a first-time user this gate is a step and not the entire page. What made\n           room for it was dropping \"you can change this at any time\" — not a loss, because the card's own\n           caption six lines up already says \"you can change this anytime\", and saying it twice in one card\n           was spending the reader's attention on reassurance instead of direction. -->\n      <span class=\"module-hint\">Confirm the modules you want to proceed — <strong>this comes first</strong>, then your setup steps appear below.</span>\n    </div>\n    </div>\n  </mat-card>\n\n  <!-- Category groups, top-down — Changed: flat spa-checklist replaces the raised mat-accordion -->\n  <!-- Changed (GS P4): trackBy is load-bearing, not a micro-optimisation. buildGroups() rebuilds these group\n       objects on EVERY refresh(), so without an identity Angular destroyed and recreated every spa-checklist\n       underneath — and a recreated component starts with a blank seededKey, re-adopts config.expandedKey and\n       throws away the step the user had opened. Tracking by the category name keeps ONE component instance per\n       group alive across a refresh, which is what makes the seededKey guard in checklist.component.ts work. -->\n  <!-- Changed (fusion, 2026-08-18): a category group FOLDS. It was the only tier on this page that could not —\n       an <h2>, a counter and a permanently open checklist — while the module bands and the preset bands inside it\n       have folded since P3/P4. The Day Book's lane group is the reference: SHUT, the head and its chip strip form\n       ONE card carrying a ring, coloured badges and a summary; OPEN, the card dissolves and the checklist rows\n       become the content layer. The checkboxes and the crossing-off inside spa-checklist are untouched — they are\n       the thing this page is FOR, and the ring is a summary of them, never a replacement.\n       The heading WRAPS the control (the W3C accordion pattern): the whole band stays one target and Enter/Space\n       work without a keydown handler, while the category keeps its <h2> for anyone navigating by heading. -->\n  <!-- Changed (v2-1, owner): the head is now the DAY BOOK SUBCARD — a bordered, shaded strip carrying the\n       disclosure marker, a section icon, the title and its description, with the status badges pinned to the\n       FAR RIGHT. Every measurement is copied from the Day Book's own section header (spa-table's\n       .tbl-section-header, table.component.css:205-212) rather than approximated; see the CSS.\n       THREE THINGS WERE REMOVED FROM THIS ROW, all on instruction:\n         • the progress ring — \"it's not coming out exactly the way I want it\". spa-progress-ring itself is\n           KEPT and still exported: it is public API and deleting it would break any consumer that uses it.\n           This page simply stops calling it. It has no other caller in the library.\n         • the info icon, whose tooltip text is now shown permanently as the caption below the title — so the\n           sentence was not lost, it was promoted. It also still rides on the aria-label, as it did before.\n         • the \"4 of 8\" numeric, which the badges beside it already say in words, and said twice. -->\n  <!-- 🔴 THE GATE (v2-1, owner). Everything from here down does not render at all until the modules are\n       confirmed. *ngIf and NOT display:none — deliberately the opposite of the ruling that governs the\n       collapses on this page, and for a reason that does not apply to them: a collapsed section is\n       information the user may want back in one click, so it stays mounted and live. A gated page is work\n       the user must not start yet, and the picker above is about to REBUILD it — mounting a checklist that\n       is going to be replaced wholesale would fire every step's action wiring and every preset load for\n       modules that may be about to be switched off. `gateOpen` is true for any tenant who has ever touched\n       the picker, and for any app with no module catalog at all, so this is a first-run gate only. -->\n  <ng-container *ngIf=\"gateOpen\">\n  <mat-card class=\"setup-group\" *ngFor=\"let group of groups; let gi = index; trackBy: trackByGroup\" [class.closed]=\"group.collapsed\" [class.all-done]=\"group.completed >= group.total\">\n    <h2 class=\"group-heading\">\n      <button type=\"button\" class=\"group-header tin-disc-row\" (click)=\"toggleCategory(group)\"\n              [attr.aria-expanded]=\"!group.collapsed\" [attr.aria-controls]=\"'group-body-' + gi\"\n              [attr.aria-label]=\"group.name + ' — ' + group.completed + ' of ' + group.total + ' complete. ' + group.about\">\n        <span class=\"tin-disc\" [class.open]=\"!group.collapsed\"><mat-icon>chevron_right</mat-icon></span>\n        <mat-icon class=\"group-icon\">{{ group.icon }}</mat-icon>\n        <span class=\"group-text\">\n          <span class=\"group-name\">{{ group.name }}</span>\n          <span class=\"group-caption\">{{ group.about }}</span>\n        </span>\n        <!-- The coloured badges, now pinned to the far right — the Day Book's \"free to dispatch\" position.\n             Shown in BOTH states, not only shut: they are the section's status line, and a section you have\n             opened has not stopped having one. Same green and amber as the ticks they count. -->\n        <span class=\"group-badges\">\n          <span class=\"gb gb-done\" *ngIf=\"group.done > 0\">{{ group.done }} done</span>\n          <span class=\"gb gb-todo\" *ngIf=\"group.todo > 0\">{{ group.todo }} to do</span>\n          <span class=\"gb gb-optional\" *ngIf=\"group.optional > 0\">{{ group.optional }} optional</span>\n        </span>\n      </button>\n    </h2>\n    <!-- What a shut group still says about itself: what is LEFT, not what is done — as CHIPS, and nothing else.\n         A separate summary line was written here first and removed after seeing it rendered: it named the same\n         outstanding steps the chips below already name, so every shut group said \"Add a supplier\" twice, once as\n         dead text and once as a control. That is the same defect the module sections closed when they rejected a\n         section per module (\"a '1 of 1' counter and a summary repeating the header directly above it\"). The chips\n         ARE the summary here, and unlike a sentence they are a way in. -->\n    <div class=\"group-chips\" *ngIf=\"group.collapsed\">\n      <button type=\"button\" class=\"group-chip\" *ngFor=\"let c of group.chips\" [class.optional]=\"c.optional\" (click)=\"goToStep(group, c.key)\">{{ c.label }}</button>\n      <span class=\"group-chip-none\" *ngIf=\"!group.chips.length\"><mat-icon>task_alt</mat-icon>Nothing left here</span>\n    </div>\n    <!-- 🔴 Hidden with display:none via .closed, NOT *ngIf — the ruling of 2026-08-12, the same one the module and\n         preset sections follow. The steps stay MOUNTED, so the counter, the badges and the summary on a shut group\n         are LIVE rather than a blank that fills in once you open it, and a group you shut keeps the step the user\n         had expanded and every tick inside it. -->\n    <div class=\"group-body\" [id]=\"'group-body-' + gi\">\n      <spa-checklist [config]=\"group.config\" [itemTemplate]=\"stepExtrasTpl\"></spa-checklist>\n    </div>\n  </mat-card>\n\n  <!-- Demo data (opt-in via setupConfig.demoData) — moved here off the per-app configuration pages -->\n  <!-- Inside the gate: seeding example records is the last thing a first-run user should be offered, and the\n       offers themselves are per-MODULE, so half of them may be about to disappear. -->\n  <mat-card class=\"setup-group setup-demo\" *ngIf=\"showDemoData\">\n    <!-- Changed (v2-1): the last header on the page that was still the OLD shape — an <h2> on the left and a\n         loose caption on the right. It is now the same subcard as every other section, so the page has ONE\n         header language rather than five-and-a-half. It is deliberately NOT a button: this card does not fold,\n         it has no steps to count, and a marker that opens nothing is worse than no marker (the same reasoning\n         .tbl-section-static carries in the Day Book's own table). -->\n    <div class=\"group-header group-header-static\">\n      <mat-icon class=\"group-icon\">science</mat-icon>\n      <span class=\"group-text\">\n        <h2 class=\"group-name\">Demo data</h2>\n        <span class=\"group-caption\">Explore with example records, then clear them out</span>\n      </span>\n    </div>\n    <p class=\"demo-description\">Seeding fills the system with example records so you can try it out before capturing anything real. Removing deletes only those example records.</p>\n\n    <!-- Added (seed-all): the per-area report. The card used to make ONE claim about the whole system, because the\n         backend sentinel is a single customer named \"Example: …\" — so one demo customer answered for products,\n         suppliers and everything else, and none of it ever looked at REAL data. Each line here is one area\n         answering for itself: what is in it now, and what a fill would add. Deliberately a compact one-line list\n         and not the full seed-offer row used on the steps — a step is where you decide about ONE area, this is a\n         report on all of them, and repeating the effect and notice paragraphs a dozen times would bury the button.\n         The full wording is still shown, in the confirm, before anything is written. -->\n    <div class=\"demo-areas\" *ngIf=\"demoAreas.length > 0\">\n      <div class=\"demo-area\" *ngFor=\"let area of demoAreas\" [class.added]=\"area.offer.applied\">\n        <mat-icon class=\"demo-area-state\" [class.on]=\"area.offer.applied\">{{ area.offer.applied ? 'check_circle' : (area.offer.icon || 'science') }}</mat-icon>\n        <span class=\"demo-area-name\">{{ area.label }}</span>\n        <span class=\"demo-area-count\">{{ area.state }}</span>\n      </div>\n    </div>\n\n    <div class=\"demo-actions\">\n      <!-- The owner's sentence, made literal: fill the areas that don't have data. It says HOW MANY areas, because\n           a button that says only \"seed\" is asking for blind consent, and it disappears entirely when there is\n           nothing left to fill rather than sitting there doing nothing when clicked. -->\n      <button mat-flat-button color=\"primary\" *ngIf=\"demoPending > 0\" [disabled]=\"seedingAll || demoBusy\" (click)=\"seedAll()\"><mat-icon>auto_fix_high</mat-icon> Fill {{ demoPending === 1 ? '1 empty area' : demoPending + ' empty areas' }}</button>\n      <span class=\"demo-full\" *ngIf=\"demoAreas.length > 0 && demoPending === 0\">Every area already has data.</span>\n      <!-- KEPT, not replaced. The offer catalogue covers the areas it declares; each app's own demo dataset still\n           comes only from here, so retiring this would take away the only way to seed those. -->\n      <button mat-stroked-button color=\"primary\" [disabled]=\"demoBusy || seedingAll\" (click)=\"seedDemoData()\"><mat-icon>add_circle</mat-icon> Seed demo data</button>\n      <button mat-stroked-button color=\"warn\" [disabled]=\"demoBusy || seedingAll\" (click)=\"removeDemoData()\"><mat-icon>delete</mat-icon> Remove demo data</button>\n    </div>\n  </mat-card>\n  </ng-container>\n\n</div>\n\n<!-- Projected into the expanded checklist body: predefined roles picker on the roles step (v2) -->\n<ng-template #stepExtrasTpl let-item>\n  <div class=\"role-templates\" *ngIf=\"hasRoleTemplates(item.data) && roleTemplates.length > 0\">\n    <div class=\"role-template\" *ngFor=\"let tpl of roleTemplates\" [class.created]=\"tpl.exists\" [class.selected]=\"!tpl.exists && selectedTemplates[tpl.key]\" (click)=\"toggleTemplate(tpl)\">\n      <div class=\"role-head\">\n        <mat-icon class=\"role-state\" [class.on]=\"tpl.exists || selectedTemplates[tpl.key]\">{{ (tpl.exists || selectedTemplates[tpl.key]) ? 'check_circle' : 'radio_button_unchecked' }}</mat-icon>\n        <span class=\"role-name\">{{ tpl.name }}</span>\n        <span class=\"role-created\" *ngIf=\"tpl.exists\"><mat-icon>check</mat-icon>Created</span>\n      </div>\n      <div class=\"role-description\">{{ tpl.description }}</div>\n    </div>\n  </div>\n\n  <!-- Added (seed seam): example-data offers for this step. Deliberately the SAME row the role picker and both\n       preset pickers use — 1px border, 8px radius, 10px/12px padding, the same green for \"already done\", the same\n       32px text indent — because this page is one the owner already likes and a fourth visual language inside it\n       would be the change, not the feature. Three things are new, and each one is a stated requirement:\n         • the effect line says exactly what lands, authored server-side;\n         • \"Also adds …\" names the prerequisites, because a vehicle cannot exist without its makes and models;\n         • the notice band says in as many words that this is EXAMPLE data you can edit later. It is the only\n           tinted band inside the row, so the eye finds it, and it is grey rather than amber, because this is a\n           clarification and not a warning — nobody has done anything wrong by reading it.\n       A row is a BUTTON, never a tick: unlike the presets there is no \"who\" to choose, so a checkbox idiom would\n       promise a selection step that does not exist. -->\n  <!-- Changed (P6): the block gains a stable id so the row's \"Example data\" action can scroll to it and put focus\n       on its button. Keyed by step so the ids stay unique across the 19 steps on this page. -->\n  <div class=\"seed-offers\" [id]=\"'seed-offers-' + item.data.key\" *ngIf=\"item.data && seedRowsByStep[item.data.key] as seedRows\">\n    <!-- 🔴 Changed (2026-08-19, owner): a seed offer is COLLAPSED BY DEFAULT, estate-wide. His reason, and it is\n         the whole design: seeding examples is OPTIONAL, and the step card around it only asks Create / View /\n         Import — so making everyone read two explanation lines, a prerequisites line and a notice band before\n         they can reach that question was the offer shouting over the step. Shut, this says its name and offers\n         to say more. Nothing about the OPEN state changed: the description, effect, \"Also adds\", the notice\n         band, the \"already in this list\" status and the Add button are byte-identical to the approved card.\n         The fold is the page's own: a real <button> head carrying .tin-disc / .tin-disc-row, exactly as\n         .group-header, .module-section-head and .cl-sub-head do — not a fourth disclosure idiom.\n         NOTHING IS PERSISTED — no expandedKey, no storage, no seeding from `applied`. A fresh load starts every\n         offer shut, which is what \"collapsed by default\" has to mean if it is to mean anything.\n         *ngIf and NOT display:none, deliberately parting from the 2026-08-12 ruling: that ruling protects folds\n         whose SHUT state shows live derived numbers (a \"3 of 5\" count, a summary). This head shows the offer's\n         own name and its Added chip, both of which live on the row above the fold, so nothing inside the body\n         is read while it is shut and keeping it mounted would buy nothing. -->\n    <div class=\"seed-offer\" *ngFor=\"let row of seedRows\" [class.added]=\"row.offer.applied\" [class.open]=\"isSeedOpen(row.offer)\">\n      <button type=\"button\" class=\"seed-head tin-disc-row\" (click)=\"toggleSeed(row.offer)\"\n              [attr.aria-expanded]=\"isSeedOpen(row.offer)\" [attr.aria-controls]=\"'seed-body-' + row.offer.key\">\n        <span class=\"tin-disc\" [class.open]=\"isSeedOpen(row.offer)\"><mat-icon>chevron_right</mat-icon></span>\n        <mat-icon class=\"seed-state\" [class.on]=\"row.offer.applied\">{{ row.offer.applied ? 'check_circle' : (row.offer.icon || 'science') }}</mat-icon>\n        <span class=\"seed-name\">{{ row.offer.name }}</span>\n        <span class=\"seed-added\" *ngIf=\"row.offer.applied\"><mat-icon>check</mat-icon>Added</span>\n      </button>\n      <div class=\"seed-body\" [id]=\"'seed-body-' + row.offer.key\" *ngIf=\"isSeedOpen(row.offer)\">\n        <div class=\"seed-description\">{{ row.offer.description }}</div>\n        <div class=\"seed-effect\">{{ row.offer.effect }}</div>\n        <div class=\"seed-also\" *ngIf=\"row.alsoAdds\">{{ row.alsoAdds }}</div>\n        <div class=\"seed-notice\"><mat-icon>science</mat-icon><span>{{ row.offer.sampleNotice }}</span></div>\n        <div class=\"seed-foot\">\n          <span class=\"seed-already\" *ngIf=\"row.hereAlready\">{{ row.hereAlready }}</span>\n          <button mat-stroked-button class=\"seed-action\" *ngIf=\"!row.offer.applied\" [disabled]=\"seedingKey !== ''\" (click)=\"applySeedOffer(row.offer)\"><mat-icon>add</mat-icon>{{ row.actionLabel }}</button>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Added (presets): the preset picker. Same row as the role picker above — same state icon, same 8px stack,\n       same colours — plus ONE sentence and ONE control.\n       Changed (presets P4): rendered through ONE shared template for both the notification step and the sign-off\n       step, parameterised by the picker object. The two sit one above the other on the same page, so a second\n       near-identical block would drift and every difference would read as a mistake. -->\n  <ng-container *ngIf=\"pickerFor(item.data) as picker\">\n    <ng-container *ngTemplateOutlet=\"presetPickerTpl; context: { $implicit: picker }\"></ng-container>\n  </ng-container>\n</ng-template>\n\n<!-- The one picker body. `picker` carries the domain: its rows, its roles, its wording, its apply call. -->\n<ng-template #presetPickerTpl let-picker>\n  <div class=\"preset-picker\" *ngIf=\"picker.loaded && picker.presets.length > 0\">\n\n    <!-- No selectable role → we ask for one instead of offering ticks that would build an inert rule. The wording\n         is the picker's own, because \"no roles\" and \"roles nobody is in\" are different situations. -->\n    <div class=\"preset-empty\" *ngIf=\"picker.roles.length === 0\">{{ picker.emptyText }}</div>\n\n    <ng-container *ngIf=\"picker.roles.length > 0\">\n      <!-- Changed (GS P4): the section band is now a real <button>, exactly as the module sections became in P3 —\n           whole band is the target, Enter/Space work without a keydown handler, and aria-expanded/aria-controls sit\n           on the control where a screen reader looks for them. The section NAMES now come from the module the\n           preset belongs to, so these read Foundation / Finance / Supply Chain — the same words, in the same\n           order, as the Your modules card above. The rows are hidden with display:none, NOT *ngIf (ruling of\n           2026-08-12): the rows stay mounted, so the head's \"n of m\" and the summary line are LIVE in the shut\n           state, and a section you shut keeps every tick and every role choice inside it. -->\n      <div class=\"preset-section\" *ngFor=\"let pgroup of picker.groups; let pi = index\" [class.closed]=\"pgroup.collapsed\">\n        <!-- Changed (2026-08-17): same leading disclosure marker as the module bands above — the owner's rule is\n             that it applies to every section that folds this way, not only the one in his screenshot. -->\n        <button type=\"button\" class=\"preset-section-head tin-disc-row\" (click)=\"togglePresetSection(picker, pgroup)\"\n                [attr.aria-expanded]=\"!pgroup.collapsed\" [attr.aria-controls]=\"'preset-rows-' + picker.stepKey + '-' + pi\">\n          <span class=\"tin-disc\" [class.open]=\"!pgroup.collapsed\"><mat-icon>chevron_right</mat-icon></span>\n          <span class=\"preset-section-name\">{{ pgroup.name }}</span>\n          <span class=\"preset-section-count\">{{ pgroup.on }} of {{ pgroup.total }}</span>\n        </button>\n        <!-- What a shut section still says: which of its rules are on, or that none are. Shown only while shut —\n             open, the rows themselves say it. -->\n        <div class=\"preset-section-summary\" *ngIf=\"pgroup.collapsed\">{{ pgroup.summary }}</div>\n        <div class=\"preset-rows\" [id]=\"'preset-rows-' + picker.stepKey + '-' + pi\">\n        <div class=\"preset-row\" *ngFor=\"let row of pgroup.rows\" role=\"checkbox\" tabindex=\"0\"\n             [class.configured]=\"row.preset.exists\" [class.selected]=\"!row.preset.exists && picker.selected[row.preset.key]\"\n             [attr.aria-checked]=\"row.preset.exists || !!picker.selected[row.preset.key]\" [attr.aria-disabled]=\"row.preset.exists\"\n             (click)=\"togglePreset(picker, row.preset)\"\n             (keydown.enter)=\"togglePreset(picker, row.preset)\"\n             (keydown.space)=\"togglePreset(picker, row.preset); $event.preventDefault()\">\n          <div class=\"preset-head\">\n            <mat-icon class=\"preset-state\" [class.on]=\"row.preset.exists || picker.selected[row.preset.key]\">{{ (row.preset.exists || picker.selected[row.preset.key]) ? 'check_circle' : 'radio_button_unchecked' }}</mat-icon>\n            <span class=\"preset-name\">{{ row.preset.name }}</span>\n            <span class=\"preset-configured\" *ngIf=\"row.preset.exists\"><mat-icon>check</mat-icon>Configured</span>\n          </div>\n          <div class=\"preset-description\">{{ row.preset.description }}</div>\n          <!-- The effect sentence comes from the server whole; `before` and `after` are its two halves either side\n               of the {role} placeholder, so reading the line IS reading the configuration. The sign-off sentences\n               carry their own deferred-notification caveat, which is why there is no extra note here. -->\n          <!-- Changed (GS Phase 5): the hand-rolled <select> that sat INSIDE this sentence is gone, replaced by the\n               house control. The sentence keeps its job — it still reads as one sentence, and the roles are still\n               written into it where {role} was, so reading the line is still reading the configuration — but it now\n               STATES the choice instead of hosting the editor, and the editor is the library field below it. A\n               mat-form-field cannot live mid-sentence at 12px: it carries a floating label and its own hint line,\n               and a multi-select's chips need the full width to be readable at 393px.\n               With nothing chosen the sentence says so (\"nobody yet\") rather than leaving a hole, because that is\n               precisely the state that keeps the row out of the button's count. -->\n          <div class=\"preset-effect\" *ngIf=\"!row.preset.exists\">{{ row.before }}<span class=\"preset-role-names\" [class.none]=\"!picker.roleValue[row.preset.key]\">{{ picker.roleNames[row.preset.key] }}</span>{{ row.after }}</div>\n          <!-- role=\"group\" + aria-label because spa-select-multi's accessible name is its mat-label, which is the\n               same four words on every row; the group names WHICH rule this field belongs to, as the old\n               <select>'s aria-label did. click/keydown are stopped exactly as they were on the native select — the\n               field sits inside a row whose whole body toggles the tick.\n               The required flag is bound to the tick, not hard-coded: a row nobody has ticked genuinely does not need a\n               role, while a TICKED row with no roles is silently dropped by apply — so this is the one state where\n               the field should mark itself, and Material already knows how to. -->\n          <div class=\"preset-role-field\" *ngIf=\"!row.preset.exists\" role=\"group\" [attr.aria-label]=\"row.roleAria\"\n               (click)=\"$event.stopPropagation()\"\n               (keydown)=\"$event.stopPropagation()\">\n            <spa-select-multi [display]=\"picker.roleLabel\" placeholder=\"Choose roles\" optionDisplay=\"name\" optionValue=\"value\" [options]=\"picker.roles\" [required]=\"!!picker.selected[row.preset.key]\" [value]=\"picker.roleValue[row.preset.key]\" (valueChange)=\"setPresetRoles(picker, row.preset, $event)\"></spa-select-multi>\n          </div>\n          <div class=\"preset-effect preset-done\" *ngIf=\"row.preset.exists\">{{ picker.doneText }}</div>\n        </div>\n        </div>\n      </div>\n\n      <!-- One page-level channel choice, notifications only. In-app is the only channel that always works; SMS is a\n           stub and is never offered; an approval request is always in-app, so the sign-off picker has no such line. -->\n      <div class=\"preset-email\" *ngIf=\"picker.showEmail\" role=\"checkbox\" tabindex=\"0\" [attr.aria-checked]=\"includeEmail\"\n           (click)=\"toggleIncludeEmail()\"\n           (keydown.enter)=\"toggleIncludeEmail()\"\n           (keydown.space)=\"toggleIncludeEmail(); $event.preventDefault()\">\n        <mat-icon class=\"preset-state\" [class.on]=\"includeEmail\">{{ includeEmail ? 'check_box' : 'check_box_outline_blank' }}</mat-icon>\n        <span class=\"preset-email-label\">Also send these by email</span>\n        <span class=\"preset-email-hint\">In-app always. Email needs your mail settings.</span>\n      </div>\n    </ng-container>\n  </div>\n</ng-template>\n\n<!-- Graceful empty state (feature disabled or status unavailable) -->\n<div class=\"setup-empty\" *ngIf=\"!status\">\n  <mat-icon>rocket_launch</mat-icon>\n  <p>Setup status is not available yet.</p>\n</div>\n","import { Injectable } from '@angular/core';\nimport { Action, ApiResponse, OrderableConfig } from '../classes/Classes';\nimport { DataServiceLib } from './datalib.service';\nimport { ApiErrorService } from './api-error.service';\n\n// Added (grouped-orderable): the reorder contract, in ONE place, shared by the flat table and the grouped view.\n// Everything here was lifted verbatim out of table.component's onRowDrop path rather than reimplemented, because\n// the two views must post the SAME request — the complete ordered id list for one scope, no order numbers,\n// position IS the order (TinWeb Contracts\\ReorderRequest.cs). Two copies of that rule would drift.\n// Deliberately NOT exported from public-api: this is library-internal plumbing, not new consumer surface.\n@Injectable({ providedIn: 'root' })\nexport class RowOrderService {\n\n  constructor(private dataService: DataServiceLib, private apiErrorService: ApiErrorService) { }\n\n  // `orderable: true` is shorthand for {}; false/absent -> null, which every caller reads as \"zero affordances\".\n  normalize(raw: OrderableConfig | boolean | undefined | null): OrderableConfig | null {\n    return raw ? (raw === true ? {} : raw as OrderableConfig) : null;\n  }\n\n  // The row's identity for the posted id list. Callers pass their own fallback keys in priority order, because\n  // the flat table has heroField/rowIdKey/findIdKey behind it and the grouped view does not — but idField must\n  // win everywhere, which is the sharp edge that cost reorder-demo-1 a whole debugging session: a config\n  // carrying loadIDField beats the ...ID convention and every row then reports the PARENT's id.\n  resolveId(row: any, cfg: OrderableConfig | null, fallbackKeys: (string | null | undefined)[]): any {\n    const key = cfg?.idField || fallbackKeys.find(k => !!k);\n    return key && row ? row[key] : null;\n  }\n\n  // Defaults to the FIRST path segment of the load URL + '/reorder', the route the base [HttpPost(\"reorder\")]\n  // action hangs off ('product-groups?action=list' -> 'product-groups/reorder').\n  action(cfg: OrderableConfig | null, loadAction: Action | undefined): Action {\n    if (cfg?.action) return cfg.action;\n    const entity = (loadAction?.url || '').split('?')[0].split('/')[0];\n    return { url: `${entity}/reorder`, method: 'post' };\n  }\n\n  // An explicit scopeValue wins (the scope is often a chip the user picked and is not on the rows at all), then\n  // scopeField read off a row. `fallbackScope` is what the GROUPED view supplies — the group's own key, which is\n  // the scope by construction there. Flat callers pass nothing and keep the previous null-means-tenant-wide result.\n  scope(cfg: OrderableConfig | null, rows: any[], fallbackScope?: any): any {\n    if (!cfg) return null;\n    if (cfg.scopeValue !== undefined) return cfg.scopeValue;\n    if (cfg.scopeField) return rows?.[0]?.[cfg.scopeField] ?? null;\n    return fallbackScope ?? null;\n  }\n\n  // Added: the ids are only postable if every row resolved one AND no two rows resolved the SAME one. The short\n  // list was already refused locally; the DUPLICATE list was not, and it is the more confusing of the two — the\n  // server answers HTTP 200 with a body refusal from its set-comparison guard, so the only symptom on screen was\n  // a row springing back, indistinguishable from a genuine stale-page conflict. It is a misconfigured idField\n  // every time, so it is named as one here instead of being posted.\n  validateIds(ids: any[], rowCount: number): string | null {\n    if (ids.length !== rowCount) return 'These rows cannot be reordered: one or more has no id to save against.';\n    if (new Set(ids).size !== ids.length) return 'These rows cannot be reordered: two or more share the same id. Set orderable.idField to the row\\'s own id.';\n    return null;\n  }\n\n  // Optimistic move already happened in the caller; this posts it and puts it back if the server says no.\n  persist(cfg: OrderableConfig | null, loadAction: Action | undefined, ids: any[], scope: any,\n    handlers: { revert: () => void, refresh?: () => void }): void {\n\n    const action = this.action(cfg, loadAction);\n    this.dataService.CallApi(action, { scope, ids }).subscribe({\n      next: (response: ApiResponse) => {\n        if (response?.success) return; // quiet settle — a successful drag is its own feedback, no snackbar\n        handlers.revert();\n        // A conflict means somebody else changed this scope, so the rows on screen are stale and reverting alone\n        // would leave the user looking at a list the server disagrees with. Refuse AND refresh.\n        if (response?.reason === 'conflict' && handlers.refresh) handlers.refresh();\n        this.apiErrorService.presentAppFailure(response, 'action', action.url); // never raw server text on a user surface\n      },\n      error: (err: any) => {\n        handlers.revert();\n        this.apiErrorService.present(err); // transport failure — classified and deduped, never a raw error string\n      }\n    });\n  }\n\n  // The local refusals above still have to SAY something, and both views route them through the same door the\n  // server's refusals use, so a user sees one consistent failure surface.\n  presentLocalRefusal(message: string, url: string): void {\n    this.apiErrorService.presentAppFailure({ success: false, message } as ApiResponse, 'action', url);\n  }\n}\n","// Quiet Loading — perceived-progress engine (FSD D1).\n//\n// Maps elapsed time to a percentage on a deterministic, asymptotic curve: a steady climb from zero that\n// decelerates continuously, approaching but NEVER reaching a cap below 100. The bar therefore always looks\n// alive and never sits at 100 waiting for data. 100 is only ever reached by complete(), which is called when\n// the response actually lands.\n//\n//   0ms    → 0\n//   600ms  → 17\n//   1500ms → 37\n//   3000ms → 60\n//   6000ms → 81\n//   →∞     → 94  (asymptotic — never attained)\n//\n// REVISED 2026-08-05 after review. The original curve was piecewise and deliberately \"fast out of the gate\":\n// 60% by 600ms. Combined with the table backdating the curve to the REQUEST time rather than the paint time,\n// the bar was already past 50% on its first painted frame — so what a user actually saw was a bar that\n// appeared half-full, barely moved, then jumped to 100. The perceived-progress illusion needs the opposite:\n// visible, unhurried motion the whole way, slowing as it goes.\n//\n// A single exponential does that with no segment joins to get wrong: p = cap * (1 - e^(-t/TAU)). It starts at\n// exactly 0, is monotonic, is continuously decelerating (no flat spots, no kinks), and never reaches the cap.\n//\n// The curve is a pure function of elapsed time (`valueAt`), so it is fully unit-testable with no timers. The\n// instance wraps it in a requestAnimationFrame loop for rendering, and `tick(now)` can be driven manually in\n// tests or by any other scheduler.\n\nexport interface PerceivedProgressOptions {\n  cap?: number;             // ceiling the crawl approaches; the whole curve scales to it (default 94)\n  completeMs?: number;      // ramp duration from wherever the curve is to 100 (default 200)\n  onChange?: (percent: number) => void; // called on every value change — bind rendering here\n}\n\nexport class PerceivedProgress {\n\n  static readonly TAU_MS = 3000;        // time constant — larger is slower and steadier throughout\n  static readonly CAP = 94;             // asymptote — approached, never reached\n  static readonly COMPLETE_MS = 200;    // ramp to 100 once the response lands\n  static readonly CAP_MARGIN = 1e-6;    // Changed: gap held below the cap so the asymptote is never attained\n\n  // Pure f(elapsed). Starts at exactly 0, monotonically increasing, continuously decelerating, strictly < cap.\n  static valueAt(elapsedMs: number, cap: number = PerceivedProgress.CAP): number {\n    const t = elapsedMs > 0 ? elapsedMs : 0;\n    const value = cap * (1 - Math.exp(-t / PerceivedProgress.TAU_MS));\n    // Changed: e^(-t/TAU) underflows to 0 past ~200 time constants (10 min), so in floating point the result\n    // lands exactly ON the cap and the \"approached, never reached\" contract breaks. Hold it a hair below —\n    // far smaller than a rounded display step, so nothing visible changes.\n    return value < cap ? value : cap - PerceivedProgress.CAP_MARGIN;\n  }\n\n  // Monotonic clock; falls back to Date.now() where performance is unavailable (SSR, some test runners).\n  static now(): number {\n    return typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();\n  }\n\n  percent = 0;      // float, for bar width\n  running = false;\n\n  private startedAt = 0;\n  private frame: any = null;\n  private completing = false;\n  private completeFrom = 0;\n  private completeStartedAt = 0;\n  private doneCallback: (() => void) | null = null;\n  private completeGuard: any = null; // Added: fires `done` even when requestAnimationFrame never does — see complete()\n\n  constructor(private options: PerceivedProgressOptions = {}) { }\n\n  // Integer for display — the caption uses tabular numerals, so a fractional value would jitter.\n  get display(): number {\n    return Math.round(this.percent);\n  }\n\n  private get cap(): number {\n    return this.options.cap ?? PerceivedProgress.CAP;\n  }\n\n  private get completeMs(): number {\n    return this.options.completeMs ?? PerceivedProgress.COMPLETE_MS;\n  }\n\n  start(now: number = PerceivedProgress.now()): void {\n    this.cancelFrame();\n    this.clearGuard(); // Added: a restart abandons any pending completion, guard included\n    this.startedAt = now;\n    this.completing = false;\n    this.doneCallback = null;\n    this.percent = 0;\n    this.running = true;\n    this.emit();\n    this.scheduleFrame();\n  }\n\n  // Called when the response lands: ramps from wherever the curve is to 100, then invokes `done` once.\n  complete(done?: () => void): void {\n    if (!this.running) {\n      // never started (or already finished) — nothing to animate, just report done\n      this.percent = 100;\n      this.emit();\n      if (done) { done(); }\n      return;\n    }\n\n    this.completing = true;\n    this.completeFrom = this.percent;\n    this.completeStartedAt = PerceivedProgress.now();\n    this.doneCallback = done ?? null;\n    this.scheduleFrame();\n\n    // Added (Phase 5): `done` is what tears the ghost rows / skeleton down, and until now it could only ever be\n    // reached from a requestAnimationFrame callback. rAF does NOT fire while the document is hidden (a\n    // backgrounded tab) and does not exist at all off-browser, so a response that landed while the user was on\n    // another tab left the surface sitting in its loading state — indefinitely in the no-rAF case, and until the\n    // user came back in the hidden-tab case. A timer is throttled in a hidden tab but it still fires, so this\n    // guarantees the stage always closes. Driving tick() at exactly completeStartedAt + completeMs forces k = 1,\n    // i.e. the same terminal frame rAF would have produced; if rAF got there first `running` is already false and\n    // tick() is a no-op.\n    this.clearGuard(); // a second complete() restarts the ramp, so the guard must be re-armed against the NEW start\n    if (typeof setTimeout !== 'undefined') {\n      const at = this.completeStartedAt + this.completeMs;\n      this.completeGuard = setTimeout(() => { this.completeGuard = null; this.tick(at); }, this.completeMs + 50);\n    }\n  }\n\n  // Abandons the run without completing (error path, component teardown).\n  stop(): void {\n    this.running = false;\n    this.completing = false;\n    this.doneCallback = null;\n    this.cancelFrame();\n    this.clearGuard(); // Added: teardown must not leave a timer holding a reference to a destroyed host\n  }\n\n  // Advances the value to `now`. Public so tests (and non-rAF hosts) can drive the engine deterministically.\n  tick(now: number = PerceivedProgress.now()): void {\n    if (!this.running) {\n      return;\n    }\n\n    if (this.completing) {\n      const span = this.completeMs;\n      const k = span > 0 ? Math.min(1, (now - this.completeStartedAt) / span) : 1;\n      this.percent = this.completeFrom + (100 - this.completeFrom) * k;\n\n      if (k >= 1) {\n        this.percent = 100;\n        this.running = false;\n        this.cancelFrame();\n        this.clearGuard(); // Added: the ramp finished normally — drop the safety-net timer\n        this.emit();\n        const done = this.doneCallback;\n        this.doneCallback = null;\n        if (done) { done(); }\n        return;\n      }\n    } else {\n      this.percent = PerceivedProgress.valueAt(now - this.startedAt, this.cap);\n    }\n\n    this.emit();\n  }\n\n  private emit(): void {\n    if (this.options.onChange) {\n      this.options.onChange(this.percent);\n    }\n  }\n\n  private scheduleFrame(): void {\n    if (this.frame !== null || typeof requestAnimationFrame === 'undefined') {\n      return; // no rAF (SSR / unit tests) — the host drives tick() itself\n    }\n\n    this.frame = requestAnimationFrame(() => {\n      this.frame = null;\n      this.tick();\n      if (this.running) {\n        this.scheduleFrame();\n      }\n    });\n  }\n\n  // Added: clears the completion safety-net timer (see complete()).\n  private clearGuard(): void {\n    if (this.completeGuard !== null) {\n      clearTimeout(this.completeGuard);\n      this.completeGuard = null;\n    }\n  }\n\n  private cancelFrame(): void {\n    if (this.frame !== null && typeof cancelAnimationFrame !== 'undefined') {\n      cancelAnimationFrame(this.frame);\n    }\n    this.frame = null;\n  }\n}\n","import { Injectable } from '@angular/core';\nimport { Icon, Color } from '../classes/Classes';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class ConditionService {\n\n\n  testIconCondition(icon: Icon, row: any): boolean {\n    if (!icon) return false;\n    return icon.condition ? icon.condition(row) : true;\n  }\n\n\n  testColorCondition(color: Color, row: any): boolean {\n    if (!color) return false;\n    return color.condition ? color.condition(row) : true;\n  }\n\n\n  getColor(value: any, options: any[]): string {\n    if (!options) return 'lightgrey';\n    const option = options.find(opt => opt.value === value);\n    return option ? option.color : 'lightgrey';\n  }\n\n\n  testCondition(condition: (value: any) => boolean, value: any): boolean {\n    return condition ? condition(value) : true;\n  }\n}\n","import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';\nimport { MatTableDataSource } from '@angular/material/table';\nimport { Subject, Subscription } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\n\n@Component({\n    selector: 'spa-filter',\n    templateUrl: './filter.component.html',\n    styleUrls: ['./filter.component.css'],\n    standalone: false\n})\nexport class FilterComponent implements OnInit, OnDestroy {\n\n  constructor() { }\n\n  // TS-14: debounce keystrokes so the (potentially full-dataset) filter runs at most every 200ms instead of per key\n  private filterInput$ = new Subject<string>();\n  private filterSub: Subscription;\n\n  ngOnInit(): void {\n    this.filterSub = this.filterInput$.pipe(debounceTime(200)).subscribe(text => this.applyFilter(text));\n  }\n\n  ngOnDestroy() {\n    this.filterSub?.unsubscribe();\n  }\n\n  ngOnChanges() {\n    this.applyFilter(this._filterText);\n  }\n\n  @Input() flatButtons = false;\n  @Input() showText = true;\n  @Input() showButton = true;\n  @Input() smallScreen = false; // Changed: Accept smallScreen for compact width on mobile\n  @Input() data = new MatTableDataSource();\n  @Input() refreshing = false; // Added (Quiet Loading D4): spins the refresh icon while the table's quiet refresh is in flight\n  @Output() refreshClick = new EventEmitter();\n  @Output() filterChange = new EventEmitter<string>(); // Added: notifies the table of filter text changes (paged-mode banner + slice handling)\n\n  _filterText = \"\";\n\n\n  keyUp(event: KeyboardEvent) {\n    let text = event.target['value'];\n    this.filterInput$.next(text); // Changed: TS-14 route through debounce instead of filtering on every keystroke\n  }\n\n\n  applyFilter(filterValue: string) {\n\n    if (this.data){\n      this.data.filter = filterValue.trim().toLowerCase();\n    }\n\n    this.filterChange.emit(filterValue); // Added: fires for keyUp, clear, and ngOnChanges paths automatically\n  }\n\n  refreshClicked(){\n    this.refreshClick.emit();\n  }\n\n  clear(){\n    this._filterText = \"\";\n    this.applyFilter(this._filterText);\n  }\n\n}\n","<!-- Changed: Added flex container div to align filter textbox and button -->\n<div class=\"filter-container\">\n  <mat-form-field *ngIf=\"showText\" [ngClass]=\"{'filter-compact': smallScreen}\"> <!-- Changed: Apply compact class on small screens -->\n   <mat-label>Filter</mat-label>\n   <input id=\"txtFilter\" matInput [(ngModel)]=\"_filterText\" (keyup)=\"keyUp($event)\" placeholder=\"Enter Filter text\" autocomplete=\"off\">\n    <div matSuffix class=\"suffix-icons\">\n      <button mat-icon-button *ngIf=\"_filterText\" (click)=\"clear()\" matTooltip=\"Clear\" matTooltipPosition=\"above\">\n        <mat-icon style=\"color: black;\">close</mat-icon>\n      </button>\n\n    </div>\n  </mat-form-field>\n\n  <!-- <button *ngIf=\"showButton && !flatButtons\" id=\"btnFilter\" mat-mini-fab color=\"primary\" matTooltip=\"Refresh Data\" matTooltipPosition=\"above\" (click)=\"refreshClicked()\" style=\"margin-right:1em;margin-top:5px\">\n    <mat-icon class=\"refreshIcon\">cached</mat-icon>\n  </button> -->\n\n  <!-- Changed: Removed inline margin-top style as alignment is now handled by flex container -->\n  <button *ngIf=\"showButton\" id=\"btnFilter\" mat-icon-button color=\"primary\" matTooltip=\"Refresh Data\" matTooltipPosition=\"above\" (click)=\"refreshClicked()\">\n    <mat-icon class=\"refreshIcon\" [class.tin-spin]=\"refreshing\">cached</mat-icon> <!-- Changed (Quiet Loading D4): spins while a quiet refresh is in flight; never applied when quiet loading is off -->\n  </button>\n</div>\n","// Simple text input component - Password, textarea, and autocomplete moved to separate components\nimport { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormControl, Validators } from '@angular/forms';\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-text',\n    templateUrl: './text.component.html',\n    styleUrls: ['./text.component.css'],\n    standalone: false\n})\nexport class TextComponent implements OnInit, OnChanges {\n\n  constructor() {  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['value'] && this.control) {\n      if (this.control.value !== changes['value'].currentValue) {\n        this.control.setValue(changes['value'].currentValue, { emitEvent: false });\n      }\n    }\n    \n    if (changes['readonly'] && this.control) {\n      this.initControl();\n    }\n  }\n\n  // Changed: the \"Enter <display>\" freeze that lived here is gone — see computedPlaceholder below.\n  ngOnInit(): void {\n  }\n\n  ngAfterViewInit() {\n    this.initControl();\n\n    if (this.value) {\n      this.control.setValue(this.value, { emitEvent: false });\n    }\n\n    this.control.valueChanges.subscribe(val => {\n      this.value = val;\n      this.control.markAsDirty();\n      this.valueChange.emit(val);\n    });\n  }\n\n  @Input() appearance: 'fill' | 'outline' = 'outline';\n  @Input() readonly = false;\n  @Input() hint = \"\";\n  @Input() display = \"\";\n  @Input() placeholder = \"\";\n  // Added: derived resting placeholder. A plain text box is typed into, so the verb is \"Enter\". Explicit wins.\n  get computedPlaceholder(): string { return derivePlaceholder('enter', this.display, this.placeholder, this.readonly); }\n  @Input() value = \"\";\n  @Output() valueChange = new EventEmitter();\n  @Input() format = \"text\";\n  @Input() type = \"\";\n\n  @Output() leave = new EventEmitter();\n  @Output() enterPress = new EventEmitter();\n\n  @Input() width = \"100%\";\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n\n  @Input() required = true;\n  @Input() min = 0;\n  @Input() max = 9000000000000000;\n  @Input() regex?: { pattern: string; message: string };\n\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n\n  isHovered = false;\n  onMouseEnter(): void {\n    this.isHovered = true;\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n  }\n\n  initControl() {\n    if (this.readonly) {\n      this.control.setValidators(null);\n      this.control.updateValueAndValidity();\n      return;\n    }\n    \n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    if (this.min > 0) {\n      validators.push(Validators.minLength(this.min));\n    }\n    \n    if (this.max < 9000000000000000) {\n      validators.push(Validators.maxLength(this.max));\n    }\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    this.control.setValidators(validators);\n    this.control.updateValueAndValidity();\n  }\n\n  leaved() {\n    this.control.markAsTouched();\n    this.leave.emit();\n\n    if (this.regex && this.value) {\n      const regexPattern = new RegExp(this.regex.pattern);\n      if (!regexPattern.test(this.value)) {\n        this.control.setErrors({ 'pattern': true });\n      }\n    }\n  }\n\n  clear() {\n    this.value = \"\";\n    this.control.setValue(\"\", { emitEvent: false });\n    this.control.markAsDirty();\n    this.control.markAsTouched();\n    this.valueChange.emit(this.value);\n  }\n\n  enterPressed() {\n    this.enterPress.emit();\n  }\n\n  control = new FormControl('', this.getValidators());\n\n  private getValidators() {\n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    validators.push(Validators.minLength(this.min));\n    validators.push(Validators.maxLength(this.max));\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    return validators;\n  }\n\n  validate(control: FormControl): string {\n    if ((this.required || this.min > 0) && control.hasError('required')) {\n      return `Required`;\n    }\n\n    if (control.hasError('minlength')) {\n      return `Minimum length is ${this.min}`;\n    }\n\n    if (control.hasError('maxlength')) {\n      return `Maximum length is ${this.max}`;\n    }\n\n    if (control.hasError('pattern')) {\n      return this.regex?.message || 'Invalid Input';\n    }\n\n    return \"\";\n  }\n}\n\n","<!-- Simple text input - Password, textarea, and autocomplete moved to separate components -->\n<mat-form-field [class.spa-readonly]=\"readonly\" [hideRequiredMarker]=\"!required\" [hintLabel]=\"hint\" [appearance]=\"appearance ?? 'fill'\" [ngStyle]=\"{'width':width ?? '100%'}\" style=\"margin-right: 5px;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n  <mat-label *ngIf=\"format=='text'\">{{display}}</mat-label>\n  <mat-label *ngIf=\"format=='date'\">{{display | date:'dd/MM/yyyy'}}</mat-label>\n  <input matInput autocomplete=\"off\" (blur)=\"leaved()\" (keyup.enter)=\"enterPressed()\" [type]=\"type\" [placeholder]=\"computedPlaceholder\" [formControl]=\"control\" [required]=\"required\" [readonly]=\"readonly\"/>\n  <mat-error *ngIf=\"control.invalid && (control.dirty || control.touched)\">{{validate(control)}}</mat-error>\n  <div matSuffix class=\"suffix-icons\">\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\n  </div>\n</mat-form-field>\n","// Autocomplete text input component\nimport { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges, OnDestroy } from '@angular/core'; // Changed: Added OnDestroy\nimport { FormControl, Validators } from '@angular/forms';\nimport { BehaviorSubject, Observable, Subscription } from 'rxjs'; // Changed: Added BehaviorSubject, Subscription imports\nimport { finalize, map, startWith } from 'rxjs/operators'; // Changed: Added finalize to settle the load indicator on success AND error\nimport { FieldLoadIndicator } from '../../runtime/field-load-indicator'; // Added: shared spinning-refresh state for loadAction fields\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\nimport { Core } from '../../classes/TinCore';\nimport { Action, ApiResponse, Button, DetailsDialogConfig, Field, FormConfig, TableConfig } from '../../classes/Classes'; // Changed: FormConfig added — it types the memo key for the hoisted tmpTableConfig\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { DialogService } from '../../services/dialog.service'; // Changed: Added DialogService import\nimport { ButtonService } from '../../services/button.service'; // Changed: Added ButtonService import\nimport { MessageService } from '../../services/message.service'; // Changed: Added MessageService import\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: routes a failed loadAction through the shared classify + dedupe path (WS-6 Phase 3)\nimport { OfflineService } from '../../services/offline.service'; // Added (WS-1 Phase 3): read-only — the component asks whether the network is down so a failed option load can say so on the field instead of toasting\n\n@Component({\n    selector: 'spa-text-single',\n    templateUrl: './text-single.component.html',\n    styleUrls: ['./text-single.component.css'],\n    standalone: false\n})\nexport class TextSingleComponent implements OnInit, OnChanges, OnDestroy { // Changed: Added OnDestroy\n\n  constructor(\n    private dataService: DataServiceLib,\n    private dialogService: DialogService, // Changed: Added DialogService injection\n    private buttonService: ButtonService, // Changed: Added ButtonService injection\n    private messageService: MessageService, // Changed: Added MessageService injection\n    private apiErrorService: ApiErrorService, // Added: so a failed option load is no longer silent\n    private offline: OfflineService // Added (WS-1 Phase 3): root-provided and already a DataServiceLib dependency, so no new graph — used only to tell an offline cache miss from a server failure\n  ) {  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    this.resolveAddOptionLabel(); // Added (dropdown quick-add): re-evaluate when detailsConfig/display change\n\n    if (changes['value'] && this.myControl) {\n      const newDisplay = this.getDisplayValue(changes['value'].currentValue);\n      if (this.myControl.value !== newDisplay) {\n        // Changed: Emit event when value is cleared so filteredOptions pipe re-evaluates and shows all options\n        const wasCleared = !changes['value'].currentValue;\n        this.myControl.setValue(newDisplay, { emitEvent: wasCleared });\n      }\n    }\n\n    if (changes['readonly'] && this.myControl) {\n      this.initControl();\n    }\n\n    // Changed: React to options changes for master field functionality\n    if (changes['options'] && this.options?.length > 0) {\n      this.initFilter();\n      // Changed: Clear current value if it's no longer valid in new options\n      if (this.value && !this.getDisplayValue(this.value)) {\n        this.clear();\n      }\n    }\n  }\n\n  private subscription: Subscription; // Changed: Added subscription for optionsSubject\n\n  ngOnInit(): void {\n    if (!this.options) {\n      this.options = [];\n    }\n\n    if (this.loadAction) {\n      this.getData(this.loadAction);\n    } else {\n      if (this.options.length > 0) {\n        this.initFilter();\n      }\n    }\n\n    // Changed: the \"Enter {display}\" default moved out to computedPlaceholder below, and now splits by whether this\n    // control is actually a PICKER. Frozen here it could never say \"or select\": ngOnInit runs before a loadAction's\n    // options arrive, so the one case that most needs the hint would always have missed it.\n\n    this.resolveAddOptionLabel(); // Added (dropdown quick-add): compute once inputs are bound\n\n    // Changed: Subscribe to optionsSubject for child field option updates\n    if (this.field?.optionsSubject) {\n      this.subscription = this.field.optionsSubject.subscribe(newOptions => {\n        if (newOptions) {\n          this.options = newOptions;\n          this.initFilter();\n        }\n      });\n    }\n  }\n\n  ngOnDestroy(): void {\n    if (this.subscription) {\n      this.subscription.unsubscribe();\n    }\n    this.loadIndicator.destroy(); // Added: clear any pending delay/hold timer on a field torn down mid-read\n  }\n\n  ngAfterViewInit() {\n    this.initControl();\n\n    if (this.value) {\n      this.myControl.setValue(this.getDisplayValue(this.value), { emitEvent: false });\n    }\n  }\n\n  filteredOptions: Observable<string[]>;\n  multiDimension = false;\n\n  @Input() appearance: 'fill' | 'outline' = 'outline';\n  @Input() readonly = false;\n  @Input() hint = \"\";\n  @Input() display = \"\";\n  @Input() placeholder = \"\";\n\n  // Added: this component is the house's TYPEABLE SELECT — a text box with a mat-autocomplete behind it. When it\n  // carries a list (options now, or a loadAction that will bring one) the user can type OR pick, and the placeholder\n  // has to say so: \"Enter or select Breed\". With no list at all it is an ordinary text box and keeps \"Enter X\".\n  // A getter, not a frozen field, so a field whose options arrive from the server still gets the picker wording.\n  get isPicker(): boolean { return !!this.loadAction || (this.options?.length ?? 0) > 0; }\n  get computedPlaceholder(): string { return derivePlaceholder(this.isPicker ? 'enter-or-select' : 'enter', this.display, this.placeholder, this.readonly); }\n\n  @Input() value = \"\";\n  @Output() valueChange = new EventEmitter();\n\n  @Output() leave = new EventEmitter();\n  @Output() enterPress = new EventEmitter();\n\n  @Input() width = \"100%\";\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n\n  // Changed: Autocomplete-specific properties\n  @Input() options: any = [];\n  @Input() optionDisplay = \"name\";\n  @Input() optionValue = \"value\";\n  @Input() loadAction: Action;\n\n  @Input() required = true;\n  @Input() min = 0;\n  @Input() max = 9000000000000000;\n  @Input() regex?: { pattern: string; message: string };\n\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n\n  @Input() field: Field; // Changed: Added field input for form integration\n  @Input() data: any; // Changed: Added data input for form integration\n  @Input() detailsConfig: DetailsDialogConfig; // Changed: Added detailsConfig for Add/View functionality\n  @Input() masterField: string; // Changed: Added masterField input for child field functionality\n\n  // Added (dropdown quick-add): sentinel value for the always-first \"add new\" option — never a real option value\n  readonly ADD_NEW_OPTION = \"__spa_add_new__\";\n  // Added: materialized label (no template-bound getter); null hides the option\n  addOptionLabel: string = null;\n\n  // Added: same gate as the plus icon — prefers the create form's title, then the field label minus a\n  // trailing \"ID\", falling back to a generic \"Add New\"\n  private resolveAddOptionLabel(): void {\n    if (!this.detailsConfig || !this.canCreate()) {\n      this.addOptionLabel = null;\n      return;\n    }\n    const entity = this.detailsConfig.formConfig?.title || this.display?.replace(/\\s+id$/i, '');\n    this.addOptionLabel = entity ? `New ${entity}` : 'Add New';\n  }\n\n  isHovered = false;\n\n  // Added (WS-1 Phase 3, offline forms): true when this autocomplete's options could not be resolved because\n  // there is no connection AND nothing was cached for its url. Identical in cause and in treatment to\n  // spa-select-common's flag of the same name — deliberately the SAME state, the SAME sentence and the SAME\n  // mark, because two different messages for one condition is worse than one imperfect message.\n  // Held out of that chunk only to keep it to a single subject; this is the sibling.\n  // The failure here is if anything MORE deceptive than the select's. With no options the autocomplete still\n  // looks and types like a working text box, but the panel is empty, so `(optionSelected)` — the ONLY path that\n  // calls changed() — never fires, `value` is never emitted, and myControl keeps its Validators.required error.\n  // The user types a customer name, sees text in the box, and the form still will not submit. Note also that\n  // leaved()'s strict-selection check is gated on `options?.length > 0`, so it goes quiet in exactly this case\n  // and cannot supply the missing explanation either.\n  // NOT an @Input, unlike the select: nothing wraps spa-text-single. It is rendered directly by\n  // form.component.html (both the field and subfield switches) and by option.component.html, there is no\n  // subclass of TextSingleComponent, and the instance that fetches is the instance that draws. The select\n  // needed the binding because spa-select/spa-select-lite WRAP spa-select-common as well as extending it.\n  optionsUnavailableOffline = false;\n\n  // Added (WS-1 Phase 3): the offline-unavailable notice OUTRANKS the configured hint — it is the one of the\n  // two that says the control in front of you cannot do its job. Reuses the mat-form-field hint line this\n  // template ALREADY binds, and the field already sets subscriptSizing=\"dynamic\", so the line appears and\n  // disappears without moving the form. No new component, layout or copy surface enters the library.\n  get computedHint(): string {\n    if (this.optionsUnavailableOffline) return \"No connection — this list wasn't saved for offline use\";\n    return this.hint;\n  }\n\n  // Added: drives the suffix refresh icon — held visible and spinning while the loadAction is in flight\n  readonly loadIndicator = new FieldLoadIndicator();\n\n  onMouseEnter(): void {\n    this.isHovered = true;\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n  }\n\n  private initFilter() {\n    // Changed: Added guard for empty options\n    if (!this.options || this.options.length === 0) {\n      this.filteredOptions = this.myControl.valueChanges.pipe(\n        startWith(\"\"),\n        map(() => [])\n      );\n      return;\n    }\n\n    const objKeyList = Object.keys(this.options[0]);\n    const firstKey = objKeyList[0];\n    this.multiDimension = !Core.isNumber(firstKey);\n\n    this.filteredOptions = this.myControl.valueChanges.pipe(\n      startWith(\"\"),\n      map((value) => this._filter(value))\n    );\n\n    this.myControl.setValue(this.getDisplayValue(this.value));\n  }\n\n  private _filter(value): string[] {\n    if (!value || !this.options) return this.options || []; // Changed: Added null safety\n\n    const filterValue = value.toLowerCase();\n    if (this.multiDimension) {\n      return this.options.filter(option =>\n        option[this.optionDisplay]?.toLowerCase()?.includes(filterValue) // Changed: Added null safety\n      );\n    }\n    return this.options.filter(option =>\n      option?.toLowerCase()?.includes(filterValue) // Changed: Added null safety\n    );\n  }\n\n  initControl() {\n    if (this.readonly) {\n      this.myControl.setValidators(null);\n      this.myControl.updateValueAndValidity();\n      return;\n    }\n    \n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    if (this.min > 0) {\n      validators.push(Validators.minLength(this.min));\n    }\n    \n    if (this.max < 9000000000000000) {\n      validators.push(Validators.maxLength(this.max));\n    }\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    this.myControl.setValidators(validators);\n    this.myControl.updateValueAndValidity();\n  }\n\n  getDisplayValue(value: any): string {\n    if (!value || !this.options.length) return '';\n\n    if (this.multiDimension) {\n      const option = this.options.find(opt => opt[this.optionValue] === value);\n      return option ? option[this.optionDisplay] : '';\n    }\n    return value;\n  }\n\n  changed() {\n    const selectedOption = this.multiDimension ?\n      this.options.find(opt => opt[this.optionDisplay] === this.myControl.value) :\n      this.options.find(opt => opt === this.myControl.value);\n\n    const valueToEmit = selectedOption ?\n      (this.multiDimension ? selectedOption[this.optionValue] : selectedOption) :\n      this.myControl.value;\n\n    this.value = valueToEmit;\n    this.valueChange.emit(valueToEmit);\n\n    // Changed: Clear invalidSelection error when a valid option is selected from dropdown\n    if (selectedOption && this.myControl.hasError('invalidSelection')) {\n      this.myControl.setErrors(null);\n    }\n\n    // Changed: Call onSelectChange callback if provided via field (only fires on explicit option selection)\n    if (this.field?.onSelectChange && this.data) {\n      this.field.onSelectChange(valueToEmit, this.data, selectedOption, (this.field as any).formConfig); // Changed (addpig-label-leak): forward the LIVE FormConfig stamped on the field by spa-form — same reason as spa-select-common, this is the third place the hook is invoked from\n    }\n  }\n\n  // Added: THE KEYBOARD PATH. The <input> carried no (input), no (change) and no (blur), and leaved() below was\n  // bound to nothing, so (optionSelected) was the ONLY route to the model. Every keystroke was discarded — not\n  // just a clear. Emptying the box left the box empty on screen and the OLD value in the model, on the wire and\n  // in the column after a 200; typing text that matched no option was silently dropped the same way.\n  // Bound to the DOM (input) event, which fires only on real typing — myControl.setValue() from ngOnChanges\n  // does not raise it, so nothing here can emit because the control initialised, rendered or was rebound.\n  typed() {\n    const raw = this.myControl.value;\n\n    // An emptied box is a deliberate clear: null, never \"\" and never the stale value.\n    if (raw === null || raw === undefined || raw === '') {\n      this.value = null;\n      this.valueChange.emit(null);\n      return;\n    }\n\n    const selectedOption = this.multiDimension ?\n      this.options?.find(opt => opt[this.optionDisplay] === raw) :\n      this.options?.find(opt => opt === raw);\n\n    if (selectedOption) {\n      this.value = this.multiDimension ? selectedOption[this.optionValue] : selectedOption;\n      this.valueChange.emit(this.value);\n      if (this.myControl.hasError('invalidSelection')) this.myControl.setErrors(null);\n      return;\n    }\n\n    // multiDimension means the box shows a NAME and the model holds an ID. Half-typed text has no id, so there\n    // is nothing honest to emit — the previous id stands until an option is picked, and leaved() below now\n    // marks the mismatch so the disagreement between box and model is visible rather than silent.\n    if (this.multiDimension) return;\n\n    // A plain string list is a free-text autocomplete: what was typed IS the value.\n    this.value = raw;\n    this.valueChange.emit(raw);\n  }\n\n  leaved() {\n    this.myControl.markAsTouched();\n    this.leave.emit();\n\n    // Changed: Validate that a valid option is selected when required\n    if (this.required && this.options?.length > 0) {\n      const inputValue = this.myControl.value;\n      if (!inputValue) {\n        this.myControl.setErrors({ 'required': true });\n        return;\n      }\n      if (!this.isValidSelection(inputValue)) {\n        this.myControl.setErrors({ 'invalidSelection': true });\n        return;\n      }\n    }\n\n    // Added: the same check for a NON-required field. Without it, typing text that matches no option leaves the\n    // box reading one thing and the model holding another, with nothing on screen to say so — and typed() above\n    // deliberately declines to invent an id for it. Turning that silence into a visible error is the point.\n    // Still gated on options?.length > 0, so a list that failed to load offline does not accuse the user.\n    if (!this.required && this.options?.length > 0) {\n      const inputValue = this.myControl.value;\n      if (inputValue && !this.isValidSelection(inputValue)) {\n        this.myControl.setErrors({ 'invalidSelection': true });\n        return;\n      }\n    }\n\n    if (this.regex && this.value) {\n      const regexPattern = new RegExp(this.regex.pattern);\n      if (!regexPattern.test(this.value)) {\n        this.myControl.setErrors({ 'pattern': true });\n      }\n    }\n  }\n\n  // Changed: Added method to check if entered value matches a valid option\n  isValidSelection(inputValue: string): boolean {\n    if (!inputValue || !this.options?.length) return false;\n\n    if (this.multiDimension) {\n      return this.options.some(opt => opt[this.optionDisplay] === inputValue);\n    }\n    return this.options.some(opt => opt === inputValue);\n  }\n\n  clear() {\n    // Changed: was `this.value = \"\"`. This control's value is frequently an ID, not a display string —\n    // datalib.service.ts customerID is an int FK — so \"\" was a JSON empty string posted at an int property.\n    // A cleared control emits null. The FormControl keeps \"\": that is how an empty BOX is spelled.\n    this.value = null;\n    this.myControl.setValue(\"\", { emitEvent: false });\n    this.myControl.markAsDirty();\n    this.myControl.markAsTouched();\n    this.valueChange.emit(this.value);\n    // Changed: Set required error when clearing a required field\n    if (this.required) {\n      this.myControl.setErrors({ 'required': true });\n    }\n  }\n\n  enterPressed() {\n    this.enterPress.emit();\n  }\n\n  refresh(event: MouseEvent): void {\n    event?.stopPropagation(); // Changed: tolerate a null event — the dropdown \"add new\" flow refreshes without a mouse event\n    if (!this.loadAction) {\n      return;\n    }\n\n    const refreshAction = {\n      ...this.loadAction,\n      forceRefresh: true\n    };\n\n    this.getData(refreshAction);\n  }\n\n  getData(action: Action) {\n    if (!action) return;\n    if (this.masterField) return; // Changed: Skip self-loading if child field (form handles loading via masterOptions)\n\n    this.loadIndicator.begin(); // Added: arm the spinning refresh icon (only paints if the read outlives the anti-flicker delay)\n\n    this.dataService.CallApi(action).pipe(\n      finalize(() => this.loadIndicator.settle()) // Added: stop the spin whether the read succeeded or failed\n    ).subscribe({\n      next: (apiResponse: ApiResponse) => {\n      if (apiResponse.success) {\n        this.optionsUnavailableOffline = false; // Added: a later successful load clears the offline notice (reconnect, or the manual refresh icon)\n        this.options = apiResponse.data;\n        // Changed: Also set field.options and notify via optionsSubject so form can update child fields\n        if (this.field) {\n          this.field.options = apiResponse.data;\n          if (!this.field.optionsSubject) {\n            this.field.optionsSubject = new BehaviorSubject(apiResponse.data);\n          } else {\n            this.field.optionsSubject.next(apiResponse.data);\n          }\n        }\n        this.initFilter();\n      } else if (this.isOfflineCacheMiss()) {\n        // Added (WS-1 Phase 3): the offline read seam answers a cache miss with HTTP-200 `success:false` and the\n        // message 'No offline data available yet for this view' (offline.service.ts serveCachedRead), which\n        // classifyMessage correctly reads as a business message and toasts. That is the WRONG surface for this\n        // one case: the failure is not the server's, it is per-FIELD, and the toast is deduped across the form\n        // so several dead lookups speak once and namelessly. Mark the field instead.\n        // This url DOES reach the seam: registerLookups walks `formConfig.fields` and registers any\n        // `field.loadAction.url` regardless of the field's TYPE, so a `text-single` lookup is registered on\n        // exactly the same terms as a `select` one — e.g. invoiceFormConfig's customerID (customers/list/x,\n        // required + strict, with quick-add) is a live instance of precisely this.\n        this.markOptionsUnavailableOffline();\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Added: was a silent no-op — an autocomplete that failed to load its options looked identical to one with none; 'load' dedupes with the page's other loads\n      }\n      },\n      // Added (WS-1 Phase 3): the OTHER offline shape. A lookup url the registry never matched does not reach\n      // the read seam at all — it goes to the wire and dies as status 0. The interceptor has already spoken for\n      // that (loader-interceptor.service.ts:110-112 shows the connection dialog for exactly the urls the offline\n      // layer does NOT suppress), so this adds no second message; it only marks the field, so once the dialog is\n      // dismissed the form still says which lookups are empty and why. Non-network errors keep their previous\n      // behaviour to the letter — there was no error callback here before, so they are logged and go no further.\n      error: (err: any) => {\n        if (err?.status === 0) { this.markOptionsUnavailableOffline(); return; }\n        console.error('[tin-spa] text-single loadAction failed', { url: action.url, err });\n      }\n    });\n  }\n\n  // Added: a cache miss served by the offline layer arrives as success:false with a network we know is down.\n  // Both halves are required — `online === false` alone would claim any 200-level failure was an offline one.\n  private isOfflineCacheMiss(): boolean {\n    return !!this.offline && this.offline.enabled && !this.offline.online;\n  }\n\n  private markOptionsUnavailableOffline(): void {\n    this.optionsUnavailableOffline = true;\n  }\n\n  myControl = new FormControl('', this.getValidators());\n\n  private getValidators() {\n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    validators.push(Validators.minLength(this.min));\n    validators.push(Validators.maxLength(this.max));\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    return validators;\n  }\n\n  validate(control: FormControl): string {\n    if ((this.required || this.min > 0) && control.hasError('required')) {\n      return `Required`;\n    }\n\n    // Changed: Added validation message for invalid selection\n    if (control.hasError('invalidSelection')) {\n      return `Please select a valid option`;\n    }\n\n    if (control.hasError('minlength')) {\n      return `Minimum length is ${this.min}`;\n    }\n\n    if (control.hasError('maxlength')) {\n      return `Maximum length is ${this.max}`;\n    }\n\n    if (control.hasError('pattern')) {\n      return this.regex?.message || 'Invalid Input';\n    }\n\n    return \"\";\n  }\n\n  // Added: canCreate() and canView() are both *ngIf-bound (text-single.component.html), so they ran on every\n  // change-detection pass and each allocated a fresh TableConfig every time — the no-template-bound-allocating-getters\n  // rule. Cached and keyed on the formConfig REFERENCE so a reassigned detailsConfig still rebuilds, matching the\n  // memoised-accessor precedent in tiles.component (ctxCache). Behaviour is identical: buttonService.testVisible only\n  // READS tableConfig?.formConfig?.security and never mutates what it is handed, so one shared instance is safe.\n  // This is the same fix, on the same pair of bodies, as select.component (b741e6c) — the two are deliberate\n  // duplicates and NOT a shared base class: SelectComponent already extends SelectCommonComponent, which declares\n  // neither detailsConfig nor a ButtonService, so hoisting the pair would push both onto SelectLiteComponent too.\n  // If a THIRD copy of this pair ever appears, revisit that call.\n  private tmpTableConfigCache: TableConfig;\n  private tmpTableConfigKey: FormConfig;\n\n  private getTmpTableConfig(): TableConfig {\n    const formConfig = this.detailsConfig?.formConfig;\n    if (!this.tmpTableConfigCache || this.tmpTableConfigKey !== formConfig) {\n      this.tmpTableConfigKey = formConfig;\n      this.tmpTableConfigCache = { formConfig: formConfig };\n    }\n    return this.tmpTableConfigCache;\n  }\n\n  // Changed: Added canCreate method for Add button visibility\n  canCreate(): boolean {\n    if (!this.detailsConfig?.buttons) return false;\n    const createButton: Button = this.detailsConfig.buttons.find(b => b.name === 'create');\n    const tmpTableConfig: TableConfig = this.getTmpTableConfig(); // Changed: was a fresh {formConfig} literal allocated on every change-detection pass\n    return createButton && (!createButton.disabled || !createButton.disabled(this.value)) && this.buttonService.testVisible(createButton, null, tmpTableConfig);\n  }\n\n  // Changed: Added canView method for View button visibility\n  canView(): boolean {\n    if (!this.detailsConfig?.buttons) return false;\n    let viewButton: Button = this.detailsConfig.buttons.find(b => b.name === 'view');\n    if (!viewButton) {\n      // Add default view button if not exists — left as-is deliberately: the find() guard makes it idempotent,\n      // and only the TableConfig allocation was hoisted, so this still runs exactly when it did before.\n      viewButton = { name: 'view', dialog: true };\n      this.detailsConfig.buttons.push(viewButton);\n    }\n    const tmpTableConfig: TableConfig = this.getTmpTableConfig(); // Changed: was a fresh {formConfig} literal allocated on every change-detection pass\n    return this.value && viewButton && this.buttonService.testVisible(viewButton, null, tmpTableConfig);\n  }\n\n  // Added (dropdown quick-add): the \"add new\" option is a command, not a selection — restore the input\n  // text and hand off to the create dialog; real options keep the existing changed() path\n  onOptionSelected(event: any): void {\n    if (event?.option?.value === this.ADD_NEW_OPTION) {\n      this.myControl.setValue(this.getDisplayValue(this.value), { emitEvent: false });\n      this.onPeekClick(null, 'create');\n      return;\n    }\n    this.changed();\n  }\n\n  // Changed: Added onPeekClick method for opening details dialog\n  onPeekClick(event: MouseEvent, mode: 'create' | 'view'): void {\n    event?.stopPropagation(); // Changed: tolerate a null event — the dropdown \"add new\" option calls this without one\n\n    if (this.detailsConfig) {\n      const dynamicData = mode === 'create' ? {} : { [this.detailsConfig.heroField]: this.value };\n\n      let button = this.detailsConfig.buttons.find(b => b.name === mode);\n      button.detailsConfig = this.detailsConfig;\n\n      this.dialogService.openDefaultDetailsDialog(button, dynamicData).subscribe(result => { // Changed: Use openDefaultDetailsDialog to avoid circular dependency\n        if (result?.message === 'success') { // Changed: a dismissed quick-add dialog closes with undefined — read through it rather than throwing\n          // Added (dropdown quick-add): auto-select the record the user just created; refresh's initFilter\n          // then resolves the display text once the new option is in the list\n          if (mode === 'create') this.selectCreated(result);\n          this.refresh(event);\n        }\n      });\n    } else {\n      this.messageService.toast(\"Peek configuration error\");\n    }\n  }\n\n  // Added (dropdown quick-add): pull the new record's id off the dialog result (create closes with the API\n  // response entity; other close paths return the details object directly) — silently skip if not found\n  private selectCreated(result: any): void {\n    const hero = this.detailsConfig.heroField;\n    if (!hero) return;\n    const createdID = result.data?.data?.[hero] ?? result.data?.[hero];\n    if (createdID == null) return;\n    this.value = createdID;\n    this.valueChange.emit(this.value);\n  }\n}\n","<!-- Autocomplete text input -->\n<!-- Changed (WS-1 Phase 3): hintLabel now reads computedHint, plus one class — no structural change. It tints the hint line the field already renders. Same treatment as spa-select-common; see the .css for why the state is spoken on the field rather than in a toast. -->\n<!-- Changed (placeholder conventions): floatLabel=\"always\" — with 'auto' the resting label covers the placeholder, so \"Enter or select Breed\" was never visible in the empty state it exists to explain. The floated label stays the CLEAN label ({{display}}) — the verb lives only in the placeholder. -->\n<mat-form-field floatLabel=\"always\" [class.spa-readonly]=\"readonly\" [hideRequiredMarker]=\"!required\" [hintLabel]=\"computedHint\" [class.spa-options-unavailable]=\"optionsUnavailableOffline\" [appearance]=\"appearance ?? 'fill'\" [ngStyle]=\"{'width':width ?? '100%'}\" style=\"margin-right: 5px;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n  <mat-label>{{display}}</mat-label>\n  <!-- Changed: (input) and (blur) added. This input had NO event binding of any kind, and leaved() in the .ts was bound to nothing, so (optionSelected) below was the only route to the model — every keystroke, including emptying the box, was discarded while the screen showed otherwise. (input) is a DOM event, so it fires on real typing only and never on a programmatic setValue. -->\n  <input [placeholder]=\"computedPlaceholder\" [formControl]=\"myControl\" matInput [matAutocomplete]=\"auto\" [matAutocompleteDisabled]=\"readonly\" [required]=\"required\" [readonly]=\"readonly\" (input)=\"typed()\" (blur)=\"leaved()\">\n  <mat-error *ngIf=\"myControl.invalid && (myControl.dirty || myControl.touched)\">{{validate(myControl)}}</mat-error>\n  <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"onOptionSelected($event)\"> <!-- Changed: route through onOptionSelected so the \"add new\" option opens the create dialog -->\n    <!-- Added (dropdown quick-add): always-first create option — outside the filter, so it shows even when nothing matches -->\n    <mat-option *ngIf=\"addOptionLabel\" [value]=\"ADD_NEW_OPTION\" class=\"spa-add-new-option\">\n      <mat-icon class=\"tinyIcon spa-add-new-icon\">add</mat-icon>{{addOptionLabel}}\n    </mat-option>\n    <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"multiDimension ? option[optionDisplay] : option\">\n      {{multiDimension ? option[optionDisplay] : option}}\n    </mat-option>\n  </mat-autocomplete>\n  <div matSuffix class=\"suffix-icons\">\n    <!-- Changed: Added Add button for creating new items via detailsConfig -->\n    <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" style=\"color: green;\">add</mat-icon>\n    </button>\n    <!-- Changed: Added View button for viewing selected item via detailsConfig -->\n    <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" color=\"primary\">launch</mat-icon>\n    </button>\n    <!-- Changed: the icon now also shows while loading (not hover-only), and spins — same .tin-spin idiom as the table/filter refresh button -->\n    <!-- Added (WS-1 Phase 3): the house's own offline mark, the same cloud_off spa-offline-indicator and spa-select-common already use, so the state is recognisable without reading — which is what carries it at phone width, where the hint line has least room. The refresh button below is left exactly as it was and stays reachable on purpose: it is the one action that fixes this once the connection is back, and getData() clears the flag on the first successful load. -->\n    <mat-icon *ngIf=\"optionsUnavailableOffline\" class=\"tinyIcon spa-options-unavailable-icon\" [matTooltip]=\"computedHint\" matTooltipPosition=\"above\">cloud_off</mat-icon>\n    <button mat-icon-button *ngIf=\"loadAction && (isHovered || loadIndicator.spinning)\" (click)=\"refresh($event)\" [matTooltip]=\"loadIndicator.spinning ? 'Loading' : 'Refresh'\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" [class.tin-spin]=\"loadIndicator.spinning\" color=\"primary\">cached</mat-icon>\n    </button>\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\n  </div>\n</mat-form-field>\n","import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormControl, Validators } from '@angular/forms';\nimport { Core } from '../../classes/TinCore';\nimport { DateBounds } from '../../classes/DateBounds'; // Added (NFD-1): resolves dynamic 'today' bounds\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-date',\n    templateUrl: './date.component.html',\n    styleUrls: ['./date.component.css'],\n    standalone: false\n})\nexport class DateComponent implements OnInit, OnChanges {\n  // Changed: default was `true` while the input was NEVER READ, so the value was inert either way. Now that it\n  // drives a real validator the default has to be `false`, because two consumers render a spa-date without\n  // binding it at all — option.component.html:8 (a table filter) and the composite/title-action pickers. A\n  // `true` default would have made every one of those filters required overnight.\n  @Input() required = false;\n  // A bound may be a literal ('1900-01-01', a Date), a dynamic token ('today', 'today-28', 'now'), or — Added\n  // (SBD-1) — a FUNCTION `(row) => Date|string|null`. A function bound is the form to reach for whenever the window\n  // depends on ANOTHER FIELD, because it is PULLED at picker-open time rather than pushed once: it cannot be missed\n  // if the data it needs arrives late, and it cannot go stale when the field it depends on changes again.\n  @Input() min = \"1900-01-01\";\n  @Input() max = \"9999-01-01\";\n\n  // Added (SBD-1): the row/form object handed to a function bound. form.component binds the live `data` object, so\n  // `min: (row) => row.stage ? ... : null` re-evaluates against whatever the user has entered so far.\n  @Input() boundContext: any = null;\n  @Input() readonly = false;\n  @Input() hint = \"\";\n  @Input() value: string | null = Core.nowDate(true);\n\n  @Input() display = \"\";\n  @Input() placeholder = \"\";\n\n  // Added: a date is ALWAYS a picker here — the input is [readonly]=\"true\" and a click opens the calendar, so\n  // \"Pick Date Of Birth\" describes what the control actually does. The template previously bound [placeholder]=\"display\",\n  // which just repeated the label; the @Input placeholder it declared was never read by anything.\n  get computedPlaceholder(): string { return derivePlaceholder('pick', this.display, this.placeholder, this.readonly); }\n\n  @Input() width = \"100%\";\n\n  @Output() valueChange = new EventEmitter<string | null>();\n\n\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n\n\n  isHovered = false;\n  \n  onMouseEnter(): void {\n    this.isHovered = true;\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n  }\n\n  minDate: FormControl;\n  maxDate: FormControl;\n  control: FormControl;\n\n  ngOnInit(): void {\n    this.initializeDateControls();\n  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['readonly']) {\n      this.updateControlState();\n      this.applyValidators(); // Added: readonly drops the validators, exactly as text.component.ts:82-86 does\n    }\n    if (changes['required']) {\n      this.applyValidators(); // Added: requiredCondition flips this at runtime as a sibling field is typed, so it cannot be read once at init\n    }\n    if (changes['value']) {\n\n\n      this.control?.setValue(this.value ? new Date(this.value) : null);\n    }\n    // Added (NFD-1): a config can flip min/max at runtime (readonlyCondition-style), so the resolved bounds\n    // have to follow it — they were snapshotted once at init and never updated again.\n    // Changed (SBD-1): boundContext joins min/max. A FUNCTION bound keeps the SAME reference for the life of the\n    // dialog, so `changes['min']` never fires for one — the row object it reads is what changes. Watching the\n    // context is what makes `min: (row) => ...` follow a sibling field being edited.\n    if (changes['min'] || changes['max'] || changes['boundContext']) this.refreshBounds();\n  }\n\n  private initializeDateControls(): void {\n    this.minDate = new FormControl(DateBounds.resolve(this.min, 'start', this.boundContext));  // Changed (NFD-1): was new Date(this.min) — now resolves the 'today' token, literals behave exactly as before. Changed (SBD-1): passes boundContext so a function bound sees the row\n    this.maxDate = new FormControl(DateBounds.resolve(this.max, 'end', this.boundContext));    // Changed (NFD-1): 'end' of day so `max: 'today'` leaves TODAY selectable and greys tomorrow\n\n\n\n    const initialValue = this.value ? new Date(this.value) : null;\n    this.control = new FormControl({ value: initialValue, disabled: this.readonly });\n\n    this.updateControlState();\n    this.applyValidators(); // Added: the control was created with no validators, so `required` never reached it\n    // Changed: removed `setTimeout(() => this.onChangeEvent(), 5)`. It emitted valueChange five milliseconds\n    // after render with NO user involved, and form.component.html binds [(value)]=\"data[field.name]\", so that\n    // emission was written straight into the form's data object — which form.component.ts processCall() posts\n    // wholesale. For a record whose projection omits the date key it MANUFACTURED \"someDate\": null on the\n    // request body, and the TinWeb present-set (e40be91) then honoured it as a deliberate clear and wrote NULL.\n    // Initialisation is not user intent: an untouched control must emit nothing at all.\n  }\n\n  // Added: `required` was accepted as an @Input and then never used anywhere in this component — the FormControl\n  // was built with NO validators at all (line above), the <input> carried no [required], and validate() had no\n  // required branch. A required date therefore rendered aria-required=\"false\" and ng-valid, with no asterisk and\n  // no mat-error, and the ONLY refusal came back from the API as the generic \"Something went wrong ... a technical\n  // problem in the app\" panel — the user was told the software had broken when they had simply left a box empty.\n  // Mirrors text.component.ts:81-108, readonly short-circuit included. Deliberately does NOT add min/max\n  // validators: [min]/[max] on the input already give matDatepickerMin/Max, which validate() already reports.\n  private applyValidators(): void {\n    if (!this.control) return; // ngOnChanges runs before ngOnInit on the first pass; initializeDateControls applies them itself\n\n    this.control.setValidators(this.readonly || !this.required ? null : [Validators.required]);\n    this.control.updateValueAndValidity({ emitEvent: false }); // emitEvent:false — an untouched control must emit nothing, see initializeDateControls\n  }\n\n  private updateControlState(): void {\n    if (this.readonly) {\n      this.control?.disable();\n    } else {\n      this.control?.enable();\n    }\n  }\n\n  onChangeEvent(): void {\n\n\n    const controlValue = this.control.value;\n    const formattedDate = controlValue ? Core.getFormatedDate2(controlValue, true) : null;\n    this.valueChange.emit(formattedDate);\n  }\n\n\n  // Added: the spa-suffix X was handed [clearContent] but no (clearClick) handler, so a click set the suffix's\n  // own dead `value` and never reached the form — a clear the user performed and the model never saw. The input\n  // is [readonly]=\"true\" and a picker cannot pick \"nothing\", so this button is the ONLY way to empty a date.\n  // Emits null, never '' — an explicit null is what says \"the user deliberately emptied this field\".\n  clear(): void {\n    this.control.setValue(null); // clears the visible picker; nothing subscribes to this control's valueChanges, so no re-entry\n    this.control.markAsDirty(); // Added: parity with text.component.ts:125-126 — emptying a required date must surface its mat-error immediately\n    this.control.markAsTouched();\n    this.value = null;\n    this.valueChange.emit(null);\n  }\n\n  onInputClick(picker: any): void {\n    if (!this.readonly) {\n      this.refreshBounds(); // Added (NFD-1): a dialog left open across midnight would otherwise still offer yesterday's \"today\"\n      picker.open();\n    }\n  }\n\n  // Added (NFD-1): re-resolves the bounds. Called on an @Input change and on picker open — deliberately NOT\n  // from a template-bound getter, which would allocate two Dates on every change-detection pass (the pattern\n  // banned after it caused a livelock).\n  // 🔴 Changed (SBD-1) — THIS METHOD USED TO SKIP A BOUND IT COULD NOT RESOLVE DYNAMICALLY, AND THAT WAS A BUG.\n  // It read:\n  //     if (DateBounds.isDynamic(this.min)) this.minDate.setValue(...)\n  // with no `else`. So a bound that changed to undefined, to null, or to a literal was NEVER WRITTEN, and the\n  // control went on enforcing the value resolved for the PREVIOUS state. MEASURED 2026-08-19 on piglet :4203, Add\n  // Pig: choosing Piglet set min = today-28 (22 Jul); switching to Sow — an open-ended stage whose min is\n  // undefined — left that 22 Jul min in place while max moved back to today-168 (4 Mar). min > max, an IMPOSSIBLE\n  // window, and EVERY date in EVERY month was greyed out. The same omission in the other direction is why a stage\n  // picked before its rules had loaded (bounds undefined) kept NO lower bound afterwards and went on offering\n  // dates six months back.\n  // Both bounds are now ALWAYS re-resolved, so the picker's window is a pure function of the CURRENT inputs and\n  // can never carry state forward from a bound that has since gone away. Cost is two Date allocations per open or\n  // per input change — deliberately not a template-bound getter, which would allocate on every change-detection\n  // pass (the pattern banned after it caused a livelock).\n  public refreshBounds(): void {\n    if (!this.minDate || !this.maxDate) return; // ngOnChanges runs before ngOnInit on the first pass; initializeDateControls resolves them itself\n\n    this.minDate.setValue(DateBounds.resolve(this.min, 'start', this.boundContext)); // resolves to null where there is no lower bound, which matDatepicker reads as unbounded\n    this.maxDate.setValue(DateBounds.resolve(this.max, 'end', this.boundContext));\n\n    this.control?.updateValueAndValidity({ emitEvent: false }); // re-run matDatepickerMin/Max against the new bounds; emitEvent:false — an untouched control must emit nothing\n  }\n\n  validate(control: FormControl): string {\n    // Added: there was no required branch, so even once the control went invalid the <mat-error> rendered an\n    // EMPTY string — an error box with nothing in it. Same wording as text.component.ts:155.\n    if (this.required && control.hasError('required')) {\n      return `Required`;\n    }\n    if (control.hasError('matDatepickerMin')) {\n      return `Earliest date is ${this.describeBound(this.minDate)}`; // Changed (SBD-1): prints the RESOLVED date. A token printed \"Minimum date is today-28\" and a function bound would have printed its source text\n    }\n    if (control.hasError('matDatepickerMax')) {\n      // Added (NFD-1): `max: 'today'` used to render the literal token back at the user as \"Maximum date is\n      // today\". This is the house wording for the no-future-dates rule, which is the overwhelming use of it.\n      if (DateBounds.isDynamic(this.max) && `${this.max}`.trim().toLowerCase() === 'today') return `Date cannot be in the future`;\n      return `Latest date is ${this.describeBound(this.maxDate)}`; // Changed (SBD-1): same reason as the min branch above\n    }\n    return \"\";\n  }\n\n  // Added (SBD-1): a bound is now printed as the date the user would have to pick, not as the expression that\n  // produced it. \"Earliest date is 22 Jul 2026\" is actionable; \"Minimum date is today-28\" and\n  // \"Minimum date is (row) => ...\" are not.\n  private describeBound(bound: FormControl): string {\n    const d: Date | null = bound?.value ?? null;\n    if (!d || isNaN(d.getTime())) return 'not set';\n    return d.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });\n  }\n}\n","<!-- Changed: Added mouse events for hover tracking, click handler for opening picker, and spa-suffix component -->\n<!-- Changed (placeholder conventions): floatLabel=\"always\" so the \"Pick X\" affordance is visible in the EMPTY state, which is the only state it is for. The floated label stays the clean label ({{display}}). -->\n<!-- Changed (2026-08-19, owner \"make sure you don't miss any\"): [hintLabel] was NEVER BOUND on this component,\n     so `@Input() hint` (date.component.ts:22) was a property that did nothing — a hint set on a date field\n     rendered no line at all. Found while sweeping every hint render site for the italic treatment: this one\n     had no render site to style. SIX date fields in the estate already set a hint and showed nothing —\n     piggery.service.ts:666 and :1000 (\"Leave blank if the birth date is not known\", both on the Add Pig and\n     Record Purchase forms), datalib.service.ts:718, payroll.service.ts:392 and :393. grip.service.ts:647 had\n     already DIAGNOSED this in a comment and worked around it by using infoMessage instead. Binding hintLabel\n     is the same idiom every sibling uses (text:2, number:2, money:3, text-area:2, text-mask:2), so the hint\n     now lands in the standard subscript and picks up the italic rule with everything else. -->\n<mat-form-field floatLabel=\"always\" [class.spa-readonly]=\"readonly\" [hideRequiredMarker]=\"!required\" [hintLabel]=\"hint\" [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\"><!-- Changed: [hideRequiredMarker] was absent, so a required date never showed the asterisk that text.component.html:2 has always shown -->\n  <mat-label>{{display}}</mat-label>\n  <input [formControl]=\"control\" [required]=\"required\" [min]=\"minDate.value\" [max]=\"maxDate.value\" matInput [matDatepicker]=\"picker_date\" (dateInput)=\"onChangeEvent()\" [placeholder]=\"computedPlaceholder\" [readonly]=\"true\" (click)=\"onInputClick(picker_date)\"><!-- Changed: [required] was never bound, so the input rendered aria-required=\"false\" on a field the form treated as mandatory -->\n  <mat-datepicker #picker_date></mat-datepicker><!-- Note (SBD-1): (opened)=\"refreshBounds()\" was tried here FIRST and MEASURED NOT TO FIRE — opening by the toggle icon called refreshBounds 0 times, opening by the input called it 1. The refresh is done on the toggle itself instead, below. -->\n  <mat-error *ngIf=\"control.invalid && (control.dirty || control.touched)\">{{validate(control)}}</mat-error><!-- Changed: gated on dirty/touched for parity with text.component.html:6 — an untouched field must not scold the user on open -->\n      <div matSuffix class=\"suffix-icons\">\n        <mat-datepicker-toggle [for]=\"picker_date\" (mousedown)=\"refreshBounds()\" (keydown)=\"refreshBounds()\"></mat-datepicker-toggle><!-- Added (SBD-1): THE CALENDAR ICON IS HOW PEOPLE ACTUALLY OPEN THIS, and it bypassed every refresh there was — onInputClick only fires for a click on the text box, and (opened) on the datepicker was measured not to fire at all. So a bound needing a re-read at open time (a function bound, or 'today' after midnight) was correct when opened one way and stale when opened the other. mousedown/keydown are used rather than click deliberately: BOTH FIRE BEFORE the activation that opens the picker, so the window is already correct when the calendar is built, instead of depending on an open calendar re-rendering when its bounds change underneath it. -->\n        <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix><!-- Changed: (clearClick) was missing, so the X wrote the suffix's own dead value and the clear never reached the form -->\n      </div>\n</mat-form-field>\n","import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'; // Changed: ViewChild — the \"add new\" restore has to be written onto MatSelect itself (see changed())\nimport { MatSelect } from '@angular/material/select'; // Added: direct handle on the control, so restoring the previous value does not depend on a binding that Angular sees as unchanged\nimport { MessageService } from '../../services/message.service';\nimport { Action, ApiResponse, Field } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: routes a failed loadAction through the shared classify + dedupe path (WS-6 Phase 3)\nimport { OfflineService } from '../../services/offline.service'; // Added (WS-1 Phase 3): read-only — the component asks whether the network is down so a failed option load can say so on the field instead of toasting\nimport { BehaviorSubject, Subscription } from 'rxjs';\nimport { finalize } from 'rxjs/operators'; // Added: settle the load indicator on success AND error\nimport { FieldLoadIndicator } from '../../runtime/field-load-indicator'; // Added: shared spinning-refresh state for loadAction fields\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-select-common',\n    templateUrl: './select-common.component.html',\n    styleUrls: ['./select-common.component.css'],\n    standalone: false\n})\nexport class SelectCommonComponent implements OnInit, OnDestroy {\n\n  constructor(protected messageService: MessageService, protected dataService: DataServiceLib, private apiErrorService: ApiErrorService, private offline: OfflineService) { } // Changed: injected ApiErrorService so a failed option load is no longer silent; injected OfflineService (root-provided, already a DataServiceLib dependency so no new graph) to tell an offline cache miss from a server failure\n\n  ngOnInit(): void {\n\n    // Changed: the \"Select {display}\" default moved OUT of ngOnInit into computedPlaceholder below. Mutating\n    // the @Input here froze the derivation at init (a later [display] change never reached it) and made an\n    // explicit override indistinguishable from a derived one. The getter keeps @Input placeholder pristine.\n\n    // Changed: deferred by one microtask, the same treatment ngOnChanges and the optionsSubject subscription\n    // already get, and for the same reason. This select's ngOnInit runs INSIDE the parent form's\n    // change-detection pass; when the options are already present, setDefaultValue() picks a value and emits\n    // valueChange from here, the form writes data[field.name] and recomputes its visible fields, and the\n    // Create User dialog's list grew 6 -> 8 after the form's *ngFor had been checked — NG0100 on every open.\n    // Deferring lets the default land before the next pass instead of mutating the parent mid-check.\n    Promise.resolve().then(() => { if (!this.destroyed) this.setDefaultValue(); });\n\n    if (this.field?.optionsSubject) {\n      this.subscription = this.field.optionsSubject.subscribe(newOptions => {\n        if (newOptions) {\n          this.options = newOptions;\n          // Changed: deferred by one microtask, for exactly the reason ngOnChanges already defers (see the\n          // comment there). optionsSubject is a BehaviorSubject, so subscribing REPLAYS the current options\n          // synchronously — inside this select's ngOnInit, which runs inside the PARENT form's change-detection\n          // pass. setDefaultValue() emits valueChange, the form writes data[field.name] and recomputes its\n          // visible fields, and on the Create User dialog that grew the list from 6 fields to 8 AFTER the\n          // form's *ngFor had already been checked: NG0100 on every open. Deferring lets the default land\n          // before the next pass instead of mutating the parent mid-check. Not a detectChanges band-aid — the\n          // write simply stops happening inside a pass that has already read it.\n          Promise.resolve().then(() => {\n            if (this.destroyed) return;\n            this.setDefaultValue();\n            this.updateSelectedOptionHint();\n          });\n        }\n      });\n    }\n  }\n\n  ngOnChanges() {\n\n    // Added (dropdown quick-add): keep the restore point in sync with parent-driven value changes\n    if (this.value !== this.ADD_NEW_OPTION) this.previousValue = this.value;\n\n    // Added: defaultFirstValue was inert on every select that names a masterField. setDefaultValue() has only\n    // two entry points — ngOnInit (options are still empty then) and the field.optionsSubject subscription —\n    // and form.component.ts only creates an optionsSubject for fields WITHOUT a masterField, so a child field\n    // has no second entry point at all. Its options arrive later, as a plain [options] input mutation from\n    // updateChildOptions(), which lands here in ngOnChanges and nowhere else. Reproduced on shift-spa's driver\n    // create dialog: Department self-selected, Position stayed empty with exactly one option in its list.\n    // Deliberately scoped to masterField selects: every other select already gets its default through one of\n    // the two existing entry points, so nothing else's timing moves.\n    // Corrected: the claim that used to sit here — \"setDefaultValue() still declines when a value is already\n    // set, so this can only fill a blank, never overwrite a choice\" — was FALSE, and it is what justified\n    // widening this feature's blast radius. setDefaultValue() declined only when the value was already set AND\n    // that value was found in the loaded options; a stored value MISSING from the list fell straight through to\n    // the defaults and was silently replaced (a stored 99 posted as 11, with nothing on screen saying so). The\n    // guard has since been made unconditional, so the sentence is true NOW — but it was not true when written,\n    // and it is a property of setDefaultValue(), not of this block. Do not restore the original wording.\n    // Deferred by one microtask on purpose: setDefaultValue() emits valueChange, and emitting from inside\n    // ngOnChanges writes the parent's data[field.name] after the parent's bindings were already checked, which\n    // is NG0100 — the same shape spa-select-multi's selectAll had. The microtask runs once the pass has\n    // finished, so the new value is picked up by the next one instead of invalidating this one.\n    if (this.masterField && this.options !== this.defaultedOptions) {\n      this.defaultedOptions = this.options;\n      Promise.resolve().then(() => { if (!this.destroyed) this.setDefaultValue(); });\n    }\n\n    if (this.readonlyMode != \"\" && this.options && this.options.length > 0) { // Changed: null-check options — the length read itself threw before the index ever ran\n      // Changed: guarded the index. filter() yields [] whenever the stored value is not in the loaded options,\n      // and [0][...] then threw on undefined, taking the whole readonly render down with it. Falls back to the\n      // raw stored value so an unmatched entry is still SHOWN rather than crashed or silently blanked.\n      const matchedOption = this.options.filter((m) => m[`${this.optionValue}`] == this.value)[0];\n      this.displayValue = matchedOption ? matchedOption[`${this.optionDisplay}`] : this.value;\n    }\n\n    //add a null option\n    if (this.nullable && this.options && this.options.length > 0 && this.options[0][this.optionValue] != null) {\n      this.options.unshift({ [this.optionValue]: null, [this.optionDisplay]: \"None\" })\n    }\n\n    this.updateSelectedOptionHint();\n  }\n\n  displayValue;\n  isHovered = false;\n  selectedOptionHint = \"\";\n\n  // Added (WS-1 Phase 3, offline forms): true when this select's options could not be resolved because there is\n  // no connection AND nothing was cached for its url. It exists because the two states looked IDENTICAL on\n  // screen — an empty dropdown offline and a dropdown over an empty list render exactly the same control, and\n  // the only difference was a 5-second toast that (a) is deduped across the whole form, so one message covered\n  // however many selects failed, and (b) never says WHICH field is the one you cannot fill in. On a required\n  // select that is not a degraded form, it is an unsubmittable one, and the user is given nothing to act on.\n  // See computedHint below for what is shown instead.\n  // @Input because spa-select and spa-select-lite WRAP this component rather than only extending it: the wrapper owns\n  // the loadAction and does the fetch (its own overridden ngOnInit calls getData), while this inner instance is\n  // the one that renders the mat-form-field. Without the binding the flag is set on the component that knows and\n  // read by the component that draws, and nothing appears — observed exactly that way before it was bound.\n  @Input() optionsUnavailableOffline = false;\n\n  // Added: drives the suffix refresh icon — held visible and spinning while the loadAction is in flight\n  readonly loadIndicator = new FieldLoadIndicator();\n\n  // Added (dropdown quick-add): sentinel value for the always-first \"add new\" option — never a real option value\n  readonly ADD_NEW_OPTION = \"__spa_add_new__\";\n  // Added: restore point so picking the \"add new\" option never leaves the sentinel as the selection\n  private previousValue;\n\n  // Added: the options array the master-driven default was last evaluated against. updateChildOptions() hands\n  // out a NEW filtered array each time, so an identity check is enough to tell a real option change from the\n  // many other input changes that also fire ngOnChanges — without it the default would re-run every cycle.\n  private defaultedOptions: any;\n\n  // Added: the deferred default must not fire into a torn-down field (a dialog closed while its options were\n  // still settling would otherwise write onto data nobody is showing any more)\n  private destroyed = false;\n\n  // Added: the control itself. Undefined while readonlyMode is set (the mat-form-field is *ngIf'd away), which\n  // is fine — the \"add new\" option only exists inside that form field.\n  @ViewChild(MatSelect) private matSelect: MatSelect;\n\n  private subscription: Subscription;\n\n  @Input() width = \"100%\"\n  @Input() readonly = false;\n  @Input() required = true;\n  @Input() defaultFirstValue = false;\n  @Input() readonlyMode = \"\";\n  @Input() hint = \"\";\n  @Input() placeholder = \"\";\n\n  // Added: the resting affordance for a PLAIN select — \"Select Source\". Derived from the display label so every\n  // select in every consumer app inherits it with no config edit; an explicit [placeholder] still wins outright.\n  get computedPlaceholder(): string { return derivePlaceholder('select', this.display, this.placeholder, this.readonly); }\n  // Removed: multiple property - use spa-multi-select component for multiple selections\n\n  @Input() display = \"\";\n  @Input() value;\n  @Input() options: any;\n  @Input() masterOptions: any;\n  @Input() masterField: string;\n  @Input() optionValue = \"\";\n  @Input() optionDisplay = \"\";\n  @Input() optionDisplayExtra = \"\";\n  @Input() nullable = false;\n\n  @Input() infoMessage: string;\n  @Input() copyContent = false;\n  @Input() loadAction: Action;\n  @Input() loadIDField: string;\n  @Input() field: Field;\n  @Input() data: any;\n  @Input() addOptionLabel: string; // Added (dropdown quick-add): when set, renders an always-first \"add new\" option in the panel\n\n  @Output() valueChange = new EventEmitter();\n  @Output() hoverChange = new EventEmitter<boolean>();\n  @Output() addNew = new EventEmitter<void>(); // Added (dropdown quick-add): fired when the \"add new\" option is picked\n\n  setDefaultValue() {\n    // Guard: Need options to set any default\n    if (!this.options || this.options.length === 0) {\n      return;\n    }\n\n    // Guard: Check if value is already meaningfully set\n    const hasValue = this.value != null &&\n                     this.value !== undefined &&\n                     !(typeof this.value === 'string' && this.value === '') &&\n                     !(typeof this.value === 'number' && this.value === 0 && !this.nullable);\n\n    // Changed: return UNCONDITIONALLY when a value is already set. This block used to verify the value against\n    // the loaded options and FALL THROUGH when it was not found, which handed the stored value straight to the\n    // defaulting code below and silently REPLACED it: observed running, a stored 99 became 11, the request body\n    // carried 11, the screen showed the substituted label, and the user had no way to know the value was ever 99.\n    // A value that is absent from the list is a LIST problem (a filtered, scoped or stale lookup) — never a\n    // licence to rewrite the stored record. The old `valueExists` probe is deleted rather than kept and ignored,\n    // because there is nothing left to decide: set means keep.\n    // Filling a BLANK is deliberately UNCHANGED and remains the settled behaviour every defaultFirstValue and\n    // field.defaultValue site depends on — hasValue is false for null, undefined, '' and (non-nullable) 0, so a\n    // blank field still falls through to Priority 1 / Priority 2 below exactly as it did before.\n    if (hasValue) {\n      return;\n    }\n\n    // Priority 1: Use field.defaultValue if configured\n    const defaultVal = this.field?.defaultValue;\n    if (defaultVal != null && defaultVal !== undefined) {\n      const matchingOption = this.options.find(opt =>\n        this.compareValues(opt[this.optionValue], defaultVal)\n      );\n\n      if (matchingOption) {\n        this.value = matchingOption[this.optionValue];\n        this.changed();\n        return;\n      }\n    }\n\n    // Priority 2: Use defaultFirstValue if configured\n    if (this.defaultFirstValue) {\n      this.value = this.options[0][this.optionValue];\n      this.changed();\n    }\n  }\n\n  // Changed: Added helper method for type-coerced value comparison (handles number vs string)\n  private compareValues(optionValue: any, targetValue: any): boolean {\n    if (optionValue === targetValue) return true;\n    if (optionValue == null || targetValue == null) return false;\n    return String(optionValue) === String(targetValue);\n  }\n\n  changed() {\n    // Added (dropdown quick-add): the \"add new\" option is a command, not a selection — restore the\n    // previous value and hand off to the host's create dialog instead of emitting a change\n    if (this.value === this.ADD_NEW_OPTION) {\n      const restore = this.previousValue !== undefined ? this.previousValue : null;\n      this.value = restore;\n      // Changed: writing the field alone was not enough and this is why the command stayed selected. mat-select\n      // set this.value through the (valueChange) half of [(value)] — Angular's [value] binding slot still holds\n      // the PREVIOUS value, so restoring the field makes the binding compare equal, the setter is never called,\n      // and the control keeps rendering \"New <Entity>\" as the selection. Writing MatSelect.value directly runs\n      // its own _setSelectionByValue and cannot be skipped by a no-change comparison. It emits nothing, so no loop.\n      if (this.matSelect) this.matSelect.value = restore;\n      this.addNew.emit();\n      return;\n    }\n    this.previousValue = this.value; // Added: remember the last real selection for the restore above\n\n    this.valueChange.emit(this.value);\n    this.updateSelectedOptionHint();\n\n    // Added: Call onSelectChange callback if provided\n    if (this.field?.onSelectChange && this.data) {\n      const selectedOption = this.options?.find(opt => opt[this.optionValue] === this.value);\n      this.field.onSelectChange(this.value, this.data, selectedOption, (this.field as any).formConfig); // Changed (addpig-label-leak): forward the LIVE FormConfig spa-form stamped on the field. A select fires this hook from HERE as well as from form.component.selectChanged, so patching only that one left every select still handing its handler `undefined` — which fell back to the app's singleton and kept the leak alive for stage/pen/quantity pickers\n    }\n  }\n\n  private updateSelectedOptionHint(): void {\n    if (!this.options || this.options.length === 0 || this.value == null || this.value == undefined) {\n      this.selectedOptionHint = this.hint; // Fall back to component hint\n      return;\n    }\n\n    const selectedOption = this.options.find(option => \n      option[this.optionValue] === this.value\n    );\n\n    if (selectedOption && selectedOption.hint) {\n      this.selectedOptionHint = selectedOption.hint; // Use option hint\n    } else {\n      this.selectedOptionHint = this.hint; // Fall back to component hint\n    }\n  }\n\n  // Changed (WS-1 Phase 3): the offline-unavailable state OUTRANKS both hints. It is the only one of the three\n  // that tells the user the control in front of them cannot do its job; a selected-option hint describes a\n  // choice that, in this state, could not be made. Deliberately reuses the mat-form-field hint surface that is\n  // already bound here rather than adding a new one: the field already renders `subscriptSizing=\"dynamic\"`, so\n  // the line appears and disappears without moving the form, and no new component, layout or copy surface\n  // enters the library for a state that is meant to be rare.\n  // Added (WS-1): a master/child dependent select NEVER fetches its own options — getData() returns early when\n  // masterField is set, so form.component.ts's loadChildMasterOptions is its only fetch. That component cannot\n  // reach this one, so it marks the FIELD (the same channel it already writes masterOptions on) and this getter\n  // folds the two sources into the single condition the hint, the class and the cloud_off icon all read.\n  // Allocates nothing — a boolean OR, safe for the template to bind every change-detection pass.\n  get offlineUnavailable(): boolean {\n    return this.optionsUnavailableOffline || this.field?.optionsUnavailableOffline === true;\n  }\n\n  get computedHint(): string {\n    if (this.offlineUnavailable) return \"No connection — this list wasn't saved for offline use\"; // Changed (WS-1): reads the folded condition so a DEPENDENT select, marked by the form, says the same thing\n    return this.selectedOptionHint || this.hint;\n  }\n\n  onMouseEnter(): void {\n    this.isHovered = true;\n    this.hoverChange.emit(true);\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n    this.hoverChange.emit(false);\n  }\n\n  refresh(event: MouseEvent): void {\n    console.log(\"refresh clicked\")\n    event?.stopPropagation(); // Changed: tolerate a null event — the dropdown \"add new\" flow refreshes without a mouse event\n    if (!this.loadAction) {\n      return;\n    }\n\n    const refreshAction : Action = {\n      ...this.loadAction,\n      skipCache: true\n    };\n\n    this.getData(refreshAction);\n  }\n\n  private transformLoadUrl(action: Action): Action {\n    if (!action?.url || !this.data) return action;\n\n    // Changed: Check if URL contains {propertyName} placeholders first\n    if (action.url.includes('{')) {\n      const transformedUrl = action.url.replace(/\\{(\\w+)\\}/g, (match, propName) => {\n        const value = this.data?.[propName];\n        return value !== undefined && value !== null ? String(value) : match;\n      });\n      return { ...action, url: transformedUrl };\n    }\n\n    // Changed: Fallback to existing loadIDField pattern for backward compatibility\n    if (!this.loadIDField) return action;\n    const idValue = this.data[this.loadIDField];\n    if (!idValue) return action;\n\n    const urlParts = action.url.split('/');\n    return {\n      ...action,\n      url: `${urlParts[0]}/${urlParts[1]}/${idValue}`\n    };\n  }\n\n  getData(loadAction: Action) {\n\n    if (!loadAction) return;\n    if (this.masterField) return;\n\n    const transformedAction = this.transformLoadUrl(loadAction);\n\n    // Changed: a URL still holding an unresolved {placeholder} has no id to fetch against. Sending it asks\n    // the server for the literal string, which 400s and pops an error dialog over the form the operator is\n    // filling in. Wait for the parent field to be set - ngOnChanges re-fetches once the URL resolves.\n    // Same rule the tab-count badges already follow, and for the same reason.\n    if (transformedAction?.url?.includes('{')) return;\n\n    this.loadIndicator.begin(); // Added: arm the spinning refresh icon (only paints if the read outlives the anti-flicker delay)\n\n    this.dataService.CallApi(transformedAction, \"\").pipe(\n      finalize(() => this.loadIndicator.settle()) // Added: stop the spin whether the read succeeded or failed\n    ).subscribe({\n      next: (apiResponse: ApiResponse) => {\n      if (apiResponse.success) {\n        this.optionsUnavailableOffline = false; // Added: a later successful load clears the offline notice (reconnect, or the manual refresh icon)\n        // Always update options when new data arrives\n        this.options = apiResponse.data;\n\n        if (this.field) {\n          this.field.options = apiResponse.data;\n\n          this.setDefaultValue();\n\n          if (!this.field.optionsSubject) {\n            this.field.optionsSubject = new BehaviorSubject(apiResponse.data);\n          } else {\n            this.field.optionsSubject.next(apiResponse.data);\n          }\n        }\n        \n        this.updateSelectedOptionHint();\n      } else if (this.isOfflineCacheMiss()) {\n        // Added (WS-1 Phase 3): the offline read seam answers a cache miss with HTTP-200 `success:false` and the\n        // message 'No offline data available yet for this view' (offline.service.ts serveCachedRead), which\n        // classifyMessage correctly reads as a business message and toasts. That is the WRONG surface for this\n        // one case: the failure is not the server's, it is per-FIELD, and the toast is deduped across the form\n        // so several dead selects speak once and namelessly. Mark the field instead — the notice then sits on\n        // the control it is about, for as long as it is true, and every affected select carries its own.\n        this.markOptionsUnavailableOffline();\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'load', transformedAction.url); // Added: was a silent no-op — a dropdown that failed to load looked identical to a dropdown with no options; 'load' dedupes with the page's other loads so a broken backend yields one dialog\n      }\n      },\n      // Added (WS-1 Phase 3): the OTHER offline shape. A lookup url the registry never matched does not reach\n      // the read seam at all — it goes to the wire and dies as status 0. The interceptor has already spoken for\n      // that (loader-interceptor.service.ts:110-112 shows the connection dialog for exactly the urls the offline\n      // layer does NOT suppress), so this adds no second message; it only marks the field, so once the dialog is\n      // dismissed the form still says which selects are empty and why. Non-network errors keep their previous\n      // behaviour to the letter — there was no error callback before, so they are logged and go no further.\n      error: (err: any) => {\n        if (err?.status === 0) { this.markOptionsUnavailableOffline(); return; }\n        console.error('[tin-spa] select loadAction failed', { url: transformedAction.url, err });\n      }\n    });\n  }\n\n  // Added: a cache miss served by the offline layer arrives as success:false with a network we know is down.\n  // Both halves are required — `online === false` alone would claim any 200-level failure was an offline one.\n  private isOfflineCacheMiss(): boolean {\n    return !!this.offline && this.offline.enabled && !this.offline.online;\n  }\n\n  private markOptionsUnavailableOffline(): void {\n    this.optionsUnavailableOffline = true;\n    this.updateSelectedOptionHint(); // keeps selectedOptionHint honest; computedHint outranks it while this flag is set\n  }\n\n  ngOnDestroy() {\n    this.destroyed = true; // Added: cancels a master-driven default still queued on the microtask queue\n    if (this.subscription) {\n      this.subscription.unsubscribe();\n    }\n    this.loadIndicator.destroy(); // Added: clear any pending delay/hold timer on a field torn down mid-read\n  }\n}","<!-- Changed (WS-1 Phase 3): one class, no structural change — it tints the hint line the field already renders. See the .css for why the state is spoken on the field rather than in a toast. -->\n<mat-form-field *ngIf=\"readonlyMode==''\" floatLabel=\"always\" [hintLabel]=\"computedHint\" [class.spa-options-unavailable]=\"offlineUnavailable\" [ngStyle]=\"{'width':width ?? '100%'}\" [hideRequiredMarker]=\"false\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n\n  <mat-label>{{display}}</mat-label>\n  <!-- Removed: [multiple]=\"multiple\" binding - component now only supports single selection -->\n  <mat-select [(value)]=\"value\" (selectionChange)=\"changed()\" [disabled]=\"readonly\" [placeholder]=\"computedPlaceholder\" [required]=\"required\">\n    <!-- Added (dropdown quick-add): always-first create option — shown even when the list is empty; picking it opens the create dialog -->\n    <mat-option *ngIf=\"addOptionLabel\" [value]=\"ADD_NEW_OPTION\" class=\"spa-add-new-option\">\n      <mat-icon class=\"tinyIcon spa-add-new-icon\">add</mat-icon>{{addOptionLabel}}\n    </mat-option>\n    <mat-option *ngFor=\"let row of options\" [value]=\"row[optionValue]\">\n      {{row[optionDisplay]}} <label *ngIf=\"optionDisplayExtra!='' && row[optionDisplayExtra] && row[optionDisplayExtra] != ''\">({{row[optionDisplayExtra]}})</label>\n    </mat-option>\n  </mat-select>\n\n  <div matSuffix class=\"suffix-icons\">\n    <ng-content select=\"[additionalButtons]\"></ng-content>\n    <!-- Changed: the icon now also shows while loading (not hover-only), and spins — same .tin-spin idiom as the table/filter refresh button -->\n    <!-- Added (WS-1 Phase 3): the house's own offline mark, the same cloud_off spa-offline-indicator uses, so the state is recognisable without reading — which is what carries it at phone width, where the hint line has least room. The refresh button is left exactly as it was and stays reachable on purpose: it is the one action that fixes this once the connection is back, and getData() clears the flag on the first successful load. -->\n    <mat-icon *ngIf=\"offlineUnavailable\" class=\"tinyIcon spa-options-unavailable-icon\" [matTooltip]=\"computedHint\" matTooltipPosition=\"above\">cloud_off</mat-icon>\n    <button mat-icon-button *ngIf=\"loadAction && (isHovered || loadIndicator.spinning) && !masterField\" (click)=\"refresh($event)\" [matTooltip]=\"loadIndicator.spinning ? 'Loading' : 'Refresh'\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" [class.tin-spin]=\"loadIndicator.spinning\" color=\"primary\">cached</mat-icon>\n    </button>\n    <spa-suffix [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\n  </div>\n\n</mat-form-field>\n","import { Component, OnInit } from '@angular/core';\nimport { SelectCommonComponent } from '../select-common/select-common.component';\n\n@Component({\n    selector: 'spa-select-lite',\n    templateUrl: './select-lite.component.html',\n    styleUrls: ['./select-lite.component.css'],\n    standalone: false\n})\nexport class SelectLiteComponent extends SelectCommonComponent implements OnInit {\n\n  override ngOnInit(): void {\n\n    // Always load data if loadAction is provided to ensure fresh data after cache expiration\n    if (this.loadAction) {\n      this.getData(this.loadAction);\n    }\n\n  }\n\n}\n","<spa-select-common [width]=\"width\" [readonly]=\"readonly\" [required]=\"required\" [defaultFirstValue]=\"defaultFirstValue\"\n                   [readonlyMode]=\"readonlyMode\" [hint]=\"hint\" [placeholder]=\"placeholder\"\n                   [display]=\"display\" [(value)]=\"value\" [options]=\"options\" [masterOptions]=\"masterOptions\" [masterField]=\"masterField\"\n                   [optionValue]=\"optionValue\" [optionDisplay]=\"optionDisplay\" [optionDisplayExtra]=\"optionDisplayExtra\"\n                   [nullable]=\"nullable\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [optionsUnavailableOffline]=\"optionsUnavailableOffline\" [loadAction]=\"loadAction\" [loadIDField]=\"loadIDField\" [field]=\"field\" [data]=\"data\"\n                   (valueChange)=\"valueChange.emit($event)\">\n</spa-select-common>\n","import { Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'; // Changed: OnDestroy to release the load indicator's timers\nimport { FormControl } from '@angular/forms';\nimport { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';\nimport { MatChipInputEvent } from '@angular/material/chips';\nimport { Observable } from 'rxjs';\nimport { finalize, map, startWith } from 'rxjs/operators'; // Changed: Added finalize to settle the load indicator on success AND error\nimport { FieldLoadIndicator } from '../../runtime/field-load-indicator'; // Added: shared spinning-refresh state for loadAction fields\nimport { MessageService } from '../../services/message.service';\nimport { Action, ApiResponse } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Added: Core.parseMultiValue — the shared multi-value contract this component's private copy became\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: routes a failed loadAction through the shared classify + dedupe path (WS-6 Phase 3)\nimport { OfflineService } from '../../services/offline.service'; // Added (WS-1 Phase 3): read-only — the component asks whether the network is down so a failed option load can say so on the field instead of toasting\n\n@Component({\n    selector: 'spa-text-multi',\n    templateUrl: './text-multi.component.html',\n    // Changed (WS-1 Phase 3): styleUrls added. The .css file already existed but was EMPTY and was never referenced\n    // by this decorator, so the component had no styles of its own at all — unlike its two siblings, both of which\n    // already declared theirs. Wiring it cannot regress anything (there was nothing in the file to start applying),\n    // and it is what lets the offline state be tinted here with the SAME rule the siblings use rather than by\n    // reaching into a shared global stylesheet for a one-control concern.\n    styleUrls: ['./text-multi.component.css'],\n    standalone: false\n})\nexport class TextMultiComponent implements OnInit, OnDestroy { // Changed: OnDestroy\n  constructor(private messageService: MessageService, private dataService: DataServiceLib, private apiErrorService: ApiErrorService, private offline: OfflineService) { } // Changed: injected ApiErrorService so a failed option load is no longer silent; added OfflineService (WS-1 Phase 3) — root-provided and already a DataServiceLib dependency, so no new graph — used only to tell an offline cache miss from a server failure\n\n  @ViewChild('textInput') textInput: ElementRef<HTMLInputElement>;\n\n  @Input() display = \"\";\n  @Input() placeholder = \"\"; // Added: this component had no placeholder input at all — the template repeated the label instead\n  // Added: derived resting placeholder. A chip field with an autocomplete list is BOTH typeable and pickable, so it\n  // takes the same \"Enter or select\" verb as a spa-text-single with options. The template previously bound the raw\n  // display here, which just repeated the label back and told the user nothing about what the control accepts.\n  get computedPlaceholder(): string { return derivePlaceholder('enter-or-select', this.display, this.placeholder, this.readonly); }\n  @Input() value = \"\";\n  @Output() valueChange = new EventEmitter<string>();\n  @Input() readonly = false;\n  @Input() required = true;\n  @Input() hint = \"\";\n  @Input() strict = false;\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n  @Input() options: any[] = [];\n  @Input() optionDisplay = \"name\"; // Default to name if not provided\n  @Input() optionValue = \"value\"; // Default to value if not provided\n\n  @Input() loadAction: Action;\n\n  values: string[] = [];\n  control = new FormControl('');\n  filteredOptions: Observable<any[]>;\n  errorState = false;\n  private selectedFromAutocomplete = false;\n\n  ngOnInit() {\n    // Changed: the private toValueList is gone — it was a hand-kept COPY of SelectMultiComponent's, held in sync\n    // by a comment asking the next reader not to let them drift. Core.parseMultiValue is that shared body, so\n    // the two components cannot drift by construction rather than by request. Behaviour is unchanged.\n    this.values = Core.parseMultiValue(this.value);\n    this.setupAutoComplete();\n    this.getData(this.loadAction);\n  }\n\n  ngOnChanges() {\n    if (this.options) {\n      this.setupAutoComplete();\n    }\n  }\n\n  private setupAutoComplete() {\n    this.filteredOptions = this.control.valueChanges.pipe(\n      startWith(''),\n      map(value => this.filterOptions(value))\n    );\n  }\n\n  private filterOptions(value: string): any[] {\n    if (!value || !this.options) return this.options || [];\n\n    const searchValue = value.toString().toLowerCase();\n    return this.options.filter(option => {\n      const displayValue = option[this.optionDisplay]?.toString().toLowerCase();\n      return displayValue?.includes(searchValue);\n    });\n  }\n\n  add(event: MatChipInputEvent): void {\n    // Skip validation if option was selected from autocomplete\n    if (this.selectedFromAutocomplete) {\n      this.selectedFromAutocomplete = false;\n      return;\n    }\n\n    const input = (event.value || '').trim();\n    if (!input) return;\n\n    if (this.strict) {\n      const found = this.options.find(opt => {\n        const optionDisplayValue = opt[this.optionDisplay]?.toString().toLowerCase();\n        const optionValue = opt[this.optionValue]?.toString().toLowerCase();\n        const inputLower = input.toLowerCase();\n        return optionDisplayValue === inputLower || optionValue === inputLower;\n      });\n\n      // if (!found) {\n      //   this.errorState = true;\n      //   this.hint = 'Value must be selected from the list';\n      //   return;\n      // }\n\n      this.addValue(found[this.optionValue]?.toString());\n    } else {\n      this.addValue(input);\n    }\n\n    this.resetInput();\n  }\n\n  private addValue(value: string): void {\n    if (!this.values.includes(value)) {\n      this.values.push(value);\n      this.errorState = false;\n      this.updateValue();\n    }\n  }\n\n  remove(value: string): void {\n    const index = this.values.indexOf(value);\n    if (index >= 0) {\n      this.values.splice(index, 1);\n      this.updateValue();\n    }\n  }\n\n  optionSelected(event: MatAutocompleteSelectedEvent): void {\n    const selectedOption = event.option.value;\n    if (selectedOption) {\n      this.selectedFromAutocomplete = true;\n      this.addValue(selectedOption[this.optionValue]?.toString());\n      this.resetInput();\n    }\n  }\n\n\n  private resetInput(): void {\n    // Reset form control\n    this.control.setValue('');\n\n    // Reset input element if available\n    if (this.textInput?.nativeElement) {\n      this.textInput.nativeElement.value = '';\n    }\n  }\n\n  updateValue(): void {\n    this.value = this.values.join(';');\n    this.valueChange.emit(this.value);\n  }\n\n  clear(): void {\n    this.values = [];\n    this.updateValue();\n  }\n\n  getDisplayValue(value: string): string {\n    const option = this.options?.find(opt =>\n      opt[this.optionValue]?.toString() === value\n    );\n    return option ? option[this.optionDisplay]?.toString() : value;\n  }\n\n  copyValues(): void {\n    navigator.clipboard.writeText(this.value).then(() => {\n      this.messageService.toast('Copied');\n    });\n  }\n\n  isHovered = false;\n\n  // Added (WS-1 Phase 3, offline forms): true when this chip autocomplete's options could not be resolved because\n  // there is no connection AND nothing was cached for its url. Identical in cause and in treatment to\n  // spa-select-common's and spa-text-single's flag of the same name — deliberately the SAME state, the SAME\n  // sentence and the SAME mark, because two different messages for one condition is worse than one imperfect\n  // message. This is the last of the three controls named in the family and it completes it.\n  // The failure shape here is the chip variant of text-single's, and just as deceptive: with no options the field\n  // still looks and types like a working chip input, but the autocomplete panel is empty, so `optionSelected()`\n  // never fires. In STRICT mode that is not merely unhelpful, it THROWS — add() looks the typed text up in\n  // this.options, the guard that used to catch a miss is commented out (see add() above), and `found` is undefined\n  // when it reaches found[this.optionValue]. So offline, a strict text-multi does not just fail to add a chip, it\n  // dies on the keystroke. Non-strict, the typed text is silently kept as a raw value that matches no option, and\n  // getDisplayValue() then echoes the raw value back because it can find no option to name it.\n  // NOT an @Input, unlike the select: nothing wraps spa-text-multi. It is declared and exported by tin-spa.module\n  // and rendered directly by form.component.html (which alone binds [loadAction]) and option.component.html, there\n  // is no subclass of TextMultiComponent, and the instance that fetches is the instance that draws. The select\n  // needed the binding only because spa-select/spa-select-lite WRAP spa-select-common as well as extending it.\n  optionsUnavailableOffline = false;\n\n  // Added (WS-1 Phase 3): the offline-unavailable notice OUTRANKS the configured hint — it is the one of the two\n  // that says the control in front of you cannot do its job. Reuses the mat-hint line this template ALREADY\n  // renders, and the field already sets subscriptSizing=\"dynamic\", so the line appears and disappears without\n  // moving the form. No new component, layout or copy surface enters the library. The sentence is character for\n  // character the siblings' — it is not re-worded here, on purpose.\n  get computedHint(): string {\n    if (this.optionsUnavailableOffline) return \"No connection — this list wasn't saved for offline use\";\n    return this.hint;\n  }\n\n  // Added: drives the suffix refresh icon — held visible and spinning while the loadAction is in flight\n  readonly loadIndicator = new FieldLoadIndicator();\n  @Output() hoverChange = new EventEmitter<boolean>();\n  onMouseEnter(): void {\n    this.isHovered = true;\n    this.hoverChange.emit(true);\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n    this.hoverChange.emit(false);\n  }\n\n  refresh(event: MouseEvent): void {\n    event.stopPropagation();\n    if (!this.loadAction) {\n      return;\n    }\n\n    const refreshAction = {\n      ...this.loadAction,\n      forceRefresh: true\n    };\n\n    this.getData(refreshAction);\n  }\n\n  getData(action: Action) {\n    if (!action) return;\n\n    this.loadIndicator.begin(); // Added: arm the spinning refresh icon (only paints if the read outlives the anti-flicker delay)\n\n    this.dataService.CallApi(action).pipe(\n      finalize(() => this.loadIndicator.settle()) // Added: stop the spin whether the read succeeded or failed\n    ).subscribe({\n      next: (apiResponse: ApiResponse) => {\n        if (apiResponse.success) {\n          this.optionsUnavailableOffline = false; // Added: a later successful load clears the offline notice (reconnect, or the manual refresh icon)\n          this.options = apiResponse.data;\n          this.setupAutoComplete();\n        } else if (this.isOfflineCacheMiss()) {\n          // Added (WS-1 Phase 3): the offline read seam answers a cache miss with HTTP-200 `success:false` and the\n          // message 'No offline data available yet for this view' (offline.service.ts serveCachedRead), which\n          // classifyMessage correctly reads as a business message and toasts. That is the WRONG surface for this\n          // one case: the failure is not the server's, it is per-FIELD, and the toast is deduped across the form\n          // so several dead lookups speak once and namelessly. Mark the field instead.\n          // This url reaches the seam on the same terms as its siblings': registerLookups walks `formConfig.fields`\n          // and registers any `field.loadAction.url` with no reference to the field's TYPE, so a `text-multi`\n          // lookup is registered exactly as a `select` or `text-single` one would be.\n          this.markOptionsUnavailableOffline();\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Added: was a silent no-op — a chip autocomplete that failed to load looked identical to one with no options; 'load' dedupes with the page's other loads\n        }\n      },\n      // Added (WS-1 Phase 3): the OTHER offline shape, and the one this control actually meets today. A lookup url\n      // the registry never matched does not reach the read seam at all — it goes to the wire and dies as status 0.\n      // The interceptor has already spoken for that (loader-interceptor.service.ts shows the connection dialog for\n      // exactly the urls the offline layer does NOT suppress), so this adds no second message; it only marks the\n      // field, so once the dialog is dismissed the form still says which lookups are empty and why. Non-network\n      // errors keep their previous behaviour to the letter — there was no error callback here at all before, so\n      // they are logged and go no further.\n      error: (err: any) => {\n        if (err?.status === 0) { this.markOptionsUnavailableOffline(); return; }\n        console.error('[tin-spa] text-multi loadAction failed', { url: action.url, err });\n      }\n    });\n  }\n\n  // Added: a cache miss served by the offline layer arrives as success:false with a network we know is down.\n  // Both halves are required — `online === false` alone would claim any 200-level failure was an offline one.\n  private isOfflineCacheMiss(): boolean {\n    return !!this.offline && this.offline.enabled && !this.offline.online;\n  }\n\n  private markOptionsUnavailableOffline(): void {\n    this.optionsUnavailableOffline = true;\n  }\n\n  ngOnDestroy() {\n    this.loadIndicator.destroy(); // Added: clear any pending delay/hold timer on a field torn down mid-read\n  }\n}\n","<!-- Changed (WS-1 Phase 3): one class added — no structural change. It tints the hint line the field already renders. Same treatment as spa-select-common and spa-text-single; see the .css for why the state is spoken on the field rather than in a toast. -->\n<mat-form-field [class.spa-readonly]=\"readonly\" [class.spa-options-unavailable]=\"optionsUnavailableOffline\" style=\"width: 100%;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n  <mat-label>{{display}}</mat-label>\n  <mat-chip-grid #chipList>\n    <mat-chip-row *ngFor=\"let value of values\" [removable]=\"!readonly\" (removed)=\"remove(value)\">\n      {{getDisplayValue(value)}}\n      <button matChipRemove *ngIf=\"!readonly\"><mat-icon class=\"tinyIcon\">cancel</mat-icon></button>\n    </mat-chip-row>\n    <input #textInput autocomplete=\"off\" [placeholder]=\"readonly ? '' : computedPlaceholder\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"add($event)\" [formControl]=\"control\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\" [matAutocompleteDisabled]=\"readonly\">\n  </mat-chip-grid>\n\n  <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\n    <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"option\">\n      {{option[optionDisplay]}}\n    </mat-option>\n  </mat-autocomplete>\n\n  <mat-error *ngIf=\"errorState\">{{hint}}</mat-error>\n  <!-- Changed (WS-1 Phase 3): the hint now reads computedHint, and — the part that matters — it is GATED on computedHint too, not on hint.\n       This differs from spa-text-single only because the surface differs: text-single uses [hintLabel], which renders whenever it is non-empty,\n       whereas this template renders an explicit <mat-hint> behind an *ngIf. Left gated on `hint`, the offline notice would never appear in the\n       filter/option context at all, because option.component.html binds [loadAction] but never binds [hint] — the exact context where a lookup\n       can fail with nothing else on screen to explain it. Both render the same .mat-mdc-form-field-hint element, so the css rule is unchanged.\n       The mat-error above is untouched and still wins when errorState is set, as before. -->\n  <mat-hint *ngIf=\"computedHint && !errorState\">{{computedHint}}</mat-hint>\n\n  <div matSuffix class=\"suffix-icons\">\n    <!-- Changed: the icon now also shows while loading (not hover-only), and spins — same .tin-spin idiom as the table/filter refresh button -->\n    <!-- Added (WS-1 Phase 3): the house's own offline mark, the same cloud_off spa-offline-indicator, spa-select-common and spa-text-single already use, so the state is recognisable without reading — which is what carries it at phone width, where the hint line has least room. The refresh button below is left exactly as it was and stays reachable on purpose: it is the one action that fixes this once the connection is back, and getData() clears the flag on the first successful load. -->\n    <mat-icon *ngIf=\"optionsUnavailableOffline\" class=\"tinyIcon spa-options-unavailable-icon\" [matTooltip]=\"computedHint\" matTooltipPosition=\"above\">cloud_off</mat-icon>\n    <button mat-icon-button *ngIf=\"loadAction && (isHovered || loadIndicator.spinning)\" (click)=\"refresh($event)\" [matTooltip]=\"loadIndicator.spinning ? 'Loading' : 'Refresh'\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" [class.tin-spin]=\"loadIndicator.spinning\" color=\"primary\">cached</mat-icon>\n    </button>\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"true\" [(value)]=\"value\"></spa-suffix>\n  </div>\n</mat-form-field>\n","// Rich-text / WYSIWYG editor field — wraps @kolkov/angular-editor.\n// Additive tin-spa Field type:'editor' — two-way binds an HTML string value.\nimport { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { AngularEditorConfig } from '@kolkov/angular-editor';\n\n@Component({\n    selector: 'spa-editor',\n    templateUrl: './editor.component.html',\n    styleUrls: ['./editor.component.css'],\n    standalone: false\n})\nexport class EditorComponent implements OnInit {\n\n  constructor() { }\n\n  ngOnInit(): void {\n    if (this.placeholder === '') {\n      this.placeholder = 'Enter ' + (this.display || 'text') + '...';\n    }\n    this.buildConfig();\n  }\n\n  ngOnChanges(): void {\n    // Rebuild config when readonly/height/placeholder inputs change.\n    this.buildConfig();\n  }\n\n  @Input() display = '';\n  @Input() value = '';                       // HTML content (two-way bound)\n  @Input() readonly = false;\n  @Input() required = false;\n  @Input() hint = '';\n  @Input() infoMessage: string;\n  @Input() placeholder = '';\n  @Input() width = '100%';\n  @Input() height = 'auto';                   // editor body height\n  @Input() minHeight = '8rem';\n  @Input() defaultFontName = 'Arial';\n  // Full AngularEditorConfig pass-through — when supplied it takes precedence.\n  @Input() editorConfig: AngularEditorConfig;\n\n  @Output() valueChange = new EventEmitter();\n\n  // Effective config handed to <angular-editor>.\n  config: AngularEditorConfig;\n\n  // Added (rop-1): the editor derives its own placeholder rather than going through runtime/field-placeholder,\n  // so the read-only suppression has to be repeated here — this is the one field type with a bespoke path.\n  // Same rule as the shared derivation: read-only renders BLANK, because a prompt to type is a lie on a\n  // control that cannot be typed into. Gated in the getter, not in ngOnInit, so toggling the pencil is live.\n  get computedPlaceholder(): string { return this.readonly ? '' : this.placeholder; }\n\n  private buildConfig(): void {\n    if (this.editorConfig) {\n      // Consumer-provided config wins; only force editability from readonly.\n      // Changed (rop-1): ...and blank its placeholder when readonly — a consumer's own copy is no more\n      // actionable on a locked field than a derived one, and angular-editor paints it from the config.\n      this.config = { ...this.editorConfig, editable: !this.readonly, placeholder: this.readonly ? '' : this.editorConfig.placeholder };\n      return;\n    }\n\n    this.config = {\n      editable: !this.readonly,\n      spellcheck: true,\n      height: this.height,\n      minHeight: this.minHeight,\n      placeholder: this.computedPlaceholder, // Changed (rop-1): blank in read-only mode\n\n      translate: 'no',\n      defaultParagraphSeparator: '',\n      defaultFontName: this.defaultFontName,\n      sanitize: false,\n      toolbarHiddenButtons: [\n        ['subscript', 'superscript', 'heading', 'fontName'],\n        ['insertVideo', 'toggleEditorMode']\n      ]\n    };\n  }\n\n  changed(val: any): void {\n    this.value = val;\n    this.valueChange.emit(val);\n  }\n}\n","<!-- Rich-text / WYSIWYG editor field -->\n<div class=\"spa-editor-wrap\" [class.spa-readonly]=\"readonly\" [ngStyle]=\"{'width': width ?? '100%'}\">\n\n  <div class=\"spa-editor-label\" *ngIf=\"display\">\n    <label>{{display}}<span *ngIf=\"required\" class=\"spa-editor-req\"> *</span></label>\n    <mat-icon *ngIf=\"infoMessage\" class=\"spa-editor-info\" matTooltip=\"{{infoMessage}}\" matTooltipPosition=\"above\">info</mat-icon>\n  </div>\n\n  <angular-editor\n    [ngModel]=\"value\"\n    (ngModelChange)=\"changed($event)\"\n    [config]=\"config\"\n    [placeholder]=\"computedPlaceholder\"><!-- Changed (rop-1): blank in read-only mode — angular-editor reads the placeholder from BOTH this binding and the config, so both are gated -->\n  </angular-editor>\n\n  <div class=\"spa-editor-hint\" *ngIf=\"hint\">{{hint}}</div>\n</div>\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { MessageService } from '../../services/message.service';\nimport { Action } from '../../classes/Classes';\n\n@Component({\n    selector: 'spa-option',\n    templateUrl: './option.component.html',\n    styleUrls: ['./option.component.css'],\n    standalone: false\n})\nexport class OptionComponent implements OnInit {\n\n  constructor(private messageService: MessageService,) { }\n\n  ngOnInit(): void {\n    this.OGValue = this.value;\n  }\n\n  OGValue\n\n\n\n  @Input() options: any;\n  @Input() optionValue = \"\";\n  @Input() optionDisplay = \"\";\n  @Input() readonly = false;\n\n  @Input() type = \"text\";\n  @Input() value = \"\";\n  @Input() display = \"\";\n  @Input() show: boolean = false;\n  @Input() required: boolean = false;\n  @Input() infoMessage: string;\n  @Input() copyContent = false;\n  @Input() suffix: string;\n  @Input() editorConfig: any; // Added: pass-through AngularEditorConfig for type:'editor'\n\n  @Input() loadAction: Action;\n\n  @Output() valueChange = new EventEmitter();\n  @Output() enterPress = new EventEmitter();\n\n  changed() {\n    this.valueChange.emit(this.value);\n  }\n\n  dateChanged(x){\n    this.value = x\n    this.changed()\n  }\n\n  enterPressed(){\n    this.enterPress.emit();\n  }\n\n  resetValue(){\n    this.value = this.OGValue;\n    this.changed();\n  }\n\n\n  onInfoClick(event: MouseEvent): void {\n    event.stopPropagation();\n\n    if (this.infoMessage) {\n      this.messageService.info(this.infoMessage);\n    }\n  }\n\n\n\n}\n","\n<div class=\"tin-row gap-0\" style=\"align-items: center;\">\n\n  <mat-checkbox color=\"primary\" style=\"margin-right: 2px;\" [(ngModel)]=\"show\" (change)=\"resetValue()\" labelPosition=\"after\" [disabled]=\"required\" >{{display}}</mat-checkbox>\n\n  <ng-container *ngIf=\"show\" [ngSwitch]=\"type\">\n\n    <spa-date class=\"opt\" *ngSwitchCase=\"'date'\" [display]=\"display\" width=\"120px\"  [(value)]=\"value\" [display]=\"display\" (valueChange)=\"dateChanged($event)\" [infoMessage]=\"infoMessage\"\n    ></spa-date>\n\n    <spa-select-multi class=\"opt\" *ngSwitchCase=\"'select-multi'\" [display]=\"display\"  [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\n      [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\n    ></spa-select-multi>\n\n    <spa-text-multi class=\"opt\" *ngSwitchCase=\"'text-multi'\" [display]=\"display\"  [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\n      [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\n    ></spa-text-multi>\n\n    <spa-select-lite class=\"opt\" *ngSwitchCase=\"'select'\" [display]=\"display\"  [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\n      [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\n    ></spa-select-lite>\n\n    <spa-editor class=\"opt\" *ngSwitchCase=\"'editor'\" [display]=\"display\" [(value)]=\"value\" (valueChange)=\"changed()\"\n      [required]=\"required\" [infoMessage]=\"infoMessage\" [editorConfig]=\"editorConfig\"\n    ></spa-editor>\n\n    <!-- Added: plain 'text' gets spa-text, matching the form component's own convention. The autocomplete\n         default below only commits a value on option SELECTION (its input has no change/enter bindings), so a\n         free-typed search value — e.g. the Logs page's error reference — never reached the search payload. -->\n    <spa-text class=\"opt\" *ngSwitchCase=\"'text'\" [display]=\"display\" (enterPress)=\"enterPressed()\" [(value)]=\"value\" (valueChange)=\"changed()\"\n      [required]=\"required\" [suffix]=\"suffix\" [copyContent]=\"copyContent\" [infoMessage]=\"infoMessage\"\n    ></spa-text>\n\n    <spa-text-single class=\"opt\" *ngSwitchDefault [display]=\"display\" (enterPress)=\"enterPressed()\"  [options]=\"options\" [optionDisplay]=\"optionDisplay\" [optionValue]=\"optionValue\" [(value)]=\"value\" (valueChange)=\"changed()\"\n      [suffix]=\"suffix\" [copyContent]=\"copyContent\" [loadAction]=\"loadAction\" [infoMessage]=\"infoMessage\"\n    ></spa-text-single>\n\n  </ng-container>\n\n  <button mat-icon-button *ngIf=\"infoMessage && !show\" (click)=\"onInfoClick($event)\" matTooltip=\"Info\" matTooltipPosition=\"above\" style=\"opacity: 1;\">\n    <mat-icon class=\"tinyIcon\" style=\"color: steelblue;\">info</mat-icon>\n  </button>\n\n</div>\n","import { Pipe, PipeTransform } from '@angular/core';\nimport { Core } from '../classes/TinCore';\n\n@Pipe({\n    name: 'camelToWords',\n    standalone: false\n})\nexport class CamelToWordsPipe implements PipeTransform {\n\n  transform(value: string): string {\n    return Core.camelToWords(value);\n  }\n}\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { SearchConfig } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore';\n\n@Component({\n    selector: 'spa-search',\n    templateUrl: './search.component.html',\n    styleUrls: ['./search.component.css'],\n    standalone: false\n})\nexport class SearchComponent implements OnInit {\n\n  constructor() { }\n\n  ngOnInit(): void {\n    this.data = Core.generateObject(this.config.fields)\n  }\n\n  data;\n  @Input() config: SearchConfig;\n  @Output() searchClick = new EventEmitter();\n\n  @Input() smallScreen: boolean;\n  @Input() tableDataSource: any;\n\n  search(){\n    this.searchClick.emit(this.data);\n  }\n\n}\n","\n<div class=\"tin-between\">\n\n  <div class=\"col tin-row\">\n\n    <div *ngFor=\"let field of config.fields\">\n\n      <spa-option \n        [type]=\"field.type\" \n        [required]=\"field.required\"  \n        [show]=\"field.show\" \n        [display]=\"field.alias ?? field.name | camelToWords\"\n        [options]=\"field.options\" \n        [optionDisplay]=\"field.optionDisplay ?? 'name'\" \n        [optionValue]=\"field.optionValue ?? 'value'\" \n        [(value)]=\"data[field.name]\" (enterPress)=\"search()\"\n        [infoMessage]=\"field.infoMessage\" \n        [suffix]=\"field.suffix\" \n        [copyContent]=\"field.copyContent\" \n        [loadAction]=\"field.loadAction\"\n      ></spa-option>\n\n    </div>\n\n  </div>\n\n  <div class=\"col-2 tin-end\">\n    <spa-filter [showText]=\"!smallScreen || (smallScreen && tableDataSource?.length > 10)\" [showButton]=\"false\" [data]=\"tableDataSource\" ></spa-filter>\n    <button mat-icon-button color=\"primary\" (click)=\"search()\" matTooltip=\"Search\" matTooltipPosition=\"right\">\n      <mat-icon>search</mat-icon>\n    </button>\n  </div>\n\n</div>\n","import { Injectable } from '@angular/core';\nimport { TableConfig } from '../classes/Classes';\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class CsvService {\n  generateCsv(data: any[], columns: string[], filename: string = 'export.csv', config: TableConfig): void {\n    const csvContent = this.convertToCsv(data, columns, config);\n    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });\n    const link = document.createElement('a');\n    if (link.download !== undefined) {\n      const url = URL.createObjectURL(blob);\n      link.setAttribute('href', url);\n      link.setAttribute('download', filename);\n      link.style.visibility = 'hidden';\n      document.body.appendChild(link);\n      link.click();\n      document.body.removeChild(link);\n    }\n  }\n\n  private convertToCsv(data: any[], columns: string[], config: TableConfig): string {\n    const columnMap = this.createColumnMap(columns, config);\n    const header = columns.map(col => columnMap[col] || col).join(',');\n    const rows = data.map(row =>\n      columns.map(col => this.escapeCommas(row[col])).join(',')\n    );\n    return [header, ...rows].join('\\n');\n  }\n\n  private createColumnMap(columns: string[], config: TableConfig): { [key: string]: string } {\n    const columnMap = {};\n    config.columns.forEach(col => {\n      if (columns.includes(col.name) && col.alias) {\n        columnMap[col.name] = col.alias;\n      }\n    });\n    return columnMap;\n  }\n\n  private escapeCommas(value: any): string {\n    const stringValue = String(value);\n    if (stringValue.includes(',') || stringValue.includes('\"') || stringValue.includes('\\n')) {\n      return `\"${stringValue.replace(/\"/g, '\"\"')}\"`;\n    }\n    return stringValue;\n  }\n}\n","// Added: reports whether an element's text is ACTUALLY clipped by `text-overflow: ellipsis`, so a tooltip can\n// be attached that only fires when there is hidden content to reveal. A tooltip on text that is fully visible\n// is noise; no tooltip on text that is cut off loses information — this directive is what tells the two apart.\n//\n// Usage (declarative, no directive ordering to get wrong):\n//   <div class=\"x\" tinEllipsis #t=\"tinEllipsis\" [matTooltip]=\"fullText\" [matTooltipDisabled]=\"!t.truncated\">\n//\n// The measurement deliberately does NOT run on a change-detection pass: reading scrollWidth forces a synchronous\n// layout, and a Day Book tile row asks this question ~32 times (a title and a hint per tile). It runs instead on\n// a ResizeObserver (the box changed) and a MutationObserver (the text changed), both outside Angular, coalesced\n// into one animation frame, and only re-enters the zone when the answer actually flips.\nimport { Directive, ElementRef, NgZone, ChangeDetectorRef, AfterViewInit, OnDestroy } from '@angular/core';\n\n@Directive({\n  selector: '[tinEllipsis]',\n  exportAs: 'tinEllipsis',\n  standalone: false\n})\nexport class EllipsisDirective implements AfterViewInit, OnDestroy {\n\n  // Public because the template reads it through the exportAs reference to drive [matTooltipDisabled]\n  truncated = false;\n\n  private resizeObserver: ResizeObserver | null = null;\n  private mutationObserver: MutationObserver | null = null;\n  private frame = 0;\n\n  constructor(private el: ElementRef<HTMLElement>, private zone: NgZone, private cdr: ChangeDetectorRef) { }\n\n  ngAfterViewInit() {\n    this.zone.runOutsideAngular(() => {\n      // The box changing size is the common case (a carousel tile, a window resize, the phone breakpoint)\n      if (typeof ResizeObserver !== 'undefined') {\n        this.resizeObserver = new ResizeObserver(() => this.schedule());\n        this.resizeObserver.observe(this.el.nativeElement);\n      }\n      // The text changing is the other case, and a ResizeObserver never sees it: a longer label in the SAME\n      // box does not resize the box, it just starts overflowing it.\n      if (typeof MutationObserver !== 'undefined') {\n        this.mutationObserver = new MutationObserver(() => this.schedule());\n        this.mutationObserver.observe(this.el.nativeElement, { characterData: true, childList: true, subtree: true });\n      }\n      this.schedule(); // first measurement, once the view exists\n    });\n  }\n\n  ngOnDestroy() {\n    this.resizeObserver?.disconnect();\n    this.mutationObserver?.disconnect();\n    if (this.frame) cancelAnimationFrame(this.frame);\n  }\n\n  // Coalesce every signal in a frame into one layout read\n  private schedule() {\n    if (this.frame) return;\n    this.frame = requestAnimationFrame(() => {\n      this.frame = 0;\n      this.measure();\n    });\n  }\n\n  private measure() {\n    const node = this.el.nativeElement;\n    // 1px of slack: sub-pixel text metrics make scrollWidth exceed clientWidth by a fraction on text that is\n    // not clipped at all, which would put a useless tooltip on every label.\n    const next = node.scrollWidth > node.clientWidth + 1;\n    if (next === this.truncated) return; // nothing to tell Angular about — the overwhelmingly common path\n    this.zone.run(() => {\n      this.truncated = next;\n      this.cdr.markForCheck(); // the tile row is OnPush; without this the binding never re-evaluates\n    });\n  }\n}\n","import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; // TS-1: ChangeDetectionStrategy + ChangeDetectorRef // Changed: ViewChild/ElementRef/AfterViewInit for the carousel scroller\nimport { Action, Tile, TileConfig, TileChartConfig, ApiResponse } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Changed: central visibility resolver\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — tiles load alongside tables, so shared dedupe keeps a broken backend to one dialog\nimport { Subject, Subscription } from 'rxjs';\nimport { resolveQuietLoading, QUIET_DELAY_MS, QUIET_MIN_MS } from '../../runtime/quiet-loading'; // Added: Quiet Loading — shared config-over-app precedence resolver\nimport { Chart, ChartData, ChartOptions, Plugin } from 'chart.js'; // Changed: Added Chart import for animation control\n\n// Changed: Compact callout plugin — projects labels strictly left/right to maximize pie vertical space\nconst TileCalloutPlugin: Plugin = {\n  id: 'tileCallout',\n  afterDraw: (chart: any) => {\n    const { ctx, canvas } = chart;\n    const meta = chart.getDatasetMeta(0);\n    if (!meta?.data?.length) return;\n\n    const dataset = chart.data.datasets[0];\n    const total = dataset.data.reduce((a: number, b: number) => a + b, 0);\n    if (total === 0) return;\n\n    const labels = chart.data.labels || [];\n    const colors = dataset.backgroundColor || [];\n\n    // Changed: Reset clip region so we can draw in the padding area outside chartArea\n    ctx.save();\n    ctx.resetTransform();\n    ctx.beginPath();\n    ctx.rect(0, 0, canvas.width, canvas.height);\n    ctx.clip();\n    const dpr = window.devicePixelRatio || 1;\n    ctx.scale(dpr, dpr);\n\n    // Changed: Collect callout positions per side, then space them vertically to avoid overlap\n    const leftItems: any[] = [];\n    const rightItems: any[] = [];\n\n    meta.data.forEach((arc: any, i: number) => {\n      const value = dataset.data[i];\n      const pct = Math.round((value / total) * 100);\n      if (pct < 8) return; // Changed: Skip small segments for tile readability\n\n      const midAngle = (arc.startAngle + arc.endAngle) / 2;\n      const outerRadius = arc.outerRadius;\n      const cx = arc.x;\n      const cy = arc.y;\n\n      // Changed: Edge point on arc circumference\n      const edgeX = cx + Math.cos(midAngle) * outerRadius;\n      const edgeY = cy + Math.sin(midAngle) * outerRadius;\n\n      // Changed: Determine left/right side based on segment position\n      const isRight = Math.cos(midAngle) >= 0;\n      const color = Array.isArray(colors) ? colors[i % colors.length] : '#333';\n      const item = { edgeX, edgeY, cx, cy, outerRadius, pct, label: labels[i] ? String(labels[i]) : '', color, isRight };\n      if (isRight) rightItems.push(item); else leftItems.push(item);\n    });\n\n    // Changed: Sort items by edgeY so vertical spacing works top-to-bottom\n    leftItems.sort((a: any, b: any) => a.edgeY - b.edgeY);\n    rightItems.sort((a: any, b: any) => a.edgeY - b.edgeY);\n\n    // Changed: Space labels vertically — minimum 12px apart (single row needs less gap)\n    const spaceLabels = (items: any[]) => {\n      const minGap = 12;\n      for (let j = 1; j < items.length; j++) {\n        if (items[j].edgeY - items[j - 1].edgeY < minGap) {\n          items[j].edgeY = items[j - 1].edgeY + minGap;\n        }\n      }\n    };\n    spaceLabels(leftItems);\n    spaceLabels(rightItems);\n\n    // Changed: Get canvas logical width for margin calculations\n    const cw = canvas.width / (window.devicePixelRatio || 1);\n\n    // Changed: Draw callouts — label name and percentage on the SAME row, side by side\n    const drawSide = (items: any[]) => {\n      items.forEach((item: any) => {\n        const { edgeX, edgeY, cx, outerRadius, pct, label, color, isRight } = item;\n\n        // Changed: Connector endpoint near the pie edge\n        const tailX = isRight ? cx + outerRadius + 10 : cx - outerRadius - 10;\n        const tailY = edgeY;\n\n        // Changed: Draw connector line from arc edge to label area\n        ctx.beginPath();\n        ctx.moveTo(edgeX, edgeY);\n        ctx.lineTo(tailX, tailY);\n        ctx.strokeStyle = '#bbb';\n        ctx.lineWidth = 0.8;\n        ctx.stroke();\n\n        // Changed: Same row layout — percentage near pie, label name at the margin edge\n        ctx.textBaseline = 'middle';\n        const textX = tailX + (isRight ? 3 : -3);\n\n        // Changed: Percentage closest to pie — bold, segment-colored\n        ctx.font = 'bold 9px Arial';\n        ctx.fillStyle = color;\n        ctx.textAlign = isRight ? 'left' : 'right';\n        ctx.fillText(pct + '%', textX, tailY);\n\n        // Changed: Label name further from pie — muted, at the outer margin edge\n        if (label) {\n          ctx.font = '8px Arial';\n          ctx.fillStyle = '#666';\n          if (isRight) {\n            const pctWidth = ctx.measureText(pct + '%').width;\n            ctx.textAlign = 'left';\n            ctx.fillText(label, textX + pctWidth + 3, tailY); // Changed: Right of percentage\n          } else {\n            const pctWidth = ctx.measureText(pct + '%').width;\n            ctx.textAlign = 'right';\n            ctx.fillText(label, textX - pctWidth - 3, tailY); // Changed: Left of percentage\n          }\n        }\n      });\n    };\n\n    drawSide(leftItems);\n    drawSide(rightItems);\n    ctx.restore();\n  }\n};\n\n@Component({\n    selector: 'spa-tiles',\n    templateUrl: './tiles.component.html',\n    styleUrls: ['./tiles.component.css'],\n    changeDetection: ChangeDetectionStrategy.OnPush, // TS-1: data set async in subscribes — markForCheck() called wherever this.data mutates\n    standalone: false\n})\nexport class TilesComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit {\n\n  private subs: Subscription[] = []; // TS-8: reload subscription was never released (no ngOnDestroy)\n  // TS-5: cache chart data/options/plugins so template bindings return STABLE references; without this each\n  // change-detection cycle produced new objects, forcing BaseChartDirective to call chart.update() continuously.\n  private chartCache = new WeakMap<Tile, { data: ChartData; options: ChartOptions; plugins: Plugin[] }>();\n\n  constructor(private dataService: DataServiceLib, private messageService: MessageService, private cdr: ChangeDetectorRef, private apiErrorService: ApiErrorService) { } // TS-1: cdr for OnPush refresh after async data set // Changed: injected ApiErrorService for application-level (HTTP 200, success:false) failures\n\n  // Added (Quiet Loading): a TileConfig value always wins, including an explicit false; otherwise the app-wide\n  // AppConfig.quietLoading decides. Same precedence rule as the table's effRealTime/effPagination getters.\n  get effQuietLoading(): boolean {\n    return resolveQuietLoading(this.config, this.dataService.appConfig?.quietLoading);\n  }\n\n  // ---------------------------------------------------------------------------\n  // Added: tile row layout. These are FIELDS, not template getters, on purpose — a getter that builds a new\n  // object every change-detection pass is what caused a real livelock in this library before (see the\n  // no-template-bound-allocating-getters rule). They are recomputed only when the config actually changes.\n  // ---------------------------------------------------------------------------\n  private static readonly DEFAULT_MIN_TILE_WIDTH = 200; // px — below this a tile's label starts wrapping to three lines\n  private static readonly TILE_GAP = 10;                // px — must match the CSS gap or maxPerRow arithmetic drifts\n\n  isAuto = true;   // Changed: 'auto' is the DEFAULT again — the original stretch/shrink layout every existing page relies on\n  hideValueMobile = false; // Added: opt-in — drop the money badge under 700px (the Day Book sets it)\n  isCarousel = false;\n  tilesStyle: { [k: string]: string } = {};\n  canScrollLeft = false;\n  canScrollRight = false;\n\n  // Added: one CACHED outlet context per tile. Building `{ $implicit: tile }` in the template would hand\n  // NgTemplateOutlet a fresh object on every change-detection pass, re-creating every tile's view — the\n  // documented cause of a real livelock in this library (and of editors being destroyed mid-typing).\n  private ctxCache = new WeakMap<Tile, { $implicit: Tile }>();\n  ctx(tile: Tile): { $implicit: Tile } {\n    let c = this.ctxCache.get(tile);\n    if (!c) { c = { $implicit: tile }; this.ctxCache.set(tile, c); }\n    return c;\n  }\n\n  @ViewChild('tileScroller') tileScroller: ElementRef<HTMLElement>;\n\n  // Added: derives the grid track / carousel basis from minTileWidth + maxPerRow.\n  // wrap  -> repeat(auto-fit, minmax(<floor>, 1fr)). auto-fit collapses unused tracks, so a few tiles still\n  //          spread across the full width, while many tiles wrap onto the next row all at the SAME width.\n  //          maxPerRow raises the floor to 1/N of the row, which caps how many can fit.\n  // carousel -> a fixed flex-basis; fixed width is precisely what makes it scroll instead of squeeze.\n  private applyLayout() {\n    const cfg = this.config;\n    const min = cfg?.minTileWidth ?? TilesComponent.DEFAULT_MIN_TILE_WIDTH;\n    // Changed: absent or 'auto' => the ORIGINAL layout. Restored as the default on the owner's instruction\n    // 2026-08-08: making the grid the default regressed every existing page on a phone, where a 200px track\n    // floor does not fit twice in a ~380px viewport and every tile dropped onto its own row.\n    this.isCarousel = cfg?.layout === 'carousel';\n    this.isAuto = !this.isCarousel && cfg?.layout !== 'wrap';\n    this.hideValueMobile = cfg?.hideValueOnMobile === true;\n\n    if (this.isAuto) {\n      this.tilesStyle = {};\n      this.tileBasis = '';\n      return;\n    }\n\n    if (this.isCarousel) {\n      // Changed: the width goes on the CONTAINER as a custom property rather than inline on every card, so a\n      // media query can narrow it on a phone. An inline style on the card would have needed !important to beat.\n      this.tilesStyle = { '--tile-basis': min + 'px' };\n      this.tileBasis = min + 'px';\n      return;\n    }\n\n    const n = cfg?.maxPerRow;\n    const floor = n && n > 0\n      ? `max(${min}px, calc((100% - ${(n - 1) * TilesComponent.TILE_GAP}px) / ${n}))`\n      : `${min}px`;\n    this.tilesStyle = { 'grid-template-columns': `repeat(auto-fit, minmax(${floor}, 1fr))` };\n    this.tileBasis = '';\n  }\n\n  tileBasis = ''; // Added: carousel-only fixed width, bound per card\n\n  private scrollObserver: ResizeObserver | null = null; // Added 2026-08-18: keeps the arrows honest as the row resizes\n\n  ngAfterViewInit(): void {\n    if (!this.isCarousel) return;\n    this.updateScrollState();\n\n    // Added 2026-08-18, with the stretch rule. updateScrollState previously ran ONLY here and on ngOnChanges,\n    // and neither fires when the WINDOW resizes — so the arrows were decided once, against a row that had\n    // usually not finished laying out, and never revisited. Measured on test-spa at 1100px: the row overflowed\n    // by 481px and offered no arrow at all.\n    // This was survivable while every tile was a fixed 200px, because the row then overflowed at practically\n    // every width and being wrong in one direction was rarely visible. With tiles that stretch, whether there\n    // is anything to scroll to is now a genuine function of the container width and changes as the user\n    // resizes — so it has to be observed rather than assumed.\n    // A ResizeObserver rather than a window listener: it also catches the row being resized by something other\n    // than the window (a sidenav opening, a tab becoming visible), which is where a window listener would miss.\n    // No feedback loop — updateScrollState only writes when a flag actually flips, and it changes no geometry.\n    if (typeof ResizeObserver !== 'undefined' && this.tileScroller?.nativeElement) {\n      this.scrollObserver = new ResizeObserver(() => this.updateScrollState());\n      this.scrollObserver.observe(this.tileScroller.nativeElement);\n    }\n  }\n\n  // Added 2026-08-18: the observer above reports the scroller's OWN box, which does not change when tiles are\n  // added or their values arrive — but scrollWidth does. Re-checking after the paint covers that second case.\n  private scheduleScrollState() {\n    if (this.isCarousel) setTimeout(() => this.updateScrollState());\n  }\n\n  // Added: only offer an arrow when there is genuinely somewhere to scroll — an arrow that does nothing is\n  // worse than no arrow. The 2px tolerance absorbs sub-pixel rounding at fractional zoom levels.\n  private updateScrollState() {\n    const el = this.tileScroller?.nativeElement;\n    if (!el) return;\n    const left = el.scrollLeft > 2;\n    const right = el.scrollLeft + el.clientWidth < el.scrollWidth - 2;\n    if (left !== this.canScrollLeft || right !== this.canScrollRight) {\n      this.canScrollLeft = left;\n      this.canScrollRight = right;\n      this.cdr.markForCheck(); // OnPush — the arrows would otherwise never appear or never leave\n    }\n  }\n\n  onTilesScroll() {\n    if (this.isCarousel) this.updateScrollState();\n  }\n\n  // Added: page by ~80% of the visible width rather than a fixed tile count, so it behaves the same on a\n  // phone showing one tile and a monitor showing six, and always leaves a sliver of context on screen.\n  scrollTiles(direction: number) {\n    const el = this.tileScroller?.nativeElement;\n    if (!el) return;\n    el.scrollBy({ left: direction * Math.max(el.clientWidth * 0.8, 160), behavior: 'smooth' });\n  }\n\n  ngOnInit(): void {\n\n    this.applyLayout(); // Added: resolve the layout before the first render\n\n    if (this.config){\n      this.tiles = this.config.tiles;\n\n      if (this.config?.loadAction && this.config.loadInit) {\n        this.loadData(this.config?.loadAction, \"\");\n      }\n    }\n\n    // Changed: Added null guard — reload is undefined when parent doesn't pass [reload] input\n    if (this.reload) {\n      this.subs.push(this.reload.subscribe(v => { // Changed: TS-8 track subscription\n        if (v == true){\n          if (this.config?.loadAction) {\n            this.loadData(this.config?.loadAction, \"\");\n          }\n        }\n      }));\n    }\n\n  }\n\n  ngOnChanges() {\n    this.chartCache = new WeakMap(); // TS-5: inputs changed (e.g. [data]) — invalidate so charts rebuild once, then stay stable\n    // Added: pick up a REPLACED config. tiles was only ever assigned in ngOnInit, so a host that swapped\n    // its TileConfig kept rendering the old tile list. Hosts therefore had to smuggle host state into each\n    // tile's visibility predicate and rely on an ambient change-detection pass to notice — which stops\n    // happening as soon as the host stops churning its bindings.\n    if (this.config && this.config.tiles !== this.tiles) this.tiles = this.config.tiles;\n    this.applyLayout(); // Added: a host that swaps its TileConfig may also be changing layout/minTileWidth/maxPerRow\n    if (this.isCarousel) setTimeout(() => this.updateScrollState()); // after the new tiles have laid out\n  }\n\n  ngOnDestroy() {\n    this.subs.forEach(s => s.unsubscribe()); // TS-8\n    this.scrollObserver?.disconnect(); // Added 2026-08-18: an observer left attached keeps the destroyed view alive\n    this.scrollObserver = null;\n    // Added (Quiet Loading): a pending ghost/settle timer would otherwise fire into a destroyed view\n    if (this.ghostDelayTimer) clearTimeout(this.ghostDelayTimer);\n    if (this.ghostSettleTimer) clearTimeout(this.ghostSettleTimer);\n    this.ghostDelayTimer = null;\n    this.ghostSettleTimer = null;\n    this.pendingApply = null;\n  }\n\n  // TS-5: build once per tile, cache, and return stable references (rebuilt only when the cache is invalidated on data change)\n  private getChartCache(tile: Tile) {\n    let c = this.chartCache.get(tile);\n    if (!c) {\n      c = { data: this.buildTileMiniChartData(tile), options: this.buildMiniChartOptions(tile), plugins: this.buildTileChartPlugins(tile) };\n      this.chartCache.set(tile, c);\n    }\n    return c;\n  }\n  getTileMiniChartData(tile: Tile): ChartData { return this.getChartCache(tile).data; }\n  getMiniChartOptions(tile: Tile): ChartOptions { return this.getChartCache(tile).options; }\n  getTileChartPlugins(tile: Tile): Plugin[] { return this.getChartCache(tile).plugins; }\n\n  tiles: Tile[];\n  @Input() config: TileConfig;\n  @Output() tileActionSelected = new EventEmitter<Action>();\n\n  @Input() lastSearch;\n  @Input() data;\n  // @Input() clickable: boolean = false;\n  @Input() reload: Subject<boolean>;\n\n  @Output() tileClick = new EventEmitter();\n  @Output() tileUnClick = new EventEmitter();\n\n  selectedTile: string = \"\";\n\n  // ---------------------------------------------------------------------------\n  // Added (Quiet Loading, FSD D5): tile value ghost state.\n  // `loading` is what the template gates the shimmer chip on, and it is deliberately NOT set the moment the\n  // request leaves. D2's anti-flicker contract: a response that beats GHOST_DELAY_MS (a listCache hit resolves\n  // synchronously) must never paint a placeholder at all, and a chip that HAS painted must stay up for at least\n  // GHOST_MIN_MS so it cannot strobe.\n  // This component is OnPush — every mutation below is paired with cdr.markForCheck() or nothing repaints.\n  // All of it is inert unless effQuietLoading is true; with the flag off loadData takes the original code path.\n  // ---------------------------------------------------------------------------\n  private static readonly GHOST_DELAY_MS = QUIET_DELAY_MS; // Changed: shared anti-flicker threshold\n  private static readonly GHOST_MIN_MS = QUIET_MIN_MS;     // Changed: shared minimum display\n\n  loading = false;                                  // a load is in flight AND the anti-flicker delay has elapsed\n  private ghostDelayTimer: any = null;              // pending \"paint the chip\" timer\n  private ghostSettleTimer: any = null;             // pending \"apply the data\" timer (minimum-display hold)\n  private pendingApply: (() => void) | null = null; // the deferred data application, kept so a second load can flush it\n  private ghostShownAt = 0;                         // when a chip actually painted (0 = none, e.g. a reload with values already on screen)\n\n  loadData(action: Action, data: any) {\n\n    if (action) {\n\n      if (action.method == 'post') {\n        data = this.lastSearch;\n      }\n\n      const quiet = this.effQuietLoading; // Added: resolved ONCE per load so the request and the render agree\n      if (quiet) this.beginGhost(); // Added: arms the anti-flicker delay — nothing renders yet\n\n      // Changed: quiet tiles fetch silently so a count refresh never drops the full-screen scrim over the app.\n      // Passing `undefined` is identical to omitting the argument, so the non-quiet call is unchanged.\n      this.dataService.CallApi(action, data, quiet ? { silent: true } : undefined).subscribe((apiResponse: ApiResponse) => {\n\n        if (apiResponse.success) {\n          // Changed: the data application is routed through settle() so a painted chip can serve its minimum\n          // display time before the number replaces it. With quiet off it runs synchronously, exactly as before.\n          this.settle(quiet, () => {\n            this.data = apiResponse.data\n            this.chartCache = new WeakMap(); // TS-5: new data — invalidate so charts rebuild once with the fresh values\n          });\n        }\n        else {\n          this.settle(quiet); // Added: clear the ghost on failure too, or the chip shimmers forever behind the error dialog\n          this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Changed: tile load — dedupes with the table loads on the same page so one broken backend raises one dialog\n        }\n\n      },\n      // Changed (Quiet Loading): the branch above only covers an APPLICATION failure — a `success: false` body\n      // that still arrived as HTTP 200. CallApi ERRORS the observable on a transport/HTTP failure, so neither\n      // branch above runs and the shimmer would spin forever on a dropped connection or a 500.\n      // Found by the Phase 4 dialog work, where the same shape left every dialog button permanently disabled;\n      // checked across all three surfaces and this was the one that still had it (the table uses finalize()).\n      // settle(false) with no apply is an early return, so this is a no-op when the flag is off. Rethrowing\n      // preserves today's unhandled-error reporting rather than silently swallowing the failure.\n      (err: any) => {\n        this.settle(quiet);\n        throw err;\n      });\n    }\n\n  }\n\n  // Added (Quiet Loading): true when this tile's value is genuinely unknown and a load is in flight.\n  // The `=== undefined` test is what keeps a RELOAD honest — the previous numbers stay on screen and simply\n  // update in place, instead of collapsing back into placeholders (or into the old lying `0`).\n  showValueGhost(tile: Tile): boolean {\n    return this.effQuietLoading && this.loading && this.data?.[tile.name] === undefined;\n  }\n\n  // Added (Quiet Loading): arms the chip. Nothing paints for GHOST_DELAY_MS, so cached/fast responses show nothing.\n  private beginGhost() {\n    this.flushPending(); // a second load must not swallow the first response's data\n    if (this.ghostDelayTimer) clearTimeout(this.ghostDelayTimer);\n    this.ghostShownAt = 0;\n    this.ghostDelayTimer = setTimeout(() => {\n      this.ghostDelayTimer = null;\n      this.loading = true;\n      // Only start the minimum-display clock when a chip can actually paint. On a reload every value is already\n      // on screen (showValueGhost is false for every tile), so there is nothing to hold open and the fresh\n      // numbers must land the instant they arrive.\n      this.ghostShownAt = this.ghostWouldRender() ? Date.now() : 0;\n      this.cdr.markForCheck(); // OnPush — without this the chip never appears\n    }, TilesComponent.GHOST_DELAY_MS);\n  }\n\n  // Added (Quiet Loading): ends the load. `apply` lands immediately unless a chip is still inside its minimum\n  // display window, in which case it waits out the remainder (at most GHOST_MIN_MS).\n  private settle(quiet: boolean, apply?: () => void) {\n\n    if (!quiet) { // untouched legacy path — no timers, no deferral, identical to pre-Quiet-Loading behaviour\n      if (apply) {\n        apply();\n        this.cdr.markForCheck(); // TS-1: async data set under OnPush — schedule a check so tiles refresh (covers reload subscribe which routes through loadData)\n        this.scheduleScrollState(); // Added 2026-08-18: values arriving can change the row's scrollWidth\n      }\n      return;\n    }\n\n    if (this.ghostDelayTimer) { clearTimeout(this.ghostDelayTimer); this.ghostDelayTimer = null; }\n\n    const held = this.ghostShownAt ? TilesComponent.GHOST_MIN_MS - (Date.now() - this.ghostShownAt) : 0;\n    if (held <= 0) { this.finish(apply); return; }\n\n    this.pendingApply = apply ?? null;\n    this.ghostSettleTimer = setTimeout(() => {\n      this.ghostSettleTimer = null;\n      const run = this.pendingApply;\n      this.pendingApply = null;\n      this.finish(run ?? undefined);\n    }, held);\n  }\n\n  // Added (Quiet Loading): applies the data (if any), drops the chip and repaints.\n  private finish(apply?: () => void) {\n    if (apply) apply();\n    this.loading = false;\n    this.ghostShownAt = 0;\n    this.cdr.markForCheck(); // OnPush\n    this.scheduleScrollState(); // Added 2026-08-18: same reason as the non-quiet path above\n  }\n\n  // Added (Quiet Loading): flushes a deferred application so a rapid second load never loses the first response.\n  private flushPending() {\n    if (this.ghostSettleTimer) {\n      clearTimeout(this.ghostSettleTimer);\n      this.ghostSettleTimer = null;\n      const run = this.pendingApply;\n      this.pendingApply = null;\n      this.finish(run ?? undefined);\n    }\n  }\n\n  // Added (Quiet Loading): would ANY visible tile actually paint a chip right now? Chart tiles are excluded —\n  // their value slot is already *ngIf-gated and keeps its current behaviour per D5.\n  private ghostWouldRender(): boolean {\n    return (this.tiles ?? []).some(t => !t.chart && !this.isHidden(t) && this.data?.[t.name] === undefined);\n  }\n\n  // Changed: mirrors the guard in clicked() — drives the hover/cursor affordance so only actionable tiles look clickable\n  isClickable(tile: Tile): boolean {\n    return this.config?.clickable == true && (tile.action != undefined || tile.filter != undefined); // Changed: filter-only tiles (local-data tables) are clickable too\n  }\n\n  clicked(clickedTile: Tile){\n\n\n\n    if(!this.isClickable(clickedTile)) return; // Changed: single clickability rule — filter-only tiles (local-data) click too\n\n\n    if(this.selectedTile == clickedTile.name){\n      this.tileUnClick.emit({ name: clickedTile.name, data: clickedTile });\n      this.selectedTile = \"\";\n    }else{\n      this.tileClick.emit({name :clickedTile.name, data : clickedTile});\n      this.selectedTile = clickedTile.name;\n    }\n\n\n  }\n\n  pop(x){\n\n    if (x){\n      this.messageService.info(x);\n    }\n\n  }\n\n  isHidden(tile: Tile): boolean {\n    return !Core.isItemVisible(tile, this.data); // Changed: unified visible/hidden replaces hidden + hiddenCondition\n  }\n\n  // Added: the tile figure as it should READ. Returns a primitive (never a new object), so binding it in the\n  // template is safe under OnPush — the no-allocating-getters rule is about object identity, not strings.\n  // Absent Tile.format the value is returned untouched, so every existing tile renders exactly as before.\n  displayValue(tile: Tile): any {\n    const value = this.data?.[tile.name];\n    if (value === null || value === undefined) return tile.chart ? value : 0; // Changed: preserves the old `?? 0` for non-chart tiles and the old blank for chart tiles\n    if (typeof value !== 'number' || !tile.format) return value;\n    if (tile.format === 'money') return value.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });\n    return value.toLocaleString(undefined, { maximumFractionDigits: 2 });\n  }\n\n  // Added: resolves Tile.color, which may now be a function of the tile data\n  tileColor(tile: Tile): string {\n    return typeof tile.color === 'function' ? tile.color(this.data) : tile.color;\n  }\n\n  // Changed: Returns true only when data[tile.name] is a displayable primitive and not already shown by the chart\n  isTileValuePrimitive(tile: Tile): boolean {\n    if (tile.chart) return false; // Changed: Chart tiles display values via chart plugins (gauge center text, callouts), not as text below\n    const val = this.data?.[tile.name];\n    return val != null && typeof val !== 'object';\n  }\n\n  // Changed: Helper to check if tile chart has data to render — supports dynamic gauge values via dataField\n  hasTileChartData(tile: Tile): boolean {\n    const chart = tile.chart;\n    if (!chart) return false;\n    if (chart.gaugeValue != null) return true;\n    if (chart.data != null) return true;\n    if (chart.dataField && this.data?.[chart.dataField] != null) return true; // Changed: Use != null to support zero values\n    return false;\n  }\n\n  // Changed: Enhanced mini chart data builder — better colors, gradient fills, proper segment colors\n  private buildTileMiniChartData(tile: Tile): ChartData {\n    const chartConfig = tile.chart;\n    if (!chartConfig) return { labels: [], datasets: [] };\n\n    // Changed: Gauge mode — supports static gaugeValue OR dynamic value via dataField\n    const gaugeVal = chartConfig.gaugeValue ?? (chartConfig.type === 'doughnut' && chartConfig.dataField ? this.data?.[chartConfig.dataField] : null);\n    if (chartConfig.type === 'doughnut' && gaugeVal != null && typeof gaugeVal === 'number' && !chartConfig.data) {\n      return {\n        datasets: [{\n          data: [gaugeVal, 100 - gaugeVal],\n          backgroundColor: [chartConfig.gaugeColor ?? '#4acccd', '#f0f0f0'],\n          borderWidth: 0,\n          hoverOffset: 4\n        }]\n      };\n    }\n\n    // Changed: Get data from API response via dataField, or from inline data property\n    const chartData = this.data?.[chartConfig.dataField!] ?? chartConfig.data;\n    if (!chartData) return { labels: [], datasets: [] };\n\n    // If data is already Chart.js format (has datasets), apply colors if needed\n    if (chartData.datasets) {\n      // Changed: Apply configured colors to datasets that lack backgroundColor\n      if (chartConfig.colors?.length) {\n        chartData.datasets.forEach((ds: any) => {\n          if (!ds.backgroundColor) ds.backgroundColor = chartConfig.colors;\n        });\n      }\n      return chartData;\n    }\n\n    // Changed: Plain array data — wrap with appropriate styling per chart type\n    const color = chartConfig.color ?? '#4acccd';\n    if (chartConfig.type === 'line') {\n      return {\n        labels: chartData.map((_: any, i: number) => ''),\n        datasets: [{ data: chartData, borderColor: color, backgroundColor: color + '20', borderWidth: 2.5, fill: true, pointRadius: 0 }] // Changed: Gradient fill for sparklines\n      };\n    }\n    if (chartConfig.type === 'bar') {\n      return {\n        labels: chartData.map((_: any, i: number) => ''),\n        datasets: [{ data: chartData, backgroundColor: chartConfig.colors ?? [color], borderRadius: 3, borderWidth: 0 }] // Changed: Rounded bars, no border\n      };\n    }\n    // Changed: Pie/doughnut plain array\n    return {\n      labels: chartData.map((_: any, i: number) => `Segment ${i + 1}`),\n      datasets: [{ data: chartData, backgroundColor: chartConfig.colors ?? [color, '#e8e8e8'], borderWidth: 1, hoverOffset: 4 }]\n    };\n  }\n\n  // Changed: Enhanced mini chart options for sparklines — clean, no axes\n  private buildMiniChartOptions(tile: Tile): ChartOptions {\n    const chart = tile.chart;\n    if (!chart) return {};\n\n    // Changed: Animate once on initial load, then disable to prevent re-triggering on scroll/hover\n    const animateOnce = { onComplete: function(this: Chart) { this.options.animation = { duration: 0 }; } };\n\n    if (chart.type === 'doughnut') {\n      // Changed: Detect gauge mode — static gaugeValue OR dynamic value via dataField\n      const gaugeVal = chart.gaugeValue ?? (chart.dataField ? this.data?.[chart.dataField] : null);\n      const isGauge = gaugeVal != null && typeof gaugeVal === 'number' && !chart.data;\n      return {\n        responsive: true,\n        maintainAspectRatio: false,\n        animation: animateOnce, // Changed: Animate once then freeze\n        plugins: {\n          legend: { display: false },\n          tooltip: { enabled: !isGauge },\n          datalabels: { display: false }\n        },\n        cutout: isGauge ? '70%' : '45%',\n        layout: { padding: isGauge ? 4 : { top: 4, bottom: 4, left: 55, right: 55 } }\n      } as any;\n    }\n\n    if (chart.type === 'pie') {\n      return {\n        responsive: true,\n        maintainAspectRatio: false,\n        animation: animateOnce, // Changed: Animate once then freeze\n        plugins: {\n          legend: { display: false },\n          tooltip: { enabled: true, backgroundColor: 'rgba(0,0,0,0.8)', padding: 8, cornerRadius: 4 },\n          datalabels: { display: false }\n        },\n        layout: { padding: { top: 4, bottom: 4, left: 55, right: 55 } } // Changed: Minimal top/bottom — callouts project left/right only\n      } as any;\n    }\n\n    if (chart.type === 'bar') {\n      return {\n        responsive: true,\n        maintainAspectRatio: false,\n        animation: animateOnce, // Changed: Animate once then freeze\n        plugins: { legend: { display: false }, tooltip: { enabled: false }, datalabels: { display: false } },\n        scales: { x: { display: false }, y: { display: false } },\n        elements: { bar: { borderRadius: 2 } } // Changed: Subtle rounded bars\n      } as any;\n    }\n\n    // Changed: Line sparkline — smooth, no axes, gradient fill\n    return {\n      responsive: true,\n      maintainAspectRatio: false,\n      animation: animateOnce, // Changed: Animate once then freeze\n      plugins: { legend: { display: false }, tooltip: { enabled: false }, datalabels: { display: false } },\n      scales: { x: { display: false }, y: { display: false } },\n      elements: { line: { tension: 0.4, borderWidth: 2.5 }, point: { radius: 0 } }\n    } as any;\n  }\n\n  // Changed: Returns plugins array for tile mini charts — callout labels for pie/doughnut, center text for gauges\n  private buildTileChartPlugins(tile: Tile): Plugin[] {\n    const chart = tile.chart;\n    if (!chart) return [];\n\n    // Changed: Detect gauge mode — static gaugeValue OR dynamic value via dataField\n    const gaugeVal = chart.gaugeValue ?? (chart.dataField ? this.data?.[chart.dataField] : null);\n    const isGauge = chart.type === 'doughnut' && gaugeVal != null && typeof gaugeVal === 'number' && !chart.data;\n\n    // Changed: Add compact callout plugin for non-gauge pie/doughnut tiles\n    if (chart.type === 'pie' || (chart.type === 'doughnut' && !isGauge)) {\n      return [TileCalloutPlugin];\n    }\n\n    // Changed: Gauge center text — supports both static and dynamic gauge values\n    if (isGauge) {\n      return [{\n        id: 'tileCenterText',\n        afterDraw: (chartInstance: any) => {\n          const ctx = chartInstance.ctx;\n          const { width, height } = chartInstance;\n          ctx.save();\n          // Changed: Re-read dynamic gauge value from data on each draw cycle\n          const currentVal = chart.gaugeValue ?? (chart.dataField ? this.data?.[chart.dataField] : null);\n          const text = (currentVal ?? 0) + '%';\n          ctx.font = 'bold 18px Arial';\n          ctx.fillStyle = chart.gaugeColor ?? '#4acccd';\n          ctx.textAlign = 'center';\n          ctx.textBaseline = 'middle';\n          ctx.fillText(text, width / 2, height / 2);\n          ctx.restore();\n        }\n      }];\n    }\n\n    return [];\n  }\n\n}\n","<!-- Tile row layout. THREE modes, and the DEFAULT is the original.\n     'auto' (default, and what every existing page gets): the original bootstrap .row/.col — tiles stretch to\n     fill and shrink to a 150px floor, wrapping when they run out of room. This is byte-for-byte the markup\n     that shipped before, restored on the owner's instruction 2026-08-08: the grid I briefly made the default\n     forced ONE tile per row on a phone, because a 200px track floor does not fit twice in a ~380px viewport.\n     'wrap': a grid of equal tracks — opt in where uniform tile widths matter more than filling the row.\n     'carousel': one row, horizontal scroll. The Day Book opts into this.\n     The tile body itself is ONE template shared by all three, so the modes can never drift apart. -->\n\n<!-- AUTO — the original layout, unchanged -->\n<div *ngIf=\"isAuto\" class=\"d-flex row align-items-center justify-content-between\" [class.hide-value-mobile]=\"hideValueMobile\">\n  <ng-container *ngFor=\"let tile of tiles\">\n    <!-- Changed: tile-clickable class gives pointer + hover lift only on tiles that actually respond to clicks -->\n    <mat-card *ngIf=\"!isHidden(tile)\" class=\"col\" [class.tile-clickable]=\"isClickable(tile)\" [class.selected-tile]=\"tile.name === selectedTile\" style=\"margin-left: 5px;margin-right: 5px; padding: 10px 16px ; min-width: 150px; margin-top: 5px;\" (click)=\"clicked(tile)\">\n      <ng-container *ngTemplateOutlet=\"tileBody; context: ctx(tile)\"></ng-container>\n    </mat-card>\n  </ng-container>\n</div>\n\n<!-- WRAP / CAROUSEL — opt-in only -->\n<div *ngIf=\"!isAuto\" class=\"spa-tiles-outer\">\n\n  <!-- Carousel only: scroll affordances, shown solely when there is something to scroll to -->\n  <button type=\"button\" class=\"tiles-nav\" *ngIf=\"isCarousel && canScrollLeft\" (click)=\"scrollTiles(-1)\" aria-label=\"Scroll tiles left\">\n    <mat-icon>chevron_left</mat-icon>\n  </button>\n\n  <div #tileScroller class=\"spa-tiles\" [class.tiles-wrap]=\"!isCarousel\" [class.tiles-carousel]=\"isCarousel\" [class.hide-value-mobile]=\"hideValueMobile\" [ngStyle]=\"tilesStyle\" (scroll)=\"onTilesScroll()\">\n    <ng-container *ngFor=\"let tile of tiles\">\n      <mat-card *ngIf=\"!isHidden(tile)\" class=\"tile-card\" [class.tile-clickable]=\"isClickable(tile)\" [class.selected-tile]=\"tile.name === selectedTile\" (click)=\"clicked(tile)\">\n        <ng-container *ngTemplateOutlet=\"tileBody; context: ctx(tile)\"></ng-container>\n      </mat-card>\n    </ng-container>\n  </div>\n\n  <button type=\"button\" class=\"tiles-nav\" *ngIf=\"isCarousel && canScrollRight\" (click)=\"scrollTiles(1)\" aria-label=\"Scroll tiles right\">\n    <mat-icon>chevron_right</mat-icon>\n  </button>\n\n</div>\n\n<!-- The tile body, shared by all three modes. ctx() returns a CACHED context object per tile — building\n     `{ $implicit: tile }` inline would hand NgTemplateOutlet a new object every change-detection pass and\n     re-create every tile's view, which is the documented cause of a real livelock in this library. -->\n<ng-template #tileBody let-tile>\n\n      <!-- Changed: Chart-style tile — header, prominent chart, optional value, footer -->\n      <ng-container *ngIf=\"tile.chart; else standardTile\">\n        <!-- Changed: Header with tile name — left-aligned for better hierarchy -->\n        <!-- Changed: same one-line-plus-tooltip rule as the icon tile's label — a chart tile sits in the same\n             row as the others and wraps for the same reason, so it cannot be left as the one that still does. -->\n        <div class=\"tile-chart-header\">\n          <span tinEllipsis #chartLabel=\"tinEllipsis\" [matTooltip]=\"tile.alias ?? tile.name | camelToWords\" [matTooltipDisabled]=\"!chartLabel.truncated\" matTooltipPosition=\"above\">{{tile.alias ?? tile.name | camelToWords}}</span>\n        </div>\n\n        <!-- Changed: Chart fills tile — uses helper method for reliable data detection -->\n        <div class=\"tile-chart\" *ngIf=\"hasTileChartData(tile)\" [style.height.px]=\"tile.chart.height ?? 120\">\n          <canvas baseChart\n            [type]=\"tile.chart.type\"\n            [data]=\"getTileMiniChartData(tile)\"\n            [options]=\"getMiniChartOptions(tile)\"\n            [plugins]=\"getTileChartPlugins(tile)\">\n          </canvas>\n        </div>\n\n        <!-- Changed: Optional value display below chart — only show primitive values, skip chart data objects -->\n        <div class=\"tile-chart-value\" *ngIf=\"tile.name && isTileValuePrimitive(tile)\">\n          <span class=\"tile-chart-value-text\" [style.color]=\"tileColor(tile)\">{{tile.prefix ?? ''}}{{displayValue(tile)}}<span *ngIf=\"tile.suffix\"> {{tile.suffix}}</span></span><!-- Changed: colour may be a function of the data; value honours Tile.format -->\n        </div>\n\n        <!-- Changed: Footer with divider for chart tiles -->\n        <div class=\"tile-footer\" *ngIf=\"tile.footer || tile.info\">\n          <mat-divider></mat-divider>\n          <div class=\"d-flex align-items-center\" style=\"gap: 4px; color: #9a9a9a; font-size: 12px; margin-top: 6px;\">\n            <mat-icon *ngIf=\"tile.footerIcon\" style=\"font-size: 16px; width: 16px; height: 16px;\">{{tile.footerIcon}}</mat-icon>\n            <mat-icon *ngIf=\"!tile.footerIcon && tile.info\" style=\"font-size: 16px; width: 16px; height: 16px; color: steelblue;\">info</mat-icon>\n            <span>{{tile.footer ?? tile.info}}</span>\n          </div>\n        </div>\n      </ng-container>\n\n      <!-- Changed: Standard tile — Paper Dashboard style: icon left, label+value right, optional footer -->\n      <ng-template #standardTile>\n        <!-- Changed: Icon-style tile — icon left, label top-right, large value below -->\n        <ng-container *ngIf=\"tile.icon; else basicTile\">\n          <div class=\"tile-icon-row\">\n            <div class=\"tile-icon-wrap\" [style.color]=\"tileColor(tile) ?? '#2196f3'\"><!-- Changed: colour may be a function of the data -->\n              <mat-icon>{{tile.icon}}</mat-icon>\n            </div>\n            <div class=\"tile-icon-content\">\n              <!-- Changed: the label is now single-line-and-ellipsised, NEVER wrapped (owner, 2026-08-17 — a\n                   two-word title like \"AWAITING PAYMENT\" wrapped on desktop while its neighbours did not, and a\n                   row of tiles at two different heights \"distorts the whole tiles component\"). Nothing is lost:\n                   tinEllipsis measures whether the text is genuinely clipped and the tooltip is enabled only\n                   then, so a title that fits carries no tooltip and a title that is cut off reveals in full. -->\n              <div class=\"tile-icon-label\" tinEllipsis #tileLabel=\"tinEllipsis\" [matTooltip]=\"tile.alias ?? tile.name | camelToWords\" [matTooltipDisabled]=\"!tileLabel.truncated\" matTooltipPosition=\"above\">{{tile.alias ?? tile.name | camelToWords}}</div>\n              <!-- Changed (Quiet Loading D5): while the value is genuinely unknown the slot shows a shimmer chip instead of the old lying `0`; icon, label and footer render normally so the card never resizes. On a reload the previous number stays put and simply updates. -->\n              <div class=\"tile-icon-value\" [style.color]=\"tileColor(tile)\" [attr.aria-busy]=\"showValueGhost(tile) ? 'true' : null\"><!-- Changed: colour may be a function of the data -->\n                <span *ngIf=\"tile.prefix\">{{tile.prefix}}</span><span *ngIf=\"showValueGhost(tile); else iconTileValue\" class=\"tin-skel tin-skel-text tile-value-ghost\" aria-hidden=\"true\"></span><ng-template #iconTileValue><span [class.tile-value-in]=\"effQuietLoading\">{{displayValue(tile)}}</span></ng-template><span *ngIf=\"tile.suffix\"> {{tile.suffix}}</span><!-- Changed: value honours Tile.format; displayValue keeps the old `?? 0` -->\n                <span *ngIf=\"tile.badge && data?.[tile.badge]\" class=\"tile-badge\" [style.backgroundColor]=\"tile.badgeColor ?? '#4caf50'\">{{data?.[tile.badge]}}</span>\n              </div>\n            </div>\n          </div>\n          <!-- Changed: Footer with divider — info tooltip or custom footer text -->\n          <div class=\"tile-icon-footer\" *ngIf=\"tile.info || tile.footer\">\n            <mat-divider></mat-divider>\n            <div class=\"tile-icon-footer-content\">\n              <mat-icon *ngIf=\"tile.footerIcon\" class=\"tile-icon-footer-icon\">{{tile.footerIcon}}</mat-icon>\n              <mat-icon *ngIf=\"!tile.footerIcon && tile.info\" class=\"tile-icon-footer-icon\" style=\"color: steelblue;\">info</mat-icon>\n              <!-- Changed: the hint gets exactly the same treatment as the label above — one line, ellipsis,\n                   tooltip only when actually clipped. It wrapped for the same reason and cost the same evenness. -->\n              <span class=\"tile-icon-footer-text\" tinEllipsis #tileHint=\"tinEllipsis\" [matTooltip]=\"tile.footer ?? tile.info\" [matTooltipDisabled]=\"!tileHint.truncated\" matTooltipPosition=\"below\">{{tile.footer ?? tile.info}}</span>\n            </div>\n          </div>\n        </ng-container>\n\n        <!-- Basic tile fallback — centered number display (no icon) -->\n        <ng-template #basicTile>\n          <div class=\"row d-flex justify-content-center align-items-center\">\n            <div style=\"text-align: center;font-size: 30px;\">\n              <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.prefix\" >{{tile.prefix}}</mat-label> &nbsp;\n              <!-- Changed (Quiet Loading D5): same value ghost as the icon tile — chip while unknown, real number otherwise -->\n              <mat-label style=\"font-weight:bold; text-align: center;\" [ngStyle]=\"{'color':tileColor(tile) }\" [attr.aria-busy]=\"showValueGhost(tile) ? 'true' : null\"><span *ngIf=\"showValueGhost(tile); else basicTileValue\" class=\"tin-skel tin-skel-text tile-value-ghost\" aria-hidden=\"true\"></span><ng-template #basicTileValue><span [class.tile-value-in]=\"effQuietLoading\">{{displayValue(tile)}}</span></ng-template></mat-label>&nbsp;<!-- Changed: colour may be a function of the data; value honours Tile.format -->\n              <mat-label style=\"font-weight:bold;\" *ngIf=\"tile.suffix\">{{tile.suffix}}</mat-label>\n              <span *ngIf=\"tile.badge && data?.[tile.badge]\" class=\"tile-badge\" [style.backgroundColor]=\"tile.badgeColor ?? '#4caf50'\">{{data?.[tile.badge]}}</span>\n            </div>\n          </div>\n          <div class=\"row d-flex justify-content-center align-items-center\">\n            <div class=\"d-flex justify-content-center align-items-center\" style=\"text-align: center;\">\n              <mat-label style=\"padding-left:5px;padding-right:5px; text-align: center;font-size: 14px;\">{{tile.alias ?? tile.name | camelToWords}}</mat-label>\n              <mat-icon *ngIf=\"tile.info\" [matTooltip]=\"tile.info\" matTooltipPosition=\"above\" style=\"font-size: 20px; color:steelblue;\">info</mat-icon>\n            </div>\n          </div>\n        </ng-template>\n      </ng-template>\n\n</ng-template>\n","import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ElementRef, AfterViewInit, SimpleChanges } from '@angular/core';\nimport { Action, ApiResponse, FilterChip, FilterChipConfig } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // central visibility resolver, same one the tiles and Day Book lanes use\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { ApiErrorService } from '../../services/api-error.service';\n\n// Added: the quick-filter chip row that sits directly under the tile row. It is deliberately NOT a new visual\n// language — the pill is the Day Book lane pill (.db-lane) and the scroll arrows are the spa-tiles carousel\n// affordance, both reproduced here so the two pages read as one system. The component owns only the selection\n// and the horizontal scroll; the actual filtering is the table's job, exactly as it is for tiles.\n@Component({\n  selector: 'spa-filter-chips',\n  templateUrl: './filter-chips.component.html',\n  styleUrls: ['./filter-chips.component.css'],\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  standalone: false\n})\nexport class FilterChipsComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {\n\n  @Input() config: FilterChipConfig;\n  @Input() data: any = []; // the table's current rows — only used to resolve a chip's visibility predicate\n\n  @Output() chipClick = new EventEmitter<FilterChip>();\n\n  @ViewChild('chipScroller') chipScroller: ElementRef<HTMLElement>;\n\n  chips: FilterChip[] = [];\n  selectedKey = 'all';\n\n  // Mirrors spa-tiles: an arrow is offered only when there is genuinely somewhere to scroll to\n  canScrollLeft = false;\n  canScrollRight = false;\n\n  private resizeObserver: ResizeObserver | null = null;\n  private loaded = false;\n\n  constructor(private dataService: DataServiceLib, private cdr: ChangeDetectorRef, private apiErrorService: ApiErrorService) { }\n\n  get isCarousel(): boolean { return (this.config?.layout ?? 'carousel') === 'carousel'; }\n\n  ngOnInit() {\n    this.restoreDefault();\n    this.build();\n  }\n\n  ngOnChanges(changes: SimpleChanges) {\n    // Changed: only a genuine config swap rebuilds. `data` changes on every load and must not re-fetch the chips.\n    if (changes['config'] && !changes['config'].firstChange) { this.loaded = false; this.restoreDefault(); this.build(); }\n  }\n\n  ngAfterViewInit() {\n    this.updateScrollState();\n    // The row can gain or lose overflow without any data change (a window resize, a sidenav opening), so the\n    // arrows have to be re-evaluated on geometry as well as on content — same reasoning as the tiles carousel.\n    if (typeof ResizeObserver !== 'undefined' && this.chipScroller?.nativeElement) {\n      this.resizeObserver = new ResizeObserver(() => this.updateScrollState());\n      this.resizeObserver.observe(this.chipScroller.nativeElement);\n    }\n  }\n\n  ngOnDestroy() {\n    this.resizeObserver?.disconnect();\n    this.resizeObserver = null;\n  }\n\n  // The remembered chip is opt-in (config.remember). Without it the row always opens on the configured\n  // default, which itself defaults to 'all' — the owner's \"by default it will be on everything\".\n  private restoreDefault() {\n    const remembered = this.config?.remember ? localStorage.getItem(this.config.remember) : null;\n    this.selectedKey = remembered || this.config?.default || 'all';\n  }\n\n  private build() {\n    const staticChips = (this.config?.chips || []).slice();\n    this.chips = this.withAll(staticChips);\n    this.cdr.markForCheck();\n    if (this.config?.loadAction && !this.loaded) this.load(this.config.loadAction, staticChips);\n  }\n\n  // The All chip is always first when it is shown, which is the owner's rule verbatim: \"The first one will\n  // always be all everything\". showAll:false is the escape hatch for a consumer that does not want it.\n  private withAll(rest: FilterChip[]): FilterChip[] {\n    if (!rest.length && !this.config?.loadAction) return []; // nothing to filter by — render nothing at all\n    if (this.config?.showAll === false) return rest;\n    return [{ key: 'all', label: this.config?.allLabel || 'All', icon: this.config?.allIcon }, ...rest];\n  }\n\n  // DYNAMIC mode. The rows come back from the base controller's list projection ({ id, name }), and each one\n  // becomes a chip whose action is the chipAction template with {value} substituted for that row's id.\n  private load(action: Action, staticChips: FilterChip[]) {\n    this.loaded = true;\n    this.dataService.CallApi(action, '', { silent: true }).subscribe({\n      next: (apiResponse: ApiResponse) => {\n        if (!apiResponse?.success) { this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); return; }\n        const rows: any[] = Array.isArray(apiResponse.data) ? apiResponse.data : [];\n        // Changed (found in live proof): the defaults must match the HOUSE list contract. BaseController.GetList\n        // projects into ListOption { Name, Value }, which serialises as { name, value } — NOT { id, name }.\n        // Defaulting valueField to 'id' silently gave every chip the key \"undefined\", so all of them matched the\n        // selection at once and every one lit up as active together. 'value' is the correct default.\n        const valueField = this.config?.valueField || 'value';\n        const labelField = this.config?.labelField || 'name';\n        const built = rows.map(row => this.toChip(row, valueField, labelField));\n        this.chips = this.withAll([...staticChips, ...built]);\n        // A remembered chip that no longer exists must not leave the page filtered by nothing — the same\n        // guard buildLanes() applies in the Day Book.\n        if (this.selectedKey !== 'all' && !this.chips.some(c => c.key === this.selectedKey)) this.selectedKey = 'all';\n        this.cdr.markForCheck();\n        setTimeout(() => this.updateScrollState()); // arrows depend on the row that has just been rendered\n      },\n      error: () => { /* a chip row that cannot load must never break the table under it — it simply stays static */ }\n    });\n  }\n\n  private toChip(row: any, valueField: string, labelField: string): FilterChip {\n    const value = row?.[valueField];\n    const chip: FilterChip = { key: String(value), label: row?.[labelField] ?? String(value), icon: this.config?.icon, data: row };\n    if (this.config?.chipAction) chip.action = { ...this.config.chipAction, url: (this.config.chipAction.url || '').replace('{value}', String(value)) };\n    if (this.config?.chipFilter) { const fn = this.config.chipFilter; chip.filter = (r: any) => fn(r, chip); }\n    return chip;\n  }\n\n  isHidden(chip: FilterChip): boolean {\n    return !Core.isItemVisible(chip, this.data);\n  }\n\n  clicked(chip: FilterChip) {\n    if (this.selectedKey === chip.key) return; // re-clicking the active chip is a no-op, never a toggle-to-empty\n    this.selectedKey = chip.key;\n    if (this.config?.remember) localStorage.setItem(this.config.remember, chip.key);\n    this.chipClick.emit(chip);\n    this.cdr.markForCheck();\n  }\n\n  // Identical logic to the tiles carousel, including the 2px tolerance that absorbs sub-pixel rounding at\n  // fractional zoom, and the markForCheck that OnPush needs or the arrows never appear and never leave.\n  private updateScrollState() {\n    const el = this.chipScroller?.nativeElement;\n    if (!el) return;\n    const left = el.scrollLeft > 2;\n    const right = el.scrollLeft + el.clientWidth < el.scrollWidth - 2;\n    if (left !== this.canScrollLeft || right !== this.canScrollRight) {\n      this.canScrollLeft = left;\n      this.canScrollRight = right;\n      this.cdr.markForCheck();\n    }\n  }\n\n  onChipsScroll() {\n    if (this.isCarousel) this.updateScrollState();\n  }\n\n  // Pages by ~80% of the visible width so it behaves the same on a phone showing two chips and a monitor\n  // showing twelve, always leaving a sliver of context on screen.\n  scrollChips(direction: number) {\n    const el = this.chipScroller?.nativeElement;\n    if (!el) return;\n    el.scrollBy({ left: direction * Math.max(el.clientWidth * 0.8, 160), behavior: 'smooth' });\n  }\n}\n","<!-- The quick-filter chip row. Renders nothing at all when there are no chips, which is what keeps this\n     strictly opt-in for every consumer that has not declared a chipConfig. -->\n<div class=\"spa-chips-outer\" *ngIf=\"chips.length\">\n\n  <!-- Scroll affordance, carousel only, and only when there is somewhere to scroll to. Same rule as spa-tiles:\n       an arrow that does nothing is worse than no arrow. -->\n  <button type=\"button\" class=\"chips-nav\" *ngIf=\"isCarousel && canScrollLeft\" (click)=\"scrollChips(-1)\" aria-label=\"Scroll filters left\">\n    <mat-icon>chevron_left</mat-icon>\n  </button>\n\n  <div #chipScroller class=\"spa-chips\" [class.chips-carousel]=\"isCarousel\" [class.chips-wrap]=\"!isCarousel\" (scroll)=\"onChipsScroll()\" role=\"tablist\">\n    <ng-container *ngFor=\"let c of chips\">\n      <button type=\"button\" class=\"spa-chip\" *ngIf=\"!isHidden(c)\" [class.active]=\"selectedKey === c.key\" [attr.aria-selected]=\"selectedKey === c.key\" role=\"tab\" (click)=\"clicked(c)\">\n        <mat-icon *ngIf=\"c.icon\">{{ c.icon }}</mat-icon>{{ c.label }}<span class=\"spa-chip-count\" *ngIf=\"c.count !== undefined\">{{ c.count }}</span>\n      </button>\n    </ng-container>\n  </div>\n\n  <button type=\"button\" class=\"chips-nav\" *ngIf=\"isCarousel && canScrollRight\" (click)=\"scrollChips(1)\" aria-label=\"Scroll filters right\">\n    <mat-icon>chevron_right</mat-icon>\n  </button>\n\n</div>\n","import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from '@angular/core'; // TS-15: OnInit/OnChanges to precompute header button VMs\nimport { TableConfig, Button, TileConfig, DetailsDialogConfig, Action, ApiResponse } from '../../classes/Classes';\nimport { Subject } from 'rxjs';\nimport { ButtonService } from '../../services/button.service';\nimport { DialogService } from '../../services/dialog.service';\nimport { MessageService } from '../../services/message.service';\nimport { CsvService } from '../../services/csv.service';\nimport { Core } from '../../classes/TinCore';\n// Removed: Direct DetailsDialog import — uses dialogService.openDefaultDialog() to avoid circular dependency\n\n// TS-15: resolved per-header-button view-model — computed once (ngOnInit/ngOnChanges) instead of filtering the list and\n// running testVisible/testDisabled/getButtonColor ~3× per change-detection cycle.\ninterface HeaderButtonVM { button: Button; visible: boolean; disabled: boolean; color: string; }\n\n@Component({\n    selector: 'app-table-header',\n    templateUrl: './table-header.component.html',\n    styleUrls: ['./table-header.component.css'],\n    standalone: false\n})\nexport class TableHeaderComponent implements OnInit, OnChanges { // TS-15: implement OnInit/OnChanges\n\n  constructor(private buttonService: ButtonService, private dialogService: DialogService, private messageService: MessageService, private csvService: CsvService) { }\n\n  ngOnInit() {\n    this.createButton = this.buttonService.getCreateButton(this.config?.buttons);\n\n    if (this.config.upload){\n\n      let uploadAction : Action = { ...this.config.upload.action, method : 'post', isFormData: true }\n\n      this.uploadDetailsDialog.buttons.find(b => b.name == \"create\").action = uploadAction;\n      this.uploadDetailsDialog.formConfig.alertConfig.messages = this.config.upload.messages;\n    }\n\n    this.buildHeaderButtons(); // TS-15: precompute the header button view-models\n  }\n\n  // TS-15: rebuild the precomputed VMs when inputs (config/parentData) change\n  ngOnChanges() {\n    this.buildHeaderButtons();\n  }\n\n  // TS-15: template binds this instead of calling getHeaderButtons()/testVisible/testDisabled/getButtonColor every CD\n  headerButtonVMs: HeaderButtonVM[] = [];\n\n  private buildHeaderButtons() {\n    this.headerButtonVMs = this.getHeaderButtons().map(button => ({\n      button,\n      visible: this.testVisible(button),\n      disabled: this.testDisabled(button),\n      color: this.getButtonColor(button, this.config?.parentData),\n    }));\n  }\n\n  createButton: Button;\n\n  @Input() lastSearch;\n  @Input() config: TableConfig;\n  @Input() hideTitle: boolean;\n  @Input() tableDataSource: any;\n  @Input() tileConfig: TileConfig;\n  @Input() smallScreen: boolean;\n  @Input() tileReload: Subject<boolean>;\n  @Input() showFilterButton: boolean;\n  @Input() data: any = [];\n  @Input() tileData: any = [];\n  @Input() isRealTime: boolean = false; // Changed: Whether this table uses real-time SignalR updates\n  @Input() isConnected: boolean = false; // Changed: Whether the SignalR data hub is currently connected\n  @Input() refreshing: boolean = false; // Added (Quiet Loading D4): relays the table's in-flight refresh to the filter's refresh icon so it spins; false everywhere quiet loading is off\n\n  @Output() createClick = new EventEmitter<void>();\n  @Output() customClick = new EventEmitter();\n  @Output() refreshClick = new EventEmitter<void>();\n  @Output() tileClick = new EventEmitter<string>();\n  @Output() tileUnClick = new EventEmitter<string>();\n  @Output() chipClick = new EventEmitter<any>(); // Added: quick-filter chip selection, relayed to the table\n  @Output() filterChange = new EventEmitter<string>(); // Added: relays filter text changes from spa-filter to the table (paged mode)\n\n\n  uploadDetailsDialog : DetailsDialogConfig = {\n\n    formConfig : {\n      title: \"Upload\",\n      fixedTitle : true,\n      alertConfig: {\n        messages: [],\n      },\n\n      mode: 'create',\n      fields: [\n        { name: \"file\", type: \"file\", required: true, span : true }\n      ]\n    },\n\n\n    buttons: [\n      { name: \"create\", color: \"primary\", dialog: true, inDialog : true },\n    ]\n\n  }\n\n  onButtonClick(button: Button) {\n    if (button.name === 'create') {\n      this.createClick.emit();\n    } else {\n      this.customClick.emit(button.name);\n    }\n  }\n\n  onDownloadClick() {\n\n    if (!this.config.download) return;\n\n    this.messageService.confirm(\"Are you sure you want to download this data?\").subscribe(result => {\n      if (result == 'yes') {\n        this.customClick.emit(\"download\");\n\n        this.csvService.generateCsv(this.data, this.config.download.columns, this.config.download.fileName, this.config);\n      }\n    });\n\n\n  }\n\n  onUploadClick() {\n    this.customClick.emit(\"upload\");\n\n    this.dialogService.openDefaultDialog(this.uploadDetailsDialog).afterClosed.subscribe(result=> { // Changed: Use token pattern to avoid circular dependency\n\n      // console.log(result)\n      if (result?.message == 'success'){ // Changed: a dismissed upload dialog closes with undefined — read through it rather than throwing\n        this.refreshClick.emit();\n        this.messageService.toast(\"Upload successful\");\n      }\n\n    });\n  }\n\n  // Added: open the generic data import wizard, refresh the table on a committed import\n  testVisibleImport(): boolean {\n    if (!this.config.import) return false;\n    return Core.testVisibleHeaderButton(this.config.parentData, this.config.import);\n  }\n\n  onImportClick() {\n    // Note: no customClick emit — import is handled entirely here; the table refreshes via refreshClick on success\n    this.dialogService.openImportDialog(this.config.import).subscribe(result => {\n      if (result === 'success') {\n        this.refreshClick.emit();\n        this.messageService.toast(\"Import successful\");\n      }\n    });\n  }\n\n  onRefreshClick() {\n    this.refreshClick.emit();\n  }\n\n  // Added: relay filter text changes to the table (same pattern as onRefreshClick)\n  onFilterChange(text: string) {\n    this.filterChange.emit(text);\n  }\n\n  // Added: a grouped view needs a filter in the header row rather than a second row of its own. Respects the\n  // existing opt-out — groupConfig.filterEnabled === false still means no filter anywhere, exactly as before.\n  get showGroupedFilter(): boolean {\n    return this.config?.viewType === 'grouped' && this.config?.groupConfig?.filterEnabled !== false;\n  }\n\n  onTileClick(tile) {\n    this.tileClick.emit(tile);\n  }\n\n  onTileUnClick(tile) {\n    this.tileUnClick.emit(tile);\n  }\n\n  // Added: relays a quick-filter chip selection up to the table, which owns the actual filtering — the same\n  // division of labour the tile row already has (the header never filters anything itself).\n  onChipClick(chip) {\n    this.chipClick.emit(chip);\n  }\n\n  // Added: does this header have ANY of the three data actions to show? Drives the *ngIf on the grouped\n  // action pill so an empty bordered container can never render on a table that declares none of them.\n  // Reads the same three predicates the buttons themselves do, so the group and its contents cannot\n  // disagree. Non-allocating — three boolean reads, no array built (the template-bound-getter livelock\n  // rule is about getters that allocate per change detection).\n  get hasHeaderActions(): boolean {\n    return (!!this.config?.download && this.testVisibleHeaderButton(this.config.download))\n      || (!!this.config?.upload && this.testVisibleHeaderButton(this.config.upload))\n      || this.testVisibleImport();\n  }\n\n  getHeaderButtons(): Button[] {\n\n    if (this.config?.buttons == undefined) {\n      return [];\n    }\n    if (!this.config?.buttons) {\n      return [];\n    }\n    return this.config.buttons.filter(b => b.name == 'create' || b.inHeader);\n  }\n\n  testVisibleHeaderButton(btn): boolean {\n    return Core.testVisibleHeaderButton(this.config.parentData,btn);\n  }\n  testVisible(button: Button): boolean {\n    return this.buttonService.testVisible(button, this.config.parentData, this.config);\n  }\n\n  testDisabled(button: Button): boolean {\n    return this.buttonService.testDisabled(button, this.config.parentData);\n  }\n\n  getButtonColor(button: Button, row: any): string {\n    return this.buttonService.getButtonColor(button, row);\n  }\n\n\n}\n","<!-- Added: the quick-filter chip row. One definition, rendered directly under whichever tile row is live.\n     The owner asked for chips \"right under the row of the tiles\", so it follows the tiles rather than sitting\n     at a fixed place in the header. It renders nothing unless config.chipConfig is declared, which is what\n     keeps every existing consumer byte-identical. -->\n<ng-template #chipRow>\n  <spa-filter-chips *ngIf=\"config.chipConfig\" [config]=\"config.chipConfig\" [data]=\"data\" (chipClick)=\"onChipClick($event)\"></spa-filter-chips>\n</ng-template>\n\n<!--Tiles Top Position -->\n<ng-container *ngIf=\"config.tileConfig && !smallScreen && config.tileConfig.headerPosition == 'top'\">\n  <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\" [lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\n  <ng-container *ngTemplateOutlet=\"chipRow\"></ng-container>\n</ng-container>\n\n<!-- Changed: Small screen tiles render above header buttons/filter -->\n<div *ngIf=\"config.tileConfig && smallScreen\" style=\"width: 100%;\">\n  <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\" [lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\n  <ng-container *ngTemplateOutlet=\"chipRow\"></ng-container>\n</div>\n\n<!-- Added: a table may declare chips WITHOUT tiles. The three tile branches are mutually exclusive and all\n     require tileConfig, so this fourth branch is the only one that fires in that case — the chip row can\n     never render twice. -->\n<div *ngIf=\"!config.tileConfig\" style=\"width: 100%;\">\n  <ng-container *ngTemplateOutlet=\"chipRow\"></ng-container>\n</div>\n\n<div class=\"top\">\n\n    <!-- Changed: Dot + buttons in a single flex row so they cascade together -->\n  <div class=\"tin-row d-flex align-items-center\" style=\"margin-right: 5px;\">\n\n    <!-- Changed: Real-time connection indicator — first item, with left padding for alignment -->\n    <div *ngIf=\"isRealTime\" class=\"d-flex align-items-center\" style=\"padding-left: 10px;\"\n      [matTooltip]=\"isConnected ? 'Live — connected to server' : 'Offline — not connected'\" matTooltipPosition=\"above\">\n      <span style=\"display: inline-block; width: 10px; height: 10px; border-radius: 50%;\"\n        [style.background-color]=\"isConnected ? '#4caf50' : '#9e9e9e'\"></span>\n    </div>\n\n    <!-- TS-15: bind precomputed headerButtonVMs instead of calling getHeaderButtons()/testVisible/testDisabled/getButtonColor per CD -->\n    <ng-container *ngFor=\"let vm of headerButtonVMs\">\n      <ng-container *ngIf=\"vm.visible\" >\n        <button *ngIf=\"!config.flatButtons\" mat-raised-button color=\"primary\" [disabled]=\"vm.disabled\" (click)=\"onButtonClick(vm.button)\" >\n          {{vm.button.display}}\n        </button>\n        <button *ngIf=\"config.flatButtons\" mat-stroked-button [disabled]=\"vm.disabled\" (click)=\"onButtonClick(vm.button)\" [ngStyle]=\"{'color': vm.color}\">\n          {{vm.button.display}}\n        </button>\n      </ng-container>\n    </ng-container>\n\n  </div>\n  <div *ngIf=\"!isRealTime && headerButtonVMs.length == 0 && config.holdHeaderButtonSpace || !isRealTime && headerButtonVMs.length == 0 && !config.tileConfig\"></div><!-- TS-15: use precomputed list length -->\n\n  <!-- tiles -->\n  <div *ngIf=\"config.tileConfig && !smallScreen && (!config.tileConfig.headerPosition || config.tileConfig.headerPosition == 'middle')\" style=\"min-width: 75%;\">\n    <spa-tiles [config]=\"config.tileConfig\" [reload]=\"tileReload\" [data]=\"tileData\" [lastSearch]=\"lastSearch\" (tileClick)=\"onTileClick($event)\" (tileUnClick)=\"onTileUnClick($event)\"></spa-tiles>\n    <ng-container *ngTemplateOutlet=\"chipRow\"></ng-container>\n  </div>\n\n  <!-- filter -->\n  <div class=\"tin-row d-flex justify-content-end\" >\n\n    <!-- Changed: the three data actions were three bare glyphs loose in the row, each shrunk to 20px beside a\n         40px refresh button and the Filter field — the owner's \"no for me\". They now sit in ONE grouped pill\n         that reads as a deliberate toolbar control and lines up with the refresh button (see the CSS note).\n         DISPLAY ONLY: every *ngIf condition, tooltip and (click) handler below is unchanged, so what each\n         button does — and the Button.name each one gates its security on — is exactly what it was.\n         The group carries its own *ngIf: any SUBSET of the three may render (import alone is the common\n         piglet/grip case), and without it a table with none of them would draw an empty bordered box.\n         No dividers between the buttons — with three independent *ngIfs a static divider would strand. -->\n    <div class=\"tin-header-actions\" *ngIf=\"hasHeaderActions\" role=\"group\" aria-label=\"Table data actions\">\n\n      <button *ngIf=\"config.download && testVisibleHeaderButton(config.download)\" mat-icon-button class=\"header-action-btn\" matTooltip=\"Download\" matTooltipPosition=\"above\" (click)=\"onDownloadClick()\">\n        <mat-icon>download</mat-icon>\n      </button>\n\n      <button *ngIf=\"config.upload && testVisibleHeaderButton(config.upload)\" mat-icon-button class=\"header-action-btn\" matTooltip=\"Upload\" matTooltipPosition=\"above\" (click)=\"onUploadClick()\">\n        <mat-icon>upload</mat-icon>\n      </button>\n\n      <button *ngIf=\"config.import && testVisibleImport()\" mat-icon-button class=\"header-action-btn\" matTooltip=\"Import\" matTooltipPosition=\"above\" (click)=\"onImportClick()\">\n        <mat-icon>upload_file</mat-icon>\n      </button>\n\n    </div>\n\n    <!-- Changed: a grouped view now renders its filter HERE, in the header row, instead of spa-groups rendering\n         its own field on a separate row underneath. That produced two half-empty rows — buttons on one with\n         nothing to their right, the filter on the next with nothing to its left — where every other table config\n         puts buttons left and filter right on ONE row. The filter itself is unchanged; only its home moved. -->\n    <div *ngIf=\"config.showFilter || showGroupedFilter\" >\n      <spa-filter [showText]=\"!smallScreen || (smallScreen && tableDataSource?.data?.length > 10)\" [showButton]=\"showFilterButton\" [data]=\"tableDataSource\" [flatButtons]=\"config.flatButtons\" [smallScreen]=\"smallScreen\" [refreshing]=\"refreshing\" (refreshClick)=\"onRefreshClick()\" (filterChange)=\"onFilterChange($event)\"></spa-filter> <!-- Changed: Added filterChange relay for paged mode; refreshing spins the icon during a quiet refresh -->\n    </div>\n    <div *ngIf=\"!config.showFilter && !showGroupedFilter && config.holdFilterSpace\"></div>\n  </div>\n\n\n</div>\n\n<!-- <div *ngIf=\"config.title && !hideTitle\" class=\"title\">\n  {{config.title | camelToWords}}\n</div> -->\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { MessageService } from '../../services/message.service';\n\n\n@Component({\n    selector: 'spa-check',\n    templateUrl: './check.component.html',\n    styleUrls: ['./check.component.css'],\n    standalone: false\n})\nexport class CheckComponent implements OnInit {\n\n  constructor(private messageService: MessageService,) { }\n\n  ngOnInit(): void {\n  }\n\n  @Input() readonly = false;\n  @Input() display = \"\";\n  @Input() value = false;\n  @Output() valueChange = new EventEmitter();\n  @Output() click = new EventEmitter();\n  @Output() check = new EventEmitter();\n  @Output() uncheck = new EventEmitter();\n\n  @Input() infoMessage: string;\n  @Output() infoClick = new EventEmitter<void>();\n\n  // Added: helper text under the switch. Every other field type carries its `hint` in the mat-form-field\n  // subscript; a checkbox has no form field, so a boolean setting had NOWHERE to say what it actually does and\n  // every one in the app shipped as a bare label. Optional — an unset hint renders nothing and moves nothing.\n  @Input() hint: string;\n\n  changed(){\n    this.valueChange.emit(this.value);\n  }\n\n  clicked(){\n    this.click.emit();\n\n    if(!this.value){\n      this.checked();\n    }else{\n      this.unchecked();\n    }\n  }\n\n  checked(){\n    this.check.emit();\n  }\n  unchecked(){\n    this.uncheck.emit();\n  }\n\n  onInfoClick(event: MouseEvent): void {\n    event.stopPropagation();\n    this.infoClick.emit();\n\n  }\n\n}\n","\n\n<!-- Changed: checkbox + hint are wrapped so the host presents ONE flex item, not two.\n     tin-styles.css's FORM-1/FORM-3 rule makes `spa-form spa-check` a flex row to centre it on the field\n     control band; with the hint as a second child it became a sibling COLUMN beside the label instead of a\n     line beneath it. Wrapping restores the single-item assumption that rule was written against, so the\n     band alignment is preserved untouched and the hint stacks where check.component.css already aims it. -->\n<div class=\"check-body\">\n  <mat-checkbox color=\"primary\" [(ngModel)]=\"value\" (change)=\"changed()\" (click)=\"clicked()\" [disabled]=\"readonly\">{{display}}</mat-checkbox>\n\n  <!-- Added: the hint line. Sits under the label rather than beside it so a full sentence can be read without\n       stretching the grid column, and is indented to the label's own left edge, not the box's. -->\n  <div class=\"check-hint\" *ngIf=\"hint\">{{hint}}</div>\n</div>\n\n<!-- <div class=\"suffix-icons\">\n\n  <mat-checkbox color=\"primary\" [(ngModel)]=\"value\" (change)=\"changed()\" (click)=\"clicked()\" [disabled]=\"readonly\">{{display}}</mat-checkbox>\n\n  <mat-icon *ngIf=\"infoMessage\" (click)=\"onInfoClick($event)\" matTooltip=\"Info\" matTooltipPosition=\"above\" style=\"color: steelblue;font-size: 15px;margin-left: 5px;margin-top: 8px;\">info</mat-icon>\n\n</div> -->\n\n","import { Component, Input, Output, EventEmitter, OnChanges, ChangeDetectionStrategy } from '@angular/core';\n\n// A person's name compacted to an initials circle. The colour is derived from a STABLE identity key\n// (the username), never from the formatted display string and never at random, so one person keeps the\n// same colour on every screen, every session and every device — that consistency is the whole point.\n\nexport type MonogramKind = 'person' | 'system' | 'unknown';\n\n// TinCore Constants.SystemUser = \"System\"; its Users row is FirstName \"System\" / LastName \"User\",\n// so a system-stamped row reaches the client as either of these. Kept tight and evidence-based —\n// speculative tokens ('job', 'seed') are NOT matched because nothing in this codebase produces them.\nconst SYSTEM_TOKENS = ['system', 'system user'];\n\n// Ten hues carry people. Slate is NOT in the rotation — it is reserved for \"not a person\", so a\n// neutral circle can never be mistaken for someone whose colour merely happens to be grey.\nexport const MONOGRAM_TONES = ['indigo', 'blue', 'cyan', 'teal', 'green', 'moss', 'ochre', 'clay', 'rose', 'plum'];\n\n// Initials from a display name. Rules, in order:\n//  - an email uses the local part, split on . _ + -           john.smith@x.com -> JS,  admin@x.com -> AD\n//  - two or more words take FIRST + LAST, so middle names are ignored   Mary Jane Watson -> MW\n//  - one word takes its first two characters                 admin -> AD,  Prince -> PR\n//  - a single character stands alone                         X -> X\nexport function monogramInitials(display: string): string {\n  const s = (display ?? '').replace(/\\s+/g, ' ').trim();\n  if (!s) return '';\n  if (s.includes('@')) {\n    const local = s.split('@')[0];\n    const parts = local.split(/[._+-]+/).filter(p => p.length);\n    if (parts.length > 1) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n    return local.slice(0, 2).toUpperCase();\n  }\n  const words = s.split(' ').filter(w => w.length);\n  if (words.length > 1) return (words[0][0] + words[words.length - 1][0]).toUpperCase();\n  return words[0].slice(0, 2).toUpperCase();\n}\n\n// Classifies the actor. BaseBasic.CreatedByName is $\"{CreatedByUser?.FirstName} {CreatedByUser?.LastName}\",\n// which yields a bare \" \" when the user is missing — that trims to empty and lands here as 'unknown',\n// which is exactly why the trim above is load-bearing rather than cosmetic.\nexport function monogramKind(display: string, key: string): MonogramKind {\n  const d = (display ?? '').replace(/\\s+/g, ' ').trim().toLowerCase();\n  const k = (key ?? '').trim().toLowerCase();\n  if (SYSTEM_TOKENS.includes(k) || SYSTEM_TOKENS.includes(d)) return 'system';\n  if (!d && !k) return 'unknown';\n  return 'person';\n}\n\n// FNV-1a over the stable key. Deterministic and well spread for short strings; Math.imul keeps the\n// multiply in 32-bit so the result is identical across engines.\nexport function monogramPaletteIndex(key: string, buckets: number): number {\n  const s = (key ?? '').trim().toLowerCase();\n  let h = 0x811c9dc5;\n  for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i); h = Math.imul(h, 0x01000193); }\n  return (h >>> 0) % buckets;\n}\n\n@Component({\n    selector: 'spa-monogram',\n    templateUrl: './monogram.component.html',\n    styleUrls: ['./monogram.component.css'],\n    changeDetection: ChangeDetectionStrategy.OnPush,\n    standalone: false\n})\nexport class MonogramComponent implements OnChanges {\n  @Input() value: string; // display name — the underlying value stays on the row, so sort/filter never see the initials\n  @Input() key: string; // stable identity (username); falls back to the display name when the API does not project one\n\n  @Output() tapped = new EventEmitter<string>(); // touch path — there is no hover on a phone\n\n  initials = '';\n  kind: MonogramKind = 'unknown';\n  tone = 'slate';\n  label = 'Unknown';\n\n  ngOnChanges() {\n    const display = (this.value ?? '').replace(/\\s+/g, ' ').trim();\n    this.kind = monogramKind(this.value, this.key);\n    // Colour seeds off the stable key when there is one; the normalized display name is the fallback,\n    // which is stable in practice because every audit name is formatted by one base class.\n    const seed = (this.key ?? '').trim() || display;\n    this.initials = monogramInitials(display || this.key);\n    this.tone = this.kind === 'person' ? MONOGRAM_TONES[monogramPaletteIndex(seed, MONOGRAM_TONES.length)] : 'slate';\n    this.label = this.kind === 'system' ? 'System' : (display || 'Unknown');\n  }\n\n  onTap() {\n    this.tapped.emit(this.label); // tap/Enter surfaces the full name where hover cannot\n  }\n}\n","<span class=\"tin-mono\" [ngClass]=\"'tin-mono--' + tone\" role=\"img\" [attr.aria-label]=\"label\" [matTooltip]=\"label\" matTooltipPosition=\"above\" tabindex=\"0\" (click)=\"onTap()\" (keydown.enter)=\"onTap()\" (keydown.space)=\"onTap()\">\n  <mat-icon *ngIf=\"kind === 'system'\" class=\"tin-mono__icon\">settings</mat-icon>\n  <ng-container *ngIf=\"kind !== 'system'\">{{ initials || '–' }}</ng-container>\n</span>\n","import { Component, Input, Output, EventEmitter, ViewEncapsulation, OnChanges, ChangeDetectionStrategy } from '@angular/core'; // Changed: Added ViewEncapsulation, OnChanges; TS-1 ChangeDetectionStrategy\nimport { Column, Button, TableConfig, Icon } from '../../classes/Classes';\nimport { ButtonService } from '../../services/button.service';\n\n// TS-3: resolved per-cell view-model — computed once when inputs change instead of running text/color/icon\n// condition methods for every cell on every change-detection cycle.\ninterface CellVM { text: any; truncated: boolean; color: string; showColumnIcon: boolean; visibleIcons: Icon[]; chips: ChipItem[]; chipsVisible: ChipItem[]; chipsMore: number; }\n\n// Added: one chip of a 'chips' cell. `data` is the pseudo-row the DIALOG will be about — { rentalID: 12 } — not\n// the row the cell lives in. A null data means the item carries no identity to open, so the chip stays inert.\ninterface ChipItem { label: any; data: any; }\n\n@Component({\n    selector: 'app-table-row',\n    templateUrl: './table-row.component.html',\n    styleUrls: ['./table-row.component.css'],\n    encapsulation: ViewEncapsulation.None, // Changed: Required to override Material button height\n    changeDetection: ChangeDetectionStrategy.OnPush, // TS-1: pure @Input leaf, vm computed in ngOnChanges — safe for OnPush\n    standalone: false\n})\nexport class TableRowComponent implements OnChanges {\n  @Input() column: Column;\n  @Input() row: any;\n  @Input() config: TableConfig;\n  @Input() smallScreen: boolean = false;\n\n  @Output() actionClick = new EventEmitter<{ name: string, row: any }>();\n  @Output() columnClick = new EventEmitter<{ column: Column, row: any }>();\n  @Output() showBannerEvent = new EventEmitter<string>();\n\n  vm: CellVM = { text: '', truncated: false, color: '', showColumnIcon: false, visibleIcons: [], chips: [], chipsVisible: [], chipsMore: 0 }; // TS-3: template binds these\n\n  // Added: a 'chips' cell shows a capped number of chips and folds the rest behind a +n. This is per-CELL state,\n  // so it must reset when the row is recycled — mat-table reuses row components as the data changes.\n  chipsExpanded = false;\n\n  ngOnChanges() {\n    const col = this.column, row = this.row;\n    const chips = this.computeChips(row, col);\n    const limit = this.smallScreen ? 2 : 3; // Added: see computeChips — the cap is what keeps a 9-hire invoice one row tall\n    this.chipsExpanded = false;\n    this.vm = {\n      text: this.computeText(row, col),\n      truncated: this.computeTruncated(row, col),\n      color: this.getColorOnCondition(row, col),\n      showColumnIcon: !!(col?.icon && this.testIconCondition(row, col.icon)),\n      visibleIcons: (col?.icons ?? []).filter(icon => this.testIconCondition(row, icon)),\n      chips: chips, // Added: BOTH lists are built here, never sliced in the template — a template-bound slice allocates on every change-detection pass, which is the shape that caused a livelock once already\n      chipsVisible: chips.length > limit ? chips.slice(0, limit) : chips,\n      chipsMore: Math.max(0, chips.length - limit),\n    };\n  }\n\n  // Added: an array field becomes one chip per item. Today it interpolates as \"12,13\" — a single cell of text that\n  // names nothing and opens nothing. Two item shapes are supported and no third is invented:\n  //   scalars  [12, 13]                        -> label is the value, and idField says what to call it: { rentalID: 12 }\n  //   objects  [{ rentalID: 12, ref: 'H-12' }] -> the item IS the pseudo-row; optionDisplay picks the label (reused\n  //                                               rather than adding a labelField — the Column already has it)\n  // A scalar with NO idField gets data:null and stays INERT. The tempting fallback — hand the dialog the row —\n  // is precisely this codebase's house bug: it opens the invoice while claiming to open the hire.\n  private computeChips(row: any, col: Column): ChipItem[] {\n    if (col?.type !== 'chips') return [];\n    const items = row?.[col.listField ?? col.name];\n    if (!Array.isArray(items)) return [];\n    return items.filter(item => item !== null && item !== undefined).map(item => {\n      if (typeof item === 'object') return { label: item[col.optionDisplay ?? col.idField] ?? '', data: item };\n      return { label: item, data: col.idField ? { [col.idField]: item } : null };\n    });\n  }\n\n  // Changed: TS-3 null/type-safe variants of textDisplayed/textTruncated (ngOnChanges runs for every column type)\n  private computeText(row: any, col: Column): any {\n    const txt = row?.[col?.name];\n    if (txt == null || typeof txt !== 'string') return txt;\n    const max = !this.smallScreen ? col?.maxLength : col?.maxLength / 2;\n    return (max && txt.length > max) ? txt.substring(0, max) : txt;\n  }\n  private computeTruncated(row: any, col: Column): boolean {\n    const txt = row?.[col?.name];\n    if (txt == null || typeof txt !== 'string') return false;\n    const max = !this.smallScreen ? col?.maxLength : col?.maxLength / 2;\n    return !!(max && txt.length > max);\n  }\n\n  constructor(private buttonService: ButtonService) { }\n\n  testIconCondition(row: any, icon: Icon): boolean {\n    return icon.condition ? icon.condition(row) : true;\n  }\n\n  getColorOnCondition(row: any, column: Column) {\n\n    if (column.options) {\n      const color = this.getColor(row[column.name], column.options);\n      return column.type === 'chip' ? color : (color === 'lightgrey' ? '' : color);\n    }\n\n\n    if (column.colors){\n      for (const color of column.colors) {\n        if (color.condition(row)) {\n          return color.name;\n        }\n\n      }\n    }\n    else{\n\n      if (column.color && column.color.condition) {\n        return column.color.condition(row) ? column.color.name : '';\n      }\n\n    }\n\n\n    return '';\n\n\n  }\n\n  getColor(value: any, options: any[]): string {\n    if (!options) return 'lightgrey';\n    const option = options.find(opt => opt.value === value);\n    return option ? option.color : 'lightgrey';\n  }\n\n  onActionClick(name: string, row: any) {\n    this.actionClick.emit({ name, row });\n  }\n\n  onColumnClick(column: Column, row: any) {\n    this.columnClick.emit({ column, row });\n  }\n\n  showBanner(message: string) {\n    this.showBannerEvent.emit(message);\n  }\n\n  // Added: a chip is a BADGE unless it declares a detailsConfig. 50 chip columns across the estate carried an\n  // unconditional (click) with no detailsConfig — 39 status/enum and count badges plus 11 entity references that\n  // were never wired — so every one of them rendered as a control, took focus, showed a pointer cursor, and did\n  // nothing when clicked. columnClicked's no-detailsConfig branch emits actionClick under the COLUMN's name; no\n  // handler anywhere in the six codebases listens for any of those 50 names, so the emit was a dead end, which is\n  // why withdrawing it is safe for the untracked consumer apps too — their inert chips already did nothing.\n  // Guarded here rather than in the template so the shape matches onMonogramTap above, which has resolved the same\n  // question for the monogram cell since it gained a details path. The template also removes the AFFORDANCE\n  // (.chip-inert + tabindex -1): swallowing a click a cell still advertises is the half fix that reads as a bug.\n  onChipClick(column: Column, row: any) {\n    if (!column?.detailsConfig) return;\n    this.onColumnClick(column, row);\n  }\n\n  // Added: one chip of a 'chips' cell. Same guard as onChipClick — no detailsConfig, no click — plus the second\n  // half that is specific to a list: the ITEM must have an identity of its own. It emits chip.data, not this.row,\n  // so the dialog loads the record the chip names. columnClicked() then flags it drillIn like every other column\n  // drill-in, which is what makes a failed load CLOSE rather than adopt the pseudo-row and render a blank form.\n  onChipItemClick(chip: ChipItem) {\n    if (!this.column?.detailsConfig || !chip?.data) return;\n    this.columnClick.emit({ column: this.column, row: chip.data });\n  }\n\n  // Added: the +n / Less control. Local, reversible, and the only thing that lets a cell grow — a chips cell is\n  // one chip tall until the operator asks otherwise.\n  toggleChips() {\n    this.chipsExpanded = !this.chipsExpanded;\n  }\n\n  // Added: a monogram cell can now DRILL IN. The circle replaces a name that may have been a click-through into\n  // the record behind it (shift's Trips driver), and until now the monogram type had no details path at all — the\n  // tap only ever surfaced the full name, so converting such a column silently deleted the navigation.\n  // detailsConfig wins when the column declares one (the same field the chip/button types route through\n  // columnClicked, so the dialog is opened by the table exactly as it always was); the banner stays the behaviour\n  // for every monogram column that declares none, which is all of them today.\n  onMonogramTap(label: string) {\n    if (this.column?.detailsConfig) { this.onColumnClick(this.column, this.row); return; }\n    this.showBanner(label);\n  }\n\n  textDisplayed(row: any, column: Column){\n\n    let txt = row[column.name]\n    let max = !this.smallScreen ? column?.maxLength : column?.maxLength/2;\n\n    if (max && txt.length > max){\n      return txt.substring(0, max);\n    }\n\n    return txt;\n\n  }\n  textTruncated(row: any, column: Column) {\n\n    let txt = row[column.name]\n\n    let max = !this.smallScreen ? column?.maxLength : column?.maxLength / 2;\n\n    if (max && txt.length > max) {\n      return true\n    }\n\n    return false;\n\n  }\n}\n","<ng-container [ngSwitch]=\"column.type\">\n  <ng-container *ngSwitchCase=\"'checkbox'\">\n    <spa-check [value]=\"row[column.name]\" [readonly]=\"true\"></spa-check>\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'select'\">\n    <spa-select-lite [options]=\"column.options\" [optionDisplay]=\"column.optionDisplay\" [optionValue]=\"column.optionValue\" [(value)]=\"row[column.name]\" width=\"90%\"></spa-select-lite>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'chip'\">\n    <button mat-stroked-button [class.chip-inert]=\"!column.detailsConfig\" [tabIndex]=\"column.detailsConfig ? 0 : -1\" (click)=\"onChipClick(column, row)\" [ngStyle]=\"{'background-color': vm.color || '#eceff1', 'color': 'rgba(0, 0, 0, 0.87)', 'border': 'none'}\">{{row[column.name]}}</button> <!-- Changed: a chip only OFFERS a click when it can honour one — chip-inert and tabindex -1 withdraw the cursor/hover/focus affordance, onChipClick withdraws the behaviour -->\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <!-- Added: chips — one chip per item of an array field. Same chip as above (mat-stroked-button, same fill, same\n       inert rules), laid out in a row that does NOT wrap while collapsed, so a cell of nine hires is exactly as\n       tall as a cell of one and the money column beside it never moves. The +n opens the rest in place. -->\n  <ng-container *ngSwitchCase=\"'chips'\">\n    <div class=\"chips-cell\" [class.chips-open]=\"chipsExpanded\">\n      <button mat-stroked-button class=\"chip-item\" *ngFor=\"let chip of (chipsExpanded ? vm.chips : vm.chipsVisible)\" [class.chip-inert]=\"!column.detailsConfig || !chip.data\" [tabIndex]=\"column.detailsConfig && chip.data ? 0 : -1\" (click)=\"onChipItemClick(chip)\" [ngStyle]=\"{'background-color': vm.color || '#eceff1', 'color': 'rgba(0, 0, 0, 0.87)', 'border': 'none'}\">{{chip.label}}</button>\n      <button mat-stroked-button class=\"chip-item chip-more\" *ngIf=\"vm.chipsMore\" (click)=\"toggleChips()\" [matTooltip]=\"chipsExpanded ? 'Show fewer' : vm.chipsMore + ' more'\" matTooltipPosition=\"above\">{{chipsExpanded ? 'Less' : '+' + vm.chipsMore}}</button>\n    </div>\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'icon'\">\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'date'\">\n    {{row[column.name] | date : (smallScreen ? 'd MMM' : 'dd/MM/yyyy')}} <!-- Changed: a 'date' column resolves to the 'd MMM' short form on mobile without any consumer config change — conserving width on phones. Note it drops the year, so two dates a year apart both read '1 Jan'. datetime/datetimesec are deliberately untouched. -->\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'date-short'\">\n    {{row[column.name] | date : 'd MMM'}}\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'datetime'\">\n    {{row[column.name] | date : 'dd/MM/yyyy HH:mm'}}\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'datetimesec'\">\n    {{row[column.name] | date : 'dd/MM/yyyy HH:mm:ss'}}\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'money'\">\n    <label [ngStyle]=\"{'color': vm.color }\">{{row[column.name] | currency:'':''}}</label>\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <!-- Added: monogram — the row still holds the full name, so filter/sort keep working on the underlying value -->\n  <ng-container *ngSwitchCase=\"'monogram'\">\n    <spa-monogram [value]=\"row[column.name]\" [key]=\"column.keyField ? row[column.keyField] : null\" (tapped)=\"onMonogramTap($event)\"></spa-monogram> <!-- Changed: tap opens the column's detailsConfig when it declares one, and still banners the full name when it does not -->\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchCase=\"'button'\">\n    <button mat-stroked-button (click)=\"onColumnClick(column, row)\" [ngStyle]=\"{'color': vm.color}\" >{{row[column.name]}}</button>\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n\n  <ng-container *ngSwitchDefault>\n    <label [ngStyle]=\"{'color': vm.color }\">\n      <ng-container *ngIf=\"column.type === 'number'\">\n        {{row[column.name] | number:'1.0-2'}}\n      </ng-container>\n      <ng-container *ngIf=\"column.type !== 'number'\">\n        {{vm.text}}\n      </ng-container>\n    </label>\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.truncated\" matTooltip='Show more'  matTooltipPosition=\"above\" (click)=\"showBanner(row[column.name])\">more_horiz</mat-icon>\n    <mat-icon class=\"col-icon\" *ngIf=\"vm.showColumnIcon\" [matTooltip]=\"row[column.icon.tipField] ?? column.icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[column.icon.tipField])\" [style.color]=\"column.icon?.color\">{{column.icon.name }}</mat-icon>\n    <ng-container *ngFor=\"let icon of vm.visibleIcons\">\n      <mat-icon class=\"col-icon\" [matTooltip]=\"row[icon.tipField] ?? icon?.tip\" matTooltipPosition=\"above\" (click)=\"showBanner(row[icon.tipField])\" [style.color]=\"icon.color\">{{icon.name }}</mat-icon>\n    </ng-container>\n  </ng-container>\n</ng-container>\n","import { Component, Input, Output, EventEmitter, OnChanges, ChangeDetectionStrategy } from '@angular/core'; // TS-1: ChangeDetectionStrategy\nimport { Button, TableConfig } from '../../classes/Classes';\nimport { ButtonService } from '../../services/button.service';\n\n// TS-2: resolved per-button view-model — computed once per row (ngOnChanges) instead of running the\n// visibility/access/icon/color pipeline for every button on every change-detection cycle.\ninterface ActionButtonVM { button: Button; name: string; visible: boolean; disabled: boolean; color: string; icon: string; }\n\n@Component({\n    selector: 'app-table-action',\n    templateUrl: './table-action.component.html',\n    styleUrls: ['./table-action.component.css'],\n    changeDetection: ChangeDetectionStrategy.OnPush, // TS-1: pure @Input leaf, VMs computed in ngOnChanges — safe for OnPush\n    standalone: false\n})\nexport class TableActionComponent implements OnChanges {\n\n  constructor(private buttonService: ButtonService) {\n   }\n\n  @Input() displayedButtons: Button[];\n  @Input() config: TableConfig;\n  @Input() row: any;\n  @Input() smallScreen = false;\n\n  @Output() actionClick = new EventEmitter<{ name: string, row: any, button: Button }>(); // Changed: emit the Button the row actually rendered, not just its name. A name is not unique — table-config.service unshifts the four framework approvals buttons onto a table's own array, so a table that declares its own 'approve'/'cancel' carries TWO buttons under one name and the consumer could only ever resolve the first one\n\n  // TS-2: precomputed VMs the template binds to. Recomputed only when inputs (row/displayedButtons/config/smallScreen) change.\n  visibleVMs: ActionButtonVM[] = [];\n  overflowVMs: ActionButtonVM[] = [];\n\n  ngOnChanges() {\n    if (!this.displayedButtons || !this.row) { this.visibleVMs = []; this.overflowVMs = []; return; }\n    this.visibleVMs = this.computeVisibleButtons().map(b => this.toVM(b));\n    this.overflowVMs = this.computeOverflowButtons().map(b => this.toVM(b));\n  }\n\n  private toVM(button: Button): ActionButtonVM {\n    return {\n      button,\n      name: button.name,\n      visible: this.buttonService.testVisible(button, this.row, this.config),\n      disabled: this.buttonService.testDisabled(button, this.row, this.config),\n      color: this.buttonService.getButtonColor(button, this.row),\n      icon: this.buttonService.getIcon(button, this.config),\n    };\n  }\n\n  testVisible(row: any, buttonName: string): boolean {\n    const button = this.displayedButtons.find(b => b.name === buttonName);\n    return button ? this.buttonService.testVisible(button, row, this.config) : false;\n  }\n\n  testDisabled(row: any, buttonName: string): boolean {\n    const button = this.displayedButtons.find(b => b.name === buttonName);\n    return button ? this.buttonService.testDisabled(button, row, this.config) : true;\n  }\n\n  getButtonColor(button: Button, row: any): string {\n    return this.buttonService.getButtonColor(button, row);\n  }\n\n  getIcon(buttonName: string): string {\n    const button = this.displayedButtons.find(b => b.name === buttonName);\n    return button ? this.buttonService.getIcon(button, this.config) : '';\n  }\n\n  onActionClick(button: Button, row: any) { // Changed: takes the rendered Button instead of its name, so the click executes the button the operator actually saw\n    this.actionClick.emit({ name: button.name, row, button });\n  }\n\n  private computeVisibleButtons(): Button[] {\n\n    // Get visible buttons first\n    const visibleButtons = this.buttonService.getVisibleButtons(this.displayedButtons, this.row, this.config);\n    const maxCount = this.config?.maxButtonsCount ?? 3;\n\n    if (this.smallScreen) {\n      if (this.config?.minButtons) {\n        // Get buttons defined in minButtons\n        const minButtonsList = visibleButtons.filter(button => this.config.minButtons.includes(button.name));\n        const remainingButtons = visibleButtons.filter(button => !this.config.minButtons.includes(button.name));\n        // Changed: If there are overflow buttons, reduce visible by 1 to make room for More button\n        const hasOverflow = remainingButtons.length > 0;\n        return hasOverflow && minButtonsList.length > 0\n          ? minButtonsList.slice(0, minButtonsList.length - 1)\n          : minButtonsList;\n      } else {\n        // Changed: If more than 1 button, show none inline (More button takes the slot)\n        return visibleButtons.length > 1 ? [] : visibleButtons.slice(0, 1);\n      }\n    }\n\n    // Changed: If overflow exists, reduce visible count by 1 to make room for More button\n    const hasOverflow = visibleButtons.length > maxCount;\n    return hasOverflow\n      ? visibleButtons.slice(0, maxCount - 1)\n      : visibleButtons.slice(0, maxCount);\n  }\n\n  private computeOverflowButtons(): Button[] {\n\n    // Get visible buttons first\n    const visibleButtons = this.displayedButtons?.filter(button => this.buttonService.testVisible(button, this.row, this.config)) ?? [];\n    const maxCount = this.config?.maxButtonsCount ?? 3;\n\n    if (this.smallScreen) {\n      if (this.config?.minButtons) {\n        const minButtonsList = visibleButtons.filter(button => this.config.minButtons.includes(button.name));\n        const remainingButtons = visibleButtons.filter(button => !this.config.minButtons.includes(button.name));\n        // Changed: Include displaced minButton (if any) plus remaining buttons\n        const hasOverflow = remainingButtons.length > 0;\n        const displacedButton = hasOverflow && minButtonsList.length > 0\n          ? minButtonsList.slice(-1)\n          : [];\n        return [...displacedButton, ...remainingButtons];\n      } else {\n        // Changed: All buttons go to overflow when more than 1 exists\n        return visibleButtons.length > 1 ? visibleButtons : [];\n      }\n    }\n\n    // Changed: If overflow exists, include displaced button plus remaining\n    const hasOverflow = visibleButtons.length > maxCount;\n    return hasOverflow\n      ? visibleButtons.slice(maxCount - 1)\n      : [];\n  }\n}\n","<!-- TS-2: iterate precomputed view-models; no per-cell method calls or getters during change detection -->\n<ng-container *ngFor=\"let vm of visibleVMs\">\n\n  <ng-container *ngIf=\"vm.name != 'create' && vm.visible\">\n    <button mat-icon-button [matTooltip]=\"vm.button.tip ?? (vm.name | titlecase)\" matTooltipPosition=\"above\" style=\"margin-right:5px\" [disabled]=\"vm.disabled\" (click)=\"onActionClick(vm.button, row)\">\n      <mat-icon [style.color]=\"vm.color\">{{vm.icon}}</mat-icon>\n    </button>\n  </ng-container>\n\n  <ng-container *ngIf=\"vm.name != 'create' && !vm.visible && config?.collapseButtons === false\">\n    <label style=\"margin-right: 35px;\"></label>\n  </ng-container>\n\n</ng-container>\n\n<button *ngIf=\"overflowVMs.length > 0\" mat-icon-button [matMenuTriggerFor]=\"menu\" [matTooltip]=\"'More actions'\" matTooltipPosition=\"above\">\n  <mat-icon>more_vert</mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\">\n  <ng-container *ngFor=\"let vm of overflowVMs\">\n    <button *ngIf=\"vm.visible\" mat-menu-item [disabled]=\"vm.disabled\" (click)=\"onActionClick(vm.button, row)\">\n      <mat-icon [style.color]=\"vm.color\">\n        {{vm.icon}}\n      </mat-icon>\n      <span>{{vm.button.tip ?? (vm.name | titlecase)}}</span>\n    </button>\n  </ng-container>\n</mat-menu>\n","// Added (email-single): the single-address email contract, in ONE place, so the form and the inline-edit cell\n// cannot drift apart on either the pattern or the wording of the failure.\n//\n// 🔑 This is deliberately NOT a mode of `type: 'email'`. That type is a mat-chip-grid holding a LIST and storing a\n// semicolon-delimited string; a single contact column wants one value and a plain text box. `email-single` is the\n// separate type for that case — see the note on Field.type in classes/Classes.ts.\n//\n// The pattern is ANCHORED on purpose. spa-text re-tests it on blur with a bare `new RegExp(pattern)`, which is a\n// SUBSTRING match — unanchored, \"a@b.com;c@d.com\" would pass the very check that exists to keep a list out of a\n// single-address field, which is the one mistake this type is here to prevent.\nexport const EMAIL_SINGLE_REGEX = {\n  pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$',\n  message: 'Enter a single valid email address'\n};\n","// Multi-line textarea component extracted from TextComponent\nimport { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormControl, Validators } from '@angular/forms';\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-text-area',\n    templateUrl: './text-area.component.html',\n    styleUrls: ['./text-area.component.css'],\n    standalone: false\n})\nexport class TextAreaComponent implements OnInit, OnChanges {\n\n  constructor() {  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['value'] && this.control) {\n      if (this.control.value !== changes['value'].currentValue) {\n        this.control.setValue(changes['value'].currentValue, { emitEvent: false });\n      }\n    }\n    \n    if (changes['readonly'] && this.control) {\n      this.initControl();\n    }\n  }\n\n  // Changed: the \"Enter <display>\" freeze that lived here is gone — see computedPlaceholder below.\n  ngOnInit(): void {\n  }\n\n  ngAfterViewInit() {\n    this.initControl();\n\n    if (this.value) {\n      this.control.setValue(this.value, { emitEvent: false });\n    }\n\n    this.control.valueChanges.subscribe(val => {\n      this.value = val;\n      this.control.markAsDirty();\n      this.valueChange.emit(val);\n    });\n  }\n\n  @Input() appearance: 'fill' | 'outline' = 'outline';\n  @Input() readonly = false;\n  @Input() hint = \"\";\n  @Input() display = \"\";\n  @Input() placeholder = \"\";\n  // Added: derived resting placeholder. A textarea is typed into, so the verb is \"Enter\". Explicit wins.\n  get computedPlaceholder(): string { return derivePlaceholder('enter', this.display, this.placeholder, this.readonly); }\n  @Input() value = \"\";\n  @Output() valueChange = new EventEmitter();\n\n  @Output() leave = new EventEmitter();\n  @Output() enterPress = new EventEmitter();\n\n  @Input() rows = 3; // Changed: Default rows for textarea\n  @Input() width = \"100%\";\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n\n  @Input() required = true;\n  @Input() min = 0;\n  @Input() max = 9000000000000000;\n  @Input() regex?: { pattern: string; message: string };\n\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n\n  isHovered = false;\n  onMouseEnter(): void {\n    this.isHovered = true;\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n  }\n\n  initControl() {\n    if (this.readonly) {\n      this.control.setValidators(null);\n      this.control.updateValueAndValidity();\n      return;\n    }\n    \n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    if (this.min > 0) {\n      validators.push(Validators.minLength(this.min));\n    }\n    \n    if (this.max < 9000000000000000) {\n      validators.push(Validators.maxLength(this.max));\n    }\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    this.control.setValidators(validators);\n    this.control.updateValueAndValidity();\n  }\n\n  leaved() {\n    this.control.markAsTouched();\n    this.leave.emit();\n\n    if (this.regex && this.value) {\n      const regexPattern = new RegExp(this.regex.pattern);\n      if (!regexPattern.test(this.value)) {\n        this.control.setErrors({ 'pattern': true });\n      }\n    }\n  }\n\n  clear() {\n    this.value = \"\";\n    this.control.setValue(\"\", { emitEvent: false });\n    this.control.markAsDirty();\n    this.control.markAsTouched();\n    this.valueChange.emit(this.value);\n  }\n\n  enterPressed() {\n    this.enterPress.emit();\n  }\n\n  control = new FormControl('', this.getValidators());\n\n  private getValidators() {\n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    validators.push(Validators.minLength(this.min));\n    validators.push(Validators.maxLength(this.max));\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    return validators;\n  }\n\n  validate(control: FormControl): string {\n    if ((this.required || this.min > 0) && control.hasError('required')) {\n      return `Required`;\n    }\n\n    if (control.hasError('minlength')) {\n      return `Minimum length is ${this.min}`;\n    }\n\n    if (control.hasError('maxlength')) {\n      return `Maximum length is ${this.max}`;\n    }\n\n    if (control.hasError('pattern')) {\n      return this.regex?.message || 'Invalid Input';\n    }\n\n    return \"\";\n  }\n}\n","<!-- Multi-line textarea input -->\n<mat-form-field [class.spa-readonly]=\"readonly\" [hideRequiredMarker]=\"!required\" [hintLabel]=\"hint\" [ngStyle]=\"{'width':width ?? '100%'}\" style=\"margin-right: 5px;\" [appearance]=\"appearance ?? 'fill'\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\">\n  <mat-label>{{display}}</mat-label>\n  <textarea matInput autocomplete=\"off\" [rows]=\"rows\" (keyup.enter)=\"enterPressed()\" [placeholder]=\"computedPlaceholder\" [formControl]=\"control\" [required]=\"required\" [readonly]=\"readonly\"></textarea>\n  <mat-error *ngIf=\"control.invalid && (control.dirty || control.touched)\">{{validate(control)}}</mat-error>\n  <div matSuffix class=\"suffix-icons\">\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\n  </div>\n</mat-form-field>\n","import { AfterViewInit, Component, EventEmitter, Input, OnInit, OnChanges, SimpleChanges, Output, ViewChild } from '@angular/core';\nimport { AbstractControl, NgModel, ValidationErrors, ValidatorFn, Validators } from '@angular/forms'; // Added (G20-1): the bound validators this control never had\nimport { DateBounds } from '../../classes/DateBounds'; // Added (NFD-1): resolves dynamic 'today' bounds\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-datetime',\n    templateUrl: './datetime.component.html',\n    styleUrls: ['./datetime.component.css'],\n    standalone: false\n})\nexport class DatetimeComponent implements OnInit, OnChanges, AfterViewInit {\n\n  constructor() { }\n\n  ngOnInit(): void {\n    this.refreshBounds();\n    this.refreshReadonlyText(); // Added (DTM-1): a field that opens already read-only must render its value on the first pass, not wait for a change\n  }\n\n  // Added (G20-1): the ngModel this template already names `#dtControl`. It is the only handle on the control\n  // Angular actually validates — the component owns no FormControl of its own.\n  @ViewChild('dtControl') dtControl?: NgModel;\n\n  // Added (G20-1): the control does not exist until the view is built, so this is the first point at which a\n  // declared bound can reach it. refreshBounds() has already run in ngOnInit and returned early for that reason.\n  ngAfterViewInit(): void {\n    this.applyValidators();\n  }\n\n  // Added (NFD-1): a config can flip min/max at runtime, so the resolved attributes have to follow it.\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['min'] || changes['max'] || changes['boundContext']) this.refreshBounds(); // Changed (SBD-1): boundContext joins them — a function bound keeps one reference, so the row it reads is the thing that changes\n    if (changes['required']) this.applyValidators(); // Added (G20-1): requiredCondition flips this at runtime, exactly as date.component.ts:78 notes\n    if (changes['value'] || changes['readonly']) this.refreshReadonlyText(); // Added (DTM-1): the read-only branch renders a plain field, so it has to be recomputed wherever the value or the lock can move\n  }\n\n  @Input() display = \"\";\n\n  // Added: same 'Pick {label}' convention as spa-date, and the same override precedence. NOTE it is only carried in\n  // the DOM here: this control is a native <input type=\"datetime-local\">, and every browser paints its own\n  // \"dd/mm/yyyy --:--\" format hint over the placeholder, so the attribute is authoritative for tests and assistive\n  // tech but is not what a sighted user reads. The mat-label above is what actually names the field on screen.\n  @Input() placeholder = \"\";\n  get computedPlaceholder(): string { return derivePlaceholder('pick', this.display, this.placeholder, this.readonly); }\n\n  @Input() value: string | null = \"\"; // Changed: widened to allow null — a cleared field emits null, not ''\n  @Output() valueChange = new EventEmitter();\n  @Input() readonly = false;\n  @Input() width = \"100%\";\n\n  // Added: this component had no `required` input AT ALL, so form.component.html could not have passed one even\n  // if it had tried — a required datetime showed no asterisk, no aria-required and no mat-error, and the only\n  // refusal was the API's. Defaults false: title-actions renders a spa-datetime without binding it.\n  @Input() required = false;\n\n  @Input() min = \"01 jan 1900\";\n\n  @Input() max = \"31 dec 9999\";\n\n  // Added (SBD-1): the row object handed to a FUNCTION bound, so `min: (row) => ...` sees what the user has entered.\n  // Same contract as spa-date — see date.component.ts for why a function bound is the form to reach for when a\n  // window depends on another field.\n  @Input() boundContext: any = null;\n\n  // Added (NFD-1): the RESOLVED bounds the template binds. min/max stay the raw config values so a token like\n  // 'today' survives for isDynamic/refresh; these two carry the local 'YYYY-MM-DDTHH:mm' the native\n  // datetime-local input actually requires. Plain fields, not getters — a template-bound getter formatting a\n  // date would allocate on every change-detection pass, which is banned here.\n  minAttr = \"\";\n  maxAttr = \"\";\n\n  // Re-resolves both bounds. Also called on focus, so a form left open across midnight cannot go on offering\n  // yesterday's \"today\" as the ceiling.\n  refreshBounds(): void {\n    // 🔴 Changed (SBD-1): DateBounds.resolve now returns NULL for an absent or unparseable bound where it used to\n    // return an Invalid Date, so the null has to be handled HERE or toLocalInput dereferences it and throws. This is\n    // not hypothetical: form.component.html binds [min]=\"field.min\", and the overwhelming majority of datetime\n    // fields in the estate declare no min at all, so undefined is the COMMON case on this path, not the edge case.\n    // An empty attribute is how a native <input type=\"datetime-local\"> spells \"no bound\".\n    const min = DateBounds.resolve(this.min, 'start', this.boundContext);\n    const max = DateBounds.resolve(this.max, 'end', this.boundContext); // 'end' → 23:59 today, so any time TODAY passes and tomorrow 00:00 does not\n    this.minAttr = min ? DateBounds.toLocalInput(min) : \"\";\n    this.maxAttr = max ? DateBounds.toLocalInput(max) : \"\";\n    this.applyValidators(); // Added (G20-1): the resolved window is the validator's only input, so it is rebuilt wherever the window moves\n  }\n\n  // Added (G20-1): tracks whether this component has ever taken ownership of the control's validator set. While it\n  // is false the directive-composed validator (the [required] on the input) is left EXACTLY as Angular built it,\n  // which is what keeps a field declaring no bounds byte-for-byte unchanged. Once a bound has been enforced the\n  // component must keep managing the set, or releasing that bound would leave it in force for ever.\n  private boundsApplied = false;\n\n  // Added (G20-1): min/max were DEAD on this control. They are bound to a native <input type=\"datetime-local\"> as\n  // [min]/[max], and Angular's MinValidator/MaxValidator directives match `input[type=number][min]...` ONLY\n  // (@angular/forms 20.3.14, forms.mjs:6536) — so nothing attached and nothing validated. The browser's own\n  // ValidityState.rangeUnderflow did fire, but ngModel never reads native validity: the out-of-range value passed\n  // straight through [(ngModel)] into the form's data object and posted. The picker half always worked — the\n  // attributes really do grey out-of-range values in the calendar — which is precisely why this looked wired up.\n  private applyValidators(): void {\n    const control = this.dtControl?.control;\n    if (!control) { return; } // ngOnInit and an early ngOnChanges both run before the view exists\n\n    const bounds: ValidatorFn[] = [];\n    if (this.minAttr) bounds.push(this.boundValidator(this.minAttr, 'min'));\n    if (this.maxAttr) bounds.push(this.boundValidator(this.maxAttr, 'max'));\n\n    // An UNDECLARED bound resolves to \"\" (DateBounds.resolve returns null for absent/unparseable), and\n    // form.component.html binds [min]=\"field.min\", so undefined is the COMMON case in the estate. In that state\n    // this method touches nothing at all — no setValidators, no updateValueAndValidity — and the control is left\n    // with the validator Angular composed from the template. Untracked consumer apps cannot move.\n    if (!bounds.length && !this.boundsApplied) { return; }\n\n    this.boundsApplied = bounds.length > 0;\n    // Validators.required is re-stated because setValidators REPLACES the directive-composed set. `required` is\n    // read live, so a requiredCondition flip is honoured on the next call.\n    control.setValidators(this.required ? [Validators.required, ...bounds] : bounds);\n    control.updateValueAndValidity({ emitEvent: false }); // emitEvent:false — recomputing validity must not look like the user edited the box\n  }\n\n  // Added (G20-1): compares against the SAME local 'YYYY-MM-DDTHH:mm' string already published to the input's\n  // min/max attribute, so the validator and the picker can never disagree about the window. Both sides parse as\n  // LOCAL time (a datetime-local string carries no zone), which is the reason toLocalInput exists and toISOString\n  // is refused here. An EMPTY value is left to `required` — a bound must never make emptiness an error.\n  private boundValidator(attr: string, edge: 'min' | 'max'): ValidatorFn {\n    return (c: AbstractControl): ValidationErrors | null => {\n      const raw = c.value;\n      if (raw === null || raw === undefined || raw === '') return null;\n      const actual = new Date(raw).getTime();\n      const limit = new Date(attr).getTime();\n      if (isNaN(actual) || isNaN(limit)) return null; // a half-typed datetime is not an out-of-range one\n      const violates = edge === 'min' ? actual < limit : actual > limit;\n      return violates ? { [edge]: { [edge]: attr, actual: raw } } : null;\n    };\n  }\n\n  // Added (G20-1): the mat-error rendered the literal word \"Required\" for every error there could be, which was\n  // harmless only while `required` was the only validator that existed. Mirrors number.component.ts:validate().\n  validate(model: NgModel | null): string {\n    const control = model?.control;\n    if (!control) return \"\";\n    if (this.required && control.hasError('required')) return `Required`;\n    if (control.hasError('min')) return `Earliest allowed is ${this.readableBound(this.minAttr)}`;\n    if (control.hasError('max')) return `Latest allowed is ${this.readableBound(this.maxAttr)}`;\n    return \"\";\n  }\n\n  // Added (G20-1): 'YYYY-MM-DDTHH:mm' is a machine format. The T is what makes it unreadable, so only the T goes —\n  // the surrounding date order stays exactly as the native input renders it, so the message and the box agree.\n  private readableBound(attr: string): string {\n    return attr ? attr.replace('T', ' ') : \"\";\n  }\n\n  changed() {\n    // Changed: normalise '' to null before emitting. A datetime-local input emptied from the KEYBOARD\n    // (select-all + delete) writes '' straight through [(ngModel)], while the X path below emits null — so the\n    // SAME user action, emptying the SAME field, emitted two different things depending on how it was done.\n    // Measured on test-spa 2026-08-15 by wrapping this component's valueChange.emit: X emitted null, keyboard\n    // emitted ''. Every sibling control already agrees with itself (number and money emit null on both paths,\n    // text emits '' on both, date has no keyboard path at all because its input is [readonly]=\"true\").\n    // null is also the only one of the two that BINDS: \"\" is not a DateTime and fails model binding on arrival,\n    // the same reason spa-money refuses to emit '' for a double. Mirrors clear() below exactly.\n    if (this.value === '') this.value = null;\n    this.valueChange.emit(this.value);\n  }\n\n  // Added: the spa-suffix X was handed [clearContent] but no (clearClick) handler, so the click emptied the\n  // suffix's own value and the form never heard about it — the visible box cleared (it is [(ngModel)]-bound)\n  // while the model kept the old datetime, so the STALE value saved on a clear the user had performed.\n  // Emits null, never '' — \"\" is not a DateTime and fails model binding on arrival.\n  clear(): void {\n    this.value = null;\n    this.refreshReadonlyText(); // Added (DTM-1): keep the read-only rendering in step with an internally-driven change\n    this.valueChange.emit(this.value);\n  }\n\n  // Added (DTM-1): what the READ-ONLY text box displays. A plain field, deliberately not a getter — this\n  // formats a date, and a template-bound getter doing that allocates on every change-detection pass, which is\n  // banned here. Same reasoning, and the same shape, as minAttr/maxAttr above.\n  readonlyText = \"\";\n\n  private refreshReadonlyText(): void {\n    this.readonlyText = this.toReadable(this.value);\n  }\n\n  // Added (DTM-1): 'YYYY-MM-DDTHH:mm' → 'dd/MM/yyyy HH:mm', the SAME form spa-label and spa-table already\n  // render a datetime in (label.component.html:34, table-row.component.html:59), so a field reads identically\n  // whether it is locked in a form or listed in a table. Read straight off the string when it is already a\n  // LOCAL datetime-local value — parsing and reformatting that would risk a timezone shift for no gain. A\n  // string carrying an explicit zone ('Z' or ±hh:mm) is the one case that must go through Date, because its\n  // literal prefix is UTC and would display an hour that is not the user's.\n  private toReadable(v: string | null): string {\n    if (!v) return \"\";\n    const raw = String(v);\n    const zoned = /(Z|[+-]\\d{2}:?\\d{2})$/.test(raw);\n    const local = zoned ? this.toLocalOrEmpty(raw) : raw;\n    const m = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})/.exec(local);\n    return m ? `${m[3]}/${m[2]}/${m[1]} ${m[4]}:${m[5]}` : raw; // an unrecognised string is shown verbatim rather than blanked — hiding a value we cannot parse is worse than showing it\n  }\n\n  private toLocalOrEmpty(raw: string): string {\n    const d = new Date(raw);\n    return isNaN(d.getTime()) ? \"\" : DateBounds.toLocalInput(d);\n  }\n\n\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n\n\n  isHovered = false;\n  \n  onMouseEnter(): void {\n    this.isHovered = true;\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n  }\n\n}\n","<!-- Changed: Added mouse events for hover tracking and spa-suffix component -->\n<mat-form-field [class.spa-readonly]=\"readonly\" [hideRequiredMarker]=\"!required\" [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\"><!-- Changed: [hideRequiredMarker] added so a required datetime shows the asterisk every text field shows -->\n<mat-label>{{display}}</mat-label>\n<!-- Changed (DTM-1): the editable control and its error are now wrapped together, because a template reference variable is scoped to the embedded view that declares it — #dtControl inside an *ngIf is invisible to a sibling mat-error outside it. Nothing about this branch itself changed. -->\n<ng-container *ngIf=\"!readonly\">\n  <input matInput autocomplete=\"off\" type=\"datetime-local\" #dtControl=\"ngModel\" [(ngModel)]=\"value\" [required]=\"required\" [min]=\"minAttr\" [max]=\"maxAttr\" (focus)=\"refreshBounds()\" (change)=\"changed()\" [placeholder]=\"computedPlaceholder\" /><!-- Changed: [required] bound — Angular's RequiredValidator then attaches to this ngModel, which is what supplies both aria-required and the invalid state the mat-error below reads. Changed (DTM-1): [readonly] dropped — this branch only ever renders when the field IS editable, so the binding was always false here. -->\n  <mat-error *ngIf=\"dtControl.invalid && (dtControl.dirty || dtControl.touched)\">{{validate(dtControl)}}</mat-error><!-- Added: there was no mat-error element on this component at all. Changed (G20-1): was the literal word \"Required\", which was the only error that could occur while min/max were inert; now that a declared bound validates, the message has to say WHICH rule was broken. Same dynamic subscript, same single line, no layout change. -->\n</ng-container>\n<!-- Added (DTM-1): the READ-ONLY branch is a plain text box, and that is the whole fix. A native <input type=\"datetime-local\"> ALWAYS paints its own \"dd/mm/yyyy --:--\" mask — the browser owns that glyph, it is not the placeholder attribute — so a locked, EMPTY datetime showed a mask where rop-1 (c7c36ba) had just made every other field type render blank, and it read like a value that failed to load. It also kept a live calendar picker on a field nobody may edit. A text input has no mask and no picker, so empty reads blank and a set value reads dd/MM/yyyy HH:mm — the same form spa-label and spa-table already render a datetime in. No ngModel here on purpose: this branch must never write. -->\n<input *ngIf=\"readonly\" matInput autocomplete=\"off\" type=\"text\" readonly [value]=\"readonlyText\" [placeholder]=\"computedPlaceholder\" />\n    <div matSuffix class=\"suffix-icons\">\n      <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix><!-- Changed: (clearClick) was missing, so the X emptied the box on screen but the old datetime still saved -->\n    </div>\n</mat-form-field>\n","import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';\nimport {  Action, ApiResponse, Button, DetailsDialogConfig, FormConfig, TableConfig } from '../../classes/Classes'; // Changed: FormConfig added — it types the memo key for the hoisted tmpTableConfig\nimport { MessageService } from '../../services/message.service';\nimport { DialogService } from '../../services/dialog.service';\nimport { SelectCommonComponent } from '../select-common/select-common.component';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { ButtonService } from '../../services/button.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: base class now takes it — a failed loadAction is no longer silent (WS-6 Phase 3)\nimport { OfflineService } from '../../services/offline.service'; // Added (WS-1 Phase 3): base class now takes it — a select whose options could not be cached says so on the field\n\n@Component({\n    selector: 'spa-select',\n    templateUrl: './select.component.html',\n    styleUrls: ['./select.component.css'],\n    standalone: false\n})\nexport class SelectComponent extends SelectCommonComponent implements OnInit, OnChanges {\n\n  constructor(\n    protected override messageService: MessageService, protected override dataService: DataServiceLib,\n    private dialogService: DialogService, private buttonService: ButtonService ,\n    apiErrorService: ApiErrorService, // Added: forwarded to the base class, which presents failed option loads\n    offline: OfflineService, // Added: forwarded to the base class, which uses it to tell an offline cache miss from a server failure\n\n  ) {\n    super(messageService,dataService,apiErrorService,offline); // Changed: base constructor gained apiErrorService, then offline\n  }\n\n  override ngOnInit(): void {\n\n    // Always load data if loadAction is provided to ensure fresh data after cache expiration\n    if (this.loadAction) {\n      // TS-19: apply a modest 5-min default cache so reference-data options aren't re-fetched on every dialog open.\n      // Leave actions that already set cacheDurationMinutes or skipCache untouched; master-field (dependent) selects\n      // never reach the network here (getData returns early when masterField is set), so they are unaffected.\n      const action = (this.loadAction.cacheDurationMinutes === undefined && !this.loadAction.skipCache)\n        ? { ...this.loadAction, cacheDurationMinutes: 5 }\n        : this.loadAction;\n      this.getData(action);\n    }\n\n    this.resolveAddOptionLabel(); // Added (dropdown quick-add): compute once inputs are bound\n\n  }\n\n  // Changed: re-fetch when a {placeholder} loadAction URL resolves to a different value (e.g. the customer changed on the load form).\n  // resolveLoadAction memoizes on the resolved URL, so fields without a placeholder keep the same object and never reach the re-fetch.\n  override ngOnChanges(changes?: SimpleChanges): void {\n    super.ngOnChanges();\n\n    this.resolveAddOptionLabel(); // Added (dropdown quick-add): re-evaluate when detailsConfig/display arrive or change\n\n    const change = changes?.['loadAction'];\n    if (!change || change.firstChange || change.previousValue?.url === change.currentValue?.url) return;\n\n    // Changed: the previous selection belonged to the previous parent, so it cannot stand once the parent changes\n    if (this.value != null) {\n      this.value = null;\n      this.changed();\n    }\n\n    this.getData(change.currentValue);\n  }\n\n  @Input() detailsConfig: DetailsDialogConfig;\n\n  // Added (dropdown quick-add): materialized label for the always-first \"add new\" option (no template-bound getter);\n  // null when the field has no create capability, which keeps the option out of the panel entirely\n  override addOptionLabel: string = null; // override: the base declares it as the inner panel's @Input; here it is self-computed\n\n  // Added: same gate as the plus icon — the option only appears where the icon already would.\n  // Label prefers the create form's title (\"New Customer\"), then the field label with any trailing \"ID\" stripped,\n  // and falls back to a generic \"Add New\" so the option never renders blank.\n  private resolveAddOptionLabel(): void {\n    if (!this.detailsConfig || !this.canCreate()) {\n      this.addOptionLabel = null;\n      return;\n    }\n    const entity = this.detailsConfig.formConfig?.title || this.display?.replace(/\\s+id$/i, '');\n    this.addOptionLabel = entity ? `New ${entity}` : 'Add New';\n  }\n\n  onHoverChange(isHovered: boolean): void {\n    this.isHovered = isHovered;\n  }\n\n  // Added: canCreate() and canView() are both *ngIf-bound (select.component.html), so they ran on every\n  // change-detection pass and each allocated a fresh TableConfig every time — the no-template-bound-allocating-getters\n  // rule. Cached and keyed on the formConfig REFERENCE so a reassigned detailsConfig still rebuilds, matching the\n  // memoised-accessor precedent in tiles.component (ctxCache). Behaviour is identical: buttonService.testVisible only\n  // READS tableConfig?.formConfig?.security and never mutates what it is handed, so one shared instance is safe.\n  private tmpTableConfigCache: TableConfig;\n  private tmpTableConfigKey: FormConfig;\n\n  private getTmpTableConfig(): TableConfig {\n    const formConfig = this.detailsConfig?.formConfig;\n    if (!this.tmpTableConfigCache || this.tmpTableConfigKey !== formConfig) {\n      this.tmpTableConfigKey = formConfig;\n      this.tmpTableConfigCache = { formConfig: formConfig };\n    }\n    return this.tmpTableConfigCache;\n  }\n\n  canCreate(): boolean {\n    if (!this.detailsConfig?.buttons) return false;\n    const createButton : Button = this.detailsConfig.buttons.find(b => b.name === 'create');\n    const tmpTableConfig : TableConfig = this.getTmpTableConfig(); // Changed: was a fresh {formConfig} literal allocated on every change-detection pass\n    return createButton && (!createButton.disabled || !createButton.disabled(this.value)) && this.buttonService.testVisible(createButton, null, tmpTableConfig)    ;\n  }\n\n  canView(): boolean {\n    if (!this.detailsConfig?.buttons) return false;\n    let viewButton : Button = this.detailsConfig.buttons.find(b => b.name === 'view');\n    if (!viewButton) {\n      // Add default view button if not exists — left as-is deliberately: the find() guard makes it idempotent,\n      // and only the TableConfig allocation was hoisted, so this still runs exactly when it did before.\n      viewButton = { name: 'view', dialog: true };\n      this.detailsConfig.buttons.push(viewButton);\n    }\n    const tmpTableConfig: TableConfig = this.getTmpTableConfig(); // Changed: was a fresh {formConfig} literal allocated on every change-detection pass\n    return this.value && viewButton && this.buttonService.testVisible(viewButton, null, tmpTableConfig);\n  }\n\n  onPeekClick(event: MouseEvent, mode: 'create' | 'view'): void {\n    event?.stopPropagation(); // Changed: tolerate a null event — the dropdown \"add new\" option calls this without one\n\n    if (this.detailsConfig) {\n      const dynamicData = mode === 'create' ? {} : { [this.detailsConfig.heroField]: this.value };\n\n      let button = this.detailsConfig.buttons.find(b => b.name === mode);\n      button.detailsConfig = this.detailsConfig;\n\n      this.dialogService.openDefaultDetailsDialog(button, dynamicData).subscribe(result => { // Changed: Use openDefaultDetailsDialog to avoid circular dependency\n        if (result?.message === 'success'){ // Changed: a dismissed quick-add dialog closes with undefined — read through it rather than throwing\n          // Added (dropdown quick-add): auto-select the record the user just created — the point of adding\n          // from a dropdown is to use the new record, so don't make them find it in the list afterwards\n          if (mode === 'create') this.selectCreated(result);\n          this.refresh(event);\n        }\n      });\n\n    } else {\n      this.messageService.toast(\"Peek configuration error\");\n    }\n  }\n\n  // Added (dropdown quick-add): pull the new record's id off the dialog result (create closes with the API\n  // response entity; other close paths return the details object directly) — silently skip if not found\n  private selectCreated(result: any): void {\n    const hero = this.detailsConfig.heroField;\n    if (!hero) return;\n    const createdID = result.data?.data?.[hero] ?? result.data?.[hero];\n    if (createdID == null) return;\n    this.value = createdID;\n    this.valueChange.emit(this.value);\n  }\n\n\n\n}\n\n","<spa-select-common [width]=\"width\" [readonly]=\"readonly\" [required]=\"required\" [defaultFirstValue]=\"defaultFirstValue\"\n                   [readonlyMode]=\"readonlyMode\" [hint]=\"hint\" [placeholder]=\"placeholder\"\n                   [display]=\"display\" [(value)]=\"value\" [options]=\"options\" [masterOptions]=\"masterOptions\" [masterField]=\"masterField\"\n                   [optionValue]=\"optionValue\" [optionDisplay]=\"optionDisplay\" [optionDisplayExtra]=\"optionDisplayExtra\"\n                   [nullable]=\"nullable\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [optionsUnavailableOffline]=\"optionsUnavailableOffline\" [loadAction]=\"loadAction\" [loadIDField]=\"loadIDField\" [field]=\"field\" [data]=\"data\"\n                   [addOptionLabel]=\"addOptionLabel\"\n                   (valueChange)=\"valueChange.emit($event)\"\n                   (hoverChange)=\"onHoverChange($event)\"\n                   (addNew)=\"onPeekClick(null, 'create')\">\n  <ng-container additionalButtons>\n    <button mat-icon-button *ngIf=\"detailsConfig && canCreate() && isHovered\" (click)=\"onPeekClick($event, 'create')\" matTooltip=\"Add\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" style=\"color: green;\">add</mat-icon>\n    </button>\n    <button mat-icon-button *ngIf=\"detailsConfig && canView() && isHovered && value\" (click)=\"onPeekClick($event, 'view')\" matTooltip=\"View\" matTooltipPosition=\"above\">\n      <mat-icon class=\"tinyIcon\" color=\"primary\">launch</mat-icon>\n    </button>\n\n  </ng-container>\n</spa-select-common>\n","import {\n  OnInit,\n  Directive,\n  HostListener,\n  ElementRef, forwardRef\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { DecimalPipe } from '@angular/common';\n\nexport const CURRENCY_INPUT_MASK_DIRECTIVE_VALUE_ACCESSOR: any = {\n  provide: NG_VALUE_ACCESSOR,\n  useExisting: forwardRef(() => CurrencyInputMaskDirective),\n  multi: true\n};\n\n@Directive({\n    selector: '[appCurrencyInputMask]',\n    providers: [\n        CURRENCY_INPUT_MASK_DIRECTIVE_VALUE_ACCESSOR,\n        DecimalPipe\n    ],\n    standalone: false\n})\nexport class CurrencyInputMaskDirective implements ControlValueAccessor, OnInit {\n  private el: HTMLInputElement;\n  private onModelChange: Function;\n  private onModelTouched: Function;\n  private lastNumVal: number;\n  private DECIMAL_MARK = '.';\n\n  constructor(\n    private elementRef: ElementRef,\n    private decimalPipe: DecimalPipe\n  ) { }\n\n  ngOnInit() {\n    this.el = this.elementRef.nativeElement;\n  }\n\n  @HostListener('focus', ['$event'])\n  handleFocus(event: any) {\n    const strVal: string = this.getInputValue();\n    const unmaskedStr: string = this.getUnmaskedValue(strVal);\n    this.updateInputValue(unmaskedStr);\n    // Select all text on focus so typing replaces the current value.\n    // setTimeout ensures selection applies after browser repositions cursor (mouse click and touch).\n    setTimeout(() => {\n      this.el.setSelectionRange(0, this.el.value.length);\n    }, 0);\n  }\n\n  @HostListener('cut', ['$event'])\n  handleCut(event: any) {\n    setTimeout(() => {\n      this.inputUpdated();\n    }, 0);\n  }\n\n  // NOTE: keypress is a DESKTOP-only guarantee. Android soft keyboards and any IME report composing input as\n  // keyCode 229 (or skip keypress entirely), and voice dictation, autofill and paste never fire it at all — which\n  // is exactly why letters could be typed into an amount on a phone while the same field behaved on a laptop.\n  // This handler is kept for the crisp desktop experience (it also positions the caret around the decimal mark),\n  // but sanitizeVisibleValue() in handleInput is the real guard. Do not remove one in favour of the other.\n  @HostListener('keypress', ['$event'])\n  handleKeypress(event: any) {\n    // Restrict characters\n    const newChar: string = String.fromCharCode(event.which);\n    const allowedChars: RegExp = /^[\\d.]+$/;\n    if (!allowedChars.test(newChar)) {\n      event.preventDefault();\n      return;\n    }\n    // Handle decimal mark input\n    const currentValue: string = event.target.value;\n    const separatorIdx: number = currentValue.indexOf(this.DECIMAL_MARK);\n    const hasFractionalPart: boolean = (separatorIdx >= 0);\n    if (!hasFractionalPart || newChar !== this.DECIMAL_MARK) {\n      return;\n    }\n    const isOutsideSelection = !this.isIdxBetweenSelection(separatorIdx);\n    if (isOutsideSelection) {\n      const positionAfterMark = separatorIdx + 1;\n      this.setCursorPosition(positionAfterMark);\n      event.preventDefault();\n      return;\n    }\n  }\n\n  @HostListener('input', ['$event'])\n  handleInput(event: any) {\n    this.sanitizeVisibleValue(); // Added: strips anything non-numeric however it arrived — soft keyboard, IME, voice, paste, autofill\n    this.inputUpdated();\n  }\n\n  // Added: the model was always safe (getUnmaskedValue strips non-digits before parsing), but the INPUT still\n  // displayed whatever was typed until blur silently wiped it. So on a phone a user could type \"abc\" into an\n  // amount, see it sitting there, and only discover on blur that the field had emptied itself — with no idea why.\n  // Removing the characters as they arrive keeps what is on screen and what will be saved the same thing.\n  //\n  // The caret is repositioned by counting how many characters were dropped BEFORE it, rather than being pushed to\n  // the end. Without that, editing the middle of \"1,234.56\" would kick the caret to the end on every keystroke.\n  private sanitizeVisibleValue(): void {\n    const current: string = this.el.value ?? '';\n    const caret: number = this.el.selectionStart ?? current.length;\n\n    // Commas are legitimate here — they are the mask's own thousands separators, re-applied on blur.\n    const cleaned: string = current.replace(/[^\\d.,]/g, '');\n    if (cleaned === current) return;\n\n    const removedBeforeCaret: number = current.slice(0, caret).replace(/[\\d.,]/g, '').length;\n\n    this.el.value = cleaned;\n    const newCaret: number = Math.max(0, caret - removedBeforeCaret);\n    this.setCursorPosition(newCaret);\n  }\n\n  @HostListener('paste', ['$event'])\n  handlePaste(event: any) {\n    setTimeout(() => {\n      this.inputUpdated();\n    }, 1);\n  }\n\n  @HostListener('blur', ['$event'])\n  handleBlur(event: any) {\n    const strVal: string = this.getInputValue();\n    const numVal: number = this.convertStrToDecimal(strVal);\n    this.maskInput(numVal);\n    this.onModelTouched.apply(event);\n  }\n\n  registerOnChange(callbackFunction: Function): void {\n    this.onModelChange = callbackFunction;\n  }\n\n  registerOnTouched(callbackFunction: Function): void {\n    this.onModelTouched = callbackFunction;\n  }\n\n  setDisabledState(value: boolean): void {\n    this.el.disabled = value;\n  }\n\n  writeValue(numValue: number): void {\n    // Changed: keep the dedup cache in step with a PROGRAMMATIC set. inputUpdated() suppresses an emission whenever the\n    // parsed number equals lastNumVal, but writeValue never updated it, so a programmatic set left the cache holding a\n    // number the control no longer had. After the X cleared the field the cache still read 500, and re-entering that\n    // same 500 in ONE input event (paste, autofill, voice dictation) was swallowed: the box showed 500 while the model\n    // stayed null, and null is what saved. Clearing by KEYBOARD never had this, because it runs through inputUpdated and\n    // refreshes the cache — so this is the X-versus-keyboard disagreement, one step later than where it was looked for.\n    // Normalised through Number() so the cache holds the same shape convertStrToDecimal() produces via parseFloat.\n    this.lastNumVal = this.isNumeric(numValue) ? Number(numValue) : null;\n    this.maskInput(numValue);\n  }\n\n  private maskInput(numVal: number): void {\n    if (!this.isNumeric(numVal)) {\n      this.updateInputValue('');\n      return;\n    }\n    const strVal: string = this.convertDecimalToStr(numVal);\n    const newVal: string = this.transformWithPipe(strVal);\n    this.updateInputValue(newVal);\n  }\n\n  private inputUpdated() {\n    this.restrictDecimalValue();\n    const strVal: string = this.getInputValue();\n    const unmaskedVal: string = this.getUnmaskedValue(strVal);\n    const numVal: number = this.convertStrToDecimal(unmaskedVal);\n    if (numVal !== this.lastNumVal) {\n      this.lastNumVal = numVal;\n      this.onModelChange(numVal);\n    }\n  }\n\n  private restrictDecimalValue(): void {\n    const strVal: string = this.getInputValue();\n    const dotIdx: number = strVal.indexOf(this.DECIMAL_MARK);\n    const hasFractionalPart: boolean = (dotIdx >= 0);\n    if (hasFractionalPart) {\n      const fractionalPart: string = strVal.substring(dotIdx + 1);\n      if (fractionalPart.length > 2) {\n        const choppedVal: string = strVal.substring(0, dotIdx + 3);\n        this.updateInputValue(choppedVal, true);\n        return;\n      }\n    }\n  }\n\n\n  private transformWithPipe(str: string): string {\n    return this.decimalPipe.transform(str, '1.2-2');\n  }\n\n  private getUnmaskedValue(value: string): string {\n    return value.replace(/[^-\\d\\\\.]/g, '');\n  }\n\n  private updateInputValue(value: string, savePosition = false) {\n    if (savePosition) {\n      this.saveCursorPosition();\n    }\n    this.el.value = value;\n  }\n\n  private getInputValue(): string {\n    return this.el.value;\n  }\n\n  private convertStrToDecimal(str: string): number {\n    return (this.isNumeric(str)) ? parseFloat(str) : null;\n  }\n\n  private convertDecimalToStr(n: number): string {\n    return (this.isNumeric(n)) ? n + '' : '';\n  }\n\n  private isNumeric(n: any): boolean {\n    return !isNaN(parseFloat(n)) && isFinite(n);\n  }\n\n  private saveCursorPosition() {\n    const position: number = this.el.selectionStart;\n    setTimeout(() => {\n      this.setCursorPosition(position);\n    }, 1);\n  }\n\n  private setCursorPosition(position: number) {\n    this.el.selectionStart = position;\n    this.el.selectionEnd = position;\n  }\n\n  private isIdxBetweenSelection(idx: number) {\n    if (this.el.selectionStart === this.el.selectionEnd) {\n      return false;\n    }\n    return (idx >= this.el.selectionStart && idx < this.el.selectionEnd);\n  }\n\n}\n","import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormControl, Validators } from '@angular/forms';\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n// Added: the documented default ceiling, named once so the @Input default and the validator fallback cannot drift apart.\nconst MONEY_MAX = 9000000000000000; // Math.max 9000000000000000\n\n@Component({\n    selector: 'spa-money',\n    templateUrl: './money.component.html',\n    styleUrls: ['./money.component.css'],\n    standalone: false\n})\nexport class MoneyComponent implements OnInit, OnChanges {\n\n  constructor() { }\n\n  // Changed: the \"Enter <display>\" freeze that lived here is gone — see computedPlaceholder below.\n  ngOnInit(): void {\n  }\n\n  // Sync @Input value changes with FormControl\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['value'] && this.control) {\n      // Update FormControl when parent changes the value, including first change\n      if (this.control.value !== changes['value'].currentValue) {\n        this.control.setValue(changes['value'].currentValue, { emitEvent: false });\n      }\n    }\n    // Added: rebuild the validators whenever a bound or a mode ARRIVES or CHANGES. `control` is a field\n    // initializer, so its validators were built from the class defaults before Angular ever wrote [min]/[max];\n    // nothing re-read them afterwards, which is why a declared min was inert on a required money field.\n    if (changes['min'] || changes['max'] || changes['required'] || changes['readonly']) {\n      this.applyValidators();\n    }\n  }\n\n  ngAfterViewInit() {\n    this.initControl(this.control)\n\n    // Set initial value after view init\n    if (this.value) {\n      this.control.setValue(this.value, { emitEvent: false });\n    }\n\n    // Subscribe to control value changes AFTER initial value is set\n    this.control.valueChanges.subscribe(val => {\n      this.value = val;\n      this.valueChange.emit(val);\n    });\n  }\n\n  // Changed: was two partial branches — readonly cleared the validators and !required re-applied min/max, while a\n  // REQUIRED field was left with whatever the field initializer built and therefore never got its declared min at\n  // any point in its lifecycle. Now every branch goes through applyValidators(), so a bound participates in\n  // validation regardless of mode.\n  initControl(control: FormControl) {\n    this.applyValidators();\n  }\n\n  // Added: the single place the validator set is decided, safe to call whenever an @Input lands.\n  private applyValidators(): void {\n    if (!this.control) { return; }\n\n    if (this.readonly) {\n      this.control.setValidators(null);\n    } else if (this.required) {\n      // Changed: a required field now carries its declared min/max as well as `required`.\n      this.control.setValidators([Validators.required, Validators.min(this.bound(this.min, 0)), Validators.max(this.bound(this.max, MONEY_MAX))]);\n    } else {\n      this.control.setValidators([Validators.min(this.bound(this.min, undefined)), Validators.max(this.bound(this.max, undefined))]);\n    }\n    // emitEvent: false — this can now run after ngAfterViewInit subscribed to valueChanges, and recomputing\n    // validity must not look like the user edited the box.\n    this.control.updateValueAndValidity({ emitEvent: false });\n  }\n\n  // Added: resolves the bound ACTUALLY enforced. The per-branch fallback is deliberate and is what keeps a field\n  // that declares no min/max byte-for-byte identical to today: the required branch has always been validated with\n  // the class defaults (min 0, max 9e15) baked in at construction, whereas the optional branch has always passed\n  // the live @Input straight through — which is `undefined` for an undeclared bound, making Validators.min inert.\n  // Applying the defaults to the optional branch instead would start REJECTING negative amounts on every optional\n  // money field in the estate, including untracked consumers. Only a genuinely declared number changes anything.\n  private bound(declared: any, fallback: number | undefined): number | undefined {\n    return typeof declared === 'number' && !isNaN(declared) ? declared : fallback;\n  }\n\n  @Input() readonly = false;\n  @Input() hint = \"\";\n  @Input() display = \"\";\n  @Input() placeholder = \"\";\n  // Added: derived resting placeholder. A money box is typed into, so the verb is \"Enter\". Explicit wins.\n  get computedPlaceholder(): string { return derivePlaceholder('enter', this.display, this.placeholder, this.readonly); }\n  @Input() value = \"\";\n  @Input() width = \"100%\"\n  @Input() currency = \"\";\n\n  @Output() valueChange = new EventEmitter();\n  @Output() leave = new EventEmitter();\n  @Output() enterPress = new EventEmitter();\n\n\n\n  //validation input\n  @Input() required = true;\n  @Input() min = 0;\n  @Input() max = MONEY_MAX; // Changed: was the literal, now the shared constant applyValidators() falls back to\n\n\n  @Input() infoMessage: string;\n  @Output() infoClick = new EventEmitter<void>();\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n  @Input() suffix: string;\n  isHovered = false;\n  onMouseEnter(): void {\n    this.isHovered = true;\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n  }\n\n  onInfoClick(event: MouseEvent): void {\n    event.stopPropagation();\n    this.infoClick.emit();\n  }\n\n  clear() {\n    // Changed: was `this.value = \"\"`, and \"\" is not a number — Newtonsoft rejects it on arrival, so the X on a\n    // money field 400'd instead of clearing. This is LIVE: payroll.service.ts minimumAmount/maximumAmount are\n    // the only two money fields in the estate declaring clearContent, and both are backed by `double?`\n    // (CommissionConfig.cs), so null is both correct and accepted.\n    //\n    // Changed: the control is now set to null rather than \"\". CORRECTING THE NOTE THAT USED TO SIT HERE — it read\n    // \"the FormControl keeps ''\", which is not what this control holds. appCurrencyInputMask is the ControlValueAccessor\n    // for this input, so the FormControl never holds the masked display string; it holds the parsed NUMBER, or null when\n    // the box will not parse. Observed on the real form: emptying the box by keyboard already puts null in the control\n    // and emits null, identically to this X. Setting \"\" here only made the two paths leave DIFFERENT control state for a\n    // moment until the parent's [(value)] round trip corrected it — so null both matches the keyboard exactly and keeps\n    // the mask directive's writeValue on the one code path that resets its dedup cache.\n    this.value = null;\n    this.control.setValue(null, { emitEvent: false }); // emitEvent: false prevents double emission\n    this.valueChange.emit(this.value);\n  }\n\n  leaved() {\n    this.leave.emit();\n  }\n\n  enterPressed() {\n    this.enterPress.emit();\n  }\n\n  //validation\n  // Note: these initial validators are a placeholder only — applyValidators() rebuilds them from the real @Input\n  // values as soon as Angular writes them (ngOnChanges) and again at ngAfterViewInit.\n  control = new FormControl('', [Validators.required, Validators.min(this.min), Validators.max(this.max)]);\n\n  validate(control: FormControl): string {\n\n    if (this.required && control.hasError('required')) {\n      return `Required`;\n    }\n\n    // Changed: \"Minimun\" -> \"Minimum\" (both occurrences). The typo was never user-visible because the min validator\n    // never fired on a required field; now that it does, the message actually reaches the user.\n    if (parseFloat(this.value) < this.min){\n      return `Minimum value is ${this.min}`;\n    }\n\n    if (parseFloat(this.value) > this.max) {\n      return `Maximum value is ${this.max}`;\n    }\n\n    if (control.hasError('min')) {\n      return `Minimum value is ${this.min}`;\n    }\n\n    if (control.hasError('max')) {\n      return `Maximum value is ${this.max}`;\n    }\n\n    return \"\";\n  }\n\n\n}\n","\n\n<mat-form-field [class.spa-readonly]=\"readonly\" hideRequiredMarker=\"true\" [hintLabel]=\"hint\" [hideRequiredMarker]=\"!required\" [ngStyle]=\"{'width':width ?? '100%'}\" hideRequiredMarker=\"true\" style=\"margin-right: 5px;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\"><!-- Changed: onMouseEnter/onMouseLeave existed in the .ts but NOTHING bound them, so isHovered was permanently false and the spa-suffix copy/clear icons (*ngIf=\"...&&isHovered\") could never render on a money field at all. Same hover idiom as spa-date/spa-text/spa-text-area. -->\n  <mat-label>{{display}}</mat-label>\n  <!-- Changed: added inputmode=\"decimal\" so a phone raises the numeric keypad. The input stays type=\"text\" on\n       purpose — it must hold the thousands-separated mask (\"1,234.56\"), which type=\"number\" refuses to display.\n       Without inputmode the field defaulted to the full alphanumeric keyboard, which is why this fell apart on\n       mobile while behaving on desktop. -->\n  <input matInput appCurrencyInputMask autocomplete=\"off\" inputmode=\"decimal\" style=\"text-align: right;\"\n  [min]=\"min\" [max]=\"max\"\n  (keyup.enter)=\"enterPressed()\" (blur)=\"leaved()\" [placeholder]=\"computedPlaceholder\" [formControl]=\"control\" [readonly]=\"readonly\" />\n  <span *ngIf=\"currency!=''\" matPrefix>{{currency}}&nbsp;</span>\n  <mat-error *ngIf=\"control.invalid\">{{validate(control)}}</mat-error>\n  <div matSuffix class=\"suffix-icons\">\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\n  </div>\n\n</mat-form-field>\n\n","import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormControl, Validators } from '@angular/forms';\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n// Added: the documented default ceiling, named once so the @Input default and the validator fallback cannot drift apart.\nconst NUMBER_MAX = 9000000000000000; // Math.max\n\n@Component({\n    selector: 'spa-number',\n    templateUrl: './number.component.html',\n    styleUrls: ['./number.component.css'],\n    standalone: false\n})\nexport class NumberComponent implements OnInit, OnChanges {\n\n  constructor() { }\n\n  // Sync @Input value changes with FormControl\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['value'] && this.control) {\n      // Update FormControl when parent changes the value, including first change\n      if (this.control.value !== changes['value'].currentValue) {\n        this.control.setValue(changes['value'].currentValue, { emitEvent: false });\n      }\n    }\n    // Added: rebuild the validators whenever a bound or a mode ARRIVES or CHANGES. `control` is a field\n    // initializer, so its validators were built from the class defaults before Angular ever wrote [min]/[max];\n    // nothing re-read them afterwards, which is why a declared min was inert on a required number field.\n    if (changes['min'] || changes['max'] || changes['required'] || changes['readonly']) {\n      this.applyValidators();\n    }\n  }\n\n  // Changed: the \"Enter <display>\" freeze that lived here is gone — see computedPlaceholder below. Freezing into\n  // this.placeholder ran once, before any async [display] arrived, and afterwards an explicit override was\n  // indistinguishable from a derived one.\n  ngOnInit(): void {\n  }\n\n  ngAfterViewInit() {\n    this.initControl(this.control)\n\n    // Set initial value after view init\n    if (this.value !== 0) {\n      this.control.setValue(this.value, { emitEvent: false });\n    }\n\n    // Subscribe to control value changes AFTER initial value is set\n    this.control.valueChanges.subscribe(val => {\n      this.value = val;\n      this.valueChange.emit(val);\n    });\n  }\n\n  // Added: tells a mobile browser which soft keyboard to raise. `type=\"number\"` alone is not enough — it is\n  // advisory, and several Android keyboards still open the full alphanumeric layout for it. `inputmode` is the\n  // attribute that actually selects the keypad, so a user tapping a quantity or amount field gets digits\n  // immediately instead of having to find the ?123 key.\n  //\n  // 'decimal' only when decimals are actually possible: a whole-number field should not offer a decimal point\n  // the value cannot hold. A fractional `step` is the signal — step=\"1\" (or unset) means integers.\n  get inputMode(): string {\n    const step = Number(this.step);\n    const allowsDecimals = !!this.step && !Number.isNaN(step) && !Number.isInteger(step);\n    return allowsDecimals ? 'decimal' : 'numeric';\n  }\n\n  // Added: select the whole value on focus, so entering a populated field lets the user type straight over it\n  // instead of fiddling with the caret. This is the SAME behaviour spa-money has had via the currency mask\n  // directive (currency-input-mask.directive.ts handleFocus) — same trigger (`focus`, NOT click) and same\n  // deferral, deliberately replicated rather than re-invented.\n  //\n  // The setTimeout(0) is load-bearing and is the money directive's own reasoning: the browser repositions the\n  // caret AFTER the focus event for both a mouse click and a touch, so a synchronous selection is immediately\n  // undone by the very click that caused the focus.\n  //\n  // select() rather than money's setSelectionRange(0, length): setSelectionRange THROWS InvalidStateError on an\n  // input of type=\"number\" (the selection API is not supported for that type), whereas select() is supported and\n  // gives the identical result. The input stays type=\"number\" precisely so the numeric keypad it already raises\n  // is preserved — so matching money's input type was never an option.\n  selectAllOnFocus(event: FocusEvent) {\n    const input = event.target as HTMLInputElement;\n    if (!input || this.readonly) return; // a readonly field is not being typed into; leave its selection alone\n    setTimeout(() => input.select(), 0);\n  }\n\n  // Added: `type=\"number\"` accepts far more than digits — 'e'/'E' (scientific notation) and stray '+'/'-' are all\n  // legal characters to type. Worse, once the field holds something unparseable the browser reports the value as\n  // an EMPTY STRING rather than what was typed, so a user can see \"1e5\" on screen while the model silently holds\n  // nothing. Blocking the characters at source is what keeps what they see and what gets saved the same thing.\n  //\n  // A leading '-' is permitted only where a negative value is actually in range, so credit/adjustment fields\n  // still work while a quantity field cannot go below zero by typing.\n  blockNonNumericKeys(event: KeyboardEvent) {\n    if (event.ctrlKey || event.metaKey || event.altKey) return; // leave copy/paste/select-all alone\n    if (event.key.length > 1) return;                            // Backspace, Tab, arrows, Delete, Enter …\n\n    if (event.key === 'e' || event.key === 'E' || event.key === '+') { event.preventDefault(); return; }\n\n    if (event.key === '-') {\n      const allowsNegative = this.min == null || Number(this.min) < 0;\n      if (!allowsNegative) event.preventDefault();\n      return;\n    }\n\n    if (event.key === '.') {\n      if (this.inputMode !== 'decimal') event.preventDefault(); // whole-number field — a decimal point cannot be stored\n      return;\n    }\n\n    if (!/^\\d$/.test(event.key)) event.preventDefault();\n  }\n\n  // Changed: was two partial branches — readonly cleared the validators and !required re-applied bounds, while a\n  // REQUIRED field was left with whatever the field initializer built and therefore never got its declared min at\n  // any point in its lifecycle. Now every branch goes through applyValidators(), so a bound participates in\n  // validation regardless of mode.\n  initControl(control: FormControl) {\n    this.applyValidators();\n  }\n\n  // Added: the single place the validator set is decided, safe to call whenever an @Input lands.\n  private applyValidators(): void {\n    if (!this.control) { return; }\n\n    if (this.readonly) {\n      this.control.setValidators(null);\n    } else if (this.required) {\n      // Changed: a required field now carries its declared min/max as well as `required`.\n      this.control.setValidators([Validators.required, Validators.min(this.bound(this.min, 0)), Validators.max(this.bound(this.max, NUMBER_MAX))]);\n    } else {\n      // Changed: was Validators.minLength/maxLength, which are STRING/ARRAY validators — they return null for a\n      // numeric control value, so the optional branch enforced nothing at all, declared bound or not. min/max are\n      // the correct validators here; with an undeclared bound they resolve to `undefined` and stay just as inert.\n      this.control.setValidators([Validators.min(this.bound(this.min, undefined)), Validators.max(this.bound(this.max, undefined))]);\n    }\n    // emitEvent: false — this can now run after ngAfterViewInit subscribed to valueChanges, and recomputing\n    // validity must not look like the user edited the box.\n    this.control.updateValueAndValidity({ emitEvent: false });\n  }\n\n  // Added: resolves the bound ACTUALLY enforced. The per-branch fallback is deliberate and is what keeps a field\n  // that declares no min/max byte-for-byte identical to today: the required branch has always been validated with\n  // the class defaults (min 0, max 9e15) baked in at construction, whereas the optional branch has always been\n  // effectively unbounded. Applying the defaults to the optional branch instead would start REJECTING negative\n  // values on every optional number field in the estate, including untracked consumers. Only a genuinely declared\n  // number changes any behaviour.\n  private bound(declared: any, fallback: number | undefined): number | undefined {\n    return typeof declared === 'number' && !isNaN(declared) ? declared : fallback;\n  }\n\n  // options: FormGroup;\n  hideRequiredControl = new FormControl(true);\n  hide = true; //for password only\n\n  @Input() readonly = false;\n  @Input() hint = \"\";\n  @Input() display = \"\";\n  @Input() placeholder = \"\";\n  // Added: derived resting placeholder. A number box is typed into, so the verb is \"Enter\". Explicit wins.\n  get computedPlaceholder(): string { return derivePlaceholder('enter', this.display, this.placeholder, this.readonly); }\n  @Input() value = 0;\n  @Input() width = \"100%\"\n\n  @Output() valueChange = new EventEmitter();\n  @Output() leave = new EventEmitter();\n  @Output() enterPress = new EventEmitter();\n\n\n\n\n\n\n  //validation input\n  @Input() required = true;\n  @Input() min = 0;\n  @Input() max = NUMBER_MAX; // Changed: was the literal, now the shared constant applyValidators() falls back to\n  @Input() step = 1;\n\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n  @Output() infoClick = new EventEmitter<void>();\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n  isHovered = false;\n  onMouseEnter(): void {\n    this.isHovered = true;\n  }\n\n  onMouseLeave(): void {\n    this.isHovered = false;\n  }\n\n  clear() {\n    // Changed: was `this.value = 0` with the box left showing \"0\". A button labelled \"Clear Content\" that\n    // leaves a 0 behind is a lie about what happened, and 0 is a REAL figure — a rate, a mileage, a count —\n    // that the user never typed. A cleared control emits null; the server decides whether the column accepts\n    // it (nullable: honoured; non-nullable: refused with a readable message, TinWeb eee221e). Zero fields in\n    // the estate declare clearContent on a number today, so this establishes the contract without moving one.\n    this.value = null;\n    this.control.setValue(null, { emitEvent: false }); // emitEvent: false prevents double emission; null renders an EMPTY box, which is what was asked for\n    this.valueChange.emit(this.value);\n  }\n\n  onInfoClick(event: MouseEvent): void {\n    event.stopPropagation();\n    this.infoClick.emit();\n  }\n\n  leaved() {\n    this.leave.emit();\n  }\n\n  enterPressed() {\n    this.enterPress.emit();\n  }\n\n  //validation\n  // Note: these initial validators are a placeholder only — applyValidators() rebuilds them from the real @Input\n  // values as soon as Angular writes them (ngOnChanges) and again at ngAfterViewInit.\n  control = new FormControl(0, [Validators.required, Validators.min(this.min), Validators.max(this.max)]);\n\n  validate(control: FormControl): string {\n\n    if (this.required  && control.hasError('required')) {\n      return `Required`;\n    }\n\n    // Changed: \"Minimun\" -> \"Minimum\". The typo was never user-visible because the min validator never fired on a\n    // required field; now that it does, the message actually reaches the user.\n    if (control.hasError('min')) {\n      return `Minimum value is ${this.min}`;\n    }\n\n    if (control.hasError('max')) {\n      return `Maximum value is ${this.max}`;\n    }\n\n    return \"\";\n  }\n\n}\n","\n<mat-form-field [class.spa-readonly]=\"readonly\" hideRequiredMarker=\"true\" [hintLabel]=\"hint\" [hideRequiredMarker]=\"!required\" [ngStyle]=\"{'width':width ?? '100%'}\" style=\"margin-right: 5px;\" subscriptSizing=\"dynamic\" (mouseenter)=\"onMouseEnter()\" (mouseleave)=\"onMouseLeave()\"><!-- Changed: same omission as spa-money — the hover handlers existed in the .ts and nothing bound them, so isHovered never became true and the copy/clear icons could never render on a number field. -->\n  <mat-label>{{display}}</mat-label>\n  <input matInput autocomplete=\"off\" type=\"number\" [attr.inputmode]=\"inputMode\" [min]=\"min\" [max]=\"max\" [step]=\"step\" (keydown)=\"blockNonNumericKeys($event)\" (focus)=\"selectAllOnFocus($event)\" (blur)=\"leaved()\" (keyup.enter)=\"enterPressed()\" [placeholder]=\"computedPlaceholder\" [formControl]=\"control\" [required]=\"required\" [readonly]=\"readonly\" />\n  <mat-error *ngIf=\"control.invalid\">{{validate(control)}}</mat-error>\n\n  <div matSuffix class=\"suffix-icons\">\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clear()\" [isHovered]=\"isHovered\" [(value)]=\"value\"></spa-suffix>\n  </div>\n</mat-form-field>\n","import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';\nimport { FormControl, Validators } from '@angular/forms';\nimport { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';\n\nimport { MatChipInputEvent, MatChipGrid } from '@angular/material/chips';\nimport { Observable } from 'rxjs';\nimport { map, startWith } from 'rxjs/operators';\nimport { MessageService } from '../../services/message.service';\nimport { Core } from '../../classes/TinCore'; // Added: Core.parseMultiValue — the shared multi-value contract\n\n@Component({\n    selector: 'spa-email',\n    templateUrl: './email.component.html',\n    styleUrls: ['./email.component.css'],\n    standalone: false\n})\nexport class EmailComponent implements OnInit {\n\n  constructor(private messageService : MessageService) { }\n\n  @Input() display = \"\";\n  @Input() value = \"\";\n  @Output() valueChange = new EventEmitter<string>();\n  @Input() readonly = false;\n  @Input() required = true;\n  @Input() hint = \"\";\n  @Input() suffix: string;\n  @Input() infoMessage: string;\n  @Input() copyContent = false;\n  @Input() clearContent = false;\n\n  // New inputs for autocomplete\n  @Input() options: any[] = [];\n  @Input() optionValue = \"\";\n\n  emails: string[] = [];\n  emailControl: FormControl;\n  filteredOptions: Observable<string[]>;\n\n\n  ngOnInit() {\n    this.emailControl = new FormControl('', [\n      Validators.required,\n      Validators.pattern('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$')\n    ]);\n    // Changed: was this.value.split(';').filter(...) — the third inline copy of the ';' split, and the most\n    // fragile: it threw outright on a null `value`, and it FILTERED blanks without TRIMMING the survivors, so a\n    // pasted \"a@b.com; c@d.com\" kept the leading space and \" c@d.com\" then failed the chip's own email pattern.\n    // Core.parseMultiValue is null-safe and trims, so both go away.\n    this.emails = Core.parseMultiValue(this.value);\n\n    // Set up autocomplete filtering\n    this.filteredOptions = this.emailControl.valueChanges.pipe(\n      startWith(''),\n      map(value => this._filter(value))\n    );\n  }\n\n  private _filter(value: string): string[] {\n    const filterValue = value.toLowerCase();\n    return this.options\n      .map(option => this.optionValue ? option[this.optionValue] : option)\n      .filter(option => option.toLowerCase().includes(filterValue));\n  }\n\n  addEmail(event: MatChipInputEvent): void {\n    const value = (event.value || '').trim();\n    if (value) {\n      this.addMultipleEmails(value);\n    }\n    event.chipInput!.clear(); // Clear the input\n  }\n\n  addMultipleEmails(value: string): void {\n    const emailsToAdd = this.extractEmails(value);\n\n    for (const email of emailsToAdd) {\n      if (this.isValidEmail(email) && !this.emails.includes(email)) {\n        this.emails.push(email);\n      }\n    }\n\n    this.emailControl.setValue(''); // Reset the form control\n    this.updateValue();\n    // this.scrollToBottom();\n  }\n\n  isValidEmail(email: string): boolean {\n    return this.emailControl.validator(new FormControl(email)) === null;\n  }\n\n  handlePaste(event: ClipboardEvent): void {\n    event.preventDefault();\n    const pastedText = event.clipboardData.getData('text');\n    const extractedEmails = this.extractEmails(pastedText);\n    this.addMultipleEmails(extractedEmails.join(';'));\n  }\n\n  extractEmails(text: string): string[] {\n    const emailRegex = /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\\.[a-zA-Z0-9._-]+)/gi;\n    const matches = text.match(emailRegex);\n    return matches ? matches : [];\n  }\n\n  removeEmail(email: string): void {\n    const index = this.emails.indexOf(email);\n    if (index >= 0) {\n      this.emails.splice(index, 1);\n      this.updateValue();\n    }\n  }\n\n  clearEmails(): void {\n    this.emails = [];\n    this.updateValue();\n  }\n\n  updateValue(): void {\n    this.value = this.emails.join(';');\n    this.valueChange.emit(this.value);\n  }\n\n\n\n  optionSelected(event: MatAutocompleteSelectedEvent): void {\n    this.addMultipleEmails(event.option.viewValue);\n    this.emailControl.setValue('');\n  }\n\n  copyEmails(): void {\n    const emailString = this.emails.join(';');\n    navigator.clipboard.writeText(emailString).then(() => {\n      this.messageService.toast('Copied');\n    });\n  }\n\n\n}\n","<mat-form-field [class.spa-readonly]=\"readonly\" style=\"width: 100%;\" subscriptSizing=\"dynamic\">\n  <mat-label>{{display}}</mat-label>\n  <mat-chip-grid #chipList>\n    <mat-chip-row *ngFor=\"let email of emails\" [removable]=\"!readonly\" (removed)=\"removeEmail(email)\">\n      {{email}}\n      <button matChipRemove *ngIf=\"!readonly\"><mat-icon class=\"tinyIcon\">cancel</mat-icon></button>\n    </mat-chip-row>\n    <input autocomplete=\"off\" #emailInput [placeholder]=\"readonly ? '' : 'Enter email addresses'\" [matChipInputFor]=\"chipList\" [matChipInputSeparatorKeyCodes]=\"[13, 186]\" [matChipInputAddOnBlur]=\"true\" (matChipInputTokenEnd)=\"addEmail($event)\" [formControl]=\"emailControl\" (paste)=\"handlePaste($event)\" [readonly]=\"readonly\" [matAutocomplete]=\"auto\" [matAutocompleteDisabled]=\"readonly\">\n  </mat-chip-grid>\n  <mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"optionSelected($event)\">\n    <mat-option *ngFor=\"let option of filteredOptions | async\" [value]=\"optionValue ? option[optionValue] : option\">\n      {{optionValue ? option[optionValue] : option}}\n    </mat-option>\n  </mat-autocomplete>\n  <mat-error *ngIf=\"emailControl.invalid && emailControl.touched\">Invalid email format</mat-error>\n  <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n  <div matSuffix class=\"suffix-icons\">\n    <spa-suffix [label]=\"suffix\" [infoMessage]=\"infoMessage\" [copyContent]=\"copyContent\" [clearContent]=\"clearContent\" [readonly]=\"readonly\" (clearClick)=\"clearEmails()\" [isHovered]=\"true\" [(value)]=\"value\"></spa-suffix>\n  </div>\n</mat-form-field>\n","import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { Field } from '../../classes/Classes';\nimport { EMAIL_SINGLE_REGEX } from '../../runtime/email-single'; // Added (email-single): the shared single-address contract\n\n// Inline row editing (TableConfig.inlineEdit) — renders one editable cell by delegating to the existing\n// spa-* input components, so field behaviour (select loadAction, money masks, dates) matches the dialog form\n@Component({\n    selector: 'app-inline-cell',\n    template: `\n    <ng-container [ngSwitch]=\"field.type\">\n\n      <spa-number *ngSwitchCase=\"'number'\" [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [suffix]=\"field.suffix\"></spa-number>\n\n      <spa-money *ngSwitchCase=\"'money'\" [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [suffix]=\"field.suffix\"></spa-money>\n\n      <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\"></spa-check>\n\n      <spa-date *ngSwitchCase=\"'date'\" [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [min]=\"field.min\" [max]=\"field.max\"></spa-date>\n\n      <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [min]=\"field.min\" [max]=\"field.max\"></spa-datetime>\n\n      <spa-select *ngSwitchCase=\"'select'\" [display]=\"display\" [nullable]=\"field.nullable\" [options]=\"field.options\" [masterOptions]=\"field.masterOptions\" [masterField]=\"field.masterField\"\n        [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\"\n        [required]=\"field.required\" [loadAction]=\"field.loadAction\" [loadIDField]=\"field.loadIDField\" [field]=\"field\" [data]=\"data\"></spa-select>\n\n      <spa-email *ngSwitchCase=\"'email'\" [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [required]=\"field.required\"></spa-email>\n\n      <!-- Added (email-single): a single address is an ordinary text cell with the anchored email pattern; the field's own regex still wins. Distinct from 'email' above, which is the multi-address chip grid -->\n      <spa-text *ngSwitchCase=\"'email-single'\" type=\"email\" [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [suffix]=\"field.suffix\" [regex]=\"field.regex ?? emailSingleRegex\"></spa-text>\n\n      <spa-text-area *ngSwitchCase=\"'text-area'\" [display]=\"display\" [rows]=\"1\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [regex]=\"field.regex\"></spa-text-area>\n\n      <spa-text *ngSwitchDefault [display]=\"display\" [(value)]=\"data[field.name]\" (valueChange)=\"cellChanged()\" [required]=\"field.required\" [min]=\"field.min\" [max]=\"field.max\" [suffix]=\"field.suffix\" [regex]=\"field.regex\"></spa-text>\n\n    </ng-container>\n  `,\n    styles: [`:host { display: block; min-width: 90px; padding-top: 6px; }`],\n    standalone: false\n})\nexport class InlineCellComponent {\n  emailSingleRegex = EMAIL_SINGLE_REGEX; // Added (email-single): fallback pattern for the 'email-single' case above\n\n  @Input() field: Field;\n  @Input() data: any;\n  @Output() valueChange = new EventEmitter<any>();\n\n  get display(): string {\n    return this.field.alias ?? this.field.name;\n  }\n\n  cellChanged() {\n    this.valueChange.emit({ field: this.field, value: this.data[this.field.name] });\n  }\n}\n","import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; // Changed: OnChanges added — invalidates the visible-button cache\nimport { Button, TableConfig } from '../../classes/Classes';\nimport { ButtonService } from '../../services/button.service';\nimport { ConditionService } from '../../services/condition.service';\n\n@Component({\n    selector: 'spa-capsules',\n    templateUrl: './capsules.component.html',\n    styleUrls: ['./capsules.component.css'],\n    standalone: false\n})\nexport class CapsulesComponent implements OnChanges { // Changed: OnChanges — invalidate the button cache when inputs change\n  constructor(\n    public buttonService: ButtonService,\n    private conditionService: ConditionService\n  ) {}\n\n  @Input() config: TableConfig;\n  @Input() dataSource: any[];\n  @Input() displayedButtons: Button[] = [];\n\n  @Output() actionClick = new EventEmitter<{name: string, row: any, button: Button}>(); // Changed: emit the Button the capsule menu actually rendered, not just its name. A name is not unique — table-config.service unshifts the four framework approvals buttons onto a table's own array, so a table declaring its own 'approve'/'cancel' carries TWO buttons under one name and the consumer could only ever resolve the first one\n\n  // Added: stable-reference cache — the template called buttonService.getVisibleButtons(...) straight from\n  // an *ngFor, so every change-detection cycle handed the loop a brand new array.\n  private buttonCache = new WeakMap<any, Button[]>();\n\n  ngOnChanges() {\n    this.buttonCache = new WeakMap(); // Added: inputs changed — visibility predicates must be re-evaluated\n  }\n\n  // Added: cached wrapper the template binds to instead of calling the service directly\n  getVisibleButtons(item: any): Button[] {\n    let buttons = this.buttonCache.get(item);\n    if (!buttons) {\n      buttons = this.buttonService.getVisibleButtons(this.displayedButtons, item, this.config);\n      this.buttonCache.set(item, buttons);\n    }\n    return buttons;\n  }\n\n  // Extract display value based on config\n  getDisplayValue(row: any): string {\n    if (!this.config?.capsuleConfig?.displayField) {\n      return '';\n    }\n    return row[this.config.capsuleConfig.displayField];\n  }\n\n  // Check icon visibility condition\n  testIconCondition(row: any, icon: any): boolean {\n    return this.conditionService.testIconCondition(icon, row);\n  }\n\n  // Handle button click from menu\n  onActionClick(button: Button, row: any): void { // Changed: takes the rendered Button instead of its name, so the click executes the button the operator actually saw\n    this.actionClick.emit({ name: button.name, row, button });\n  }\n\n  // Get button color using service\n  getButtonColor(button: Button, row: any): string {\n    return this.buttonService.getButtonColor(button, row);\n  }\n\n  // Get icon for button using service\n  getIcon(button: Button): string { // Changed: takes the rendered Button — a name lookup returned the FIRST match, so a colliding menu showed the framework button's icon on the app's own button\n    return this.buttonService.getIcon(button, this.config);\n  }\n\n  // Test if button should be disabled\n  testDisabled(row: any, button: Button): boolean { // Changed: takes the rendered Button — the name lookup applied the framework button's disabled predicate to the app's own button\n    return this.buttonService.testDisabled(button, row, this.config);\n  }\n\n  // Removed: getButton(name) resolved a name back to the FIRST Button carrying it. Every caller above sits inside the *ngFor over getVisibleButtons(item) and now receives that very Button, so there is nothing left to look up and nothing left to resolve wrongly.\n}","<mat-chip-set>\n    <mat-chip *ngFor=\"let row of dataSource\" [matMenuTriggerFor]=\"itemMenu\" [matMenuTriggerData]=\"{item: row}\">\n      <!-- Left icons -->\n      <ng-container *ngFor=\"let icon of config.capsuleConfig?.leftIcons\">\n        <mat-icon *ngIf=\"testIconCondition(row, icon)\" \n                  [ngStyle]=\"{'color': icon?.color}\" \n                  style=\"font-size: 18px; padding-top: 3px; margin-right: 5px;\">\n          {{icon.name}}\n        </mat-icon>\n      </ng-container>\n  \n      <!-- Display text -->\n      <label style=\"margin-right: 5px;\">{{getDisplayValue(row)}}</label>\n  \n      <!-- Right icons -->\n      <ng-container *ngFor=\"let icon of config.capsuleConfig?.rightIcons\">\n        <mat-icon *ngIf=\"testIconCondition(row, icon)\" \n                  [ngStyle]=\"{'color': icon?.color}\" \n                  style=\"font-size: 18px; padding-top: 3px; margin-left: 5px;\">\n          {{icon.name}}\n        </mat-icon>\n      </ng-container>\n    </mat-chip>\n</mat-chip-set>\n  \n  <!-- Context menu -->\n<!-- Changed: every call below passes the Button object this *ngFor is rendering rather than its name. displayedButtons can carry two buttons under one name (table-config.service unshifts the framework approvals buttons onto a table's own array), and a name lookup always returned the first — so a capsule menu rendered the app's button and ran the framework's, posting api/null/approve. Inert where there is no collision: the rendered button IS the first name match there. -->\n<mat-menu #itemMenu=\"matMenu\">\n    <ng-template matMenuContent let-item=\"item\">\n      <button mat-menu-item *ngFor=\"let button of getVisibleButtons(item)\"\n              [disabled]=\"testDisabled(item, button)\"\n              (click)=\"onActionClick(button, item)\">\n        <mat-icon [ngStyle]=\"{'color': getButtonColor(button, item)}\">\n          {{getIcon(button)}}\n        </mat-icon>\n        <span>{{button.display || (button.name | titlecase)}}</span>\n      </button>\n    </ng-template>\n</mat-menu>","import { Component, EventEmitter, Input, OnChanges, Output } from '@angular/core'; // Changed: OnChanges added — invalidates the card content cache\nimport { Button, TableConfig } from '../../classes/Classes';\nimport { ButtonService } from '../../services/button.service';\nimport { ConditionService } from '../../services/condition.service';\n\n@Component({\n    selector: 'spa-cards',\n    templateUrl: './cards.component.html',\n    styleUrls: ['./cards.component.css'],\n    standalone: false\n})\nexport class CardsComponent implements OnChanges { // Changed: OnChanges — invalidate the content cache when inputs change\n  constructor(\n    public buttonService: ButtonService,\n    private conditionService: ConditionService\n  ) {}\n\n  @Input() config: TableConfig;\n  @Input() dataSource: any[];\n  @Input() displayedButtons: Button[] = [];\n  @Input() smallScreen = false;\n\n  @Output() actionClick = new EventEmitter<{name: string, row: any, button: Button}>(); // Changed: emit the Button the card actually rendered, not just its name. A name is not unique — table-config.service unshifts the four framework approvals buttons onto a table's own array, so a table declaring its own 'approve'/'cancel' carries TWO buttons under one name and the consumer could only ever resolve the first one\n  @Output() columnClick = new EventEmitter<{column: any, row: any}>();\n  @Output() showBannerEvent = new EventEmitter<string>();\n\n  // Get title value for a card\n  getTitleValue(row: any): string {\n    const titleField = this.config?.cardConfig?.titleField;\n    return titleField ? row[titleField] : '';\n  }\n\n  // Get subtitle value for a card\n  getSubtitleValue(row: any): string {\n    const subtitleField = this.config?.cardConfig?.subtitleField;\n    return subtitleField ? row[subtitleField] : '';\n  }\n\n  // Added: stable-reference cache — getContentValues is bound to an *ngFor and .map() built BRAND NEW\n  // objects on every change-detection cycle, so the loop re-created its DOM forever.\n  private contentCache = new WeakMap<any, {label: string, value: any}[]>();\n\n  ngOnChanges() {\n    this.contentCache = new WeakMap(); // Added: rows/config replaced — rebuild once, then stay stable\n  }\n\n  // Get content values for a card\n  getContentValues(row: any): {label: string, value: any}[] { // Changed: now returns a cached, stable reference\n    let values = this.contentCache.get(row);\n    if (!values) {\n      values = this.buildContentValues(row);\n      this.contentCache.set(row, values);\n    }\n    return values;\n  }\n\n  private buildContentValues(row: any): {label: string, value: any}[] { // Changed: extracted from getContentValues — called only on a cache miss\n    const contentFields = this.config?.cardConfig?.contentFields || [];\n    return contentFields.map(field => {\n      const column = this.config.columns.find(col => col.name === field);\n      return {\n        label: column?.alias || field,\n        value: row[field]\n      };\n    });\n  }\n\n  // Handle button click from menu\n  onActionClick(button: Button, row: any): void { // Changed: takes the rendered Button instead of its name, so the click executes the button the operator actually saw\n    this.actionClick.emit({ name: button.name, row, button });\n  }\n\n  // Get color for button\n  getButtonColor(button: Button, row: any): string {\n    return this.buttonService.getButtonColor(button, row);\n  }\n\n  // Get icon for button\n  getIcon(button: Button): string { // Changed: takes the rendered Button — a name lookup returned the FIRST match, so a colliding card showed the framework button's icon on the app's own button\n    return this.buttonService.getIcon(button, this.config);\n  }\n\n  // Test if button should be disabled\n  testDisabled(row: any, button: Button): boolean { // Changed: takes the rendered Button — the name lookup applied the framework button's disabled predicate to the app's own button\n    return this.buttonService.testDisabled(button, row, this.config);\n  }\n\n  // Test if button should be visible\n  testVisible(row: any, button: Button): boolean { // Changed: takes the rendered Button — the name lookup applied the framework button's visible predicate, which hid the app's own button on a colliding table\n    return this.buttonService.testVisible(button, row, this.config);\n  }\n\n  // Get elevation class based on config\n  getElevationClass(): string {\n    const elevation = this.config?.cardConfig?.elevation || 'medium';\n    switch(elevation) {\n      case 'low': return 'mat-elevation-z1';\n      case 'high': return 'mat-elevation-z8';\n      default: return 'mat-elevation-z4';\n    }\n  }\n\n  // Get number of columns for grid\n  getColumnCount(): number {\n    if (this.smallScreen) return 1;\n    return this.config?.cardConfig?.columns || 3;\n  }\n\n  // Removed: getButton(name) resolved a name back to the FIRST Button carrying it. Every caller above sits inside the *ngFor over displayedButtons and now receives that very Button, so there is nothing left to look up and nothing left to resolve wrongly.\n}","<div class=\"cards-container\" [style.grid-template-columns]=\"'repeat(' + getColumnCount() + ', 1fr)'\">\n    <mat-card *ngFor=\"let row of dataSource\" [class]=\"getElevationClass()\" class=\"card-item\">\n      <mat-card-header>\n        <mat-card-title>{{getTitleValue(row)}}</mat-card-title>\n        <mat-card-subtitle *ngIf=\"getSubtitleValue(row)\">{{getSubtitleValue(row)}}</mat-card-subtitle>\n      </mat-card-header>\n  \n      <mat-card-content>\n        <div class=\"content-item\" *ngFor=\"let content of getContentValues(row)\">\n          <span class=\"label\">{{content.label}}:</span>\n          <span class=\"value\">{{content.value}}</span>\n        </div>\n      </mat-card-content>\n  \n      <!-- Changed: every call below passes the Button object this *ngFor is rendering rather than its name. displayedButtons can carry two buttons under one name (table-config.service unshifts the framework approvals buttons onto a table's own array), and a name lookup always returned the first — so a card rendered the app's button and ran the framework's, posting api/null/approve. Inert where there is no collision: the rendered button IS the first name match there. -->\n      <mat-card-actions align=\"end\">\n        <ng-container *ngFor=\"let button of displayedButtons\">\n          <button *ngIf=\"!config.flatButtons && testVisible(row, button)\" \n                  mat-mini-fab\n                  [matTooltip]=\"button.tip ?? (button.name | titlecase)\"\n                  matTooltipPosition=\"above\"\n                  [ngStyle]=\"{'background-color': getButtonColor(button, row)}\"\n                  [disabled]=\"testDisabled(row, button)\"\n                  (click)=\"onActionClick(button, row)\">\n            <mat-icon>{{getIcon(button)}}</mat-icon>\n          </button>\n  \n          <button *ngIf=\"config.flatButtons && testVisible(row, button)\"\n                  mat-icon-button \n                  [matTooltip]=\"button.tip ?? (button.name | titlecase)\"\n                  matTooltipPosition=\"above\"\n                  [disabled]=\"testDisabled(row, button)\"\n                  (click)=\"onActionClick(button, row)\">\n            <mat-icon [ngStyle]=\"{'color': getButtonColor(button, row)}\">{{getIcon(button)}}</mat-icon>\n          </button>\n        </ng-container>\n      </mat-card-actions>\n    </mat-card>\n  </div>","import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core';\nimport { CdkDragDrop, CdkDragEnter, CdkDragExit, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop'; // Changed: Added CdkDragEnter/Exit for drop zone highlighting\nimport { Button, TableConfig, GroupConfig, GroupData, Icon, ApiResponse, OrderableConfig } from '../../classes/Classes'; // Changed: Added ApiResponse import; Changed: OrderableConfig for within-group drag-to-reorder\nimport { RowOrderService } from '../../services/row-order.service'; // Added (grouped-orderable): the reorder contract, shared with spa-table so both views post the identical request\nimport { Core } from '../../classes/TinCore'; // Changed: central visibility resolver\nimport { ConditionService } from '../../services/condition.service';\nimport { ButtonService } from '../../services/button.service';\nimport { DataServiceLib } from '../../services/datalib.service'; // Changed: Added for drop action API calls\nimport { MatSnackBar } from '@angular/material/snack-bar'; // Changed: Added for error feedback on failed drops\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: routes a failed drop's server response through the shared classify + dedupe path instead of showing raw server text (WS-6 Phase 3)\n\n// Displays data in grouped card format with chips for items\n@Component({\n  selector: 'spa-groups',\n  templateUrl: './groups.component.html',\n  styleUrls: ['./groups.component.css'],\n  standalone: false\n})\nexport class GroupsComponent implements OnInit {\n\n  constructor(\n    private conditionService: ConditionService,\n    private buttonService: ButtonService,\n    private dataService: DataServiceLib, // Changed: Injected for drop action API calls\n    private snackBar: MatSnackBar, // Changed: Injected for error feedback on failed drops (still used by the transport-error fallback below)\n    private apiErrorService: ApiErrorService // Added: classifies a failed drop's response.message — a leaked SQL fragment gets the friendly dialog, a business refusal stays a toast\n  ) { }\n\n  ngOnInit(): void {\n    this.setupOrderable(); // Added (grouped-orderable): resolve the opt-in ONCE, never in a template getter\n    this.mapServerData();\n  }\n\n  //---------------- Row reordering within a group (opt-in via config.orderable) ----------------\n  // Added (grouped-orderable): the grouped view's answer to the flat table's drag-to-reorder. Everything below is\n  // inert — and every affordance absent from the DOM — unless a config declares `orderable`. It is a SEPARATE\n  // feature from groupConfig.dragEnabled/dropAction, which moves an item BETWEEN groups; this one sequences items\n  // WITHIN one, and the group's own key is the scope.\n\n  // A FIELD, not a getter: `orderable: true` normalises to an object, and allocating that on every\n  // change-detection tick is the template-bound-allocating-getter livelock this library is scarred by.\n  orderableConfig: OrderableConfig | null = null;\n\n  // Built lazily for the same reason as in spa-table — see RowOrderService's own note.\n  private rowOrderService: RowOrderService | null = null;\n  private get rowOrder(): RowOrderService {\n    return this.rowOrderService ??= new RowOrderService(this.dataService, this.apiErrorService);\n  }\n\n  private setupOrderable(): void {\n    this.orderableConfig = this.rowOrder.normalize(this.config?.orderable); // false/absent → null → zero affordances\n  }\n\n  // Whether items can be picked up at ALL. The pre-existing cross-group feature and the new within-group one are\n  // independent opt-ins, and either is enough to make an item draggable. A config that declares NEITHER is\n  // byte-identical to before: cdkDropListDisabled stays true and cdkDrag stays disabled, exactly as it was.\n  get itemsDraggable(): boolean {\n    return !!this.config?.groupConfig?.dragEnabled || !!this.orderableConfig;\n  }\n\n  // The filter rewrites a group's items into a NEW, SHORTER array (applyFilter builds {...group, items: matching}),\n  // so what is on screen is not the complete scope — and the reorder contract requires every id in it. Same\n  // refusal the flat table makes, for the same reason, worded the same way. There is no paginator or column sort\n  // in the grouped view, so those two flat rules have no counterpart here.\n  get orderDisabledReason(): string | null {\n    if (!this.orderableConfig) return null;\n    if (this.filterText?.trim()) return 'Clear the filter to reorder';\n    return null;\n  }\n\n  get orderEnabled(): boolean {\n    return !!this.orderableConfig && !this.orderDisabledReason;\n  }\n\n  // Whether a drag may currently HAPPEN, as opposed to whether items are draggable at all. Bound to\n  // cdkDropListDisabled and read by the grip's greying, so a dead drop list and a bright grip cannot disagree —\n  // the same single-source rule the flat table applies.\n  get dragActive(): boolean {\n    return !!this.config?.groupConfig?.dragEnabled || this.orderEnabled;\n  }\n\n  // Refuses a drop coming from a DIFFERENT group unless the cross-group move feature is actually switched on.\n  // The container is wrapped in cdkDropListGroup, so without this an orderable-only grouped view would happily\n  // offer a cross-group drag that has nowhere to persist to — the scope is the group, and moving between scopes\n  // is a different write. An arrow property because the template binds it unbound.\n  cdkNoCrossGroup = (drag: any, drop: any): boolean => {\n    if (this.config?.groupConfig?.dragEnabled) return true; // the pre-existing feature is on — behave exactly as before\n    return drag?.dropContainer === drop; // orderable-only: a drop is accepted only from its own list\n  }\n\n  // Added: stable-reference caches — all three of these are bound to *ngFor (per group and per item), and\n  // each call re-filtered into a NEW array on every change-detection cycle.\n  private iconCache = new WeakMap<any, Icon[]>();\n  private headerButtonCache = new WeakMap<any, Button[]>();\n  private buttonCache = new WeakMap<any, Button[]>();\n\n  private invalidateVisibilityCaches() {\n    this.iconCache = new WeakMap();\n    this.headerButtonCache = new WeakMap();\n    this.buttonCache = new WeakMap();\n  }\n\n  ngOnChanges(changes: SimpleChanges) {\n    this.invalidateVisibilityCaches(); // Added: inputs changed — visibility predicates must be re-evaluated\n    if (changes['config']) this.setupOrderable(); // Added (grouped-orderable): a swapped config must re-resolve the opt-in\n    if (changes['dataSource']) {\n      this.mapServerData();\n    }\n    // Added: filter text now normally arrives from the table header's filter rather than from a field this\n    // component renders itself, so re-filter whenever it changes.\n    if (changes['filterText'] && !changes['filterText'].firstChange) {\n      this.applyFilter();\n    }\n  }\n\n  @Input() config: TableConfig;\n  @Input() dataSource: any[];\n  @Input() displayedButtons: Button[];\n\n  // Added: true when this component is rendered WITHOUT the standard table header (spa-groups used directly),\n  // in which case it still renders its own filter so filtering is not silently lost. The table sets this to\n  // false because the header supplies the filter, on the same row as the action buttons AND with the refresh\n  // button that this component's own field never had.\n  @Input() showOwnFilter = true;\n\n  @Output() actionClick = new EventEmitter<{ name: string, row: any, group?: GroupData, button?: Button }>();\n\n  groupedData: GroupData[] = [];\n  allGroupedData: GroupData[] = []; // Changed: Unfiltered groups for search\n  // Changed: now an @Input. The text normally arrives from the standard table header's filter (same row as the\n  // action buttons, and it has the refresh button); it is still bound with ngModel by the fallback field below\n  // when this component is used without that header, so both paths drive the same filtering logic.\n  @Input() filterText = '';\n  highlightedGroup: GroupData | null = null; // Changed: Track which group is being hovered during drag\n\n  // Maps server-driven grouped response to GroupData[] using field name config with defaults\n  private mapServerData(): void {\n    if (!this.dataSource || !this.config?.groupConfig) {\n      this.groupedData = [];\n      return;\n    }\n\n    const gc = this.config.groupConfig;\n    const groupValueField = gc.groupValueField ?? 'groupValue';\n    const displayNameField = gc.displayNameField ?? 'displayName';\n    const iconField = gc.iconField ?? 'icon';\n    const colorField = gc.colorField ?? 'color';\n    const orderField = gc.orderField ?? 'order';\n    const itemsField = gc.itemsField ?? 'items';\n\n    const allGroups: GroupData[] = this.dataSource.map((group: any) => ({\n      groupValue: group[groupValueField],\n      displayName: group[displayNameField] ?? String(group[groupValueField]),\n      icon: group[iconField] ?? this.getGroupIconFromConfig(group),\n      color: group[colorField] ?? this.getGroupColorFromConfig(group),\n      items: group[itemsField] ?? [],\n      order: group[orderField] ?? 999\n    }));\n\n    allGroups.sort((a, b) => a.order - b.order);\n\n    // Apply frontend showEmptyGroups filter\n    this.allGroupedData = gc.showEmptyGroups !== false\n      ? allGroups\n      : allGroups.filter(g => g.items.length > 0);\n\n    this.applyFilter(); // Changed: Apply current filter to new data\n  }\n\n  // Changed: Filter groups by group name or item text\n  applyFilter(): void {\n    if (!this.filterText.trim()) {\n      this.groupedData = this.allGroupedData;\n      return;\n    }\n    const term = this.filterText.toLowerCase().trim();\n    const textField = this.config.groupConfig?.itemTextField ?? 'name';\n\n    this.groupedData = this.allGroupedData\n      .map(group => {\n        const groupNameMatch = group.displayName.toLowerCase().includes(term);\n        const matchingItems = group.items.filter(item =>\n          (item[textField] ?? '').toString().toLowerCase().includes(term)\n        );\n        // Show group if name matches (with all items) or if any items match\n        if (groupNameMatch) return group;\n        if (matchingItems.length > 0) return { ...group, items: matchingItems };\n        return null;\n      })\n      .filter(g => g !== null);\n  }\n\n  // Fallback: evaluate groupIcons conditions against group data when backend doesn't provide icon\n  private getGroupIconFromConfig(group: any): string | null {\n    const groupIcons = this.config.groupConfig?.groupIcons;\n    if (!groupIcons || groupIcons.length === 0) return null;\n\n    const matchedIcon = groupIcons.find(icon =>\n      this.conditionService.testIconCondition(icon, group)\n    );\n    return matchedIcon?.name || null;\n  }\n\n  // Fallback: evaluate groupIcons conditions against group data when backend doesn't provide color\n  private getGroupColorFromConfig(group: any): string | null {\n    const groupIcons = this.config.groupConfig?.groupIcons;\n    if (!groupIcons || groupIcons.length === 0) return null;\n\n    const matchedIcon = groupIcons.find(icon =>\n      this.conditionService.testIconCondition(icon, group)\n    );\n    return matchedIcon?.color || null;\n  }\n\n  // Changed: Highlight only the drop zone being hovered, not all zones\n  onDropListEntered(event: CdkDragEnter<any[]>): void {\n    this.highlightedGroup = this.groupedData.find(g => g.items === event.container.data) ?? null;\n  }\n\n  onDropListExited(event: CdkDragExit<any[]>): void {\n    if (this.highlightedGroup && this.highlightedGroup.items === event.container.data) {\n      this.highlightedGroup = null;\n    }\n  }\n\n  // Changed: Handle drag-drop between groups with optimistic move and API sync\n  onDrop(event: CdkDragDrop<any[]>): void {\n    this.highlightedGroup = null; // Changed: Clear highlight on drop\n    if (event.previousContainer === event.container) {\n      // Changed (grouped-orderable): a within-group move used to be an optimistic shuffle that PERSISTED NOTHING —\n      // the array moved, the server never heard about it, and the next load put everything back. It now posts the\n      // same reorder request the flat table does, scoped to this group. A grouped view WITHOUT `orderable` keeps\n      // the old behaviour exactly: the move stays local, because that is all it ever asked for.\n      if (event.previousIndex === event.currentIndex) return; // landed where it started — not a write\n      moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);\n      if (!this.orderEnabled) return;\n      this.persistGroupOrder(event.container.data, event.previousIndex, event.currentIndex);\n      return;\n    }\n\n    const item = event.previousContainer.data[event.previousIndex];\n    const targetGroup = this.groupedData.find(g => g.items === event.container.data);\n\n    // Optimistic move\n    transferArrayItem(event.previousContainer.data, event.container.data,\n      event.previousIndex, event.currentIndex);\n\n    // Call backend drop action if configured\n    const dropAction = this.config.groupConfig?.dropAction;\n    if (dropAction) {\n      const groupValueField = this.config.groupConfig?.groupValueField ?? 'groupValue';\n      const payload = { ...item, [groupValueField]: targetGroup?.groupValue };\n      this.dataService.CallApi(dropAction, payload).subscribe({\n        next: (response: ApiResponse) => {\n          if (!response.success) {\n            // Revert on failure\n            transferArrayItem(event.container.data, event.previousContainer.data,\n              event.currentIndex, event.previousIndex);\n            this.apiErrorService.presentAppFailure(response, 'action', dropAction.url); // Changed: was snackBar.open(response.message ...) — raw server text on a user surface; presentAppFailure classifies it (business refusal -> toast, opaque server text -> friendly dialog) and dedupes. The drag revert above is unchanged\n          }\n        },\n        error: () => {\n          // Revert on error\n          transferArrayItem(event.container.data, event.previousContainer.data,\n            event.currentIndex, event.previousIndex);\n          this.snackBar.open('Failed to update item', 'OK', { duration: 3000 });\n        }\n      });\n    }\n  }\n\n  // Added (grouped-orderable): POST the complete ordered id list for THIS group, revert the optimistic move if the\n  // server refuses. The scope is the group's own key unless the config names one explicitly — scopeValue and\n  // scopeField still win, in that order, which is what \"honours scopeField\" means here.\n  private persistGroupOrder(items: any[], previousIndex: number, currentIndex: number): void {\n    const revert = () => { moveItemInArray(items, currentIndex, previousIndex); };\n\n    const ids = items.map(i => this.rowOrderId(i)).filter(id => id !== null && id !== undefined);\n    const refusal = this.rowOrder.validateIds(ids, items.length);\n    const url = this.rowOrder.action(this.orderableConfig, this.config?.loadAction).url;\n    if (refusal) { revert(); this.rowOrder.presentLocalRefusal(refusal, url); return; }\n\n    const group = this.groupedData.find(g => g.items === items);\n    const scope = this.rowOrder.scope(this.orderableConfig, items, group?.groupValue);\n\n    this.rowOrder.persist(this.orderableConfig, this.config?.loadAction, ids, scope, { revert });\n  }\n\n  // The item's identity for the posted id list. idField first — the sharp edge banked by reorder-demo-1 is that a\n  // config's loadIDField can name the PARENT's id and beat the ...ID convention, so every row reports the same id\n  // and the server refuses the lot. No heroField/trackBy cache here: the grouped view has neither.\n  private rowOrderId(item: any): any {\n    return this.rowOrder.resolveId(item, this.orderableConfig, [this.findIdKey(item)]);\n  }\n\n  // Same ...ID convention spa-table uses for trackBy, and TenantID is excluded there for the same reason.\n  private findIdKey(item: any): string | null {\n    if (!item) return null;\n    return Object.keys(item).find(k => k.endsWith('ID') && k !== 'TenantID') || null;\n  }\n\n  getItemText(item: any): string {\n    const textField = this.config.groupConfig.itemTextField;\n    return item[textField] ?? '';\n  }\n\n  getItemIcon(item: any): string | null {\n    const groupConfig = this.config.groupConfig;\n\n    if (groupConfig.itemIcons && groupConfig.itemIcons.length > 0) {\n      const matchedIcon = groupConfig.itemIcons.find(icon =>\n        this.conditionService.testIconCondition(icon, item)\n      );\n      return matchedIcon?.name || null;\n    }\n\n    if (groupConfig.itemIcon) {\n      if (this.conditionService.testIconCondition(groupConfig.itemIcon, item)) {\n        return groupConfig.itemIcon.name;\n      }\n    }\n\n    return null;\n  }\n\n  // Changed: Get tooltip for primary item icon from matched itemIcons config\n  getItemIconTip(item: any): string {\n    const groupConfig = this.config.groupConfig;\n    if (groupConfig.itemIcons?.length > 0) {\n      const matchedIcon = groupConfig.itemIcons.find(icon => this.conditionService.testIconCondition(icon, item));\n      return matchedIcon ? this.getIconTooltip(matchedIcon, item) : '';\n    }\n    if (groupConfig.itemIcon) return this.getIconTooltip(groupConfig.itemIcon, item);\n    return '';\n  }\n\n  getItemIconColor(item: any): string | null {\n    const groupConfig = this.config.groupConfig;\n\n    if (groupConfig.itemIcons && groupConfig.itemIcons.length > 0) {\n      const matchedIcon = groupConfig.itemIcons.find(icon =>\n        this.conditionService.testIconCondition(icon, item)\n      );\n      return matchedIcon?.color || null;\n    }\n\n    if (groupConfig.itemIcon) {\n      if (this.conditionService.testIconCondition(groupConfig.itemIcon, item)) {\n        return groupConfig.itemIcon.color || null;\n      }\n    }\n\n    return null;\n  }\n\n  getVisibleAdditionalIcons(item: any): Icon[] { // Changed: now returns a cached, stable reference\n    let icons = this.iconCache.get(item);\n    if (!icons) {\n      icons = this.buildVisibleAdditionalIcons(item);\n      this.iconCache.set(item, icons);\n    }\n    return icons;\n  }\n\n  private buildVisibleAdditionalIcons(item: any): Icon[] { // Changed: extracted — called only on a cache miss\n    const additionalIcons = this.config.groupConfig.itemAdditionalIcons;\n    if (!additionalIcons) return [];\n\n    return additionalIcons.filter(icon =>\n      this.conditionService.testIconCondition(icon, item)\n    );\n  }\n\n  getIconTooltip(icon: Icon, item: any): string {\n    if (icon.tipField) {\n      return item[icon.tipField] ?? icon.tip ?? '';\n    }\n    return icon.tip ?? '';\n  }\n\n  getVisibleHeaderButtons(group: GroupData): Button[] { // Changed: now returns a cached, stable reference\n    let buttons = this.headerButtonCache.get(group);\n    if (!buttons) {\n      buttons = this.buildVisibleHeaderButtons(group);\n      this.headerButtonCache.set(group, buttons);\n    }\n    return buttons;\n  }\n\n  private buildVisibleHeaderButtons(group: GroupData): Button[] { // Changed: extracted — called only on a cache miss\n    const headerButtons = this.config.groupConfig.headerButtons;\n    if (!headerButtons) return [];\n\n    return headerButtons.filter(button =>\n      this.buttonService.testVisible(button, group)\n    );\n  }\n\n  getHeaderButtonIcon(button: Button): string {\n    return this.buttonService.getIcon(button, this.config);\n  }\n\n  getHeaderButtonColor(button: Button, group: GroupData): string {\n    return this.buttonService.getButtonColor(button, group);\n  }\n\n  getHeaderButtonTooltip(button: Button): string {\n    return button.tip || button.display || button.name;\n  }\n\n  isHeaderButtonDisabled(button: Button, group: GroupData): boolean {\n    return this.buttonService.testDisabled(button, group);\n  }\n\n  getVisibleButtons(item: any): Button[] { // Changed: now returns a cached, stable reference\n    let buttons = this.buttonCache.get(item);\n    if (!buttons) {\n      buttons = this.displayedButtons ? this.displayedButtons.filter(button => Core.isItemVisible(button, item) && this.buttonService.hasCapability(button)) : []; // Changed: unified visible/hidden (boolean | condition) + the opt-in capability, which this path bypassed by not going through testVisible\n      this.buttonCache.set(item, buttons);\n    }\n    return buttons;\n  }\n\n  // Get button icon using ButtonService to apply defaults for standard buttons\n  getButtonIcon(button: Button): string {\n    return this.buttonService.getIcon(button, this.config);\n  }\n\n  // Get button color using ButtonService to apply defaults (red for delete, green for create, etc.)\n  getButtonIconColor(button: Button, item: any): string {\n    return this.buttonService.getButtonColor(button, item);\n  }\n\n  // Check if button is disabled\n  isButtonDisabled(button: Button, item: any): boolean {\n    return this.buttonService.testDisabled(button, item, this.config);\n  }\n\n  itemActionClicked(button: Button, item: any, group: GroupData): void { // Changed: takes the rendered Button instead of its name, so the click executes the button the operator actually saw. A name is not unique — table-config.service unshifts the four framework approvals buttons onto a table's own array, so a table declaring its own 'approve'/'cancel' carries TWO buttons under one name and table.component could only ever resolve the first one. headerButtonClicked directly below has always passed the object; this is the same shape.\n    this.actionClick.emit({\n      name: button.name,\n      row: item,\n      button: button // Changed: the identity the rest of the chain now runs on instead of re-resolving the name\n      // Changed: `group` is deliberately NO LONGER emitted here, and dropping it is load-bearing rather than tidying. Both group-only branches in table.component's actionClicked are gated on `button && group` (:1132 sets actionData to the GROUP aggregate, :1155 routes straight to doAction and skips the view/edit/delete dialogs). Until now an item click emitted `group` but no `button`, so both gates were dead and `group` had no effect whatsoever on this path. Emitting the button WITHOUT also dropping `group` would switch both on for every item click — the row would be replaced by its group and the dialog skipped. Header clicks are unaffected: headerButtonClicked still emits both, which is exactly what those two branches exist for. This mirrors the `undefined` group slot the row, card and capsule bindings pass in table.component.html.\n    });\n  }\n\n  headerButtonClicked(button: Button, group: GroupData): void {\n    if (button.onClick) {\n      button.onClick(group);\n    }\n\n    this.actionClick.emit({\n      name: button.name,\n      row: group,\n      group: group,\n      button: button\n    });\n  }\n\n}\n","<!-- Changed: this filter row was REMOVED from the grouped view's own markup and now lives in the table header,\n     beside the action buttons, where every other table config puts it. It used to sit on a row of its own\n     directly under the buttons row, leaving both rows half empty and visibly misaligned.\n     The filtering logic here is untouched — only the input that drives it moved, and its text arrives via the\n     filterText @Input relayed from the header. Kept as a fallback for a grouped view rendered WITHOUT the\n     standard header (spa-groups can be used directly), so filtering is never simply lost. -->\n<div class=\"groups-filter\" *ngIf=\"showOwnFilter\">\n  <mat-form-field appearance=\"outline\" class=\"filter-field\">\n    <mat-icon matPrefix>search</mat-icon>\n    <input matInput placeholder=\"Filter\" [(ngModel)]=\"filterText\" (ngModelChange)=\"applyFilter()\">\n    <button *ngIf=\"filterText\" mat-icon-button matSuffix (click)=\"filterText = ''; applyFilter()\">\n      <mat-icon>close</mat-icon>\n    </button>\n  </mat-form-field>\n</div>\n\n<div class=\"groups-container\" cdkDropListGroup>\n\n  <mat-card *ngFor=\"let group of groupedData\" class=\"group-card\">\n\n    <div class=\"group-header\">\n      <div class=\"header-left\">\n        <mat-icon *ngIf=\"group.icon\" [style.color]=\"group.color\" class=\"group-icon\">{{group.icon}}</mat-icon>\n        <!-- Changed: added the native title attribute. On a phone the title now truncates with an ellipsis rather\n             than wrapping to a second line, so the full name has to stay reachable somewhere — this is the\n             zero-cost way to keep it. No tooltip directive, so nothing changes on touch. -->\n        <label class=\"group-title\" [title]=\"group.displayName\">{{group.displayName}}</label>\n        <label *ngIf=\"config.groupConfig.showGroupCount !== false\" class=\"group-count\">({{group.items.length}})</label>\n      </div>\n\n      <div class=\"header-right\">\n        <button\n          *ngFor=\"let button of getVisibleHeaderButtons(group)\"\n          mat-icon-button\n          [matTooltip]=\"getHeaderButtonTooltip(button)\"\n          matTooltipPosition=\"above\"\n          [style.color]=\"getHeaderButtonColor(button, group)\"\n          [disabled]=\"isHeaderButtonDisabled(button, group)\"\n          (click)=\"headerButtonClicked(button, group)\">\n          <mat-icon>{{getHeaderButtonIcon(button)}}</mat-icon>\n        </button>\n      </div>\n    </div>\n\n    <hr class=\"group-divider\" />\n\n    <!-- Empty state: show when no items and drag is disabled -->\n    <div *ngIf=\"group.items.length === 0 && !config.groupConfig.dragEnabled\" class=\"empty-state\">\n      <label>{{config.groupConfig.emptyGroupMessage ?? 'Empty'}}</label>\n    </div>\n\n    <!-- Changed: Replaced mat-chip-set with flex container of mat-stroked-button for cleaner button style -->\n    <div\n      *ngIf=\"group.items.length > 0 || config.groupConfig.dragEnabled\"\n      cdkDropList\n      [cdkDropListData]=\"group.items\"\n      [cdkDropListDisabled]=\"!dragActive\"\n      [cdkDropListEnterPredicate]=\"cdkNoCrossGroup\"\n      (cdkDropListDropped)=\"onDrop($event)\"\n      (cdkDropListEntered)=\"onDropListEntered($event)\"\n      (cdkDropListExited)=\"onDropListExited($event)\"\n      [class.drop-highlight]=\"group === highlightedGroup\"\n      class=\"drop-list items-container\">\n\n      <!-- Empty state inside drop list when drag is enabled -->\n      <div *ngIf=\"group.items.length === 0\" class=\"empty-state drop-empty\">\n        <label>{{config.groupConfig.emptyGroupMessage ?? 'Empty'}}</label>\n      </div>\n\n      <button\n        mat-stroked-button\n        *ngFor=\"let item of group.items\"\n        cdkDrag [cdkDragData]=\"item\"\n        [cdkDragDisabled]=\"!dragActive\"\n        [matMenuTriggerFor]=\"config.groupConfig.contextMenuEnabled !== false ? itemMenu : null\"\n        [matMenuTriggerData]=\"{item: item, group: group}\"\n        class=\"item-button\">\n\n        <!-- Added (grouped-orderable): the drag grip, rendered ONLY for a config that declared `orderable`. Same\n             glyph, same sizing and the same quiet-until-hover treatment as the flat table's grip — this is the\n             library's existing drag affordance, reused, not a second visual language. handle: true restricts the\n             drag to the grip itself; two branches because cdkDragHandle is a directive presence, not a bindable. -->\n        <ng-container *ngIf=\"orderableConfig\">\n          <mat-icon *ngIf=\"orderableConfig.handle; else plainGrip\" cdkDragHandle class=\"tin-grip\" [class.tin-grip-disabled]=\"!orderEnabled\"\n            [matTooltip]=\"orderDisabledReason ?? 'Drag to reorder'\" matTooltipPosition=\"above\">drag_indicator</mat-icon>\n          <ng-template #plainGrip>\n            <mat-icon class=\"tin-grip\" [class.tin-grip-disabled]=\"!orderEnabled\"\n              [matTooltip]=\"orderDisabledReason ?? 'Drag to reorder'\" matTooltipPosition=\"above\">drag_indicator</mat-icon>\n          </ng-template>\n        </ng-container>\n\n        <mat-icon\n          *ngIf=\"getItemIcon(item)\"\n          [style.color]=\"getItemIconColor(item)\"\n          [matTooltip]=\"getItemIconTip(item)\"\n          matTooltipPosition=\"above\"\n          class=\"item-icon\">\n          {{getItemIcon(item)}}\n        </mat-icon>\n\n        <!-- Changed: the item text moved into its own span so a runaway name can be capped and ellipsised without\n             also squeezing the icons, which share this projection slot with it. The native title attribute keeps the\n             full name recoverable on a truncated chip — same treatment already used on the group title above, and no\n             tooltip directive, so touch behaviour is unchanged. -->\n        <span class=\"item-label\" [title]=\"getItemText(item)\">{{getItemText(item)}}</span>\n\n        <ng-container *ngFor=\"let additionalIcon of getVisibleAdditionalIcons(item)\">\n          <mat-icon\n            [style.color]=\"additionalIcon.color\"\n            [matTooltip]=\"getIconTooltip(additionalIcon, item)\"\n            matTooltipPosition=\"above\"\n            class=\"item-additional-icon\">\n            {{additionalIcon.name}}\n          </mat-icon>\n        </ng-container>\n\n      </button>\n    </div>\n\n  </mat-card>\n\n</div>\n\n<mat-menu #itemMenu=\"matMenu\">\n  <ng-template matMenuContent let-item=\"item\" let-group=\"group\">\n    <!-- Changed: the click below hands itemActionClicked the Button object this *ngFor is already rendering rather than its name. displayedButtons can carry two buttons under one name (table-config.service unshifts the framework approvals buttons onto a table's own array), and the name lookup on the far side always returned the first — so a grouped item menu drew the app's button and ran the framework's, posting api/null/approve. Every other call on this element already passes the object; only the click did not. Inert where there is no collision: the rendered button IS the first name match there. -->\n    <button\n      *ngFor=\"let button of getVisibleButtons(item)\"\n      mat-menu-item\n      [disabled]=\"isButtonDisabled(button, item)\"\n      (click)=\"itemActionClicked(button, item, group)\">\n      <mat-icon [style.color]=\"getButtonIconColor(button, item)\">{{getButtonIcon(button)}}</mat-icon>\n      <span>{{button.display ?? button.tip ?? (button.name | titlecase)}}</span>\n    </button>\n  </ng-template>\n</mat-menu>\n","import { Component, EventEmitter, Input, OnInit, OnDestroy, Output, SimpleChanges, ViewChild, AfterViewInit, Optional, Inject } from '@angular/core'; // Changed: Added OnDestroy; Optional/Inject for the runtime table defaults\nimport { MatTableDataSource } from '@angular/material/table';\nimport { Action, Button, Color, Column, DetailsDialogConfig, DetailsSource, Field, FormConfig, Icon, InlineEditConfig, NoAccessInfo, OrderableConfig, TableConfig, ApiResponse } from '../../classes/Classes'; // Changed: added DetailsSource, Field, InlineEditConfig for inline edit + local mode; Changed: NoAccessInfo for the named no-access state; Changed: OrderableConfig for opt-in row reordering\nimport { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; // Added: opt-in row reordering. DragDropModule is already imported by tin-spa.module.ts:86,132 — no new dependency\nimport { LogService } from '../../services/log.service'; // Added: the single denial log line — a refusal left no trace anywhere before this\nimport { MatPaginator, PageEvent } from '@angular/material/paginator'; // Changed: Added PageEvent for server-side paged mode\nimport { MessageService } from '../../services/message.service';\nimport { MatDialog } from '@angular/material/dialog';\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { Core, DetailsDialogProcessor } from '../../classes/TinCore';\nimport { Subject, Subscription } from 'rxjs'; // Changed: Added Subscription for cleanup\nimport { finalize } from 'rxjs/operators'; // Added: Quiet Loading — clears the loading stage on success, failure AND unsubscribe without swallowing the error\nimport { ButtonService } from '../../services/button.service';\nimport { DialogService } from '../../services/dialog.service';\nimport { TableConfigService } from '../../services/table-config.service';\nimport { ConditionService } from '../../services/condition.service';\nimport { AuthService } from '../../services/auth.service';\nimport { SignalRService } from '../../services/signalr.service'; // Changed: Added for real-time table updates\nimport { OfflineService, OfflineEntry, OutboxOp } from '../../services/offline.service'; // Added: TinSync unified offline support\nimport { TIN_SPA_RUNTIME_CONFIG, TinSpaRuntimeConfig } from '../../runtime/tinspa-runtime'; // Added: app-wide table defaults (realTime/offline/pagination)\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { RowOrderService } from '../../services/row-order.service'; // Added (grouped-orderable): the reorder contract, shared with the grouped view so both post the identical request\nimport { resolveQuietLoading, QUIET_DELAY_MS, QUIET_MIN_MS } from '../../runtime/quiet-loading'; // Added: Quiet Loading — shared config-over-app precedence resolver\nimport { PerceivedProgress } from '../../classes/perceived-progress'; // Added: Quiet Loading — asymptotic progress curve behind the initial-load bar and the refresh line\n\n@Component({\n    selector: 'spa-table',\n    templateUrl: './table.component.html',\n    styleUrls: ['./table.component.css'],\n    standalone: false\n})\nexport class TableComponent implements OnInit, AfterViewInit, OnDestroy { // Changed: Added OnDestroy\n\n  constructor(private dataService: DataServiceLib, private messageService: MessageService, private breakpointObserver: BreakpointObserver, public dialog: MatDialog,\n    private buttonService: ButtonService, private dialogService: DialogService, private tableConfigService: TableConfigService, private conditionService: ConditionService, private authService: AuthService, private signalRService: SignalRService, // Changed: Added SignalRService\n    private offline: OfflineService, // Changed: TinSync unified offline service (inert unless config.offline is set)\n    private apiErrorService: ApiErrorService, // Added: routes application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n    @Optional() @Inject(TIN_SPA_RUNTIME_CONFIG) private runtimeConfig: TinSpaRuntimeConfig | null, // Added: supplies app-wide table defaults; @Optional so a test harness without the token still constructs\n    @Optional() private logService: LogService | null = null ) // Added: emits the single denial line; @Optional + defaulted so every existing hand-built harness and consumer keeps constructing unchanged\n    {\n    // detect screen size changes\n    this.subs.push(this.breakpointObserver.observe([\"(max-width: 600px)\"]).subscribe((result: BreakpointState) => { // Changed: TS-8 track subscription\n      this.smallScreen = result.matches;\n      this.updateTableConfiguration();\n    }));\n  }\n\n  private subs: Subscription[] = []; // TS-8: breakpoint + parent-owned reload subscriptions leaked on table teardown; stacked reload subs also caused duplicate loadData fetches\n\n  ngOnInit() {\n    this.ensureInitialized(); // Changed: the body moved to ensureInitialized so ngOnChanges can pull it forward when it has to start a load first\n    this.buildSectionHeader(); // Added (delivered-order-lines-ui-gate): the caption must not depend on rows ever arriving — the dataSource setter is the other rebuild point, and a table that loads nothing would otherwise never resolve one\n  }\n\n  private initialized = false; // Added: guards ensureInitialized — initialization must happen exactly once, whichever hook reaches it first\n\n  // Added: Angular runs ngOnChanges BEFORE ngOnInit on the first pass. A lazy tab that is already active on the\n  // first binding (a details dialog's tableConfigs[0]) therefore started its load from ngOnChanges while\n  // setupPagination() had not yet run, so pagedMode was still false and the rows landed on the legacy path;\n  // ngOnInit then flipped pagedMode on and the next updateSlice() drew from the empty loadedRows window and\n  // replaced the good rows with nothing. Initialization is now idempotent so the load site can order it first.\n  private ensureInitialized() {\n    if (this.initialized) return;\n    this.initialized = true;\n\n    this.sectionCollapsed = !!this.config?.sectionConfig?.collapsed; // Added: seed section collapse from config — state lives on the component, never written back to the shared config\n\n    if (this.config?.formConfig) {\n      this.hasFormAccess = Core.hasFormAccess( this.config.formConfig, this.authService.currentRoleSource.value );\n      this.noAccess = Core.describeFormAccess( this.config.formConfig, this.authService.currentRoleSource.value ); // Added: name the refusal at the gate — the one place that knows which capability was wanted\n    }\n\n    if (this.hasFormAccess){\n      this.initializeComponent();\n    }\n    else { // Added: the denial left NO trace anywhere — no request, no 403, no console line, no log entry. A support engineer had nothing to go on. One line, here, because ensureInitialized runs exactly once per instance.\n      this.logDenial();\n    }\n\n  }\n\n  // Added: the diagnostic half of the no-access state. Deliberately NOT a toast or a dialog — the user already\n  // has the banner; this line is for whoever is reading a console or a log after the fact. LogService is\n  // providedIn:'root' and depends on nothing but Core, so it injects cleanly, but it is @Optional because a\n  // consumer harness that constructs this component by hand supplies none, and the trace is the whole point of\n  // the change — it must not be the thing that vanishes in the awkward case.\n  private logDenial() {\n    if (!this.noAccess) return; // nothing was declared, so there is nothing to name — see Core.describeFormAccess\n    const line = `no-access: ${this.noAccess.entity} requires ${this.noAccess.capName} (${this.noAccess.capDisplay}); role holds none`;\n    if (this.logService) this.logService.info(line); else console.info(line);\n  }\n\n  ngAfterViewInit() {\n    // Set paginator after view initialization to ensure ViewChild is ready\n    this.setPaginator();\n  }\n\n  ngOnChanges(changes: SimpleChanges) {\n\n    if (this.isLocal) { this.refreshLocalData(); return; } // Added: local rows are the only data source — never clobber with the (empty) data input\n\n    if (!this.config.loadAction && !this.config.searchConfig) {\n      this.applyTileFilter(); // Changed: routes through the tile filter (falls back to the full set when none is active)\n    }\n\n    if (this.inTab && changes['activeTab']) {\n      if (!this.hasBeenActivated && this.activeTab && this.config?.lazyLoad && this.config.loadAction) {\n        this.ensureInitialized(); // Changed: this is the ONLY load ngOnChanges can start, and it must not run ahead of setupPagination() — see ensureInitialized\n        this.loadData(this.config.loadAction, \"\");\n        this.hasBeenActivated = true;\n      }\n    }\n  }\n\n\n\n  elevation = \"mat-elevation-z5\";\n  actionsWidth = \"50px\";\n\n  // Added: collapsible flat section header (sectionConfig) — Day Book sections\n  sectionCollapsed = false;\n\n  get sectionHidden(): boolean {\n    return !!(this.config?.sectionConfig?.hideWhenEmpty && this.dataSource?.length === 0);\n  }\n\n  // Changed: the expand half is delegated to expandSection so the two entry points cannot drift apart\n  toggleSection() {\n    if (this.config?.sectionConfig?.collapsible === false) return;\n    if (this.sectionCollapsed) { this.expandSection(); return; }\n    this.sectionCollapsed = true;\n  }\n\n  // Added: the expand-ONLY entry point, for a caller that wants this section open rather than flipped — a Day\n  // Book chip or stage tile means \"show me this list\", and routing that through toggleSection() closes the very\n  // thing the user asked to see whenever the section happened to be open already. Deliberately NOT gated on\n  // `collapsible === false`: a section the operator may not collapse by hand is one that should be open anyway.\n  expandSection() {\n    if (!this.sectionCollapsed) return;\n    this.sectionCollapsed = false;\n    setTimeout(() => this.setPaginator()); // re-attach — the paginator ViewChild did not exist while collapsed\n  }\n\n  // Changed: materialized — both fed *ngFor in the section header and allocated a new array every CD cycle.\n  sectionChipList: any[] = [];\n  sectionButtonList: any[] = [];\n  // Added (delivered-order-lines-ui-gate): materialized, not a getter. A string caption would have been safe as\n  // a getter (see noAccessTitle above — the ban is on ALLOCATING getters), but a FUNCTION caption is consumer\n  // code, and calling it on every change-detection pass is exactly the shape that caused the livelock the ban\n  // exists for. Rebuilt at the same choke point as the chips.\n  captionText = '';\n\n  private buildSectionHeader() {\n    // Added: parentData is stamped on the CLONE of this config by DetailsDialogProcessor (TinCore.ts:842), so\n    // reading it off this.config here is reading the populated copy the component was actually handed.\n    const caption = this.config?.caption;\n    this.captionText = (typeof caption === 'function' ? caption(this.config?.parentData) : caption) || '';\n    this.sectionChipList = (this.config?.sectionConfig?.chips || []).filter(c => Core.isItemVisible(c, this.dataSourceValue)); // predicates receive the rows\n    this.sectionButtonList = (this.config?.sectionConfig?.buttons || []).filter(b => Core.isItemVisible(b, this.dataSourceValue) && this.buttonService.hasCapability(b)); // Changed: section-header buttons bypass testVisible, so the opt-in capability is applied here too. No-op for a button that names none\n  }\n\n  sectionChips() { return this.sectionChipList; } // Changed: returns the materialized field\n  sectionButtons() { return this.sectionButtonList; } // Changed: returns the materialized field\n\n  // Changed: a section-level button used to be routed straight at customModel() -> open(), which never reads\n  // onClick and, for a non-dialog button, hands back { action:'doAction' } — and doAction then re-resolved the\n  // name against config.buttons, where a sectionConfig button has never lived. So a section button that was not\n  // also a row button silently did nothing, which is why two apps had to drop their batch actions. It now\n  // follows the same three-way shape actionClicked already uses: onClick first, then a direct action, then the\n  // dialog. Row buttons are untouched — this method is only ever called from the section header.\n  sectionButtonClicked(button: Button, event: Event) {\n    event.stopPropagation(); // header click collapses — the button must not\n\n    // A section button acts on the whole list, so the rows ARE its data — there is no row to hand it\n    const rows = this.dataSourceValue || [];\n\n    if (button?.onClick) {\n      button.onClick(rows, () => this.reloadAfterOnClick()); // Changed: hand the handler a reload callback — a section button's whole purpose is a job over the list, and until now its onClick was terminal, so the two apps that ran one reached for window.location.reload()\n      if (!button.dialog && !button.action && !button.detailsConfig) return; // a pure onClick button is fully handled\n    }\n\n    if (button?.action && !button.dialog && !button.detailsConfig) {\n      this.doAction(button.name, rows, button); // pass the button itself — it is not in config.buttons to be found by name\n      return;\n    }\n\n    this.customModel(button.name, null, button); // dialog / detailsConfig button — opens empty, as it always did\n  }\n\n  // Added: what config gets when it calls the `reload` argument handed to Button.onClick. It is deliberately the\n  // SAME pair execAction fires on a successful row action — refresh this table if it owns a loadAction, and emit\n  // actionSuccess for whoever hosts it. That matters because a Day Book section table has no loadAction of its\n  // own: the page supplies [data] and reloads the whole book off (actionSuccess). One call therefore does the\n  // right thing in both hosts. Safe to call more than once and safe to call with nothing to refresh —\n  // refreshClicked() falls through to a dataLoad emit when there is no loadAction.\n  private reloadAfterOnClick() {\n    this.realTimeRefreshOrFallback();\n    this.actionSuccess.emit();\n  }\n  showFilterButton = true;\n  tileReload: Subject<boolean> = new Subject();\n  hasBeenActivated = false; \n\n  smallScreen = false\n  hasFormAccess = true;\n  noAccess: NoAccessInfo | null = null; // Added: populated at the gate ONLY when a declared capability is positively lacked — null on every authorised or unsecured grid\n\n  // Changed (Phase 4): the two refusal sentences were literals in this component's template. There is now a second\n  // tier that refuses — the no-access PAGE behind capabilityGuard — and a copy of a sentence in each would drift\n  // apart the first time one was edited. Both now read from Core, so the grid and the page always agree.\n  // Cheap getters over two string concatenations; no allocation of arrays or objects, so the template-bound\n  // getter ban (which exists for allocating getters) is not in play.\n  get noAccessTitle(): string { return Core.noAccessTitle(this.noAccess?.entity); }\n  get noAccessHint(): string { return Core.noAccessHint(this.noAccess?.capDisplay); }\n\n  //Table\n  tableDataSource;\n  // Changed: dataSource became a get/set pair so the section-header chips/buttons can be rebuilt at the ONE\n  // choke point where rows change, instead of being re-filtered by the template on every CD cycle.\n  private dataSourceValue: any[];\n  get dataSource(): any[] { return this.dataSourceValue; } // returns the stored reference unchanged — safe in templates\n  set dataSource(rows: any[]) {\n    this.dataSourceValue = rows;\n    this.buildSectionHeader();\n    if (this.applyingTileFilter) return; // Changed: the tile filter's own write — the baseline must not become the narrowed set, or a second click would filter the filtered rows\n    this.tileFilterBase = rows; // Changed: every OTHER assignment (a server load, a refresh, local rows) re-establishes what a tile filter narrows\n    if (this.activeTileFilter || this.activeChipFilter) this.applyTileFilter(); // Changed: a refresh under an active tile filter re-applies it instead of silently dropping it while the tile still reads as selected. Changed: the quick-filter chip is included for the same reason — a reload must not leave a chip reading as selected over unfiltered rows\n  }\n  displayedColumns = []\n  displayedButtons = []\n  originalTableLoadAction: Action\n\n  // Changed: Explicitly set static: false to ensure ViewChild is available after view init\n  @ViewChild('tablePaginator', { static: false }) tablePaginator: MatPaginator;\n\n  @Input() data: any = [];\n  @Input() tileData: any = [];\n  @Input() config: TableConfig;\n  @Input() localMode = false; // Added: one-step create — table runs disconnected, rows live on the parent model\n  @Input() parentDetails: any; // Added: live parent form model that local rows bind to (details[navigationProperty])\n  @Input() reload: Subject<boolean>;\n  @Input() activeTab = false;\n  @Input() inTab = false;\n  @Input() nestingLevel: number = 0; // Changed: Track nesting depth for dialog recursion control\n  @Output() dataLoad = new EventEmitter();\n  @Output() totalChange = new EventEmitter<number>(); // Added: row total for the set this grid actually loaded — lets hosts (tab count badges) reuse the filtered result instead of firing a second, unfiltered count call\n  @Output() actionSuccess = new EventEmitter();\n  @Output() refreshClick = new EventEmitter();\n  @Output() searchClick = new EventEmitter();\n  @Output() createClick = new EventEmitter();\n  @Output() actionClick = new EventEmitter();\n  @Output() inputChange = new EventEmitter();\n  @Output() actionResponse = new EventEmitter();\n\n  // Changed: Real-time SignalR subscription management\n  private realTimeSubs: Subscription[] = [];\n  private realTimeEntityName = '';\n\n  // Added: app-wide table defaults resolution. A TableConfig value ALWAYS wins — including an explicit\n  // `false`, which is why these test `!== undefined` rather than truthiness. That is what lets a single\n  // table opt OUT of an app-wide default instead of only opting in.\n  //\n  // These getters (rather than mutating this.config) matter because TableConfigs are long-lived singletons\n  // on the app services, shared between the main page and every details-dialog clone. Writing resolved\n  // defaults back into them would leak one surface's resolution into another.\n  //\n  // This is also the fix for detail-dialog tabs not showing the real-time indicator: those nested configs\n  // are SEPARATE objects that simply never set realTime/offline/pagination (verified across Grip, Piglet\n  // and Shift — every child config omits them). Nothing strips them in the dialog path; they were never\n  // set. With an app default in place, nested tabs now inherit the same behaviour as the main page.\n  private get tableDefaults() { return this.runtimeConfig?.tableDefaults ?? {}; }\n\n  get effRealTime(): boolean {\n    return this.config?.realTime !== undefined ? !!this.config.realTime : !!this.tableDefaults.realTime;\n  }\n\n  get effOffline(): any {\n    return this.config?.offline !== undefined ? this.config.offline : this.tableDefaults.offline;\n  }\n\n  // Added: how long a real-time table waits for its own write to come back as a broadcast before falling back\n  // to a refresh. Same precedence rule as the getters above. 3000ms is a local round trip plus generous slack;\n  // the window only ever costs anything when the broadcast never arrives at all.\n  get effRealTimeFallbackMs(): number {\n    const raw = this.config?.realTimeFallbackMs !== undefined ? this.config.realTimeFallbackMs : this.tableDefaults.realTimeFallbackMs;\n    return typeof raw === 'number' && raw >= 0 ? raw : 3000;\n  }\n\n  get effPagination(): any {\n    const raw = this.config?.pagination !== undefined ? this.config.pagination : this.tableDefaults.pagination;\n    return raw === true ? {} : raw; // boolean shorthand → default page size\n  }\n\n  // Added (Quiet Loading): same precedence rule as the getters above, but the app-wide default lives on\n  // AppConfig alongside dialogStyle rather than in the runtime token — apps set their loading // Changed: dropped the progressLine reference — that flag no longer exists\n  // style where they already set the rest of the app's personality.\n  get effQuietLoading(): boolean {\n    return resolveQuietLoading(this.config, this.dataService.appConfig?.quietLoading);\n  }\n\n  //---------------- Quiet Loading — table loading stage (FSD D2/D3/D4) ----------------\n  //\n  // `loadingStage` is the ONLY thing the template reads, and it is only ever non-null when quiet loading is on,\n  // so every quiet branch in the markup is a single comparison and the classic rendering is untouched when off.\n  //\n  //   'initial' — nothing on screen yet: progress module + ghost rows stand in for the table body.\n  //   'refresh' — rows are already live: only the 2px top line and the spinning refresh icon, rows stay clickable.\n  //\n  // D2 anti-flicker contract, implemented by beginStage/endStage below:\n  //   * nothing renders for the first 150ms, so a listCache hit (which resolves synchronously) never flashes;\n  //   * once rendered, the stage is held a minimum of 350ms, so it can never strobe.\n  static readonly STAGE_DELAY_MS = QUIET_DELAY_MS;  // Changed: shared anti-flicker threshold (see runtime/quiet-loading.ts)\n  static readonly STAGE_MIN_MS = QUIET_MIN_MS;      // Changed: shared minimum display (see runtime/quiet-loading.ts)\n\n  loadingStage: 'initial' | 'refresh' | null = null;\n  progressPercent = 0; // float — bar width\n  progressDisplay = 0; // integer — the tabular-nums caption, so it never jitters\n\n  // The bar and the refresh line share one engine: a table only ever has one read in flight per stage.\n  private progress = new PerceivedProgress({\n    onChange: p => { this.progressPercent = p; this.progressDisplay = Math.round(p); }\n  });\n\n  private hasLoadedOnce = false;          // after the first successful load every fetch is a refresh, even if it returned no rows\n  private nextStageKind: 'initial' | 'refresh' | null = null; // set by refreshClicked — a user-pressed refresh is a refresh even on an empty table\n  private requestStartedAt = 0;           // curve start: the REQUEST time, not the render time, so the bar appears already in motion\n  private stageShownAt = 0;\n  private stageDelayTimer: any = null;\n  private stageHoldTimer: any = null;\n  private stageInFlight = 0;              // reads currently covered by this stage — a table can fire two (setup + reload subject), and the first to finish must not close the stage on the second\n\n  // Ghost rows are fixed at 4 (FSD D3) and their cells follow the real header, so the stage occupies the space the\n  // rows will fill. Falls back to four generic cells if columns have not resolved yet.\n  ghostRows = [0, 1, 2, 3];\n\n  get ghostColumns(): any[] {\n    return this.displayedColumns?.length ? this.displayedColumns : ['', '', '', ''];\n  }\n\n  // Varied widths per column index read as data rather than as a placeholder grid; deterministic, not random,\n  // so the stage looks identical every time it is shown. The action column gets a narrow stub.\n  ghostWidth(index: number, column: any): number {\n    if (column === 'action') return 35;\n    return [72, 58, 86, 64, 78, 52][index % 6];\n  }\n\n  // Added: \"nothing here yet\" and \"nothing matches what you typed\" are two different states and they get two\n  // different sentences. The \"No Data\" line beside this one tests dataSource — the LOADED WINDOW — which a\n  // filter never shrinks: filtering happens downstream of it (MatTableDataSource.filteredData when unpaged,\n  // filteredRows when paged). So a filter matching nothing left dataSource full, the line suppressed, and the\n  // user staring at a header, a \"0 of 0\" paginator and no explanation. This getter is the missing case only —\n  // it is FALSE whenever dataSource is empty, so the genuinely-empty state keeps the line and the words it\n  // always had. Reads lengths and flags only; it allocates nothing, so it is safe to bind in the template.\n  get filteredToNothing(): boolean {\n    if (this.loadingStage === 'initial') return false; // the loading stage owns the space until it completes\n    if (!(this.dataSource?.length > 0)) return false; // genuinely empty — \"No Data\" answers for that state\n    // Only the table view filters what it renders. Cards and capsules are bound to dataSource directly and show\n    // every row regardless of the filter, and the grouped view filters on its own predicate inside spa-groups —\n    // claiming \"no matches\" over a screen still full of cards would be a worse lie than saying nothing.\n    if (this.config?.viewType && this.config.viewType !== 'table') return false;\n    if (this.pagedMode) return this.filterActive && this.filteredRows?.length === 0;\n    return !!this.tableDataSource?.filter && this.tableDataSource.filteredData?.length === 0;\n  }\n\n  // Added: THE predicate for \"the filter did not see everything\". In paged mode the client filter runs over\n  // loadedRows — the accumulated window — and filterChanged issues no fetch, so with a partial window a filter\n  // searched the loaded rows ONLY. This getter is deliberately the single definition of that fact: the hint\n  // banner above the grid and the empty-state message below it both bind to it, so the two physically cannot\n  // disagree about how much was searched. They previously stated it independently and did — the banner said\n  // \"only the 20 loaded rows of 240\" while the message underneath offered \"all 240 rows\", implying the filter\n  // had covered the lot. Reads lengths and flags only; allocates nothing, so it is safe to bind in a template.\n  get filterScopePartial(): boolean {\n    return this.pagedMode && this.filterActive && this.loadedRows.length < this.serverTotal;\n  }\n\n  // Added: what the user gets back by clearing the filter. Paged mode's dataSource is only the loaded window, so\n  // the server total (the same figure its own paginator shows) is the honest number there. Only ever rendered in\n  // the COMPLETE-scope state — where the window is partial the count would misdescribe what was searched, which\n  // is exactly why that state gets its own sentence rather than this one.\n  get filteredTotal(): number {\n    return this.pagedMode ? this.serverTotal + this.overlayDelta : (this.dataSource?.length ?? 0);\n  }\n\n  get filteredRowNoun(): string { return this.filteredTotal === 1 ? 'row' : 'rows'; } // Added: keeps \"all 1 rows\" out of the message\n\n  get stageEntityName(): string {\n    // An author-supplied entityName is their wording and is used verbatim.\n    if (this.config?.entityName) return this.config.entityName;\n\n    // A DERIVED name comes straight off a URL segment, which deriveEntityName capitalises and singularises for\n    // SignalR (\"product-groups\" -> \"Product-group\"). That is right for an entity key and wrong inside a\n    // sentence — the caption read \"Loading Product-group…\". De-hyphenate and lowercase it so it reads as prose.\n    // Changed: this used to say deriveEntityName must be left alone because realTimeEntityName depends on its exact\n    // output. The dependency is real but the conclusion was wrong, and it protected a bug for a release. The OTHER\n    // side of that comparison is the server's `typeof(TEntity).Name` (TinWeb BaseController.BroadcastEntityChange),\n    // never a second copy of this derivation — so the test is \"does the corrected name match the C# class name\",\n    // not \"did the string change\". Every -ies segment failed that test BEFORE the correction and three now pass.\n    // Change deriveEntityName only with that comparison re-run; see its own comment for the segment census.\n    const derived = this.deriveEntityName();\n    return derived ? derived.replace(/[-_]+/g, ' ').toLowerCase() : 'data';\n  }\n\n  // Added (Quiet Loading): ghost counts for the NON-table views. Column-shaped rows are the wrong furniture in a\n  // card grid or a capsule strip, so each view gets a shape that matches what is about to replace it. Counts are\n  // deliberately small — the stage should suggest the layout, not fake a full page of content.\n  ghostCards = [0, 1, 2];   // a card grid reads as a grid from three\n  ghostCapsules = [0, 1, 2, 3, 4]; // capsules are small and wrap, so a few more read correctly\n  ghostGroups = [0, 1];     // two group cards is enough to show the grouping, not the data\n\n  // Opens a stage for a read that is about to be issued. No-op unless quiet loading is on, so every call site\n  // stays a single unguarded line.\n  private beginStage(kind?: 'initial' | 'refresh') {\n    if (!this.effQuietLoading) return;\n\n    const resolved = kind ?? this.nextStageKind ?? ((this.hasLoadedOnce || this.dataSource?.length > 0) ? 'refresh' : 'initial');\n    this.nextStageKind = null;\n    this.stageInFlight++;\n\n    if (this.stageHoldTimer) {\n      // A new read landed inside the previous stage's minimum-hold window (rapid refresh). The stage is still on\n      // screen, so carry it into this read and restart the curve instead of blinking it off and back on.\n      clearTimeout(this.stageHoldTimer);\n      this.stageHoldTimer = null;\n      this.loadingStage = resolved;\n      this.requestStartedAt = PerceivedProgress.now();\n      this.stageShownAt = this.requestStartedAt;\n      this.progress.start(this.requestStartedAt);\n      return;\n    }\n\n    if (this.loadingStage || this.stageDelayTimer) return; // a stage is already open (overlapping reads) — the first one owns the run\n\n    this.requestStartedAt = PerceivedProgress.now();\n    this.stageDelayTimer = setTimeout(() => {\n      this.stageDelayTimer = null;\n      this.loadingStage = resolved;\n      this.stageShownAt = PerceivedProgress.now();\n      // Changed 2026-08-05: start the curve NOW, not at requestStartedAt. Backdating meant the bar's very first\n      // painted frame was already well past zero, so users saw it appear half-full and barely move. The point of\n      // a perceived-progress bar is the motion; starting it where it is painted is what makes that visible.\n      this.progress.start();\n    }, TableComponent.STAGE_DELAY_MS);\n  }\n\n  // Closes the stage. Safe to call when no stage was ever shown (the fast path) and safe to call twice.\n  private endStage() {\n    if (this.stageInFlight > 0) this.stageInFlight--;\n    if (this.stageInFlight > 0) return; // another read this stage covers is still running — keep it open\n\n    if (this.stageDelayTimer) { clearTimeout(this.stageDelayTimer); this.stageDelayTimer = null; }\n\n    if (!this.loadingStage) { this.progress.stop(); return; } // resolved inside 150ms — nothing was rendered, nothing to unwind\n\n    this.progress.complete(() => {\n      const shownFor = PerceivedProgress.now() - this.stageShownAt;\n      const wait = Math.max(0, TableComponent.STAGE_MIN_MS - shownFor);\n      if (this.stageHoldTimer) clearTimeout(this.stageHoldTimer);\n      this.stageHoldTimer = setTimeout(() => { this.stageHoldTimer = null; this.loadingStage = null; }, wait);\n    });\n  }\n\n  private clearStage() {\n    if (this.stageDelayTimer) { clearTimeout(this.stageDelayTimer); this.stageDelayTimer = null; }\n    if (this.stageHoldTimer) { clearTimeout(this.stageHoldTimer); this.stageHoldTimer = null; }\n    this.stageInFlight = 0;\n    this.progress.stop();\n    this.loadingStage = null;\n  }\n\n  isSignalRConnected = false; // Changed: Tracks data hub connection state for indicator\n\n  // Added: TinSync offline state — registry entry, live pending ops, and the last raw (un-overlaid) server rows\n  private offlineEntry: OfflineEntry | null = null;\n  private pendingOps: OutboxOp[] = [];\n  private rawRows: any[] | null = null;\n  private offlineSubs: Subscription[] = [];\n\n  // Added: reconnect-refresh state — see setupReconnectRefresh(). Each `armed` flag opens only after its stream\n  // has been seen DOWN, so a BehaviorSubject's replayed initial value and SignalR's first connect cannot fire a\n  // refresh. The dedupe window exists because online$ and dataHubConnected$ recover together by design.\n  private static readonly RECONNECT_DEDUPE_MS = 5000;\n  private reconnectArmedOnline = false; // online$ has been observed false at least once\n  private reconnectArmedHub = false;    // dataHubConnected$ has been up, and has since gone down\n  private hubHasConnected = false;      // guards the arm above against an ordinary page load's initial false\n  private lastReconnectRefresh = 0;\n\n  // Added: server-side pagination state — active only when config.pagination is set (accumulate-as-you-go window over the server dataset)\n  pagedMode = false;\n  serverTotal = 0;\n  loadedRows: any[] = [];\n  filteredRows: any[] = []; // Added: loaded rows matching the active filter (paged mode pages this subset client-side)\n  overlayDelta = 0; // Added: TinSync — rows the pending-op overlay adds (creates) minus removes (deletes); keeps the paginator length truthful\n  pageIndex = 0;\n  pageSize = 10;\n  filterActive = false;\n  private filterText = ''; // Added: current paged-mode filter text\n  groupFilterText = ''; // Added: relayed to spa-groups so the standard header filter drives the grouped view\n  // Added: the headline for the \"filter matched nothing\" empty state. Built ONCE per filter change rather than\n  // by a template getter — a getter that concatenates a string allocates on every change-detection pass.\n  filterEmptyTitle = 'No matches';\n  filterEmptyTitlePartial = 'No matches in the rows loaded so far'; // Added: the partial-window variant of the headline above (see filterScopePartial)\n  // Added: a load that FAILED is not a load that returned nothing, and until now the grid could not tell them\n  // apart. The failure paths never assign dataSource, so it stayed undefined and the template's\n  // `!dataSource && !loadingStage` branch rendered \"Loading...\" — permanently, under a dismissed error dialog.\n  // Set by every failure handler, cleared whenever a read starts or succeeds.\n  loadFailed = false;\n  private fetchSize = 20;\n  private pagedUrlBase = '';\n  private pageFetchInFlight = false;\n\n  private initializeComponent() {\n    // Added: local mode (one-step create) — bind to the in-memory rows on the parent model and skip all server machinery\n    if (this.isLocal) {\n      this.updateTableConfiguration();\n      this.formDefaults();\n      this.refreshLocalData();\n      return;\n    }\n    // Changed: setupPagination now runs FIRST. It no longer depends on offline (the two are no longer mutually\n    // exclusive), while setupOffline now reads pagedMode to size the cache window — so the dependency reversed.\n    this.setupPagination(); // Added: paged-mode activation must precede setupDataLoading so loadData routes correctly\n    this.setupOffline(); // Changed: TinSync registration + status column must precede column computation\n    this.updateTableConfiguration();\n    this.setupDataLoading();\n    this.formDefaults();\n    this.originalTableLoadAction = { ...this.config.loadAction } //Core.getClone(this.config.loadAction);\n    this.dataSource = this.data;\n    this.setTableData(this.data); // Changed: TS-9 reuse datasource\n    if (this.effRealTime) this.setupRealTimeSubscriptions(); // Changed: resolves via the app-wide default, so detail-dialog tabs get the live indicator too\n    this.setupReconnectRefresh(); // Added: offline -> back online must re-read this grid; deliberately NOT gated on effRealTime — a plain table went just as stale\n  }\n\n  //---------------- Local mode (one-step create via TableConfig.createConfig) ----------------\n\n  // Active when hosted inside a create-mode dialog: rows are kept on the parent model and only submitted with the parent\n  get isLocal(): boolean {\n    return this.localMode && !!this.config?.createConfig?.navigationProperty && !!this.parentDetails;\n  }\n\n  // The live array on the parent form model that the final create POST will carry as the navigation property\n  private get localRows(): any[] {\n    const nav = this.config.createConfig.navigationProperty;\n    if (!Array.isArray(this.parentDetails[nav])) this.parentDetails[nav] = [];\n    return this.parentDetails[nav];\n  }\n\n  private refreshLocalData() {\n    this.dataSource = [...this.localRows];\n    this.setTableData(this.dataSource);\n  }\n\n  //---------------- Inline row editing (opt-in via TableConfig.inlineEdit) ----------------\n\n  editingRow: any = null; // the row currently open for in-place editing (one at a time)\n  editingModel: any = null; // working copy the cell editors bind to — cancel discards it\n\n  isRowEditing(row: any): boolean {\n    return this.editingRow === row;\n  }\n\n  // A column is editable when the row is in edit mode, it maps to a form field, and (if configured) is in inlineEdit.fields\n  getInlineField(column: Column): Field | null {\n    if (!this.config.inlineEdit) return null;\n    const cfg = this.config.inlineEdit as InlineEditConfig;\n    if (Array.isArray(cfg.fields) && !cfg.fields.includes(column.name)) return null;\n    const field = this.config.formConfig?.fields?.find(f => f.name === column.name);\n    if (!field || field.readonly || field.type === 'section' || field.type === 'blank' || field.type === 'file' || field.type === 'file-view' || field.type === 'label' || field.type === 'string') return null;\n    return field;\n  }\n\n  // Added: every field the CONFIG declares inline-editable, whether or not it has a cell on screen\n  private configuredInlineFields(): Field[] {\n    return (this.config?.columns ?? []).map(column => this.getInlineField(column)).filter(field => !!field);\n  }\n\n  // Added: the inline-editable fields that are ACTUALLY RENDERED. <app-inline-cell> lives inside a per-column\n  // matColumnDef (table.component.html:101), so a column missing from displayedColumns has no editor at all.\n  // displayedColumns is not config.columns: setColumns REPLACES it with the minColumns subset below 600px\n  // (table-config.service.ts:26-27) and also drops columns pruned by a visible/hidden predicate.\n  private renderedInlineFields(): Field[] {\n    return (this.config?.columns ?? []).filter(column => this.displayedColumns?.includes(column.name)).map(column => this.getInlineField(column)).filter(field => !!field);\n  }\n\n  // Added: inline edit is only honest when EVERY editable field has a cell the operator can see and change.\n  // Previously seedInlineDefaults and submitInlineEdit both walked config.columns, so a field cut by minColumns\n  // was still seeded with its defaultValue, still passed the required check, and was still posted — the row\n  // submitted values nobody ever saw (piglet weaned litters at an optimistic count on a phone, 2026-08-10).\n  private canEditInline(): boolean {\n    const configured = this.configuredInlineFields();\n    return configured.length > 0 && this.renderedInlineFields().length === configured.length;\n  }\n\n  startInlineEdit(row: any) {\n    this.editingRow = row;\n    this.editingModel = { ...row }; // shallow copy — scalars only change, cancel restores by discarding\n    this.seedInlineDefaults(row); // Added: a field the row does not carry would otherwise open blank\n  }\n\n  // Added: an inline-editable field the row has no value for (a weaning date on a \"ready to wean\" row) opened\n  // empty, so every operator retyped the same obvious answer. It now takes the field's OWN defaultValue, exactly\n  // as the dialog form does via Core.getInitialValue — including defaultValue:'now' for dates. defaultValue may\n  // additionally be a FUNCTION OF THE ROW here (count -> row.alive), which the dialog path has no need of because\n  // a create dialog has no row to read. Only null/undefined values are seeded, so real row data is never replaced.\n  private seedInlineDefaults(row: any) {\n    if (!this.config.inlineEdit || !this.config.columns) return;\n    for (const field of this.renderedInlineFields()) { // Changed: was config.columns — an unrendered field must never be silently seeded, because nobody can see or correct what it was seeded with\n      if (field.defaultValue === undefined || field.defaultValue === null) continue;\n      const current = this.editingModel[field.name];\n      if (current !== undefined && current !== null && current !== '') continue;\n      this.editingModel[field.name] = typeof field.defaultValue === 'function' ? field.defaultValue(row) : Core.getInitialValue(field);\n    }\n  }\n\n  cancelInlineEdit() {\n    this.editingRow = null;\n    this.editingModel = null;\n  }\n\n  submitInlineEdit() {\n    if (!this.editingRow) return;\n\n    // Validate only the fields that are editable inline, with the same rules the dialog form applies\n    const editableFields = this.renderedInlineFields(); // Changed: was config.columns — validating a field with no cell on screen let a required check pass against a value the operator never supplied\n    const validationResult = Core.validateObject(editableFields, this.editingModel);\n    if (validationResult !== '') {\n      this.messageService.toast(validationResult);\n      return;\n    }\n\n    const merged = { ...this.editingRow, ...this.editingModel };\n\n    // Local mode: update the in-memory row — nothing is persisted until the parent submits\n    if (this.isLocal) {\n      const index = this.localRows.indexOf(this.editingRow);\n      if (index >= 0) this.localRows[index] = merged;\n      this.cancelInlineEdit();\n      this.refreshLocalData();\n      return;\n    }\n\n    // Server mode: submit the merged row through the same edit action the dialog would have used\n    const editButton = this.getButton('edit');\n    if (!editButton?.action) {\n      this.messageService.toast('Edit action not configured');\n      return;\n    }\n\n    this.noteWriteIssued(); // Added: stamp before the write leaves, so a broadcast it causes is provably later\n    this.dataService.CallApi(editButton.action, merged).subscribe((apiResponse: ApiResponse) => {\n      if (apiResponse.success) {\n        this.cancelInlineEdit();\n        this.messageService.toast(editButton.action.successMessage ?? (apiResponse.message !== 'success' && apiResponse.message !== '' ? apiResponse.message : 'Updated'));\n        this.realTimeRefreshOrFallback();\n        this.actionSuccess.emit();\n        this.actionResponse.emit({ name: 'edit', data: apiResponse });\n      } else if (apiResponse.reason === 'conflict') {\n        // Added: optimistic-concurrency (IConcurrency) — stale inline edit refused; drop the edit and reload so the user sees the current server data\n        this.cancelInlineEdit();\n        this.messageService.toast(`${apiResponse.message} — the table has been refreshed with the latest data, please re-apply your changes`);\n        this.realTimeRefreshOrFallback();\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'submit', editButton.action.url); // Changed: inline edit IS a write — opaque server text now raises the friendly \"Not saved\" dialog instead of a 5s toast the user misses before retrying\n      }\n    },\n      (error) => { this.apiErrorService.present(error); } // Changed: transport failure on inline edit — was toast(\"Error: \" + error), the last raw-text survivor on this path; present() classifies, dedupes and never shows raw error text\n    );\n  }\n\n  private updateTableConfiguration() {\n    this.elevation = this.getElevationClass(this.config?.elevation);\n    this.displayedColumns = this.tableConfigService.setColumns(this.config, this.smallScreen);\n    this.displayedButtons = this.tableConfigService.getDisplayedButtons(this.config?.buttons, this.smallScreen, this.config);\n    this.actionsWidth = this.tableConfigService.getActionsWidth(this.displayedButtons, this.smallScreen, this.config);\n    this.placeLockIcon(); // Added: convention — a locked row gets its lock cue here, AFTER displayedColumns is known, so the host column is one that is genuinely on screen (and it re-resolves on resize)\n    this.setupOrderable(); // Added: resolve the reorder opt-in once per configuration pass — NEVER in a template getter, which would allocate a fresh object on every change-detection tick (the livelock this codebase has already been bitten by)\n\n    // Added: the same defect through the resize door. A row opened for edit on a wide screen keeps its seeded\n    // editingModel when the window narrows past 600px, but its cells vanish with the columns — so the tick would\n    // post values the operator can no longer see. Discard the edit instead; cancel has always been non-destructive.\n    if (this.editingRow && !this.canEditInline()) {\n      this.cancelInlineEdit();\n      this.messageService.toast('Editing was closed — this screen is too narrow to show every editable field');\n    }\n\n    if (this.config?.searchConfig) {\n      this.showFilterButton = false;\n    }\n\n    if (this.config?.showFilterButton === false) {\n      this.showFilterButton = false;\n    }\n\n  }\n\n  private setupDataLoading() {\n\n    if (this.config.lazyLoad && this.inTab) return;\n\n    if (this.config.loadAction) {\n      this.loadData(this.config.loadAction, \"\");\n    }\n\n\n    if (this.reload) {\n      this.subs.push(this.reload.subscribe(v => { // Changed: TS-8 track subscription — prevents leak and duplicate fetches when the table is recreated (view-type/tab switches)\n        if (v && this.config?.loadAction) {\n          this.loadData(this.config.loadAction, \"\");\n        }\n      }));\n    }\n  }\n\n\n  loadData(action: Action, data: any) {\n\n    this.loadFailed = false; // Added: a retry must clear the previous failure before it can be re-decided — set here, the ONE entry point both modes pass through\n\n    if (this.pagedMode) { this.loadDataPaged(action, data); return; } // Added: paged mode routes to chunked fetching — legacy path below unchanged\n\n    //if searchConfig is set, use last search\n\n\n    if (action.method == 'post') {\n      if (this.config.searchConfig) {\n        if (!this.lastSearch) { this.nextStageKind = null; return; } // Changed (Quiet Loading, Phase 5): this return issues NO read, so a 'refresh' parked by refreshClicked would survive to the next genuine FIRST load and suppress its ghost rows\n        data = this.lastSearch;\n      }\n    }\n\n\n    if (action) {\n\n      // Added (Quiet Loading): the read goes silent so the global scrim never appears, and the local stage opens\n      // instead. With quiet off, `quiet` is false — the options argument falls through to the action's own flag\n      // and no stage/finalize is attached, so the call is identical to before.\n      const quiet = this.effQuietLoading;\n      this.beginStage();\n\n      let call: any = this.dataService.CallApi(action, data, quiet ? { silent: true } : undefined); // `any`: CallApi returns a union (cached `of(...)` vs the HTTP observable) that .pipe() cannot resolve across\n      if (quiet) call = call.pipe(finalize(() => this.endStage())); // finalize, not an error callback: an HTTP failure still propagates exactly as it did\n\n      call.subscribe((apiResponse: ApiResponse) => {\n\n        if (this.config.logResponse) {\n          console.log(apiResponse)\n        }\n\n        if (apiResponse.success) {\n          const rows = this.applyOfflineOverlay(apiResponse.data); // Changed: TinSync — pending offline ops overlay onto server rows\n          this.dataSource = rows\n          this.setTableData(rows); // Changed: TS-9 reuse datasource instead of new MatTableDataSource\n\n          this.dataLoaded(rows);\n\n          if (apiResponse.message != \"success\" && apiResponse.message != \"\"){\n            this.messageService.toast(apiResponse.message);\n          }\n\n        } else {\n          this.loadFailed = true; // Added: the dialog is dismissable and dedupes across tables — without this the grid is left saying \"Loading...\" with nothing still loading\n          this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Changed: a failed row load — dedupes with other loads so a broken backend yields one dialog, not one per table\n        }\n      },\n        // Added: the TRANSPORT failure — a dead API, a dropped connection, a CORS refusal. It never reaches the\n        // branch above because there is no ApiResponse at all: LoaderInterceptor shows the dialog and rethrows,\n        // and this subscribe had no error callback, so the grid was left rendering \"No Data\" — the one thing\n        // that was definitely NOT true. Rethrown so the error still reaches Angular's global handler exactly as\n        // it did before; this callback only records WHY the grid is empty.\n        (err: any) => { this.loadFailed = true; throw err; }\n      );\n    }\n  }\n\n\n  // Added (phone density, opt-in via config.hideSinglePagePaginator): true when the pager is navigating a\n  // single page on a phone, and is therefore 56px of chrome that can reach nowhere it is not already. The\n  // paginator is still RENDERED and only hidden in CSS — the same reason the empty-data case is a class and\n  // not an *ngIf: #tablePaginator is a ViewChild that setPaginator() attaches to the MatTableDataSource, and\n  // removing it from the DOM would break paging for every table that does have a second page.\n  // Desktop returns false on the smallScreen guard alone, so nothing above 600px can be affected.\n  get singlePagePaginatorHidden(): boolean {\n    if (!this.config?.hideSinglePagePaginator || !this.smallScreen) return false;\n    // On a phone hidePageSize is on, so the size cannot be changed from the UI and the paginator's own value\n    // and pageSizes[0] agree; reading the live one first keeps this honest if it was changed before a resize.\n    const size = this.pagedMode ? this.pageSize : (this.tablePaginator?.pageSize || this.config?.pageSizes?.[0] || 10);\n    if (!size) return false;\n    const total = this.pagedMode\n      ? (this.filterActive ? this.filteredRows.length : this.serverTotal + this.overlayDelta)\n      : (this.dataSource?.length || 0);\n    return total > 0 && total <= size; // zero rows is already handled by the existing empty-data rule\n  }\n\n  private setPaginator() {\n    if (this.pagedMode) return; // Added: paged mode drives a manual paginator — MatTableDataSource is never attached to one\n    // Changed: Since paginator is now always in DOM, this should always work on mobile\n    // Safely set paginator with null checks to ensure connection on all screen sizes\n    if (this.tableDataSource && this.tablePaginator) {\n      this.tableDataSource.paginator = this.tablePaginator;\n    }\n  }\n\n  //---------------- Server-side pagination (opt-in via config.pagination) ----------------\n\n  // Changed: pagination and offline are no longer mutually exclusive. Previously offline silently won and\n  // paging was switched off, which made the two most valuable behaviours for a field user unavailable at the\n  // same time — exactly the combination a high-volume transactional table needs on a poor connection.\n  //\n  // What made them look incompatible was only the READ CACHE: caching page slices as though they were the\n  // whole list corrupts it. Nothing about the OUTBOX conflicts with paging, and fetchChunk already marks\n  // every paged request `skipCache: true`, so slices never reached the cache in the first place.\n  //\n  // So when both are set: reads stay server-paged while online, writes still queue to the outbox, and the\n  // offline read cache holds a bounded window (see cacheRows in setupOffline's registration) rather than\n  // pretending to hold everything. Deep offline browsing beyond that window is intentionally not offered.\n  private setupPagination() {\n    const pagination = this.effPagination;\n    this.pagedMode = !!(pagination && this.config?.loadAction);\n    if (!this.pagedMode) return;\n\n    this.fetchSize = pagination.pageSize ?? 20;\n    this.pageSize = (this.config.pageSizes ?? [10, 20, 50])[0];\n  }\n\n  // Paged-mode entry point — POST (search mode) loads the full result set; GET fetches only the needed chunk\n  private loadDataPaged(action: Action, data: any) {\n    if (!action) return;\n\n    if (action.method == 'post') {\n      if (this.config.searchConfig) {\n        if (!this.lastSearch) { this.nextStageKind = null; return; } // Changed (Quiet Loading, Phase 5): same stranded-stage-kind guard as the unpaged path above\n        data = this.lastSearch;\n      }\n\n      // Added (Quiet Loading): same treatment as the unpaged path — silent read, local stage, finalize-based teardown\n      const quiet = this.effQuietLoading;\n      this.beginStage();\n\n      let call: any = this.dataService.CallApi(action, data, quiet ? { silent: true } : undefined);\n      if (quiet) call = call.pipe(finalize(() => this.endStage()));\n\n      call.subscribe((apiResponse: ApiResponse) => {\n        if (this.config.logResponse) {\n          console.log(apiResponse);\n        }\n\n        if (apiResponse.success) {\n          this.applyFullSet(apiResponse.data ?? []); // search results are user-narrowed — load fully, page client-side\n\n          if (apiResponse.message != \"success\" && apiResponse.message != \"\") {\n            this.messageService.toast(apiResponse.message);\n          }\n        } else {\n          this.loadFailed = true; // Added: same treatment as the unpaged path — a failed search load must not read as a load still running\n          this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Changed: paged-mode search load — same classify + dedupe treatment as the unpaged path above\n        }\n      },\n        (err: any) => { this.loadFailed = true; throw err; } // Added: transport failure — same reasoning as the unpaged path above\n      );\n      return;\n    }\n\n    if (action.url !== this.pagedUrlBase) {\n      // URL swap (first load, tile click/un-click, child URL rewrite) — reset the accumulated window\n      this.pagedUrlBase = action.url;\n      this.loadedRows = [];\n      this.pageIndex = 0;\n      this.fetchChunk(action, 0, this.fetchSize, 'replace');\n    } else {\n      // Same URL (refresh / reload subject / post-CUD) — re-fetch exactly what the user has navigated to\n      this.fetchChunk(action, 0, Math.max(this.loadedRows.length, this.fetchSize), 'replace');\n    }\n  }\n\n  // Fetches one server chunk; paging params go on a shallow copy so config.loadAction.url stays pristine, and slices are never cached\n  private fetchChunk(action: Action, skip: number, take: number, mode: 'replace' | 'append') {\n    const pagedAction: Action = { ...action, url: this.withPaging(action.url, skip, take), skipCache: true, cacheDurationMinutes: undefined };\n    this.pageFetchInFlight = true;\n\n    // Added (Quiet Loading): an 'append' is always a refresh — the user is paging rows that are already on screen,\n    // so it gets the top line only (FSD D4) and never the ghost rows.\n    const quiet = this.effQuietLoading;\n    this.beginStage(mode === 'append' ? 'refresh' : undefined);\n\n    let call: any = this.dataService.CallApi(pagedAction, \"\", quiet ? { silent: true } : undefined);\n    if (quiet) call = call.pipe(finalize(() => this.endStage()));\n\n    call.subscribe((apiResponse: ApiResponse) => {\n      this.pageFetchInFlight = false;\n\n      if (this.config.logResponse) {\n        console.log(apiResponse);\n      }\n\n      if (!apiResponse.success) {\n        this.loadFailed = true; // Added: only ever SEEN on a first chunk (the message is gated on !dataSource) — a failed page-forward leaves the rows already on screen alone\n        this.apiErrorService.presentAppFailure(apiResponse, 'load', pagedAction.url); // Changed: chunk fetch — scrolling a broken table fires these repeatedly, so deduping matters most here\n        return;\n      }\n\n      const rows = apiResponse.data ?? [];\n\n      if (apiResponse.total == null) {\n        this.applyFullSet(rows); // no total ⇒ server did not page (tile/child CustomCriteria, overridden GetAll, old API) — graceful degrade\n      } else {\n        this.serverTotal = apiResponse.total;\n\n        if (mode === 'replace') {\n          this.loadedRows = rows;\n        } else {\n          // Dedupe incoming rows by id — the PK-desc window can shift when rows are created between fetches\n          const idKey = this.findIdKey(rows[0] ?? this.loadedRows[0]);\n          const fresh = idKey ? rows.filter(r => !this.loadedRows.some(l => l[idKey] === r[idKey])) : rows;\n          this.loadedRows = [...this.loadedRows, ...fresh];\n        }\n\n        this.rawRows = this.loadedRows; // Added: TinSync — the loaded window IS the raw server data in paged mode; keeps reapplyOverlay/realTimeBaseRows honest\n        this.cachePagedWindow(); // Added: TinSync — persist the accumulated window (the seam never writes paged chunks)\n        this.clampPageIndex();\n        this.updateSlice();\n        this.dataLoaded(this.loadedRows);\n      }\n\n      if (apiResponse.message != \"success\" && apiResponse.message != \"\") {\n        this.messageService.toast(apiResponse.message);\n      }\n    },\n      () => { this.pageFetchInFlight = false; this.loadFailed = true; } // never leave the single-flight guard stuck on a failed request; Added: a transport-level failure (no ApiResponse at all) is still a failed load\n    );\n  }\n\n  // Appends skip/take to a URL copy at fetch time\n  private withPaging(url: string, skip: number, take: number): string {\n    return url + (url.includes('?') ? '&' : '?') + `skip=${skip}&take=${take}`;\n  }\n\n  // Graceful degrade — treat rows as the complete dataset and page them client-side\n  private applyFullSet(rows: any[]) {\n    this.loadedRows = Array.isArray(rows) ? rows : [];\n    this.serverTotal = this.loadedRows.length;\n    this.rawRows = this.loadedRows; // Added: TinSync — same as fetchChunk; these are raw server rows, un-overlaid\n    this.cachePagedWindow(); // Added: TinSync — covers the no-total degrade path too\n    this.clampPageIndex();\n    this.updateSlice();\n    this.dataLoaded(this.loadedRows);\n  }\n\n  // Added: TinSync — writes the ACCUMULATED paged window to the offline read cache under the base (un-paged)\n  // url. OfflineService deliberately does not write paged responses through, because an 'append' chunk is a\n  // mid-list slice and would clobber the window. Called only where data ARRIVES (never from updateSlice, which\n  // runs on every page click and filter keystroke). putRead caps it at cacheRows, so storage stays bounded.\n  private cachePagedWindow() {\n    if (!this.offlineEntry || !this.offline.online) return; // offline reads come FROM the cache — never write them back\n    const url = this.pagedUrlBase || this.config.loadAction?.url;\n    if (!url) return;\n    this.offline.putRead(url, this.offlineEntry.entity, this.loadedRows, this.offlineEntry.config.cacheRows);\n  }\n\n  // Keeps the current page valid when the total shrinks (deletes, shorter tile sets)\n  private clampPageIndex() {\n    const lastPage = Math.max(0, Math.ceil(this.serverTotal / this.pageSize) - 1);\n    if (this.pageIndex > lastPage) this.pageIndex = lastPage;\n  }\n\n  // Renders the visible page. When filtering, the base is the filtered loaded rows (paged client-side); otherwise the loaded window.\n  // We own the filtering (filterPredicate is neutered in paged mode) so the manual paginator can page the filtered subset.\n  private updateSlice() {\n    // Changed: TinSync — the pending-op overlay is applied HERE, before the slice, and nowhere else in paged\n    // mode. Applying it afterwards (as reapplyOverlay does for unpaged tables) assigns the whole overlaid\n    // window to tableDataSource.data and silently defeats pagination. Overlaying first keeps the page a page.\n    const base = this.offlineEntry ? this.computeOverlay(this.loadedRows) : this.loadedRows;\n    this.overlayDelta = base.length - this.loadedRows.length; // pending creates add rows / pending deletes remove them — the paginator's length must follow\n\n    this.dataSource = base;\n    if (!this.tableDataSource) this.tableDataSource = new MatTableDataSource<any>([]);\n    this.tableDataSource.filterPredicate = () => true; // paged mode owns filtering (we slice filteredRows) — neuter MatTableDataSource's own filter so the spa-filter setting .filter never re-drops our slice\n    this.filteredRows = this.filterActive ? base.filter(r => this.pagedRowMatches(r, this.filterText)) : base;\n    this.tableDataSource.data = this.filteredRows.slice(this.pageIndex * this.pageSize, (this.pageIndex + 1) * this.pageSize);\n  }\n\n  // Default-style match used when filtering loaded rows in paged mode (mirrors MatTableDataSource's stringify-and-contains predicate)\n  private pagedRowMatches(row: any, text: string): boolean {\n    if (!text) return true;\n    const dataStr = Object.keys(row).reduce((acc, key) => acc + row[key] + '◬', '').toLowerCase();\n    return dataStr.indexOf(text.toLowerCase()) !== -1;\n  }\n\n  // Manual paginator handler — during filter, pages the in-memory filtered subset (no fetch); otherwise serves from loaded rows or fetches the gap\n  onServerPage(e: PageEvent) {\n    this.pageIndex = e.pageIndex;\n    this.pageSize = e.pageSize;\n\n    if (this.filterActive) { this.updateSlice(); return; } // filtered subset is fully in memory — pure client-side paging\n\n    const neededEnd = Math.min((e.pageIndex + 1) * e.pageSize, this.serverTotal);\n    if (this.loadedRows.length >= neededEnd) { this.updateSlice(); return; } // back / within loaded window — no network\n    if (this.pageFetchInFlight) return; // single-flight guard against rapid next-clicks\n\n    this.fetchChunk({ ...this.config.loadAction }, this.loadedRows.length, Math.max(this.fetchSize, neededEnd - this.loadedRows.length), 'append');\n  }\n\n  // Paged-mode filter — filters ALL loaded rows; the paginator stays visible and pages the filtered subset (next/prev). Legacy filter untouched.\n  filterChanged(text: string) {\n    // Added: the grouped view is filtered by the STANDARD header filter now, not by a second field of its own,\n    // so its text has to be relayed regardless of paged mode. Set before the paged-mode guard below — grouped\n    // views are not paged, and returning early here is what would leave the header filter doing nothing.\n    this.groupFilterText = (text ?? '').trim();\n\n    // Added: build the filtered-empty headline here, where the text arrives for EVERY mode. spa-filter is the\n    // only writer of MatTableDataSource.filter in the library and it emits on keyUp, clear and ngOnChanges\n    // alike, so this field cannot drift from the filter the grid is actually applying. Long pastes are capped\n    // so one field cannot push the message off a phone screen.\n    const term = this.groupFilterText;\n    const shown = term.length > 40 ? term.slice(0, 40) + '…' : term;\n    this.filterEmptyTitle = term ? `No matches for “${shown}”` : 'No matches';\n    // Added: the partial-window headline. Built here beside its sibling so both are computed once per filter\n    // change rather than per change-detection pass. Neither string embeds a COUNT — counts are the banner's and\n    // the paginator's to state — so neither can go stale if the loaded window grows while a filter is active.\n    this.filterEmptyTitlePartial = term ? `No matches for “${shown}” in the rows loaded so far` : 'No matches in the rows loaded so far';\n\n    if (!this.pagedMode) return;\n    this.filterText = (text ?? '').trim();\n    this.filterActive = !!this.filterText;\n    this.pageIndex = 0; // jump to the first page of the filtered results\n    this.updateSlice();\n  }\n\n  inputChanged(event) {\n    this.inputChange.emit({ field: event.field, value: event.value })\n  }\n\n  formDefaults() {\n\n    if (!this.config?.formConfig) {\n      // Changed: a config with no `columns` (a tile-only or action-only table declares none) threw\n      // \"Cannot read properties of undefined (reading 'forEach')\" out of ngOnInit. Nothing visibly failed\n      // because the throw happened AFTER the table had configured itself, but it aborted the rest of\n      // initializeComponent(). Bail instead of fabricating an empty FormConfig: with no columns there are no\n      // fields to derive, and leaving formConfig unset keeps the caller's existing \"no form configured\"\n      // fallback rather than handing it a form with zero fields.\n      if (!this.config?.columns?.length) return;\n\n      let config = new FormConfig\n\n      config.fields = []\n\n      this.config.columns.forEach(column => {\n\n        // Changed: monogram and chips are DISPLAY-only column types with no form editor. monogram's value is a\n        // plain name string and chips' is an array, so an auto-derived field falls back to text rather than\n        // leaking a Field type that does not exist. This path only runs when a config declares NO formConfig at\n        // all, so it never overrides an author's own field.\n        let field = { name: column.name, type: (column.type === 'monogram' || column.type === 'chips') ? 'text' : column.type }\n        config.fields.push(field)\n\n      });\n\n      this.config.formConfig = config;\n    }\n  }\n\n  setButtons(){\n    if (!this.config.buttons) return\n    if (!this.smallScreen){\n      this.displayedButtons = this.config.buttons;\n    }else{\n      this.displayedButtons = this.config.buttons;\n    }\n  }\n\n  getButton(name: string) {\n    let button = this.buttonService.getButton(this.config.buttons, name);\n    // If not found in main buttons, check header buttons in groupConfig\n    if (!button && this.config.groupConfig?.headerButtons) {\n      button = this.buttonService.getButton(this.config.groupConfig.headerButtons, name);\n    }\n    return button;\n  }\n\n  getIcon(buttonName: string) {\n    const button = this.getButton(buttonName);\n    return this.buttonService.getIcon(button, this.config);\n  }\n\n  getButtonColor(button: Button, row) {\n    return this.buttonService.getButtonColor(button, row);\n  }\n\n  getOptions(column){\n    let x = this.config.columns.find(opt => opt.name === column);\n    return  x\n  }\n\n  getColor(value: any, options: any[]): string {\n    return this.conditionService.getColor(value, options);\n  }\n\n  testIconCondition(row: any, icon: Icon): boolean {\n    return this.conditionService.testIconCondition(icon, row);\n  }\n\n  testColorCondition(row: any, color: Color): boolean {\n    return this.conditionService.testColorCondition(color, row);\n  }\n\n  showBanner(message: string) {\n    if (message && message !== '') {\n      this.messageService.info(message);\n    }\n  }\n\n  testDisabled(row, buttonName: string): boolean {\n    const button = this.getButton(buttonName);\n    return this.buttonService.testDisabled(button, row);\n  }\n\n  // testVisible(row, buttonName: string): boolean {\n  //   const button = this.getButton(buttonName);\n  //   return this.buttonService.testVisible(button, row, this.config);\n  // }\n\n\n\n  //Events\n  lastSearch\n  searchClicked(x){\n    this.searchClick.emit(x);\n    this.lastSearch = x;\n\n    if (this.config.searchConfig.searchAction){\n      this.config.loadAction = { ...this.config.searchConfig.searchAction } //Core.getClone(this.config.searchConfig.searchAction);\n      this.originalTableLoadAction = { ...this.config.searchConfig.searchAction } //Core.getClone(this.config.searchConfig.searchAction);\n      this.loadData(this.config.loadAction, x);\n    }\n  }\n\n  // Added: client-side tile filtering for local-data tables — a tile with `filter` narrows the rows in\n  // memory instead of swapping loadAction (which local tables do not have)\n  private activeTileFilter: ((row: any) => boolean) | null = null;\n  // Changed: the rows a tile filter narrows. It used to be `this.data`, which is the LOCAL-mode @Input and is\n  // `[]` on every server-loaded table — so a filter tile on a loaded grid emptied it instead of narrowing it.\n  // The dataSource setter now keeps this in step with whatever was last loaded.\n  private tileFilterBase: any[] | null = null;\n  private applyingTileFilter = false; // re-entrancy guard for the dataSource setter\n\n  // Added: the quick-filter chip's client-side predicate. It is kept SEPARATE from activeTileFilter rather\n  // than overwriting it, because a tile and a chip are two independent filter layers the user can combine —\n  // \"show me the sows\" AND \"in the east shelter\". Sharing one slot would have made each click silently\n  // cancel the other.\n  private activeChipFilter: ((row: any) => boolean) | null = null;\n\n  private applyTileFilter() {\n    const source = this.tileFilterBase ?? this.data;\n    const base = Array.isArray(source) ? source : [];\n    // Changed: compose the tile and chip predicates. Either may be null; both null leaves the base untouched.\n    const rows = this.narrowByActiveFilters(base);\n    this.applyingTileFilter = true;\n    this.dataSource = rows;\n    this.applyingTileFilter = false;\n    this.setTableData(rows);\n  }\n\n  // Added: applies whichever of the two local filters are active, in sequence.\n  private narrowByActiveFilters(base: any[]): any[] {\n    let rows = base;\n    if (this.activeTileFilter) rows = this.narrowByTile(rows, this.activeTileFilter);\n    if (this.activeChipFilter) rows = this.narrowByTile(rows, this.activeChipFilter);\n    return rows;\n  }\n\n  // Changed: a grouped view's rows ARE the groups, so running a ROW predicate straight over them drops every\n  // group and renders an empty board. The predicate has to run over each group's items instead, leaving the\n  // groups themselves standing (empty ones included, exactly as an unfiltered load leaves them). Copies rather\n  // than mutates, so unclicking restores the original items untouched.\n  private narrowByTile(base: any[], predicate: (row: any) => boolean): any[] {\n    if (this.config?.viewType !== 'grouped') return base.filter(predicate);\n    const itemsField = this.config?.groupConfig?.itemsField ?? 'items'; // mirrors spa-groups' own default\n    return base.map(group => ({ ...group, [itemsField]: (group?.[itemsField] ?? []).filter(predicate) }));\n  }\n\n  tileClicked(tile){\n    if (tile.data?.filter) { this.activeTileFilter = tile.data.filter; this.applyTileFilter(); return; } // Changed: filter tiles narrow locally\n    this.config.loadAction = { ...tile.data.action } //Core.getClone(tile.data.action);\n    this.refreshClicked();\n  }\n\n  tileUnClicked(tile) {\n    if (tile.data?.filter) { this.activeTileFilter = null; this.applyTileFilter(); return; } // Changed: unclick restores the full local set\n    this.config.loadAction = { ...this.originalTableLoadAction } //Core.getClone(this.originalTableLoadAction);\n    this.refreshClicked();\n  }\n\n  // Added: a quick-filter chip was selected. Deliberately mirrors tileClicked/tileUnClicked rather than\n  // introducing a third mechanism — a chip filters EITHER by swapping the loadAction (the server narrows the\n  // result, which is what a shelter chip does: it must drop the other pens entirely, not show them empty) or\n  // by a local predicate over the rows already loaded.\n  // The leading \"All\" chip carries neither, so it falls through to the restore branch and puts the table back\n  // to its original loadAction — the owner's \"if I want to click back to everything, then I can just click\".\n  chipClicked(chip) {\n    if (chip?.filter) { this.activeChipFilter = chip.filter; this.applyTileFilter(); return; }\n\n    this.activeChipFilter = null; // a server-mode chip narrows on the wire, so no local predicate must survive\n\n    // The action this chip wants the table to load. The All chip declares none, so it falls back to whatever\n    // the table was originally loading — that IS \"show me everything again\".\n    // Changed (found in live proof, second pass): test for a real URL, never for truthiness. Line 525 sets\n    // `originalTableLoadAction = { ...this.config.loadAction }`, so a table with NO loadAction gets `{}` — an\n    // EMPTY OBJECT, which is truthy. Testing the object alone sent the All chip down the server branch, where\n    // it fetched nothing and left the table showing the previous chip's rows while the row read as \"All\".\n    // `?.url` is the same guard isOriginalLoad() already uses at line 1954.\n    const target = chip?.action?.url ? { ...chip.action } : (this.originalTableLoadAction?.url ? { ...this.originalTableLoadAction } : null);\n\n    // Changed (found in live proof, not in review): there may be NO server to ask — a table whose rows were\n    // supplied through [data] has no loadAction at all. The first cut assigned `{ ...undefined }` here, i.e. an\n    // empty object, which is TRUTHY: refreshClicked() then fired a load at no URL and the rows never came back,\n    // so clicking All appeared to clear the chip while leaving the table still filtered. Dropping the predicate\n    // and re-applying in memory is the correct restore for that table, and it must not touch loadAction at all.\n    if (!target) { this.applyTileFilter(); return; }\n\n    this.config.loadAction = target;\n    if (this.isLocal) { this.applyTileFilter(); return; } // nested local-rows mode has no server either\n    this.refreshClicked();\n  }\n\n  refreshClicked() {\n    if (this.isLocal) { this.refreshLocalData(); return; } // Added: local mode has no server to refresh from\n    this.refreshClick.emit();\n\n    if (this.config.loadAction) {\n\n      this.nextStageKind = 'refresh'; // Changed (Quiet Loading, Phase 5): set INSIDE this branch. A user-pressed refresh is never a first load, so it must never ghost over content the user is looking at — but the else branch below opens no stage at all, and parking the value there left it to be consumed by whatever load came next (a genuine first load would then get the 2px refresh line instead of its ghost rows)\n      this.loadData(this.config.loadAction,\"\");\n    }else{\n      this.dataLoad.emit();\n    }\n\n\n  }\n\n  dataLoaded(x) {\n    this.hasLoadedOnce = true; // Added (Quiet Loading): every load after the first is a refresh — an empty first result must not re-ghost on the next fetch\n    this.dataLoad.emit(x)\n    this.totalChange.emit(this.pagedMode ? this.serverTotal : (Array.isArray(x) ? x.length : 0)); // Added: paged mode already knows the true server total; legacy mode loads the whole filtered set, so its length IS the total\n\n    if (this.config.tileConfig?.loadAction) {\n      this.tileReload.next(true);\n    }\n\n  }\n\n  actionClicked(name: string, row: any, group?: any, button?: Button) {\n\n\n    const actionButton = button || this.getButton(name);\n\n    if (actionButton?.onClick) {\n      actionButton.onClick(row, () => this.reloadAfterOnClick()); // Changed: a ROW button's onClick is terminal for the same reason a section button's was, and it is the same Button type — so the contract is uniform rather than a special case. Nothing passes a second argument today, so no existing handler changes behaviour\n      // Changed: a pure onClick button (no dialog/action/detailsConfig) is fully handled by its handler — don't also open a dialog\n      if (!actionButton.dialog && !actionButton.action && !actionButton.detailsConfig) return;\n    }\n\n\n    // For item context menu actions, use the row data as-is (which contains the full item)\n    // For group header button actions, pass group-level data + items using server field mapping\n    let actionData = row;\n    if (button && group && group.groupValue !== undefined) {\n      const gc = this.config?.groupConfig;\n      if (gc) {\n        const groupValueField = gc.groupValueField ?? 'groupValue';\n        const displayNameField = gc.displayNameField ?? 'displayName';\n        actionData = {\n          [groupValueField]: group.groupValue,\n          [displayNameField]: group.displayName,\n          items: group.items // Changed: Include group items so header actions can act on all items\n        };\n      }\n    }\n\n    // Changed: Apply rowDataMap — string for simple field mapping, function for computed values\n    if (actionButton?.rowDataMap) {\n      const mapped = { ...actionData };\n      for (const [targetField, sourceOrFn] of Object.entries(actionButton.rowDataMap)) {\n        mapped[targetField] = typeof sourceOrFn === 'function' ? sourceOrFn(actionData) : actionData[sourceOrFn];\n      }\n      actionData = mapped;\n    }\n\n    // Changed: Group header buttons with action but no dialog/detailsConfig go directly to doAction\n    if (button && group && actionButton?.action && !actionButton?.dialog && !actionButton?.detailsConfig) {\n      this.doAction(actionButton.name, actionData, actionButton); // Changed: hand doAction the Button already resolved on line 1120 instead of throwing it away and re-resolving by name. getButton() searches config.buttons FIRST and only then groupConfig.headerButtons, and config.buttons is where table-config.service unshifts the framework approvals buttons — so a group header button named 'approve'/'cancel' was re-resolved to the FRAMEWORK's button, not its own, undoing the identity the caller had already established.\n      return;\n    }\n\n    if (name === 'view') {\n      this.viewModel(actionData, actionButton);\n    } else if (name === 'edit') {\n      // Changed: inlineEdit tables open the row cells in place instead of the dialog — but ONLY when every\n      // editable field actually has a cell on screen. Inline edit is an optimisation of the dialog, so when it\n      // cannot show the whole editor it falls back to the dialog it was optimising: same row, same edit action,\n      // every field rendered (a form has no minColumns). Nothing is submitted that the operator could not see.\n      if (this.config.inlineEdit && this.canEditInline()) {\n        this.startInlineEdit(actionData);\n        return;\n      }\n      this.editModel(actionData, actionButton);\n    } else if (name === 'delete') {\n      this.deleteModel(actionData, actionButton);\n    } else {\n      this.customModel(name, actionData, actionButton);\n    }\n  }\n\n\n  //Dialog events\n  columnClicked(column : Column, row){\n    if (column.detailsConfig) {\n      // Changed: the drill-in is FLAGGED as one. Every column drill-in — chip (table-row.html:15), button (:79) and\n      // monogram (:71, via onMonogramTap) — arrives here, and all three share one property the row-level view button\n      // does not have: the record the dialog is about is named BY the row rather than BEING the row. shift's Trips\n      // grid drills from a trip row into a DRIVER, so the clicked row is a trip. The dialog's failed-load path used\n      // to adopt that row as the record, which renders a driver form with every field empty and no error — the\n      // reported defect. Flagging it here rather than testing for it in the dialog keeps the knowledge where it is\n      // certain: only the table knows the dialog was opened from a column.\n      const button : Button = { name: column.name, dialog: true, detailsConfig: { ...column.detailsConfig, drillIn: true } } // Changed: spread, so the flag never mutates the shared config object an app declares once and every row reuses\n      this.open(button, row, );\n    } else {\n      this.actionClickedEmit(column.name, row);\n    }\n  }\n\n  customModel(name, row, button?: Button) {\n    const actionButton = button || this.getButton(name);\n    this.open(actionButton, row);\n  }\n\n\n  actionClickedEmit(name, row) {\n    this.actionClick.emit({name:name,data : row});\n  }\n\n  viewModel(row, button?: Button) {\n    const actionButton = button || this.getButton('view');\n    this.open(actionButton, row);\n  }\n\n  newModel() {\n    const button = this.getButton('create');\n    this.open(button, null);\n  }\n\n  editModel(row, button?: Button) {\n    let actionButton = button || this.getButton('edit');\n    this.open(actionButton, row);\n  }\n\n  private open(button: Button, row: any | null ): void {\n\n    const buttonName = button.name\n\n\n    // LOAD-BEARING COUPLING — read before changing this fallback or TableConfigService.getDisplayedButtons.\n    // By the time open() runs, `this.config.buttons` has been MUTATED IN PLACE by getDisplayedButtons, which unshifts\n    // the framework approvals buttons into it by reference. Passing that mutated array below is the ONLY reason\n    // Approve/Decline/Cancel (all `inDialog: true`) appear in this dialog's footer — initializeConfigs forwards\n    // `detailsConfig.buttons` unmerged and setupButtons filters on `inDialog`. Reached by any button with no\n    // detailsConfig of its own on a create/edit/delete table (e.g. shift-spa fuel.service.ts edit); make that mutation\n    // a copy and approvals disappear from every one of them across five apps.\n    let btn : Button = {\n      ...button,\n      detailsConfig: {\n        ...(button.detailsConfig ?? {\n          formConfig: this.config.formConfig,\n          stepConfig: this.config.stepConfig,\n          buttons: this.config.buttons, // Mutated array — see the note above; carries the injected approvals buttons\n          heroField: this.config.heroField,\n          heroValue: this.config.heroValue,\n        }),\n        allowUserKeepOpen: this.config.allowUserKeepOpen, // Changed: table config is the single source of truth for this setting\n        keepOpenBehavior: this.config.keepOpenBehavior, // Changed: propagate create behavior preference from table config\n      }\n    }\n\n    // Added: local mode — the dialog validates and returns the row instead of POSTing; edits work on a copy so cancel leaves the array untouched\n    if (this.isLocal) {\n      const localIndex = row ? this.localRows.indexOf(row) : -1;\n      btn.detailsConfig.localMode = true;\n      btn.detailsConfig.detailsSource = DetailsSource.Row;\n      btn.detailsConfig.allowUserKeepOpen = false;\n\n      this.noteWriteIssued(); // Added: the dialog's own write is later still, so stamping at open is always early enough\n      this.dialogService.openDefaultDetailsDialog(btn, row ? { ...row } : null, this.nestingLevel).subscribe(result => {\n        // Delete requested from inside the dialog — remove the in-memory row\n        if (result?.message === 'localDelete' && localIndex >= 0) {\n          this.localRows.splice(localIndex, 1);\n          this.refreshLocalData();\n          return;\n        }\n        if (result?.message !== 'success') return;\n        const localRow = result.data?.data;\n        if (!localRow) return;\n\n        if (buttonName === 'create') {\n          this.localRows.push(localRow);\n        } else if (localIndex >= 0) {\n          this.localRows[localIndex] = localRow;\n        }\n        this.refreshLocalData();\n        this.actionSuccess.emit();\n      });\n      return;\n    }\n\n    this.noteWriteIssued(); // Added: the dialog's own write is later still, so stamping at open is always early enough\n    this.dialogService.openDefaultDetailsDialog(btn, row, this.nestingLevel).subscribe(result => { // Changed: Use token pattern instead of direct DetailsDialog import\n      if (!result) return; // Added: Escape or a backdrop click closes with undefined — a dismissal is a normal outcome, so fall straight out rather than throwing on result.action. No branch below is a default, so doing nothing is exactly right: no refresh, no emit, no onSuccessButton.\n      if (result.action === 'doAction') {\n        this.doAction(result.name, result.row, button); // Changed: hand doAction the same Button object, not just its name. A button with an action but no dialog comes straight back out of openConfiguredDetailsDialog as 'doAction' (dialog.service:63), and re-resolving by name here re-introduced the first-match collision the caller had already resolved correctly.\n        this.actionClickedEmit(result.name, result.row);\n      } else if (result.action === 'inputChange') {\n        this.inputChanged(result.change);\n      } else if (result.message === 'success') {\n        // Changed: emit under the ACTING footer button's name when it opted in via `emitOwnName`, otherwise under the\n        // opener's name exactly as before. The dialog only puts `name` on the payload for an opted-in button, so with\n        // no opt-in anywhere this is `undefined || buttonName` — identical behaviour, including for the framework\n        // approvals buttons. Control flow below deliberately stays on `buttonName`: editOnSuccess and onSuccessButton\n        // are properties of the button that OPENED this dialog and have nothing to do with which footer button closed it.\n        const emittedName = result.name || buttonName;\n        this.actionClickedEmit(emittedName, result.data);\n        this.actionResponse.emit({ name: emittedName, data: result.data });\n        this.realTimeRefreshOrFallback(); // Changed: Use real-time update if enabled, otherwise refresh\n        this.actionSuccess.emit();\n\n        if (buttonName == 'create' && btn.editOnSuccess) {\n          this.editModel(result.data.data);\n        }\n\n        if (btn.onSuccessButton && !result.data?.data?._offline){ // Changed: TinSync — offline creates have no server ID yet, so the auto-open second step is skipped\n          this.open(btn.onSuccessButton, result.data.data);\n        }\n\n      } else if (result.message === 'emit') {\n        this.actionClickedEmit(result.name || buttonName, result.data); // Changed: same opt-in as the success branch above — this is the branch an action-less `inDialog` button (shift-spa's Location) actually takes\n      }\n    });\n  }\n\n  deleteModel(row, button?: Button) {\n\n    let actionButton = button || this.getButton('delete');\n    if (!actionButton) return;\n\n    // Added: local mode — nothing is persisted yet, so delete just removes the in-memory row\n    if (this.isLocal) {\n      const index = this.localRows.indexOf(row);\n      if (index >= 0) {\n        this.localRows.splice(index, 1);\n        this.refreshLocalData();\n      }\n      return;\n    }\n\n    // Changed: message + labels + destructiveness now resolve through the one shared helper instead of this\n    // method assembling the message alone. This is the prompt behind 47 of the delete buttons across the four\n    // apps — none of them declare a confirm of their own — so it is the site where naming the action pays off\n    // most. With appConfig.namedDestructiveActions unset it still renders \"Yes\" / \"No\", unchanged (that is\n    // test-spa, the deliberate control; and the affirmative there is purple, never green — see getConfirmOptions).\n    // Changed: no longer passes the literal `Are you sure you want to delete ?`. That string interpolated NOTHING,\n    // so every delete prompt in the estate read with an empty gap where the record's name belongs. The message is\n    // now composed by getConfirmOptions, which names the row and falls back to \"this record\".\n    const c = this.buttonService.getConfirmOptions(actionButton, row, undefined, this.dataService.namedDestructiveActions, this.tableConfigService.resolveIdentityColumn(this.config, { includeIdColumn: false })?.name);\n\n    // Changed (N22): forwards c.requirePhrase, and unwraps the close value through confirmAccepted rather than\n    // testing `result == \"yes\"` directly — a phrase-gated confirm closes with { response, phrase }. Without a\n    // phrase the dialog still emits the bare string and this behaves exactly as before.\n    this.messageService.confirm(c.message, c.confirmLabel, c.cancelLabel, c.destructive, c.requirePhrase).subscribe((result) => {\n      if (this.buttonService.confirmAccepted(result)) {\n        this.actionClickedEmit('delete', row)\n        this.doAction(actionButton.name, row, undefined, this.buttonService.confirmPhrase(result)); // Changed: carry the typed phrase through — doAction sends a 'delete' straight to execAction without re-prompting, so this is its only route to the payload\n      }\n    });\n\n  }\n\n\n  //Actions\n  doAction(buttonName: string, row, button?: Button, phrase?: string) { // Changed: optional button — a section-level button is not in config.buttons, so it cannot be resolved by name. Changed (N22): optional phrase — deleteModel has already confirmed by the time it calls here, so the text it collected has to be handed on rather than re-collected\n\n    let b = button || this.getButton(buttonName)\n\n    if (!b) return;\n    if (!b.action) return;\n\n    if (b.setHeroField && row && this.config.heroValue) { // Changed: a section-level action has an array (or nothing) for a row — never index into it\n      row[this.config.heroField] = this.config.heroValue;\n    }\n\n    if (b.confirm && b.name != \"delete\") {\n      // Changed: routed through getConfirmOptions so a custom button that names its action ('remove', or any\n      // button carrying confirm.confirmLabel) is honoured here too. The `b.confirm` guard above is untouched, so\n      // a button with no confirm config still runs straight through without a prompt.\n      const c = this.buttonService.getConfirmOptions(b, row, undefined, this.dataService.namedDestructiveActions);\n      // Changed (N22): forwards c.requirePhrase and unwraps both close shapes — see deleteModel.\n      this.messageService.confirm(c.message, c.confirmLabel, c.cancelLabel, c.destructive, c.requirePhrase).subscribe((result) => {\n        if (this.buttonService.confirmAccepted(result)) {\n          this.execAction(b, row, this.buttonService.confirmPhrase(result))\n        }\n      });\n    }else{\n      this.execAction(b, row, phrase) // Changed (N22): a 'delete' reaches here already confirmed by deleteModel, carrying its phrase\n    }\n\n  }\n\n  execAction(button: Button, row, phrase?: string){\n    this.noteWriteIssued(); // Added: stamp before the write leaves, so a broadcast it causes is provably later\n    // Added (N22): the typed phrase rides in the payload because the server re-validates it independently — the\n    // dialog's gate lives in the browser and any direct caller never sees it. Sent on a COPY: mutating `row`\n    // would write a stray `phrase` onto the live table record, which then shows up in the next save.\n    const payload = phrase !== undefined ? { ...row, phrase } : row;\n    this.dataService.CallApi(button.action, payload).subscribe((apiResponse : ApiResponse) => {\n\n      if (apiResponse.success) {\n\n        if (apiResponse.message.includes(\"approval\") || apiResponse.message.includes(\"approve\") || apiResponse.message.includes(\"decline\")) {\n          this.messageService.toast(apiResponse.message);\n        }else if (button.action.successMessage) {\n          this.messageService.toast(button.action.successMessage);\n        } else if (apiResponse.message != \"success\" && apiResponse.message != \"\") {\n          this.messageService.toast(apiResponse.message);\n        } else {\n          this.messageService.toast(\"Updated\");\n        }\n\n        this.realTimeRefreshOrFallback(); // Changed: Use real-time update if enabled, otherwise refresh\n        this.actionSuccess.emit();\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'action', button.action.url); // Changed: row action (approve/cancel/delete/custom) — business refusals stay toasts, opaque server text gets the dialog\n      }\n\n      this.actionResponse.emit({name:button.name, data:apiResponse});\n    },\n      (error) => {\n        this.apiErrorService.present(error); // Changed: transport failure on a row action — was toast(\"Error: \" + error); present() classifies, dedupes with other transport failures and never shows raw error text\n      }\n    );\n  }\n\n\n  //Misc\n  private getElevationClass(elevation: string): string {\n\n    if (elevation == \"none\"){\n      return \"\"\n    }\n    else if (elevation == \"low\"){\n      return \"mat-elevation-z1\"\n    }\n    else if (elevation == \"medium\"){\n      return \"mat-elevation-z5\"\n    }\n    else if (elevation == \"high\"){\n      return \"mat-elevation-z9\"\n    }\n    else{\n      return \"mat-elevation-z5\"\n    }\n\n  }\n\n  // The real-time table contract. Three states, not two:\n  //\n  //   real-time OFF, or SignalR DOWN  -> refresh immediately. Unchanged, and the only behaviour most tables see.\n  //   real-time healthy               -> do NOT refresh. The broadcast is coming to everyone including the\n  //                                      author, and the grid patches in place from it. This is the efficiency\n  //                                      the real-time design exists to buy: one push instead of a re-read.\n  //   real-time healthy, no broadcast -> a single-shot fallback refresh fires after effRealTimeFallbackMs.\n  //\n  // HISTORY, because this has now been wrong in both directions and the middle ground is the whole point:\n  // the original body was `if (!effRealTime || !isSignalRConnected) refreshClicked()`, with no fallback. That\n  // left a healthy real-time table doing NOTHING when a write produced no matching broadcast — and the SignalR\n  // streams are filtered on this table's own entityName, so an action writing a DIFFERENT entity (invoicing a\n  // rental writes an Invoice) never emits one. Grip's rentals grid kept rendering \"Returned\" for a row already\n  // Invoiced in the database. 0a305df fixed that staleness by refreshing UNCONDITIONALLY, which cured the bug\n  // but discarded the contract: a healthy table then did the broadcast patch AND a full re-fetch on every write\n  // (measured 2026-08-17 on test-spa — 1 broadcast frame and 1 list re-fetch per create).\n  //\n  // The fallback timer is the machinery that reconciles them, and it needs no correlation id: not hearing a\n  // matching broadcast within the window is itself the signal. A cross-entity action never cancels the timer,\n  // so the rentals case still self-heals — a few seconds later instead of never — while the ordinary\n  // same-entity write is served by the push alone and never re-reads the list.\n  private realTimeRefreshOrFallback() {\n    if (!this.effRealTime || !this.isSignalRConnected) { this.refreshClicked(); return; }\n\n    // 🔴 THE BROADCAST USUALLY WINS THE RACE, so \"arm a timer and let the broadcast cancel it\" is not enough on\n    // its own. The server broadcasts as it commits, while this method runs only once the write has been fully\n    // handled — for the dialog paths, not until the dialog has CLOSED. Measured on test-spa 2026-08-17: the\n    // EntityCreated frame landed at +339ms and this ran at ~+460ms, so the cancel found no timer, the timer was\n    // then armed, and a pointless refresh fired at +3464ms. The contract failed while looking like it worked.\n    //\n    // So the test is not \"does a broadcast arrive from here on\" but \"has one been APPLIED since this write was\n    // issued\". noteWriteIssued() stamps the moment before each write leaves, which is always strictly earlier\n    // than any broadcast that write can cause.\n    // >= not >: Date.now() has millisecond resolution and a fast local round trip can stamp both in the same\n    // tick. Ties count as \"the push already covered it\" — the alternative is a needless refresh on exactly the\n    // fastest, healthiest connections, which is where the contract matters most.\n    if (this.lastRealTimeApplyAt >= this.writeIssuedAt && this.lastRealTimeApplyAt > 0) return;\n\n    this.armRealTimeFallback();\n  }\n\n  private realTimeFallbackTimer: any = null;\n  private lastRealTimeApplyAt = 0; // when a matching broadcast was last APPLIED to this grid\n  private writeIssuedAt = 0;       // when this table last sent a write\n\n  // Stamped immediately before a write leaves the component, so a broadcast caused by that write always lands\n  // after it. Cheap and side-effect free, which is why it can sit on the dialog-OPEN path too: the dialog's own\n  // write is necessarily later still, and stamping early can only ever make the fallback more eager, never less.\n  private noteWriteIssued() {\n    this.writeIssuedAt = Date.now();\n  }\n\n  // Arms the single-shot backstop. Re-arming (a second write inside the window) restarts it rather than\n  // stacking timers, so N rapid writes can never queue N refreshes.\n  private armRealTimeFallback() {\n    this.cancelRealTimeFallback();\n    const wait = this.effRealTimeFallbackMs;\n    this.realTimeFallbackTimer = setTimeout(() => {\n      this.realTimeFallbackTimer = null;\n      this.refreshClicked(); // no broadcast arrived in time — a refresh beats a stale grid\n    }, wait);\n  }\n\n  // Cancels the backstop. Called ONLY from the points where a broadcast has actually been APPLIED to this\n  // grid — never merely where one arrived. The create stream is deliberately skipped for a subset view\n  // (setupRealTimeSubscriptions, offline + non-entity-wide): there the row was NOT added, so the write is\n  // still unreflected and the fallback must be left running to fetch it.\n  private cancelRealTimeFallback() {\n    this.lastRealTimeApplyAt = Date.now(); // records the apply even when no timer is running yet — see the race note above\n    if (this.realTimeFallbackTimer) {\n      clearTimeout(this.realTimeFallbackTimer);\n      this.realTimeFallbackTimer = null;\n    }\n  }\n\n  //---------------- TinSync offline support ----------------\n\n  // Registers the table's URLs with the offline service, starts the sync engine, and wires live overlay updates\n  private setupOffline() {\n    const offlineCfg = this.effOffline; // Changed: honours the app-wide default so nested/detail tabs inherit it too\n    if (!offlineCfg) return;\n\n    // Changed: register against a config carrying the RESOLVED offline value, so a table relying on the\n    // app-wide default registers identically to one that declared `offline` inline.\n    //\n    // When paged, the read cache is capped to roughly the fetch window rather than the 500-row default:\n    // a paged table only ever holds a window in memory, so persisting more would cache rows the user never\n    // loaded and inflate storage for no benefit.\n    const registration: any = { ...this.config, offline: offlineCfg === true ? { enabled: true } : offlineCfg };\n    if (this.pagedMode) {\n      const cfg = registration.offline;\n      registration.offline = { ...cfg, cacheRows: cfg.cacheRows ?? Math.max(this.fetchSize * 3, 60) };\n    }\n\n    this.offlineEntry = this.offline.register(registration);\n    if (!this.offlineEntry) return;\n\n    this.placeStatusIcons();\n\n    // Live pending ops for this entity — re-render badges/overlay the moment anything changes, in every tab\n    this.offlineSubs.push(this.offline.pendingOpsFor$(this.offlineEntry.entity).subscribe(ops => {\n      this.pendingOps = ops;\n      this.reapplyOverlay();\n    }));\n\n    // Push-then-pull: refetch after the drainer syncs ops for this entity so server state replaces speculative rows\n    this.offlineSubs.push(this.offline.drained$.subscribe(entities => {\n      if (this.offlineEntry && entities.includes(this.offlineEntry.entity)) this.refreshClicked();\n    }));\n  }\n\n  //---------------- Reconnect refresh (offline -> back online) ----------------\n\n  // Added: the defined contract — whenever the app detects offline -> back online, the affected tables refresh\n  // themselves. Both indicators the user watches already recovered on their own (the toolbar cloud icon from\n  // OfflineService.online$, this header's green dot from dataHubConnected$) while the grid went on showing\n  // whatever it held when the connection dropped. The UI therefore stated \"live\" over stale rows, which is the\n  // one state the real-time contract exists to prevent. Reproduced on test-spa 2026-08-18: both indicators\n  // recovered, zero list re-fetches followed, and a row created during the outage never appeared.\n  //\n  // This is the SANCTIONED EXCEPTION to \"a real-time table waits for its broadcast instead of re-reading the\n  // list\" (0fe681d). While we were offline the hub was down, so the broadcasts that would have patched those\n  // rows in place were never delivered and cannot arrive late — there is nothing to wait for, and a re-read is\n  // the only route back to the truth. It stays an exception by construction: it fires on a connectivity\n  // TRANSITION only, never on a write, and never on a first connect.\n  //\n  // Why BOTH signals, and why neither alone is enough:\n  //   • online$ is OfflineService's ping-and-SignalR verdict — the cloud icon's own source — but\n  //     ensureConnectivity() is gated on runtimeConfig.offline, so in an app with realTime and no offline\n  //     capability it never moves off its initial value.\n  //   • dataHubConnected$ covers that app, but it is silent when real-time is off.\n  // Deduped because the two are married on purpose (OfflineService.setOnline() calls signalR.reconnectIfNeeded()),\n  // so one recovery normally flips both within a second or two and must still cost exactly ONE fetch.\n  //\n  // Note on the dead hook this replaces: SignalRService.onDataReconnected has carried the comment \"tables should\n  // reload (set by table components)\" since 1edd335 (2026-03-23) and is invoked on both reconnect paths, but\n  // NOTHING EVER ASSIGNED IT — `git log --all -G\"onDataReconnected\\s*=\\s*\\(\"` is empty. So this behaviour was\n  // declared and never implemented; it is not a regression. It is also a single-slot callback, which cannot serve\n  // the N tables a page may hold — hence a per-table subscription here rather than filling that slot in.\n  private setupReconnectRefresh() {\n    // ARMING is the whole correctness argument. Both streams are BehaviorSubjects, so each replays its CURRENT\n    // value to a new subscriber, and dataHubConnected$ additionally emits false-then-true on every normal page\n    // load. A naive \"refresh when it turns true\" would therefore re-fetch every list immediately after its first\n    // load, on every app start. Each arm opens only once its stream has been seen DOWN after having been UP.\n    this.subs.push(this.offline.online$.subscribe(online => {\n      if (!online) { this.reconnectArmedOnline = true; return; } // includes a table MOUNTED while offline, which is exactly a table that never loaded\n      if (!this.reconnectArmedOnline) return;                    // the replayed initial `true`, or a repeat — not a recovery\n      this.reconnectArmedOnline = false;\n      this.reconnectRefresh();\n    }));\n\n    this.subs.push(this.signalRService.dataHubConnected$.subscribe(connected => {\n      if (connected) {\n        if (this.reconnectArmedHub) { this.reconnectArmedHub = false; this.reconnectRefresh(); }\n        this.hubHasConnected = true;\n        return;\n      }\n      // A drop only counts once there was a connection to lose. KNOWN AND DELIBERATE GAP: a table mounted while\n      // the hub is already down is not armed by this stream, because the initial `false` of a perfectly ordinary\n      // page load is indistinguishable from it here. Arming on it would re-fetch every grid on every startup —\n      // a certain cost against an uncertain one. In an offline-capable app (where the owner's report came from)\n      // online$ above covers that case; in a realTime-only app that table waits for the user's refresh.\n      if (this.hubHasConnected) this.reconnectArmedHub = true;\n    }));\n  }\n\n  // One fetch per recovery. refreshClicked() already carries the whole refresh contract — the paged reset, the\n  // 'refresh' loading stage that never ghosts over content the user is reading, the parent-driven dataLoad emit\n  // for a table with no loadAction of its own, and the local-mode early return — so this deliberately adds no\n  // second path to the same job.\n  private reconnectRefresh() {\n    const now = Date.now();\n    if (now - this.lastReconnectRefresh < TableComponent.RECONNECT_DEDUPE_MS) return;\n    this.lastReconnectRefresh = now;\n    this.refreshClicked();\n  }\n\n  // Status icons go into an existing Name (first choice) or Description column so authors define nothing;\n  // only if neither exists do we inject a dedicated 'Sync' column as the LAST column before Action.\n  // IDEMPOTENT: TableConfig is often a shared singleton reused across page revisits, so each injected icon is\n  // tagged and any previously-injected set is stripped before re-adding — preventing duplicate icon build-up.\n  private placeStatusIcons() {\n    if (!this.config.columns) return;\n\n    const TAG = '_tinsyncIcon';\n    const tag = (icon: Icon): Icon => { (icon as any)[TAG] = true; return icon; };\n    const statusIcons: Icon[] = [\n      { name: 'cloud_upload', color: '#FFA000', condition: (x: any) => x._offline?.status === 'pending' || x._offline?.status === 'syncing', tip: 'Waiting to sync — will be sent when connection is restored' },\n      { name: 'error', color: '#F44336', condition: (x: any) => x._offline?.status === 'failed', tip: 'Sync failed — open the sync tray to review' },\n      { name: 'call_merge', color: '#FF6F00', condition: (x: any) => x._offline?.status === 'conflict', tip: 'Changed by someone else — review in the sync tray' },\n      { name: 'hourglass_empty', color: '#90A4AE', condition: (x: any) => x._offline?.status === 'stale', tip: 'Held — too old to auto-send; review in the sync tray' },\n    ].map(tag);\n\n    // Changed: the name/description search is now TableConfigService.resolveIdentityColumn — the one definition of\n    // \"which column names the thing this row IS\", shared with the locked-row cue. Same scope (every column in the\n    // config, not just the displayed ones) and includeIdColumn:false keeps the id/PK step OUT, which is the\n    // difference this consumer has always had: sync falls back to injecting its own column rather than riding an id.\n    // What DOES change: a config declaring identityColumn now hosts the sync icons there instead of injecting a\n    // '_offlineStatus' column, and identityColumn:false injects one. No config in the estate declares it yet, so\n    // nothing moves today.\n    const host = this.tableConfigService.resolveIdentityColumn(this.config, { includeIdColumn: false });\n\n    if (host) {\n      // strip any previously-injected status icons, then re-add exactly one set (idempotent across revisits)\n      host.icons = [...(host.icons ?? []).filter(i => !(i as any)[TAG]), ...statusIcons];\n      return;\n    }\n\n    const existing = this.config.columns.find(c => c.name === '_offlineStatus');\n    if (existing) { existing.icons = statusIcons; return; } // reuse the already-injected column instead of adding another\n    this.config.columns = [...this.config.columns, { name: '_offlineStatus', type: 'icon', alias: 'Sync', icons: statusIcons }]; // last data column -> renders just before Action\n  }\n\n  //---------------- Locked-row cue (convention, no configuration) ----------------\n\n  // Added: an ILock row (server projects `locked`) had NO visual indicator — the only sign was a kebab item\n  // appearing on some rows and not others, which reads as a glitch rather than as state. This mirrors the\n  // TinSync convention above: the cue rides an EXISTING column's icons array, so an author configures nothing.\n  //\n  // Deliberately DIFFERENT from placeStatusIcons in two ways:\n  //   1. It never invents a column. Sync falls back to injecting '_offlineStatus'; a lock is a decoration on an\n  //      identity the operator already reads, not a fact worth a column of its own. No name/description/id on\n  //      screen -> no cue (the unlock button still carries the state on those grids).\n  //   2. It resolves against displayedColumns, not config.columns, so a host cut by minColumns on a phone or by\n  //      a visible/hidden predicate is not chosen — an icon parked on a column nobody renders is invisible.\n  //\n  // Runs unconditionally on every table (the condition simply never fires on rows without `locked`) and is\n  // IDEMPOTENT: TableConfig is often a shared singleton, and this re-runs on every resize, so the previously\n  // injected icon is stripped from EVERY column before one is re-added — the host may have changed.\n  private placeLockIcon() {\n    if (!this.config?.columns) return;\n\n    const TAG = '_tinlockIcon';\n    const lockIcon: any = { name: 'lock', color: '#90A4AE', tip: 'Locked — protected from editing and deletion', condition: (x: any) => !!(x?.locked ?? x?.Locked) }; // muted blue-grey, the tone the held/stale sync icon already uses: a cue, not an alarm. Both casings because a locked flag reaching the row un-camel-cased must not silently show nothing.\n    lockIcon[TAG] = true;\n\n    this.config.columns.forEach(c => { if (c.icons?.some(i => (i as any)[TAG])) c.icons = c.icons.filter(i => !(i as any)[TAG]); });\n\n    const host = this.resolveLockHost();\n    if (!host) return; // nothing to decorate — correct outcome, not a failure\n    host.icons = [...(host.icons ?? []), lockIcon]; // appended, so any author icon and the sync icons keep their place and a row can carry both cues\n  }\n\n  // Changed: the lock host IS the row's identifying column, so it is no longer resolved here — the whole chain\n  // (name -> description -> id/PK, matched on name or alias, plus any declared identityColumn) now lives in\n  // TableConfigService.resolveIdentityColumn and is shared with the sync icons. This consumer's own difference is\n  // stated in the one argument it passes: the scope is the columns ACTUALLY DISPLAYED, so a host cut by minColumns\n  // on a phone is not chosen. `?? []` is deliberate — displayedColumns is legitimately undefined before the first\n  // breakpoint emission, and an empty scope must mean \"nothing is rendered\", never \"consider everything\".\n  // lockIdColumnNames() moved to the service with it; it had no other caller.\n  private resolveLockHost(): Column | null {\n    return this.tableConfigService.resolveIdentityColumn(this.config, { scope: this.displayedColumns ?? [] });\n  }\n\n  // Captures the raw server rows and merges pending ops: creates prepend, edits patch by id, deletes hide\n  private applyOfflineOverlay(rows: any): any {\n    if (!this.offlineEntry || !Array.isArray(rows)) return rows;\n    this.rawRows = rows;\n    return this.computeOverlay(rows);\n  }\n\n  private computeOverlay(rows: any[]): any[] {\n    if (!this.offlineEntry || !this.pendingOps?.length) return rows;\n    const idField = this.offlineEntry.idField;\n    let result = [...rows];\n\n    this.pendingOps.forEach(op => {\n      if (op.opAction === 'create') {\n        const alreadyOnServer = result.some(r => r.clientRef && r.clientRef === op.clientRef);\n        if (!alreadyOnServer) result = [{ ...op.payload, _offline: { status: op.status, opId: op.opId, clientRef: op.clientRef } }, ...result];\n      } else if (op.opAction === 'edit') {\n        result = result.map(r => r[idField] === op.targetId ? { ...r, ...op.payload, _offline: { status: op.status, opId: op.opId } } : r);\n      } else if (op.opAction === 'delete') {\n        result = result.filter(r => r[idField] !== op.targetId);\n      }\n    });\n\n    return result;\n  }\n\n  private reapplyOverlay() {\n    if (!this.offlineEntry) return;\n    // Changed: paged mode re-renders through updateSlice, which overlays THEN slices. Falling through to the\n    // assignment below would put the entire overlaid window on one page (defect C).\n    if (this.pagedMode) { this.updateSlice(); return; }\n    if (!this.rawRows) return;\n    const rows = this.computeOverlay(this.rawRows);\n    this.dataSource = rows;\n    if (this.tableDataSource) this.tableDataSource.data = rows;\n  }\n\n  // Changed: Set up SignalR subscriptions for real-time entity change updates\n  private setupRealTimeSubscriptions() {\n    this.realTimeEntityName = this.config.entityName || this.deriveEntityName();\n\n    // Changed: Subscribe to data hub connection state for real-time indicator\n    this.realTimeSubs.push(\n      this.signalRService.dataHubConnected$.subscribe(connected => {\n        this.isSignalRConnected = connected;\n      })\n    );\n\n    // Changed: Subscribe to entity created — add new row to table\n    this.realTimeSubs.push(\n      this.signalRService.entityCreated$.subscribe(event => {\n        if (event.entityName !== this.realTimeEntityName) return;\n        if (!this.tableDataSource) return;\n        // Added: the SignalR create stream is ENTITY-WIDE — it carries no criteria — so a row it announces is\n        // not known to belong to a SUBSET view (a per-parent detail tab, or a tile-filtered view). Prepending\n        // it there was already a display bug; now that those urls are in the offline read registry it would\n        // also be PERSISTED into that subset's cache on the next window write. Skipped for offline tables,\n        // where the consequence is durable — the row still arrives on the next refresh. Update and delete need\n        // no such guard: they only touch rows already present, so membership is never fabricated.\n        if (this.offlineEntry && !this.isEntityWideView()) return;\n\n        // Added: paged mode patches the accumulated window in place — new rows prepend (PK-desc order) and the true total grows\n        if (this.pagedMode) {\n          this.loadedRows = [event.data, ...this.loadedRows];\n          this.serverTotal++;\n          this.updateSlice();\n          this.cancelRealTimeFallback(); // Added: the push landed — the backstop refresh is no longer needed\n          return;\n        }\n\n        const base = this.realTimeBaseRows(); // Changed: build from raw server rows so the offline cache mirrors what's shown\n        this.applyRealTimeData([event.data, ...base]); // Changed: Insert at top so new records are immediately visible\n        this.cancelRealTimeFallback(); // Added: the push landed — the backstop refresh is no longer needed\n      })\n    );\n\n    // Changed: Subscribe to entity updated — replace existing row by ID\n    this.realTimeSubs.push(\n      this.signalRService.entityUpdated$.subscribe(event => {\n        if (event.entityName !== this.realTimeEntityName) return;\n        if (!this.tableDataSource) return;\n\n        const idKey = this.findIdKey(event.data);\n        if (!idKey) return;\n\n        // Added: paged mode patches loaded rows by id — rows beyond the loaded window are simply not present, so nothing to update\n        if (this.pagedMode) {\n          this.loadedRows = this.loadedRows.map(row => row[idKey] === event.data[idKey] ? event.data : row);\n          this.updateSlice();\n          this.cancelRealTimeFallback(); // Added: the push landed — the backstop refresh is no longer needed\n          return;\n        }\n\n        const base = this.realTimeBaseRows();\n        this.applyRealTimeData(base.map(row => row[idKey] === event.data[idKey] ? event.data : row));\n        this.cancelRealTimeFallback(); // Added: the push landed — the backstop refresh is no longer needed\n      })\n    );\n\n    // Changed: Subscribe to entity deleted — remove row by ID\n    this.realTimeSubs.push(\n      this.signalRService.entityDeleted$.subscribe(event => {\n        if (event.entityName !== this.realTimeEntityName) return;\n        if (!this.tableDataSource) return;\n\n        // Added: paged mode removes from the loaded window and shrinks the total; rows beyond the window self-heal on next refresh\n        if (this.pagedMode) {\n          const pagedIdKey = this.findIdKey(this.loadedRows[0]);\n          if (!pagedIdKey) return;\n          const before = this.loadedRows.length;\n          this.loadedRows = this.loadedRows.filter(row => row[pagedIdKey] !== event.data);\n          if (this.loadedRows.length < before) {\n            this.serverTotal--;\n            this.clampPageIndex();\n            this.updateSlice();\n            this.cancelRealTimeFallback(); // Added: only when a row actually left the window — an unmatched delete leaves the backstop armed\n          }\n          return;\n        }\n\n        const base = this.realTimeBaseRows();\n        const idKey = this.findIdKey(base[0]);\n        if (!idKey) return;\n        const remaining = base.filter(row => row[idKey] !== event.data);\n        this.applyRealTimeData(remaining);\n        if (remaining.length < base.length) this.cancelRealTimeFallback(); // Added: same rule — a delete that removed nothing has not reflected the write\n\n      })\n    );\n  }\n\n  // Added: true when this table shows the WHOLE entity, false when it shows a subset — a per-parent detail tab\n  // (loadCriteria rewrites the url to `<entity>/<criteria>/<id>`) or a tile-filtered view (tileClicked swaps\n  // config.loadAction, so it no longer matches the url captured at init). Both now register with the offline\n  // read cache under their OWN url, which is what makes the distinction matter.\n  private isEntityWideView(): boolean {\n    if (this.config.loadCriteria) return false;\n    const url = this.config.loadAction?.url;\n    return !!url && (!this.originalTableLoadAction?.url || url === this.originalTableLoadAction.url);\n  }\n\n  // Base rows for a real-time patch: the RAW server rows for offline tables (so overlay/cache stay correct),\n  // otherwise the current table rows.\n  private realTimeBaseRows(): any[] {\n    if (this.offlineEntry) return this.rawRows ?? [];\n    return this.tableDataSource.data;\n  }\n\n  // Applies real-time rows to the table AND, for offline-enabled tables, mirrors them into the persistent\n  // read cache + rawRows so records created/edited online stay visible after going offline; overlay reapplied.\n  private applyRealTimeData(rawRows: any[]) {\n    if (this.offlineEntry && this.config.loadAction?.url) {\n      const clean = rawRows.map(r => { const { _offline, ...rest } = r; return rest; }); // never cache overlay markers\n      this.rawRows = clean;\n      this.offline.putRead(this.config.loadAction.url, this.offlineEntry.entity, clean, this.offlineEntry.config.cacheRows);\n      const overlaid = this.computeOverlay(clean);\n      this.dataSource = overlaid;\n      this.tableDataSource.data = overlaid;\n    } else {\n      this.dataSource = rawRows;\n      this.tableDataSource.data = rawRows;\n    }\n  }\n\n  // Changed: the derivation itself moved to TableConfigService.deriveEntityName, so the token SignalR subscribes\n  // with and the token the identity/lock resolver hunts a PK column by cannot drift apart — they were two copies\n  // of one singulariser sitting 200 lines apart. The body was carried over verbatim, including the segment-census\n  // reasoning for why the rule is deliberately narrow; read it there before widening it.\n  private deriveEntityName(): string {\n    return this.tableConfigService.deriveEntityName(this.config);\n  }\n\n  // Changed: Find the ID property key in a row object (convention: ends with 'ID')\n  private findIdKey(row: any): string | null {\n    if (!row) return null;\n    return Object.keys(row).find(k => k.endsWith('ID') && k !== 'TenantID') || null;\n  }\n\n  //---------------- Row reordering (opt-in via config.orderable) ----------------\n  // Added: drag-to-reorder for an entity implementing TinWeb's IOrder. Everything below is inert — and every\n  // affordance absent from the DOM — unless a config declares `orderable`.\n\n  // Resolved ONCE per configuration pass by setupOrderable(). Deliberately a FIELD and not a getter: the\n  // `orderable: true` shorthand has to be normalised into an object, and doing that in a template-bound getter\n  // allocates a new object on every change-detection tick, which is the exact shape of the livelock that\n  // template-bound allocating getters are banned for in this library.\n  orderableConfig: OrderableConfig | null = null;\n\n  // Changed (grouped-orderable): the reorder rules moved to the shared RowOrderService so the GROUPED view posts\n  // the identical request instead of growing a second copy of the contract. Constructed here rather than injected\n  // ON PURPOSE — eleven spec files construct TableComponent with positional arguments, and adding a constructor\n  // parameter would churn all of them for no behavioural gain. The service has only these two collaborators.\n  // Built LAZILY: the constructor body subscribes to the breakpoint observer, which can call setupOrderable\n  // synchronously, so a field initializer here would not reliably have run yet.\n  private rowOrderService: RowOrderService | null = null;\n  private get rowOrder(): RowOrderService {\n    return this.rowOrderService ??= new RowOrderService(this.dataService, this.apiErrorService);\n  }\n\n  private setupOrderable() {\n    this.orderableConfig = this.rowOrder.normalize(this.config?.orderable); // `false`/absent → null → zero affordances\n    // The grip gets its own leading column, added HERE rather than inside TableConfigService.setColumns so that\n    // a table which never asked to be orderable cannot acquire a column through the shared column builder.\n    if (this.orderableConfig && this.displayedColumns && !this.displayedColumns.includes('orderHandle')) {\n      this.displayedColumns = ['orderHandle', ...this.displayedColumns];\n    }\n  }\n\n  // A filter narrows the rows, so the rendered list is NOT the complete scope. The contract requires every id\n  // in the scope, and the server's set comparison would refuse a partial list anyway — so refuse it here, with\n  // a sentence that names the remedy, rather than posting something we know is going to bounce.\n  get orderFilterActive(): boolean {\n    return this.pagedMode ? this.filterActive : !!this.tableDataSource?.filter;\n  }\n\n  // spa-table wires no MatSort today (there is no mat-sort-header anywhere in its template), so this is a\n  // FORWARD GUARD, not dead code: the day a sort lands, a prescribed order computed from a sequence the user\n  // cannot see must not silently become the saved one.\n  get orderSortActive(): boolean {\n    return !!this.tableDataSource?.sort?.active;\n  }\n\n  // Drag is allowed only when the rows on screen ARE the whole scope. Applied to the client-side paginator as\n  // well as server-side paged mode, and that is deliberate: a MatTableDataSource with a paginator renders one\n  // page while .data holds everything, so CDK's drop indices are page-relative and mapping them onto the full\n  // list is exactly the absolute-index arithmetic the FSD defers. Cross-page dragging is OUT OF SCOPE.\n  get orderMultiPage(): boolean {\n    const total = this.pagedMode ? this.serverTotal : (this.tableDataSource?.data?.length ?? 0);\n    const size = this.pagedMode ? this.pageSize : (this.tablePaginator?.pageSize ?? 0);\n    return !!size && total > size;\n  }\n\n  // Returns the SENTENCE shown on the greyed grip, or null when dragging is live. One string, so the template\n  // binds a tooltip and a disabled state from a single source and they cannot disagree.\n  get orderDisabledReason(): string | null {\n    if (!this.orderableConfig) return null;\n    if (this.orderSortActive) return 'Clear sorting to reorder';\n    if (this.orderFilterActive) return 'Clear the filter to reorder';\n    if (this.orderMultiPage) return 'Show all rows on one page to reorder';\n    return null;\n  }\n\n  get orderEnabled(): boolean {\n    return !!this.orderableConfig && !this.orderDisabledReason;\n  }\n\n  // mat-table row-def predicate. Deliberately keyed on the CONFIG, not on row data, so it is constant for a\n  // given table: rows are draggable-capable or they are not. It gates whether cdkDrag is ATTACHED at all,\n  // which is a different question from orderEnabled (whether a drag may currently HAPPEN) — a filtered\n  // orderable table still attaches cdkDrag and disables it, so the grip can grey and explain itself, while a\n  // table that never opted in attaches nothing. An arrow property because the template calls it unbound.\n  rowsAreOrderable = (_index: number, _row: any): boolean => !!this.orderableConfig;\n\n  // The row's identity for the posted id list: an explicit idField, then the table's heroField, then the\n  // ...ID convention findIdKey already encodes for trackBy. Reused rather than re-derived.\n  private rowOrderId(row: any): any {\n    // Changed: same precedence as before (idField, heroField, cached trackBy key, ...ID convention) — the ordering\n    // is now expressed as the service's fallback list so the grouped view resolves ids by the identical rule.\n    return this.rowOrder.resolveId(row, this.orderableConfig, [this.config?.heroField, this.rowIdKey, this.findIdKey(row)]);\n  }\n\n  // Defaults to the FIRST path segment of the load URL + '/reorder', which is the controller route the base\n  // [HttpPost(\"reorder\")] action hangs off ('product-groups?action=list' → 'product-groups/reorder'). An app\n  // whose reorder endpoint is not that sets orderable.action explicitly rather than fighting this.\n  private reorderAction(): Action {\n    return this.rowOrder.action(this.orderableConfig, this.config?.loadAction); // Changed: shared with the grouped view\n  }\n\n  // The scope this drag happened inside. An explicit scopeValue wins, because the scope is often a chip the\n  // user picked and is not on the rows at all; scopeField reads it off a row; absent both, the sequence is\n  // flat across the tenant and null is the correct thing to send.\n  private orderScope(rows: any[]): any {\n    return this.rowOrder.scope(this.orderableConfig, rows); // Changed: shared. No fallback scope here — a flat table with neither scopeValue nor scopeField is a tenant-wide sequence and null is the correct thing to send\n  }\n\n  // Optimistic move, POST, revert on refusal — the shape proven at groups.component.ts:166-196.\n  onRowDrop(event: CdkDragDrop<any[]>) {\n    if (!this.orderEnabled) return; // the drop list is disabled too; this is the belt to that braces\n    if (event.previousIndex === event.currentIndex) return; // a drag that landed where it started is not a write\n\n    const rows = this.tableDataSource?.data;\n    if (!rows?.length) return;\n\n    // Optimistic move. moveItemInArray mutates in place, so dataSource — the same array reference — moves with\n    // it; reassigning .data is what makes MatTableDataSource redraw.\n    moveItemInArray(rows, event.previousIndex, event.currentIndex);\n    this.tableDataSource.data = [...rows];\n\n    const revert = () => {\n      moveItemInArray(rows, event.currentIndex, event.previousIndex);\n      this.tableDataSource.data = [...rows];\n    };\n\n    const ids = rows.map(r => this.rowOrderId(r)).filter(id => id !== null && id !== undefined);\n    // Changed: the short-list refusal is unchanged in effect, but it now also catches a DUPLICATE id list and\n    // SAYS SO. A row with no resolvable id posts a short list, and two rows resolving the same id post a\n    // same-length list the server's set comparison refuses at HTTP 200 — both used to revert in total silence,\n    // which is indistinguishable from a genuine conflict. It is a misconfigured idField every time.\n    const refusal = this.rowOrder.validateIds(ids, rows.length);\n    if (refusal) { revert(); this.rowOrder.presentLocalRefusal(refusal, this.reorderAction().url); return; }\n\n    // The payload is the whole ordered scope and no order numbers — position IS the order (ReorderRequest.cs).\n    this.rowOrder.persist(this.orderableConfig, this.config?.loadAction, ids, this.orderScope(rows), {\n      revert,\n      refresh: () => { if (this.config?.loadAction) this.loadData(this.config.loadAction, ''); }\n    });\n  }\n\n  // Changed: Clean up SignalR subscriptions on component destroy\n  ngOnDestroy() {\n    this.clearStage(); // Added (Quiet Loading): cancels the rAF loop and both anti-flicker timers — a table torn down mid-load must not keep ticking\n    this.cancelRealTimeFallback(); // Added: a pending backstop must not fire into a destroyed table\n    this.realTimeSubs.forEach(s => s.unsubscribe());\n    this.offlineSubs.forEach(s => s.unsubscribe()); // Changed: TinSync subscriptions cleaned up\n    this.subs.forEach(s => s.unsubscribe()); // Changed: TS-8 release breakpoint + reload subscriptions\n  }\n\n  // Changed: TS-9 — reuse the MatTableDataSource (assign .data) instead of constructing a new one on every load.\n  // A new datasource tore down and rebuilt every row view (N table-row + action + menu components) and lost\n  // paginator/filter state; reuse lets Angular diff rows (with trackBy below) and keeps state across refresh.\n  private setTableData(rows: any[]) {\n    if (!this.tableDataSource) {\n      this.tableDataSource = new MatTableDataSource<any>(rows ?? []);\n    } else {\n      this.tableDataSource.data = rows ?? [];\n    }\n    this.setPaginator();\n  }\n\n  private rowIdKey: string | null = null; // TS-9 cached entity id key for trackBy (computed once from the first row)\n  trackByRow = (index: number, row: any): any => {\n    if (this.rowIdKey === null && row) this.rowIdKey = this.findIdKey(row);\n    return this.rowIdKey && row ? row[this.rowIdKey] : index;\n  }\n}\n","\n<ng-container *ngIf=\"hasFormAccess && !sectionHidden\"> <!-- Changed: sectionConfig.hideWhenEmpty hides the whole table -->\n\n  <!-- Added: collapsible flat section header (sectionConfig) — 1px border, no elevation, whole row toggles -->\n  <div class=\"tbl-section-header tin-disc-row\" *ngIf=\"config.sectionConfig\" (click)=\"toggleSection()\" [attr.aria-expanded]=\"!sectionCollapsed\" [class.tbl-section-static]=\"config.sectionConfig.collapsible === false\" role=\"button\" tabindex=\"0\" (keydown.enter)=\"toggleSection()\">\n    <!-- Changed (2026-08-17): the expand affordance moves to the LEFT, where the eye starts. It used to be a\n         single small chevron at the far right edge, and a shut section therefore read as flat text with nothing\n         inviting anyone to open it. Same marker, same place, on every folding band in the library — see\n         tin-styles.css \".tin-disc\". A section that cannot collapse shows no marker, exactly as it showed no\n         chevron before. -->\n    <span class=\"tin-disc\" *ngIf=\"config.sectionConfig.collapsible !== false\" [class.open]=\"!sectionCollapsed\"><mat-icon>chevron_right</mat-icon></span>\n    <mat-icon class=\"tbl-section-icon\" *ngIf=\"config.sectionConfig.icon\">{{ config.sectionConfig.icon }}</mat-icon>\n    <span class=\"tbl-section-title\">{{ config.sectionConfig.title }}</span>\n    <span class=\"tbl-section-count\" *ngIf=\"config.sectionConfig.showCount !== false\">{{ dataSource?.length || 0 }}</span>\n    <span class=\"tbl-section-chip\" *ngFor=\"let chip of sectionChips()\" [style.color]=\"chip.color\">{{ chip.text }}</span>\n    <span class=\"tbl-section-spacer\"></span>\n    <!-- Changed: the label is wrapped so a NARROW screen can drop it and leave an icon-only button. Only a\n         button that HAS an icon loses its text — otherwise it would collapse to a blank square. -->\n    <button mat-stroked-button color=\"primary\" *ngFor=\"let btn of sectionButtons()\" (click)=\"sectionButtonClicked(btn, $event)\" [matTooltip]=\"btn.display || btn.name\"><mat-icon *ngIf=\"btn.icon?.name\">{{ btn.icon.name }}</mat-icon><span class=\"tbl-section-btn-text\" [class.has-icon]=\"!!btn.icon?.name\">{{ btn.display || btn.name }}</span></button>\n<!-- Changed (2026-08-17): the trailing chevron is gone — it is now the leading .tin-disc marker above. Two\n         chevrons saying the same thing at both ends of the row is noise, and the right-hand one was the one\n         nobody looked at. -->\n  </div>\n\n  <!-- Added: the section's \"why this list exists\" line. It sits UNDER the title (a reason only makes sense once\n       the list has been named) and only while the section is open — a shut section already has its own summary\n       line, and a paragraph over the top of that is noise. -->\n  <p class=\"tbl-section-caption\" *ngIf=\"config.sectionConfig?.caption && !sectionCollapsed\">{{ config.sectionConfig.caption }}</p>\n\n  <!-- Added (delivered-order-lines-ui-gate): the TABLE's own caption, same element and same class as the section\n       caption above, for a table that has no section header to hang one on. It carries the reason a list is\n       read-only where the buttons that are now hidden used to be — hiding them silently leaves the user with no\n       guidance at all. Deliberately a quiet 12.5px line, NOT a bordered/iconed notice bar: the unconditional\n       read-only annotation bar was removed from every table dialog on 2026-08-19 for being noise, and this must\n       not read as its return. -->\n  <p class=\"tbl-section-caption\" *ngIf=\"captionText && !sectionCollapsed\">{{ captionText }}</p>\n\n  <!-- Added: collapsed section affordance — mirrors the Day Book \"Show the N\" pattern -->\n  <div class=\"tbl-section-more\" *ngIf=\"config.sectionConfig && sectionCollapsed && (dataSource?.length || 0) > 0\">\n    <button type=\"button\" class=\"tbl-section-link\" (click)=\"toggleSection()\">Show the {{ dataSource.length }}</button>\n  </div>\n\n  <ng-container *ngIf=\"!config.sectionConfig || !sectionCollapsed\"> <!-- Added: section collapse hides the table body -->\n\n  <!-- Search -->\n  <spa-search\n    *ngIf=\"config.searchConfig\" [config]=\"config.searchConfig\" [smallScreen]=\"smallScreen\" [tableDataSource]=\"tableDataSource\" style=\"margin-bottom: 20px;\" (searchClick)=\"searchClicked($event)\">\n  </spa-search>\n\n  <!-- Header -->\n  <!-- Changed: [isRealTime] binds the RESOLVED value, not the raw config. It was `config.realTime`, so the live\n       indicator only ever appeared on a table that set the flag ITSELF — a table relying on the app-wide\n       `tableDefaults.realTime` was genuinely subscribed to SignalR (setupRealTimeSubscriptions and\n       realTimeRefreshOrFallback both resolve through effRealTime) and simply never showed the dot. That is\n       how \"Trips and Loads have no real time\" got reported: a status light disagreeing with the system it\n       reports on. effRealTime also gets the inverse right — realTime:true under a global false still lights,\n       and realTime:false under a global true stays dark. -->\n  <app-table-header\n    [config]=\"config\" [data]=\"dataSource\" [tableDataSource]=\"tableDataSource\" [tileConfig]=\"config.tileConfig\" [tileData]=\"tileData\" [tileReload]=\"tileReload\" [lastSearch]=\"lastSearch\" [smallScreen]=\"smallScreen\"\n    [showFilterButton]=\"showFilterButton\" [isRealTime]=\"effRealTime\" [isConnected]=\"isSignalRConnected\" [refreshing]=\"loadingStage === 'refresh'\"\n    (createClick)=\"newModel()\" (customClick)=\"customModel($event,null)\"\n    (refreshClick)=\"refreshClicked()\" (tileClick)=\"tileClicked($event)\" (tileUnClick)=\"tileUnClicked($event)\" (chipClick)=\"chipClicked($event)\" (filterChange)=\"filterChanged($event)\">\n  </app-table-header>\n\n  <!-- Added (Quiet Loading D4): refresh with data already on screen — a 2px line flush under the header and the\n       spinning refresh icon are the ONLY signals. Rows stay live, clickable and un-dimmed while they swap. -->\n  <div *ngIf=\"loadingStage === 'refresh'\" class=\"tin-load-line\" aria-hidden=\"true\">\n    <span class=\"tin-load-line-fill\" [style.width.%]=\"progressPercent\"></span>\n  </div>\n\n  <!-- Added: paged-mode filter hint — the client filter only covers rows loaded so far.\n       Changed: the condition moved into filterScopePartial so this banner and the empty-state message below\n       read the SAME predicate. Stated independently they drifted: this banner said \"only the 20 loaded rows\n       of 240\" while the message underneath offered \"all 240 rows\". This banner owns SCOPE (what was searched)\n       and the remedy; the message below owns the RESULT; the paginator owns the COUNT. One fact each. -->\n  <div *ngIf=\"filterScopePartial\" class=\"paged-filter-hint\">\n    <mat-icon>info</mat-icon>\n    <span>Filtering only the {{loadedRows.length}} loaded rows of {{serverTotal}}. {{ config.searchConfig ? 'Use Search for complete results.' : 'Refine with search for complete results.' }}</span>\n  </div>\n\n\n  <!-- Table -->\n  <div *ngIf=\"!config.viewType || config?.viewType === 'table'\">\n\n    <p *ngIf=\"!config\"><em>Configure Table</em></p>\n    <p *ngIf=\"!dataSource && !loadingStage && !loadFailed\"><em>Loading...</em></p> <!-- Changed (Quiet Loading): the bare text is replaced by the stage below while a quiet load is on screen --><!-- Changed: ...and a FAILED load is not a running one — without the loadFailed guard this line sat there forever once the error dialog was dismissed -->\n\n    <!-- Added (Quiet Loading D3): first load, nothing on screen yet. The progress module is the hero (eased bar +\n         counting percentage + caption) and the ghost rows hold the exact space the real rows will fill, so the\n         table does not jump when data lands. Only ever rendered when quiet loading is on. -->\n    <div *ngIf=\"loadingStage === 'initial'\" class=\"tin-load-stage\" role=\"status\" aria-busy=\"true\">\n\n      <div class=\"tin-load-progress\">\n        <div class=\"tin-load-bar\">\n          <span class=\"tin-load-bar-fill\" [style.width.%]=\"progressPercent\"></span>\n        </div>\n        <span class=\"tin-load-percent\" aria-hidden=\"true\">{{progressDisplay}}%</span>\n      </div>\n\n      <div class=\"tin-load-caption\">Loading {{stageEntityName}}…</div>\n\n      <div class=\"tin-load-ghosts\">\n        <div class=\"tin-load-ghost-row\" *ngFor=\"let r of ghostRows\">\n          <div class=\"tin-load-ghost-cell\" *ngFor=\"let c of ghostColumns; let i = index\">\n            <span class=\"tin-skel\" [style.width.%]=\"ghostWidth(i, c)\" [style.animation-delay.ms]=\"r * 120\"></span> <!-- staggered sweep: each row starts 120ms after the one above -->\n          </div>\n        </div>\n      </div>\n\n    </div>\n\n    <div *ngIf=\"dataSource && loadingStage !== 'initial' && (!smallScreen || (smallScreen && dataSource?.length > 0))\" [class.tin-load-in]=\"effQuietLoading\"> <!-- Changed (Quiet Loading): the empty header-only table is suppressed while the initial stage stands in for it, and the real rows fade in where the ghosts were (D3) -->\n\n      <!-- Changed: the row region becomes a CDK drop list ONLY when config.orderable is declared. cdkDropListDisabled\n           is bound to the same single reason string the grip's tooltip reads, so a greyed grip and a dead drop\n           list can never disagree. A table without `orderable` has orderableConfig === null: no drop list, no\n           drag directives, no handle column — nothing at all. -->\n      <table mat-table [dataSource]=\"tableDataSource\" [trackBy]=\"trackByRow\" [ngClass]=\"elevation\" [class.tin-no-col-headers]=\"config.hideColumnHeaders\"\n        cdkDropList [cdkDropListDisabled]=\"!orderEnabled\" (cdkDropListDropped)=\"onRowDrop($event)\" [class.tin-orderable]=\"!!orderableConfig\"> <!-- Changed: optional column-header suppression -->\n\n        <!-- Added: the drag grip. Its column is pushed onto displayedColumns by setupOrderable(), so it exists\n             only for an orderable table. -->\n        <ng-container matColumnDef=\"orderHandle\">\n          <th mat-header-cell *matHeaderCellDef class=\"tin-grip-cell\"></th>\n          <td mat-cell *matCellDef=\"let row\" class=\"tin-grip-cell\">\n            <!-- handle: true restricts dragging to the grip itself (cdkDragHandle); absent/false leaves the whole\n                 row as the drag target, which is the documented default. Two branches because cdkDragHandle is a\n                 structural directive presence, not a bindable boolean. -->\n            <mat-icon *ngIf=\"orderableConfig?.handle; else plainGrip\" cdkDragHandle class=\"tin-grip\" [class.tin-grip-disabled]=\"!orderEnabled\"\n              [matTooltip]=\"orderDisabledReason ?? 'Drag to reorder'\" matTooltipPosition=\"above\">drag_indicator</mat-icon>\n            <ng-template #plainGrip>\n              <mat-icon class=\"tin-grip\" [class.tin-grip-disabled]=\"!orderEnabled\"\n                [matTooltip]=\"orderDisabledReason ?? 'Drag to reorder'\" matTooltipPosition=\"above\">drag_indicator</mat-icon>\n            </ng-template>\n          </td>\n        </ng-container>\n\n\n        <ng-container *ngFor=\"let column of config.columns\" [matColumnDef]=\"column.name\">\n          <th mat-header-cell *matHeaderCellDef >{{ column.alias ?? column.name | camelToWords }}</th>\n          <td mat-cell *matCellDef=\"let row;\" class=\"right-padding\" >\n\n            <!-- Added: inline edit — editable cells swap to their form-field editor while the row is in edit mode -->\n            <app-inline-cell *ngIf=\"isRowEditing(row) && getInlineField(column); else displayCell\" [field]=\"getInlineField(column)\" [data]=\"editingModel\"></app-inline-cell>\n\n            <!-- Rows -->\n            <ng-template #displayCell>\n              <app-table-row [column]=\"column\" [row]=\"row\" [config]=\"config\" [smallScreen]=\"smallScreen\"\n                (actionClick)=\"actionClicked(column.name, row)\" (columnClick)=\"columnClicked($event.column, $event.row)\" (showBannerEvent)=\"showBanner($event)\"> <!-- Changed: take the column and row the CELL emitted instead of re-reading the template's own. Identical for every existing type — the cell emits the very objects it was passed — but a 'chips' cell emits the CLICKED ITEM's pseudo-row, and the old binding silently discarded it and opened the row instead. That is the exact failure this codebase has already been bitten by: a drill-in that renders the record you clicked FROM. spa-cards (:230) has always bound it this way. -->\n              </app-table-row>\n            </ng-template>\n\n          </td>\n        </ng-container>\n\n        <ng-container matColumnDef=\"action\">\n          <th mat-header-cell *matHeaderCellDef> Action </th>\n          <td mat-cell *matCellDef=\"let row\" [ngStyle]=\"{width:false ? '20px' : actionsWidth}\">\n            <div class=\"action-buttons-container\">\n\n              <!-- Added: inline edit — while a row edits in place, its actions collapse to submit/cancel -->\n              <ng-container *ngIf=\"isRowEditing(row); else rowActions\">\n                <button mat-icon-button matTooltip=\"Save\" matTooltipPosition=\"above\" (click)=\"submitInlineEdit()\"><mat-icon class=\"inline-save\">check</mat-icon></button> <!-- Changed: dropped color=\"primary\" — the icon now carries a green save cue -->\n                <button mat-icon-button matTooltip=\"Cancel\" matTooltipPosition=\"above\" (click)=\"cancelInlineEdit()\"><mat-icon class=\"inline-cancel\">close</mat-icon></button> <!-- Changed: red cancel cue -->\n              </ng-container>\n\n              <!-- Actions -->\n              <ng-template #rowActions>\n                <app-table-action\n                  [displayedButtons]=\"displayedButtons\" [config]=\"config\" [smallScreen]=\"smallScreen\" [row]=\"row\" (actionClick)=\"actionClicked($event.name, $event.row, undefined, $event.button)\"> <!-- Changed: pass the Button the row rendered. actionClicked has always taken this optional 4th argument (the group-header binding at :245 already supplies it); the row binding did not, so a name collision between a table's own button and an injected framework one resolved to the framework's — shift's Trips row ran the approvals 'approve'/'cancel' and posted api/null/approve. `undefined` for group keeps every group-only branch inside actionClicked switched off exactly as before. -->\n                </app-table-action>\n              </ng-template>\n\n            </div>\n          </td>\n        </ng-container>\n\n\n        <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n        <!-- Changed: TWO row definitions, selected by the `when` predicate, so `cdkDrag` is attached ONLY to an\n             orderable table's rows. A single row def with [cdkDragDisabled] was measured to still instantiate a\n             CDK DragRef — and stamp .cdk-drag — on EVERY row of EVERY grid in the estate, which is a real cost\n             and makes \"a non-orderable table renders zero drag affordances\" untrue at the DOM level. This is the\n             standard mat-table multi-rowDef idiom; the predicate reads config, not row data, so it is constant\n             per table. The draggable def MUST come first — mat-table takes the first def whose `when` matches,\n             and the default (no `when`) is the fallback. -->\n        <tr mat-row *matRowDef=\"let row; columns: displayedColumns; when: rowsAreOrderable\" [ngClass]=\"{'make-gray': (config.greyOut && config.greyOut(row)) || row.pendingApproval, 'row-editing': isRowEditing(row)}\"\n          cdkDrag [cdkDragData]=\"row\" [cdkDragDisabled]=\"!orderEnabled\" cdkDragPreviewContainer=\"parent\" cdkDragLockAxis=\"y\"> <!-- cdkDragPreviewContainer=\"parent\" keeps the cloned <tr>'s real column widths; a body-level preview collapses to zero-width cells -->\n          <div class=\"tin-drag-placeholder\" *cdkDragPlaceholder></div>\n        </tr>\n        <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" [ngClass]=\"{'make-gray': (config.greyOut && config.greyOut(row)) || row.pendingApproval, 'row-editing': isRowEditing(row)}\"></tr> <!-- Changed: row-editing flags the row that is open for inline edit -->\n      </table>\n\n    </div>\n\n    <!-- Changed: Removed *ngIf condition to keep paginator always in DOM and maintain ViewChild reference -->\n    <!-- Changed: Added CSS class binding to hide when no data instead of conditional rendering -->\n    <!-- Changed: Legacy paginator only renders in non-paged mode (pagedMode is constant per instance, set before first render) -->\n    <!-- Changed: hidePageSize on a phone. The \"Items per page\" label and its select cost a whole row of a\n         narrow screen for a control almost nobody touches there — the default is what gets used. The range\n         (\"1 – 10 of 54\") and the arrows stay, which is the part that is actually navigated. Bound to\n         smallScreen, the component's existing breakpoint (max-width 600px, live via BreakpointObserver), so\n         the paginator agrees with how this table already decides what \"mobile\" means rather than\n         introducing a third breakpoint. -->\n    <mat-paginator *ngIf=\"!pagedMode\"\n      #tablePaginator\n      [pageSizeOptions]=\"config.pageSizes ?? [10, 20, 50]\"\n      [hidePageSize]=\"smallScreen\"\n      [ngClass]=\"{'paginator-hidden': !dataSource || (smallScreen && dataSource?.length === 0) || loadingStage === 'initial' || singlePagePaginatorHidden}\"\n      showFirstLastButtons>\n    </mat-paginator>\n\n    <!-- Added: manual paginator for server-side paged mode — fully state-bound, never attached to MatTableDataSource. Always visible: when filtering it pages the in-memory filtered subset (length = filtered count); otherwise the server window (length = true total). No first/last jump (would force fetching the whole gap). -->\n    <mat-paginator *ngIf=\"pagedMode\"\n      [length]=\"filterActive ? filteredRows.length : serverTotal + overlayDelta\"\n      [pageIndex]=\"pageIndex\"\n      [pageSize]=\"pageSize\"\n      [pageSizeOptions]=\"config.pageSizes ?? [10, 20, 50]\"\n      [hidePageSize]=\"smallScreen\"\n      [ngClass]=\"{'paginator-hidden': !dataSource || (smallScreen && dataSource?.length === 0) || loadingStage === 'initial' || singlePagePaginatorHidden}\"\n      (page)=\"onServerPage($event)\">\n    </mat-paginator>\n\n  </div>\n  \n  <!-- Added (Quiet Loading): the initial-load stage for the NON-table views.\n       Without this, card/capsule/grouped showed literally nothing during a first load — the view component\n       renders an empty dataSource and the \"No Data\" line is suppressed while the stage owns the space.\n       The progress header is identical to the table's so the two feel like one feature; only the ghost\n       furniture differs, because column-shaped rows are wrong in a card grid. -->\n  <div *ngIf=\"loadingStage === 'initial' && config?.viewType && config?.viewType !== 'table'\" class=\"tin-load-stage\" role=\"status\" aria-busy=\"true\">\n    <div class=\"tin-load-progress\">\n      <div class=\"tin-load-bar\">\n        <span class=\"tin-load-bar-fill\" [style.width.%]=\"progressPercent\"></span>\n      </div>\n      <span class=\"tin-load-percent\" aria-hidden=\"true\">{{progressDisplay}}%</span>\n    </div>\n    <div class=\"tin-load-caption\">Loading {{stageEntityName}}…</div>\n\n    <div *ngIf=\"config?.viewType === 'capsule'\" class=\"tin-load-ghost-capsules\" aria-hidden=\"true\">\n      <span class=\"tin-skel tin-load-ghost-capsule\" *ngFor=\"let c of ghostCapsules\"></span>\n    </div>\n\n    <div *ngIf=\"config?.viewType === 'card'\" class=\"tin-load-ghost-cards\" aria-hidden=\"true\">\n      <div class=\"tin-load-ghost-card\" *ngFor=\"let c of ghostCards\">\n        <span class=\"tin-skel tin-skel-text tin-load-ghost-card-title\"></span>\n        <span class=\"tin-skel tin-skel-text\"></span>\n        <span class=\"tin-skel tin-skel-text tin-load-ghost-card-short\"></span>\n      </div>\n    </div>\n\n    <div *ngIf=\"config?.viewType === 'grouped'\" class=\"tin-load-ghost-groups\" aria-hidden=\"true\">\n      <div class=\"tin-load-ghost-group\" *ngFor=\"let g of ghostGroups\">\n        <span class=\"tin-skel tin-load-ghost-group-head\"></span>\n        <!-- Pills, not rows: a group card's body is a wrap of chips, so full-width bars promised a table\n             and the stage did not resemble what replaced it. -->\n        <div class=\"tin-load-ghost-group-items\">\n          <span class=\"tin-skel tin-load-ghost-capsule\" *ngFor=\"let r of ghostCards\"></span>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Capsules -->\n  <spa-capsules *ngIf=\"config?.viewType === 'capsule' && loadingStage !== 'initial'\"\n    [config]=\"config\"\n    [dataSource]=\"dataSource\"\n    [displayedButtons]=\"displayedButtons\"\n    (actionClick)=\"actionClicked($event.name, $event.row, undefined, $event.button)\"> <!-- Changed: pass the Button spa-capsules rendered into actionClicked's long-existing optional 4th argument, exactly as the row binding at :131 and the group-header binding at :245 do. Without it a colliding table in capsule view still resolved by name and ran the framework's approve/cancel. \"undefined\" for group is load-bearing — it keeps every group-only branch inside actionClicked switched off exactly as before. -->\n  </spa-capsules>\n\n\n  <!-- Cards -->\n  <!-- Changed: the (actionClick) binding below passes the Button spa-cards rendered into actionClicked's long-existing optional 4th argument, exactly as the row binding at :131 and the group-header binding at :245 do. Without it a colliding table in card view resolved by name and ran the framework's approve/cancel. \"undefined\" for group is load-bearing — it keeps every group-only branch inside actionClicked switched off exactly as before. -->\n  <spa-cards *ngIf=\"config?.viewType === 'card' && loadingStage !== 'initial'\"\n    [config]=\"config\"\n    [dataSource]=\"dataSource\"\n    [displayedButtons]=\"displayedButtons\"\n    [smallScreen]=\"smallScreen\"\n    (actionClick)=\"actionClicked($event.name, $event.row, undefined, $event.button)\"\n    (columnClick)=\"columnClicked($event.column, $event.row)\"\n    (showBannerEvent)=\"showBanner($event)\">\n  </spa-cards>\n\n  <!-- Groups - Added: New grouped view type -->\n  <!-- Changed: the grouped view no longer renders its own filter field. It used to sit on a row of its own\n       beneath the buttons row, which left both rows half empty and, more importantly, was a SECOND filter with\n       no refresh button. The standard header filter (which has refresh, like every other table) now drives it,\n       with its text relayed in through filterText. -->\n  <spa-groups *ngIf=\"config?.viewType === 'grouped' && loadingStage !== 'initial'\"\n    [config]=\"config\"\n    [dataSource]=\"dataSource\"\n    [displayedButtons]=\"displayedButtons\"\n    [showOwnFilter]=\"false\"\n    [filterText]=\"groupFilterText\"\n    (actionClick)=\"actionClicked($event.name, $event.row, $event.group, $event.button)\">\n  </spa-groups>\n\n\n  <div class=\"tin-center\">\n    <p *ngIf=\"dataSource?.length == 0 && loadingStage !== 'initial' && !loadFailed\"><em>{{config.noDataMessage ?? 'No Data'}}</em></p> <!-- Changed (Quiet Loading): the stage owns the space until it completes, then hands straight over to this message — no \"No Data\" flashing underneath the ghost rows --><!-- Changed: ...and NOT when the load failed. A failed read leaves dataSource as an empty array, so this line confidently reported \"No Data\" — an assertion about the data — when the truth was that we never got any. That state now has its own sentence below. -->\n\n    <!-- Added: the load-failed state. \"There is nothing here\" and \"we could not find out\" are different facts and\n         this grid stated the first for both. Gated on having no rows, so a failed REFRESH leaves the rows already\n         on screen alone — the error dialog covers that case and an empty state under live rows would be a lie. -->\n    <div *ngIf=\"!(dataSource?.length > 0) && !loadingStage && loadFailed\" class=\"tin-filter-empty\" role=\"status\">\n      <p class=\"tin-filter-empty-title\"><em>Couldn’t load {{stageEntityName}}</em></p>\n      <p class=\"tin-filter-empty-hint\">Check your connection, then use the refresh button to try again.</p>\n    </div>\n\n    <!-- Added: the OTHER empty state. The line above means \"there is nothing here yet\"; this one means \"nothing\n         matches what you typed\", and until now it rendered nothing at all — a header, a \"0 of 0\" paginator and\n         no reason. filteredToNothing is false whenever dataSource is empty, so the two can never both show and\n         the line above is reached on exactly the rows it always was. role=\"status\" announces the change to a\n         screen reader, which otherwise gets silence when the rows disappear. -->\n    <!-- Changed: ONE message became TWO, because \"no matches\" means two different things and only one of them\n         was ever true. In paged mode the client filter runs over the loaded WINDOW and issues no fetch, so with\n         a partial window \"No matches for X\" overstates what was searched and \"see all 240 rows\" implies the\n         filter covered 240 when it covered 20 — while the banner at the top of the grid was simultaneously\n         saying so. The split is driven by filterScopePartial, the same getter that banner binds to, so the two\n         cannot contradict each other. Neither variant restates a COUNT the paginator or the banner already owns. -->\n\n    <!-- COMPLETE scope: the filter saw every row there is (any unpaged grid, or a paged one holding the full\n         set — search/POST mode and the no-total degrade both land here). The total is honest, so it is offered. -->\n    <div *ngIf=\"filteredToNothing && !filterScopePartial\" class=\"tin-filter-empty\" role=\"status\">\n      <p class=\"tin-filter-empty-title\"><em>{{filterEmptyTitle}}</em></p>\n      <p class=\"tin-filter-empty-hint\">Clear the filter to see all {{filteredTotal}} {{filteredRowNoun}}.</p>\n    </div>\n\n    <!-- PARTIAL scope: the filter saw only the rows loaded so far. The headline says exactly that, and the hint\n         stops at the way back — the banner above already carries both the counts and the \"use search\" remedy,\n         so repeating either here would be the contradiction this split exists to remove. -->\n    <div *ngIf=\"filteredToNothing && filterScopePartial\" class=\"tin-filter-empty\" role=\"status\">\n      <p class=\"tin-filter-empty-title\"><em>{{filterEmptyTitlePartial}}</em></p>\n      <p class=\"tin-filter-empty-hint\">Clear the filter to keep browsing.</p>\n    </div>\n  </div>\n\n  </ng-container> <!-- Added: end section-collapse wrapper -->\n\n</ng-container>\n\n\n<!-- Changed: \"Access Restricted\" named nothing and offered no next step, and as a bare centred italic <p> it read\n     as page furniture. A refusal is the one member of this file's empty-state family (:259 no rows, :264 couldn't\n     load, :283/:291 filtered to nothing) that was never given a title, a hint and role=\"status\". It is also the\n     only one that is NOT about data: it is decided at table.component.ts:65 from the config and the role, before\n     any request exists, which is why it can name the permission with certainty — and why it can never collide\n     with the \"no rows\" line, which lives inside the *ngIf=\"hasFormAccess\" container opened at :1.\n     The capability DISPLAY is what a user repeats to an administrator; the raw capN key stays in the log line. -->\n<ng-container *ngIf=\"!hasFormAccess\">\n  <div class=\"tin-center\">\n    <div class=\"tin-filter-empty\" role=\"status\">\n      <!-- Changed (Phase 4): both sentences now come from Core via the component, not from literals here. The\n           route tier (the no-access page) renders the same two strings from the same source, so the grid and the\n           page cannot drift apart. The empty-allow case still lands on the generic hint — Core.noAccessHint\n           returns it whenever there is no capability display to name. -->\n      <!-- Changed (Phase 4): tin-no-access-title added ALONGSIDE the shared empty-state class, which is kept so\n           the visual styling is untouched. The extra class exists because tin-filter-empty-title is shared with\n           \"Couldn't load\" (:265) and both filtered-to-nothing states (:284, :292) — so it cannot tell a REFUSAL\n           from an ordinary empty grid, and a test selecting on it would pass on the wrong state. It is the same\n           class the route-tier no-access page uses, so one selector reads a refusal at either tier and reads\n           nothing else. -->\n      <p class=\"tin-filter-empty-title tin-no-access-title\"><em>{{noAccessTitle}}</em></p>\n      <p class=\"tin-filter-empty-hint tin-no-access-hint\">{{noAccessHint}}</p>\n    </div>\n  </div>\n</ng-container>\n\n","import { Component, Input, NgZone, OnInit, QueryList, ViewChildren, inject } from '@angular/core'; // Changed: NgZone — the settle poll behind goTo() runs off the change-detection path\nimport { ApiResponse, Button, Column, DayBookButtonView, DayBookColumnView, DayBookConfig, DayBookLane, DayBookSection, DayBookStage, TableConfig, Tile, TileConfig } from '../../classes/Classes'; // Changed: Column + the two view types — the section resolution below selects page columns/buttons by name\nimport { Core } from '../../classes/TinCore';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service';\nimport { ButtonService } from '../../services/button.service';\nimport { TableComponent } from '../../components/table/table.component';\n\n// Added: the materialized view state for one section. Everything the template binds to lives here as a stable\n// reference — rows are rebuilt only on a real change (load, lane), never per change-detection cycle.\nexport interface DayBookSectionView {\n  section: DayBookSection;\n  cfg: TableConfig | null; // the section's cloned table config — a section IS a spa-table\n  all: any[];\n  rows: any[]; // what spa-table gets\n  // Added: the section card is now drawn from ONE template used from two places (flat, and inside a lane\n  // group), so it needs an outlet context — materialized once here for the same reason the rows are.\n  outletContext: { $implicit: DayBookSectionView } | null;\n  caption: string; // resolved once — a caption may be a function of the book (a tenant threshold, not a constant)\n  count: number;\n  limit: number;\n  collapsed: boolean;\n}\n\n// Added: the materialized view state for one LANE GROUP. The Day Book grew to 9-16 section cards and, on\n// 'Everything', all of them stacked in one column — the overcrowding the user reported. A group is not a new\n// concept: every section already declares the lane it belongs to, and the lane pills already name them. This\n// just renders that same lane as a collapsible stack instead of only as a filter. Everything on it is\n// materialized here for the same reason the row contexts are — the template must bind to stable values, never\n// to a getter that allocates on every change-detection pass.\nexport interface DayBookGroupView {\n  lane: DayBookLane;\n  sections: DayBookSectionView[];\n  count: number; // items across the group's visible sections — what a collapsed group still has to say\n  value: number; // the group's money: its own valueField, else the sum of its stages' values\n  chips: { key: string; label: string; count: number }[]; // one per non-empty list, so a collapsed group is still identifiable\n  collapsed: boolean;\n}\n\n// Added: spa-day-book — the centralized Day Book page. Replaces the per-app copy-forks (shift/grip/piglet):\n// the library owns the behaviour (lanes, stage tiles, section chrome, all-clear) and the app supplies only\n// appConfig.dayBookConfig (or [dayBookConfig]) + its own backend endpoint returning the flat book object.\n// Changed: there is now ONE rendering path — config. The app row/header template hatches are gone, and with\n// them the last way for a consumer to reproduce its old fork inside the library's chrome. Design decisions\n// carried in from the forks: zero-count tiles HIDE (not grey out), a stage click un-collapses its section\n// BEFORE scrolling (piglet's fix), and \"nothing outstanding\" derives from the configured stages so it can\n// never drift from the sections (grip's bug, killed by construction).\n@Component({\n    selector: 'spa-day-book',\n    templateUrl: './day-book.component.html',\n    styleUrls: ['./day-book.component.css'],\n    standalone: false\n})\nexport class DayBookComponent implements OnInit {\n  dataService = inject(DataServiceLib);\n  private messageService = inject(MessageService); // Added: page actions confirm and toast like every other button in the suite\n  private apiErrorService = inject(ApiErrorService);\n  private buttonService = inject(ButtonService);\n  private zone = inject(NgZone, { optional: true }); // Added: optional so a bare test harness instantiating this class directly still constructs\n\n  @ViewChildren(TableComponent) tables: QueryList<TableComponent>;\n\n  // Added: an app hosting <spa-day-book> in its own page can pass the config directly rather than parking it on\n  // appConfig — the library route still reads appConfig, so both entry points work.\n  @Input() dayBookConfig?: DayBookConfig;\n\n  book: any = null;\n  loading = false; // the re-entrancy guard — deliberately NOT bound in the template (see showLoading)\n  // Added (NG0100): what the template actually binds. `loading` flips inside load(), and load() can be reached\n  // from inside a change-detection pass (a host that re-enters the page, a child's lifecycle hook) — moving a\n  // BOUND flag there is exactly what ExpressionChangedAfterItHasBeenChecked reports. The bound copy therefore\n  // moves on the next microtask, after the pass that already read it has finished.\n  showLoading = false;\n  lane = 'all';\n  tileConfig: TileConfig | null = null;\n  tileData: any = null; // Added: book + resolved stage counts, a NEW object per build so spa-tiles sees a change\n  sectionConfigs: DayBookSectionView[] = [];\n  visibleSections: DayBookSectionView[] = []; // Changed: materialized (was an allocating getter feeding *ngFor)\n  visibleGroups: DayBookGroupView[] = []; // Added: the lane groups rendered on 'Everything' — materialized, same discipline\n  ungroupedSections: DayBookSectionView[] = []; // Added: sections that declare no lane — they stay above the groups, never hidden behind one\n  lanes: DayBookLane[] = []; // Changed: materialized (was a getter building a new array literal every cycle)\n  pageActions: Button[] = []; // Added: config-driven header buttons — materialized, never a getter feeding *ngFor\n\n  // Added: the operator's own expand/collapse choice per lane, remembered next to the remembered lane pill\n  private groupState: { [key: string]: boolean } = {};\n  grouped = false; // Added: materialized — grouping only ever applies on 'Everything', and only with two or more populated lanes\n\n  get config(): DayBookConfig | undefined {\n    return this.dayBookConfig || this.dataService.appConfig?.dayBookConfig; // Changed: input wins, appConfig is the fallback\n  }\n\n  get title(): string {\n    return this.config?.title || 'Day Book';\n  }\n\n  ngOnInit(): void {\n    const saved = localStorage.getItem('tin-daybook-lane');\n    if (saved) this.lane = saved;\n    // Added: the operator's expand/collapse choice per lane group, remembered under the library's own key next\n    // to the lane pill. A corrupt value must not take the page down with it, hence the catch.\n    try { this.groupState = JSON.parse(localStorage.getItem('tin-daybook-groups') || '{}') || {}; } catch { this.groupState = {}; }\n    this.buildActions(); // the header buttons exist before the first book does — Refresh must be there while it loads\n    this.load();\n  }\n\n  // Added (NG0100): the one place the bound loading flag moves, always one microtask behind the guard\n  private setShowLoading(value: boolean) {\n    if (this.showLoading === value) return;\n    Promise.resolve().then(() => this.showLoading = value);\n  }\n\n  load() {\n    if (!this.config?.loadAction || this.loading) return;\n    this.loading = true;\n    this.setShowLoading(true);\n    this.dataService.CallApi(this.config.loadAction).subscribe({\n      next: (response: ApiResponse) => {\n        this.loading = false;\n        this.setShowLoading(false);\n        if (!response.success) { this.apiErrorService.presentAppFailure(response, 'load', this.config.loadAction.url); return; } // Changed: was a bare `return`, the last unhandled failure in this file — runPageAction below was already converted. rebuild() never ran, so the lanes, the tiles and every section stayed at their previous values: a Day Book that quietly shows yesterday's book is worse than one that admits it could not load\n        this.book = response.data;\n        this.rebuild();\n      },\n      error: () => { this.loading = false; this.setShowLoading(false); }\n    });\n  }\n\n  // Added: public so an app that mutated the book in place (a row actioned without a refetch) can re-derive the\n  // tiles, the counts and the section rows without the page reshuffling under the operator's hand.\n  rebuild() {\n    this.buildLanes();\n    this.buildTiles();\n    this.buildSections();\n    this.buildActions(); // a page action may hide itself off a book fact, so it is re-resolved with everything else\n  }\n\n  //---------- Page actions ----------\n\n  // Added: the header buttons the [dayBookActions] slot used to carry. Content projection needs a consumer\n  // component to do the projecting, and a config-only Day Book has no component — so every app converted to\n  // pure config silently lost its Refresh. These come from config instead, and the ng-content slot is still\n  // there beside them for anyone who does host the page themselves.\n  private buildActions() {\n    // Changed: also honour the button's opt-in capability. Day Book actions carry NO formConfig, so nothing in\n    // the library could ever gate them — hasCapability is the only gate that reaches here. Buttons that name no\n    // capability are unaffected (hasCapability returns true); only isItemVisible ran before and it still runs.\n    this.pageActions = (this.config?.actions || []).filter(b => Core.isItemVisible(b, this.book) && this.buttonService.hasCapability(b));\n  }\n\n  pageActionClicked(button: Button) {\n    if (button.onClick) {\n      button.onClick(this.book, () => this.load()); // Changed: hand the handler a reload callback. A pure onClick used to be terminal, so an app running a multi-call job from a header button could only get the page honest again with window.location.reload(). load() already no-ops while a fetch is in flight, so calling it twice is safe, and a handler that ignores the argument behaves exactly as it did\n      if (!button.action) return; // a pure onClick button (a navigation, a dialog the app opens itself) is fully handled\n    }\n\n    // No endpoint and no handler IS the Refresh case — the only work a bare page button can mean is \"load it again\"\n    if (!button.action) { this.load(); return; }\n\n    if (button.confirm) {\n      this.messageService.confirm(this.buttonService.getConfirmMessage(button, this.book)).subscribe(result => {\n        if (result === 'yes') this.runPageAction(button);\n      });\n      return;\n    }\n    this.runPageAction(button);\n  }\n\n  private runPageAction(button: Button) {\n    this.dataService.CallApi(button.action, this.book).subscribe({\n      next: (response: ApiResponse) => {\n        if (!response.success) { this.apiErrorService.presentAppFailure(response, 'action', button.action.url); return; }\n        this.messageService.toast(button.action.successMessage || (response.message && response.message !== 'success' ? response.message : 'Updated'));\n        this.load(); // whatever it just did, the book it did it to is now stale\n      },\n      error: (error: any) => this.apiErrorService.present(error)\n    });\n  }\n\n  //---------- Lanes ----------\n\n  private buildLanes() {\n    const lanes = (this.config?.lanes || []).filter(l => Core.isItemVisible(l, this.book)); // Changed: a lane can hide itself off a book fact\n    this.lanes = lanes.length ? [{ key: 'all', label: 'Everything' }, ...lanes] : [];\n    if (this.lane !== 'all' && !lanes.some(l => l.key === this.lane)) this.lane = 'all'; // Added: a remembered lane that no longer exists must not blank the page\n  }\n\n  setLane(key: string) {\n    this.lane = key;\n    localStorage.setItem('tin-daybook-lane', key);\n    // Changed: the tile strip is now rebuilt on a lane change so spa-tiles receives a REAL input change.\n    // It previously relied on each tile's hidden predicate being re-evaluated by an ambient change-detection\n    // pass, which only happened because the section tables were churning their [data] binding every cycle.\n    this.buildTiles();\n    this.buildVisibleSections(); // Added: the lane filter changed — recompute the visible set once, here\n  }\n\n  inLane(lane?: string): boolean {\n    return this.lane === 'all' || !lane || lane === this.lane;\n  }\n\n  //---------- Stages ----------\n\n  // Added: countField may name either the count the backend adds (<key>Count) or the list itself. Taking\n  // .length off an array is what keeps the strip honest when an app edits a row list in place.\n  private stageCount(stage: DayBookStage): number {\n    const value = this.book?.[stage.countField];\n    return Array.isArray(value) ? value.length : (value || 0);\n  }\n\n  // Added: the one place a section's human name is resolved, so the chip, the card header and anything added\n  // later can never disagree. Explicit label → the table section's own title → the key humanised.\n  // Core.camelToWords is what the `camelToWords` pipe calls, so this matches the rest of the library exactly.\n  sectionLabel(section: DayBookSection): string {\n    return section.label || section.tableConfig?.sectionConfig?.title || Core.camelToWords(section.key);\n  }\n\n  // Added: the strip's money figure. valueField may name the total the backend added (<key>Value) or compute it\n  // off the book — Shift sums its own 'preparing'/'onTheRoad' rows and Grip its unallocated receipts, because\n  // neither payload carries a total for those lists and inventing one server-side would break payload parity.\n  private stageValue(stage: DayBookStage): number {\n    return this.resolveValue(stage.valueField);\n  }\n\n  // Changed: extracted from stageValue — a lane group shows money by exactly the same rules as a stage, so the\n  // resolution (named field on the book, or a function of the book) is written once and used by both.\n  private resolveValue(field?: string | ((book: any) => number)): number {\n    if (!field || !this.book) return 0;\n    if (typeof field === 'function') return field(this.book) || 0;\n    const value = this.book[field];\n    return typeof value === 'number' ? value : 0;\n  }\n\n  // Stages map onto spa-tiles: name = countField so the tile reads its count straight off the book object;\n  // zero-count tiles HIDE via the tile's own visibility predicate (design decision — no greyed-out tiles).\n  // Changed: the stage row is ALWAYS spa-tiles. The 'strip' alternative is gone — it existed only so the apps\n  // could keep their fork's stage row, and one page cannot have two stage rows and still be one page.\n  private buildTiles() {\n    const stages = (this.config?.stages || []).filter(s => Core.isItemVisible(s, this.book));\n\n    const tiles: Tile[] = stages.map(s => ({\n      name: s.countField, alias: s.label, style: 'icon', icon: s.icon || 'checklist', info: s.hint,\n      // Changed (owner ruling, 2026-08-12): the tile no longer carries a value badge. It used to render data[valueField] as a grey pill beside the count — a raw unformatted number with no currency symbol, which read as ambiguous (money? an account number?) and earned no space on this surface. The COUNT is the only tile property the Day Book shows now. valueField itself is untouched and still resolves the lane group header's money (resolveValue / laneStageValue) — this removes the RENDERING, not the data.\n      color: Core.isItemVisible({ visible: s.alert }, this.book) && s.alert !== undefined ? '#c62828' : undefined,\n      action: { method: 'get', url: '' }, // never fired — clickable tiles emit tileClick, which we map to a scroll\n      hidden: (d: any) => !d?.[s.countField] || !this.inLane(s.lane), // Changed: lane filter lives in the predicate so pill clicks re-filter tiles live\n      data: s.key // stage key travels on the tile so the click can find its section\n    } as any));\n    // Changed: the Day Book opts into the CAROUSEL (owner's instruction 2026-08-08). A book carries 9-16\n    // stages — more than any row can show — so one scrolling row beats either squeezing them or stacking\n    // them down the page above the lists. This is a Day Book decision made once in the library rather than\n    // repeated in five app configs; `stageTiles` still lets an app override it, including back to 'auto'.\n    // Changed: the hideValueOnMobile note goes with the badge. What it argued — the count is what the tile\n    // is FOR and the money is a second opinion — is now the rule at EVERY width, not just on a phone.\n    this.tileConfig = { tiles, clickable: true, layout: 'carousel', ...(this.config?.stageTiles ?? {}) } as TileConfig; // Changed: hideValueOnMobile dropped — it existed only to hide the money badge under 700px and there is no badge left to hide. Still a NEW object each build, so spa-tiles sees an input change\n    // Added: counts resolved onto a copy of the book, so a countField naming a LIST still shows a number\n    this.tileData = this.book ? { ...this.book, ...stages.reduce((a: any, s) => { a[s.countField] = this.stageCount(s); return a; }, {}) } : null;\n  }\n\n  onTileClick(event: any) {\n    const stage = (this.config?.stages || []).find(s => s.countField === event?.name);\n    if (stage) this.goTo(stage.key);\n  }\n\n  //---------- Sections ----------\n\n  // Clone the app's TableConfig per section rather than mutating the shared singleton (house rule).\n  // Changed: one path only — a section IS a spa-table, and spa-table owns its own collapse and paging.\n  private buildSections() {\n    this.sectionConfigs = (this.config?.sections || []).map(section => {\n      const all = this.book?.[section.listField] || [];\n\n      const view: DayBookSectionView = {\n        section, cfg: null,\n        all, rows: all, outletContext: null, count: all.length,\n        caption: typeof section.caption === 'function' ? section.caption(this.book) : (section.caption || ''),\n        limit: section.pageSize || this.config?.pageSize || 10,\n        // Changed (owner, 2026-08-08): sections start COLLAPSED by default — he opens the list he wants\n        // rather than scrolling past several opened ones. `collapsed: false` on a section still forces it open.\n        collapsed: section.collapsed !== false\n      };\n\n      if (section.tableConfig) {\n        const cfg: TableConfig = { ...section.tableConfig };\n        // Added (config injection): a section may now point at a PAGE's TableConfig instead of restating it. The\n        // four steps below are what make that safe; everything they do not touch — formConfig, each button's\n        // detailsConfig, capability, requiredAccess, security, visible/hidden/disabled/confirm, rowDataMap,\n        // onSuccessButton, inlineEdit — passes through BY REFERENCE, and that pass-through is the feature.\n        this.stripFetchingSurface(cfg);       // a Day Book section is fed by the book, never by its own request\n        this.stripSectionTiles(cfg);          // Added: tiles belong to the PAGE — a Day Book section is a snippet\n        this.stripSectionFilter(cfg);         // Added: the filter bar/button belongs to the PAGE too — and the seam had been RE-ENABLING it\n        this.stripHeaderActions(cfg);         // Added: import/upload/download act on the PAGE's dataset — never on a book snippet\n        this.stripRealTimeSurface(cfg);       // Added: SignalR/offline are PAGE behaviour — a broadcast is incoherent against a book projection\n        this.resolveColumns(cfg, section);    // onto a NEW array — never write into the page's\n        this.resolveButtons(cfg, section);    // ditto, and the delta can carry no behavioural key by type\n        if (section.overrides) Object.assign(cfg, section.overrides); // chrome-only escape hatch, applied before the Day Book's own defaults below\n        // Changed: reads cfg.sectionConfig rather than section.tableConfig.sectionConfig so that an overrides.sectionConfig wins. Identical for every section that declares no overrides.\n        cfg.sectionConfig = cfg.sectionConfig ? { ...cfg.sectionConfig, collapsed: section.collapsed !== false } : undefined;\n        cfg.elevation = cfg.elevation ?? 'none'; // flat tables on the section cards — Day Book design language\n        // Added (phone density): a Day Book stacks 9-16 of these cards, and on a phone each one was spending\n        // 56px on a pager that read \"1 – 4 of 4\" — the largest single item in the card, navigating nothing.\n        // The count it reports is already on the section header's own badge, so nothing is lost. This is a Day\n        // Book decision made ONCE in the library rather than repeated in five app configs, exactly as the\n        // carousel stage strip is; an app that wants its pagers back still sets the flag false on its own\n        // tableConfig. Desktop is untouched — the flag only ever acts below 600px.\n        cfg.hideSinglePagePaginator = cfg.hideSinglePagePaginator ?? true;\n        if (cfg.sectionConfig) {\n          cfg.sectionConfig.hideWhenEmpty = cfg.sectionConfig.hideWhenEmpty !== false; // sections disappear when empty by default\n          // Added: the section's \"why this list exists\" line rides INSIDE the table's own header, under the\n          // title. It used to be drawn only on the app-template path, so every app that converted to config\n          // lost it. An explicit sectionConfig.caption still wins — the section-level one is the default.\n          cfg.sectionConfig.caption = cfg.sectionConfig.caption || view.caption || undefined;\n        }\n        // Added: pageSize was previously only honoured by the app-template path's row limit. It now seeds the\n        // table's own paginator, so it still means what it says instead of becoming dead config.\n        if (!cfg.pageSizes && (section.pageSize || this.config?.pageSize)) cfg.pageSizes = [view.limit, ...[10, 20, 50].filter(n => n !== view.limit)];\n        view.cfg = cfg;\n      }\n\n      view.outletContext = { $implicit: view }; // built after the view exists, and never rebuilt in the template\n      return view;\n    });\n    this.buildVisibleSections();\n  }\n\n  // Added (config injection): a page's TableConfig ALWAYS carries a loadAction, and table.component.ts fires it\n  // on init. Injected verbatim, a Day Book section would fetch the entire page dataset and overwrite the book's\n  // rows — the section would silently stop being a Day Book section while still looking like one. The book's\n  // list is bound through [data], so the whole fetching surface goes. Written on the CLONE only.\n  private stripFetchingSurface(cfg: TableConfig) {\n    cfg.loadAction = undefined;\n    cfg.countAction = undefined;\n    cfg.searchConfig = undefined;\n    cfg.pagination = undefined;\n    cfg.lazyLoad = undefined;\n  }\n\n  // Added (owner rule, 2026-08-18): \"day book section tables should not have tiles\". A page's TableConfig may\n  // carry an overview tile row (invoices, assets, inventory stock in the library; equipment and rentals in\n  // grip) and injected verbatim that row would draw INSIDE a Day Book section card — a page's summary strip\n  // repeated under a section header, above four rows the book already summarised on the stage tiles and the\n  // section count badge. The Day Book presents snippets; tiles belong to the pages. It is also a second\n  // fetching surface: table.component.ts fires tileConfig.loadAction on every dataLoaded (line ~1175).\n  // The same strip already exists for the same reason on the create-tab path — dialog.service.ts:105 clears\n  // tileConfig beside loadAction/countAction/searchConfig/pagination. Written on the CLONE only.\n  private stripSectionTiles(cfg: TableConfig) {\n    cfg.tileConfig = undefined;\n  }\n\n  // Added (Arbiter ruling, 2026-08-18): the same \"snippets, not pages\" rule as the tile strip above, plus a live\n  // REGRESSION this seam itself introduced. A page config's filter bar is page chrome — inventory's\n  // productsTableConfig sets showFilter: true, so the converted Out of Stock section was drawing a page filter\n  // over four Day Book rows the book had already filtered. Worse: table.component.ts:189 defaults\n  // showFilterButton = true and only turns it off when the config carries a truthy searchConfig (:664) or sets\n  // showFilterButton === false (:667) — and stripFetchingSurface() above clears searchConfig, so a page that\n  // suppressed its filter button THAT way had it silently RE-ENABLED on injection. Hence explicit `false`, never\n  // undefined: undefined falls back to the component's own true. Written on the CLONE only, and BEFORE\n  // section.overrides is applied — a section that wants a filter on purpose can still put one back through\n  // overrides, exactly as with tiles. showFilter/showFilterButton stay in the DayBookTableView Pick<> for that.\n  private stripSectionFilter(cfg: TableConfig) {\n    cfg.showFilter = false;\n    cfg.showFilterButton = false;\n    cfg.holdFilterSpace = false;\n  }\n\n  // Added (Arbiter ruling, 2026-08-18): the THIRD instance of the tiles/filter family — page chrome the table\n  // HEADER draws that a Day Book section card must never show. table-header.component.html renders an icon per\n  // member: `download` (:46), `upload` (:50) and `import` (:54, the upload_file icon measured leaking onto grip's\n  // converted workshop card). All three act on the PAGE's ENTIRE dataset — download CSVs config.download.columns\n  // of the page, upload POSTs to config.upload.action, import opens the wizard against config.import.entity —\n  // while the card below them holds four rows the book selected. None of the three is a member of the\n  // DayBookTableView Pick<>, so an app CANNOT suppress them through overrides; the ruling was to strip in the\n  // library rather than widen the Pick, because the Pick is an escape hatch and \"the page has it, the book must\n  // never\" is settled as a strip. Written on the CLONE only.\n  // DELIBERATELY NOT STRIPPED, each read by this same header and each checked:\n  //   flatButtons / holdHeaderButtonSpace / collapseButtons — presentation only, and already in the Pick<>.\n  //   buttons — resolveButtons() below owns them; a page's `create`/`inHeader` button is a section's to select.\n  //   viewType === 'grouped' — showGroupedFilter (table-header.component.ts:166) draws a filter that\n  //     stripSectionFilter cannot reach, but suppressing it means editing the table's RENDERING MODE, not its\n  //     chrome. No injected section uses a grouped config today; left as a documented residual.\n  //   realTime / offline / entityName — RULED ON SEPARATELY and now stripped: see stripRealTimeSurface() below.\n  private stripHeaderActions(cfg: TableConfig) {\n    cfg.import = undefined;\n    cfg.upload = undefined;\n    cfg.download = undefined;\n  }\n\n  // Added (Arbiter ruling, 2026-08-18): the BEHAVIOURAL half of the same family — not chrome this time, so it\n  // gets its own strip and its own reasoning. A Day Book section's rows are a PROJECTION the server chose for\n  // the book: a curated subset, with book-only extraColumns, keyed off the book payload. Real-time broadcasts\n  // are entity-wide and carry no criteria, and they DO match an injected section — a donor page config sets\n  // `entityName`, and where it does not the table derives one — so the subscription is live, not inert:\n  //   entityCreated$  PREPENDS any new row of that entity into the card (table.component.ts:1821/1828), i.e.\n  //     into a curated subset the row has no business being in. The isEntityWideView() guard at :1816 does NOT\n  //     save us — it is gated on `offlineEntry`, so a non-offline table skips it entirely.\n  //   entityUpdated$  REPLACES the book's row wholesale with the page-shaped payload, blanking every\n  //     extraColumn the book computed (daysIdle, daysOverdue, …) because the page row has no such fields.\n  // `offline` is the same argument one layer down: it would enrol a projection's url in the offline read\n  // registry and PERSIST the fabricated membership. `entityName` goes with them so nothing re-derives a\n  // subscription downstream.\n  // 🔑 `realTime` is set to an explicit FALSE, never undefined — table.component.ts:262 resolves undefined\n  // through the app-wide runtimeConfig.tableDefaults, and all five apps set tableDefaults.realTime = true, so\n  // `undefined` would subscribe every Day Book card in the estate. `offline`/`entityName` have no such truthy\n  // default and are cleared to undefined. Applied to EVERY section config the book builds, injected or\n  // hand-written — the book's rows are a projection either way. Written on the CLONE only, and BEFORE\n  // section.overrides, so a section that genuinely wants a live card can still put one back.\n  private stripRealTimeSurface(cfg: TableConfig) {\n    cfg.realTime = false;\n    cfg.offline = undefined;\n    cfg.entityName = undefined;\n  }\n\n  // Added: select the section's columns BY NAME out of the injected config, in the order the section declares.\n  // A named column the injected config does not have is DROPPED, never invented — the page is the definition.\n  private resolveColumns(cfg: TableConfig, section: DayBookSection) {\n    if (!section.columns && !section.omitColumns && !section.extraColumns) return; // untouched sections keep the exact array they had\n    const source = cfg.columns || [];\n    let resolved: Column[] = section.columns\n      ? section.columns.map(c => this.applyColumnView(source, c)).filter((c): c is Column => !!c)\n      : [...source]; // Constraint 3: a COPY — filtering the page's own array would reshape the live page\n    if (section.omitColumns) resolved = resolved.filter(c => !section.omitColumns!.includes(c.name));\n    if (section.extraColumns) resolved = [...resolved, ...section.extraColumns]; // book-only fields the page has no reason to carry (daysIdle, daysOverdue)\n    cfg.columns = resolved;\n  }\n\n  // The page's Column, spread under a presentation-only delta. The delta's TYPE cannot carry `name`, so the\n  // column keeps the field it reads — a renamed column would read a field the row does not have.\n  private applyColumnView(source: Column[], view: string | DayBookColumnView): Column | null {\n    const name = typeof view === 'string' ? view : view.column;\n    const found = source.find(c => c.name === name);\n    if (!found) return null;\n    if (typeof view === 'string') return found; // no delta — pass the page's object straight through, by reference\n    const { column, ...presentation } = view;\n    return { ...found, ...presentation };\n  }\n\n  // Added: the same, for row buttons. `name` is inherited untouched — see DayBookPresentation in Classes.ts for\n  // why renaming one is a security change and not a label change.\n  private resolveButtons(cfg: TableConfig, section: DayBookSection) {\n    if (!section.buttons && !section.extraButtons) return;\n    const source = cfg.buttons || [];\n    let resolved: Button[] = section.buttons\n      ? section.buttons.map(b => this.applyButtonView(source, b)).filter((b): b is Button => !!b)\n      : [...source];\n    if (section.extraButtons) resolved = [...resolved, ...section.extraButtons];\n    cfg.buttons = resolved;\n  }\n\n  private applyButtonView(source: Button[], view: string | DayBookButtonView): Button | null {\n    const name = typeof view === 'string' ? view : view.button;\n    const found = source.find(b => b.name === name);\n    if (!found) return null;\n    if (typeof view === 'string') return found;\n    const { button, prefill, ...presentation } = view;\n    return { ...found, ...presentation, rowDataMap: prefill ?? found.rowDataMap }; // prefill re-aims the page's dialog at the book's row — context, never behaviour\n  }\n\n  // Changed: was a getter — now recomputed only when the book loads or the lane changes\n  private buildVisibleSections() {\n    this.visibleSections = this.sectionConfigs\n      .filter(x => this.inLane(x.section.lane))\n      .filter(x => Core.isItemVisible(x.section, this.book)) // Added: a section can hide itself off a book fact (a module the app switched off)\n      .filter(x => x.cfg?.sectionConfig?.hideWhenEmpty === false || x.rows.length > 0); // Changed: empty sections hide the whole card, not just the table (fork behaviour)\n    this.buildGroups(); // Added: the same visible set, stacked into collapsible lane groups on 'Everything'\n  }\n\n  //---------- Lane groups ----------\n\n  // Added: stack the visible sections into one collapsible group per lane. Grouping is a RENDERING of the lane\n  // each section already declares — not a new concept and not new per-app config — and it only applies on\n  // 'Everything', because picking a lane pill has already narrowed the page to one group. A book with fewer\n  // than two populated lanes is left flat: a single group wrapping everything is chrome that buys nothing.\n  private buildGroups() {\n    const lanes = this.lanes.filter(l => l.key !== 'all'); // 'all' is the pill, never a group\n    const groupable = this.config?.groupLanes !== false && this.lane === 'all' && lanes.length > 1;\n    // Changed (owner, 2026-08-08): EVERY group now starts collapsed — he opens the area he cares about\n    // rather than scrolling past an opened one. Was `?? 1` (first group open). An app that wants the old\n    // behaviour still sets `expandedGroups: 1`; `groupState` and a caller's previous state still win below,\n    // so a group the operator opened during the session does not slam shut on the next refresh.\n    const open = this.config?.expandedGroups ?? 0;\n\n    const groups = !groupable ? [] : lanes.map((lane, index) => {\n      const sections = this.visibleSections.filter(x => x.section.lane === lane.key);\n      const previous = this.visibleGroups.find(g => g.lane.key === lane.key);\n      return {\n        lane, sections,\n        count: sections.reduce((total, x) => total + x.count, 0),\n        // The group's money: its own valueField if it declares one, otherwise the sum of its stages' — which is\n        // the same figure the strip is already showing, so a collapsed group can never contradict the strip.\n        value: lane.valueField ? this.resolveValue(lane.valueField) : this.laneStageValue(lane.key),\n        // The 'small details' a collapsed group keeps: one chip per non-empty list. A group that reads\n        // 'Getting paid — 3 to issue, 7 overdue' is identifiable without opening it; a bare title is not.\n        // Changed (owner, 2026-08-08): a chip was falling back to the RAW CONFIG KEY, so a collapsed group\n        // read \"onTheRoad 3 · readyToInvoice 8\" — camelCase leaking into the UI. It now walks the same\n        // cascade the rest of the library uses: an explicit label wins, then the section header's own title\n        // (which every converted app already writes), and only then the key humanised via Core.camelToWords —\n        // the identical helper behind the `camelToWords` pipe the tiles use. So it reads properly with no\n        // config change anywhere, and an app that wants different wording still just sets label/title.\n        chips: sections.filter(x => x.count).map(x => ({ key: x.section.key, label: this.sectionLabel(x.section), count: x.count })),\n        collapsed: previous?.collapsed ?? this.groupState[lane.key] ?? (index >= open)\n      } as DayBookGroupView;\n    }).filter(g => g.sections.length); // a lane with nothing in it today is not worth a header\n\n    this.grouped = groups.length > 1;\n    this.visibleGroups = this.grouped ? groups : [];\n    // Sections with no lane never belong to a group — they sit above the groups so they can never be buried\n    // behind a collapsed header. With grouping off, this IS the whole page and the template renders it flat.\n    this.ungroupedSections = this.grouped ? this.visibleSections.filter(x => !x.section.lane) : this.visibleSections;\n  }\n\n  // Added: what a lane is worth — the sum of the values its own stages already resolve\n  private laneStageValue(lane: string): number {\n    return (this.config?.stages || [])\n      .filter(stage => stage.lane === lane && Core.isItemVisible(stage, this.book))\n      .reduce((total, stage) => total + this.stageValue(stage), 0);\n  }\n\n  // Added: expand/collapse a whole lane, remembered per lane for the next visit\n  toggleGroup(group: DayBookGroupView) {\n    group.collapsed = !group.collapsed;\n    this.groupState[group.lane.key] = group.collapsed;\n    localStorage.setItem('tin-daybook-groups', JSON.stringify(this.groupState));\n  }\n\n  // Un-collapse BEFORE scrolling (piglet's fix, applied suite-wide) — a click must never land on a bare header.\n  //\n  // Changed (owner, 2026-08-09): a chip scrolled to its section and left it SHUT, so the operator had to click\n  // again to see the list he had just asked for. There are THREE doors between a chip and its rows, not one:\n  //\n  //   chip  →  lane GROUP (.db-gbody is *ngIf=\"!g.collapsed\")  →  SECTION (spa-table's own sectionCollapsed)\n  //\n  // and the previous code only really cleared the third. It opened the group by flipping `group.collapsed`, then\n  // in the SAME synchronous tick asked `this.tables` for the section's table — but Angular had not re-rendered\n  // yet, so that table did not exist in the QueryList and the expand silently no-opped. Which is exactly the\n  // reported symptom, and it applied to every chip: chips are only rendered on a COLLAPSED group, so the broken\n  // path was the only path a chip could ever take.\n  //\n  // The fix does not race the renderer. Level 2 seeds the section's own cloned config, so a table that has not\n  // been created yet is BORN open (TableComponent.ngOnInit seeds sectionCollapsed off exactly this field), and\n  // only expands a live instance if there already is one. Nothing here has to guess when Angular will catch up.\n  goTo(key: string) {\n    const target = this.sectionConfigs.find(x => x.section.key === key);\n    if (target) {\n      // Level 1 — the lane group. Nothing inside a shut group is in the DOM at all.\n      const group = this.visibleGroups.find(g => g.lane.key === target.section.lane);\n      if (group?.collapsed) this.toggleGroup(group); // expand-only: an already-open group is left alone, and so is every OTHER group — this is not an accordion\n      // Level 2 — the section. Seeding the config covers the not-yet-created table; expandSection covers the live one.\n      if (target.cfg?.sectionConfig) target.cfg.sectionConfig.collapsed = false; // cfg is this section's own clone (buildSections), never the app's shared singleton\n      target.collapsed = false;\n      this.tables?.find(t => t.config === target.cfg)?.expandSection(); // expand, never toggle — a toggle would shut a section that was already open\n    }\n    // Level 3 — scroll, but only once the two expansions above have actually changed the layout.\n    this.scrollWhenSettled('sec-' + key);\n  }\n\n  // Added: the scroll has to be the LAST thing that happens, and a fixed delay cannot promise that. A section\n  // that is still collapsed when we scroll is ~110px of bare chrome: we land on that position, the section then\n  // expands to several hundred px and grows UNDER the viewport, and the operator ends up parked below the list\n  // he asked for — looking, from his side, exactly like the bug we are fixing. So instead of guessing a delay we\n  // watch the target until its height stops changing (the same measurement two frames running), which covers the\n  // group render, the table's own creation and the paginator re-attach without knowing anything about any of\n  // them. The frame cap stops a section whose height never settles (a live-updating list) from never scrolling.\n  // Runs outside Angular: this is a poll, and every frame of it would otherwise drag a change-detection pass\n  // behind it for no reason — the house rule about not putting work on the CD path applies to timers too.\n  private scrollWhenSettled(id: string) {\n    const smooth = !window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches; // a jump, not a glide, when the operator has asked for less motion\n    const run = () => {\n      let previous = -1;\n      let frames = 0;\n      const step = () => {\n        const element = document.getElementById(id);\n        const height = element ? element.getBoundingClientRect().height : -1;\n        if ((element && height === previous) || frames >= 20) {\n          element?.scrollIntoView({ behavior: smooth ? 'smooth' : 'auto', block: 'start' });\n          return;\n        }\n        previous = height;\n        frames++;\n        requestAnimationFrame(step);\n      };\n      requestAnimationFrame(step);\n    };\n    this.zone ? this.zone.runOutsideAngular(run) : run();\n  }\n\n  //---------- Header facts ----------\n\n  get booksFrom(): any {\n    return this.config?.booksFromField ? this.book?.[this.config.booksFromField] : null;\n  }\n\n  get owed(): number | null {\n    const field = this.config?.owedField;\n    if (!field || !this.book) return null;\n    if (typeof field === 'function') return field(this.book) || null; // Changed: owedField may compute the total off the book — Grip's is the sum of four lane totals nothing server-side adds up\n    return this.book[field] != null ? this.book[field] : null;\n  }\n\n  // Derived from the configured stages, NOT a hand-maintained list — cannot drift from the sections\n  get allClear(): boolean {\n    if (!this.book) return false;\n    const stages = (this.config?.stages || []).filter(s => this.inLane(s.lane)).filter(s => Core.isItemVisible(s, this.book));\n    return stages.length > 0 && stages.every(s => !this.stageCount(s));\n  }\n}\n","<div class=\"db-page\" *ngIf=\"config\">\n\n  <!-- Header. Changed (2026-08-17, owner: \"it just looks like text that was dumped\"): the four loose pieces of\n       text that sat above the lane pills are now ONE hero card, built to the pattern of the Getting Started\n       hero he named as the quality bar — identity on the left, the page's single most important number on the\n       right, set large. The pieces are unchanged; what changed is that they are composed and contained.\n       This is also what makes the page consistent with itself: the tiles below are cards and the lists are\n       cards, so a bare block of text at the top was the one thing on the page with no surface under it. -->\n  <mat-card class=\"db-hero\">\n    <div class=\"db-hero-main\">\n      <div class=\"db-head-text\">\n        <h1>{{ title }}</h1>\n        <p class=\"db-sub\" *ngIf=\"config.subtitle\">{{ config.subtitle }}</p>\n        <!-- the provenance line — small, iconed, and clearly subordinate to the title rather than a third\n             paragraph of the same weight -->\n        <span class=\"db-caption\" *ngIf=\"booksFrom\"><mat-icon>event</mat-icon>books from {{ booksFrom | date: 'mediumDate' }}</span>\n      </div>\n      <!-- The right-hand column of the hero: the controls sit above, the number below. Keeping them in one\n           column is what stops the card becoming three things competing for the same edge. -->\n      <div class=\"db-hero-side\">\n        <!-- The page's own actions (refresh, an escape hatch to a full screen). Changed: they now come from\n             config.actions, because an app with no component of its own has nothing to project with — the\n             ng-content slot stays beside them for anyone who does host the page themselves. -->\n        <!-- Changed: an action WITH an icon renders icon-only (owner, 2026-08-08 — \"the refresh and all trips\n             buttons can just be icons with no text\"). The label is not lost, it moves to the tooltip and to\n             aria-label, so the control still announces itself to a screen reader and on hover. An action with\n             no icon keeps its text button, because an unlabelled blank button would be unusable. -->\n        <div class=\"db-head-actions\">\n          <ng-container *ngFor=\"let a of pageActions\">\n            <button mat-icon-button color=\"primary\" type=\"button\" *ngIf=\"a.icon?.name; else textAction\" (click)=\"pageActionClicked(a)\" [matTooltip]=\"a.tip || a.display || a.name\" [attr.aria-label]=\"a.display || a.name\">\n              <mat-icon>{{ a.icon.name }}</mat-icon>\n            </button>\n            <ng-template #textAction>\n              <button mat-stroked-button color=\"primary\" type=\"button\" (click)=\"pageActionClicked(a)\" [title]=\"a.tip || ''\">{{ a.display || a.name }}</button>\n            </ng-template>\n          </ng-container>\n          <ng-content select=\"[dayBookActions]\"></ng-content>\n        </div>\n        <!-- The money, given the treatment the setup hero gives its percentage: a quiet label over a large\n             figure. It is the number the operator opens this page to see, and it was previously set at 13px in\n             the same grey as the caption beside it. -->\n        <div class=\"db-hero-metric\" *ngIf=\"owed !== null\">\n          <span class=\"db-metric-label\">Owed to us</span>\n          <span class=\"db-metric-value\">{{ owed | currency }}</span>\n        </div>\n      </div>\n    </div>\n  </mat-card>\n\n  <!-- Lane pills -->\n  <div class=\"db-lanes\" *ngIf=\"lanes.length\">\n    <button type=\"button\" class=\"db-lane\" *ngFor=\"let l of lanes\" [class.active]=\"lane === l.key\" (click)=\"setLane(l.key)\">\n      <mat-icon *ngIf=\"l.icon\">{{ l.icon }}</mat-icon>{{ l.label }}\n    </button>\n  </div>\n\n  <!-- Added: the library owns the loading state — first load only, a refresh keeps the page on screen.\n       Changed: binds showLoading, the copy that only ever moves between change-detection passes (NG0100) -->\n  <div class=\"db-loading\" *ngIf=\"showLoading && !book\">{{ config.loadingMessage || 'Loading…' }}</div>\n\n  <ng-container *ngIf=\"book\">\n\n    <!-- The stage row. Changed: always spa-tiles — zero-count tiles hide -->\n    <spa-tiles *ngIf=\"tileConfig\" [config]=\"tileConfig\" [data]=\"tileData\" (tileClick)=\"onTileClick($event)\"></spa-tiles>\n\n    <!-- All clear -->\n    <div class=\"db-clear\" *ngIf=\"allClear\">\n      <mat-icon>task_alt</mat-icon>\n      <span>{{ config.allClearMessage || 'Nothing outstanding — all caught up.' }}</span>\n    </div>\n\n    <!-- Sections. A book carries 9-16 of these cards and, on 'Everything', all of them used to stack in one\n         column — so they are grouped into one collapsible lane group each, with the first open and the rest\n         showing only their identity: label, count, money and a chip per list. Sections that declare no lane\n         sit above the groups, and with grouping off (one lane, a picked lane, or groupLanes:false) the page\n         renders exactly as it did before. -->\n    <ng-container *ngFor=\"let s of ungroupedSections\">\n      <ng-container *ngTemplateOutlet=\"sectionCard; context: s.outletContext\"></ng-container>\n    </ng-container>\n\n    <section class=\"db-group\" *ngFor=\"let g of visibleGroups\" [class.closed]=\"g.collapsed\">\n      <!-- Changed (2026-08-17): the disclosure marker leads the row instead of trailing it — the shared idiom\n           from tin-styles.css, the same one the Getting Started bands and every spa-table section now use. -->\n      <button type=\"button\" class=\"db-ghead tin-disc-row\" (click)=\"toggleGroup(g)\" [attr.aria-expanded]=\"!g.collapsed\">\n        <span class=\"tin-disc\" [class.open]=\"!g.collapsed\"><mat-icon>chevron_right</mat-icon></span>\n        <mat-icon *ngIf=\"g.lane.icon\">{{ g.lane.icon }}</mat-icon>\n        <span class=\"g-label\">{{ g.lane.label }}</span>\n        <span class=\"db-count\">{{ g.count }}</span>\n        <span class=\"g-value\" *ngIf=\"g.value\">{{ g.value | currency: undefined : 'symbol' : '1.0-0' }}</span>\n        <span class=\"g-lists\">{{ g.sections.length }} {{ g.sections.length === 1 ? 'list' : 'lists' }}</span>\n      </button>\n      <!-- Collapsed, the group still says what it is about — one chip per non-empty list, and a chip is a way\n           in: it opens the group and scrolls to that section, the same path a stage click takes. -->\n      <div class=\"db-chips\" *ngIf=\"g.collapsed\">\n        <button type=\"button\" class=\"db-chip\" *ngFor=\"let c of g.chips\" (click)=\"goTo(c.key)\">{{ c.label }}<span>{{ c.count }}</span></button>\n        <span class=\"db-chip-none\" *ngIf=\"!g.chips.length\">Nothing outstanding here</span>\n      </div>\n      <div class=\"db-gbody\" *ngIf=\"!g.collapsed\">\n        <ng-container *ngFor=\"let s of g.sections\">\n          <ng-container *ngTemplateOutlet=\"sectionCard; context: s.outletContext\"></ng-container>\n        </ng-container>\n      </div>\n    </section>\n\n    <!-- One section card, drawn from two places (flat above, and inside a lane group). Changed: ONE rendering\n         path — a section is a spa-table fed local rows off the book object. The table draws its own section\n         header (icon, title, count, chips, buttons, caption, chevron); (actionSuccess) reloads the book so a\n         row that has just been actioned leaves the list instead of sitting there looking undone — the section\n         has no loadAction of its own to refresh from. -->\n    <ng-template #sectionCard let-s>\n      <mat-card class=\"db-section\" [id]=\"'sec-' + s.section.key\" [class.alert]=\"s.section.tone === 'alert'\" [class.quiet]=\"s.section.tone === 'quiet'\">\n        <!-- the \"why this list exists\" line rides inside the table's own header, under the title. With no\n             section header there is nothing to ride, so the card carries it instead. -->\n        <p class=\"db-why\" *ngIf=\"s.caption && !s.cfg?.sectionConfig\">{{ s.caption }}</p>\n        <!-- Added (reconnect no-op fix): the reconnect-refresh contract (fadd03d) ends in refreshClicked(), and a\n             table with no loadAction of its own — which every Day Book section is, the seam strips it — falls to\n             `this.dataLoad.emit()` (table.component.ts:1174). Nothing was bound to it here, so coming back from\n             offline or a dropped hub left the whole book stale. load() carries a re-entrancy guard\n             (day-book.component.ts:114), so all N section tables emitting in the same tick still cost exactly ONE\n             daybook/get. -->\n        <spa-table [config]=\"s.cfg\" [data]=\"s.rows\" (actionSuccess)=\"load()\" (dataLoad)=\"load()\"></spa-table>\n      </mat-card>\n    </ng-template>\n\n  </ng-container>\n\n</div>\n\n<!-- Graceful empty state (feature not configured) -->\n<div class=\"db-empty\" *ngIf=\"!config\">\n  <mat-icon>checklist</mat-icon>\n  <p>The Day Book is not configured for this app.</p>\n</div>\n","// Password masking component\nimport { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core';\nimport { FormControl, Validators } from '@angular/forms';\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-text-mask',\n    templateUrl: './text-mask.component.html',\n    styleUrls: ['./text-mask.component.css'],\n    standalone: false\n})\nexport class TextMaskComponent implements OnInit, OnChanges {\n\n  constructor() {  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['value'] && this.control) {\n      if (this.control.value !== changes['value'].currentValue) {\n        this.control.setValue(changes['value'].currentValue, { emitEvent: false });\n      }\n    }\n    \n    if (changes['readonly'] && this.control) {\n      this.initControl();\n    }\n  }\n\n  // Changed: the \"Enter <display>\" freeze that lived here is gone — see computedPlaceholder below.\n  ngOnInit(): void {\n  }\n\n  ngAfterViewInit() {\n    this.initControl();\n\n    if (this.value) {\n      this.control.setValue(this.value, { emitEvent: false });\n    }\n\n    this.control.valueChanges.subscribe(val => {\n      this.value = val;\n      this.control.markAsDirty();\n      this.valueChange.emit(val);\n    });\n  }\n\n  hide = true; // Changed: Controls password visibility\n\n  @Input() appearance: 'fill' | 'outline' = 'outline';\n  @Input() readonly = false;\n  @Input() hint = \"\";\n  @Input() display = \"\";\n  @Input() placeholder = \"\";\n  // Added: derived resting placeholder. A masked field is typed into, so the verb is \"Enter\". Explicit wins.\n  get computedPlaceholder(): string { return derivePlaceholder('enter', this.display, this.placeholder, this.readonly); }\n  @Input() value = \"\";\n  @Output() valueChange = new EventEmitter();\n\n  @Output() leave = new EventEmitter();\n  @Output() enterPress = new EventEmitter();\n\n  @Input() width = \"100%\";\n\n  @Input() required = true;\n  @Input() min = 0;\n  @Input() max = 9000000000000000;\n  @Input() regex?: { pattern: string; message: string };\n\n  @Input() infoMessage: string;\n\n  initControl() {\n    if (this.readonly) {\n      this.control.setValidators(null);\n      this.control.updateValueAndValidity();\n      return;\n    }\n    \n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    if (this.min > 0) {\n      validators.push(Validators.minLength(this.min));\n    }\n    \n    if (this.max < 9000000000000000) {\n      validators.push(Validators.maxLength(this.max));\n    }\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    this.control.setValidators(validators);\n    this.control.updateValueAndValidity();\n  }\n\n  leaved() {\n    this.control.markAsTouched();\n    this.leave.emit();\n\n    if (this.regex && this.value) {\n      const regexPattern = new RegExp(this.regex.pattern);\n      if (!regexPattern.test(this.value)) {\n        this.control.setErrors({ 'pattern': true });\n      }\n    }\n  }\n\n  enterPressed() {\n    this.enterPress.emit();\n  }\n\n  control = new FormControl('', this.getValidators());\n\n  private getValidators() {\n    const validators = [];\n    \n    if (this.required) {\n      validators.push(Validators.required);\n    }\n    \n    validators.push(Validators.minLength(this.min));\n    validators.push(Validators.maxLength(this.max));\n    \n    if (this.regex) {\n      validators.push(Validators.pattern(this.regex.pattern));\n    }\n    \n    return validators;\n  }\n\n  validate(control: FormControl): string {\n    if ((this.required || this.min > 0) && control.hasError('required')) {\n      return `Required`;\n    }\n\n    if (control.hasError('minlength')) {\n      return `Minimum length is ${this.min}`;\n    }\n\n    if (control.hasError('maxlength')) {\n      return `Maximum length is ${this.max}`;\n    }\n\n    if (control.hasError('pattern')) {\n      return this.regex?.message || 'Invalid Input';\n    }\n\n    return \"\";\n  }\n}\n","<!-- Password input with visibility toggle -->\n<mat-form-field class=\"spa-password\" [class.spa-readonly]=\"readonly\" [hideRequiredMarker]=\"!required\" [hintLabel]=\"hint\" [ngStyle]=\"{'width':width ?? '100%'}\" style=\"margin-right: 5px\" [appearance]=\"appearance ?? 'fill'\" subscriptSizing=\"dynamic\">\n  <mat-label>{{display}}</mat-label>\n  <input matInput [type]=\"hide ? 'password' : 'text'\" (keyup.enter)=\"enterPressed()\" (blur)=\"leaved()\" autocomplete=\"off\" [placeholder]=\"computedPlaceholder\" [formControl]=\"control\" [required]=\"required\" [readonly]=\"readonly\">\n  <mat-error *ngIf=\"control.invalid && (control.dirty || control.touched)\">{{validate(control)}}</mat-error>\n  <button mat-icon-button matSuffix (click)=\"hide = !hide\" [attr.aria-label]=\"'Hide password'\" [attr.aria-pressed]=\"hide\">\n    <mat-icon style=\"font-size: 12px;\">{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>\n  </button>\n</mat-form-field>\n","import { Component, Input, OnInit } from '@angular/core';\n\n@Component({\n    selector: 'spa-label',\n    templateUrl: './label.component.html',\n    styleUrls: ['./label.component.css'],\n    standalone: false\n})\nexport class LabelComponent implements OnInit {\n\n  constructor() { }\n\n  ngOnInit(): void {\n  }\n\n  @Input() display = \"\";\n  @Input() value = \"\";\n  @Input() format = \"text\";\n\n  @Input() suffix = \"\";\n  @Input() size = \"\";\n}\n","<!-- Changed 2026-08-20 (owner): the five format branches were five copies of the same markup, each a BLOCK\n     div holding two inline <label>s separated by &nbsp;. Two things followed from that shape and both were\n     the reported defect:\n\n       1. Inline labels align on a shared BASELINE, and the two had different line boxes (caption 16px/24px,\n          value 20px/30px). Measured on test-spa /docdemo at 1920x1080: caption centreline 846.1, value\n          centreline 844.1 — the caption sat 2.0px LOWER than its own value, which is what the owner saw on\n          piglet's Record Feeding dialog (\"Available Stock : 0 Kilogram\").\n       2. The &nbsp; separators were layout-by-typography: real text nodes doing a gutter's job, so the gap\n          could not be stated, measured or kept equal across the five copies.\n\n     Now ONE wrapper renders every format and the value alone switches, so all five formats are geometrically\n     identical by construction rather than by five copies staying in sync. The wrapper is a flex row with\n     align-items:center (see label.component.css), which centres the two line BOXES instead of hanging them\n     off a baseline — the centreline delta becomes 0.0px and stays there whatever the value's font size.\n\n     Behaviour is deliberately unchanged: the same pipes on the same formats, including 'number' keeping the\n     currency:'USD':'' pipe it has always used (that yields the 2-decimal grouping without a symbol; it is a\n     pre-existing choice and this is a geometry pass, so it is preserved verbatim rather than \"fixed\"), and\n     suffix still shows for text/money/number only, never for the date formats. -->\n<div class=\"label-row\">\n\n  <label class=\"label-caption\">{{display}} :</label>\n\n  <!-- Changed: default 20px -> 17px (owner: \"if the value's font makes the row too tall, REDUCE the value\n       font a little\"). At 20px the value's line box was 30px and filled 75% of the 40px control band, which\n       is most of why the row read as something other than a field. 17px sits in the 24px line box the CSS\n       pins, exactly the line box a mat-input's own 16px text occupies, so the display row now has an input's\n       vertical geometry while staying a step larger than the 16px caption beside it.\n       The `size` input still wins: ngStyle writes an INLINE font-size, which outranks the stylesheet. -->\n  <label class=\"label-value\" [ngStyle]=\"{'font-size': size || '17px'}\">\n    <ng-container [ngSwitch]=\"format\">\n      <ng-container *ngSwitchCase=\"'date'\">{{value | date:'dd/MM/yyyy'}}</ng-container>\n      <ng-container *ngSwitchCase=\"'datetime'\">{{value | date:'dd/MM/yyyy HH:mm'}}</ng-container>\n      <ng-container *ngSwitchCase=\"'money'\">{{value | currency:'USD':''}} {{suffix ?? ''}}</ng-container>\n      <ng-container *ngSwitchCase=\"'number'\">{{value | currency:'USD':''}} {{suffix ?? ''}}</ng-container>\n      <ng-container *ngSwitchDefault>{{value}} {{suffix ?? ''}}</ng-container>\n    </ng-container>\n  </label>\n\n</div>\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { MessageService } from '../../services/message.service';\nimport imageCompression from 'browser-image-compression';\n\n\n@Component({\n    selector: 'spa-attach',\n    templateUrl: './attach.component.html',\n    styleUrls: ['./attach.component.scss'],\n    standalone: false\n})\nexport class AttachComponent implements OnInit {\n\n  constructor(private messageService : MessageService) { }\n\n  ngOnInit(): void {\n    // this.fileOptions = {allowedExtensions: ['.jpg', '.jpeg', '.png', '.gif'], maxSizeMB: 1, compressImages: true};\n  }\n\n  @Input() fileOptions: {\n    allowedExtensions?: string[];\n    maxSizeMB?: number;\n    compressImages?: boolean;\n  };\n  private readonly imageExtensions = ['.jpg', '.jpeg', '.png', '.gif'];\n\n  @Input() message = \"Drag and drop files here\"\n  @Input() files: any[] = [];\n  @Output() filesChange = new EventEmitter();\n  @Output() upload = new EventEmitter();\n\n  // Added (Phase 6): the backend's RepoResponse.FileMessage, set by HandleSaveFiles (BaseController.cs:920/933/949).\n  // 🔴 THIS IS THE POINT OF THE WHOLE TASK. The save and the file write are two operations behind one response:\n  // the record can persist while every attachment is rejected, and the caller was still told \"Submitted\".\n  // The message is shown HERE, against the drop zone the user just filled, rather than only as a toast that\n  // scrolls away — the files they chose are the thing the message is about.\n  @Input() fileMessage = '';\n\n  // Added (Phase 6): fires after a submit that actually carried files, with the names as sent. This is what\n  // pairs the drop zone to its sibling <spa-document> shelf so an upload appears without a page reload.\n  @Output() uploaded = new EventEmitter<string[]>();\n\n\n  @Input() enableUpload = false;\n\n\n  onFileDropped($event) {\n    this.prepareFilesList($event);\n  }\n\n  fileBrowseHandler(event) {\n    let files = event.target.files;\n    this.prepareFilesList(files);\n  }\n\n\n  deleteFile(index: number) {\n    this.files.splice(index, 1);\n  }\n\n\n  async prepareFilesList(files: Array<any>) {\n    for (const file of files) {\n      const ext = this.getFileExtension(file.name);\n      // Changed (G18): was `allowedExtensions.includes(ext.toLowerCase())` — a VERBATIM compare against a value\n      // that always carries a leading dot, so a dotless entry like 'pdf' matched nothing and EVERY file was\n      // dropped while the submit still POSTed and still answered 200. Normalise both sides instead.\n      if (this.fileOptions?.allowedExtensions?.length && !this.isAllowedExtension(ext)) {\n        // Changed (G18): reasoned refusal — name the file and the allowed list, not just the type. The old\n        // wording (\"File type .pdf not allowed\") named neither the file nor what WOULD be accepted.\n        const described = ext ? `${ext} files are not allowed here` : `it has no file extension`; // Added (G18): the extensionless case must still read as a sentence\n        this.messageService.toast(`${file.name} was not attached: ${described}. Allowed: ${this.normalizedAllowedExtensions().join(', ')}`);\n        continue;\n      }\n\n      let processedFile = file;\n      if (this.fileOptions?.compressImages && this.isImage(file.name)) {\n        try {\n          const options = {\n            maxSizeMB: this.fileOptions.maxSizeMB || 1,\n            maxWidthOrHeight: 1920,\n            useWebWorker: true\n          };\n          processedFile = await imageCompression(file, options);\n        } catch (error) {\n          this.messageService.toast(`Error compressing image: ${file.name}`);\n          continue;\n        }\n      }\n\n      processedFile.progress = 0;\n      this.files.push(processedFile);\n    }\n    this.filesChange.emit(this.files);\n  }\n\n  // Add new helper methods\n  private getFileExtension(filename: string): string {\n    // Changed (G18): a name with NO dot made lastIndexOf return -1, and substring(-1) returns the WHOLE name —\n    // so \"README\" reported an extension of \"readme\". Return '' instead; an extensionless file is then refused\n    // by name against the allowed list rather than accidentally matching one.\n    const dot = (filename ?? '').lastIndexOf('.');\n    return dot < 0 ? '' : filename.substring(dot).toLowerCase();\n  }\n\n  // Added (G18): dot-insensitive, case-insensitive, whitespace-tolerant matching. 'pdf', '.pdf', 'PDF' and\n  // ' .PDF ' all accept a .pdf file. Mirrors the normalisation document.component.ts already does at :161.\n  private isAllowedExtension(ext: string): boolean {\n    const candidate = ext.replace(/^\\./, '').trim().toLowerCase();\n    return this.normalizedAllowedExtensions().includes(candidate);\n  }\n\n  // Added (G18): the allowed list reduced to bare, lowercase extensions — also what the refusal message shows.\n  private normalizedAllowedExtensions(): string[] {\n    return (this.fileOptions?.allowedExtensions ?? []).map(x => (x ?? '').replace(/^\\./, '').trim().toLowerCase()).filter(x => x.length > 0);\n  }\n\n  private isImage(filename: string): boolean {\n    const ext = this.getFileExtension(filename);\n    return this.imageExtensions.includes(ext.toLowerCase());\n  }\n\n\n\n  formatBytes(bytes, decimals) {\n    if (bytes === 0) {\n      return '0 Bytes';\n    }\n    const k = 1024;\n    const dm = decimals <= 0 ? 0 : decimals || 2;\n    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];\n    const i = Math.floor(Math.log(bytes) / Math.log(k));\n    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];\n  }\n\n  // Changed (Phase 6): renamed from uploaded() — the name is now the @Output that reports a completed save.\n  // The `upload` output it emits is unchanged, so the enableUpload button behaves exactly as before.\n  emitUpload(){\n    this.upload.emit();\n  }\n\n  // Added (Phase 6): called by the host after a submit that carried files. Clears the staged list (they are\n  // on the server now, and leaving them queued invites a duplicate second submit) and announces the names.\n  notifyUploaded(fileNames: string[]){\n    this.files = [];\n    this.filesChange.emit(this.files);\n    this.uploaded.emit(fileNames ?? []);\n  }\n\n  filesChanged(){\n    this.filesChange.emit(this.files);\n  }\n}\n","<div class=\"tin-input-row\" style=\"width: 100%;\">\n\n  <div class=\"col\">\n    <div class=\"container\" appDnd (fileDropped)=\"onFileDropped($event)\">\n      <input type=\"file\" #fileDropRef id=\"fileDropRef\" multiple (change)=\"fileBrowseHandler($event)\" />\n      <h4>{{message}}</h4>\n\n      <label for=\"fileDropRef\">Click to Browse</label>\n    </div>\n  </div>\n\n  <div class=\"col\">\n\n    <!-- Added (Phase 6): the backend's FileMessage. It is only ever rendered when the server actually said\n         something about the files, so a clean save shows nothing at all. -->\n    <div class=\"tin-attach-message\" *ngIf=\"fileMessage\" role=\"status\">\n      <mat-icon>warning_amber</mat-icon>\n      <span>{{fileMessage}}</span>\n    </div>\n\n    <div class=\"files-list \">\n      <div class=\"single-file \" style=\"width: 100%;\" *ngFor=\"let file of files; let i = index\">\n\n        <div class=\"tin-input-row info\" >\n          <h4 class=\"name\">\n            {{ file?.name }}\n          </h4>\n          <p class=\"size\">\n            {{ formatBytes(file?.size, 2) }}\n          </p>\n        </div>\n\n        <div class=\"delete\" (click)=\"deleteFile(i)\">\n          <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"18\" viewBox=\"0 0 14 18\">\n            <path fill=\"#B1B1B1\" fill-rule=\"nonzero\"\n              d=\"M1 16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v10zm3.17-7.83a.996.996 0 0 1 1.41 0L7 9.59l1.42-1.42a.996.996 0 1 1 1.41 1.41L8.41 11l1.42 1.42a.996.996 0 1 1-1.41 1.41L7 12.41l-1.42 1.42a.996.996 0 1 1-1.41-1.41L5.59 11 4.17 9.58a.996.996 0 0 1 0-1.41zM10.5 1L9.79.29C9.61.11 9.35 0 9.09 0H4.91c-.26 0-.52.11-.7.29L3.5 1H1c-.55 0-1 .45-1 1s.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1h-2.5z\" />\n          </svg>\n        </div>\n      </div>\n    </div>\n\n    <div *ngIf=\"files.length > 0 && enableUpload\" class=\"tin-input-row d-flex justify-content-center\" style=\"width: 100%;\" >\n      <button mat-button color=\"primary\" (click)=\"emitUpload()\" matTooltip=\"Upload New Documents\" matTooltipPosition=\"above\"  ><mat-icon>file_upload</mat-icon> Upload</button>\n    </div>\n  </div>\n\n</div>\n","// spa-document — the in-form document shelf, and the replacement for the `file-view` field's <spa-viewer>.\n//\n// WHAT IT REPLACES AND WHY. spa-viewer listed a record's documents as a row of undifferentiated grey chips\n// and opened them through viewerDialog, which resolved bytes via ./assets/ or a PUBLIC Azure container.\n// This component lists the same names, but every byte it opens comes from the app's own authorized stream\n// through DocumentService — the bearer token, the capability gate and tenant scoping all apply.\n//\n// 🔴 IT IS NOT A COMPONENT THAT FETCHES DOCUMENTS. It fetches only the NAME LIST. The bytes are the\n// viewer dialog's job, which matters for memory: a form with five attachments must not hold five blobs.\n//\n// DESIGN NOTE — the \"shelf\". Each document is a card with a kind-tinted spine rather than a chip, because\n// the two questions a user actually asks of this field are \"how many?\" and \"which one is the invoice?\",\n// and a row of identical chips answers neither. The file name is truncated in the MIDDLE\n// (see truncateMiddle) so the extension — the single most informative part of a document's name — always\n// survives; end-truncation turns `haulage-invoice-2026-q3-final.pdf` into something with no visible type.\n\nimport { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { DialogService } from '../../services/dialog.service';\nimport { DocumentService } from '../../services/document.service';\nimport { Action, ApiResponse } from '../../classes/Classes';\nimport { DocumentKind, DocumentSource } from '../../classes/DocumentClasses';\n\n// One entry on the shelf. Built once per list load — never derived in the template, because\n// template-bound getters that allocate are banned in this library (they caused a real livelock).\nexport interface DocumentEntry {\n  fileName: string;\n  label: string;\n  extension: string;\n  kind: DocumentKind;\n  icon: string;\n}\n\n// Material icon per kind. A plain map rather than a ternary chain: the viewer's toolbar used to hard-code\n// \"image or else PDF\" and called a spreadsheet a PDF.\nconst ICON_BY_KIND: { [kind: string]: string } = {\n  pdf: 'picture_as_pdf',\n  image: 'image',\n  word: 'article',\n  excel: 'grid_on',\n  text: 'subject',\n  unsupported: 'draft'\n};\n\n@Component({\n  selector: 'spa-document',\n  templateUrl: './document.component.html',\n  styleUrls: ['./document.component.css'],\n  standalone: false\n})\nexport class DocumentComponent implements OnInit, OnChanges {\n\n  constructor(\n    private dataService: DataServiceLib,\n    private dialogService: DialogService,\n    private documentService: DocumentService\n  ) { }\n\n  // The Phase 6 contract. When present it supplies BOTH halves — listAction for the names, streamUrl for\n  // the authorized bytes. Its absence is what the legacy inputs below are for.\n  @Input() documentSource: DocumentSource;\n\n  // Legacy inputs, kept so the field can be switched over before the consumer apps are migrated\n  // (Phase 7 task 1). listAction is the same Action spa-viewer took as `fileAction`.\n  @Input() listAction: Action;\n\n  // The parent row's key, substituted into {keyField} in both the list URL and the stream URL.\n  @Input() keyValue: any;\n\n  @Input() title = 'Documents';\n\n  // 🔴 THE PAIRING MECHANISM. form.component bumps this after a submit that carried files, and the shelf\n  // reloads from the API. It is deliberately a counter and not a boolean: two uploads in a row must both\n  // fire, and a boolean's second `true` is not a change. Reloading from the API rather than appending the\n  // uploaded names locally is also deliberate — the server renames on collision, so a locally appended\n  // name can be a name that does not exist.\n  @Input() refreshToken = 0;\n\n  @Output() loaded = new EventEmitter<string[]>();\n\n  entries: DocumentEntry[] = [];\n  state: 'loading' | 'ready' | 'empty' | 'error' = 'loading';\n  errorMessage = '';\n\n  // Skeleton placeholders while the name list is in flight. Three is the honest guess — it fills the row\n  // without implying a count.\n  readonly placeholders = [0, 1, 2];\n\n  ngOnInit(): void {\n    this.load();\n  }\n\n  ngOnChanges(changes: SimpleChanges): void {\n    // Only reload on things that actually change WHAT is listed. Re-running on every change detection pass\n    // would put this field into a fetch loop.\n    if (changes['refreshToken'] && !changes['refreshToken'].firstChange) {\n      this.load();\n      return;\n    }\n\n    if ((changes['keyValue'] && !changes['keyValue'].firstChange) ||\n        (changes['documentSource'] && !changes['documentSource'].firstChange)) {\n      this.load();\n    }\n  }\n\n  // Public so a host can refresh the shelf without owning refreshToken.\n  load(): void {\n    const action = this.documentSource?.listAction ?? this.listAction;\n\n    if (!action?.url) {\n      this.entries = [];\n      this.state = 'empty';\n      return;\n    }\n\n    this.state = 'loading';\n\n    // The same placeholder bag the stream URL uses, so a misconfigured {keyField} fails identically in\n    // both halves instead of listing names that then cannot be fetched.\n    const url = this.documentService.resolveUrl(action.url, this.placeholderValues());\n\n    this.dataService.CallApi({ ...action, url: url }, '').subscribe({\n      next: (apiResponse: ApiResponse) => {\n        this.setEntries(this.toFileNames(apiResponse?.data));\n      },\n      error: () => {\n        // Surfaced, not swallowed. An empty shelf on a failed list is indistinguishable from a record with\n        // no documents, and that is the house's recurring bug shape.\n        this.entries = [];\n        this.errorMessage = 'The document list could not be loaded.';\n        this.state = 'error';\n      }\n    });\n  }\n\n  // Accepts the two shapes the estate's list endpoints actually return: a real array, and the\n  // pipe-delimited string spa-viewer's convert() handled. Anything else lists as nothing rather than\n  // throwing inside a form.\n  toFileNames(data: any): string[] {\n    if (Array.isArray(data)) {\n      return data.filter(name => typeof name === 'string' && name.trim() !== '');\n    }\n\n    if (typeof data === 'string') {\n      return data.split('|').map(name => name.trim()).filter(name => name !== '');\n    }\n\n    return [];\n  }\n\n  // Client-side cosmetic filter only. 🔴 The SERVER remains the sole authority on what may be read — this\n  // must never be mistaken for a security control, which is why it lives here and not near the fetch.\n  allowed(fileName: string): boolean {\n    const allowedExtensions = this.documentSource?.allowedExtensions;\n    if (!allowedExtensions || allowedExtensions.length === 0) {\n      return true;\n    }\n\n    const extension = this.extensionOf(fileName);\n    return allowedExtensions.some(candidate => candidate.replace('.', '').toLowerCase() === extension);\n  }\n\n  extensionOf(fileName: string): string {\n    if (!fileName || typeof fileName !== 'string') {\n      return '';\n    }\n\n    const dot = fileName.lastIndexOf('.');\n    return dot < 0 || dot === fileName.length - 1 ? '' : fileName.substring(dot + 1).toLowerCase();\n  }\n\n  // Middle-truncation, keeping the extension. `head…tail` rather than `head…`, because the tail is where\n  // the type and usually the version live. Pure and exported through the component so it can be pinned by\n  // a spec — the CSS-only ellipsis it replaces could not be.\n  truncateMiddle(fileName: string, limit = 28): string {\n    if (!fileName || fileName.length <= limit) {\n      return fileName ?? '';\n    }\n\n    const dot = fileName.lastIndexOf('.');\n    const tail = dot > 0 ? fileName.substring(dot) : '';\n    const head = dot > 0 ? fileName.substring(0, dot) : fileName;\n\n    // Room for the ellipsis plus a few characters of the head's own end, so two files that differ only in\n    // their suffix (\"...-draft.pdf\" / \"...-final.pdf\") stay distinguishable.\n    const keep = Math.max(4, limit - tail.length - 5);\n    return `${head.substring(0, keep)}…${head.substring(head.length - 4)}${tail}`;\n  }\n\n  buildEntry(fileName: string): DocumentEntry {\n    const kind = this.documentService.kindFor(fileName);\n\n    return {\n      fileName: fileName,\n      label: this.truncateMiddle(fileName),\n      extension: this.extensionOf(fileName).toUpperCase(),\n      kind: kind,\n      icon: ICON_BY_KIND[kind] ?? 'draft'\n    };\n  }\n\n  // Opens the full-bleed viewer on the clicked document, handing it the WHOLE set so the picker rail can\n  // navigate between them — and, at exactly one document, so the rail is absent from the DOM entirely.\n  open(entry: DocumentEntry): void {\n    const streamUrl = this.documentSource?.streamUrl;\n\n    if (!streamUrl) {\n      // Configuration, not a runtime fault. Saying so beats opening a viewer that can only render an error.\n      this.errorMessage = 'This field has no document source configured.';\n      this.state = 'error';\n      return;\n    }\n\n    this.dialogService.openDocumentViewer({\n      documents: this.entries.map(item => item.fileName),\n      fileName: entry.fileName,\n      streamUrl: streamUrl,\n      values: this.placeholderValues(),\n      downloadable: this.documentSource?.downloadable !== false,\n      title: this.title\n    });\n  }\n\n  // Bound by *ngFor. A field, not a getter — see the ban on template-bound allocating getters.\n  trackByFileName(index: number, entry: DocumentEntry): string {\n    return entry.fileName;\n  }\n\n  private setEntries(fileNames: string[]): void {\n    this.entries = fileNames.filter(name => this.allowed(name)).map(name => this.buildEntry(name));\n    this.state = this.entries.length === 0 ? 'empty' : 'ready';\n    this.errorMessage = '';\n    this.loaded.emit(this.entries.map(entry => entry.fileName));\n  }\n\n  // {keyField} is the token both the list URL and the stream URL are written against. Named rather than\n  // positional so a URL reads as documentation of what it needs.\n  private placeholderValues(): { [key: string]: any } {\n    return { keyField: this.keyValue };\n  }\n}\n","<div class=\"spa-docs\">\n\n  <div class=\"spa-docs-head\" *ngIf=\"title !== ''\">\n    <span class=\"spa-docs-title\">{{title}}</span>\n    <!-- The count is the answer to the first question anyone asks of this field. Rendered only once the\n         list is settled, so it never flickers a wrong number while loading. -->\n    <span class=\"spa-docs-count\" *ngIf=\"state === 'ready'\">{{entries.length}}</span>\n  </div>\n\n  <!-- Skeleton. Same shape as the real cards, so the row does not resize when they arrive. -->\n  <div class=\"spa-docs-shelf\" *ngIf=\"state === 'loading'\">\n    <!-- 🔴 The skeleton deliberately does NOT carry .spa-docs-card. It shares the card's LAYOUT through the\n         grouped selector in the stylesheet, but not its class, so nothing that counts `.spa-docs-card` — a\n         test, or a consumer walking the DOM — can mistake three placeholders for three documents. That\n         exact confusion produced a \"5 documents became 3\" failure while this was being built. -->\n    <div class=\"spa-docs-skeleton-card\" *ngFor=\"let placeholder of placeholders\">\n      <div class=\"spa-docs-tile spa-docs-skeleton-block\"></div>\n      <div class=\"spa-docs-text\">\n        <div class=\"spa-docs-skeleton-line\"></div>\n        <div class=\"spa-docs-skeleton-line spa-docs-skeleton-line-short\"></div>\n      </div>\n    </div>\n  </div>\n\n  <div class=\"spa-docs-shelf\" *ngIf=\"state === 'ready'\">\n    <button type=\"button\" class=\"spa-docs-card\" *ngFor=\"let entry of entries; trackBy: trackByFileName\"\n            [ngClass]=\"'spa-docs-kind-' + entry.kind\" (click)=\"open(entry)\" [attr.title]=\"entry.fileName\"\n            [attr.data-kind]=\"entry.kind\">\n      <span class=\"spa-docs-spine\"></span>\n      <span class=\"spa-docs-tile\"><mat-icon>{{entry.icon}}</mat-icon></span>\n      <span class=\"spa-docs-text\">\n        <span class=\"spa-docs-name\">{{entry.label}}</span>\n        <span class=\"spa-docs-ext\">{{entry.extension}}</span>\n      </span>\n    </button>\n  </div>\n\n  <!-- A quiet line, not an empty box. This is one field among many on a form; an illustrated empty state\n       here would outweigh the fields that carry the actual record. -->\n  <p class=\"spa-docs-empty\" *ngIf=\"state === 'empty'\">No {{title.toLowerCase()}} yet</p>\n\n  <p class=\"spa-docs-error\" *ngIf=\"state === 'error'\">\n    <mat-icon>error_outline</mat-icon>\n    <span>{{errorMessage}}</span>\n  </p>\n\n</div>\n","import { Component, Input, OnInit, SecurityContext } from '@angular/core';\nimport { DomSanitizer } from '@angular/platform-browser';\n\n@Component({\n    selector: 'spa-html',\n    templateUrl: './html.component.html',\n    styleUrls: ['./html.component.css'],\n    standalone: false\n})\nexport class HtmlComponent implements OnInit {\n  constructor(private sanitizer: DomSanitizer) { }\n\n  ngOnInit(): void {\n    this.sanitizeHtml();\n  }\n\n  ngOnChanges(): void {\n    this.sanitizeHtml();\n  }\n\n  @Input() value = '';\n  @Input() maxHeight = '500px'; // Default maximum height\n  @Input() display = ''; // For consistency with other components\n\n  sanitizedHtml = '';\n\n  private sanitizeHtml(): void {\n    // Changed: sanitize instead of bypassing Angular's protection. This strips <script>, event handlers\n    // (onerror/onclick, etc.) and other XSS vectors while keeping safe formatting markup, preventing\n    // stored XSS from any user-influenced html-type field.\n    this.sanitizedHtml = this.sanitizer.sanitize(SecurityContext.HTML, this.value ?? '') ?? '';\n  }\n}","<div *ngIf=\"display\" class=\"html-label\">{{display}}</div>\n<div class=\"html-container\" [ngStyle]=\"{'max-height': maxHeight}\">\n  <div class=\"html-content\" [innerHTML]=\"sanitizedHtml\"></div>\n</div>","import { Component, Input, OnInit } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { ApiResponse } from '../../classes/Classes';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: a failed note load rendered an empty panel (WS-6 Phase 4)\n\n@Component({\n    selector: 'spa-notes',\n    templateUrl: './notes.component.html',\n    styleUrls: ['./notes.component.css'],\n    standalone: false\n})\nexport class NotesComponent implements OnInit {\n  constructor(private dataService: DataServiceLib, private apiErrorService: ApiErrorService) { } // Changed: injected so a failed note load says so\n\n  ngOnInit(): void {\n    this.loadNotes();\n  }\n\n  // Input properties\n  @Input() title = \"Notes\";\n  @Input() notes: any[] = []; // Data array if provided directly\n  @Input() loadAction: any; // URL config if notes need to be loaded \n  @Input() loadIDField: string; // Field to use for ID when loading notes\n  @Input() data: any; // Parent data object for ID reference\n\n  // Field mapping inputs (defaults match the existing activity component)\n  @Input() nameField = \"createdByName\";\n  @Input() dateField = \"createdDate\";\n  @Input() commentField = \"details\";\n\n  private loadNotes(): void {\n\n    // If notes are already provided as an object, use them directly\n    if (this.notes && this.notes.length > 0) {\n      return;\n    }\n\n    // Otherwise, load from the URL if configured\n    if (this.loadAction && this.data) {\n      let url = this.loadAction.url;\n      \n      // Changed: Support generic {propertyName} placeholders first\n      if (url.includes('{')) {\n        url = url.replace(/\\{(\\w+)\\}/g, (match, propName) => {\n          const value = this.data?.[propName];\n          return value !== undefined && value !== null ? String(value) : match;\n        });\n      } else if (this.loadIDField) {\n        // Fallback: Use loadIDField for backward compatibility\n        const idValue = this.data[this.loadIDField];\n        if (!idValue) return;\n        url = url.replace('/x', '/' + idValue);\n      }\n\n      this.dataService.CallApi({ ...this.loadAction, url }).subscribe((apiResponse: ApiResponse) => {\n        // CONVERTED (WS-6 Phase 4 triage). This is the same shape as the five field loads Phase 3 fixed —\n        // notes attached to a record are content, not decoration, and an empty panel asserts \"there are no\n        // notes on this record\", which is a statement someone will act on. It runs once per record view,\n        // not on a timer, so there is no storm to cause.\n        if (!apiResponse.success) this.apiErrorService.presentAppFailure(apiResponse, 'load', url);\n        if (apiResponse.success && apiResponse.data) {\n          this.notes = apiResponse.data;\n        }\n      });\n    }\n  }\n}","  <div class=\"notes-container\" *ngIf=\"notes && notes.length > 0\">\n    <div class=\"tin-input-row mt-3\" *ngIf=\"title != ''\">\n      <mat-label style=\"font-size: 20px; font-weight: 300\">{{title}}</mat-label>\n    </div>\n  \n    <ul class=\"list-group list-group-flush\" style=\"max-height:350px; margin-left:5px\">\n      <li *ngFor=\"let note of notes\" class=\"list-group-item list-group-item-action flex-column align-items-start\">\n        <div class=\"d-flex w-100 justify-content-between\">\n          <div class=\"mb-0\">{{note[nameField] || note.createdByName}}</div>\n        </div>\n        <small>{{note[commentField] || note.details}} (<em>{{note[dateField] || note.createdDate | date: 'dd MMM yyyy HH:mm'}}</em>)</small>\n      </li>\n    </ul>\n  </div>\n  \n  <div *ngIf=\"!notes || notes.length == 0\" class=\"d-flex justify-content-center row align-items-center\" style=\"max-height:200px\">\n    No {{title.toLowerCase()}}\n  </div>","import { Component, ContentChild, DoCheck, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; // TS-11: DoCheck to detect parent-driven mode changes. Changed: ElementRef for focusInvalidField\nimport { FormConfig, Field, Button, ApiResponse } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore';\nimport { MessageService } from '../../services/message.service';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { BehaviorSubject, Subscription } from 'rxjs';\nimport { AuthService } from '../../services/auth.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — a standalone form submit has the same double-post risk as the dialog\nimport { EMAIL_SINGLE_REGEX } from '../../runtime/email-single'; // Added (email-single): the shared single-address contract, so form and inline cell cannot drift\nimport { OfflineService } from '../../services/offline.service'; // Added (WS-1): read-only — lets a dead child-option fetch tell an offline cache miss from a server failure\n\n\n@Component({\n    selector: 'spa-form',\n    templateUrl: './form.component.html',\n    styleUrls: ['./form.component.css'],\n    standalone: false\n})\nexport class FormComponent implements OnInit, OnDestroy, DoCheck { // TS-11: DoCheck\n\n  private subscriptions: Subscription[] = []; // TS-6: track per-instance subscriptions so a destroyed form is not retained by the shared field.optionsSubject\n\n  emailSingleRegex = EMAIL_SINGLE_REGEX; // Added (email-single): the default pattern the 'email-single' case falls back to when a field declares no regex of its own\n\n  visibleFields: Field[] = []; // TS-11: cached visible fields — template binds this instead of calling getVisibleFields() every CD\n  private lastMode: string; // TS-11: track config.mode so a parent-driven mode change (e.g. detailsDialog view→edit) refreshes the cache\n\n  constructor(private messageService: MessageService, private dataService: DataServiceLib, private authService: AuthService, private apiErrorService: ApiErrorService, private offline: OfflineService, private hostRef: ElementRef<HTMLElement>) { } // Changed: injected ElementRef to locate the offending field's control on a blocked submit (focusInvalidField) — the rejected field was left ng-untouched, so Material rendered no error at all. Changed: injected ApiErrorService to route application-level (HTTP 200, success:false) failures through the shared classify + dedupe path; injected OfflineService (root-provided and already a DataServiceLib dependency, so no new graph) to tell an offline cache miss from a server failure\n\n  ngOnDestroy() {\n    this.subscriptions.forEach(s => s.unsubscribe()); // TS-6: release subscriptions to the shared (singleton config) optionsSubject\n  }\n\n  ngOnInit() {\n\n    this.hasAccess = Core.hasFormAccess(this.config, this.authService.currentRoleSource.value);\n\n    if (!this.hasAccess) {\n      // this.messageService.toast('Access denied'); // Optional - notify user\n      return;\n    }\n\n    if (!this.config.fields){\n      this.messageService.toast(\"Please Configure Form Fields\")\n      return;\n    }\n\n    if (!this.data) {\n      this.messageService.toast(\"Please Configure Form Data\")\n      return;\n    }\n\n    this.fields = this.config.fields;\n\n    // Added (addpig-label-leak): STAMP each field with the config this form is actually rendering.\n    //\n    // A handler that must rewrite a SIBLING field's `alias`/`hint` needs the live object, and since\n    // 20.14.82 (42d665c) deep-clones the config per dialog open, the app service's own singleton is NOT\n    // it — a write there repaints nothing and then leaks into the next open (measured on piglet :4203).\n    // `onChange`/`onSelectChange` now receive the config as a trailing argument, but form.component is not\n    // the only caller: spa-select-common and spa-text-single invoke `field.onSelectChange` themselves, and\n    // the select markup is a CONSUMER-PROJECTABLE template (#dynamicSelect), so threading a new @Input\n    // through it would reach outside this library. Stamping the field is what lets every call path answer\n    // the same question without a new binding.\n    //\n    // NON-ENUMERABLE on purpose, and that is load-bearing twice over: `Core.deepClone2` copies via\n    // Object.entries, so this never clones (each form stamps its own object afresh, and no clone can\n    // inherit a stale form's config), and JSON.stringify of a field is unaffected — so no payload,\n    // log or storage path can trip over the reference cycle it would otherwise create.\n    this.fields?.forEach(field => {\n      Object.defineProperty(field, 'formConfig', { value: this.config, enumerable: false, configurable: true, writable: true });\n    });\n\n    // Initialize BehaviorSubjects for fields with loadActions\n    this.fields?.forEach(field => {\n      if (field.loadAction && !field.masterField) {\n        // Changed: TS-6 — create the shared subject once, but subscribe PER INSTANCE and track it.\n        // Previously the subscription was created only for the first form instance and never released,\n        // retaining that destroyed component (and running its update logic) for the life of the app.\n        if (!field.optionsSubject) {\n          field.optionsSubject = new BehaviorSubject<any[]>([]);\n        }\n\n        // Subscribe to options changes (BehaviorSubject replays current value to this instance)\n        this.subscriptions.push(field.optionsSubject.subscribe(newOptions => {\n          field.options = newOptions;\n\n          // Update child fields that depend on this field\n          if (this.childFields?.some(x => x.masterField === field.name)) {\n            this.updateChildOptions(field.name);\n          }\n          this.refreshVisibleFields(); // TS-11: options changed — refresh cached visible fields (previously recomputed every CD)\n        }));\n      }\n    });\n\n\n    if (this.config.multiColumn){\n      this.multiColumn = this.config.multiColumn\n    }else{\n      this.multiColumn = this.fields.length > 2\n    }\n\n    if (this.config?.button?.display){\n      this.buttonDisplay = this.config.button.display;\n    }\n\n    this.fileField = this.fields.find(x => x.type == 'file')\n\n    if (this.config?.button?.action && this.fileField || this.config?.button?.action.url.includes(\"/form\")) {\n      this.config.button.action.isFormData = true;\n\n    }\n\n    this.childFields = this.fields.filter(x => x.masterField)\n\n    // Changed (lazy options): moved ABOVE the two loadChildMasterOptions loops. Those loops fetch options for\n    // every field carrying a loadAction, so they can only skip a collapsed section's fields if the collapse\n    // state has already been decided — it used to be decided three statements later.\n    this.initializeSectionStates();\n\n    this.childFields.forEach(child => {\n      let master = this.fields.find(x => x.name == child.masterField)\n      if (child.loadAction) {\n        this.loadChildMasterOptions(child);\n      }else{\n        this.updateChildOptions(master.name);\n      }\n\n    });\n\n    this.fields.forEach(field => {\n      if (field.loadAction) {\n        this.loadChildMasterOptions(field);\n      }\n    });\n\n    this.initializeCompositeFields();\n\n    this.applyValueCalculations();\n\n    this.lastMode = this.config?.mode; // TS-11: seed mode tracker\n    this.refreshVisibleFields(); // TS-11: seed the cached visible fields once\n  }\n\n  // TS-11: detect parent-driven mode changes (config.mode mutated in place by detailsDialog) and refresh the cache\n  ngDoCheck() {\n    if (this.config?.mode !== this.lastMode) {\n      this.lastMode = this.config?.mode;\n      this.refreshVisibleFields();\n    }\n  }\n\n  // TS-11: recompute the cached visible-fields list; called from ngOnInit and every internal state change that affects visibility\n  private refreshVisibleFields() {\n    // Changed: only ADOPT a new array when the visible set has actually changed. getVisibleFields() allocates\n    // a fresh array on every call, so reassigning unconditionally handed *ngFor a new identity even when the\n    // fields were identical. The optionsSubject subscription above calls this whenever a select's options\n    // arrive — which for an async load lands AFTER the view has been checked, and the bare identity change\n    // then surfaced as NG0100 on the Create User dialog (previous and current values identical JSON).\n    // Comparing element-by-element by reference is O(n) over a handful of fields and keeps the binding stable.\n    const next = this.getVisibleFields();\n    if (!this.sameFields(next, this.visibleFields)) this.visibleFields = next;\n\n    // Added: subfield visibility depends on the same data, so it still has to be re-derived — but the cached\n    // array is only replaced when its contents differ, for exactly the reason above (getVisibleSubfields\n    // feeds its own *ngFor). Rebuilding the WeakMap unconditionally would churn that binding instead.\n    const previousSubfields = this.subfieldCache;\n    this.subfieldCache = new WeakMap();\n    this.previousSubfieldCache = previousSubfields;\n  }\n\n  // Added: reference-wise array equality. Field objects are filtered out of this.fields, so the SAME object\n  // identities come back each pass — only the containing array is new. Reference comparison is therefore the\n  // correct test, and it is what distinguishes a real visibility change from a pure reallocation.\n  private sameFields(a: Field[], b: Field[]): boolean {\n    if (!a || !b || a.length !== b.length) return false;\n    return a.every((field, i) => field === b[i]);\n  }\n\n  // Added: the pre-invalidation subfield arrays, so getVisibleSubfields can hand back the SAME array when a\n  // recompute produces an identical list (see getVisibleSubfields).\n  private previousSubfieldCache = new WeakMap<Field, Field[]>();\n\n  // Added: stable-reference cache for subfields — getVisibleSubfields() feeds an *ngFor and allocated a new\n  // array every change-detection cycle. Invalidated from refreshVisibleFields(), which already runs on every\n  // state change that can affect visibility (so conditional subfields still appear/disappear live).\n  private subfieldCache = new WeakMap<Field, Field[]>();\n\n  @ContentChild('dynamicSelect') dynamicSelectTemplate: TemplateRef<any>;\n\n  // Fixed: fallback select template baked into spa-form itself — a consumer-projected #dynamicSelect\n  // (detailsDialog) still takes precedence, but spa-form used directly no longer renders selects as nothing\n  @ViewChild('defaultDynamicSelect', { static: true }) defaultDynamicSelectTemplate: TemplateRef<any>;\n\n  get selectTemplate(): TemplateRef<any> {\n    return this.dynamicSelectTemplate ?? this.defaultDynamicSelectTemplate;\n  }\n\n  hasAccess = false;\n  fileNames\n  fileField: Field;\n  fileViewField: Field;\n\n  // Added (Phase 6): the backend's RepoResponse.FileMessage, passed down to <spa-attach>. Independent of\n  // apiResponse.success — the record can save while every attachment is rejected, and that combination used\n  // to be reported to the user as a plain \"Submitted\".\n  fileMessage = '';\n\n  // Added (Phase 6): THE PAIRING COUNTER. Bumped after a submit that carried files, and bound to the sibling\n  // <spa-document>'s refreshToken so the shelf reloads its names from the API with no page reload. A counter\n  // rather than a boolean because two uploads in a row must both fire, and a second `true` is not a change.\n  documentRefresh = 0;\n  @Input() files: any[] = [];\n  fields: Field[];\n  buttonDisplay = \"Submit\";\n  isProcessing: boolean = false;\n  multiColumn: boolean = false;\n\n  childFields: Field[];\n  manuallyToggledSections: Set<string> = new Set();\n\n  @Input() data: any;\n  @Input() config: FormConfig;\n  @Output() buttonClick = new EventEmitter();\n  @Output() inputChange = new EventEmitter();\n\n  private loadActionCache = new Map<Field, { url: string; action: any }>(); // TS-12: memoize resolved loadActions so a stable object reference is returned while the placeholder value is unchanged\n\n  // Changed: Resolve {placeholder} in loadAction URLs from form data — e.g. 'pigs/list/bypen-{fromPenID}' → 'pigs/list/bypen-5'\n  resolveLoadAction(field: Field): any {\n    if (!field.loadAction?.url || !field.loadAction.url.includes('{')) return field.loadAction;\n    // Changed (refetchOnChange): an unresolved token is now LEFT IN PLACE for a field that opts in, instead of being\n    // substituted with ''. Everything else keeps the '' substitution byte-for-byte — this branch is unreachable\n    // unless field.refetchOnChange is true, so no existing field's URL changes by one character.\n    // Why it is needed: 'pigs/list/bypen-{penID}' with no pen chosen became 'pigs/list/bypen-', a url that LOOKS\n    // complete and that the server answers 200 to with the whole unfiltered list. Keeping the brace gives the\n    // consuming control something it can recognise as not-yet-ready and decline to send (both spa-select-common and\n    // now spa-select-multi return early on a url containing '{'). An empty string is indistinguishable from a real id.\n    // '' is treated as unresolved alongside null/undefined: a placeholder field cleared back to blank is exactly as\n    // unready as one never set.\n    const resolvedUrl = field.loadAction.url.replace(/\\{(\\w+)\\}/g, (match, key) => {\n      const value = this.data?.[key];\n      if (value !== undefined && value !== null && value !== '') return String(value);\n      return field.refetchOnChange ? match : '';\n    });\n    // TS-12: return the cached object when the resolved URL hasn't changed — avoids a new object every CD (child ngOnChanges churn)\n    const cached = this.loadActionCache.get(field);\n    if (cached && cached.url === resolvedUrl) return cached.action;\n    const action = { ...field.loadAction, url: resolvedUrl };\n    this.loadActionCache.set(field, { url: resolvedUrl, action }); // TS-12: memo invalidated automatically when resolvedUrl (placeholder source) changes\n    return action;\n  }\n\n  initializeCompositeFields() {\n    // Changed: seed composite subfields on the CREATE path ONLY. This ran in every mode, so on an EDIT any\n    // subfield the projection did not return was FABRICATED here from Core.getInitialValue — checkbox -> false,\n    // number/money -> 0, text -> '' and date -> TODAY — before the user had touched anything. The key was then\n    // present on the posted body, the TinWeb present-set (e40be91) faithfully honoured it as a deliberate value,\n    // and the stored column was overwritten. Proved on ContactPerson 1 with only the Mobile retyped:\n    // CanCall/CanSMS/CanWhatsApp went 1/1/1 -> 0/0/0 on an HTTP 200 with no warning.\n    // Initialisation is not user intent. On CREATE absence genuinely means \"use the default\", which is why the\n    // seeding is kept there; on EDIT absence must stay absence. Same rule, same reason and the same wording as\n    // TableComponent.seedInlineDefaults (\"an unrendered field must never be silently seeded\") and the\n    // FormConfig.seedDefaults opt-in in Classes.ts — this extends an agreed policy, it does not invent one.\n    if (this.config?.mode !== 'create') return;\n\n    this.fields.forEach(field => {\n      if (field.type === 'composite' && field.subfields) {\n        field.subfields.forEach(subfield => {\n          if (this.data[subfield.name] === undefined) {\n            this.data[subfield.name] = Core.getInitialValue(subfield);\n          }\n        });\n      }\n    });\n  }\n\n\n  initializeSectionStates() {\n    if (!this.fields) return;\n    \n    this.fields.forEach(field => {\n      if (field.type !== 'section' || this.manuallyToggledSections.has(field.name)) return;\n\n      if (field.collapsedCondition) {\n        field.collapsed = field.collapsedCondition(this.data);\n      } else if (field.collapseOnView) {\n        // Added: mode-driven collapse — capture everything on create, then fold the secondary groups away so the\n        // dialog's tabs are visible without scrolling past fields nobody is reading\n        field.collapsed = this.config?.mode !== 'create';\n      }\n    });\n\n    // Added (lazy options): this runs again after a reload or a mode change, and can leave a section OPEN that\n    // was collapsed when the form initialised. Anything parked for a now-open section is due — no-op on the\n    // first call, where nothing has been deferred yet.\n    this.fields.forEach(field => {\n      if (field.type === 'section' && !field.collapsed) this.loadDeferredOptions(field.name);\n    });\n  }\n\n  private applyValueCalculations() {\n    if (!this.data || !this.fields) return;\n    \n    // Get visible fields that have valueCalculation functions\n    const calculatedFields = this.getVisibleFields()\n      .filter(field => typeof field.valueCalculation === 'function');\n    \n    if (calculatedFields.length === 0) return;\n    \n    // Apply calculations to each field\n    calculatedFields.forEach(field => {\n      try {\n        const calculatedValue = field.valueCalculation(this.data);\n        if (calculatedValue !== undefined) {\n          this.data[field.name] = calculatedValue;\n        }\n      } catch (error) {\n        console.error(`Error calculating value for field ${field.name}:`, error);\n      }\n    });\n  }\n\n  getVisibleSubfields(field : Field){ // Changed: now returns a cached, stable reference\n    let subfields = this.subfieldCache.get(field);\n    if (!subfields) {\n      subfields = Core.getVisibleSubfields(this.config, this.data, field, this.authService.currentRoleSource.value);\n      // Changed: after an invalidation the recompute usually yields the SAME subfields. Reuse the previous\n      // array in that case so this *ngFor's binding identity does not change for nothing — the same NG0100\n      // and needless-re-render source that refreshVisibleFields() guards against for the top-level fields.\n      const previous = this.previousSubfieldCache.get(field);\n      if (previous && this.sameFields(subfields, previous)) subfields = previous;\n      this.subfieldCache.set(field, subfields);\n    }\n    return subfields;\n  }\n\n\n  getVisibleFields() {\n    let visibleFields = this.fields?.filter(x => Core.testVisible(this.config, this.data, x, this.authService.currentRoleSource.value)) ?? [];\n\n    // Filter out fields under collapsed sections\n    return visibleFields.filter(field => {\n      if (field.type === 'section') return true;\n      if (field.section) {\n        const sectionField = this.fields.find(f => f.type === 'section' && f.name === field.section);\n        return !sectionField?.collapsed;\n      }\n      return true;\n    });\n  }\n\n  testReadOnly(field: Field): boolean {\n    return Core.testReadOnly(this.config, this.data, field);\n  }\n\n  testRequired(field: Field): boolean {\n    return Core.testRequired(this.config, this.data, field);\n  }\n\n  // Added (placeholder-passthrough-1): spa-form never bound [placeholder] to ANY field component, so a\n  // config-level `field.placeholder` was inert estate-wide — the only way to set one was on the instance,\n  // which is why field-placeholder-conventions.spec.ts assigns .placeholder directly. Every field component\n  // already declares an @Input placeholder and already resolves precedence through derivePlaceholder, so the\n  // whole defect was this one missing binding. Returning '' when absent is exactly the components' own\n  // default, which is what keeps BOTH existing behaviours intact: '' leaves derivePlaceholder to fall through\n  // to the DERIVED convention (\"Enter Name\"), and read-only suppression still wins over everything because it\n  // is checked first, inside derivePlaceholder — an explicit placeholder is blanked on a locked field too.\n  // Non-allocating (a property read and a constant), so it is safe to call from the template per the\n  // no-template-bound-allocating-getters rule, and it matches the testReadOnly(field) idiom used throughout.\n  // ⚠️ `placeholder` is not yet declared on the Field interface (Classes.ts is another chunk's file this\n  // session), hence the cast — the one-line `placeholder?: string` declaration lands with that commit and\n  // gives consumers type-checked config. Runtime behaviour here does not depend on it.\n  fieldPlaceholder(field: Field): string {\n    return (field as any)?.placeholder ?? '';\n  }\n\n  // Readonly resolver for composite subfields projected into the dynamic select template: the\n  // template calls testReadOnly(subfield) once, but composite members must also inherit the\n  // parent composite's readonly state (parity with the inline subfield types, which bind\n  // testReadOnly(field) || testReadOnly(subfield)).\n  compositeReadOnly(parent: Field) {\n    return (subfield: Field): boolean => this.testReadOnly(parent) || this.testReadOnly(subfield);\n  }\n\n  // Added (lazy options): fields whose option fetch was deferred because their section was collapsed on open\n  private deferredOptionFields: Field[] = [];\n\n  // Added (lazy options): true when this field lives under a section that is currently collapsed. Section state\n  // is decided by initializeSectionStates() before the load loops run, so this is answerable at ngOnInit.\n  private isCollapsedSectionField(field: Field): boolean {\n    if (!field?.section) return false;\n    const section = this.fields?.find(f => f.type === 'section' && f.name === field.section);\n    return !!section?.collapsed;\n  }\n\n  // Added (lazy options): flush the parked fetches for a section the moment it opens. Removed from the queue\n  // first, so a section toggled shut and open again does not re-fetch — fetch once, then behave normally.\n  private loadDeferredOptions(sectionName: string) {\n    if (!sectionName || this.deferredOptionFields.length === 0) return;\n    const due = this.deferredOptionFields.filter(f => f.section === sectionName);\n    if (due.length === 0) return;\n    this.deferredOptionFields = this.deferredOptionFields.filter(f => f.section !== sectionName);\n    due.forEach(f => this.loadChildMasterOptions(f));\n  }\n\n  toggleSection(field: Field) {\n    if (field.type === 'section') {\n      field.collapsed = !field.collapsed;\n      this.manuallyToggledSections.add(field.name);\n      if (!field.collapsed) this.loadDeferredOptions(field.name); // Added (lazy options): first expand is what pays for this section's option fetches\n      this.refreshVisibleFields(); // TS-11: collapse toggle changes which fields are visible — refresh cache\n    }\n  }\n\n  // Added: expand the section a field sits under, and re-show its fields — used when validation rejects a\n  // field the user cannot currently see. Public so the details dialog, which runs its own validation over this\n  // form's fields, can reveal through the component that owns the cached visible-field list.\n  revealSection(field: Field) {\n    if (!field) return;\n\n    // Changed: the section expansion below used to be the whole method, behind two early returns. Both are now\n    // scoped to the expansion only, because a rejected field that is ALREADY visible still needs the focus pass\n    // underneath — that was the silent-block case (a required field in an open section was rejected with no\n    // section to expand, so this method did nothing at all).\n    if (field.section) {\n      const section = this.fields?.find(f => f.type === 'section' && f.name === field.section);\n\n      if (section?.collapsed) {\n        section.collapsed = false;\n        this.manuallyToggledSections.add(section.name);\n        this.loadDeferredOptions(section.name); // Added (lazy options): a section revealed by failed validation must also get its parked option fetches\n        this.refreshVisibleFields();\n      }\n    }\n\n    this.focusInvalidField(field); // Added: always bring the rejected field to the user — see focusInvalidField\n  }\n\n  // Added: a blocked submit used to leave the offending control ng-untouched AND ng-pristine, so Material's own\n  // `*ngIf=\"control.invalid && (control.dirty || control.touched)\"` mat-error never rendered and the outline never\n  // turned red. The only feedback was a 5-second snackbar pinned to the bottom of the window, typically several\n  // hundred pixels from the field it names — once it auto-dismissed, nothing on screen said why save did nothing.\n  // Measured on piglet's inventory-return create form: required Reason rejected, no POST issued, field left\n  // \"ng-untouched ng-pristine ng-invalid\" with mat-error null.\n  //\n  // This drives the control through a REAL blur event rather than reaching into ~25 separate field components:\n  // every one of them binds [formControl], so Angular Forms' own blur handling marks the control touched, which is\n  // exactly the condition their mat-error already waits on. Deliberately additive — nothing that previously\n  // rendered stops rendering; the field is only scrolled into view and given focus.\n  private focusInvalidField(field: Field) {\n\n    // Deferred a tick: a section revealed above is not in the DOM until change detection has run.\n    setTimeout(() => {\n\n      const wrapper = this.hostRef?.nativeElement?.querySelector(`[data-field=\"${field.name}\"]`);\n      if (!wrapper) return;\n\n      const control = wrapper.querySelector('input, textarea, select, [role=\"combobox\"]') as HTMLElement | null;\n      if (!control) return;\n\n      wrapper.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n      // focus then blur then refocus: the blur is what marks the control touched so the error renders, the\n      // refocus leaves the caret in the field the toast is complaining about, ready to be typed into.\n      control.focus();\n      control.dispatchEvent(new Event('blur', { bubbles: false }));\n      control.focus();\n    });\n  }\n\n  hasSectionFields(sectionName: string): boolean {\n    return this.fields?.some(field =>\n      field.section === sectionName &&\n      Core.testVisible(this.config, this.data, field, this.authService.currentRoleSource.value)\n    ) ?? false;\n  }\n\n  shouldSectionCollapse(field: Field): boolean {\n\n    return field.collapsed ?? false;\n  }\n\n\n  onInfoClick(event: MouseEvent, infoMessage: string): void {\n    event.stopPropagation();\n    this.messageService.info(infoMessage);\n  }\n\n\n  selectChanged(field: Field){\n    this.inputChanged(field, this.data[field.name] )\n    \n    if (field.onSelectChange) {\n      // Changed: Find and pass the selected option as the third parameter\n      const selectedOption = field.options?.find(opt => opt[field.optionValue || 'value'] === this.data[field.name]);\n      field.onSelectChange(this.data[field.name], this.data, selectedOption, this.config); // Changed (addpig-label-leak): pass the LIVE config as a 4th arg, matching inputChanged below — a select that drives a sibling field's copy (a quantity that rewrites a price label) needs the object this form is actually rendering, not the app's singleton\n    }\n  }\n\n\n\n  inputChanged(field : Field, value){\n\n    this.inputChange.emit({ field: field, value: value})\n\n    this.updateChildOptions(field.name)\n\n\n    if (this.config.mode == 'create' && field.children){\n      field.children.forEach(childConfig => {\n        let child = this.fields.find(x => x.name == childConfig.childField)\n        this.data[child.name] = field.options.find(x => x[field.optionValue ?? 'value'] == value)[childConfig.childValueField]\n      });\n    }\n\n    this.applyValueCalculations();\n\n    // Added (TOTAL-FIRST): fire the field's own onChange. `onChange` has been DECLARED on Field\n    // (Classes.ts) all along but the form never called it — only title-actions did — so a form field\n    // that set it got silence, which is this codebase's recurring silent-failure shape. Selects already\n    // had a hook via selectChanged/onSelectChange; every other type (checkbox, money, number, date, text)\n    // had none, so nothing could react to them. That is why a label/hint cannot currently follow a\n    // checkbox or a money value. Additive and backwards-compatible: no existing form field sets\n    // onChange, so nothing that works today changes behaviour.\n    field.onChange?.(value, this.data, this.config); // Changed (addpig-label-leak): third arg is the LIVE FormConfig this form renders. Without it a handler could only reach its app service's SINGLETON config, and since 42d665c (20.14.82) deep-clones the config per dialog open, such a write never repainted the open dialog and then surfaced — wrong — on the next one. See Field.onChange in Classes.ts for the measurement\n\n    this.refreshVisibleFields(); // TS-11: input value may toggle field visibility / section collapse — refresh cache\n  }\n\n  updateChildOptions(masterFieldName: string){\n\n    let children = this.childFields.filter(x => x.masterField == masterFieldName)\n\n    if (children != null) {\n\n      //current is master\n      let masterField = this.fields.find(x => x.name == masterFieldName)\n\n      if (!masterField || !masterField.options) return;\n\n      let masterOption = masterField.options?.find(x => x[masterField.optionValue ?? 'value'] == this.data[masterFieldName])\n\n      // TS-21: removed per-interaction console.log(\"masterOption\", ...)\n\n      children.forEach(child => {\n\n        if (child.masterOptions){\n\n          if (child.masterValueField) {\n            \n            if (masterOption) {\n              child.options = child.masterOptions?.filter(x => x[child.masterOptionValue ?? 'masterValue'] == masterOption[child.masterValueField]);\n\n              if (child.masterDefaultValueField && !this.data[child.name]) {\n                \n                this.data[child.name] = masterOption[child.masterDefaultValueField];\n              }\n            }\n            \n          }else{\n            child.options = child.masterOptions?.filter(x => x[child.masterOptionValue ?? 'masterValue'] == this.data[masterFieldName])\n          }\n        }\n      });\n\n    }\n  }\n\n  private loadChildMasterOptions(child: Field) {\n    if (!child.loadAction) return;\n\n    // Added (lazy options): a field sitting under a COLLAPSED section is filtered out of visibleFields, so it is\n    // not rendered and nothing on screen can show its options or its selected label. Fetching them as the dialog\n    // opens spends one request per hidden select on information the user has not asked for. Park the field and\n    // fetch on the FIRST expand (toggleSection / revealSection), once — after that it behaves exactly as before.\n    if (this.isCollapsedSectionField(child)) {\n      if (!this.deferredOptionFields.includes(child)) this.deferredOptionFields.push(child);\n      return;\n    }\n\n    // Changed: skip a URL that still holds an unresolved {placeholder}. ngOnInit calls this for EVERY field\n    // carrying a loadAction, so a dependent field like the load form's Customer PO picker\n    // ('customerpurchaseorders/open/{customerID}') was requested with the literal placeholder before any\n    // customer had been chosen - a 400 that popped an error dialog over the form as it opened.\n    // NOTE worth revisiting separately: this runs for every field, not only master/child ones, so every\n    // select is fetched twice on open - once here and once by the select itself.\n    if (child.loadAction.url?.includes('{')) return;\n\n    this.dataService.CallApi(child.loadAction).subscribe({\n      next: (apiResponse: ApiResponse) => {\n      if (apiResponse.success) {\n\n        if (child.masterField) child.optionsUnavailableOffline = false; // Added (WS-1): a later successful load clears the notice. For a dependent select that means the next time this form is built on a live connection — see markChildOptionsUnavailable for why the field's own refresh icon cannot do it\n        child.masterOptions = apiResponse.data;\n        this.updateChildOptions(child.masterField);\n      } else if (this.isOfflineCacheMiss()) {\n        this.markChildOptionsUnavailable(child); // Added (WS-1): the offline read seam answers a cache miss with HTTP-200 success:false — before this, that returned early and left the dropdown empty and silent\n      }\n      },\n      // Added (WS-1): the OTHER offline shape — a lookup url the registry never matched never reaches the read\n      // seam, it goes to the wire and dies as status 0. There was NO error callback here at all, so both failure\n      // shapes vanished. Non-network errors keep their previous behaviour to the letter: logged, and no further.\n      error: (err: any) => {\n        if (err?.status === 0) { this.markChildOptionsUnavailable(child); return; }\n        console.error('[tin-spa] form child option load failed', { url: child.loadAction?.url, err });\n      }\n    });\n  }\n\n  // Added (WS-1): a cache miss served by the offline layer arrives as HTTP-200 success:false with a network we\n  // know is down. Both halves are required — `online === false` alone would claim any 200-level failure was an\n  // offline one. Same test select-common makes; kept identical on purpose.\n  private isOfflineCacheMiss(): boolean {\n    return !!this.offline && this.offline.enabled && !this.offline.online;\n  }\n\n  // Added (WS-1): mark the FIELD, because this component cannot reach the control that must show the state.\n  // 🔴 Scoped to masterField children ON PURPOSE. loadChildMasterOptions runs for EVERY field carrying a\n  // loadAction, but only a master/child dependent select is unable to speak for itself: select-common.getData\n  // and text-single.getData both early-return when masterField is set, making THIS the sole fetch for those\n  // fields. Every other field's own control already handles all three outcomes, so marking here would duplicate\n  // a notice the control is about to draw anyway — and could strand one, since the control clears only its own\n  // copy of the flag.\n  // ⚠️ Known limitation, pre-existing and NOT introduced here: the field's refresh icon calls getData, which\n  // early-returns for a masterField select, so a dependent select recovers when the form is next built with a\n  // connection (reopen the dialog), not from the icon.\n  private markChildOptionsUnavailable(child: Field) {\n    if (!child.masterField) return;\n    child.optionsUnavailableOffline = true;\n  }\n\n\n  buttonClicked(){\n\n    this.buttonClick.emit(this.data);\n\n    let button = this.config.button;\n\n    if (!button) {\n      return;\n    }\n\n    //validation\n    // Changed: validate every visible field (collapsed sections included) and open the section holding the\n    // offending one, so the toast never names a field the user cannot see\n    let resp = Core.validateObject(this.fields?.filter(x => Core.testVisible(this.config, this.data, x, this.authService.currentRoleSource.value)) ?? [], this.data, field => this.revealSection(field));\n    if (resp != ''){\n      this.messageService.toast(resp)\n      return;\n    }\n\n\n\n    if (this.files.length < 1 && this.fileField?.required && this.config.mode =='create') {\n      this.messageService.toast(\"Please attach file(s)\");\n      return;\n    }\n\n\n    if (button.confirm){\n\n      // Changed: passes the config's explicit labels and destructive flag straight through. Deliberately NOT\n      // routed via buttonService.getConfirmOptions — this component does not inject ButtonService and a form\n      // button never carries the built-in 'delete' name, so there is nothing here for the app-level flag to\n      // infer. An explicit label in the config is honoured; anything absent still renders \"Yes\" / \"No\".\n      this.messageService.confirm(`${button.confirm.message}`, button.confirm.confirmLabel, button.confirm.cancelLabel, button.confirm.destructive === true).subscribe((result) => {\n        if (result == \"yes\") {\n          this.processCall(button)\n        }\n      });\n\n    }else{\n      this.processCall(button)\n    }\n\n\n\n\n  }\n\n  processCall(button: Button){\n\n    if (!button.action) return\n\n    let dataOut;\n\n    // Added (C60): a value the user entered while a field was VISIBLE was still posted after a predicate hid it.\n    // The payload is now a COPY of this.data with predicate-hidden keys omitted — this.data itself is untouched,\n    // so re-showing the field restores the typed value. Shared with detailsDialog's submit path, which had the\n    // same defect. Full rationale on Core.buildSubmitPayload.\n    const outgoing = Core.buildSubmitPayload(this.config, this.data);\n\n    if (button.action.isFormData){\n\n      let formData: FormData = new FormData();\n      for (let i = 0; i < this.files.length; i++) {\n        formData.append(`uploadFile${i}`, this.files[i], this.files[i].name);\n      }\n\n      formData.append(\"data\", JSON.stringify(outgoing)); // Changed (C60): was this.data — the multipart path posted the same stale hidden values\n\n\n      dataOut = formData\n    }else{\n\n      dataOut = outgoing // Changed (C60): was this.data\n    }\n\n\n\n\n    // Added (Phase 6): captured BEFORE the call, because the reset branch below empties this.files on success\n    // and the sibling shelf still needs to know an upload happened.\n    const sentFileNames = this.files.map(file => file?.name).filter(name => !!name);\n\n    this.isProcessing = true\n    this.dataService.CallApi(button.action, dataOut).subscribe((apiResponse) => {\n      this.isProcessing = false\n\n      // Added (Phase 6): surface the file outcome REGARDLESS of apiResponse.success, and before the success\n      // branch's toast. HandleSaveFiles reports here and only here; a rejected attachment on an otherwise\n      // successful save was previously invisible.\n      this.fileMessage = apiResponse.fileMessage ?? '';\n      if (this.fileMessage) {\n        this.messageService.toast(this.fileMessage);\n      }\n\n      if (apiResponse.success) {\n\n        // Added (Phase 6): the upload landed, so tell the paired <spa-document> to re-read its list from the\n        // API. Re-reading rather than appending sentFileNames locally is deliberate — the server renames on\n        // collision, so an appended name can be a name that does not exist on disk.\n        if (sentFileNames.length > 0) {\n          this.documentRefresh++;\n        }\n\n\n        // Added: optimistic-concurrency — adopt the refreshed token so a form left open can save again without a stale-write false conflict\n        if (apiResponse.rowVersion && this.data) this.data.rowVersion = apiResponse.rowVersion;\n\n        if (button.action.successMessage) {\n          this.messageService.toast(button.action.successMessage);\n        } else {\n          this.messageService.toast(\"Submitted\");\n        }\n\n        if (this.config.reset) {\n          Core.resetObject(this.fields, this.data)\n          this.files = [];\n          this.manuallyToggledSections.clear();\n          this.initializeSectionStates();\n          this.applyValueCalculations();\n          this.refreshVisibleFields(); // TS-11: post-reset state change — refresh cached visible fields\n        }\n\n\n      } else if (apiResponse.reason === 'conflict' && apiResponse.data) {\n        // Added: optimistic-concurrency (IConcurrency) — patch the fresh server row (incl. new rowVersion) into the bound model in place so the user re-applies changes on current data\n        Object.assign(this.data, apiResponse.data);\n        this.applyValueCalculations();\n        this.refreshVisibleFields();\n        this.messageService.toast(`${apiResponse.message} — the latest version has been loaded, please review and re-apply your changes`);\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'submit', button.action?.url); // Changed: form submit — the form keeps its values on failure, so an unnoticed toast invites a second submit\n      }\n    });\n  }\n\n  processForm(){\n\n\n\n\n\n  }\n\n}\n\n\n","\n\n\n<!-- Changed (owner, 2026-08-20): tin-form-unsectioned marks a form whose FIRST visible field is not a\n     section header. Yesterday's dialog spacing (.dialog-scroll-content padding-top:8px, table.component.css)\n     was tuned for the SECTIONED shape, where the section's own 0.5em (8.4px) margin-top adds the rest of the\n     headroom. A form with no leading section has no such margin, so its first field's FLOATING LABEL — which\n     rides on the outline's top border — came up almost against the dialog title bar (his Add Breed screenshot).\n     A bound class rather than :has(), matching roles.component.css:116 (\"so the rule does not depend on\n     selector support\"). Non-allocating expression: an index and a compare on the already-cached visibleFields,\n     so it is safe in a template per the no-allocating-getters rule. The class is only ACTED ON inside a\n     dialog (see table.component.css) — page-hosted forms are unaffected. -->\n<div class=\"tin-form-container\" [class.tin-form-unsectioned]=\"visibleFields?.length && visibleFields[0].type !== 'section'\">\n  <div [ngClass]=\"[multiColumn ? 'tin-grid' : 'tin-col', config.notesConfig ? 'width-75' : 'width-100']\" class=\"form-main-content\">\n\n    <div *ngIf=\"!hasAccess\" class=\"tin-center\">\n      <p><em>Access Restricted</em></p>\n    </div>\n  \n    <div [attr.data-field]=\"field.name\" [ngClass]=\"field.span || field.type =='section' || field.type =='file' || field.type =='file-view' || field.type =='editor'  ? 'span-col' : ''\" *ngFor=\"let field of visibleFields\"><!-- TS-11: bind cached visibleFields instead of getVisibleFields() per CD --><!-- Changed: data-field lets a blocked submit locate the offending field's control (see focusInvalidField) — a rejected required field was previously left ng-untouched, so Material drew no error and the only feedback was a 5s snackbar 400px away -->\n  \n      <ng-container>\n  \n        <ng-container [ngSwitch]=\"field.type\" class=\"highlight\">\n  \n          <!-- Changed (owner, 2026-08-19): the section header adopts the estate's ONE disclosure marker.\n               It used to swap two glyphs at the FAR RIGHT — expand_more/expand_less — which is the pattern the\n               .tin-disc block in tin-styles.css was written to replace (\"ONE glyph, rotated — never two glyphs\n               swapped. A swap cannot animate\"). The owner reported it as no longer matching the Day Book,\n               Getting Started and roles surfaces, and he is right: all three of those, plus spa-table's section\n               header and spa-checklist, already render <span class=\"tin-disc\"><mat-icon>chevron_right</mat-icon>\n               rotated 90deg when open, with the marker LEADING on the left where reading starts. This form\n               section was one of the last three holdouts (the others are tenant-settings and app-configuration).\n               The row keeps its <div> rather than becoming the <button> the tin-disc usage note shows, on\n               purpose: `.tin-grid button { width: 50% }` in tin-styles.css would halve a header inside a form\n               grid. role/tabindex/aria-expanded plus the keydown handlers give it the same keyboard and screen\n               reader behaviour without inheriting that rule. -->\n          <div *ngSwitchCase=\"'section'\" class=\"title tin-disc-row d-flex align-items-center\" (click)=\"toggleSection(field)\" (keydown.enter)=\"toggleSection(field)\" (keydown.space)=\"toggleSection(field)\" [attr.role]=\"hasSectionFields(field.name) ? 'button' : null\" [attr.tabindex]=\"hasSectionFields(field.name) ? 0 : null\" [attr.aria-expanded]=\"hasSectionFields(field.name) ? !shouldSectionCollapse(field) : null\" style=\"cursor: pointer;\">\n            <span class=\"tin-disc\" *ngIf=\"hasSectionFields(field.name)\" [class.open]=\"!shouldSectionCollapse(field)\"><mat-icon>chevron_right</mat-icon></span>\n            <label class=\"section-name\">{{field.alias ?? field.name | camelToWords}}</label>\n            <mat-icon *ngIf=\"field.infoMessage\" (click)=\"onInfoClick($event, field.infoMessage)\" style=\"color: steelblue; font-size: 14px;\">info</mat-icon>\n          </div>\n  \n          <ng-container *ngSwitchCase=\"'file'\">\n            <div class=\"mt-1 mb-2\" *ngIf=\"config.mode !='view'\">\n              <spa-attach [message]=\"field.alias ?? 'Drag and Drop files here'\" [(files)]=\"files\" [fileOptions]=\"field.fileOptions\" [fileMessage]=\"fileMessage\"></spa-attach>\n            </div>\n          </ng-container>\n  \n          <ng-container *ngSwitchCase=\"'file-view'\">\n            <div class=\"mt-1 mb-2\" *ngIf=\"config.mode && config.mode !='create'\">\n              <!-- Changed (Phase 7): the `else legacyFileView` fallback to <spa-viewer> is DELETED, together with\n                   spa-viewer, viewerDialog and DialogService.openViewerDialog(). file-view now renders only the\n                   new <spa-document>, whose bytes come from the app's OWN authorized stream. A field with no\n                   documentSource renders nothing — that is a BREAKING change for any consumer still declaring\n                   path/loadAction, and it is documented in the release note. Arbiter ruling 2026-08-19. -->\n              <spa-document *ngIf=\"field.documentSource\" [documentSource]=\"field.documentSource\" [keyValue]=\"data[field.keyField]\" [title]=\"field.alias ?? 'Documents'\" [refreshToken]=\"documentRefresh\"></spa-document>\n            </div>\n          </ng-container>\n  \n          <spa-html *ngSwitchCase=\"'html'\" [display]=\"field.alias | camelToWords\" [value]=\"data[field.name]\" [maxHeight]=\"field.maxHeight\"></spa-html>\n  \n          <label *ngSwitchCase=\"'blank'\"></label>\n  \n          <label *ngSwitchCase=\"'string'\" [ngStyle]=\"{'font-size':field.size ?? '14px'}\" >{{data[field.name] ?? field.alias ?? field.name}} {{field.suffix ?? ''}}</label>\n  \n          <spa-label *ngSwitchCase=\"'label'\" [display]=\"field.alias ?? field.name | camelToWords\" [value]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [format]=\"field.format ?? 'text'\" [suffix]=\"field.suffix\" [size]=\"field.size\"></spa-label>\n  \n          <spa-number *ngSwitchCase=\"'number'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"testRequired(field)\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-number>\n  \n          <spa-money *ngSwitchCase=\"'money'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"testRequired(field)\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-money>\n  \n          <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [readonly]=\"testReadOnly(field)\" [infoMessage]=\"field.infoMessage\" [hint]=\"field.hint\" ></spa-check><!-- Changed: field.hint was dropped on the floor for checkboxes only — every other type already passed it through -->\n  \n          <spa-date *ngSwitchCase=\"'date'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [min]=\"field?.min\" [max]=\"field?.max\" [boundContext]=\"data\" [required]=\"testRequired(field)\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-date><!-- Changed: [suffix]/[copyContent]/[clearContent] were never bound, so field.clearContent was inert on every date in the estate — the spa-money and spa-email lines above already pass all three --><!-- Changed (SBD-1): [boundContext]=\"data\" lets a field declare `min`/`max` as a FUNCTION of the row, so a date window that depends on a sibling field (stage, contract start, ...) re-evaluates at picker-open instead of being written once -->\n  \n          <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"testRequired(field)\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [min]=\"field.min\" [max]=\"field.max\" [boundContext]=\"data\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-datetime><!-- Changed: same omission as spa-date above — field.clearContent never reached the control -->\n  \n          <spa-email *ngSwitchCase=\"'email'\" [display]=\"field.alias ?? field.name | camelToWords\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [readonly]=\"testReadOnly(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\"  [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\"></spa-email>\n  \n          <spa-text-mask *ngSwitchCase=\"'text-mask'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\"></spa-text-mask>\n  \n  \n          <ng-container *ngSwitchCase=\"'select'\">\n            <ng-container *ngTemplateOutlet=\"selectTemplate; context: {\n                    $implicit: field,\n                    field: field,\n                    data: data,\n                    testReadOnly: testReadOnly.bind(this),\n                    testRequired: testRequired.bind(this),\n                    selectChanged: selectChanged.bind(this),\n                    resolveLoadAction: resolveLoadAction.bind(this)\n                  }\">\n            </ng-container>\n          </ng-container>\n  \n  \n          <spa-select-multi *ngSwitchCase=\"'select-multi'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field, data[field.name])\" [required]=\"testRequired(field)\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\" [loadAction]=\"resolveLoadAction(field)\" [selectAll]=\"field.selectAll\" [refetchOnChange]=\"field.refetchOnChange\">\n          </spa-select-multi>\n  \n          <spa-text-multi *ngSwitchCase=\"'text-multi'\" [strict]=\"field.strict\" [display]=\"field.alias ?? field.name | camelToWords\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\" [loadAction]=\"resolveLoadAction(field)\"></spa-text-multi>\n  \n  \n  \n          <ng-container *ngSwitchCase=\"'composite'\">\n            <div class=\"composite-field-container\">\n              <div class=\"composite-field-group\">\n                <ng-container *ngFor=\"let subfield of getVisibleSubfields(field)\">\n                  <ng-container [ngSwitch]=\"subfield.type\">\n  \n                    <label *ngSwitchCase=\"'string'\" [ngStyle]=\"{'font-size':field.size ?? '14px'}\" >{{data[field.name] ?? field.alias ?? field.name}} {{field.suffix ?? ''}}</label>\n                    \n                    <spa-number *ngSwitchCase=\"'number'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\"  [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\"></spa-number>\n  \n                    <spa-money *ngSwitchCase=\"'money'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\"></spa-money><!-- Changed: passed the PARENT composite's copyContent/clearContent, unlike every sibling subfield case here. A money subfield could never get its own clear affordance, and a parent that set the flag handed one to every money subfield at once. -->\n  \n                    <spa-check *ngSwitchCase=\"'checkbox'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [infoMessage]=\"subfield.infoMessage\" [hint]=\"subfield.hint\" ></spa-check><!-- Changed: same hint pass-through as the top-level checkbox above -->\n  \n                    <spa-date *ngSwitchCase=\"'date'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [boundContext]=\"data\" [required]=\"testRequired(subfield)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\"></spa-date><!-- Changed: composite subfield had the same omission as the top-level spa-date -->\n  \n                    <spa-datetime *ngSwitchCase=\"'datetime'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [boundContext]=\"data\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\"></spa-datetime><!-- Changed: composite subfield had the same omission as the top-level spa-datetime -->\n  \n                    <!-- Fixed: composite select subfields projected the PARENT composite field into the\n                         dynamic select template (wrong options/value binding) and omitted testRequired,\n                         so the template's testRequired(field) call threw and killed the whole dialog.\n                         Context now mirrors the top-level select outlet, with the SUBFIELD, and readonly\n                         cascades composite parent || subfield like every other subfield type. -->\n                    <ng-container *ngSwitchCase=\"'select'\">\n                      <ng-container *ngTemplateOutlet=\"selectTemplate; context: {\n                                      $implicit: subfield,\n                                      field: subfield,\n                                      data: data,\n                                      testReadOnly: compositeReadOnly(field),\n                                      testRequired: testRequired.bind(this),\n                                      selectChanged: selectChanged.bind(this),\n                                      resolveLoadAction: resolveLoadAction.bind(this)\n                                    }\">\n                      </ng-container>\n                    </ng-container>\n  \n                    <spa-text-single *ngSwitchCase=\"'text-single'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [options]=\"subfield.options\" [optionDisplay]=\"subfield.optionDisplay ?? 'name'\" [optionValue]=\"subfield.optionValue ?? 'value'\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\" [loadAction]=\"resolveLoadAction(subfield)\" [regex]=\"subfield.regex\" [field]=\"subfield\" [data]=\"data\" [detailsConfig]=\"subfield.detailsConfig\" [masterField]=\"subfield.masterField\"></spa-text-single>\n\n                    <spa-text-area *ngSwitchCase=\"'text-area'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [rows]=\"subfield.rows\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\" [regex]=\"subfield.regex\"></spa-text-area>\n\n                    <!-- Added (email-single): same control and same contract as the top-level case below, so a single email address behaves identically inside a composite -->\n                    <spa-text *ngSwitchCase=\"'email-single'\" type=\"email\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\" [regex]=\"subfield.regex ?? emailSingleRegex\"></spa-text>\n\n                    <spa-editor *ngSwitchCase=\"'editor'\" [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [editorConfig]=\"subfield.editorConfig\"></spa-editor>\n\n                    <spa-text *ngSwitchDefault [display]=\"subfield.alias ?? subfield.name | camelToWords\" [width]=\"subfield.width\" [(value)]=\"data[subfield.name]\" (valueChange)=\"inputChanged(subfield, $event)\" [required]=\"testRequired(subfield)\" [min]=\"subfield.min\" [max]=\"subfield.max\" [readonly]=\"testReadOnly(field) || testReadOnly(subfield)\" [placeholder]=\"fieldPlaceholder(subfield)\" [hint]=\"subfield.hint\" [infoMessage]=\"subfield.infoMessage\" [suffix]=\"subfield.suffix\" [copyContent]=\"subfield.copyContent\" [clearContent]=\"subfield.clearContent\" [regex]=\"subfield.regex\"></spa-text>\n  \n  \n                  </ng-container>\n                </ng-container>\n              </div>\n            </div>\n          </ng-container>\n  \n  \n          <spa-text-single *ngSwitchCase=\"'text-single'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [options]=\"field.options\" [optionDisplay]=\"field.optionDisplay ?? 'name'\" [optionValue]=\"field.optionValue ?? 'value'\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\" [loadAction]=\"resolveLoadAction(field)\" [regex]=\"field.regex\" [field]=\"field\" [data]=\"data\" [detailsConfig]=\"field.detailsConfig\" [masterField]=\"field.masterField\"></spa-text-single>\n\n          <spa-text-area *ngSwitchCase=\"'text-area'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [rows]=\"field.rows\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\" [regex]=\"field.regex\"></spa-text-area>\n\n          <spa-editor *ngSwitchCase=\"'editor'\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [editorConfig]=\"field.editorConfig\"></spa-editor>\n\n          <!-- Added (email-single): a SINGLE email address. Deliberately the same spa-text the default branch renders — a single address is an ordinary text box and every text affordance (placeholder, suffix, copy/clear, hint, mat-error) must behave identically — with the anchored email pattern supplied for free. A field's own `regex` still wins, so an app with a stricter corporate-domain rule keeps it. Distinct from 'email' above, which is the multi-address chip grid. -->\n          <spa-text *ngSwitchCase=\"'email-single'\" type=\"email\" [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\" [regex]=\"field.regex ?? emailSingleRegex\"></spa-text>\n\n          <spa-text *ngSwitchDefault [display]=\"field.alias ?? field.name | camelToWords\" [width]=\"field.width\" [(value)]=\"data[field.name]\" (valueChange)=\"inputChanged(field,data[field.name])\" [required]=\"testRequired(field)\" [min]=\"field.min\" [max]=\"field.max\" [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\" [hint]=\"field.hint\" [infoMessage]=\"field.infoMessage\" [suffix]=\"field.suffix\" [copyContent]=\"field.copyContent\" [clearContent]=\"field.clearContent\" [regex]=\"field.regex\"></spa-text>\n  \n        </ng-container>\n  \n      </ng-container>\n  \n    </div>\n  \n  \n    <div class=\"span-col-center\" *ngIf=\"config.button\">\n      <button mat-raised-button color=\"primary\"  (click)=\"buttonClicked()\"  cdkFocusInitial>{{buttonDisplay}}</button>\n    </div>\n  \n  \n  </div>\n  <!-- Fixed: built-in fallback select template — spa-form used consumers' projected #dynamicSelect\n       (only detailsDialog provides one), so selects silently rendered NOTHING when spa-form was used\n       directly. The projected template (if any) still wins; this default carries the same bindings. -->\n  <ng-template #defaultDynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\" let-resolveLoadAction=\"resolveLoadAction\">\n    <spa-select\n      [display]=\"field.alias ?? field.name | camelToWords\"\n      [width]=\"field.width\"\n      [nullable]=\"field.nullable\"\n      [options]=\"field.options\"\n      [masterOptions]=\"field.masterOptions\"\n      [masterField]=\"field.masterField\"\n      [optionDisplay]=\"field.optionDisplay ?? 'name'\"\n      [optionValue]=\"field.optionValue ?? 'value'\"\n      [(value)]=\"data[field.name]\"\n      [defaultFirstValue]=\"field.defaultFirstValue\"\n      [required]=\"testRequired(field)\"\n      [readonly]=\"testReadOnly(field)\" [placeholder]=\"fieldPlaceholder(field)\"\n      [hint]=\"field.hint\"\n      [detailsConfig]=\"field.detailsConfig\"\n      [loadAction]=\"resolveLoadAction(field)\"\n      [loadIDField]=\"field.loadIDField\"\n      [field]=\"field\"\n      [data]=\"data\"\n      [infoMessage]=\"field.infoMessage\"\n      [copyContent]=\"field.copyContent\"\n      (valueChange)=\"selectChanged(field)\"\n    ></spa-select>\n  </ng-template>\n\n  <div class=\"notes-section\" *ngIf=\"config.notesConfig\">\n    <spa-notes\n      [title]=\"config.notesConfig.title || 'Notes'\"\n      [notes]=\"config.notesConfig.notes || []\"\n      [loadAction]=\"config.notesConfig.loadAction\"\n      [loadIDField]=\"config.notesConfig.loadIDField\"\n      [data]=\"data\"\n      [nameField]=\"config.notesConfig.nameField || 'createdByName'\"\n      [dateField]=\"config.notesConfig.dateField || 'createdDate'\"\n      [commentField]=\"config.notesConfig.commentField || 'details'\">\n    </spa-notes>\n  </div>\n</div>\n\n","import { Component, OnInit, inject } from '@angular/core';\nimport { Router } from '@angular/router'; // Added (v3): the \"modules live in Getting Started\" pointer\nimport { ApiResponse, AppConfigSection, AppConfigurationConfig, Field, FormConfig, RoleAccess } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\nimport { ConfigService } from '../../services/config.service'; // Added: the shared app-wide config copy, refreshed on save\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: a failed config read showed an empty page and a failed save toasted raw server text (WS-6 Phase 4)\nimport { ButtonService } from '../../services/button.service'; // Added (N22): the capability gate and the confirm resolver for the reset, reused rather than re-derived\n\n// Added: spa-app-configuration — the one settings page for every app. Replaces the retired spa-preferences\n// (library) and the four hand-written per-app configuration components, which had drifted into four different\n// levels of maturity over the same entity. The library owns the behaviour; the app supplies only\n// appConfig.appConfigurationConfig. An app that registers nothing still gets the library base sections, so\n// Pulse has a working App Configuration page with zero frontend code.\n//\n// Design decisions carried over from the forks: one mat-card per section (Day Book card language), the module\n// switch lives IN the card header and greys its children rather than hiding them (Grip's pattern — a disabled\n// module's settings stay visible so you can see what turning it on would give you), and there is exactly one\n// Save for the whole page (Shift's page had the save split per area and drifted out of sync).\n@Component({\n  selector: 'spa-app-configuration',\n  templateUrl: './app-configuration.component.html',\n  styleUrls: ['./app-configuration.component.css'],\n  standalone: false\n})\nexport class AppConfigurationComponent implements OnInit {\n  dataService = inject(DataServiceLib);\n  private messageService = inject(MessageService);\n  private authService = inject(AuthService);\n  private configService = inject(ConfigService);\n  private apiErrorService = inject(ApiErrorService); // Added: the load and the save both needed a real failure surface\n  private router = inject(Router); // Added (v3)\n  private buttonService = inject(ButtonService); // Added (N22)\n\n  // Added (v3): module toggles moved out of this page and into the Getting Started picker, which is the only\n  // writer that also enforces the capability, marks the selection confirmed and refreshes the setup badge.\n  goToModules() {\n    this.router.navigate(['/home/setup']);\n  }\n\n  configuration: any = {};\n  loading = false;\n  saving = false;\n  canEdit = true;\n  resetting = false; // Added (N22): the reset is a long tenant-wide sweep — the button must not be pressable twice\n  // Added (N22): materialized in ngOnInit exactly like canEdit, never a template-bound getter. hasCapability reads\n  // the role off a BehaviorSubject on every call, and a getter bound in the template would re-run it on every\n  // change-detection pass for the life of the page.\n  canReset = false;\n\n  // Added: the page's own record that the last save was REFUSED. Without it the only evidence was the 5s toast\n  // (a business refusal) or a dialog the user dismisses (a technical failure) — after either one vanished, an\n  // unsaved page looked exactly like a saved one while still displaying the value the server rejected. Held\n  // until a save actually succeeds, NOT cleared on edit: editing does not make the shown values in force.\n  saveFailure: { reason: string, technical: boolean } | null = null;\n\n  // Materialized, never a template-bound getter — a getter returning a new array here would hand the\n  // *ngFor a fresh reference on every change-detection pass (see the day-book/table livelock).\n  cards: { section: AppConfigSection, form: FormConfig, collapsed: boolean }[] = [];\n  visibleCards: { section: AppConfigSection, form: FormConfig, collapsed: boolean }[] = [];\n\n  get config(): AppConfigurationConfig | undefined {\n    return this.dataService.appConfig?.appConfigurationConfig;\n  }\n\n  get title(): string {\n    return this.config?.title || 'App Configuration';\n  }\n\n  get sections(): AppConfigSection[] {\n    return this.config?.sections?.length ? this.config.sections : this.dataService.configBaseSections;\n  }\n\n  ngOnInit(): void {\n    // Save is gated on the app's config capability the same way the backend gates configuration/update;\n    // reads stay open because the module flags drive nav gating and the Day Book for every role.\n    this.canEdit = Core.getFormAccess({ security: this.config?.security } as FormConfig, this.authService.currentRoleSource.value) >= RoleAccess.Edit;\n    // Added (N22): cap92 at Full, resolved through the same gate every other capability-conditioned button uses.\n    // Deliberately INDEPENDENT of canEdit: editing the configuration row and emptying the organisation are\n    // different powers, which is the whole reason the reset stopped sharing the App Configuration edit capability.\n    this.canReset = this.buttonService.hasCapability(this.dataService.resetTenantButton);\n    this.load();\n  }\n\n  load(): void {\n    if (this.loading) return;\n    this.loading = true;\n    this.dataService.CallApi(this.config?.loadAction || { url: 'configuration/get' }).subscribe({\n      next: (response: ApiResponse) => {\n        this.loading = false;\n        if (!response.success) { this.apiErrorService.presentAppFailure(response, 'load', (this.config?.loadAction || { url: 'configuration/get' }).url); return; } // Changed: was a bare `return`, so buildCards() never ran and the page rendered its heading over nothing at all — the emptiest possible screen with no statement of why\n        this.configuration = response.data || {}; // the backend creates the row on first read, so this is never empty in practice\n        this.buildCards();\n      },\n      error: () => this.loading = false\n    });\n  }\n\n  //---------- Cards ----------\n\n  // Each section becomes a small FormConfig. mode is 'edit' deliberately: Core.testReadOnly short-circuits\n  // to false in 'create' mode, which would defeat both the toggle cascade and the no-edit-access lockout.\n  private buildCards(): void {\n    this.cards = this.sections.map(section => ({\n      section,\n      form: { fields: this.fieldsFor(section), mode: 'edit', multiColumn: true } as FormConfig,\n      collapsed: !!section.collapsed\n    }));\n    this.seedDefaults(); // Changed: seed before buildVisibleCards() so a section's hidden/visible predicate reads the seeded value, not the blank it replaced\n    this.buildVisibleCards();\n  }\n\n  // Added: apply each field's defaultValue to a setting the server has never stored. This page loads the row and\n  // renders it as mode:'edit', and NOTHING on that path has ever called Core.getInitialValue — generateObject and\n  // resetObject run on create/reset, form.component.initializeCompositeFields early-returns unless mode==='create',\n  // and detailsDialog.seedFormDefaults is for dialogs. So every defaultValue declared on an App Configuration field\n  // was silently inert, and a column the server had never filled rendered BLANK while the backend was quietly\n  // working to a default of its own (AppConfigurationControllerBase.cs:49 stamps 1 January, but only when it\n  // CREATES the row — an existing row left NULL is never backfilled). The user could not see the value in force.\n  // Deliberately NOT opt-in, unlike detailsConfig.seedDefaults: that flag exists because the library cannot tell a\n  // true-edit dialog from a capture form. There is no such ambiguity here — this is one known page over one\n  // singleton row of settings where \"unset\" is a state the server already resolves to a default, and the page has\n  // a single Save with the value on screen in front of the user before they press it.\n  // The two guards are the precedent's, unchanged in meaning:\n  //   1. seed ONLY an empty value, so anything the row already holds is never overwritten. Tested against\n  //      undefined/null/'' specifically, so a stored false or 0 counts as PRESENT and survives;\n  //   2. seed ONLY a field that passes testVisible, because an unrendered field must never be silently seeded —\n  //      nobody can see or correct what it was seeded with.\n  private seedDefaults(): void {\n    if (!this.configuration) return;\n\n    const currentRole = this.authService.currentRoleSource.value;\n\n    for (const card of this.cards) {\n      for (const field of card.form.fields || []) {\n        if (field.type === 'section' || field.type === 'blank') continue; // matches generateObject — these carry no value\n        if (field.defaultValue === undefined || field.defaultValue === null) continue;\n\n        const current = this.configuration[field.name];\n        if (current !== undefined && current !== null && current !== '') continue;\n\n        if (!Core.testVisible(card.form, this.configuration, field, currentRole)) continue;\n\n        this.configuration[field.name] = Core.getInitialValue(field); // via getInitialValue, never a literal — so a seeded value is identical to what the create path would produce, tokens ('now', 'yearStart') included\n      }\n    }\n  }\n\n  // The toggle cascade and the read-only lockout are folded into each field's own readonlyCondition rather\n  // than set as a flat readonly, so a field that already carries a condition keeps it (either one wins).\n  private fieldsFor(section: AppConfigSection): Field[] {\n    return (section.fields || [])\n      .filter(field => field.name !== section.toggleField) // the switch renders in the card header, not twice\n      .map(field => {\n        const own = field.readonlyCondition;\n        const toggle = section.toggleField;\n        if (!toggle && this.canEdit) return field;\n        return { ...field, readonlyCondition: (data: any) => !this.canEdit || (!!toggle && !data?.[toggle]) || (own ? own(data) : false) };\n      });\n  }\n\n  // Recomputed on load and whenever a value changes — a section's visibility can depend on the config itself\n  private buildVisibleCards(): void {\n    this.visibleCards = this.cards.filter(c => Core.isItemVisible(c.section, this.configuration));\n  }\n\n  toggle(card: { section: AppConfigSection, collapsed: boolean }): void {\n    if (card.section.collapsible === false) return;\n    card.collapsed = !card.collapsed;\n  }\n\n  // spa-form writes straight into this.configuration, so this only has to re-test section visibility\n  onInputChange(): void {\n    this.buildVisibleCards();\n  }\n\n  // Added: the escape hatch for the banner. Reverting the form automatically on a refusal was rejected — it\n  // throws away every OTHER edit on a page that saves as one object, and on a business refusal it also destroys\n  // the values the user needs in front of them to act on the message. Offered as a deliberate press instead, so\n  // \"show me what is actually saved\" is one click away without being forced on anyone.\n  discardChanges(): void {\n    this.saveFailure = null;\n    this.load();\n  }\n\n  //---------- Save ----------\n\n  save(): void {\n    if (this.saving || !this.canEdit) return;\n    this.saving = true;\n    this.dataService.CallApi(this.config?.saveAction || { url: 'configuration/update', method: 'post' }, this.configuration).subscribe({\n      next: (response: ApiResponse) => {\n        this.saving = false;\n        if (response.success) {\n          this.saveFailure = null; // Added: the values on screen are now the values in force, so the banner must go\n          this.messageService.toast('Configuration updated successfully');\n          this.load(); // re-read so computed/server-stamped values (and a first-read created row's key) come back\n          this.configService.refresh(); // every app-side subscriber (nav gating, unit suffixes) sees the change now, not next login\n        } else {\n          // Changed: was toast(response.message ...) — the server's raw words for 5 seconds while the page\n          // still showed every edited value, so it looked saved. 'submit' is exactly right and literally\n          // true here: the user's configuration edits ARE still on the form and do not need re-entering.\n          const failureClass = this.apiErrorService.presentAppFailure(response, 'submit', (this.config?.saveAction || { url: 'configuration/update' }).url); // Changed: capture the class — it already distinguishes a deliberate refusal from a technical failure, so the banner does not have to re-derive it\n          // Added: this page is a PERSISTENT page, not a dialog. Everywhere else in the library a failed submit\n          // leaves a modal open, and the open modal is itself the visible \"not saved\" signal. Here there is no\n          // modal: once the toast expires the page looks settled while showing values the server refused and the\n          // database does not hold. The banner is that missing signal, and unlike the toast it does not expire.\n          this.saveFailure = {\n            reason: failureClass === 'business'\n              ? this.apiErrorService.stripReference(response.message) // the server's own sentence names what to fix; stripReference drops the \"(reference X)\" suffix exactly as the toast does\n              : 'A technical problem stopped the save.',\n            technical: failureClass !== 'business'\n          };\n        }\n      },\n      // Changed: was `error: () => this.saving = false` — a TRANSPORT failure (server down, DNS, CORS, dropped\n      // connection) never reaches the next() handler above, so this page said nothing at all and simply went\n      // un-busy, which is the most convincing \"saved\" signal of the lot. The interceptor's own network dialog is\n      // dismissible and page-agnostic; the banner is what keeps the statement attached to the values on screen.\n      error: () => {\n        this.saving = false;\n        this.saveFailure = { reason: 'A technical problem stopped the save.', technical: true };\n      }\n    });\n  }\n\n  //---------- Reset ----------\n\n  // Added (N22): the tenant reset. The button is only rendered with cap92 at Full, but the check is repeated here\n  // because canReset is DOM state and this method is public — the same reason the dialog re-checks its own gate.\n  // The server re-validates both the capability and the phrase independently; neither gate here is trusted by it.\n  resetTenant(): void {\n    if (this.resetting || !this.canReset) return;\n\n    // Routed through getConfirmOptions rather than calling messageService.confirm with literals, so this prompt\n    // is composed by the same resolver as every other confirm in the library and the phrase, labels and\n    // destructive colouring all come from the one Button config in datalib.\n    const button = this.dataService.resetTenantButton;\n    const c = this.buttonService.getConfirmOptions(button, this.configuration, undefined, this.dataService.namedDestructiveActions);\n\n    this.messageService.confirm(c.message, c.confirmLabel, c.cancelLabel, c.destructive, c.requirePhrase).subscribe((result: any) => {\n      if (!this.buttonService.confirmAccepted(result)) return;\n\n      // The typed text is sent verbatim — never trimmed or case-folded. The server compares it ordinally and\n      // will refuse anything else, so \"fixing up\" the input here would only ever turn an accepted press into an\n      // unexplained refusal.\n      const phrase = this.buttonService.confirmPhrase(result);\n\n      this.resetting = true;\n      this.dataService.CallApi(this.config?.resetAction || button.action!, { phrase }).subscribe({\n        next: (response: ApiResponse) => {\n          this.resetting = false;\n          // The server's own sentence is surfaced on BOTH outcomes. On success it states what the sweep actually\n          // did (the ledger makes it precise), and on refusal it names the reason — a bare \"done\"/\"failed\" here\n          // would discard the only account of a tenant-wide destructive operation the user will ever see.\n          if (response.success) {\n            this.messageService.toast(response.message && response.message !== 'success' ? response.message : 'Organisation reset');\n            this.load(); // re-read: the sweep changes rows this page renders, and the row itself is re-stamped\n            this.configService.refresh(); // every app-side subscriber sees the post-reset state now, not next login\n          } else {\n            this.apiErrorService.presentAppFailure(response, 'submit', (this.config?.resetAction || button.action!).url);\n          }\n        },\n        // A transport failure never reaches next(), and a reset that silently goes un-busy is the most convincing\n        // \"it worked\" signal there is — on an operation whose whole point is that it destroyed something.\n        error: () => {\n          this.resetting = false;\n          this.messageService.toast('A technical problem stopped the reset. Nothing has been confirmed as deleted.');\n        }\n      });\n    });\n  }\n\n}\n","<div class=\"ac-page\">\n\n  <div class=\"ac-head\">\n    <h1>{{ title }}</h1>\n    <span class=\"ac-caption\" *ngIf=\"!canEdit\">Read only — you do not have permission to change these settings</span>\n    <!-- Added (Setup v3): this page used to carry its own module checkboxes, which wrote the same flags as the\n         Getting Started picker but skipped its capability check, its \"modules confirmed\" step and its badge\n         refresh. One write path now — the page keeps the settings, the picker owns what is switched on. -->\n    <a class=\"ac-modules-link\" (click)=\"goToModules()\"><mat-icon>tune</mat-icon>Modules are chosen in Getting Started</a>\n  </div>\n\n  <!-- One card per section. The header carries the title, the optional module switch and the collapse chevron -->\n  <mat-card class=\"ac-section\" *ngFor=\"let card of visibleCards\" [id]=\"'cfg-' + card.section.key\">\n\n    <!-- Changed (2026-08-19): the collapse control was two glyphs swapped at the far right —\n         expand_more/expand_less. The estate has ONE disclosure marker, .tin-disc in tin-styles.css: a single\n         chevron_right rotated 90deg on open, leading the row. A swap cannot animate and changes the marker's\n         shape between its two states. This card header was the last holdout in tin-spa alongside\n         tenant-settings. role/tabindex/aria-expanded are set only when the section can actually collapse,\n         matching form.component.html:29 — a static header must not announce itself as a button. -->\n    <div class=\"ac-section-head\" [class.clickable]=\"card.section.collapsible !== false\" [class.tin-disc-row]=\"card.section.collapsible !== false\" (click)=\"toggle(card)\" (keydown.enter)=\"toggle(card)\" (keydown.space)=\"toggle(card)\" [attr.role]=\"card.section.collapsible !== false ? 'button' : null\" [attr.tabindex]=\"card.section.collapsible !== false ? 0 : null\" [attr.aria-expanded]=\"card.section.collapsible !== false ? !card.collapsed : null\">\n      <span class=\"tin-disc\" *ngIf=\"card.section.collapsible !== false\" [class.open]=\"!card.collapsed\"><mat-icon>chevron_right</mat-icon></span> <!-- Changed: leading rotated marker replaces the trailing swap -->\n      <mat-icon class=\"ac-section-icon\" *ngIf=\"card.section.icon\">{{ card.section.icon }}</mat-icon>\n\n      <!-- toggleField sections put the module switch IN the header; children below go readonly while it is off -->\n      <spa-check *ngIf=\"card.section.toggleField\" class=\"ac-section-switch\" [display]=\"card.section.title\" [(value)]=\"configuration[card.section.toggleField]\" (valueChange)=\"onInputChange()\" [readonly]=\"!canEdit\" (click)=\"$event.stopPropagation()\" (keydown)=\"$event.stopPropagation()\"></spa-check> <!-- Changed: the header now handles enter/space to collapse, so the switch must swallow its own keys — otherwise toggling the module with the keyboard would also collapse the card -->\n\n      <span class=\"ac-section-title\" *ngIf=\"!card.section.toggleField\">{{ card.section.title }}</span>\n    </div>\n\n    <div class=\"ac-section-hint\" *ngIf=\"card.section.hint && !card.collapsed\">{{ card.section.hint }}</div>\n\n    <div class=\"ac-section-body\" *ngIf=\"!card.collapsed\">\n      <spa-form [config]=\"card.form\" [data]=\"configuration\" (inputChange)=\"onInputChange()\"></spa-form>\n    </div>\n\n  </mat-card>\n\n  <!-- Added (N22): the reset. Deliberately the LAST thing on the page and visually separated from the settings\n       cards — it is not a setting, it destroys the data the settings describe. Rendered only with cap92 at Full,\n       so for everyone else the page ends exactly as it did before. It sits OUTSIDE the sticky save footer: an\n       irreversible action must not follow the pointer down the page next to Save. -->\n  <div class=\"ac-danger\" *ngIf=\"canReset\">\n    <div class=\"ac-danger-head\">\n      <mat-icon class=\"ac-danger-icon\">restart_alt</mat-icon>\n      <span class=\"ac-danger-title\">Reset organisation</span>\n    </div>\n    <p class=\"ac-danger-text\">\n      Removes every operational record in this organisation — transactions, documents and the day-to-day data built\n      on top of these settings. Your configuration, users and roles are kept.\n    </p>\n    <div class=\"ac-danger-actions\">\n      <button mat-stroked-button class=\"ac-danger-button\" [disabled]=\"resetting\" (click)=\"resetTenant()\">{{ resetting ? 'Resetting…' : 'Reset Organisation' }}</button>\n    </div>\n  </div>\n\n  <!-- One Save for the whole page — the object posts as a unit, so the sections can never drift apart.\n       The sticky footer now also carries the refusal banner, so the \"not saved\" statement is on screen at every\n       scroll position rather than only for the 5 seconds the toast lives. -->\n  <div class=\"ac-footer\" *ngIf=\"canEdit && visibleCards.length\">\n\n    <!-- Added: persists until a save succeeds. role=alert so it is announced, not just drawn -->\n    <div class=\"ac-save-alert\" role=\"alert\" *ngIf=\"saveFailure\">\n      <mat-icon class=\"ac-save-alert-icon\">report_problem</mat-icon>\n      <div class=\"ac-save-alert-text\">\n        <strong>Not saved{{ saveFailure.technical ? '' : ' — ' + saveFailure.reason }}</strong>\n        <span *ngIf=\"saveFailure.technical\">{{ saveFailure.reason }}</span>\n        <span>The settings shown on this page are <b>not in force</b>. Your saved configuration is unchanged.</span>\n      </div>\n      <button mat-stroked-button class=\"ac-save-alert-discard\" (click)=\"discardChanges()\">Discard my changes</button>\n    </div>\n\n    <div class=\"ac-actions\">\n      <button mat-raised-button color=\"primary\" [disabled]=\"saving\" (click)=\"save()\">Save Configuration</button>\n    </div>\n\n  </div>\n\n</div>\n","import { Component, OnInit, inject } from '@angular/core';\nimport { ApiResponse, Field, FormConfig, RoleAccess } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\nimport { ApiErrorService } from '../../services/api-error.service';\nimport { PasswordPolicyService } from '../../services/password-policy.service'; // Added: the sentence generator that used to live in this file, now shared with the two surfaces the user actually reads\n\n// Added: spa-password-policy — the admin page for the per-tenant password policy (N8). One row per tenant,\n// read from `passwordconfig/get` and written back to `passwordconfig/update`; PasswordConfigController is the\n// only door, and this page is the only thing that opens it.\n//\n// Shaped on spa-app-configuration deliberately, down to the card language, the sticky footer and the persistent\n// refusal banner — that page is the estate's one worked example of a single-row settings form, and the banner in\n// particular earns its place twice over here: on a persistent (non-dialog) page an expired toast leaves edited\n// values on screen looking saved, and on THIS page those values are a security control. A password policy the\n// admin believes is in force while the database holds another one is the exact failure this whole initiative\n// started from.\n//\n// It is NOT built on spa-app-configuration for the same reason PasswordConfigController is not built on\n// AppConfigurationControllerBase: that component reads its sections from `appConfig.appConfigurationConfig`, a\n// single per-app global, so it can only ever serve one entity per app. PasswordConfig is one library-owned entity\n// with five known columns, identical in all five apps, so the fields are declared here once and every consumer\n// gets the page with no per-app registration to forget.\n@Component({\n  selector: 'spa-password-policy',\n  templateUrl: './password-policy.component.html',\n  styleUrls: ['./password-policy.component.css'],\n  standalone: false\n})\nexport class PasswordPolicyComponent implements OnInit {\n  dataService = inject(DataServiceLib);\n  private messageService = inject(MessageService);\n  private authService = inject(AuthService);\n  private apiErrorService = inject(ApiErrorService);\n  private passwordPolicyService = inject(PasswordPolicyService); // Added: states the rule; this page no longer owns the wording\n\n  // The WHOLE row, held as one object and posted back as one object. This is not incidental: `POST update` copies\n  // every property off the payload with SetValues, so a partial body writes CLR defaults over the columns it\n  // omits. Round-tripping the object the GET returned is what makes that safe.\n  configuration: any = {};\n  loading = false;\n  saving = false;\n  canEdit = true;\n\n  // Persists until a save actually succeeds — see the class comment. Not cleared on edit: editing does not make\n  // the values on screen the values in force.\n  saveFailure: { reason: string, technical: boolean } | null = null;\n\n  // Materialized, never template-bound getters. A getter returning a new array to an *ngFor hands change detection\n  // a fresh reference every pass — the livelock the day-book/table pages already paid for once.\n  requirements: { text: string, required: boolean }[] = [];\n  effectiveLength = 0;\n  weakerThanDefault = false;\n\n  // Changed: LegacyDefaults moved to PasswordPolicyService. It was never specific to this page — it is the rule\n  // the server falls back to — and the change-password surfaces need the same constant for their fallback wording.\n  // Still used only to STATE when a tenant has moved below it, never to prevent it: whether a configured policy may\n  // be weaker than the legacy rule is an open product decision and this page must not settle it by quietly\n  // refusing to save one.\n\n  formConfig: FormConfig = {\n    fields: [\n      { name: 'minLength', type: 'number', alias: 'Minimum length', min: 0, infoMessage: 'The fewest characters a password may contain.' },\n      { name: 'minUpperCase', type: 'number', alias: 'Uppercase letters', min: 0, infoMessage: 'How many capital letters (A-Z) a password must contain. 0 means none are required.' },\n      { name: 'minLowerCase', type: 'number', alias: 'Lowercase letters', min: 0, infoMessage: 'How many small letters (a-z) a password must contain. 0 means none are required.' },\n      { name: 'minNumericChars', type: 'number', alias: 'Numbers', min: 0, infoMessage: 'How many digits (0-9) a password must contain. 0 means none are required.' },\n      { name: 'minSpecialChars', type: 'number', alias: 'Special characters', min: 0, infoMessage: 'How many symbols (for example ! ? @ #) a password must contain. 0 means none are required.' }\n    ],\n    mode: 'edit',\n    multiColumn: true\n  };\n\n  // min: 0 rather than min: 1 throughout, on purpose. The server refuses a NEGATIVE threshold — a negative is\n  // unresolvable, so UserService would decline the whole row and enforce something other than what the page\n  // displays — and the client mirrors exactly that and no more. Zero is a legitimate, deliberate admin act and the\n  // form must not be the thing that silently makes it unreachable.\n\n  ngOnInit(): void {\n    this.canEdit = Core.getFormAccess({ security: { allow: [this.dataService.capPasswordPolicy] } } as FormConfig, this.authService.currentRoleSource.value) >= RoleAccess.Edit;\n    this.applyReadonly();\n    this.load();\n  }\n\n  // The lockout is folded into each field's readonlyCondition rather than set as a flat readonly, matching\n  // spa-app-configuration — a field that later grows its own condition then keeps it.\n  private applyReadonly(): void {\n    if (this.canEdit) return;\n    this.formConfig = { ...this.formConfig, fields: this.formConfig.fields.map((field: Field) => ({ ...field, readonlyCondition: () => true })) };\n  }\n\n  load(): void {\n    if (this.loading) return;\n    this.loading = true;\n    this.dataService.CallApi({ url: 'passwordconfig/get' }).subscribe({\n      next: (response: ApiResponse) => {\n        this.loading = false;\n        if (!response.success) { this.apiErrorService.presentAppFailure(response, 'load', 'passwordconfig/get'); return; }\n        this.configuration = response.data || {}; // the backend creates the row on first read, so this is never empty in practice\n        this.describe();\n      },\n      error: () => this.loading = false\n    });\n  }\n\n  //---------- The rule, in words ----------\n\n  // Rebuilt on load and on every keystroke. The numbers ARE the policy, but nobody reads a password rule as five\n  // integers — the user meeting this rule will be shown a sentence, so the admin setting it should be reading the\n  // same sentence while they set it.\n  //\n  // Changed: the sentence-building itself moved to PasswordPolicyService and this now calls it. That is the whole\n  // point of the extraction — the admin reading this card and the user being refused elsewhere are now guaranteed\n  // to be reading text produced by the same function from the same row, rather than by three hand-written copies\n  // that had already drifted. Results are still MATERIALIZED into fields here: the service returns a fresh array,\n  // and handing a new reference to an *ngFor on every change-detection pass is the livelock this estate has\n  // already paid for once.\n  private describe(): void {\n    const described = this.passwordPolicyService.describe(this.configuration);\n    this.requirements = described.requirements;\n    this.effectiveLength = described.effectiveLength;\n    this.weakerThanDefault = described.weakerThanDefault;\n  }\n\n  // spa-form writes straight into this.configuration, so this only has to restate the rule\n  onInputChange(): void {\n    this.describe();\n  }\n\n  discardChanges(): void {\n    this.saveFailure = null;\n    this.load();\n  }\n\n  //---------- Save ----------\n\n  save(): void {\n    if (this.saving || !this.canEdit) return;\n    this.saving = true;\n    this.dataService.CallApi({ url: 'passwordconfig/update', method: 'post' }, this.configuration).subscribe({\n      next: (response: ApiResponse) => {\n        this.saving = false;\n        if (response.success) {\n          this.saveFailure = null;\n          this.passwordPolicyService.refresh(); // Added: the policy just changed, so the sentences the change-password surfaces cached are now the PREVIOUS rule — drop them rather than let this session keep showing it\n          this.messageService.toast('Password policy updated successfully');\n          this.load(); // re-read so the row's own key and audit columns come back, and so the page states what the DATABASE holds rather than what was typed\n        } else {\n          const failureClass = this.apiErrorService.presentAppFailure(response, 'submit', 'passwordconfig/update');\n          this.saveFailure = {\n            reason: failureClass === 'business' ? this.apiErrorService.stripReference(response.message) : 'A technical problem stopped the save.',\n            technical: failureClass !== 'business'\n          };\n        }\n      },\n      // A transport failure never reaches next(), so without this the page would simply go un-busy — the most\n      // convincing \"saved\" signal there is\n      error: () => {\n        this.saving = false;\n        this.saveFailure = { reason: 'A technical problem stopped the save.', technical: true };\n      }\n    });\n  }\n\n}\n","<div class=\"pp-page\">\n\n  <div class=\"pp-head\">\n    <h1>Password Policy</h1>\n    <span class=\"pp-caption\" *ngIf=\"!canEdit\">Read only — you do not have permission to change these settings</span>\n  </div>\n\n  <p class=\"pp-lead\">These rules apply to every password set in this organisation — new accounts, invitations and password changes alike.</p>\n\n  <!-- The settings and the sentence they produce sit side by side deliberately. Five integers are the policy, but\n       nobody reads a password rule as five integers, and the admin choosing them should be reading the same\n       wording the user will be refused by. Collapses to one column on a narrow screen. -->\n  <div class=\"pp-grid\">\n\n    <mat-card class=\"pp-card\">\n      <div class=\"pp-card-head\">\n        <mat-icon class=\"pp-card-icon\">password</mat-icon>\n        <span class=\"pp-card-title\">Requirements</span>\n      </div>\n      <div class=\"pp-card-hint\">Set a figure to 0 to stop requiring that kind of character.</div>\n      <div class=\"pp-card-body\">\n        <spa-form [config]=\"formConfig\" [data]=\"configuration\" (inputChange)=\"onInputChange()\"></spa-form>\n      </div>\n    </mat-card>\n\n    <mat-card class=\"pp-card pp-summary\">\n      <div class=\"pp-card-head\">\n        <mat-icon class=\"pp-card-icon\">checklist</mat-icon>\n        <span class=\"pp-card-title\">A password must</span>\n      </div>\n\n      <ul class=\"pp-req-list\">\n        <li *ngFor=\"let req of requirements\" class=\"pp-req\" [class.pp-req-off]=\"!req.required\">\n          <mat-icon class=\"pp-req-icon\">{{ req.required ? 'check_circle' : 'remove_circle_outline' }}</mat-icon>\n          <span>{{ req.text }}</span>\n        </li>\n      </ul>\n\n      <!-- Plain arithmetic, not a rule of its own: the class minimums are counted inside the length, so their sum\n           can bind above the configured minimum length. Shown only when it actually differs. -->\n      <div class=\"pp-note\" *ngIf=\"effectiveLength > (configuration.minLength || 0)\">\n        <mat-icon class=\"pp-note-icon\">straighten</mat-icon>\n        <span>The required characters already add up to <b>{{ effectiveLength }}</b>, so nothing shorter than {{ effectiveLength }} characters can pass.</span>\n      </div>\n\n      <!-- States what has been chosen; never prevents it. Whether a tenant may set a policy weaker than the rule\n           that applied before this page existed is an open decision, and this page does not settle it. -->\n      <div class=\"pp-note pp-note-soft\" *ngIf=\"weakerThanDefault\">\n        <mat-icon class=\"pp-note-icon\">info_outline</mat-icon>\n        <span>This is less strict than the standard rule (8 characters with an uppercase, a lowercase, a number and a special character).</span>\n      </div>\n    </mat-card>\n\n  </div>\n\n  <!-- One Save for the whole row, because the row posts as one object. The banner shares the sticky footer so the\n       \"not saved\" statement is on screen at every scroll position, not only for the seconds the toast lives. -->\n  <div class=\"pp-footer\" *ngIf=\"canEdit\">\n\n    <div class=\"pp-save-alert\" role=\"alert\" *ngIf=\"saveFailure\">\n      <mat-icon class=\"pp-save-alert-icon\">report_problem</mat-icon>\n      <div class=\"pp-save-alert-text\">\n        <strong>Not saved{{ saveFailure.technical ? '' : ' — ' + saveFailure.reason }}</strong>\n        <span *ngIf=\"saveFailure.technical\">{{ saveFailure.reason }}</span>\n        <span>The rules shown on this page are <b>not in force</b>. Your saved password policy is unchanged.</span>\n      </div>\n      <button mat-stroked-button class=\"pp-save-alert-discard\" (click)=\"discardChanges()\">Discard my changes</button>\n    </div>\n\n    <div class=\"pp-actions\">\n      <button mat-raised-button color=\"primary\" [disabled]=\"saving\" (click)=\"save()\">Save Password Policy</button>\n    </div>\n\n  </div>\n\n</div>\n","// Renders the agent's replies as the markdown they are actually written in.\n//\n// The agent writes **bold**, lists, headings and menu paths, and the widget printed all of it verbatim — so a\n// reply the guide carefully formatted arrived as a wall of asterisks. Telegram and WhatsApp now convert to\n// their own markup; this is the web's half of the same job.\n//\n// Deliberately a small hand-rolled subset rather than a markdown library: the input is not arbitrary user\n// markdown, it is the agent's own output, which uses bold, italic, inline code, headings, bullets and\n// numbered steps and nothing else. A library would add a dependency and a much larger escaping surface for\n// no gain here.\n//\n// SECURITY: every character is HTML-escaped BEFORE any formatting is applied, so nothing in a reply can\n// become markup. That matters more than usual for this component — an agent reply can contain data a\n// different user typed, so it must be treated as hostile text, not as trusted output.\nimport { Pipe, PipeTransform } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\n@Pipe({ name: 'agentMarkdown', standalone: false })\nexport class AgentMarkdownPipe implements PipeTransform {\n\n  constructor(private sanitizer: DomSanitizer) { }\n\n  transform(value: string | null | undefined): SafeHtml {\n    if (!value) return '';\n\n    let html = this.escape(value);\n\n    // Headings first: they are line-anchored, and converting them after inline rules would let a ** on the\n    // same line interfere\n    html = html.replace(/^#{1,6}\\s*(.+)$/gm, '<strong class=\"md-heading\">$1</strong>');\n\n    html = html.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n    html = html.replace(/(?<![\\w*])\\*(?!\\s)(.+?)(?<!\\s)\\*(?![\\w*])/g, '<em>$1</em>');\n    html = html.replace(/`([^`]+)`/g, '<code>$1</code>');\n\n    // Bullets and numbered steps keep their marker — turning them into <ul>/<ol> would need block parsing,\n    // and the agent's lists are already readable as lines\n    html = html.replace(/^(\\s*)[-•*]\\s+(.+)$/gm, '$1<span class=\"md-bullet\">•</span> $2');\n\n    html = html.replace(/\\n/g, '<br>');\n\n    return this.sanitizer.bypassSecurityTrustHtml(html);\n  }\n\n  // Escaping BEFORE formatting is what makes bypassSecurityTrustHtml safe here: by the time anything is\n  // trusted, the only tags present are the ones this pipe put there itself.\n  private escape(text: string): string {\n    return text\n      .replace(/&/g, '&amp;')\n      .replace(/</g, '&lt;')\n      .replace(/>/g, '&gt;')\n      .replace(/\"/g, '&quot;')\n      .replace(/'/g, '&#39;');\n  }\n}\n","// Floating chat widget component for in-app Agent (renamed from AssistantComponent)\nimport { Component, OnInit, OnDestroy, ViewChild, ElementRef, AfterViewChecked, HostListener, NgZone, Input } from '@angular/core'; // Changed: Input added for pageMode\nimport { Subscription } from 'rxjs';\nimport { filter } from 'rxjs/operators'; // Changed: NavigationEnd-only router stream for the agent-route check\nimport { Router, NavigationEnd } from '@angular/router'; // Changed: the floating widget stands down on the chat page's own route\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout'; // Changed: the bottom tab bar replaces the FAB on mobile\nimport { AgentService, AgentMessage, ConversationSummary, AgentSessionInfo } from '../../services/agent.service';\nimport { SignalRService } from '../../services/signalr.service';\nimport { trigger, transition, style, animate } from '@angular/animations';\n\n@Component({\n  selector: 'spa-agent', // Changed: was spa-assistant\n  templateUrl: './agent.component.html',\n  styleUrls: ['./agent.component.css'],\n  standalone: false,\n  animations: [\n    trigger('slideUp', [\n      // Changed: page mode enters in normal flow and must not slide up — a page that animates in like a\n      // dialog still reads as a dialog. Both empty transitions are declared BEFORE :enter/:leave because the\n      // first matching transition wins, so 'none' opts the page instance out of the floating animation.\n      transition('void => none', []), // Changed: page mode — no enter animation\n      transition('none => void', []), // Changed: page mode — no leave animation\n      transition(':enter', [\n        style({ opacity: 0, transform: 'translateY(20px) scale(0.95)' }),\n        animate('250ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 1, transform: 'translateY(0) scale(1)' }))\n      ]),\n      transition(':leave', [\n        animate('200ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'translateY(20px) scale(0.95)' }))\n      ])\n    ])\n  ]\n})\nexport class AgentComponent implements OnInit, OnDestroy, AfterViewChecked { // Changed: was AssistantComponent\n\n  @ViewChild('messageContainer') messageContainer!: ElementRef;\n  @ViewChild('messageInput') messageInput!: ElementRef;\n  @ViewChild('cameraInput') cameraInput!: ElementRef<HTMLInputElement>; // Changed: hands off to the phone camera\n  @ViewChild('galleryInput') galleryInput!: ElementRef<HTMLInputElement>; // Changed: gallery / file picker\n\n  // Changed: one component, two presentations. false = the floating widget (FAB + fixed window, unchanged);\n  // true = the routed chat page (home/agent) — no FAB, window always rendered, no outside-click close, no\n  // minimize. Only presentation differs; all chat behaviour stays shared through AgentService.\n  @Input() pageMode = false;\n\n  // Changed: mobile retires the floating widget entirely — the bottom tab bar's Chat tab is the entry point\n  // and home/agent is the surface. Both flags only ever gate the FLOATING presentation; page mode ignores them.\n  smallScreen = false; // Changed: same (max-width: 600px) breakpoint nav-menu uses — one source of truth\n  onAgentRoute = false; // Changed: true while the routed chat page owns the screen\n\n  // Changed: the floating FAB is suppressed in page mode (Phase 1), on mobile, and on the chat page's own\n  // route at any width — otherwise it hovers over the very page it would open.\n  get showFab(): boolean {\n    return !this.pageMode && !this.smallScreen && !this.onAgentRoute;\n  }\n\n  // Changed: the floating window follows the FAB. Page mode renders regardless of isOpen; the floating\n  // instance additionally refuses to render wherever its FAB is gone, so there are never two chat surfaces.\n  get showWindow(): boolean {\n    return this.pageMode || (this.isOpen && !this.smallScreen && !this.onAgentRoute);\n  }\n\n  messages: AgentMessage[] = [];\n  conversations: ConversationSummary[] = []; // Changed: switcher list\n  currentConversationId: number | null = null;\n  showConversations = false; // Changed: the switcher is a dropdown, not a permanent panel — the window is small\n  sessionInfo: AgentSessionInfo | null = null; // Changed: drives the \"you are creating a Customer\" banner\n  isOpen = false;\n  isTyping = false;\n  inputText = '';\n  greeting = '';\n  suggestedQuestions: string[] = [];\n  isOnline = false;\n\n  isRecording = false; // Changed: voice note capture state\n  recordSeconds = 0;\n  mediaError = ''; // Changed: shown inline when the mic is blocked or unavailable\n  pendingPhoto: File | null = null; // Changed: photo is staged, not sent — the user adds a caption first\n  isTranscribing = false; // Changed: Stop pressed, waiting for the transcript to land in the text box\n\n  private subs: Subscription[] = [];\n  private shouldScroll = false;\n  private viewportHandler: (() => void) | null = null; // Changed: visualViewport resize handler reference\n\n  // Changed: voice note recording internals\n  private recorder: MediaRecorder | null = null;\n  private mediaStream: MediaStream | null = null;\n  private chunks: Blob[] = [];\n  private recordTimer: any = null;\n  private stopMode: 'send' | 'transcribe' | 'cancel' = 'send'; // Changed: what to do with the clip once stopped\n\n  private static readonly MAX_RECORD_SECONDS = 120; // Auto-stop so a forgotten recording can't run away\n\n  // ---------------------------------------------------------------------------------------------------\n  // Voice mode — hands-free. Enter once, then speak and listen in a loop until you exit. Built for someone\n  // driving or with their hands full, so nothing between entry and exit requires touch or sight.\n  //\n  // The session is deliberately HALF-DUPLEX: the microphone is closed whenever audio is playing, and\n  // playback finishes before it reopens. That single property removes echo cancellation, acoustic feedback\n  // and interrupt arbitration entirely. Preserve it — barge-in would be a re-architecture, not an increment.\n  // ---------------------------------------------------------------------------------------------------\n  voiceMode = false;\n  // 'starting' is the room-calibration window. It exists because showing \"Listening\" during it was a lie —\n  // the microphone is open but the detector is still measuring the noise floor, so anything said then is\n  // measured AS noise and raises the bar against the speaker's own voice.\n  voiceState: 'idle' | 'starting' | 'listening' | 'capturing' | 'thinking' | 'speaking' = 'idle';\n  voiceTranscript = '';  // what it heard on the last turn\n  voiceReply = '';       // what it answered, verbatim (the spoken version is shortened)\n  voiceError = '';\n  voiceLevel = 0;        // 0..1, drives the level meter so the user can see the mic is live\n\n  // Tunable because a vehicle cabin is not a desk. These are fields rather than constants so they can be\n  // adjusted against a real environment without a rebuild.\n  voiceThreshold = 0.01;      // absolute floor — the room can raise this, never lower it\n  noiseMultiplier = 3;        // speech must be this many times the measured room noise\n  maxThreshold = 0.08;        // ...but never so high that a normal voice cannot clear it\n  onsetMs = 250;              // sustained loudness needed before it counts as speech at all\n  silenceMs = 2200;           // quiet needed to call the utterance finished\n  minSpeechMs = 400;          // anything shorter than this was a noise, not a sentence\n\n  // What calibration actually settled on, exposed so it can be inspected while running\n  noiseFloor = 0;\n  activeThreshold = 0.03;\n\n  private static readonly SETTLE_MS = 450;          // let the speakers finish before trusting the mic again\n  private static readonly CALIBRATION_MS = 600;     // listen to the room before listening to the person\n  private static readonly CONTINUE_RATIO = 0.55;    // hysteresis: it takes less to STAY in speech than to enter it\n  private static readonly MAX_UTTERANCE_MS = 30000; // a noisy cab must not record forever\n  private static readonly IDLE_MS = 12000;          // no speech this long → don't upload silence, listen again\n  private static readonly MAX_SILENT_MS = 180000;   // ...but give up after three minutes of nothing at all\n\n  private calibrationEndsAt = 0;\n  private calibrationSamples: number[] = [];\n  private loudSince = 0;\n\n  private voiceRecorder: MediaRecorder | null = null;\n  private voiceStream: MediaStream | null = null;\n  private voiceChunks: Blob[] = [];\n  private audioContext: AudioContext | null = null;\n  private analyser: AnalyserNode | null = null;\n  private vadTimer: any = null;\n  private player: HTMLAudioElement | null = null;\n  private speechStartedAt = 0;\n  private lastLoudAt = 0;\n  private listenStartedAt = 0;\n  private silentSince = 0;\n  private abandonUtterance = false; // true when the clip should be dropped rather than uploaded\n\n  constructor(public agentService: AgentService, private signalRService: SignalRService,\n    private zone: NgZone, private router: Router, private breakpointObserver: BreakpointObserver) {} // Changed: Router + BreakpointObserver gate the floating presentation\n\n  // Every voice state change goes through here. The states are set from audio-element events, a MediaRecorder\n  // callback and a sampling timer, and those did not reliably trigger a repaint — the panel was showing\n  // \"Listening\" while the machine was already capturing, thinking, or speaking aloud. That is worse than no\n  // indicator at all: someone who cannot look at the screen is being told the wrong thing about whose turn it\n  // is. Re-entering the Angular zone forces the view to catch up immediately.\n  private setVoiceState(state: 'idle' | 'starting' | 'listening' | 'capturing' | 'thinking' | 'speaking') {\n    if (this.voiceState === state) return;\n    this.zone.run(() => { this.voiceState = state; });\n  }\n\n  get agentName(): string { // Changed: was assistantName\n    return this.agentService.agentName;\n  }\n\n  ngOnInit(): void {\n    this.agentService.loadConfig();\n    this.initMobileViewport(); // Changed: Listen for keyboard resize on mobile\n\n    this.subs.push(\n      this.agentService.messages$.subscribe(msgs => {\n        this.messages = msgs;\n        this.shouldScroll = true;\n      }),\n      this.agentService.isOpen$.subscribe(open => {\n        this.isOpen = open;\n        if (open) this.focusInput();\n        // Changed: the widget can be closed by an outside click while a voice session is running. The\n        // component survives that (only the window is *ngIf'd away), so without this the microphone would\n        // stay live behind a hidden window with no way to reach the exit button.\n        // Changed: page mode ignores isOpen for visibility, so a close() from the floating window elsewhere\n        // must not tear down a voice session that is still on screen on the page.\n        else if (this.voiceMode && !this.pageMode) this.stopVoiceMode();\n      }),\n      this.agentService.typing$.subscribe(typing => {\n        this.isTyping = typing;\n        this.shouldScroll = true;\n      }),\n      this.agentService.greeting$.subscribe(g => this.greeting = g),\n      this.agentService.suggestedQuestions$.subscribe(q => this.suggestedQuestions = q),\n      // Changed: the conversation switcher and the session banner both come from the service\n      this.agentService.conversations$.subscribe(list => this.conversations = list),\n      this.agentService.currentConversationId$.subscribe(id => this.currentConversationId = id),\n      this.agentService.sessionInfo$.subscribe(info => this.sessionInfo = info),\n      this.signalRService.dataHubConnected$.subscribe(connected => this.isOnline = connected),\n      // Changed: crossing into mobile must not strand an open floating window behind the new tab bar. Only\n      // the FLOATING instance closes it — the page instance never mutates the shared isOpen (see fsd Risk 2).\n      this.breakpointObserver.observe(['(max-width: 600px)']).subscribe((result: BreakpointState) => {\n        this.smallScreen = result.matches;\n        if (result.matches && !this.pageMode && this.isOpen) this.agentService.close();\n      }),\n      // Changed: the routed chat page renders its own instance, so the floating one steps aside on that URL\n      this.router.events.pipe(\n        filter(event => event instanceof NavigationEnd)\n      ).subscribe((event: NavigationEnd) => {\n        this.onAgentRoute = this.isAgentRoute(event.urlAfterRedirects || event.url);\n        if (this.onAgentRoute && !this.pageMode && this.isOpen) this.agentService.close();\n      })\n    );\n\n    this.onAgentRoute = this.isAgentRoute(this.router.url); // Changed: NavigationEnd has usually already fired by now\n\n    this.agentService.loadConversations(); // Changed: the switcher needs the list before it is opened\n  }\n\n  // Changed: 'home/agent' is mounted through the shared home routing module, so the reliable test is the\n  // trailing segment rather than a whole-URL match that would miss a consumer app's own route prefix.\n  private isAgentRoute(url: string): boolean {\n    const path = (url || '').split('?')[0].split(';')[0].split('#')[0].replace(/\\/+$/, '');\n    return path.endsWith('/agent');\n  }\n\n  // Reads as \"creating a Customer\" rather than \"Create a Customer\" in the banner\n  get sessionVerb(): string {\n    switch (this.sessionInfo?.sessionType) {\n      case 'Create': return 'Creating';\n      case 'Edit': return 'Editing';\n      case 'Delete': return 'Deleting';\n      case 'BatchPost': return 'Batch posting';\n      default: return 'Working on';\n    }\n  }\n\n  // Changed: switching threads. The agent has always kept several conversations per user, but the widget\n  // could only ever show the newest one — earlier threads existed and were unreachable.\n  selectConversation(id: number) {\n    if (id === this.currentConversationId) return;\n    this.showConversations = false;\n    this.agentService.loadMessages(id);\n  }\n\n  toggleConversationList() {\n    this.showConversations = !this.showConversations;\n    if (this.showConversations) this.agentService.loadConversations();\n  }\n\n  ngAfterViewChecked(): void {\n    if (this.shouldScroll) {\n      this.scrollToBottom();\n      this.shouldScroll = false;\n    }\n  }\n\n  toggleChat() {\n    this.agentService.toggle();\n  }\n\n  // Changed: Close chat when clicking outside the chat window and FAB button\n  @HostListener('document:click', ['$event'])\n  onDocumentClick(event: MouseEvent) {\n    if (this.pageMode) return; // Changed: a page does not close when you click the page — outside-click close is float-only\n    if (!this.isOpen) return;\n\n    // Changed: match on composedPath() instead of closest(). A control that re-renders the widget removes\n    // itself from the DOM before this handler runs — the mic button lives inside *ngIf=\"!isRecording\", so\n    // starting a recording detaches it. closest() on a detached node finds nothing, and the widget used to\n    // close itself the instant recording began, leaving the mic live behind a hidden window.\n    //\n    // cdk-overlay-container is checked for the same reason: Material renders menus, tooltips and dialogs in\n    // an overlay attached to <body>, OUTSIDE .agent-window. Without this, picking an item from the attach\n    // menu closed the whole chat. Any overlay open on top of the widget counts as being inside it.\n    const path = (event.composedPath ? event.composedPath() : []) as HTMLElement[];\n    if (path.some(el => el?.classList?.contains('agent-window')\n      || el?.classList?.contains('agent-fab')\n      || el?.classList?.contains('cdk-overlay-container'))) return;\n\n    // Fallback for browsers without composedPath, and for targets still attached\n    const target = event.target as HTMLElement;\n    if (target?.isConnected && (target.closest('.agent-window') || target.closest('.agent-fab'))) return;\n\n    // A detached target means the click came from a control that just re-rendered — i.e. inside the widget\n    if (target && !target.isConnected) return;\n\n    this.agentService.close();\n  }\n\n  // Changed: sends whatever is staged — typed text, an attached photo, or both. A recording in progress is\n  // stopped and folded into the same send rather than being lost.\n  sendMessage() {\n    if (this.isRecording) { this.stopMode = 'send'; this.recorder?.stop(); return; }\n\n    const caption = this.inputText.trim();\n    if (!caption && !this.pendingPhoto) return;\n\n    if (this.pendingPhoto) {\n      this.agentService.sendComposed(this.pendingPhoto, this.pendingPhoto.name || 'photo.jpg', null, '', caption);\n      this.pendingPhoto = null;\n    } else {\n      this.agentService.sendMessage(caption);\n    }\n\n    this.inputText = '';\n  }\n\n  // Changed: true when there is anything worth sending\n  get canSend(): boolean {\n    return !!this.inputText.trim() || !!this.pendingPhoto;\n  }\n\n  clearPhoto() {\n    this.pendingPhoto = null;\n  }\n\n  sendSuggested(question: string) {\n    this.agentService.sendMessage(question);\n  }\n\n  onKeydown(event: KeyboardEvent) {\n    if (event.key === 'Enter' && !event.shiftKey) {\n      event.preventDefault();\n      this.sendMessage();\n    }\n  }\n\n  newConversation() {\n    this.agentService.newConversation();\n  }\n\n  // Changed: mm:ss shown while recording\n  get recordDisplay(): string {\n    const mins = Math.floor(this.recordSeconds / 60);\n    const secs = this.recordSeconds % 60;\n    return `${mins}:${secs < 10 ? '0' : ''}${secs}`;\n  }\n\n  // Changed: voice note capture — the clip goes straight to the backend, which transcribes it and feeds the\n  // text into the agent exactly as Telegram and WhatsApp voice notes are handled\n  async startRecording() {\n    if (this.isRecording) return;\n    this.mediaError = '';\n\n    if (!navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === 'undefined') {\n      this.mediaError = 'Voice notes are not supported in this browser.';\n      return;\n    }\n\n    try {\n      this.mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n    } catch {\n      this.mediaError = 'Microphone access was blocked. Allow it in your browser settings to send voice notes.';\n      return;\n    }\n\n    this.chunks = [];\n    this.stopMode = 'send';\n\n    const mimeType = this.pickAudioMimeType();\n    this.recorder = mimeType ? new MediaRecorder(this.mediaStream, { mimeType }) : new MediaRecorder(this.mediaStream);\n    this.recorder.ondataavailable = e => { if (e.data && e.data.size > 0) this.chunks.push(e.data); };\n    this.recorder.onstop = () => this.finishRecording();\n    this.recorder.start();\n\n    this.isRecording = true;\n    this.recordSeconds = 0;\n    this.recordTimer = setInterval(() => {\n      this.recordSeconds++;\n      if (this.recordSeconds >= AgentComponent.MAX_RECORD_SECONDS) this.stopRecording();\n    }, 1000);\n  }\n\n  // Changed: send immediately — the clip goes with whatever else is staged, no review step\n  stopRecording() {\n    if (!this.isRecording || !this.recorder) return;\n    this.stopMode = 'send';\n    this.recorder.stop(); // finishRecording() runs from onstop\n  }\n\n  // Changed: stop and transcribe INTO the text box so the user can read it back, edit it, and send when ready\n  stopAndTranscribe() {\n    if (!this.isRecording || !this.recorder) return;\n    this.stopMode = 'transcribe';\n    this.recorder.stop();\n  }\n\n  cancelRecording() {\n    if (!this.isRecording || !this.recorder) return;\n    this.stopMode = 'cancel';\n    this.recorder.stop();\n  }\n\n  // ---------------------------------------------------------------------------------------------------\n  // Voice mode\n  // ---------------------------------------------------------------------------------------------------\n\n  // Tap versus hold on the single mic button. The composer row is full — attach, text, mic, send — so voice\n  // mode gets a gesture rather than a fifth control that would squeeze the text field on a phone. Same idea\n  // as holding the mic in WhatsApp: the button keeps its obvious job, the second mode hides behind the hold.\n  micHeld = false;\n  private micHoldTimer: any = null;\n  private micHoldFired = false;\n\n  private static readonly MIC_HOLD_MS = 500; // long enough not to fire on a normal tap\n\n  onMicPressStart() {\n    if (this.voiceMode || this.isRecording) return;\n\n    this.micHeld = true;\n    this.micHoldFired = false;\n\n    this.micHoldTimer = setTimeout(() => {\n      this.micHeld = false;\n      this.micHoldFired = true; // swallows the click that follows the release\n      if (navigator.vibrate) navigator.vibrate(30); // confirms the mode switch without needing to look\n      this.startVoiceMode();\n    }, AgentComponent.MIC_HOLD_MS);\n  }\n\n  onMicPressEnd() {\n    this.micHeld = false;\n    if (this.micHoldTimer) { clearTimeout(this.micHoldTimer); this.micHoldTimer = null; }\n  }\n\n  // Runs after pointerup. A hold has already acted, so the click that follows it must do nothing.\n  onMicClick() {\n    if (this.micHoldFired) { this.micHoldFired = false; return; }\n    this.startRecording();\n  }\n\n  // Entering is the ONLY user gesture in the whole session, so everything that needs one happens here: iOS\n  // will not let audio play later unless an AudioContext was created and resumed inside a real tap.\n  async startVoiceMode() {\n    if (this.voiceMode) return;\n\n    this.voiceError = '';\n    this.voiceTranscript = '';\n    this.voiceReply = '';\n\n    if (!navigator.mediaDevices?.getUserMedia || typeof MediaRecorder === 'undefined') {\n      this.voiceError = 'Voice mode is not supported in this browser.';\n      return;\n    }\n\n    if (this.isRecording) this.cancelRecording(); // never run both capture paths at once\n\n    try {\n      const Ctx = (window as any).AudioContext || (window as any).webkitAudioContext;\n      this.audioContext = new Ctx();\n      if (this.audioContext!.state === 'suspended') await this.audioContext!.resume();\n    } catch {\n      this.voiceError = 'Audio could not be started in this browser.';\n      return;\n    }\n\n    this.voiceMode = true;\n    this.silentSince = Date.now();\n    await this.beginListening();\n  }\n\n  // One tap out, from anywhere in the loop. Everything is torn down: recorder, microphone, playback, timers.\n  stopVoiceMode() {\n    this.voiceMode = false;\n    this.setVoiceState('idle');\n    this.voiceLevel = 0;\n\n    this.abandonUtterance = true;\n    this.stopVoiceCapture();\n    this.stopPlayback();\n\n    if (this.audioContext) {\n      try { this.audioContext.close(); } catch {}\n      this.audioContext = null;\n    }\n  }\n\n  // Opens the mic and waits. The clip records from the moment the mic opens, so the first syllable is never\n  // clipped — the detector decides afterwards whether anything worth sending was actually said.\n  private async beginListening() {\n    if (!this.voiceMode) return;\n\n    try {\n      // These three constraints were all settled by measurement on a real machine, not by reasoning:\n      //\n      // echoCancellation ON  — without it the microphone hears the agent's OWN reply from the speakers and\n      //                        answers itself; a spoken reply came back as the next command.\n      // noiseSuppression OFF — tried ON to fight fan noise and it crushed the voice instead: a normal\n      //                        speaking voice fell from 0.15 to 0.026 RMS, barely grazing the threshold, and\n      //                        no utterance was ever captured. Steady noise is already handled better by the\n      //                        per-cycle noise-floor calibration and the sustained-onset rule below, neither\n      //                        of which costs any signal.\n      // autoGainControl ON   — also tried OFF (to keep levels stable for calibration) and that made it worse\n      //                        still, 0.008 RMS. A drifting floor beats a microphone that cannot hear you.\n      this.voiceStream = await navigator.mediaDevices.getUserMedia({\n        audio: {\n          echoCancellation: true,\n          noiseSuppression: false,\n          autoGainControl: true\n        }\n      });\n    } catch {\n      this.voiceError = 'Microphone access was blocked. Allow it in your browser settings to use voice mode.';\n      this.stopVoiceMode();\n      return;\n    }\n\n    if (!this.voiceMode) { // exited while the permission prompt was up\n      this.voiceStream.getTracks().forEach(t => t.stop());\n      this.voiceStream = null;\n      return;\n    }\n\n    this.voiceChunks = [];\n    this.abandonUtterance = false;\n    this.speechStartedAt = 0;\n    this.listenStartedAt = Date.now();\n    this.lastLoudAt = 0;\n    this.loudSince = 0;\n\n    // Re-measure the room on every cycle: an engine starts, a window opens, the air-con changes note\n    this.calibrationSamples = [];\n    this.calibrationEndsAt = Date.now() + AgentComponent.CALIBRATION_MS;\n\n    const mimeType = this.pickAudioMimeType();\n    this.voiceRecorder = mimeType\n      ? new MediaRecorder(this.voiceStream, { mimeType })\n      : new MediaRecorder(this.voiceStream);\n    this.voiceRecorder.ondataavailable = e => { if (e.data && e.data.size > 0) this.voiceChunks.push(e.data); };\n    this.voiceRecorder.onstop = () => this.onUtteranceCaptured();\n    this.voiceRecorder.start();\n\n    // NOT 'listening' yet — the room is being measured first. The \"your turn\" tone and the Listening label\n    // both wait for calibration to finish, so the tone always means the same thing: start talking now.\n    this.setVoiceState('starting');\n    this.startVad();\n  }\n\n  // Voice activity detection: RMS over a short window, no dependencies. Speech starts when it goes loud, ends\n  // after a run of quiet — which is what makes the turn hands-free, since nothing has to be pressed to stop.\n  private startVad() {\n    if (!this.audioContext || !this.voiceStream) return;\n\n    const source = this.audioContext.createMediaStreamSource(this.voiceStream);\n    this.analyser = this.audioContext.createAnalyser();\n    this.analyser.fftSize = 1024;\n    source.connect(this.analyser);\n\n    const samples = new Uint8Array(this.analyser.fftSize);\n\n    this.vadTimer = setInterval(() => {\n      if (!this.analyser) return;\n\n      this.analyser.getByteTimeDomainData(samples);\n\n      let sum = 0;\n      for (let i = 0; i < samples.length; i++) {\n        const deviation = (samples[i] - 128) / 128;\n        sum += deviation * deviation;\n      }\n      const rms = Math.sqrt(sum / samples.length);\n\n      this.voiceLevel = Math.min(1, rms / 0.15); // meter only — the decision uses rms directly\n      this.evaluateVad(rms);\n    }, 50);\n  }\n\n  private evaluateVad(rms: number) {\n    const now = Date.now();\n\n    // Phase 0 — listen to the ROOM before listening to the person. A fixed threshold cannot know whether it\n    // is sitting in a quiet office or next to a fan, so the first moments of every listening cycle measure the\n    // ambient level and the speech threshold is set above it. This is what stops a fan being heard as speech.\n    if (this.calibrationEndsAt) {\n      if (now < this.calibrationEndsAt) { this.calibrationSamples.push(rms); return; }\n\n      this.applyCalibration();\n\n      // Only NOW is it actually listening to the person, so this is where the label flips and the \"your turn\"\n      // tone plays. The listening clock restarts here too — the calibration window must not count against the\n      // idle timeout, or a slow starter loses part of their thinking time.\n      this.setVoiceState('listening');\n      this.listenStartedAt = now;\n      this.earcon('ready');\n    }\n\n    const enterThreshold = this.activeThreshold;\n    // Hysteresis: once someone is speaking it takes LESS to keep them speaking. Without this, the natural dip\n    // between words reads as the end of the sentence.\n    const stayThreshold = enterThreshold * AgentComponent.CONTINUE_RATIO;\n\n    if (!this.speechStartedAt) {\n      // Not speaking yet. Loudness must be SUSTAINED to count — a door, a keyboard, a fan surge is loud for\n      // an instant, and a single loud sample used to be enough to start capturing.\n      if (rms >= enterThreshold) {\n        if (!this.loudSince) this.loudSince = now;\n\n        if (now - this.loudSince >= this.onsetMs) {\n          this.speechStartedAt = this.loudSince; // backdated, so the first word is not clipped\n          this.lastLoudAt = now;\n          this.setVoiceState('capturing');\n          this.silentSince = 0; // they are talking, so the give-up clock stops\n          this.earcon('gotyou'); // \"I can hear you\" — answers the question the old single beep left open\n        }\n      } else {\n        this.loudSince = 0; // a blip, not a sentence\n      }\n    } else {\n      // Mid-sentence. Pauses and breaths are expected — only a long quiet ends the turn.\n      if (rms >= stayThreshold) {\n        this.lastLoudAt = now;\n      } else if (now - this.lastLoudAt >= this.silenceMs) {\n        // Too short to be a sentence? Then it was a noise — throw it away instead of asking the model to\n        // find words in it, which is where \"Hallo!\" and other invented transcripts come from.\n        const spoken = this.lastLoudAt - this.speechStartedAt;\n        this.endUtterance(spoken < this.minSpeechMs);\n        return;\n      }\n\n      if (now - this.speechStartedAt >= AgentComponent.MAX_UTTERANCE_MS) this.endUtterance(false);\n      return;\n    }\n\n    // Nothing said yet — don't upload silence. Reopen the mic instead of ending the session, because someone\n    // driving may simply not be ready to talk yet.\n    // The speechStartedAt guard matters: the branch above can START speech on this very sample, and without\n    // it the idle check below would immediately throw that fresh utterance away.\n    if (!this.speechStartedAt && now - this.listenStartedAt >= AgentComponent.IDLE_MS) {\n      if (!this.silentSince) this.silentSince = now;\n\n      if (now - this.silentSince >= AgentComponent.MAX_SILENT_MS) {\n        this.voiceError = 'Voice mode ended after a long silence.';\n        this.stopVoiceMode();\n        return;\n      }\n\n      this.endUtterance(true); // drop this clip and listen again\n    }\n  }\n\n  // Turns the room measurement into a working threshold. Uses a high percentile rather than the average so a\n  // steady hum sets the floor without one loud knock dragging it up, then requires speech to be several times\n  // that. The configured voiceThreshold acts as a floor only — a noisy room can raise the bar, never lower it.\n  private applyCalibration() {\n    this.calibrationEndsAt = 0;\n\n    const samples = this.calibrationSamples.slice().sort((a, b) => a - b);\n    this.calibrationSamples = [];\n\n    if (!samples.length) { this.activeThreshold = this.voiceThreshold; return; }\n\n    const percentile = samples[Math.min(samples.length - 1, Math.floor(samples.length * 0.9))];\n    this.noiseFloor = percentile;\n\n    // Clamped at BOTH ends. The upper clamp is not theoretical: calibrating while someone was still talking\n    // measured a \"room\" of 0.17 and set the bar at 0.52 — around three times louder than any normal voice, so\n    // the microphone was open and permanently deaf. A ceiling means the worst case is over-sensitivity, which\n    // the onset rule and minimum-utterance check still catch, rather than total silence.\n    const scaled = percentile * this.noiseMultiplier;\n    this.activeThreshold = Math.min(this.maxThreshold, Math.max(this.voiceThreshold, scaled));\n  }\n\n  // Ends the current capture. `abandon` means the clip is thrown away rather than sent.\n  private endUtterance(abandon: boolean) {\n    this.abandonUtterance = abandon;\n\n    if (this.vadTimer) { clearInterval(this.vadTimer); this.vadTimer = null; }\n    this.voiceLevel = 0;\n\n    if (this.voiceRecorder && this.voiceRecorder.state !== 'inactive') {\n      this.voiceRecorder.stop(); // onUtteranceCaptured() runs from onstop\n    } else {\n      this.onUtteranceCaptured();\n    }\n  }\n\n  // The microphone is released HERE, before anything is sent — so it is provably shut for the whole of\n  // thinking and speaking, which is what keeps the session half-duplex.\n  private onUtteranceCaptured() {\n    const chunks = this.voiceChunks;\n    const mimeType = this.voiceRecorder?.mimeType || 'audio/webm';\n\n    this.releaseMic();\n\n    if (!this.voiceMode) return;\n\n    if (this.abandonUtterance || !chunks.length) {\n      this.voiceChunks = [];\n      this.beginListening(); // nothing worth sending — straight back to listening\n      return;\n    }\n\n    this.voiceChunks = [];\n    this.setVoiceState('thinking');\n\n    const blob = new Blob(chunks, { type: mimeType });\n    const fileName = `voice-turn.${this.extensionFor(mimeType)}`;\n\n    this.agentService.voiceTurn(blob, fileName).subscribe({\n      next: (res: any) => this.onTurnAnswered(res),\n      error: () => this.speakThenListen('', 'Sorry, that did not get through. Please try again.')\n    });\n  }\n\n  private onTurnAnswered(res: any) {\n    if (!this.voiceMode) return;\n\n    const data = res?.data || {};\n\n    if (data.transcript) {\n      this.voiceTranscript = data.transcript;\n      this.agentService.appendSpokenMessage(data.transcript); // the spoken turn joins the normal thread\n    }\n\n    const reply = data.replyText || res?.message || 'Sorry, something went wrong.';\n    this.speakThenListen(data.audioBase64, reply, data.audioMimeType);\n  }\n\n  // Plays the answer, then reopens the microphone STRICTLY on 'ended'. Never before — that ordering is the\n  // half-duplex guarantee, and it is why no echo cancellation is needed anywhere in this feature.\n  private speakThenListen(audioBase64: string, replyText: string, mimeType: string = 'audio/mpeg') {\n    this.voiceReply = replyText;\n    this.setVoiceState('speaking');\n\n    if (!audioBase64) {\n      // No audio came back (a network failure, or speech synthesis was unavailable server-side). Say it with\n      // the browser's own voice rather than leaving someone who cannot look at the screen in silence.\n      this.speakFallback(replyText);\n      return;\n    }\n\n    this.stopPlayback();\n\n    this.player = new Audio(`data:${mimeType || 'audio/mpeg'};base64,${audioBase64}`);\n    // Keep the label honest: 'speaking' is re-asserted when sound actually starts, not merely when it was\n    // requested, so the indicator never claims to be doing something the ear cannot hear yet.\n    this.player.onplaying = () => { if (this.voiceMode) this.setVoiceState('speaking'); };\n    this.player.onended = () => this.afterSpeaking();\n    this.player.onerror = () => this.afterSpeaking();\n\n    this.player.play().catch(() => this.afterSpeaking()); // autoplay refused → don't hang the loop\n  }\n\n  // Browser speech synthesis, used only when the server could not produce audio.\n  // Chrome's utterance.onend is unreliable for long text — it can fire early or not at all, which is what made\n  // the panel say \"Listening\" while a voice was still talking. So the end of speech is confirmed by POLLING\n  // speechSynthesis.speaking rather than by trusting the event.\n  private speakFallback(text: string) {\n    const synth = (window as any).speechSynthesis;\n\n    if (!synth || !text) { this.afterSpeaking(); return; }\n\n    try {\n      const utterance = new (window as any).SpeechSynthesisUtterance(text);\n      synth.speak(utterance);\n\n      const started = Date.now();\n      const watch = setInterval(() => {\n        const stillTalking = synth.speaking || synth.pending;\n        const tooLong = Date.now() - started > 60000; // never wedge the loop on a stuck engine\n\n        if (!this.voiceMode) { clearInterval(watch); return; }\n        if (stillTalking && !tooLong) { this.setVoiceState('speaking'); return; }\n\n        clearInterval(watch);\n        this.afterSpeaking();\n      }, 200);\n    } catch {\n      this.afterSpeaking();\n    }\n  }\n\n  // 'ended' means the audio element finished, NOT that the room is quiet: the last of it is still leaving the\n  // speakers and reverberating. Reopening instantly meant the mic caught the tail of the agent's own sentence\n  // and, worse, calibrated the noise floor against it. A short settle keeps the loop honest.\n  private afterSpeaking() {\n    this.player = null;\n    if (!this.voiceMode) return;\n\n    setTimeout(() => { if (this.voiceMode) this.beginListening(); }, AgentComponent.SETTLE_MS);\n  }\n\n  // Three tones, each meaning exactly ONE thing, because \"a beep happened\" is not information:\n  //\n  //   ready  — rising two-note, plays when it is ready FOR YOU.        \"Start talking now.\"\n  //   gotyou — single soft note, plays the moment your speech is       \"I can hear you, keep going.\"\n  //            detected, so you know you were picked up\n  //   taken  — falling two-note, plays when the mic closes and it      \"I have it, I'm working on it.\"\n  //            starts working\n  //\n  // Rising always means the floor is yours; falling always means it has been taken away. That direction is\n  // the whole cue — it can be recognised without looking and without remembering pitches.\n  private earcon(kind: 'ready' | 'gotyou' | 'taken') {\n    if (!this.audioContext) return;\n\n    const notes = kind === 'ready' ? [660, 990]\n                : kind === 'taken' ? [660, 440]\n                : [880];\n\n    try {\n      const start = this.audioContext.currentTime;\n\n      notes.forEach((frequency, index) => {\n        const oscillator = this.audioContext!.createOscillator();\n        const gain = this.audioContext!.createGain();\n\n        oscillator.type = 'sine';\n        oscillator.frequency.value = frequency;\n\n        const at = start + index * 0.1;\n        const peak = kind === 'gotyou' ? 0.06 : 0.12; // the mid-speech cue is deliberately quieter\n\n        gain.gain.setValueAtTime(0.0001, at);\n        gain.gain.exponentialRampToValueAtTime(peak, at + 0.01);\n        gain.gain.exponentialRampToValueAtTime(0.0001, at + 0.09);\n\n        oscillator.connect(gain);\n        gain.connect(this.audioContext!.destination);\n        oscillator.start(at);\n        oscillator.stop(at + 0.1);\n      });\n    } catch {}\n  }\n\n  private releaseMic() {\n    if (this.vadTimer) { clearInterval(this.vadTimer); this.vadTimer = null; }\n\n    this.analyser = null;\n    this.voiceRecorder = null;\n    this.voiceLevel = 0;\n\n    if (this.voiceStream) {\n      this.voiceStream.getTracks().forEach(t => t.stop());\n      this.voiceStream = null;\n      this.earcon('taken'); // \"I have it\" — the floor is no longer yours\n    }\n  }\n\n  private stopVoiceCapture() {\n    if (this.voiceRecorder && this.voiceRecorder.state !== 'inactive') {\n      try { this.voiceRecorder.stop(); } catch {}\n    }\n    this.releaseMic();\n    this.voiceChunks = [];\n  }\n\n  private stopPlayback() {\n    if (!this.player) return;\n    try { this.player.pause(); this.player.currentTime = 0; } catch {}\n    this.player.onended = null;\n    this.player.onerror = null;\n    this.player = null;\n\n    const synth = (window as any).speechSynthesis;\n    if (synth) { try { synth.cancel(); } catch {} }\n  }\n\n  // What the state indicator reads. Plain words, because it is glanced at rather than read.\n  get voiceStateLabel(): string {\n    switch (this.voiceState) {\n      // Changed: shown during room calibration. \"Wait\" rather than \"Listening\", because talking during this\n      // window is actively harmful — the words get measured as background noise.\n      case 'starting': return 'Getting ready';\n      case 'listening': return 'Listening';\n      // Changed: capturing is now shown. It tells the user it has locked onto their voice and is WAITING for\n      // them to finish — without it, a long pause feels like the thing has stopped paying attention.\n      case 'capturing': return 'Hearing you';\n      case 'thinking': return 'Thinking';\n      case 'speaking': return 'Speaking';\n      default: return '';\n    }\n  }\n\n  get voiceStateIcon(): string {\n    switch (this.voiceState) {\n      case 'starting': return 'graphic_eq'; // measuring the room, not the person\n      case 'listening':\n      case 'capturing': return 'mic';\n      case 'thinking': return 'hourglass_top';\n      case 'speaking': return 'volume_up';\n      default: return 'mic_off';\n    }\n  }\n\n  // Changed: \"Take photo\" — hands off to the device camera. On a phone this opens the camera app on the rear\n  // lens and returns the shot; no in-page camera permission is involved because the OS handles it. Desktop\n  // browsers ignore `capture` and fall back to the file picker.\n  takePhoto() {\n    this.cameraInput?.nativeElement.click();\n  }\n\n  // Changed: \"Choose photo\" — same input minus `capture`, so it opens the gallery / file picker\n  choosePhoto() {\n    this.galleryInput?.nativeElement.click();\n  }\n\n  // Changed: photo capture now STAGES the file instead of sending it. Nothing leaves until the user presses\n  // send, so they can add a typed or spoken caption first — that caption is the actual command, the photo is\n  // the evidence it refers to. `capture` opens the camera directly on mobile, the file picker on desktop.\n  onPhotoSelected(event: Event) {\n    const input = event.target as HTMLInputElement;\n    const file = input.files && input.files.length ? input.files[0] : null;\n    input.value = ''; // Reset so picking the same file twice still fires a change event\n\n    if (!file) return;\n\n    this.pendingPhoto = file;\n    this.focusInput();\n  }\n\n  // Picks a container the browser can record AND the transcription endpoint accepts. Chrome/Edge/Firefox give\n  // webm/opus, Safari gives mp4 — both are supported server-side, so no transcoding is needed anywhere.\n  private pickAudioMimeType(): string {\n    const candidates = ['audio/webm;codecs=opus', 'audio/webm', 'audio/mp4', 'audio/ogg;codecs=opus', 'audio/ogg'];\n    return candidates.find(t => MediaRecorder.isTypeSupported(t)) || '';\n  }\n\n  private finishRecording() {\n    const mode = this.stopMode;\n    this.clearRecording();\n\n    if (mode === 'cancel' || !this.chunks.length) {\n      this.chunks = [];\n      return;\n    }\n\n    const type = this.recorder?.mimeType || 'audio/webm';\n    const blob = new Blob(this.chunks, { type });\n    const fileName = `voice-note.${this.extensionFor(type)}`;\n    this.chunks = [];\n\n    // Stop → transcribe into the text box for review; the photo (if any) stays staged\n    if (mode === 'transcribe') {\n      this.isTranscribing = true;\n      this.agentService.transcribeOnly(blob, fileName).subscribe({\n        next: (res: any) => {\n          this.isTranscribing = false;\n          if (res?.success && res.data?.text) {\n            const existing = this.inputText.trim();\n            this.inputText = existing ? `${existing} ${res.data.text}` : res.data.text;\n            this.focusInput();\n          } else {\n            this.mediaError = res?.message || 'Sorry, that recording could not be transcribed.';\n          }\n        },\n        error: () => {\n          this.isTranscribing = false;\n          this.mediaError = 'Sorry, that recording could not be transcribed.';\n        }\n      });\n      return;\n    }\n\n    // Send → the clip goes with the staged photo and whatever is typed, all in one message\n    this.agentService.sendComposed(\n      this.pendingPhoto, this.pendingPhoto?.name || 'photo.jpg',\n      blob, fileName,\n      this.inputText.trim()\n    );\n\n    this.pendingPhoto = null;\n    this.inputText = '';\n  }\n\n  private extensionFor(mimeType: string): string {\n    const type = (mimeType || '').toLowerCase();\n    if (type.indexOf('mp4') >= 0) return 'mp4';\n    if (type.indexOf('ogg') >= 0) return 'ogg';\n    return 'webm';\n  }\n\n  // Releases the mic — without this the browser keeps showing the recording indicator\n  private clearRecording() {\n    this.isRecording = false;\n    this.recordSeconds = 0;\n\n    if (this.recordTimer) {\n      clearInterval(this.recordTimer);\n      this.recordTimer = null;\n    }\n\n    if (this.mediaStream) {\n      this.mediaStream.getTracks().forEach(t => t.stop());\n      this.mediaStream = null;\n    }\n  }\n\n  private scrollToBottom() {\n    try {\n      if (this.messageContainer) {\n        this.messageContainer.nativeElement.scrollTop = this.messageContainer.nativeElement.scrollHeight;\n      }\n    } catch (e) {}\n  }\n\n  private focusInput() {\n    setTimeout(() => {\n      if (this.messageInput) {\n        this.messageInput.nativeElement.focus();\n      }\n    }, 300);\n  }\n\n  trackMessage(index: number, msg: AgentMessage): string {\n    return `${index}-${msg.role}-${msg.createdDate}`;\n  }\n\n  // Changed: Set --agent-vh CSS variable from visualViewport so the chat resizes when the mobile keyboard opens\n  private initMobileViewport() {\n    if (!window.visualViewport) return;\n    this.viewportHandler = () => {\n      const vh = window.visualViewport!.height;\n      document.documentElement.style.setProperty('--agent-vh', `${vh}px`);\n      // Changed: one signal, a second consumer. When the on-screen keyboard opens the visual viewport\n      // collapses well below the layout viewport; the fixed bottom tab bar has to get out of the way or it\n      // sits between the keyboard and the field being typed into. Published as a class on <html> so the tab\n      // bar reacts in CSS alone — deliberately NOT a second visualViewport listener of its own.\n      // 0.75 is the usual heuristic: real keyboards take 30-50% of the height, browser chrome far less.\n      document.documentElement.classList.toggle('keyboard-open', vh < window.innerHeight * 0.75);\n    };\n    window.visualViewport.addEventListener('resize', this.viewportHandler);\n    this.viewportHandler(); // Set initial value\n  }\n\n  ngOnDestroy(): void {\n    this.subs.forEach(s => s.unsubscribe());\n    if (this.isRecording) this.cancelRecording(); // Changed: never leave the mic open behind a destroyed widget\n    if (this.voiceMode) this.stopVoiceMode();     // Changed: same for a voice session — no orphaned mic\n    this.onMicPressEnd();                          // Changed: a held mic must not fire after teardown\n    this.clearRecording();\n    if (this.viewportHandler && window.visualViewport) {\n      window.visualViewport.removeEventListener('resize', this.viewportHandler);\n      document.documentElement.classList.remove('keyboard-open'); // Changed: never leave the tab bar hidden by a destroyed widget\n    }\n  }\n}\n","<!-- Floating chat widget for in-app Agent (renamed from Assistant) -->\n\n<!-- FAB toggle button -->\n<!-- Changed: the page presentation has no FAB — the page IS the chat, so a button to open it is nonsense.\n     Changed: showFab also stands the FAB down on mobile (the bottom tab bar's Chat tab replaces it) and on\n     the home/agent route at any width, where it would otherwise hover over the page it opens. -->\n<button mat-fab class=\"agent-fab\" *ngIf=\"showFab\" (click)=\"toggleChat()\" [matTooltip]=\"agentName\">\n  <mat-icon>{{ isOpen ? 'close' : 'chat_bubble' }}</mat-icon>\n</button>\n\n<!-- Chat window -->\n<!-- Changed: rendered unconditionally in page mode (isOpen only governs the floating window); .page-mode\n     swaps the fixed overlay for in-flow layout and 'none' opts out of the slide-up animation -->\n<!-- Changed: showWindow keeps the floating window off wherever its FAB is off, so mobile and the chat route\n     can never show two chat surfaces at once -->\n<div class=\"agent-window\" [class.page-mode]=\"pageMode\" *ngIf=\"showWindow\" [@slideUp]=\"pageMode ? 'none' : 'float'\">\n\n  <!-- Header with online status -->\n  <div class=\"agent-header\">\n    <div class=\"header-info\">\n      <mat-icon class=\"header-icon\">smart_toy</mat-icon>\n      <div class=\"header-text\">\n        <span class=\"header-title\">{{ agentName }}</span>\n        <span class=\"status-badge\" [class.online]=\"isOnline\" [class.offline]=\"!isOnline\">\n          <span class=\"status-dot\"></span>\n          {{ isOnline ? 'Online' : 'Offline' }}\n        </span>\n      </div>\n    </div>\n    <div class=\"header-actions\">\n      <!-- Changed: earlier conversations existed but were unreachable — the widget only ever showed the newest -->\n      <button mat-icon-button matTooltip=\"Conversations\" (click)=\"toggleConversationList()\">\n        <mat-icon>forum</mat-icon>\n      </button>\n      <button mat-icon-button matTooltip=\"New conversation\" (click)=\"newConversation()\">\n        <mat-icon>add_comment</mat-icon>\n      </button>\n      <!-- Changed: minimise is float-only — there is nothing to minimise a routed page into -->\n      <button mat-icon-button matTooltip=\"Close\" *ngIf=\"!pageMode\" (click)=\"toggleChat()\">\n        <mat-icon>remove</mat-icon>\n      </button>\n    </div>\n  </div>\n\n  <!-- Conversation switcher. A dropdown rather than a panel: the window is small and this is a jump list,\n       not somewhere the user spends time. -->\n  <div class=\"agent-conversations\" *ngIf=\"showConversations\">\n    <div class=\"conversation-row\" *ngFor=\"let c of conversations\"\n         [class.current]=\"c.conversationID === currentConversationId\"\n         (click)=\"selectConversation(c.conversationID)\">\n      <mat-icon class=\"conversation-icon\">chat</mat-icon>\n      <span class=\"conversation-title\">{{ c.title }}</span>\n    </div>\n    <div class=\"conversation-empty\" *ngIf=\"conversations.length === 0\">No earlier conversations</div>\n  </div>\n\n  <!-- Changed: the session banner. The agent has always known it was holding a half-built record; until the\n       reply carried structured state, that fact only existed as prose the user had to read carefully. -->\n  <div class=\"agent-session-banner\" *ngIf=\"sessionInfo?.sessionType\">\n    <mat-icon class=\"session-icon\">edit_note</mat-icon>\n    <span class=\"session-text\">{{ sessionVerb }} a {{ sessionInfo?.modelName }}</span>\n    <!-- Changed: chips rather than a sentence. What is still required is the one thing the user has to act\n         on, and a chip per field is scannable where a comma-separated list inside a sentence is not. -->\n    <span class=\"session-chip\" *ngFor=\"let field of sessionInfo?.missingFields\">{{ field | camelToWords }}</span>\n  </div>\n\n  <!-- Messages area -->\n  <div class=\"agent-messages\" #messageContainer>\n\n    <!-- Welcome experience (show when no messages) -->\n    <div class=\"agent-greeting\" *ngIf=\"messages.length === 0\">\n      <mat-icon class=\"greeting-icon\">smart_toy</mat-icon>\n      <p class=\"greeting-text\">{{ greeting }}</p>\n\n      <!-- Three capability pillars -->\n      <div class=\"capability-pillars\">\n\n        <!-- Pillar 1: Navigate & Inquire -->\n        <div class=\"pillar\" (click)=\"sendSuggested('How do I post a transaction?')\">\n          <div class=\"pillar-header\">\n            <mat-icon class=\"pillar-icon\">explore</mat-icon>\n            <span class=\"pillar-title\">Ask & Navigate</span>\n          </div>\n          <p class=\"pillar-desc\">Ask how to do things or find features in the app</p>\n          <span class=\"pillar-example\">\"How do I post a transaction?\"</span>\n        </div>\n\n        <!-- Pillar 2: Create & Modify -->\n        <div class=\"pillar\" (click)=\"sendSuggested('Create a new customer')\">\n          <div class=\"pillar-header\">\n            <mat-icon class=\"pillar-icon\">edit_note</mat-icon>\n            <span class=\"pillar-title\">Create & Modify</span>\n          </div>\n          <p class=\"pillar-desc\">Add, edit, or delete records using natural language</p>\n          <span class=\"pillar-example\">\"Create a new customer called Acme Ltd\"</span>\n        </div>\n\n        <!-- Pillar 3: Get Information -->\n        <div class=\"pillar\" (click)=\"sendSuggested('List all accounts')\">\n          <div class=\"pillar-header\">\n            <mat-icon class=\"pillar-icon\">search</mat-icon>\n            <span class=\"pillar-title\">Get Information</span>\n          </div>\n          <p class=\"pillar-desc\">Retrieve details, list records, or get summaries</p>\n          <span class=\"pillar-example\">\"Show me the details of Customer A\"</span>\n        </div>\n\n      </div>\n    </div>\n\n    <!-- Message bubbles -->\n    <ng-container *ngFor=\"let msg of messages; trackBy: trackMessage\">\n\n      <!-- Changed: a conversation boundary is drawn, not spoken. Without a visible line, the agent starting a\n           fresh thread after a long gap just looks like it forgetting what was said. -->\n      <div class=\"conversation-divider\" *ngIf=\"msg.divider\">\n        <span class=\"divider-label\">{{ msg.content }}</span>\n      </div>\n\n      <div *ngIf=\"!msg.divider\" class=\"message-row\" [class.user-row]=\"msg.role === 'user'\" [class.agent-row]=\"msg.role === 'assistant'\">\n        <!-- Changed: agent replies are markdown and were being printed verbatim, so a carefully formatted\n             answer arrived as a wall of asterisks. User messages stay plain text — they are not markdown,\n             and interpreting them as such would be putting words in the user's mouth. -->\n        <div class=\"message-bubble\" [class.user-bubble]=\"msg.role === 'user'\" [class.agent-bubble]=\"msg.role === 'assistant'\" [class.pending-bubble]=\"msg.pending\">\n          <span *ngIf=\"msg.role === 'assistant'\" [innerHTML]=\"msg.content | agentMarkdown\"></span>\n          <span *ngIf=\"msg.role !== 'assistant'\">{{ msg.content }}</span>\n        </div>\n      </div>\n\n    </ng-container>\n\n    <!-- Typing indicator -->\n    <div class=\"message-row agent-row\" *ngIf=\"isTyping\">\n      <div class=\"message-bubble agent-bubble typing-bubble\">\n        <span class=\"typing-dot\"></span>\n        <span class=\"typing-dot\"></span>\n        <span class=\"typing-dot\"></span>\n      </div>\n    </div>\n\n  </div>\n\n  <!-- Media error (mic blocked / unsupported browser) -->\n  <div class=\"agent-media-error\" *ngIf=\"mediaError\">\n    <mat-icon class=\"media-error-icon\">error_outline</mat-icon>\n    <span>{{ mediaError }}</span>\n  </div>\n\n  <!-- Staged attachment: a photo waits here until the user adds a caption and presses send -->\n  <div class=\"agent-attachment\" *ngIf=\"pendingPhoto\">\n    <mat-icon class=\"attach-icon\">image</mat-icon>\n    <span class=\"attach-label\">Photo attached</span>\n    <button mat-icon-button class=\"attach-remove\" matTooltip=\"Remove photo\" (click)=\"clearPhoto()\">\n      <mat-icon>close</mat-icon>\n    </button>\n  </div>\n\n  <!-- Transcribing indicator for the Stop button -->\n  <div class=\"agent-transcribing\" *ngIf=\"isTranscribing\">\n    <mat-icon class=\"transcribing-icon\">graphic_eq</mat-icon>\n    <span>Transcribing…</span>\n  </div>\n\n  <!-- Voice mode: replaces the composer entirely. Everything here is sized to be used without looking —\n       a big state indicator, the last exchange, and a thumb-sized exit. -->\n  <div class=\"agent-voice\" *ngIf=\"voiceMode\">\n\n    <div class=\"voice-state\" [class.is-starting]=\"voiceState === 'starting'\"\n         [class.is-listening]=\"voiceState === 'listening' || voiceState === 'capturing'\"\n         [class.is-thinking]=\"voiceState === 'thinking'\" [class.is-speaking]=\"voiceState === 'speaking'\">\n      <mat-icon class=\"voice-state-icon\">{{ voiceStateIcon }}</mat-icon>\n      <span class=\"voice-state-label\">{{ voiceStateLabel }}</span>\n    </div>\n\n    <!-- Live level, so the mic being open is visible as well as audible. Not shown while calibrating: the\n         meter would invite exactly the talking that ruins the measurement. -->\n    <div class=\"voice-meter\" *ngIf=\"voiceState === 'listening' || voiceState === 'capturing'\">\n      <div class=\"voice-meter-fill\" [style.width.%]=\"voiceLevel * 100\"></div>\n    </div>\n\n    <!-- Deliberately NO transcript/reply repeated here: both already appear in the chat thread directly above,\n         and duplicating them pushed the state indicator — the one thing that must be readable at a glance —\n         down the panel. The state, the meter and the exit are all this needs. -->\n\n    <!-- Says explicitly that pauses are fine, because the natural worry is that stopping to think will send -->\n    <p class=\"voice-hint\" *ngIf=\"voiceState === 'starting'\">Checking the background noise — hold on…</p>\n    <p class=\"voice-hint\" *ngIf=\"voiceState === 'capturing'\">Take your time — it waits until you're done.</p>\n    <p class=\"voice-hint\" *ngIf=\"voiceState === 'listening'\">Just speak — it sends when you finish.</p>\n\n    <button mat-flat-button color=\"warn\" class=\"voice-exit\" (click)=\"stopVoiceMode()\">\n      <mat-icon>close</mat-icon>\n      <span>Exit voice mode</span>\n    </button>\n  </div>\n\n  <!-- Input area -->\n  <div class=\"agent-input\" [class.recording]=\"isRecording\" *ngIf=\"!voiceMode\">\n\n    <!-- Normal input: attach, text, voice note, hands-free, send -->\n    <ng-container *ngIf=\"!isRecording\">\n      <button mat-icon-button class=\"media-btn\" matTooltip=\"Attach\" [matMenuTriggerFor]=\"attachMenu\">\n        <mat-icon>add</mat-icon>\n      </button>\n      <mat-form-field appearance=\"outline\" class=\"input-field\">\n        <input matInput #messageInput placeholder=\"Type, speak or snap...\" [(ngModel)]=\"inputText\" (keydown)=\"onKeydown($event)\" autocomplete=\"off\" />\n      </mat-form-field>\n      <!-- Tap records a voice note; HOLD enters hands-free voice mode. Deliberately no separate button for\n           voice mode: the row is already at capacity, and a fifth control would crowd out the text field on a\n           phone. The gesture is the accelerator, the \"+\" menu below is the discoverable path to the same\n           thing — a gesture nobody can see is a feature nobody finds. -->\n      <button mat-icon-button class=\"media-btn mic-btn\" [class.arming]=\"micHeld\"\n              matTooltip=\"Tap to record · hold for hands-free\"\n              (click)=\"onMicClick()\"\n              (pointerdown)=\"onMicPressStart()\" (pointerup)=\"onMicPressEnd()\"\n              (pointerleave)=\"onMicPressEnd()\" (pointercancel)=\"onMicPressEnd()\">\n        <mat-icon>mic</mat-icon>\n      </button>\n      <button mat-icon-button color=\"primary\" class=\"send-btn\" (click)=\"sendMessage()\" [disabled]=\"!canSend\">\n        <mat-icon>send</mat-icon>\n      </button>\n    </ng-container>\n\n    <!-- Recording bar: replaces the input while a voice note is being captured.\n         Three exits — discard it, stop and read it back as text, or send it straight away. -->\n    <ng-container *ngIf=\"isRecording\">\n      <button mat-icon-button class=\"media-btn cancel-btn\" matTooltip=\"Discard\" (click)=\"cancelRecording()\">\n        <mat-icon>delete</mat-icon>\n      </button>\n      <div class=\"recording-status\">\n        <span class=\"rec-dot\"></span>\n        <span class=\"rec-label\">Recording</span>\n        <span class=\"rec-time\">{{ recordDisplay }}</span>\n      </div>\n      <button mat-icon-button class=\"media-btn stop-btn\" matTooltip=\"Stop and add as text\" (click)=\"stopAndTranscribe()\">\n        <mat-icon>stop_circle</mat-icon>\n      </button>\n      <button mat-icon-button color=\"primary\" class=\"send-btn\" matTooltip=\"Send now\" (click)=\"stopRecording()\">\n        <mat-icon>send</mat-icon>\n      </button>\n    </ng-container>\n\n    <!-- Attach menu — keeps the row compact: one \"+\" instead of a button per source -->\n    <mat-menu #attachMenu=\"matMenu\">\n      <button mat-menu-item (click)=\"takePhoto()\">\n        <mat-icon>photo_camera</mat-icon>\n        <span>Take photo</span>\n      </button>\n      <button mat-menu-item (click)=\"choosePhoto()\">\n        <mat-icon>photo_library</mat-icon>\n        <span>Choose photo</span>\n      </button>\n      <!-- The discoverable way into voice mode. The mic long-press does the same thing faster, but only\n           once you know it exists — this is how you find out. -->\n      <button mat-menu-item (click)=\"startVoiceMode()\">\n        <mat-icon>record_voice_over</mat-icon>\n        <span>Hands-free voice mode</span>\n      </button>\n    </mat-menu>\n\n    <!-- Two separate pickers on purpose. `capture=\"environment\"` hands off to the phone's camera app and\n         opens the rear lens; WITHOUT it the same input opens the gallery/file picker. One input cannot do\n         both, which is why the old single button always went to the camera on mobile. -->\n    <input type=\"file\" #cameraInput accept=\"image/*\" capture=\"environment\" hidden (change)=\"onPhotoSelected($event)\" />\n    <input type=\"file\" #galleryInput accept=\"image/*\" hidden (change)=\"onPhotoSelected($event)\" />\n  </div>\n\n</div>\n","// Routed chat page (home/agent) — the shared agent widget rendered in page mode. The component is a shell:\n// all chat state lives in the AgentService singleton, which is what lets a conversation started in the\n// desktop floating window continue here unchanged.\nimport { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { take } from 'rxjs/operators';\nimport { AgentService } from '../../services/agent.service';\n\n@Component({\n  selector: 'spa-agent-page',\n  templateUrl: './agent-page.component.html',\n  styleUrls: ['./agent-page.component.css'],\n  standalone: false\n})\nexport class AgentPageComponent implements OnInit, OnDestroy {\n\n  private subs: Subscription[] = [];\n\n  constructor(private agentService: AgentService) {}\n\n  ngOnInit(): void {\n    // open() is the call that restores the last conversation, so the page needs it — but isOpen is SHARED\n    // with the desktop floating window, and forcing it true when a thread is already loaded would leave that\n    // window popped open on the next route. So it is called only when nothing has loaded yet, mirroring the\n    // service's own hasLoadedInitial guard.\n    this.subs.push(this.agentService.currentConversationId$.pipe(take(1)).subscribe(id => {\n      if (id === null) this.agentService.open();\n    }));\n  }\n\n  ngOnDestroy(): void {\n    // Deliberately no close() here — isOpen belongs to the floating window. Closing it on leaving the page\n    // would reach across and shut a chat the user never opened from here.\n    this.subs.forEach(s => s.unsubscribe());\n  }\n}\n","<!-- No page chrome of its own: the widget header already carries the agent name, online status, conversation\n     switcher and new-conversation button, and a second title bar above it would just repeat them. -->\n<spa-agent [pageMode]=\"true\"></spa-agent>\n","import { Component } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { combineLatest, map, Observable, of, startWith, switchMap } from 'rxjs';\nimport { OfflineService } from '../../services/offline.service';\n\n// TinSync toolbar indicator — a persistent connection light that lives in the nav bar next to Notifications.\n// Green when the backend is reachable, grey when offline; a badge shows the count of unsynced changes.\n// Clicking navigates to the full Pending Changes page (same pattern as the Notifications icon).\n@Component({\n  selector: 'spa-offline-indicator',\n  standalone: false,\n  template: `\n  <ng-container *ngIf=\"enabled\">\n    <button *ngIf=\"state$ | async as s\" mat-icon-button (click)=\"openSyncPage()\" [matTooltip]=\"tooltip(s)\">\n      <mat-icon [matBadge]=\"s.badge > 0 ? s.badge : null\" [matBadgeColor]=\"s.attention > 0 ? 'warn' : 'accent'\" matBadgeSize=\"small\"\n        [ngStyle]=\"{ color: s.online ? '#4CAF50' : '#9E9E9E' }\">{{ s.online ? 'cloud_done' : 'cloud_off' }}</mat-icon>\n    </button>\n  </ng-container>\n  `,\n  // Changed: nav-menu centres its toolbar icon buttons via `.sm-topbar .mat-mdc-icon-button`, but that rule is\n  // view-encapsulated and cannot reach this child component's button — so the glyph fell 6px below the notification\n  // and signout icons. Re-apply the same centring here, where the button actually lives.\n  // Changed (residual from the icon-global-survey, 2026-08-19): cloud_done is the ONE glyph the survey measured\n  // as actually overhanging its em box — ink 22px wide inside the 20px box that tin-styles.css:453-464 forces on\n  // every icon inside a <button> — and mat-icon's own `overflow: hidden` is what shaves the 1px off each side.\n  // `overflow: visible` is deliberately the ONLY declaration here, exactly as checklist.component.css:28 records:\n  // it is the one property the !important global does not name, so it lands without a fight and without touching\n  // a rule that sizes every button icon in five apps. The geometry (font-size/width/height) is left alone on\n  // purpose — resizing would make this glyph disagree with the notification and signout icons beside it, and the\n  // 1px it now shows falls inside the icon button's own padding, not onto a neighbour. NOT visually measured:\n  // no browser was driven for this change (the shared MCP browser was out of bounds), so it is argued from the\n  // survey's measurements plus the computed-style spec next to this file, not from a screenshot.\n  styles: [`\n    :host { display: inline-flex; align-items: center; vertical-align: middle; }\n    :host .mat-mdc-icon-button { display: inline-flex; align-items: center; justify-content: center; }\n    :host .mat-mdc-icon-button mat-icon { overflow: visible; }\n  `],\n})\nexport class OfflineIndicatorComponent {\n\n  state$: Observable<{ online: boolean, pending: number, attention: number, badge: number }>;\n  enabled = false;\n\n  constructor(private offline: OfflineService, private router: Router) {\n    this.enabled = this.offline.enabled; // app-level gate — the indicator is invisible + inert when offline capability is off\n    if (!this.enabled) { this.state$ = of({ online: true, pending: 0, attention: 0, badge: 0 }); return; }\n\n    this.offline.ensureConnectivity(); // start connection detection so the toolbar light is live\n\n    // Pending counts only materialize once an offline table has registered (keeps IndexedDB untouched otherwise)\n    this.state$ = combineLatest([\n      this.offline.online$,\n      this.offline.registered$.pipe(\n        switchMap(reg => reg ? this.offline.activeOps$().pipe(startWith([] as any[])) : of([] as any[]))\n      ),\n    ]).pipe(\n      map(([online, ops]) => {\n        const pending = ops.filter(o => o.status === 'pending' || o.status === 'syncing').length;\n        const attention = ops.filter(o => o.status === 'failed' || o.status === 'conflict' || o.status === 'stale').length;\n        return { online, pending, attention, badge: pending + attention };\n      })\n    );\n  }\n\n  tooltip(s: { online: boolean, pending: number, attention: number, badge: number }): string {\n    if (!s.online) return s.badge ? `Offline — ${s.badge} change(s) waiting to sync` : 'Offline — the server is not reachable';\n    if (s.attention > 0) return `${s.attention} change(s) need review`;\n    if (s.pending > 0) return `${s.pending} change(s) waiting to sync`;\n    return 'Online';\n  }\n\n  openSyncPage() { this.router.navigate(['home/workflow/sync']); }\n}\n","import { Component, DoCheck, Input, OnInit } from '@angular/core'; // Changed: OnChanges swapped for DoCheck — ngOnChanges only fires on input REFERENCE change, so a mutated `data` left the cache stale\nimport { AlertMessage, AlertConfig } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Changed: central visibility resolver\n\n@Component({\n    selector: 'spa-alert',\n    templateUrl: './alert.component.html',\n    styleUrls: ['./alert.component.css'],\n    standalone: false\n})\nexport class AlertComponent implements OnInit, DoCheck { // Changed: DoCheck — the gate and the list are now rebuilt together, once per change-detection pass\n\n  constructor() { }\n\n  ngOnInit(): void {\n  }\n\n\n  @Input() config: AlertConfig;\n  @Input() data;\n\n\n  // Added: shared frozen empty list — lets the template getters return a stable reference without allocating\n  private static readonly noMessages: AlertMessage[] = Object.freeze([]) as AlertMessage[];\n\n  // Changed: the cache is now the SINGLE SOURCE OF TRUTH for both the *ngIf gate and the *ngFor list.\n  // Previously hasAlertMessages() re-evaluated visibility live while getAlertMessages() returned a cache\n  // invalidated only by ngOnChanges — which never fires when `data` is MUTATED rather than reassigned.\n  // The gate could therefore say \"show\" while the cached list was still the stale empty one, rendering\n  // an empty warning box (repro: Piglet → Weaner mid-dialog).\n  private messageCache = new Map<any, AlertMessage[]>();\n  private anyVisible = false;\n\n  ngDoCheck() {\n    this.rebuildMessages(); // Added: one rebuild per change-detection pass — catches mutation of `data`, not just reassignment\n  }\n\n  // Added: single pass over the configured messages, grouped by severity. Allocation happens HERE, in the\n  // lifecycle hook — never inside a template-bound getter (house ban on allocating getters, which livelocked).\n  private rebuildMessages(): void {\n    const visible = (this.config?.messages || []).filter(x => this.testVisible(x));\n    const next = new Map<any, AlertMessage[]>();\n\n    for (const msg of visible) {\n      const bucket = next.get(msg.type);\n      if (bucket) bucket.push(msg); else next.set(msg.type, [msg]);\n    }\n\n    // Added: keep the PREVIOUS array reference when the contents are unchanged, so *ngFor and change\n    // detection see a stable identity and do not re-render on every tick\n    next.forEach((list, type) => {\n      const prev = this.messageCache.get(type);\n      if (prev && prev.length === list.length && prev.every((m, i) => m === list[i])) next.set(type, prev);\n    });\n\n    this.messageCache = next;\n    this.anyVisible = visible.length > 0;\n  }\n\n  getAlertMessages(type = undefined): AlertMessage[] { // Changed: pure cache read — no allocation, no filtering\n    return this.messageCache.get(type) || AlertComponent.noMessages;\n  }\n\n  hasAlertMessages(type = undefined): boolean { // Changed: reads the SAME cache the list comes from, so the two can never disagree\n    return (this.messageCache.get(type)?.length || 0) > 0;\n  }\n\n  hasAnyAlertMessages(): boolean { // Changed: reads the rebuilt flag; also no longer throws when config.messages is undefined\n    return this.anyVisible;\n  }\n\n  testVisible(msg: AlertMessage): boolean {\n    // Guard: don't evaluate condition functions until data is loaded\n    if (!this.data && (typeof msg.visible === 'function' || typeof msg.hidden === 'function')) {\n      return false;\n    }\n    return Core.isItemVisible(msg, this.data); // Changed: unified visible/hidden replaces showCondition/hiddenCondition\n  }\n\n  getMessageContent(msg: AlertMessage): string {\n    // If messageField is specified and data exists, use dynamic message\n    if (msg.messageField && this.data && this.data[msg.messageField]) {  // Changed: contentField to messageField\n      return this.data[msg.messageField];  // Changed: contentField to messageField\n    }\n\n    // Fall back to static message\n    return msg.message || '';  // Changed: content to message\n  }\n\n}\n","<div [style.margin-bottom]=\"hasAnyAlertMessages() ? '15px' : '0'\">\n  \n<div *ngIf=\"hasAlertMessages()\" class=\"alert alert-secondary\" [ngClass]=\"{'alert-compact': config.compact}\" style=\"font-size: 14px;margin-bottom: 5px;\" role=\"alert\">\n  <p *ngIf=\"config.subject\">{{config.subject}}</p>\n  <ng-container *ngFor=\"let msg of getAlertMessages(); let last = last\">\n    <label>{{getMessageContent(msg)}}</label>\n    <br *ngIf=\"!last\">\n  </ng-container>\n</div>\n\n<div *ngIf=\"hasAlertMessages('success')\" class=\"alert alert-success\" [ngClass]=\"{'alert-compact': config.compact}\" style=\"font-size: 14px;margin-bottom: 5px;\" role=\"alert\">\n  <p *ngIf=\"config.subject\">{{config.subject}}</p>\n  <ng-container *ngFor=\"let msg of getAlertMessages('success'); let last = last\">\n    <label>{{getMessageContent(msg)}}</label>\n    <br *ngIf=\"!last\">\n  </ng-container>\n</div>\n\n<div *ngIf=\"hasAlertMessages('info')\" class=\"alert alert-info\" [ngClass]=\"{'alert-compact': config.compact}\" style=\"font-size: 14px;margin-bottom: 5px;\" role=\"alert\">\n  <p *ngIf=\"config.subject\">{{config.subject}}</p>\n  <ng-container *ngFor=\"let msg of getAlertMessages('info'); let last = last\">\n    <label>{{getMessageContent(msg)}}</label>\n    <br *ngIf=\"!last\">\n  </ng-container>\n\n</div>\n\n<div *ngIf=\"hasAlertMessages('warn')\" class=\"alert alert-warning\" [ngClass]=\"{'alert-compact': config.compact}\" style=\"font-size: 14px;margin-bottom: 5px;\" role=\"alert\">\n  <p *ngIf=\"config.subject\">{{config.subject}}</p>\n  <ng-container *ngFor=\"let msg of getAlertMessages('warn'); let last = last\">\n    <label>{{getMessageContent(msg)}}</label>\n    <br *ngIf=\"!last\">\n  </ng-container>\n</div>\n\n<div *ngIf=\"hasAlertMessages('critical')\" class=\"alert alert-danger\" [ngClass]=\"{'alert-compact': config.compact}\" style=\"font-size: 14px;margin-bottom: 5px;\" role=\"alert\">\n  <p *ngIf=\"config.subject\">{{config.subject}}</p>\n  <ng-container *ngFor=\"let msg of getAlertMessages('critical'); let last = last\">\n    <label>{{getMessageContent(msg)}}</label>\n    <br *ngIf=\"!last\">\n  </ng-container>\n</div>\n\n</div>","import { Component, OnDestroy, OnInit, inject } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { AlertConfig, Button, TableConfig } from '../../classes/Classes';\nimport { OfflineService, OutboxOp } from '../../services/offline.service';\nimport { MessageService } from '../../services/message.service';\n\n// TinSync page — the full-page list of unsynced changes, reached from the toolbar cloud indicator\n// (same pattern as the Notifications page). Built from the standard spa-table + spa-alert; row buttons\n// use onClick handlers (Retry / Keep server / Keep mine / Discard) gated by per-row visible predicates.\n@Component({\n  selector: 'spa-sync',\n  standalone: false,\n  templateUrl: './sync.component.html',\n  styleUrls: ['./sync.component.css'],\n})\nexport class SyncComponent implements OnInit, OnDestroy {\n\n  private offline = inject(OfflineService);\n  private messageService = inject(MessageService);\n\n  ops: OutboxOp[] = [];\n  alertConfig: AlertConfig | null = null;\n  private sub: Subscription;\n\n  private retryButton: Button = { name: 'retry', display: 'Retry', icon: { name: 'refresh' }, visible: (op: OutboxOp) => ['failed', 'stale', 'pending'].includes(op.status), onClick: (op: OutboxOp) => this.offline.retryOp(op.opId) };\n  private keepServerButton: Button = { name: 'keepServer', display: 'Keep server', icon: { name: 'cloud_done' }, visible: (op: OutboxOp) => op.status === 'conflict', onClick: (op: OutboxOp) => this.offline.resolveConflict(op.opId, 'keepServer') };\n  private keepMineButton: Button = { name: 'keepMine', display: 'Keep mine', icon: { name: 'upload' }, visible: (op: OutboxOp) => op.status === 'conflict', onClick: (op: OutboxOp) => this.offline.resolveConflict(op.opId, 'keepMine') };\n  private discardButton: Button = { name: 'discard', display: 'Discard', icon: { name: 'delete' }, onClick: (op: OutboxOp) => this.discard(op) };\n  private syncNowButton: Button = { name: 'syncNow', display: 'Sync Now', inHeader: true, icon: { name: 'sync' }, onClick: () => this.offline.drain() };\n\n  tableConfig: TableConfig = {\n    showFilter: true,\n    flatButtons: true,\n    noDataMessage: 'Nothing waiting to sync.',\n    columns: [\n      { name: 'entityName', type: 'text', alias: 'Type' },\n      { name: 'opAction', type: 'chip', alias: 'Change', colors: [ { name: '#66BB6A', condition: (op: OutboxOp) => op.opAction === 'create' }, { name: '#42A5F5', condition: (op: OutboxOp) => op.opAction === 'edit' }, { name: '#EF5350', condition: (op: OutboxOp) => op.opAction === 'delete' } ] },\n      { name: 'summary', type: 'text', alias: 'Item' },\n      { name: 'statusLabel', type: 'chip', alias: 'Status',\n        colors: [ { name: '#FFA000', condition: (op: OutboxOp) => op.status === 'pending' || op.status === 'syncing' }, { name: '#F44336', condition: (op: OutboxOp) => op.status === 'failed' }, { name: '#FF6F00', condition: (op: OutboxOp) => op.status === 'conflict' }, { name: '#90A4AE', condition: (op: OutboxOp) => op.status === 'stale' } ] },\n      { name: 'lastError', type: 'text', alias: 'Detail' },\n    ],\n    buttons: [this.syncNowButton, this.retryButton, this.keepServerButton, this.keepMineButton, this.discardButton],\n  };\n\n  ngOnInit(): void {\n    this.sub = this.offline.outboxView$().subscribe(rows => {\n      this.ops = rows;\n      this.updateAlert();\n    });\n  }\n\n  ngOnDestroy(): void { this.sub?.unsubscribe(); }\n\n  private discard(op: OutboxOp) {\n    this.messageService.confirm('Discard this change? It will never be sent to the server.').subscribe(result => {\n      if (result === 'yes') this.offline.discardOp(op.opId);\n    });\n  }\n\n  private updateAlert() {\n    const conflicts = this.ops.filter(o => o.status === 'conflict').length;\n    const failed = this.ops.filter(o => o.status === 'failed').length;\n    const messages = [];\n    if (conflicts) messages.push({ type: 'warn' as const, message: `${conflicts} change(s) conflict with newer server data — choose Keep server or Keep mine.` });\n    if (failed) messages.push({ type: 'critical' as const, message: `${failed} change(s) failed and need your attention.` });\n    if (!this.offline.online) messages.push({ type: 'info' as const, message: \"You're offline — changes will be sent automatically when the connection returns.\" });\n    this.alertConfig = messages.length ? { messages } : null;\n  }\n}\n","<div class=\"row\">\n  <div class=\"col-auto\">\n    <h4>Pending Changes</h4>\n  </div>\n</div>\n\n<hr style=\"margin-top: 0px;\" />\n\n<div style=\"font-size: 14px;\">\n  <spa-alert *ngIf=\"alertConfig\" [config]=\"alertConfig\"></spa-alert>\n  <spa-table [config]=\"tableConfig\" [data]=\"ops\"></spa-table>\n</div>\n","// Functional guard for Angular 15+ (replaces deprecated class-based CanActivate)\nimport { inject } from '@angular/core';\nimport { CanActivateFn } from '@angular/router';\nimport { AuthService } from '../services/auth.service';\nimport { SignalRService } from '../services/signalr.service';\nimport { HttpService } from '../services/http.service';\nimport { StorageService } from '../services/storage.service';\nimport { Constants } from '../classes/Classes';\n\n// Changed: Returns Promise<boolean> to properly await token refresh before allowing navigation\nexport const authGuard: CanActivateFn = async (route, state) => {\n  const authService = inject(AuthService);\n  const signalRService = inject(SignalRService);\n  const httpService = inject(HttpService);\n  const storageService = inject(StorageService);\n\n  const isAuthenticated = await authService.checkAuthentication();\n\n  // Changed: Ensure consolidated SignalR hub connection is started on every authenticated route access\n  if (isAuthenticated) {\n    const appHubUrl = httpService.apiUrl.replace(/\\/api\\/$/, '/hubs/app'); // Changed: Single hub URL\n    const token = await storageService.get(Constants.AUTH_TOKEN);\n    if (token) signalRService.startConnection(appHubUrl, token); // Changed: Uses single startConnection\n  }\n\n  return isAuthenticated;\n};\n","// Functional guard for plan-based feature gating — blocks navigation to restricted routes\nimport { inject } from '@angular/core';\nimport { CanActivateFn, Router } from '@angular/router';\nimport { SubscriptionService } from '../services/subscription.service';\n\n// Factory function that returns a guard for a specific feature key\nexport const featureGuard = (featureKey: string): CanActivateFn => {\n  return (route, state) => {\n    const subscriptionService = inject(SubscriptionService);\n    const router = inject(Router);\n\n    if (subscriptionService.isFeatureEnabled(featureKey)) {\n      return true;\n    }\n\n    // Feature not available — redirect to home\n    router.navigate(['home']);\n    return false;\n  };\n};\n","// Functional guard for tenant module gating — the SetupService.isModuleEnabled sibling of featureGuard. The server\n// already refuses actions from a disabled module; this refuses the NAVIGATION so the user never reaches a dead\n// screen and fills in a form the server was always going to reject.\n//\n// NOTE for the next reader: this is SetupService.isModuleEnabled (the tenant's own module choice, fails OPEN), NOT\n// SubscriptionService.isModuleEnabled (plan entitlement, fails CLOSED). The names are identical and the semantics\n// are opposite; featureGuard next door covers the other one.\nimport { inject } from '@angular/core';\nimport { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';\nimport { of } from 'rxjs';\nimport { catchError, map, timeout } from 'rxjs/operators';\nimport { SetupService } from '../services/setup.service';\nimport { MessageService } from '../services/message.service';\n\n// Deepest wins, so a leaf can override the area it sits in (invoicing lives under home/accounting). pathFromRoot\n// rather than route.data avoids depending on paramsInheritanceStrategy, which does not inherit data through a\n// parent that has both a path and a component.\nconst resolveKey = (route: ActivatedRouteSnapshot): string => {\n  let key = '';\n  route.pathFromRoot.forEach(r => { if (r.data && r.data['moduleKey']) key = r.data['moduleKey']; });\n  return key;\n};\n\n// Optional key: moduleGuard('workshop') gates one route explicitly, moduleGuard() reads data.moduleKey off the\n// route tree so one canActivateChild registration can cover a whole subtree\nexport const moduleGuard = (moduleKey?: string): CanActivateFn => {\n  return (route, state) => {\n    const setupService = inject(SetupService);\n    const messageService = inject(MessageService);\n    const router = inject(Router);\n\n    const key = moduleKey || resolveKey(route);\n    if (!key || !setupService.enabled) return of(true); // No module restriction on this route, or an app with no setup concept — fail open\n\n    return setupService.ensureModules().pipe(\n      timeout(3000),                          // A slow or hung catalog must never wedge navigation\n      catchError(() => of(true)),             // Fail OPEN, exactly like isModuleEnabled and the server's ModuleCatalog.IsEnabled\n      map(() => {\n        if (setupService.isModuleEnabled(key)) return true;\n        messageService.toast(`${setupService.moduleTitle(key)} is switched off for your organisation. Turn it on in Getting Started.`);\n        return router.parseUrl('/home'); // UrlTree, not navigate() + false — a UrlTree cannot race an in-flight navigation\n      })\n    );\n  };\n};\n","// Added (Phase 4, D4): the CAPABILITY tier of route gating. moduleGuard next door answers \"is this module turned\n// on for the tenant\"; this answers \"was this ROLE ever granted this page\". They are different questions with\n// different failure modes and they are deliberately kept as two guards rather than one overloaded one.\n//\n// WHY THIS EXISTS AT ALL: the nav menu is already cap-gated per item (nav-menu.component.html gates every entry on\n// myRole[item.name]), so a role without cap39 never sees a Sales Orders menu entry. The hole is the DEEP LINK — a\n// typed or bookmarked URL builds the whole page, chrome and tabs and action bar, around one small refusal inside\n// a single spa-table. This refuses the NAVIGATION instead, so the user gets one page that names the permission.\n//\n// NOTE for the next reader: the decision is SYNCHRONOUS and local. It reads the role the client already holds and\n// never issues a request — there is no status code to wait for, and this codebase's refusals are HTTP 200 with\n// success:false anyway, so a round-trip could not have answered the question. The required capability is known\n// from the route BEFORE anything is fetched, which is exactly what makes \"never authorised\" distinguishable from\n// \"authorised but empty\" with certainty.\nimport { inject } from '@angular/core';\nimport { ActivatedRouteSnapshot, CanActivateFn, Router } from '@angular/router';\nimport { AuthService } from '../services/auth.service';\n\n// Deepest wins, so a leaf can override the area it sits in — the same resolution moduleGuard uses. pathFromRoot\n// rather than route.data avoids depending on paramsInheritanceStrategy, which does not inherit data through a\n// parent that has both a path and a component.\nconst resolveCap = (route: ActivatedRouteSnapshot): string => {\n  let key = '';\n  route.pathFromRoot.forEach(r => { if (r.data && r.data['capName']) key = r.data['capName']; });\n  return key;\n};\n\n// Optional key: capabilityGuard('cap39') gates one route explicitly, capabilityGuard() reads data.capName off the\n// route tree so one canActivateChild registration can cover a whole subtree\nexport const capabilityGuard = (capName?: string): CanActivateFn => {\n  return (route, state) => {\n    const key = capName || resolveCap(route);\n    if (!key) return true; // No capability declared on this route — no opinion, never blocks. FAIL OPEN: this is the line that keeps an untracked consumer app that adopts nothing byte-for-byte unaffected\n\n    const authService = inject(AuthService);\n    const router = inject(Router);\n\n    const myRole = authService.currentRoleSource.value;\n    if (!myRole) return true; // No role resolved yet — authGuard owns the unauthenticated case; refusing here would turn a login-timing race into a spurious no-access page\n\n    if (myRole[key]) return true; // Any non-zero access level opens the page; the grid tier still applies the finer View/Edit/Create distinction\n\n    // UrlTree, not navigate() + false — a UrlTree cannot race an in-flight navigation. `from` is carried so the\n    // page can offer a way back that is not just \"home\", and `cap` so it can name the permission rather than\n    // restate a generic apology.\n    return router.createUrlTree(['/home/no-access'], { queryParams: { cap: key, from: state.url } });\n  };\n};\n","// Structural directive for plan-based feature gating in templates\n// Usage: *spaFeature=\"'sales.quotes'\" — hides element if feature is disabled\nimport { Directive, Input, TemplateRef, ViewContainerRef, OnInit, OnDestroy } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { SubscriptionService } from '../services/subscription.service';\n\n@Directive({\n  selector: '[spaFeature]',\n  standalone: false\n})\nexport class FeatureDirective implements OnInit, OnDestroy {\n\n  @Input() spaFeature: string = '';\n\n  private hasView = false;\n  private subscription: Subscription | null = null;\n\n  constructor(\n    private templateRef: TemplateRef<any>,\n    private viewContainer: ViewContainerRef,\n    private subscriptionService: SubscriptionService\n  ) { }\n\n  ngOnInit() {\n    // Subscribe to feature changes so UI updates reactively when features load\n    this.subscription = this.subscriptionService.enabledFeatures$.subscribe(() => {\n      this.updateView();\n    });\n  }\n\n  ngOnDestroy() {\n    if (this.subscription) {\n      this.subscription.unsubscribe();\n    }\n  }\n\n  private updateView() {\n    const enabled = this.subscriptionService.isFeatureEnabled(this.spaFeature);\n\n    if (enabled && !this.hasView) {\n      this.viewContainer.createEmbeddedView(this.templateRef);\n      this.hasView = true;\n    } else if (!enabled && this.hasView) {\n      this.viewContainer.clear();\n      this.hasView = false;\n    }\n  }\n}\n","import { Component } from '@angular/core';\n\n@Component({\n    selector: 'spa-tin-spa',\n    template: `\n    <p>\n      tin-spa works!\n    </p>\n  `,\n    styles: [],\n    standalone: false\n})\nexport class TinSpaComponent {\n\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { MatAutocompleteModule } from '@angular/material/autocomplete';\nimport { MatBadgeModule } from '@angular/material/badge';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatChipsModule } from '@angular/material/chips';\nimport { MatNativeDateModule, MAT_DATE_LOCALE } from '@angular/material/core';\nimport { MatDatepickerModule } from '@angular/material/datepicker';\nimport { MatDialogModule, MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatListModule } from '@angular/material/list';\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatPaginatorModule } from '@angular/material/paginator';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatRadioModule } from '@angular/material/radio';\nimport { MatSelectModule } from '@angular/material/select';\nimport { MatSliderModule } from '@angular/material/slider';\nimport { MatSnackBarModule } from '@angular/material/snack-bar';\nimport { MatSortModule } from '@angular/material/sort';\nimport { MatStepperModule } from '@angular/material/stepper';\nimport { MatTableModule } from '@angular/material/table';\nimport { MatTabsModule } from '@angular/material/tabs';\nimport { MatProgressBarModule } from '@angular/material/progress-bar';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { ReactiveFormsModule, FormsModule } from '@angular/forms';\n\nimport { MatSidenavModule } from '@angular/material/sidenav';\nimport { MatToolbarModule } from '@angular/material/toolbar';\nimport { RouterModule } from '@angular/router';\nimport { MatExpansionModule } from '@angular/material/expansion';\n\n@NgModule({\n  declarations: [],\n  imports: [\n\n\n  ],\n  exports: [\n    CommonModule,FormsModule, ReactiveFormsModule,\n    MatMenuModule,    MatSliderModule,    MatTableModule,    MatPaginatorModule,\n    MatCheckboxModule,    MatBadgeModule,    MatButtonModule,    MatIconModule,    MatDialogModule,    MatSnackBarModule,\n    MatTabsModule,    MatFormFieldModule,    MatInputModule,    MatCardModule,    MatChipsModule,    MatSelectModule,\n    MatNativeDateModule,    MatProgressSpinnerModule,    MatListModule,    MatAutocompleteModule,    MatTooltipModule,    MatSortModule,\n    MatDatepickerModule,    MatStepperModule,    MatRadioModule, MatProgressBarModule,\n\n    MatSidenavModule,\n    MatToolbarModule,\n    RouterModule,\n    MatExpansionModule,\n  ],\n  providers:[\n    { provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: { disableClose: true, hasBackdrop: true }  },\n    { provide: MAT_DATE_LOCALE, useValue: \"en-GB\" },\n  ]\n})\nexport class SpaMatModule { }\n","import { Component, Input, OnInit } from '@angular/core';\n\n@Component({\n    selector: 'spa-activity',\n    templateUrl: './activity.component.html',\n    styleUrls: ['./activity.component.css'],\n    standalone: false\n})\nexport class ActivityComponent implements OnInit {\n\n  constructor() { }\n\n  ngOnInit(): void {\n  }\n\n  @Input() notes = new Array();\n  notesMessage: string = \"Empty\";\n  @Input() title = \"Notes\"\n\n}\n","\n      <div class=\"tin-input-row mt-3\" *ngIf=\"title != ''\">\n        <mat-label style=\"font-size: 20px; font-weight: 300\" >  {{title}}</mat-label >\n      </div>\n\n      <ul *ngIf=\"notes && notes.length>0\" class=\"list-group list-group-flush\" style=\"max-height:350px; margin-left:5px\">\n\n        <li *ngFor=\"let note of notes\" class=\"list-group-item  list-group-item-action flex-column align-items-start\">\n          <div class=\"d-flex w-100 justify-content-between\">\n            <div class=\"mb-0\">{{note.createdByName}}</div>\n            <!-- <small class=\"text-muted\">{{note.expr1}} ago</small> -->\n          </div>\n\n          <small>{{note.details}} (<em>{{note.createdDate | date: 'dd MMM yyyy HH:mm'}}</em>) </small>\n        </li>\n\n\n      </ul>\n\n      <div *ngIf=\"notes && notes.length==0\" class=\"d-flex justify-content-center row align-items-center\" style=\"max-height:200px\">\n\n        No {{title.toLowerCase()}}\n\n      </div>\n","import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core'; // Changed: reverted navigable outputs — steps are a read-only indicator\nimport { MatStepper } from '@angular/material/stepper';\nimport { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';\nimport { ApiResponse, Step, StepConfig } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Changed: central visibility resolver\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: routes a failed loadAction through the shared classify + dedupe path (WS-6 Phase 3)\n\n@Component({\n    selector: 'spa-steps',\n    templateUrl: './steps.component.html',\n    styleUrls: ['./steps.component.css'],\n    providers: [{\n            provide: STEPPER_GLOBAL_OPTIONS, useValue: { displayDefaultIndicatorType: false }\n        }],\n    standalone: false\n})\nexport class StepsComponent implements OnInit {\n\n  constructor(private breakpointObserver: BreakpointObserver, private dataService: DataServiceLib, private apiErrorService: ApiErrorService ) { } // Changed: injected ApiErrorService so a failed step load is no longer silent\n\n  ngOnInit(): void {\n    this.loadSteps();\n\n    this.observeScreenSize();\n  }\n\n\n  ngOnChanges() {\n    this.buildVisibleSteps(); // Added: recompute the materialized list before any early return below\n\n    // Added: host-driven index — when a wizard host passes activeIndex, it wins over value-matching.\n    // The indicator still cannot be clicked; only the host's Next/Back buttons move it.\n    if (this.activeIndex !== null && this.activeIndex !== undefined) {\n      this.selectedIndex = this.activeIndex;\n      if (this.stepper) this.stepper.selectedIndex = this.selectedIndex;\n      return;\n    }\n    this.updateSelectedStep();\n  }\n\n  private observeScreenSize() {\n    this.breakpointObserver.observe([\"(max-width: 600px)\"]).subscribe((result: BreakpointState) => {\n      this.smallScreen = result.matches;\n    });\n  }\n\n  @ViewChild('stepper') stepper: MatStepper;\n  @Input() value = \"\";\n  @Input() config: StepConfig;\n  @Input() data;\n  @Input() activeIndex: number | null = null; // Added: host-driven current step (wizard hosts advance it with their own Next/Back buttons) — steps stay a read-only indicator, never clickable\n\n\n  selectedIndex = 0;\n  smallScreen = false;\n  steps: Step[] = [];\n\n  private loadSteps() {\n    // If loadAction is provided, fetch steps from backend\n    if (this.config?.loadAction) {\n      this.dataService.CallApi(this.config.loadAction).subscribe((response: ApiResponse) => {\n        if (response.success) {\n          this.steps = response.data;\n          this.buildVisibleSteps(); // Added: steps arrived from the API — rebuild the materialized list\n          this.updateSelectedStep();\n        } else {\n          this.apiErrorService.presentAppFailure(response, 'load', this.config.loadAction.url); // Added: was a silent no-op — a steps strip that failed to load simply never appeared; 'load' dedupes with the page's other loads\n        }\n      });\n    } else {\n      // Use static steps if provided\n      this.steps = this.config?.steps ?? [];\n      this.buildVisibleSteps(); // Added: static steps assigned — rebuild the materialized list\n      this.updateSelectedStep();\n    }\n  }\n\n  private updateSelectedStep() {\n    if (!this.steps?.length) return;\n\n    // Get visible steps only\n    const visibleSteps = this.getVisibleSteps();\n    if (!visibleSteps.length) return;\n\n    // Get value from data object if valueField is specified\n    const currentValue = this.config?.valueField ?\n      this.data[this.config.valueField] : this.value;\n\n    // Find matching step index among visible steps\n    const index = visibleSteps.findIndex(step => step.value === currentValue);\n    this.selectedIndex = index >= 0 ? index : 0;\n\n    // Update stepper if already initialized\n    // if (this.stepper) {\n    //   this.stepper.selectedIndex = this.selectedIndex;\n\n    // }\n\n    // Update stepper if already initialized\n    if (this.stepper) {\n      // Loop through all previous steps to select them\n      let currentStep = 0;\n      const selectStepsInterval = setInterval(() => {\n        if (currentStep <= this.selectedIndex) {\n          this.stepper.selectedIndex = currentStep;\n          currentStep++;\n        } else {\n          clearInterval(selectStepsInterval);\n        }\n      }, 100); // 300ms delay between each step selection\n    }\n  }\n\n  get shouldShowLabels(): boolean {\n    const visibleSteps = this.getVisibleSteps();\n    return !(visibleSteps.length > 5 && this.smallScreen);\n  }\n\n  // Changed: materialized — getVisibleSteps() feeds the *ngFor of mat-step and was allocating a new array\n  // on every change-detection cycle. It now returns a stable reference rebuilt only on real changes.\n  visibleSteps: Step[] = [];\n\n  private buildVisibleSteps() {\n    this.visibleSteps = this.steps?.length ? this.steps.filter(step => Core.isItemVisible(step, this.data || {})) : []; // Changed: unified visible/hidden replaces hiddenCondition\n  }\n\n  // New method to filter hidden steps\n  getVisibleSteps(): Step[] { return this.visibleSteps; } // Changed: returns the materialized field (internal callers and the template both use this)\n\n\n}\n","\n<mat-horizontal-stepper class=\"transparent\" [labelPosition]=\"shouldShowLabels ? 'bottom' : 'end'\" #stepper [selectedIndex]=\"selectedIndex\">\n\n  <mat-step *ngFor=\"let step of getVisibleSteps()\"\n    [editable]=\"false\"  [label]=\"shouldShowLabels ? step.name : ''\" [state]=\"step.icon ?? 'number'\">\n  </mat-step>\n\n</mat-horizontal-stepper>\n","import { Component, Input, OnChanges } from '@angular/core';\n\n// Added: spa-progress-ring — a circular n-of-m indicator. Written for the Getting Started category groups\n// (owner, 2026-08-18: \"a circular progress ring representing e.g. 5-of-8 … the ring is the headline\") but\n// placed in components/ rather than inside the page on purpose: a ring of n-of-m is not setup-specific, and\n// a page-private copy is how a second visual language starts on a page that already argues against one.\n// Inline SVG, no library. The colours are the CHECKLIST's own state colours, so a ring and the ticks it is\n// counting can never be two different greens.\n@Component({\n    selector: 'spa-progress-ring',\n    templateUrl: './progress-ring.component.html',\n    styleUrls: ['./progress-ring.component.css'],\n    standalone: false\n})\nexport class ProgressRingComponent implements OnChanges {\n  @Input() value = 0;\n  @Input() total = 0;\n  @Input() size = 34;\n  @Input() stroke = 3.5;\n  @Input() tone: 'done' | 'required' | 'neutral' = 'required'; // required = amber, exactly .cl-state.required\n\n  // Materialized in ngOnChanges and never exposed as getters. These feed SVG attribute bindings, which are\n  // evaluated on EVERY change-detection pass; a getter doing the arithmetic there is the template-bound\n  // allocating getter this library banned after it caused a real livelock.\n  radius = 0;\n  circumference = 0;\n  offset = 0;\n  centre = 0;\n  complete = false;\n  label = '';\n\n  ngOnChanges() {\n    this.centre = this.size / 2;\n    this.radius = (this.size - this.stroke) / 2;\n    this.circumference = 2 * Math.PI * this.radius;\n    const total = this.total > 0 ? this.total : 0;\n    // clamped both ends: a backend count can exceed its target (the page's own progressLabel guards the same\n    // way at setup-guide.component.ts progressLabel), and a negative would draw the ring backwards\n    const value = total > 0 ? Math.min(Math.max(this.value, 0), total) : 0;\n    const fraction = total > 0 ? value / total : 0;\n    this.offset = this.circumference * (1 - fraction);\n    this.complete = total > 0 && value >= total;\n    this.label = `${value} of ${total} complete`;\n  }\n}\n","<!-- role=\"img\" + aria-label so the ring announces itself once. The svg itself is aria-hidden: the group header\n     it sits in already carries a live \"5 of 8\" counter, and two readings of the same number is noise. -->\n<span class=\"pr-ring\" [class.done]=\"complete\" [class.tone-required]=\"tone === 'required' && !complete\"\n      [style.width.px]=\"size\" [style.height.px]=\"size\" role=\"img\" [attr.aria-label]=\"label\">\n  <svg [attr.width]=\"size\" [attr.height]=\"size\" [attr.viewBox]=\"'0 0 ' + size + ' ' + size\" focusable=\"false\" aria-hidden=\"true\">\n    <circle class=\"pr-track\" [attr.cx]=\"centre\" [attr.cy]=\"centre\" [attr.r]=\"radius\" [attr.stroke-width]=\"stroke\" fill=\"none\"></circle>\n    <circle class=\"pr-value\" [attr.cx]=\"centre\" [attr.cy]=\"centre\" [attr.r]=\"radius\" [attr.stroke-width]=\"stroke\" fill=\"none\"\n            [attr.stroke-dasharray]=\"circumference\" [attr.stroke-dashoffset]=\"offset\"></circle>\n  </svg>\n  <!-- At 100% the fraction stops being the point, so the middle becomes a single confirmation glyph -->\n  <mat-icon class=\"pr-check\" *ngIf=\"complete\">check</mat-icon>\n</span>\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { MessageService } from '../../services/message.service';\n@Component({\n    selector: 'spa-chips',\n    templateUrl: './chips.component.html',\n    styleUrls: ['./chips.component.css'],\n    standalone: false\n})\nexport class ChipsComponent implements OnInit {\n\n  constructor(private messageService: MessageService) { }\n\n\n  ngOnInit(): void {\n  }\n\n\n  @Input() icon = \"\";\n  @Input() removable = false;\n  @Input() addable = false;\n\n\n\n  @Input() chips: string[];\n  // @Output() chipClick = new EventEmitter();\n\n  @Output() click = new EventEmitter();\n\n  @Output() remove = new EventEmitter();\n\n  clicked(chip: string) {\n\n    if (typeof chip != 'string') {\n      return;\n    }\n\n    if (chip) {\n      this.click.emit(chip);\n    }\n  }\n\n\n  removed(chip) {\n\n    // const index = this.chips.indexOf(chip);\n\n    // if (index >= 0) {\n    //   this.chips.splice(index, 1);\n    // }\n\n    this.messageService.confirm(`Remove ${chip} ?`).subscribe((result) => {\n      if (result == \"yes\") {\n\n        this.remove.emit(chip);\n\n      };\n    });\n\n  }\n\n}\n\n","\n\n\n<div class=\"row  mt-1\" style=\"margin-left: 1em;\">\n  <mat-chip-set>\n    <mat-chip *ngFor=\"let chip of chips let i = index\" [removable]=\"removable\" style=\"font-size: 12px;\" [ngStyle]=\"{'padding-right': removable ? '5px':'12px'}\" (click)=\"clicked(chip)\">\n      <mat-icon *ngIf=\"icon != ''\" color=\"primary\" style=\"font-size: 22px;\">{{icon}}</mat-icon>\n\n      {{chip}}\n\n      <button *ngIf=\"removable\" matChipRemove style=\"font-size: 20px; margin-left: 5px;margin-top: 3px;margin-right: 0px; color: grey;\" (click)=\"removed(chip)\"><mat-icon>cancel</mat-icon></button>\n    </mat-chip>\n  </mat-chip-set>\n</div>\n\n\n\n","import { Component, OnInit, Input, signal } from '@angular/core';\nimport { LoaderService } from '../../services/loader.service';\n\n@Component({\n    selector: 'spa-loader',\n    templateUrl: './loader.component.html',\n    styleUrls: ['./loader.component.css'],\n    standalone: false\n})\nexport class LoaderComponent implements OnInit {\n\n  constructor(private loaderService: LoaderService) {\n\n    this.loaderService.isLoading.subscribe((v) => {\n      this.loading.set(v); // Changed: signal write, see the declaration below\n    });\n\n  }\n  ngOnInit() {\n  }\n\n  @Input() logo = \"\";\n\n  // Changed: was a plain boolean field bound as [hidden]=\"!loading\". Callers flip\n  // LoaderService.isLoading in the middle of a change-detection pass — opening the propose dialog starts\n  // its load from inside CD — so the binding's value changed after the view had been checked and dev mode\n  // reported NG0100 (\"Previous value for 'hidden': 'true'. Current value: 'false'\"). A signal is the\n  // structural fix rather than a detectChanges band-aid: writing it marks this view dirty and Angular\n  // re-renders it on the next pass instead of comparing a value that legitimately moved underneath it.\n  loading = signal(false);\n\n}\n","<div class=\"progress-loader\"  [hidden]=\"!loading()\">\n  <div class=\"loading-spinner\">\n\n      <img *ngIf=\"logo==''\" style=\"width: 100px;\"\n      src=\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==\"\n\n      >\n\n      <img *ngIf=\"logo!=''\" [src]=\"logo\" style=\"width: 100px;\" />\n\n\n      <span id=\"loadingMessage\" class=\"loading-message\">Please wait...</span>\n  </div>\n</div>\n","import { Component } from '@angular/core';\nimport { MatDialogRef } from '@angular/material/dialog';\n\n// Generic Terms and Conditions dialog component for tin-spa library\n@Component({\n  selector: 'spa-terms-dialog',\n  templateUrl: './terms-dialog.component.html',\n  styleUrls: ['./terms-dialog.component.css'],\n  standalone: false\n})\nexport class TermsDialogComponent {\n\n  constructor(private dialogRef: MatDialogRef<TermsDialogComponent>) { }\n\n  close() {\n    this.dialogRef.close();\n  }\n}\n","<h2 mat-dialog-title>Terms and Conditions</h2>\n\n<mat-dialog-content class=\"terms-content\">\n  <h3>1. Acceptance of Terms</h3>\n  <p>By accessing and using this application, you acknowledge that you have read, understood, and agree to be bound by these Terms and Conditions. If you do not agree to these terms, please do not use this application.</p>\n\n  <h3>2. Use of the Application</h3>\n  <p>You agree to use this application only for lawful purposes and in accordance with these Terms. You are responsible for ensuring that your use of the application complies with all applicable laws and regulations.</p>\n\n  <h3>3. User Accounts</h3>\n  <p>If you create an account, you are responsible for maintaining the confidentiality of your account credentials and for all activities that occur under your account. You agree to notify us immediately of any unauthorized use of your account.</p>\n\n  <h3>4. Intellectual Property</h3>\n  <p>All content, features, and functionality of this application, including but not limited to text, graphics, logos, and software, are the exclusive property of the application owner and are protected by copyright, trademark, and other intellectual property laws.</p>\n\n  <h3>5. User Content</h3>\n  <p>You retain ownership of any content you submit to the application. By submitting content, you grant us a non-exclusive, worldwide, royalty-free license to use, reproduce, and display such content in connection with the operation of the application.</p>\n\n  <h3>6. Limitation of Liability</h3>\n  <p>To the fullest extent permitted by law, we shall not be liable for any indirect, incidental, special, consequential, or punitive damages arising out of or related to your use of this application.</p>\n\n  <h3>7. Disclaimer of Warranties</h3>\n  <p>This application is provided \"as is\" without warranties of any kind, either express or implied. We do not warrant that the application will be uninterrupted, error-free, or free of harmful components.</p>\n\n  <h3>8. Modifications to Terms</h3>\n  <p>We reserve the right to modify these Terms at any time. Changes will be effective immediately upon posting. Your continued use of the application after any changes constitutes acceptance of the new Terms.</p>\n\n  <h3>9. Termination</h3>\n  <p>We may terminate or suspend your access to the application at any time, without prior notice, for any reason, including breach of these Terms.</p>\n\n  <h3>10. Governing Law</h3>\n  <p>These Terms shall be governed by and construed in accordance with the laws of the jurisdiction in which the application owner operates, without regard to conflict of law principles.</p>\n\n  <h3>11. Contact Information</h3>\n  <p>If you have any questions about these Terms and Conditions, please contact us through the application's support channels.</p>\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n  <button mat-flat-button color=\"primary\" (click)=\"close()\">Close</button>\n</mat-dialog-actions>\n","import { Component } from '@angular/core';\nimport { MatDialogRef } from '@angular/material/dialog';\n\n// Generic Privacy Policy dialog component for tin-spa library\n@Component({\n  selector: 'spa-privacy-dialog',\n  templateUrl: './privacy-dialog.component.html',\n  styleUrls: ['./privacy-dialog.component.css'],\n  standalone: false\n})\nexport class PrivacyDialogComponent {\n\n  constructor(private dialogRef: MatDialogRef<PrivacyDialogComponent>) { }\n\n  close() {\n    this.dialogRef.close();\n  }\n}\n","<h2 mat-dialog-title>Privacy Policy</h2>\n\n<mat-dialog-content class=\"privacy-content\">\n  <h3>1. Information We Collect</h3>\n  <p>We collect information you provide directly, such as when you create an account, use our services, or contact us for support. This may include your name, email address, and other contact information.</p>\n\n  <h3>2. How We Use Your Information</h3>\n  <p>We use the information we collect to provide, maintain, and improve our services, communicate with you, and ensure the security of our platform. We may also use your information to send you updates and promotional materials, subject to your preferences.</p>\n\n  <h3>3. Information Sharing</h3>\n  <p>We do not sell your personal information. We may share your information with third-party service providers who assist us in operating our platform, subject to confidentiality obligations. We may also disclose information when required by law or to protect our rights.</p>\n\n  <h3>4. Data Security</h3>\n  <p>We implement appropriate technical and organizational measures to protect your personal information against unauthorized access, alteration, disclosure, or destruction. However, no method of transmission over the internet is completely secure.</p>\n\n  <h3>5. Cookies and Tracking</h3>\n  <p>We use cookies and similar tracking technologies to enhance your experience, analyze usage patterns, and deliver personalized content. You can control cookie settings through your browser preferences.</p>\n\n  <h3>6. Data Retention</h3>\n  <p>We retain your personal information for as long as necessary to fulfill the purposes for which it was collected, comply with legal obligations, resolve disputes, and enforce our agreements.</p>\n\n  <h3>7. Your Rights</h3>\n  <p>Depending on your location, you may have rights regarding your personal information, including the right to access, correct, delete, or port your data. You may also have the right to opt out of certain processing activities.</p>\n\n  <h3>8. Third-Party Links</h3>\n  <p>Our application may contain links to third-party websites or services. We are not responsible for the privacy practices of these third parties, and we encourage you to review their privacy policies.</p>\n\n  <h3>9. Children's Privacy</h3>\n  <p>Our services are not directed to children under the age of 13. We do not knowingly collect personal information from children. If you believe we have collected information from a child, please contact us immediately.</p>\n\n  <h3>10. Changes to This Policy</h3>\n  <p>We may update this Privacy Policy from time to time. We will notify you of any material changes by posting the new policy on this page and updating the effective date.</p>\n\n  <h3>11. Contact Us</h3>\n  <p>If you have any questions about this Privacy Policy or our data practices, please contact us through the application's support channels.</p>\n</mat-dialog-content>\n\n<mat-dialog-actions align=\"end\">\n  <button mat-flat-button color=\"primary\" (click)=\"close()\">Close</button>\n</mat-dialog-actions>\n","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { SignalRService, NotificationEvent } from '../../services/signalr.service';\nimport { Subscription } from 'rxjs';\nimport { trigger, transition, style, animate } from '@angular/animations';\n\n// Changed: Toast notification interface for cascading alerts\nexport interface ToastItem {\n  id: number;\n  message: string;\n  icon: string;\n  color: string;\n  category: string;\n  timestamp: Date;\n}\n\n@Component({\n  selector: 'spa-toast',\n  templateUrl: './toast.component.html',\n  styleUrls: ['./toast.component.css'],\n  standalone: false,\n  animations: [\n    trigger('toastAnim', [\n      transition(':enter', [\n        style({ opacity: 0, transform: 'translateX(100%)' }),\n        animate('300ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 1, transform: 'translateX(0)' }))\n      ]),\n      transition(':leave', [\n        animate('250ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'translateX(100%)' }))\n      ])\n    ])\n  ]\n})\nexport class ToastComponent implements OnInit, OnDestroy {\n\n  toasts: ToastItem[] = [];\n  private subs: Subscription[] = [];\n  private nextId = 0;\n  private maxToasts = 5;\n  private autoDismissMs = 5000; // Changed: Auto-dismiss after 5 seconds\n\n  constructor(private signalRService: SignalRService) {}\n\n  ngOnInit(): void {\n    // Changed: Subscribe to backend NotificationService broadcasts for toast alerts\n    this.subs.push(\n      this.signalRService.notificationReceived$.subscribe(event => this.show(event))\n    );\n  }\n\n  // Changed: Build toast from backend notification event\n  private show(event: NotificationEvent) {\n    const typeConfig: Record<string, { icon: string; color: string }> = {\n      info: { icon: 'info', color: '#2196f3' },\n      warn: { icon: 'warning', color: '#ff9800' },\n      error: { icon: 'error', color: '#f44336' },\n      success: { icon: 'check_circle', color: '#4caf50' }\n    };\n    const config = typeConfig[event.type] || typeConfig['info'];\n\n    const toast: ToastItem = {\n      id: this.nextId++,\n      message: event.message,\n      icon: config.icon,\n      color: config.color,\n      category: event.category,\n      timestamp: new Date()\n    };\n\n    this.toasts.unshift(toast); // Changed: Newest at top, pushes others down\n\n    if (this.toasts.length > this.maxToasts) {\n      this.toasts.pop();\n    }\n\n    setTimeout(() => this.dismiss(toast.id), this.autoDismissMs);\n  }\n\n  dismiss(id: number) {\n    this.toasts = this.toasts.filter(t => t.id !== id);\n  }\n\n  trackToast(index: number, toast: ToastItem): number {\n    return toast.id;\n  }\n\n  ngOnDestroy(): void {\n    this.subs.forEach(s => s.unsubscribe());\n  }\n}\n","<!-- Changed: Fixed-position toast container, top-right corner with cascading layout -->\n<div class=\"toast-container\">\n  <div *ngFor=\"let toast of toasts; trackBy: trackToast\"\n       class=\"toast-item\"\n       [@toastAnim]\n       (click)=\"dismiss(toast.id)\">\n    <div class=\"toast-accent\" [style.background-color]=\"toast.color\"></div>\n    <mat-icon class=\"toast-icon\" [style.color]=\"toast.color\">{{toast.icon}}</mat-icon>\n    <div class=\"toast-content\">\n      <span class=\"toast-category\">{{toast.category}}</span>\n      <span class=\"toast-message\">{{toast.message}}</span>\n    </div>\n    <mat-icon class=\"toast-close\">close</mat-icon>\n  </div>\n</div>\n","import { Component, OnInit, OnDestroy } from '@angular/core';\nimport { Router, NavigationEnd } from '@angular/router';\nimport { Subscription } from 'rxjs';\nimport { filter } from 'rxjs/operators';\nimport { BottomTab } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { NotificationsService } from '../../services/notifications.service';\nimport { SetupService } from '../../services/setup.service';\n\n// Mobile bottom tab bar. Config-driven from AppConfig.bottomTabs, mounted once by nav-menu so a single\n// instance serves all four navigation layouts (top, top-modern, side, side-modern). It is rendered only\n// when nav-menu's existing (max-width: 600px) BreakpointObserver says smallScreen — this component\n// deliberately owns no breakpoint of its own, so there is one source of truth for \"mobile\".\n@Component({\n  selector: 'spa-bottom-tabs',\n  templateUrl: './bottom-tabs.component.html',\n  styleUrls: ['./bottom-tabs.component.css'],\n  standalone: false\n})\nexport class BottomTabsComponent implements OnInit, OnDestroy {\n\n  notificationCount$; // Re-subscription to the same stream the topbar bell uses — no new plumbing\n  activeTab = ''; // name of the tab matching the current URL, recomputed on every NavigationEnd\n  private routerSub: Subscription | undefined;\n\n  constructor(public router: Router, public dataService: DataServiceLib, private notificationsService: NotificationsService, private setupService: SetupService) {\n    this.notificationCount$ = this.notificationsService.notificationCount$;\n  }\n\n  ngOnInit() {\n    this.setActiveTab(this.router.url); // initial paint — NavigationEnd has usually already fired by now\n    this.routerSub = this.router.events.pipe(\n      filter(event => event instanceof NavigationEnd)\n    ).subscribe((event: NavigationEnd) => {\n      this.setActiveTab(event.urlAfterRedirects || event.url);\n    });\n  }\n\n  ngOnDestroy() {\n    if (this.routerSub) this.routerSub.unsubscribe();\n  }\n\n  get tabs(): BottomTab[] {\n    return this.dataService.appConfig?.bottomTabs ?? [];\n  }\n\n  // A tab with a moduleKey follows the same gate that decides whether <spa-agent> renders at all —\n  // multitenant AND the tenant having that module switched on in Getting Started. Ungated tabs always show.\n  isTabVisible(tab: BottomTab): boolean {\n    if (!this.isSurfaceAvailable(tab)) return false; // Added (DBT-1): a tab leading to a surface this app never configured is absent, not dead\n    if (!tab.moduleKey) return true;\n    return this.dataService.appConfig.multitenant && this.setupService.isModuleEnabled(tab.moduleKey);\n  }\n\n  // Added (DBT-1): does the SURFACE this tab leads to exist in this app at all? Distinct from the moduleKey gate\n  // above, which asks whether a TENANT has switched a module on — a question that presupposes both tenancy and a\n  // Getting Started toggle. Day Book has neither: it is configured (or not) by the app itself via\n  // AppConfig.dayBookConfig, and when that is undefined the route renders an empty state (Classes.ts, and\n  // day-book.component.config, which falls back to exactly this property). The default tab bar shipped Day Book\n  // ungated, so every app that never configured one gave a quarter of its mobile navigation to a cell that could\n  // only ever lead nowhere.\n  //\n  // 🔑 Absence-only, and deliberately so. This can HIDE a tab that would have led to an empty state; it can never\n  // show one that was hidden, never reorder, and never changes anything where the surface does exist — so an app\n  // with a dayBookConfig, and every app that assigns its own bottomTabs without setting `requires`, is\n  // byte-for-byte unaffected. That is what keeps it safe for the consumers outside this workspace.\n  private isSurfaceAvailable(tab: BottomTab): boolean {\n    if (!tab.requires) return true; // no surface requirement declared — the overwhelmingly common case\n    if (tab.requires === 'dayBook') return !!this.dataService.appConfig?.dayBookConfig;\n    return true; // an unrecognised requirement must not silently erase a tab\n  }\n\n  // Longest matching link wins, which is what makes 'home' behave as the fallback: on /home/day-book both\n  // the Home and Day Book tabs match, but Day Book's link is longer so only it lights up. On an unmapped\n  // page like /home/sales/invoices only Home matches, so Home stays lit.\n  private setActiveTab(url: string) {\n    const current = this.normalize(url);\n    let best = '';\n    let bestLength = -1;\n\n    this.tabs.forEach(tab => {\n      const link = this.normalize(tab.link);\n      if (!link) return;\n      if (current !== link && !current.startsWith(link + '/')) return;\n      if (link.length > bestLength) { best = tab.name; bestLength = link.length; }\n    });\n\n    this.activeTab = best;\n  }\n\n  // Router.url arrives as '/home/day-book?x=1'; tab links are configured as 'home/day-book'\n  private normalize(url: string): string {\n    if (!url) return '';\n    return url.split('?')[0].split(';')[0].split('#')[0].replace(/^\\/+/, '').replace(/\\/+$/, '');\n  }\n\n  navigate(tab: BottomTab) {\n    if (!tab.link) return;\n    this.router.navigate([tab.link]);\n  }\n\n  trackByName(index: number, tab: BottomTab): string {\n    return tab.name;\n  }\n\n}\n","<nav class=\"bt-bar\" role=\"navigation\" aria-label=\"Primary\">\n\n  <ng-container *ngFor=\"let tab of tabs; trackBy: trackByName\">\n\n    <button type=\"button\" class=\"bt-tab\" *ngIf=\"isTabVisible(tab)\" [class.active]=\"activeTab == tab.name\" [attr.aria-current]=\"activeTab == tab.name ? 'page' : null\" [attr.aria-label]=\"tab.display\" (click)=\"navigate(tab)\">\n\n      <span class=\"bt-pill\">\n        <mat-icon\n          [matBadge]=\"tab.badge == 'notifications' ? (notificationCount$ | async) : null\"\n          [matBadgeHidden]=\"tab.badge != 'notifications' || (notificationCount$ | async) === 0\"\n          matBadgeColor=\"warn\"\n          matBadgeSize=\"small\">{{tab.icon}}</mat-icon>\n      </span>\n\n      <span class=\"bt-label\">{{tab.display}}</span>\n\n    </button>\n\n  </ng-container>\n\n</nav>\n","import { AppConfig, CapItem, } from './../../classes/Classes';\nimport { Component, OnInit, Input, HostListener } from '@angular/core'; // Changed: Added HostListener for scroll detection\nimport { Router, NavigationEnd } from '@angular/router'; // Changed: Added NavigationEnd for active route tracking\nimport {  AuthService } from '../../services/auth.service';\nimport { StorageService } from '../../services/storage.service';\n\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';\nimport { NotificationsService } from '../../services/notifications.service';\nimport { SetupService } from '../../services/setup.service'; // Added: Setup readiness badge count\nimport { LastRouteService } from '../../services/last-route.service'; // Added: resumeLastRoute — records the visited page\nimport { OfflineService } from '../../services/offline.service'; // Added: unsynced-work warning on sign-out\nimport { SubscriptionService } from '../../services/subscription.service'; // Added: Subscription service for feature gating\nimport { distinctUntilChanged, filter } from 'rxjs/operators'; // Changed (F3): Added distinctUntilChanged so the auth-gated setup loads fire once per session, and again after a re-login in the same shell\nimport { Observable } from 'rxjs'; // Added: Typed setupCount$ observable\nimport { MatDialog } from '@angular/material/dialog'; // Changed: Added MatDialog for terms/privacy dialogs\nimport { TermsDialogComponent } from '../terms-dialog/terms-dialog.component'; // Changed: Added terms dialog\nimport { PrivacyDialogComponent } from '../privacy-dialog/privacy-dialog.component'; // Changed: Added privacy dialog\n\n\n@Component({\n    selector: 'spa-nav-menu',\n    templateUrl: './nav-menu.component.html',\n    styleUrls: ['./nav-menu.component.css'],\n    standalone: false\n})\nexport class NavMenuComponent {\n\n\n  constructor(public router: Router, public authService: AuthService, private storageService: StorageService, private notificationsService: NotificationsService,\n    private breakpointObserver: BreakpointObserver, public dataService: DataServiceLib, private dialog: MatDialog, public subscriptionService: SubscriptionService,\n    public setupService: SetupService,\n    private lastRouteService: LastRouteService,\n    private offlineService: OfflineService) { // Added: SetupService for the Getting Started toolbar badge // Added: LastRouteService records the page for resumeLastRoute // Added: OfflineService to warn about unsynced work on sign-out\n\n    this.notificationCount$ = this.notificationsService.notificationCount$;\n    this.setupCount$ = this.setupService.pendingCount$; // Added: pending required setup steps for badge\n    \n    // detect screen size changes\n    this.breakpointObserver.observe([\"(max-width: 600px)\"]).subscribe((result: BreakpointState) => {\n\n      if (result.matches) {\n        this.smallScreen = true\n      } else {\n        this.smallScreen = false\n      }\n\n    });\n   }\n\n  ngOnInit() {\n\n    this.authService.loggedUserFullName.subscribe(user => this.loggedUserFullName = user)\n    this.authService.myRoleObserv.subscribe(rol => this.myRole = rol);\n    this.authService.loggedinObserv.subscribe(obj => this.loggedin = obj)\n    this.authService.tenantNameObserv.subscribe(obj => this.tenantName = obj)\n\n    if (!this.smallScreen) {\n      this.isExpanded = true;\n    }\n\n    // Changed (F3): these two used to fire unconditionally right here. spa-nav-menu is app-root's FIRST CHILD, so\n    // it wraps the whole app — login and signup included — and its ngOnInit runs long before any restored token is\n    // attached. Both calls therefore answered 401 on every reload (two console errors, and on an anonymous page a\n    // handle401() bounce to login), and after a fresh login only loadCount() ever ran again (login.component.ts:270),\n    // so the module catalog stayed EMPTY for the whole session. Firing on the first non-empty token instead makes\n    // the catalog real for the first route resolution on the deep-link/F5 path — which is what a module route guard\n    // reads — and makes an anonymous visitor issue no setup calls at all. Strictly fewer requests than before.\n    // distinctUntilChanged re-fires after a logout/login in the same shell, which the ngOnInit placement never did.\n    this.authService.tokenObserv.pipe(filter(token => !!token), distinctUntilChanged()).subscribe(() => {\n      this.setupService.loadCount(); // Changed (F3): setup badge, now on an authenticated session (persists across F5 — no SignalR for setup)\n      this.setupService.loadModules(); // Changed (F3): module catalog for moduleKey menu gating, now on an authenticated session\n    });\n\n    // Added: start recording the visited page for resumeLastRoute. The nav shell only exists while signed in,\n    // so this one subscription covers every in-app navigation without touching individual pages.\n    this.lastRouteService.start();\n\n    // Changed: Track current URL for side-modern active route highlighting\n    this.currentUrl = this.router.url;\n    this.router.events.pipe(\n      filter(event => event instanceof NavigationEnd)\n    ).subscribe((event: NavigationEnd) => {\n      this.currentUrl = event.urlAfterRedirects || event.url;\n    });\n\n  }\n\n\n  notificationCount$;\n  setupCount$: Observable<number>; // Added: Getting Started pending step count (typed so template comparison compiles)\n  smallScreen\n  myRole;\n  loggedUserFullName: string;\n  tenantName : string;\n  loggedin: boolean;\n  isExpanded = false;\n\n  nowDate = new Date()\n\n  // Changed: Side-modern navigation properties\n  isMiniSidebar = false; // Mini/icon-only mode toggle\n  isMiniHovered = false; // Hover state over mini sidebar\n  openMenus = new Set<string>(); // Tracks which parent menus are expanded\n  currentUrl = ''; // Current URL for active route detection\n  topbarScrolled = false; // Changed: Tracks scroll state for topbar transparency\n\n  // Changed: Detect scroll to toggle topbar frosted glass effect\n  @HostListener('window:scroll')\n  onWindowScroll() {\n    this.topbarScrolled = window.scrollY > 30;\n  }\n\n\n  @Input() appConfig = new AppConfig();\n  @Input() footer: string = 'alsquaretech.net';\n\n\n\n  collapse() {\n    this.isExpanded = false;\n  }\n\n  toggle() {\n    this.isExpanded = !this.isExpanded;\n  }\n\n  closeSide() {\n    this.isExpanded = false;\n  }\n\n  logoff() {\n    // Added: never sign out silently on top of unsynced work. The changes are preserved either way (the outbox\n    // survives logout and drains when this user signs back in), but they must be told before they walk away.\n    this.offlineService.pendingCount().then(pending => {\n      if (pending > 0) {\n        const many = pending > 1;\n        const message = `You have ${pending} change${many ? 's' : ''} saved on this device that ${many ? 'have' : 'has'} not reached the server yet. ` +\n          `${many ? 'They' : 'It'} will be kept and sent automatically the next time you sign in here with a connection.`;\n        if (!confirm(`${message}\\n\\nSign out anyway?`)) return;\n      }\n      // Added: an explicit sign-out is not a session to resume — clear first, while AUTH_USER still resolves\n      this.lastRouteService.clear().then(() => this.authService.logoff());\n    });\n  }\n\n  redirectTo(link: string){\n\n    this.collapse();\n\n    if (link!=\"\"){\n      this.router.navigate([link]);\n    }\n\n  }\n\n\n  // Added: stable-reference cache — getSubItems() is bound to three separate *ngFor loops in the menu and\n  // was re-filtering into a NEW array on every change-detection cycle. Keyed by capItem; the sub-item list\n  // is static config, so it only needs rebuilding when capItems itself is replaced.\n  private subItemCache = new WeakMap<CapItem, CapItem[]>();\n\n  getSubItems(capItem : CapItem) : CapItem[] { // Changed: now returns a cached, stable reference\n    let subItems = this.subItemCache.get(capItem);\n    if (!subItems) {\n      // Changed: still hide pure boolean permission caps, but allow navigable isBool\n      // items (those with a link) to appear as sub-menu items\n      subItems = capItem.capSubItems.filter(x => x.showMenu && (!x.isBool || (x.link && x.link.trim() !== '')));\n      this.subItemCache.set(capItem, subItems);\n    }\n    return subItems;\n  }\n\n  // Added: Check if a capItem is enabled by subscription plan (featureKey gating)\n  isFeatureAllowed(cap: CapItem): boolean {\n    if (cap.moduleKey && !this.setupService.isModuleEnabled(cap.moduleKey)) return false; // Added (Setup v2): tenant module choice hides unused menus\n    if (!cap.featureKey) return true; // No feature restriction\n    return this.subscriptionService.isModuleEnabled(cap.featureKey);\n  }\n\n  // Changed: was `[...capItems].reverse()` — a brand new array on every change-detection cycle. There is no\n  // lifecycle hook here (appConfig is populated asynchronously), so the cache keys off the SOURCE reference\n  // and rebuilds only when capItems itself is replaced.\n  private reversedSource: CapItem[] | null = null;\n  private reversedCache: CapItem[] = [];\n\n  // Returns reversed capItems for top navigation display\n  get reversedCapItems(): CapItem[] {\n    const source = this.appConfig?.capItems ?? null;\n    if (source !== this.reversedSource) {\n      this.reversedSource = source;\n      this.reversedCache = source ? [...source].reverse() : [];\n    }\n    return this.reversedCache;\n  }\n\n  // Changed: Opens terms dialog or redirects to URL based on appConfig\n  openTerms() {\n    if (this.appConfig.termsUrl && this.appConfig.termsUrl.trim() !== '') {\n      window.open(this.appConfig.termsUrl, '_blank');\n    } else {\n      this.dialog.open(TermsDialogComponent, { width: '600px', maxHeight: '80vh', panelClass: this.dataService?.dialogPanelClass ?? [] });\n    }\n  }\n\n  // Changed: Opens privacy dialog or redirects to URL based on appConfig\n  openPrivacy() {\n    if (this.appConfig.privacyUrl && this.appConfig.privacyUrl.trim() !== '') {\n      window.open(this.appConfig.privacyUrl, '_blank');\n    } else {\n      this.dialog.open(PrivacyDialogComponent, { width: '600px', maxHeight: '80vh', panelClass: this.dataService?.dialogPanelClass ?? [] });\n    }\n  }\n\n  // Changed: Toggle mini/icon-only sidebar mode\n  toggleMiniSidebar() {\n    this.isMiniSidebar = !this.isMiniSidebar;\n    this.isMiniHovered = false;\n  }\n\n  // Changed: Hover handlers for mini sidebar overlay expansion\n  onMiniMouseEnter() {\n    if (this.isMiniSidebar) this.isMiniHovered = true;\n  }\n\n  onMiniMouseLeave() {\n    if (this.isMiniSidebar) this.isMiniHovered = false;\n  }\n\n  // Changed: Toggle parent menu expand/collapse in side-modern\n  toggleModernMenu(capName: string) {\n    if (this.openMenus.has(capName)) {\n      this.openMenus.delete(capName);\n    } else {\n      this.openMenus.add(capName);\n    }\n  }\n\n  // Changed: Check if parent menu is expanded\n  isMenuOpen(capName: string): boolean {\n    return this.openMenus.has(capName);\n  }\n\n  // Changed: Check if route matches current URL (supports HashLocationStrategy)\n  isActiveRoute(link: string): boolean {\n    if (!link || !this.currentUrl) return false;\n    const cleanUrl = this.currentUrl.replace(/^#\\//, '/').split('?')[0];\n    const cleanLink = '/' + link.replace(/^\\//, '');\n    return cleanUrl === cleanLink;\n  }\n\n  // Changed: Check if any sub-item of a parent is active\n  isParentActive(cap: CapItem): boolean {\n    if (!cap.capSubItems) return false;\n    return cap.capSubItems.some(sub => this.isActiveRoute(sub.link));\n  }\n\n  // Changed: Generate letter initials for sub-items without specific icons\n  getInitials(display: string): string {\n    if (!display) return '?';\n    const words = display.trim().split(/\\s+/);\n    return words.length > 1\n      ? (words[0][0] + words[1][0]).toUpperCase()\n      : display.substring(0, 2).toUpperCase();\n  }\n\n  // Changed: Navigate and close sidebar on mobile for side-modern\n  modernNavigate(link: string) {\n    if (link) this.router.navigate([link]);\n    if (this.smallScreen) this.isExpanded = false;\n  }\n\n  // Changed: Whether side-modern sidebar should display as expanded\n  get isModernExpanded(): boolean {\n    return !this.isMiniSidebar || this.isMiniHovered;\n  }\n\n}\n","<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top'\">\n\n  <!-- Changed: Removed mb-3 class to eliminate gap between toolbar and content -->\n  <nav class=\"toolbar navbar navbar-expand-sm navbar-toggleable-sm navbar-light border-bottom box-shadow\" style=\"padding-right: 10px;\">\n\n\n    <div class=\"container-fluid\" style=\"padding-right: 0px;\">\n\n      <img *ngIf=\"appConfig.logo!=''\" [src]=\"appConfig.logo\" style=\"height: 50px; margin-right: 2em\" />\n\n      <div>\n            <!-- <div style=\"font-size: 20px;\">\n              {{appConfig.appName}}\n            </div>\n\n            <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px;\">\n              {{tenantName}}\n            </div> -->\n\n        <div *ngIf=\"!dataService.appConfig.multitenant\" style=\"font-size: 22px;\">\n          {{appConfig.appName}}\n        </div>\n\n        <div *ngIf=\"dataService.appConfig.multitenant\" style=\"font-size: 20px; ; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\n          {{appConfig.appName}}\n        </div>\n\n        <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\n          {{tenantName}}\n        </div>\n\n      </div>\n\n\n\n      <button class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-label=\"Toggle navigation\" [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\n        <span class=\"navbar-toggler-icon\"></span>\n      </button>\n\n      <div *ngIf=\"myRole\" class=\" navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse stack-top\" style=\"margin-right: 0px;\" [ngClass]=\"{ show: isExpanded, navitems: isExpanded }\" >\n\n        <button mat-icon-button (click)=\"logoff()\" > <mat-icon>logout</mat-icon> </button>\n\n        <div *ngIf=\"dataService.appConfig.multitenant\">\n\n          <button mat-icon-button (click)=\"redirectTo('home/tenancy/settings')\" > <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon> </button>\n\n          <!-- Removed: Support icon — replaced by floating assistant chat widget -->\n        </div>\n\n\n        <button id=\"btnUser\" mat-button [matMenuTriggerFor]=\"profileMenu\"  ><mat-icon style=\"font-size: 24px;\">account_circle</mat-icon>  &nbsp;{{loggedUserFullName}}</button>\n\n        <mat-menu #profileMenu=\"matMenu\">\n          <button id=\"btnProfile\" mat-menu-item (click)=\"redirectTo('home/user/profile')\" >Profile</button>\n          <button id=\"btnLogOff\" mat-menu-item (click)=\"logoff()\">Log Off</button>\n        </mat-menu>\n\n        <div *ngFor=\"let item of reversedCapItems\">\n\n          <!-- Menu Item — Added: isFeatureAllowed check for plan-based gating -->\n          <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && !item.capSubItems && item.showMenu && isFeatureAllowed(item)\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\n\n          <!-- Menu Item with Sub items ignored — Added: isFeatureAllowed check -->\n          <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && item.ignoreSubsDisplay && isFeatureAllowed(item)\" mat-button (click)=\"redirectTo(item.link)\">{{item.display}}</button>\n\n          <!-- Menu Item with Sub items to display — Added: isFeatureAllowed check -->\n          <button id=\"btnMenu\" *ngIf=\"myRole[item.name] && item.capSubItems && item.showMenu && !item.ignoreSubsDisplay && isFeatureAllowed(item)\" mat-button [matMenuTriggerFor]=\"adminMenu\">{{item.display}}</button>\n\n\n          <!-- Sub Menu Items — Added: isFeatureAllowed check on sub-items -->\n          <mat-menu #adminMenu=\"matMenu\">\n\n            <div *ngFor=\"let subItem of item.capSubItems\">\n\n              <button *ngIf=\"myRole[subItem.name] && subItem.showMenu && isFeatureAllowed(subItem)\" mat-menu-item (click)=\"redirectTo(subItem.link)\">{{subItem.display}}</button>\n\n            </div>\n\n          </mat-menu>\n\n        </div>\n\n      </div>\n\n\n    </div>\n\n  </nav>\n\n</header>\n\n<!-- Changed: Removed top/bottom padding to eliminate gaps, but kept left/right padding for content spacing -->\n<div class=\"container-fluid tin-bg-image\" [class.has-bottom-tabs]=\"loggedin && smallScreen\" *ngIf=\"dataService.appConfig.navigation == 'top'\" style=\"padding: 12px 12px; margin: 0;\"> <!-- Changed: bottom padding so the fixed tab bar cannot cover the last row -->\n  <router-outlet></router-outlet>\n  <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\n</div>\n\n\n\n\n<!-- ============================================================ -->\n<!-- TOP-MODERN  (navigation == 'top-modern')                     -->\n<!-- Changed: Modernised horizontal top navigation                -->\n<!-- ============================================================ -->\n<header *ngIf=\"loggedin && dataService.appConfig.navigation == 'top-modern'\">\n\n  <nav class=\"tm-navbar\" [class.tm-scrolled]=\"topbarScrolled\">\n    <div class=\"tm-bar\">\n\n      <!-- Brand -->\n      <div class=\"tm-brand\" (click)=\"modernNavigate('')\">\n        <img *ngIf=\"appConfig.logo\" [src]=\"appConfig.logo\" class=\"tm-logo\" alt=\"logo\" />\n        <div class=\"tm-brand-text\">\n          <div class=\"tm-app-name\">{{appConfig.appName}}</div>\n          <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" class=\"tm-tenant\">{{tenantName}}</div>\n        </div>\n      </div>\n\n      <!-- Mobile toggle -->\n      <button class=\"tm-toggler\" type=\"button\" aria-label=\"Toggle navigation\"\n        [attr.aria-expanded]=\"isExpanded\" (click)=\"toggle()\">\n        <mat-icon>{{isExpanded ? 'close' : 'menu'}}</mat-icon>\n      </button>\n\n      <!-- Menu items -->\n      <div class=\"tm-menu\" [class.tm-menu-open]=\"isExpanded\">\n\n        <ng-container *ngFor=\"let item of dataService.appConfig.capItems\">\n          <div class=\"tm-item-wrap\"\n            *ngIf=\"myRole[item.name] && item.showMenu && isFeatureAllowed(item)\">\n\n            <!-- Simple item (no sub-items, or sub-items ignored for display) -->\n            <button *ngIf=\"!item.capSubItems || item.ignoreSubsDisplay\"\n              class=\"tm-item\"\n              [class.tm-item-active]=\"isActiveRoute(item.link)\"\n              (click)=\"modernNavigate(item.link)\">\n              <mat-icon *ngIf=\"item.icon && item.icon != 'navigate_next'\" class=\"tm-item-icon\">{{item.icon}}</mat-icon>\n              <span class=\"tm-item-text\">{{item.display}}</span>\n            </button>\n\n            <!-- Parent item with displayed sub-items -->\n            <ng-container *ngIf=\"item.capSubItems && !item.ignoreSubsDisplay\">\n              <button class=\"tm-item tm-item-parent\"\n                [class.tm-item-active]=\"isParentActive(item)\"\n                [matMenuTriggerFor]=\"tmSubMenu\">\n                <mat-icon *ngIf=\"item.icon && item.icon != 'navigate_next'\" class=\"tm-item-icon\">{{item.icon}}</mat-icon>\n                <span class=\"tm-item-text\">{{item.display}}</span>\n                <!-- Changed: Caret signals this item has more items beneath it -->\n                <mat-icon class=\"tm-item-caret\">expand_more</mat-icon>\n              </button>\n\n              <mat-menu #tmSubMenu=\"matMenu\" class=\"tm-submenu-panel\" [overlapTrigger]=\"false\" yPosition=\"below\">\n                <ng-container *ngFor=\"let sub of getSubItems(item)\">\n                  <button *ngIf=\"myRole[sub.name] && sub.showMenu && isFeatureAllowed(sub)\"\n                    mat-menu-item\n                    [class.tm-sub-active]=\"isActiveRoute(sub.link)\"\n                    (click)=\"modernNavigate(sub.link)\">\n                    <mat-icon *ngIf=\"sub.icon && sub.icon != 'navigate_next'\">{{sub.icon}}</mat-icon>\n                    <span>{{sub.display}}</span>\n                  </button>\n                </ng-container>\n              </mat-menu>\n            </ng-container>\n\n          </div>\n        </ng-container>\n\n      </div>\n\n      <!-- Right-side actions -->\n      <div class=\"tm-actions\" [class.tm-actions-open]=\"isExpanded\">\n\n        <ng-container *ngIf=\"dataService.appConfig.multitenant\">\n          <button mat-icon-button class=\"tm-action-btn\" (click)=\"modernNavigate('home/tenancy/settings')\" matTooltip=\"Organisation Settings\">\n            <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon>\n          </button>\n          <button *ngIf=\"setupService.enabled && ((setupCount$ | async) || 0) > 0 && !smallScreen\" mat-icon-button class=\"tm-action-btn\" (click)=\"modernNavigate('home/setup')\" matTooltip=\"Getting Started\"> <!-- Added: Setup readiness badge — hidden when complete or unconfigured -->\n            <mat-icon [matBadge]=\"setupCount$ | async\" matBadgeColor=\"warn\" matBadgeSize=\"small\">rocket_launch</mat-icon>\n          </button>\n          <button *ngIf=\"!smallScreen\" mat-icon-button class=\"tm-action-btn\" (click)=\"modernNavigate('home/workflow/notifications')\" matTooltip=\"Notifications\">\n            <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\n          </button>\n          <spa-offline-indicator *ngIf=\"!smallScreen\"></spa-offline-indicator> <!-- Changed: TinSync connection + pending-sync indicator -->\n        </ng-container>\n\n        <span class=\"tm-divider-v\"></span>\n\n        <!-- Profile -->\n        <button mat-button class=\"tm-user-btn\" [matMenuTriggerFor]=\"tmProfileMenu\">\n          <mat-icon class=\"tm-user-icon\">account_circle</mat-icon>\n          <span class=\"tm-user-name\">{{loggedUserFullName}}</span>\n        </button>\n\n        <mat-menu #tmProfileMenu=\"matMenu\" [overlapTrigger]=\"false\" yPosition=\"below\">\n          <button mat-menu-item (click)=\"modernNavigate('home/user/profile')\">\n            <mat-icon>person</mat-icon><span>Profile</span>\n          </button>\n          <mat-divider></mat-divider>\n          <button mat-menu-item (click)=\"logoff()\">\n            <mat-icon>logout</mat-icon><span>Log Off</span>\n          </button>\n        </mat-menu>\n\n        <!-- Sign out — Changed: aligned via flex-centred action button -->\n        <button mat-icon-button class=\"tm-action-btn tm-signout\" (click)=\"logoff()\" matTooltip=\"Sign Out\">\n          <mat-icon>logout</mat-icon>\n        </button>\n\n      </div>\n\n    </div>\n  </nav>\n\n</header>\n\n<!-- Top-modern page content — Changed: use original 'top' background (tin-bg-image), no footer bar -->\n<div class=\"container-fluid tin-bg-image\" [class.has-bottom-tabs]=\"loggedin && smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'top-modern'\" style=\"padding: 12px 12px; margin: 0;\"> <!-- Changed: bottom padding so the fixed tab bar cannot cover the last row -->\n  <router-outlet></router-outlet>\n  <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\n</div>\n\n<!-- Not logged in fallback for top-modern -->\n<div class=\"tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'top-modern'\">\n  <router-outlet></router-outlet>\n  <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\n</div>\n\n\n\n\n<!-- SIDE -->\n<mat-toolbar class=\"tin-bg-image-toolbar\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\" style=\"padding: 0px 8px;\">\n\n  <button mat-icon-button (click)=\"toggle()\" matTooltip=\"Menu\">\n    <mat-icon>menu</mat-icon>\n  </button>\n\n  <img [src]=\"dataService.appConfig.logo\" style=\"height: 50px;\" />\n\n  <div style=\"padding-left: 10px; \">\n\n    <div style=\"font-size: 22px; font-weight: 400;\">\n      {{appConfig.appName}}\n    </div>\n\n    <!-- <div style=\"font-size: 20px; height: 25px; font-weight: 400;\" [ngStyle]=\"{'margin-top': dataService.appConfig.multitenant ? '12px' : ''}\">\n      {{appConfig.appName}}\n    </div> -->\n\n    <!-- <div *ngIf=\"dataService.appConfig.multitenant && tenantName\" style=\"font-size: 12px; margin-bottom: 5px;\">\n      {{tenantName}}\n    </div> -->\n\n  </div>\n\n\n\n  <span class=\"toolbar-item-spacer\"></span>\n\n  <!-- buttons -->\n\n  <div *ngIf=\"dataService.appConfig.multitenant\" style=\"display: flex; align-items: center;\">\n\n    <!-- <label style=\"font-size: 14px;\">Hi, {{loggedUserFullName}}</label> -->\n\n    <button mat-icon-button (click)=\"redirectTo('home/tenancy/settings')\" matTooltip=\"Organisation Settings\">\n      <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon>\n    </button>\n    <label style=\"font-size: 14px;margin-right: 20px;\">{{tenantName}}</label>\n\n    <!-- Changed: Support/help icon removed — replaced by floating agent chat widget -->\n\n    <button *ngIf=\"setupService.enabled && ((setupCount$ | async) || 0) > 0 && !smallScreen\" mat-icon-button (click)=\"redirectTo('home/setup')\" matTooltip=\"Getting Started\"> <!-- Added: Setup readiness badge — hidden when complete or unconfigured -->\n      <mat-icon [matBadge]=\"setupCount$ | async\" matBadgeColor=\"warn\" matBadgeSize=\"small\">rocket_launch</mat-icon>\n    </button>\n    <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/workflow/notifications')\" matTooltip=\"Notifications\">\n      <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\n    </button>\n\n    <spa-offline-indicator *ngIf=\"!smallScreen\"></spa-offline-indicator> <!-- Changed: TinSync connection + pending-sync indicator -->\n\n  </div>\n\n\n\n  <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"userAccountMenu\"><mat-icon>account_circle</mat-icon></button>\n  <label style=\"font-size: 14px;\">{{loggedUserFullName}}</label>\n\n  <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\"  matTooltip=\"Signout\">\n    <mat-icon>logout</mat-icon>\n  </button>\n\n\n  <!-- my account menu -->\n  <mat-menu #userAccountMenu [overlapTrigger]=\"false\" yPosition=\"below\">\n\n\n    <button mat-menu-item routerLink=\"home/user/profile\">\n      <mat-icon>person</mat-icon><span>Profile</span>\n    </button>\n\n    <!-- Removed: Help menu item — replaced by floating assistant chat widget -->\n\n    <mat-divider></mat-divider>\n\n    <button mat-menu-item (click)=\"logoff()\">\n      <mat-icon>logout</mat-icon>Logout\n    </button>\n\n  </mat-menu>\n\n</mat-toolbar>\n\n\n\n\n<mat-sidenav-container class=\"app-container\" [hasBackdrop]=\"smallScreen\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\">\n\n  <mat-sidenav #sidenav [mode]=\"smallScreen ? 'over' : 'side'\" [class.mat-elevation-z4]=\"true\" [opened]=\"isExpanded\"  class=\"app-sidenav side-color\" style=\"height: 100%;\"\n  [ngStyle]=\"{'width': dataService.appConfig.navWidth}\">\n    <mat-nav-list >\n\n      <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\" >\n\n        <!-- Menu item — Added: isFeatureAllowed check for plan-based gating -->\n        <mat-list-item [routerLink]=\"cap.link\"  *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.capSubItems && cap.ignoreSubsDisplay) && isFeatureAllowed(cap)\" style=\"height: 40px;font-size: 15px;\"\n        (click)=\"smallScreen ? toggle() : null\">\n          <mat-icon [ngStyle]=\"{'color': cap.color}\" style=\"margin-right: 5px;\">{{cap.icon}}</mat-icon>{{cap.display}}\n        </mat-list-item>\n\n        <!-- Menu With Sub items — Added: isFeatureAllowed check -->\n        <mat-expansion-panel class=\"side-color\" [class.mat-elevation-z0]=\"true\"  *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay && isFeatureAllowed(cap)\">\n\n          <mat-expansion-panel-header style=\"height: 40px;padding-left: 15px;\">\n            <mat-icon [ngStyle]=\"{'color': cap.color}\" style=\"margin-right: 5px;\">{{cap.icon != 'navigate_next' ? cap.icon : 'fiber_manual_record' }}</mat-icon>{{cap.display}}\n          </mat-expansion-panel-header>\n\n          <!-- Sub items - Changed: Use ng-container to avoid blank spaces for hidden items -->\n          <mat-nav-list>\n            <ng-container *ngFor=\"let capSub of getSubItems(cap)\">\n              <mat-list-item [routerLink]=\"capSub.link\" style=\"height: 30px; font-size: 15px; padding-left: 4px; padding-right: 10px; margin-bottom: 5px;\" (click)=\"smallScreen ? toggle() : null\" *ngIf=\"myRole[capSub.name] && capSub.showMenu && isFeatureAllowed(capSub)\" [matTooltip]=\"capSub.display\" matTooltipPosition=\"right\">\n                <mat-icon [ngStyle]=\"{'color': capSub.color}\" style=\"margin-right: 5px;\">{{capSub.icon}}</mat-icon>{{capSub.display}}\n              </mat-list-item>\n            </ng-container>\n          </mat-nav-list>\n\n        </mat-expansion-panel>\n\n      </ng-container>\n\n    </mat-nav-list>\n  </mat-sidenav>\n\n\n\n  <mat-sidenav-content class=\"tin-bg-image\" [class.has-bottom-tabs]=\"loggedin && smallScreen\" style=\"padding: 0px 12px;\" *ngIf=\"loggedin && dataService.appConfig.navigation == 'side'\"> <!-- Changed: bottom padding so the fixed tab bar cannot cover the last row -->\n    <hr style=\"margin-top: 0px;\">\n    <router-outlet></router-outlet>\n    <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\n  </mat-sidenav-content>\n\n</mat-sidenav-container>\n\n\n<!-- footer -->\n<!-- Changed: hidden on mobile — the bottom tab bar owns the bottom edge there, and a footer under a fixed\n     bar is either invisible or a second competing strip of chrome -->\n<div class=\"tin-center\" *ngIf=\"loggedin && !smallScreen && dataService.appConfig.navigation == 'side'\">\n  <label style=\"text-align: center; font-size: 12px;\">&copy; {{nowDate | date : 'yyyy'}} <a color=\"primary\" class=\"terms-link\" [href]=\"appConfig.siteUrl\" target=\"_blank\">{{footer}}</a> | <a color=\"primary\" class=\"terms-link\" style=\"cursor: pointer;\" (click)=\"openTerms()\">Terms</a> | <a color=\"primary\" class=\"terms-link\" style=\"cursor: pointer;\" (click)=\"openPrivacy()\">Privacy Policy</a></label>\n</div>\n\n\n<div class=\"tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side'\">\n  <router-outlet></router-outlet>\n  <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\n</div>\n\n\n<!-- SIDE-MODERN -->\n\n<!-- Changed: Side-modern navigation layout -->\n<div class=\"sm-layout\"\n  *ngIf=\"loggedin && dataService.appConfig.navigation == 'side-modern'\"\n  [class.sm-mini]=\"isMiniSidebar && !isMiniHovered\"\n  [class.sm-mini-hovered]=\"isMiniSidebar && isMiniHovered\"\n  [class.sm-mobile-open]=\"smallScreen && isExpanded\">\n\n  <!-- Sidebar -->\n  <aside class=\"sm-sidebar\"\n    (mouseenter)=\"onMiniMouseEnter()\"\n    (mouseleave)=\"onMiniMouseLeave()\">\n\n    <!-- Background layers -->\n    <div class=\"sm-sidebar-bg\">\n      <div class=\"sm-sidebar-bg-image\" *ngIf=\"appConfig.navImage\" [ngStyle]=\"{'background-image': 'url(' + appConfig.navImage + ')'}\"></div>\n      <div class=\"sm-sidebar-bg-overlay\" [ngStyle]=\"{'background-color': appConfig.navColor}\"></div>\n    </div>\n\n    <!-- Sidebar content -->\n    <div class=\"sm-sidebar-content\">\n\n      <!-- Brand -->\n      <div class=\"sm-brand\">\n        <img *ngIf=\"appConfig.logo\" [src]=\"appConfig.logo\" alt=\"logo\" />\n        <span class=\"sm-brand-name\">{{appConfig.appName}}</span>\n      </div>\n\n      <mat-divider></mat-divider>\n\n      <!-- Profile -->\n      <div class=\"sm-profile\">\n        <mat-icon class=\"sm-profile-icon\">account_circle</mat-icon>\n        <div class=\"sm-profile-info\">\n          <div class=\"sm-profile-name\">{{loggedUserFullName}}</div>\n          <div class=\"sm-profile-role\">{{tenantName || 'User'}}</div>\n        </div>\n      </div>\n\n      <mat-divider></mat-divider>\n\n      <!-- Scrollable menu -->\n      <div class=\"sm-menu-scroll\">\n\n        <ng-container *ngFor=\"let cap of dataService.appConfig.capItems\">\n\n          <!-- Simple menu item (no sub-items or ignoring sub display) — Added: isFeatureAllowed check -->\n          <div *ngIf=\"myRole[cap.name] && cap.showMenu && (!cap.capSubItems || cap.ignoreSubsDisplay) && isFeatureAllowed(cap)\"\n            class=\"sm-menu-item\"\n            [class.sm-active]=\"isActiveRoute(cap.link)\"\n            (click)=\"modernNavigate(cap.link)\">\n            <mat-icon class=\"sm-menu-icon\">{{cap.icon != 'navigate_next' ? cap.icon : 'dashboard'}}</mat-icon>\n            <span class=\"sm-menu-text\">{{cap.display}}</span>\n          </div>\n\n          <!-- Parent menu item with sub-items — Added: isFeatureAllowed check -->\n          <ng-container *ngIf=\"myRole[cap.name] && cap.showMenu && cap.capSubItems && !cap.ignoreSubsDisplay && isFeatureAllowed(cap)\">\n\n            <!-- Parent item (toggles sub-menu) -->\n            <div class=\"sm-menu-item\"\n              [class.sm-active]=\"isParentActive(cap) && !isMenuOpen(cap.name)\"\n              (click)=\"toggleModernMenu(cap.name)\">\n              <mat-icon class=\"sm-menu-icon\">{{cap.icon != 'navigate_next' ? cap.icon : 'dashboard'}}</mat-icon>\n              <span class=\"sm-menu-text\">{{cap.display}}</span>\n              <mat-icon class=\"sm-caret\" [class.sm-caret-open]=\"isMenuOpen(cap.name)\">expand_more</mat-icon>\n            </div>\n\n            <!-- Sub-menu container (animated) -->\n            <div class=\"sm-submenu\" [class.sm-submenu-open]=\"isMenuOpen(cap.name)\">\n              <ng-container *ngFor=\"let sub of getSubItems(cap)\">\n                <div *ngIf=\"myRole[sub.name] && sub.showMenu && isFeatureAllowed(sub)\"\n                  class=\"sm-submenu-item\"\n                  [class.sm-active]=\"isActiveRoute(sub.link)\"\n                  (click)=\"modernNavigate(sub.link)\">\n                  <mat-icon *ngIf=\"sub.icon && sub.icon != 'navigate_next'\" class=\"sm-sub-icon\">{{sub.icon}}</mat-icon>\n                  <span *ngIf=\"!sub.icon || sub.icon == 'navigate_next'\" class=\"sm-initials\">{{getInitials(sub.display)}}</span>\n                  <span class=\"sm-menu-text\">{{sub.display}}</span>\n                </div>\n              </ng-container>\n            </div>\n\n          </ng-container>\n\n        </ng-container>\n\n      </div>\n\n    </div>\n  </aside>\n\n  <!-- Mobile backdrop -->\n  <div class=\"sm-backdrop\" (click)=\"isExpanded = false\"></div>\n\n  <!-- Main content -->\n  <div class=\"sm-main\">\n\n    <!-- Top bar - Changed: Added scroll class for frosted glass effect -->\n    <div class=\"sm-topbar\" [class.sm-topbar-scrolled]=\"topbarScrolled\">\n      <button mat-icon-button (click)=\"smallScreen ? toggle() : toggleMiniSidebar()\" matTooltip=\"Menu\">\n        <mat-icon>menu</mat-icon>\n      </button>\n\n      <!-- Changed: Mobile branding - show logo + app name when sidebar is hidden on small screens -->\n      <img *ngIf=\"smallScreen && appConfig.logo\" [src]=\"appConfig.logo\" alt=\"logo\" class=\"sm-topbar-logo\" />\n      <span *ngIf=\"smallScreen\" class=\"sm-topbar-brand\">{{appConfig.appName}}</span>\n\n      <span class=\"sm-topbar-spacer\"></span>\n\n      <!-- Multitenant buttons -->\n      <div *ngIf=\"dataService.appConfig.multitenant\" style=\"display: flex; align-items: center;\">\n        <button mat-icon-button (click)=\"redirectTo('home/tenancy/settings')\" matTooltip=\"Organisation Settings\">\n          <mat-icon fontSet=\"material-icons-round\">apartment</mat-icon>\n        </button>\n        <span class=\"sm-topbar-label\">{{tenantName}}</span>\n\n        <!-- Changed: Support/help icon removed — replaced by floating agent chat widget -->\n\n        <button *ngIf=\"setupService.enabled && ((setupCount$ | async) || 0) > 0 && !smallScreen\" mat-icon-button (click)=\"redirectTo('home/setup')\" matTooltip=\"Getting Started\"> <!-- Added: Setup readiness badge — hidden when complete or unconfigured -->\n          <mat-icon [matBadge]=\"setupCount$ | async\" matBadgeColor=\"warn\" matBadgeSize=\"small\">rocket_launch</mat-icon>\n        </button>\n        <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"redirectTo('home/workflow/notifications')\" matTooltip=\"Notifications\">\n          <mat-icon [matBadge]=\"notificationCount$ | async\" [matBadgeHidden]=\"(notificationCount$ | async) === 0\" matBadgeColor=\"warn\" matBadgeSize=\"small\">notifications</mat-icon>\n        </button>\n        <spa-offline-indicator *ngIf=\"!smallScreen\"></spa-offline-indicator> <!-- Changed: TinSync connection + pending-sync indicator -->\n      </div>\n\n      <!-- Profile menu -->\n      <button mat-icon-button matTooltip=\"My Account\" [matMenuTriggerFor]=\"smProfileMenu\">\n        <mat-icon>account_circle</mat-icon>\n      </button>\n      <span class=\"sm-topbar-label\">{{loggedUserFullName}}</span>\n\n      <mat-menu #smProfileMenu=\"matMenu\" [overlapTrigger]=\"false\" yPosition=\"below\">\n        <button mat-menu-item routerLink=\"home/user/profile\">\n          <mat-icon>person</mat-icon><span>Profile</span>\n        </button>\n        <!-- Changed: Help menu item removed — replaced by floating agent chat widget -->\n        <mat-divider></mat-divider>\n        <button mat-menu-item (click)=\"logoff()\">\n          <mat-icon>logout</mat-icon>Logout\n        </button>\n      </mat-menu>\n\n      <button *ngIf=\"!smallScreen\" mat-icon-button (click)=\"logoff()\" matTooltip=\"Signout\">\n        <mat-icon>logout</mat-icon>\n      </button>\n    </div>\n\n    <!-- Page content - Changed: Replaced tin-bg-image with sm-content modern texture -->\n    <div class=\"sm-content\" [class.has-bottom-tabs]=\"loggedin && smallScreen\"> <!-- Changed: bottom padding so the fixed tab bar cannot cover the last row -->\n      <router-outlet></router-outlet>\n      <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\n    </div>\n\n    <!-- Footer -->\n    <div class=\"sm-footer\">\n      &copy; {{nowDate | date : 'yyyy'}} <a [href]=\"appConfig.siteUrl\" target=\"_blank\">{{footer}}</a> | <a (click)=\"openTerms()\">Terms</a> | <a (click)=\"openPrivacy()\">Privacy Policy</a>\n    </div>\n\n  </div>\n\n</div>\n\n<!-- Not logged in fallback for side-modern -->\n<div class=\"tin-bg-image\" *ngIf=\"!loggedin && dataService.appConfig.navigation == 'side-modern'\">\n  <router-outlet></router-outlet>\n  <spa-loader [logo]=\"this.dataService.appConfig.logo\"></spa-loader>\n</div>\n\n<!-- Changed: Cascading toast notifications for real-time entity changes — visible in all layouts -->\n<spa-toast *ngIf=\"loggedin && dataService.appConfig.multitenant\"></spa-toast>\n\n<!-- Changed: Floating agent chat widget — renamed from spa-assistant -->\n<!-- Changed (Setup v3): also gated on the \"agent\" module. The widget is floating, not a nav item, so\n     CapItem.moduleKey could never reach it — a tenant who switched the assistant off in Getting Started\n     still had it hovering over every page. -->\n<spa-agent *ngIf=\"loggedin && dataService.appConfig.multitenant && setupService.isModuleEnabled('agent')\"></spa-agent>\n\n<!-- Added: mobile bottom tab bar. Mounted ONCE here, outside every layout block, because the bar is\n     position: fixed and so serves top, top-modern, side and side-modern from this single instance.\n     smallScreen is nav-menu's existing (max-width: 600px) BreakpointObserver — the one source of truth\n     for this feature, so no second breakpoint is introduced. Never renders on desktop. -->\n<spa-bottom-tabs *ngIf=\"loggedin && smallScreen\"></spa-bottom-tabs>\n","import { Router } from '@angular/router';\nimport { AuthService } from './auth.service';\nimport { MessageService } from './message.service';\nimport { Injectable } from '@angular/core';\nimport { HttpResponse, HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';\nimport { Observable, BehaviorSubject, throwError } from 'rxjs';\nimport { catchError, filter, take, switchMap, finalize } from 'rxjs/operators';\nimport { LoaderService } from './loader.service';\nimport { LogService } from './log.service';\nimport { Constants } from '../classes/Classes';\nimport { StorageService } from './storage.service';\nimport { OfflineService } from './offline.service'; // Added: TinSync — suppresses Connection Error toasts for offline-handled URLs\nimport { ApiErrorService } from './api-error.service'; // Added: friendly, de-duplicated API failure messages\nimport { TIN_SILENT_REQUEST } from '../runtime/silent-request'; // Added: Quiet Loading — marks reads that must not raise the global scrim\n\n@Injectable()\nexport class LoaderInterceptor implements HttpInterceptor {\n\n  private requests: HttpRequest<any>[] = [];\n  private isRefreshing = false; // Changed: Tracks whether a token refresh is in progress\n  private refreshResult$ = new BehaviorSubject<string | null>(null); // Changed: Signals queued requests when refresh completes\n\n  constructor(private loaderService: LoaderService, private messageService: MessageService, private authService: AuthService, private router: Router, private logService: LogService, private storage: StorageService,\n    private offline: OfflineService, // Changed: TinSync offline service injected for toast suppression\n    private apiError: ApiErrorService) { } // Added: friendly classification + burst suppression for API failures\n\n\n  removeRequest(req: HttpRequest<any>) {\n\n    const i = this.requests.indexOf(req);\n\n    if (i >= 0) {\n      this.requests.splice(i, 1);\n    }\n\n    this.loaderService.isLoading.next(this.requests.length > 0);\n  }\n\n  // Changed: was branching on localhost — showing `error.error.Message` in a dialog for developers and a bare\n  // toast everywhere else. Both were wrong for a user:\n  //   * `error.error.Message` is undefined whenever there is no JSON body (a downed backend yields a\n  //     ProgressEvent), so the dialog rendered EMPTY — \"Error\" with nothing under it.\n  //   * the toast said only \"Connection Error\", with no guidance on what to do about it.\n  // ApiErrorService now classifies the failure, phrases it for a non-technical user, and shows it at most once\n  // per kind per window so a page firing twenty calls at a downed backend produces ONE dialog, not twenty.\n  // The full technical detail still goes to the console for developers.\n  showError(userMessage : string,  error : HttpErrorResponse){\n    this.apiError.present(error);\n  }\n\n  // Changed: Helper to clone a request with the current bearer token\n  private addToken(request: HttpRequest<any>): HttpRequest<any> {\n    return request.clone({\n      setHeaders: {\n        Authorization: \"Bearer \" + this.authService.tokenSource.value,\n      }\n    });\n  }\n\n  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n\n    // Changed: Don't attach Bearer token to refresh/revoke — they use AllowAnonymous and authenticate via body\n    const url = request.url || '';\n    let requestClone = (url.includes('User/refresh') || url.includes('User/revoke'))\n      ? request.clone()\n      : this.addToken(request);\n\n    // Changed: Skip loader tracking AND generic error popups for background infrastructure — SignalR hub, agent chat,\n    // TinSync heartbeat, and the refresh/revoke auth calls. A failed silent re-login must never surface an error\n    // dialog; AuthService handles the outcome and quietly routes to the login page instead.\n    if (request.url.includes('/hubs/') || url.includes('/agent/') || url.endsWith('api/ping') || url.includes('User/refresh') || url.includes('User/revoke')) {\n      return next.handle(requestClone).pipe(\n        catchError((error: HttpErrorResponse) => throwError(() => error))\n      );\n    }\n\n    // Added: Quiet Loading — a silent request skips ONLY the in-flight bookkeeping below, so the global scrim\n    // never appears for it. It deliberately does NOT take the whitelist branch above: 401 refresh, offline\n    // suppression and the friendly error dialog must all still apply exactly as they do to any other request.\n    const silent = request.context.get(TIN_SILENT_REQUEST);\n\n    if (!silent) {\n      this.requests.push(requestClone);\n\n      if (this.requests.length > 1) {\n        this.logService.info(\"Multiple connections detected >= \" + this.requests.length)\n      }\n\n      this.loaderService.isLoading.next(true);\n    }\n\n    return next.handle(requestClone).pipe(\n      // Changed: Track response for loading spinner — nothing to remove when the request was never tracked\n      finalize(() => { if (!silent) { this.removeRequest(requestClone); } }),\n      catchError((error: HttpErrorResponse) => {\n\n        if (error.status === 401) {\n          // Changed: refresh/revoke URLs never reach here anymore — they use the pass-through branch above\n          // Changed: Handle 401 with request queuing during token refresh\n          return this.handle401(request, next);\n        }\n\n        // Changed: the old three-way branch (500 / 'Unknown Error' / everything else) only distinguished three\n        // cases and passed a label the user never actually saw. ApiErrorService classifies every status and\n        // phrases it, so the interceptor's only remaining job here is deciding whether to speak at all.\n        //\n        // A request the offline layer already handles must stay silent: TinSync has either served it from cache\n        // or queued it for later, so there is nothing wrong from the user's point of view and an error dialog\n        // would contradict the sync indicator sitting in the toolbar.\n        const isNetwork = error.status === 0 || error.statusText === 'Unknown Error';\n\n        // Added: the same argument as the line above, for the failure shape it could not see.\n        //\n        // A 408/502/503/504 is a GATEWAY saying it could not reach the origin. When the app already KNOWS it is\n        // offline — the offline indicator is up, the recovery ping is running, OfflineService is asserting it —\n        // a modal reading \"Taking too long ... please try again\" directly contradicts what the toolbar is\n        // already telling the user, and asks them to retry a thing the app is retrying on their behalf. That is\n        // the same reasoning the `isNetwork` suppression beside it already encodes; a 504 escaped it only\n        // because that clause is gated on `status === 0`.\n        //\n        // This is a STATE gate, not a time window, and the distinction is the whole reason it is safe. It cannot\n        // silence a request by wall-clock coincidence: it closes the instant a ping proves connectivity, and it\n        // can never be open in an app that has not started the connectivity subsystem at all (see\n        // OfflineService.knownOffline). Nothing here changes what an ordinary in-app request does while online,\n        // and no timeout anywhere is lengthened.\n        //\n        // Scoped by STATE ONLY, deliberately NOT by offline.suppressesUrl(). suppressesUrl() answers \"is this URL\n        // a registered offline-cached read or a queueable mutation\", and the Day Book's `daybook/get` — the exact\n        // endpoint in the owner's report — is neither. Reusing that scoping would have left the reported case\n        // unfixed while looking like a fix. The right scope for \"don't contradict the offline indicator\" is the\n        // indicator's own state, which is app-wide, not a per-URL registration.\n        const isGatewayUnreachable = error.status === 408 || error.status === 502 || error.status === 503 || error.status === 504;\n\n        const suppress = (isNetwork && this.offline.suppressesUrl(url)) || (isGatewayUnreachable && this.offline.knownOffline);\n\n        if (!suppress) {\n          this.apiError.present(error);\n        }\n\n        return throwError(() => error);\n      })\n    );\n  }\n\n  // Changed: Handles 401 errors — first caller starts refresh, subsequent callers queue and wait\n  private handle401(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n    if (!this.isRefreshing) {\n      this.isRefreshing = true;\n      this.refreshResult$.next(null); // Reset the signal\n\n      const refreshToken = this.storage.getPersistent(Constants.AUTH_REFRESH_TOKEN);\n      if (!refreshToken) {\n        this.isRefreshing = false;\n        // Changed: quiet redirect to login — no error popup; losing a session is not a system failure\n        this.authService.sessionExpired();\n        this.messageService.toast('Please sign in to continue');\n        return throwError(() => new Error('No refresh token'));\n      }\n\n      // Changed: Start refresh, then retry the original request with new token\n      return new Observable(observer => {\n        this.authService.silentRefresh().then((result) => { // Changed: silentRefresh returns tri-state result\n          this.isRefreshing = false;\n\n          if (result === 'success') {\n            this.refreshResult$.next(this.authService.tokenSource.value); // Signal waiting requests\n\n            // Retry original request with new token\n            const retryReq = this.addToken(request);\n            next.handle(retryReq).subscribe({\n              next: (event) => observer.next(event),\n              error: (err) => observer.error(err),\n              complete: () => observer.complete()\n            });\n          } else if (result === 'rejected') {\n            this.refreshResult$.next('FAILED'); // Unblock waiting requests\n            // Changed: gentle toast + login redirect instead of error dialog. This branch now fires ONLY for an\n            // explicit server rejection — the refresh endpoint answered HTTP 200 with success:false, meaning the\n            // refresh token is revoked or expired. That is the only outcome that genuinely ends a session, and it\n            // is the only one where silentRefresh() clears the stored token (auth.service.ts:370-380).\n            this.authService.sessionExpired();\n            this.messageService.toast('Please sign in to continue');\n            observer.error(new Error('Token refresh failed'));\n          } else {\n            // Changed: 'network' no longer logs the user out. silentRefresh() resolves 'network' for EVERY\n            // non-2xx on User/refresh — status 0, 408, 429 and every 5xx alike — because HttpClient routes them\n            // all to its error callback. Treating that as \"session over\" made a transient condition destroy a\n            // session that was never invalid.\n            //\n            // The 429 case is the one that turns this from untidy into damaging: an office behind a single NAT\n            // IP, whose tokens expire together after a shared morning sign-in, refreshes as one burst, trips one\n            // shared rate limit, and logs ITSELF out — every user at once, for a condition that would have\n            // cleared in seconds. 5xx and status 0 are grouped with it for the same reason: in none of them did\n            // the server assert anything about the token, so inferring \"your session is over\" from them is an\n            // inference the response does not support. Their common property is not the status number, it is the\n            // ABSENCE of an authoritative rejection.\n            //\n            // Doing nothing destructive is also what auth.service.ts already does on its own refresh paths\n            // (:265-269, :277-281, :299-304): only 'rejected' calls sessionExpired(), 'network' reschedules. This\n            // branch was the single place in the codebase that disagreed. The refresh token is deliberately\n            // preserved by silentRefresh(), the proactive timer will try again, and the next 401 re-enters here —\n            // so the session recovers on its own with no user action.\n            this.refreshResult$.next('FAILED'); // Unblock waiting requests — the ORIGINAL request still fails, only the session survives\n            this.messageService.toast('The server is busy. You are still signed in — please try again in a moment.');\n            observer.error(new Error('Token refresh unavailable'));\n          }\n        });\n      });\n    } else {\n      // Changed: Another refresh is in progress — wait for it, then retry with new token\n      return this.refreshResult$.pipe(\n        filter(result => result !== null), // Wait until refresh completes\n        take(1),\n        switchMap((result) => {\n          if (result === 'FAILED') {\n            return throwError(() => new Error('Token refresh failed'));\n          }\n          // Retry with the refreshed token\n          const retryReq = this.addToken(request);\n          return next.handle(retryReq);\n        })\n      );\n    }\n  }\n}\n","import { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { CurrencyInputMaskDirective } from './currency-input-mask.directive';\n\n@NgModule({\n  imports: [\n    CommonModule,\n    FormsModule\n  ],\n  declarations: [\n    CurrencyInputMaskDirective\n  ],\n  exports: [\n    CurrencyInputMaskDirective\n  ]\n})\nexport class CurrencyInputModule {\n}\n","// Quiet Loading (FSD D6) — the loading state of a details dialog's form.\n//\n// The whole point is spatial continuity: this renders the SHAPE of the form that is about to arrive, built from\n// the very same `formConfig.fields` spa-form will use, so the dialog does not jump when the entity lands. It is\n// therefore a deliberate mirror of form.component's two layout decisions — the multiColumn rule (form.component.ts\n// ngOnInit) and the span-col test (form.component.html) — and both are copied from the source, not re-invented.\n//\n// Purely presentational: no data, no requests, no state beyond the units it builds on input change.\nimport { Component, Input, OnChanges } from '@angular/core';\nimport { Field, FormConfig } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore';\nimport { AuthService } from '../../services/auth.service';\n\n// One rendered placeholder cell. Precomputed on input change rather than resolved per change-detection cycle,\n// because the widths/delays must stay stable — a width that re-randomises every CD would visibly twitch.\ninterface SkeletonUnit {\n  section: boolean;   // renders a single full-width heading bar\n  blank: boolean;     // holds the grid cell but draws nothing (type 'blank' does the same in the real form)\n  span: boolean;      // span-col — full grid width\n  labelWidth: string; // varied 30-60% so the column does not read as a barcode\n  delay: string;      // sweep stagger, top-to-bottom\n}\n\n@Component({\n    selector: 'spa-form-skeleton',\n    templateUrl: './form-skeleton.component.html',\n    styleUrls: ['./form-skeleton.component.css'],\n    standalone: false\n})\nexport class FormSkeletonComponent implements OnChanges {\n\n  constructor(private authService: AuthService) { }\n\n  @Input() config: FormConfig;\n\n  units: SkeletonUnit[] = [];\n  multiColumn = false;\n\n  ngOnChanges() {\n    this.build();\n  }\n\n  // Label widths cycle through a fixed set (not Math.random) so the skeleton is deterministic and testable,\n  // while still looking organic. Values stay inside the 30-60% band the design calls for.\n  private static readonly LABEL_WIDTHS = [46, 34, 58, 40, 52, 30, 60, 38];\n  private static readonly STAGGER_MS = 60; // each row starts its sweep slightly after the one above it\n\n  private build() {\n    const fields: Field[] = this.config?.fields ?? [];\n\n    // Copied from form.component.ts ngOnInit: an explicit truthy config.multiColumn wins, otherwise the\n    // \"more than two fields\" rule decides — and it counts ALL fields, not the visible ones. Reproduced exactly\n    // (truthiness, not `!== undefined`) so the skeleton lays out in the same number of columns as the real form.\n    this.multiColumn = this.config?.multiColumn ? this.config.multiColumn : fields.length > 2;\n\n    this.units = fields\n      .filter(field => this.isVisible(field))\n      .map((field, index) => ({\n        section: field.type === 'section',\n        blank: field.type === 'blank',\n        span: this.isSpanned(field),\n        labelWidth: `${FormSkeletonComponent.LABEL_WIDTHS[index % FormSkeletonComponent.LABEL_WIDTHS.length]}%`,\n        delay: `${index * FormSkeletonComponent.STAGGER_MS}ms`,\n      }));\n  }\n\n  // Copied from form.component.html's ngClass on the field wrapper.\n  private isSpanned(field: Field): boolean {\n    return !!field.span || field.type === 'section' || field.type === 'file' || field.type === 'file-view' || field.type === 'editor';\n  }\n\n  // The entity has not arrived yet, so visibility is resolved against an empty object. Security rules, mode rules\n  // (hideOnCreate/hideOnExists) and static hidden/visible flags all still apply; only a caller's visible()/hidden()\n  // FUNCTION can object, because it may dereference a record that does not exist yet. A throwing predicate falls\n  // back to \"show\" — a placeholder bar too many for a few hundred milliseconds is the harmless failure.\n  private isVisible(field: Field): boolean {\n    try {\n      return Core.testVisible(this.config, {}, field, this.authService.currentRoleSource.value);\n    } catch {\n      return true;\n    }\n  }\n}\n","<!-- Quiet Loading (FSD D6): same grid decision as form.component.html line 5 (tin-grid vs tin-col) and the same\n     span-col wrapper per field, so the placeholder occupies the space the real controls are about to fill.\n     aria-busy marks the region as pending (D7); the bars themselves are decoration and are hidden from AT. -->\n<div class=\"tin-form-skel\" [ngClass]=\"multiColumn ? 'tin-grid' : 'tin-col'\" aria-busy=\"true\">\n\n  <div *ngFor=\"let unit of units\" [ngClass]=\"unit.span ? 'span-col' : ''\" class=\"tin-form-skel-cell\">\n\n    <!-- section: one full-width heading bar, matching the form's larger section label -->\n    <span *ngIf=\"unit.section\" class=\"tin-skel tin-form-skel-heading\" [style.animation-delay]=\"unit.delay\" aria-hidden=\"true\"></span>\n\n    <!-- a normal field: short label bar above a control band exactly --tin-field-band tall -->\n    <ng-container *ngIf=\"!unit.section && !unit.blank\">\n      <span class=\"tin-skel tin-form-skel-label\" [style.width]=\"unit.labelWidth\" [style.animation-delay]=\"unit.delay\" aria-hidden=\"true\"></span>\n      <span class=\"tin-skel tin-form-skel-band\" [style.animation-delay]=\"unit.delay\" aria-hidden=\"true\"></span>\n    </ng-container>\n\n  </div>\n\n</div>\n","import { Component, ElementRef, Input, OnInit, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core'; // Changed: Added OnChanges, SimpleChanges; Changed: ElementRef so spa-tabs-float can measure the REAL tab header and hand over to it at the exact pixel\nimport { TableConfig } from '../../classes/Classes';\nimport { Subject } from 'rxjs';\nimport { TabService, VisibleTab } from '../../services/tab.service';\n\n// Component to display multiple tables in tabs with lazy loading and count badges\n@Component({\n    selector: 'spa-tabs',\n    templateUrl: './tabs.component.html',\n    styleUrls: ['./tabs.component.css'],\n    standalone: false\n})\nexport class TabsComponent implements OnInit, OnChanges { // Changed: Implement OnChanges\n\n  constructor(private tabService: TabService, private host: ElementRef<HTMLElement>) { } // Changed: host injected for headerElement below\n\n  // Added: the REAL Material tab-title strip. spa-tabs-float measures this to know the exact moment the real\n  // strip reaches the floating strip's resting line, so the hand-off is pixel-identical — no jump, and the two\n  // are never on screen together. Returns null before the group renders (no tabs / not yet mounted).\n  get headerElement(): HTMLElement | null {\n    return this.host.nativeElement.querySelector('.mat-mdc-tab-header');\n  }\n\n  // Added: select a tab from OUTSIDE the group (the floating strip). Routed through the same handler a real\n  // click uses, so lazy loading of that tab's table behaves identically whichever strip was clicked.\n  selectTab(index: number): void {\n    if (index === this.selectedTabIndex) return;\n    this.onTabChange({ index });\n  }\n\n  ngOnInit(): void {\n    // Changed: seed the tab state BEFORE the visibility sweep. updateVisibleTabs() is the only line in this hook\n    // that runs consumer-supplied visible/hidden predicates — code this library does not own and cannot trust —\n    // and when one of them threw (a details dialog renders its tabs before loadAction returns, so a predicate\n    // written `x => !x.vehicleID` met an undefined record), ngOnInit aborted on its FIRST statement. countsInitialized\n    // stayed false, so the ngOnChanges guard below never let the eager pass run again and no badge was ever\n    // requested for the life of the dialog — the tab only showed a number once the user clicked it and its own grid\n    // reported. Seeding first means a throw costs one pass, not the whole feature: the ngOnChanges that fires when\n    // the parent record arrives still syncs. TinCore.resolveVisibility now also stops that throw at source.\n    //\n    // Changed: initializeTabs no longer fetches (fetchCounts=false) — syncTabCounts() below is the ONE place a\n    // badge is requested, so countUrls records exactly what was asked for and a tab can never fall between the\n    // eager pass and the resolve pass. initializeTabs is still what builds the per-tab reload subjects, and with\n    // fetchCounts=false it never consults eagerIndex, so nothing is lost by resolving that index after this call.\n    const initialized = this.tabService.initializeTabs(this.tableConfigs, this.parentDetails, undefined, false);\n    this.tabCounts = initialized.tabCounts;\n    this.tableReloads = initialized.tableReloads;\n    this.countsInitialized = true; // Added: ngOnChanges runs BEFORE ngOnInit on the first bind — counts are seeded here, never there\n\n    this.updateVisibleTabs(); // Changed: still resolved before syncTabCounts — the tab opened on load is the first VISIBLE one, and its count is skipped in favour of its own grid total\n    this.syncTabCounts(); // Changed (was seedCountUrls): fetch every badge that is already resolvable, and record only what was actually requested\n\n    // Added: targeted sibling refresh — the host pushes a tab index (into tableConfigs) to reload that tab's\n    // table and count badge (e.g. a custom catalog tab submitting a request refreshes the My Requests tab).\n    this.reloadTab?.subscribe((index: number) => {\n      this.tableReloads[index]?.next(true);\n      this.refreshTabCount(index);\n    });\n  }\n\n  // Changed: Recalculate visible tabs when inputs change\n  ngOnChanges(changes: SimpleChanges): void {\n    if (changes['tableConfigs'] || changes['parentDetails']) {\n      this.updateVisibleTabs();\n      // Added: details dialogs load the parent record asynchronously, so the counts fired at init had an unresolved\n      // {id} placeholder — re-fire them now that the id is known, otherwise the badge keeps the global count forever\n      if (this.countsInitialized) this.syncTabCounts();\n    }\n  }\n\n  private countsInitialized = false; // Added: guards syncTabCounts until ngOnInit has built tabCounts/tableReloads\n  private countUrls: { [index: number]: string } = {}; // Added: the count URL each tab was actually REQUESTED with (never a URL we only resolved and then skipped)\n  private eagerIndex?: number; // Added: the tab opened on load — its grid publishes the same total, so it never needs a count call\n\n  // Changed (was refreshResolvedCounts): the single place a badge is requested. Fetch every tab whose count URL\n  // is resolvable and has not already been requested for THIS parent record; never fetch a tab whose own mounted\n  // grid is about to publish the same number.\n  //\n  // What this fixes: the previous pair (seedCountUrls + refreshResolvedCounts) recorded a URL for every tab,\n  // including tabs it had deliberately NOT fetched. A tab skipped as \"the open one\" therefore looked already-done\n  // on every later pass, so if it was not in fact the tab being rendered its badge never arrived and the number\n  // only appeared once the user clicked it and the grid reported — exactly the reported symptom. eagerIndex was\n  // also frozen at ngOnInit, when a details dialog has not yet loaded its record, so every tab whose visibility\n  // depends on that record was still hidden and the index pointed at the wrong tab.\n  private syncTabCounts(): void {\n    (this.tableConfigs ?? []).forEach((config, index) => {\n      const url = this.tabService.resolveCountUrl(config, this.parentDetails);\n      if (!url || url.includes('{')) return; // no derivable count, or the parent record has not supplied the id yet — a later pass retries\n      if (this.gridWillReport(config, index)) return; // its own grid is the authority; do NOT record the URL, so it is still eligible if it stops being the open tab\n      if (url === this.countUrls[index]) return; // already requested for this parent — keeps auto-refresh ticks from re-firing every count\n      this.countUrls[index] = url;\n      this.refreshTabCount(index);\n    });\n  }\n\n  // Added: the open tab's own grid publishes its total, so its count call is redundant — but ONLY while that grid\n  // is actually mounted. A tab that is not rendered publishes nothing, and treating it as though it would was what\n  // left a permanently blank badge.\n  private gridWillReport(config: TableConfig, index: number): boolean {\n    if (!this.tabService.gridPublishesOwnTotal(config, index, this.eagerIndex)) return false;\n    return this.shouldLoadTabData(this.visibleTabs.findIndex(tab => tab.originalIndex === index));\n  }\n\n  // Added: the tab's own grid is the authority on how many rows belong to this parent, so adopt its total —\n  // the badge then always matches the \"1 – 1 of 1\" shown under the tabs and cannot drift from a separate count call\n  onTabTotal(index: number, total: number): void {\n    if (total === null || total === undefined) return;\n    this.tabCounts[index] = total;\n  }\n\n  @Input() tableConfigs: TableConfig[] = [];\n  @Input() reload: Subject<boolean>;\n  @Input() reloadTab?: Subject<number>; // Added: targeted single-tab reload (index into tableConfigs) + count refresh\n  @Input() parentDetails: any;\n  @Input() localMode = false; // Added: one-step create — tables run against in-memory rows on parentDetails\n  @Input() nestingLevel: number = 0; // Changed: Track nesting depth for dialog recursion control\n  @Output() formRefresh = new EventEmitter<void>();\n  @Output() actionSuccess = new EventEmitter<void>(); // Changed: bubble successful nested-table actions to the host dialog so refreshOnCloseIfActioned can flag that something changed\n\n  tabCounts: { [index: number]: number } = {};\n  activeTabsLoaded: { [index: number]: boolean } = {};\n  selectedTabIndex = 0;\n  tableReloads: { [index: number]: Subject<boolean> } = {};\n  visibleTabs: VisibleTab[] = []; // Changed: Cache visible tabs to prevent infinite loop\n\n  // Changed: Use service for tab change handling\n  onTabChange(event: any): void {\n    this.selectedTabIndex = event.index;\n    this.tabService.handleTabChange(this.selectedTabIndex, this.activeTabsLoaded);\n  }\n\n  // Changed: Use service to get tab count\n  getTabCount(index: number): number | undefined {\n    return this.tabService.getTabCount(index, this.tabCounts);\n  }\n\n  // Changed: Use service to check if badge should be shown\n  shouldShowBadge(index: number): boolean {\n    return this.tabService.shouldShowBadge(index, this.tableConfigs, this.tabCounts);\n  }\n\n  // Changed: Use service to get tab title\n  getTabTitle(config: TableConfig): string {\n    return this.tabService.getTabTitle(config);\n  }\n\n  // Changed: Use service to check if tab data should be loaded\n  shouldLoadTabData(index: number): boolean {\n    return this.tabService.shouldLoadTabData(index, this.activeTabsLoaded);\n  }\n\n  // Refresh count for specific tab\n  refreshTabCount(index: number): void {\n    // Changed: forget the recorded URL when a badge does NOT arrive, so the next sync pass asks again instead of\n    // treating the tab as done. Without this one failed response left that badge blank for the life of the dialog.\n    this.tabService.refreshTabCount(index, this.tableConfigs, this.tabCounts, this.parentDetails, succeeded => { if (!succeeded) delete this.countUrls[index]; }); // Changed: Pass parentDetails for URL placeholder replacement\n  }\n\n  // Changed: Handle action success from table (matching tabs-internal)\n  onTableActionSuccess(tabIndex: number, event: any): void {\n    const config = this.tableConfigs[tabIndex];\n    \n    // Refresh count if available\n    this.refreshTabCount(tabIndex);\n\n    this.actionSuccess.emit(); // Changed: always notify the host dialog an action succeeded (independent of causeFormRefresh)\n\n    // Trigger form refresh if configured\n    if (config.causeFormRefresh) {\n      this.formRefresh.emit();\n    }\n  }\n\n  // Changed: Check if tab is visible based on permissions and conditions\n  isTabVisible(config: TableConfig): boolean {\n    return this.tabService.isTabVisible(config, this.parentDetails);\n  }\n\n  // Changed: Update cached visible tabs - called on init and when inputs change\n  updateVisibleTabs(): void {\n    this.visibleTabs = this.tabService.getVisibleTabs(this.tableConfigs, this.parentDetails);\n    // Changed: eagerIndex is recomputed here rather than captured once in ngOnInit. At ngOnInit a details dialog\n    // has not loaded its record yet, so any tab with a data-driven visible/hidden condition was still hidden and\n    // the first visible tab — the one whose grid is actually mounted — was not the one this index named.\n    this.eagerIndex = this.visibleTabs[0]?.originalIndex;\n  }\n\n  // Changed: Get reload subject for specific tab or use global reload\n  getReloadSubject(index: number): Subject<boolean> {\n    return this.reload || this.tableReloads[index];\n  }\n}","<mat-tab-group (selectedTabChange)=\"onTabChange($event)\" [selectedIndex]=\"selectedTabIndex\">\n\n  <!-- Changed: Use cached visibleTabs property to prevent infinite change detection loop -->\n  <ng-container *ngFor=\"let tab of visibleTabs; let i = index\">\n    <mat-tab><!-- TS-11: visibleTabs is already filtered via getVisibleTabs; dropped per-tab isTabVisible() call per CD -->\n\n      <!-- Tab label with count pill.\n           Changed: was matBadge, which renders as a faint superscript unless the consuming app includes\n           Material's badge theme — several do not, so the number was effectively invisible. This pill is\n           styled entirely in this component, so every app gets the same legible count.\n           An empty tab still shows its count, muted rather than accented: saying \"nothing in here\" before\n           the tab is opened is the whole point, and it saves the round trip of opening it. -->\n      <ng-template matTabLabel>\n        <span class=\"tab-label\">\n          {{getTabTitle(tab.config)}}\n          <span *ngIf=\"shouldShowBadge(tab.originalIndex)\"\n                class=\"tab-count\"\n                [class.tab-count-zero]=\"getTabCount(tab.originalIndex) === 0\">{{getTabCount(tab.originalIndex)}}</span>\n        </span>\n      </ng-template>\n\n      <!-- Tab content: custom template when provided (tabTemplate), otherwise the lazy-loaded table.\n           Templates keep the same lazy semantics — rendered only once the tab has been activated. -->\n      <div *ngIf=\"shouldLoadTabData(i) && tab.config.tabTemplate\" class=\"tab-content\">\n        <ng-container [ngTemplateOutlet]=\"tab.config.tabTemplate\"></ng-container>\n      </div>\n\n      <div *ngIf=\"shouldLoadTabData(i) && !tab.config.tabTemplate\" class=\"tab-content\">\n        <spa-table\n          [config]=\"tab.config\"\n          [reload]=\"getReloadSubject(tab.originalIndex)\"\n          [inTab]=\"true\"\n          [activeTab]=\"selectedTabIndex === i\"\n          [nestingLevel]=\"nestingLevel\"\n          [localMode]=\"localMode\"\n          [parentDetails]=\"parentDetails\"\n          (totalChange)=\"onTabTotal(tab.originalIndex, $event)\"\n          (actionSuccess)=\"onTableActionSuccess(tab.originalIndex, $event)\">\n        </spa-table><!-- Changed: badge adopts the grid's filtered total so it can never show a global/unfiltered count --><!-- Changed: localMode + parentDetails passed through for one-step create local tables -->\n      </div>\n\n      <!-- Placeholder for non-loaded tabs -->\n      <div *ngIf=\"!shouldLoadTabData(i)\" class=\"tab-placeholder\">\n        <!-- Empty placeholder - content will load when tab is activated -->\n      </div>\n\n    </mat-tab>\n  </ng-container>\n\n</mat-tab-group>","import { Component, Input } from '@angular/core';\nimport { StatusConfig, StatusItem } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Changed: central visibility resolver\n\n\n\n@Component({\n    selector: 'spa-statuses',\n    templateUrl: './statuses.component.html',\n    styleUrls: ['./statuses.component.css'],\n    standalone: false\n})\nexport class StatusesComponent {\n\n  @Input() config: StatusConfig;\n  @Input() data: any;\n\n  // Check if the entire component should be visible\n  isComponentVisible(): boolean {\n    if (!this.config || !this.data) return false;\n    return Core.isItemVisible(this.config, this.data); // Changed: unified visible/hidden replaces hiddenCondition\n  }\n\n  // Check if individual status item should be visible\n  isItemVisible(item: StatusItem): boolean {\n    if (!this.data) return false;\n    return Core.isItemVisible(item, this.data); // Changed: unified visible/hidden replaces hiddenCondition\n  }\n\n  // Get the icon based on status value and state conditions\n  getIcon(item: StatusItem): string {\n    if (!this.data || !item.states) return '';\n    \n    const matchingState = item.states.find(state => state.condition(this.data));\n    \n    return matchingState ? matchingState.icon : '';\n  }\n\n  // Get the icon color based on status value and state conditions\n  getIconColor(item: StatusItem): string {\n    if (!this.data || !item.states) return '';\n    \n    const matchingState = item.states.find(state => state.condition(this.data));\n    \n    return matchingState ? matchingState.color : '';\n  }\n}","<div *ngIf=\"isComponentVisible()\" class=\"statuses-container\">\n  <ng-container *ngFor=\"let item of config.items\">\n    <button \n      *ngIf=\"isItemVisible(item)\"\n      mat-stroked-button \n      class=\"status-button\">\n      {{item.name}} \n      <mat-icon [ngStyle]=\"{'color': getIconColor(item)}\">{{getIcon(item)}}</mat-icon>\n    </button>\n  </ng-container>\n</div>","import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, NgZone, OnDestroy, ViewChild } from '@angular/core';\nimport { TabsComponent } from './tabs.component';\n\n// Floating tab-TITLE strip for the details dialog (owner ask, 2026-08-20).\n//\n// Why this exists: in a details dialog with nested table tabs the tab strip sits below the form. When the\n// form is long the strip is off the bottom of the scroll region and a user never learns the tables are\n// there at all. This pins the TITLES ONLY (never the table content) to the bottom edge of the dialog body\n// while the form is scrolled, and hands over to the real strip the moment the real strip gets there.\n//\n// Why not plain `position: sticky` on the real Material strip — the obvious answer, and it does not work:\n// a sticky box is constrained to the padding box of ITS OWN PARENT, not to the scroll container. The real\n// strip lives inside mat-tab-group inside spa-tabs, which is itself at the very bottom of the content, so\n// sticking it would only pin it while spa-tabs is ALREADY on screen — exactly the case that needs no help.\n// The float therefore has to live in an element that spans the whole scrolled content: it is mounted as the\n// last child of the dialog's `.tin-input`, which does.\n//\n// Why it cannot disturb any existing dialog: the anchor is `height: 0`, so it occupies no space in flow in\n// any state; and the strip inside it is absolutely positioned. A dialog whose tabs are already visible\n// (short form) never shows it, because the very same measurement that releases it also keeps it down.\n@Component({\n    selector: 'spa-tabs-float',\n    templateUrl: './tabsFloat.component.html',\n    styleUrls: ['./tabsFloat.component.css'],\n    standalone: false\n})\nexport class TabsFloatComponent implements AfterViewInit, OnDestroy {\n\n  // The live spa-tabs instance. Titles, counts, visibility and selection are all READ FROM IT rather than\n  // recomputed here — so the float can never disagree with the real strip, and no second count call is made.\n  @Input() tabs: TabsComponent;\n\n  @ViewChild('strip') strip: ElementRef<HTMLElement>;\n  @ViewChild('anchor') anchor: ElementRef<HTMLElement>;\n\n  visible = false;\n\n  constructor(private host: ElementRef<HTMLElement>, private zone: NgZone, private cdr: ChangeDetectorRef) { }\n\n  private scroller: HTMLElement | null = null;\n  private frame = 0;\n  private observer: ResizeObserver | null = null;\n  private timers: any[] = []; // Added: the settle re-measures, cleared on destroy so a closed dialog leaves nothing pending\n  private listener = () => this.schedule();\n\n  ngAfterViewInit(): void {\n    this.scroller = this.findScroller();\n    if (!this.scroller) return;\n\n    // Outside Angular: this fires on every scroll frame and must not run change detection for its own sake.\n    // Only an actual flip of `visible` re-enters the zone (see evaluate()).\n    this.zone.runOutsideAngular(() => {\n      this.scroller!.addEventListener('scroll', this.listener, { passive: true });\n      window.addEventListener('resize', this.listener, { passive: true });\n\n      // A details form changes height without any scrolling — expandable sections, an async record arriving,\n      // a validation subscript appearing. Re-measure whenever the content box does anything.\n      if (typeof ResizeObserver !== 'undefined') {\n        this.observer = new ResizeObserver(() => this.schedule());\n        this.observer.observe(this.scroller!);\n        if (this.host.nativeElement.parentElement) this.observer.observe(this.host.nativeElement.parentElement);\n      }\n      this.schedule();\n\n      // A dialog opens with a scale/opacity animation and its tab tables arrive asynchronously, so the very\n      // first measurement is taken against a surface that is still moving. These two re-measure the settled\n      // dialog; without them a mid-animation reading could stand until the user happened to scroll.\n      this.timers.push(setTimeout(() => this.schedule(), 200), setTimeout(() => this.schedule(), 700));\n    });\n  }\n\n  ngOnDestroy(): void {\n    if (this.frame) cancelAnimationFrame(this.frame);\n    this.timers.forEach(t => clearTimeout(t));\n    this.scroller?.removeEventListener('scroll', this.listener);\n    window.removeEventListener('resize', this.listener);\n    this.observer?.disconnect();\n  }\n\n  // Clicking a title selects that tab and smooth-scrolls the dialog body down to the real tables — his\n  // \"they can just click on the tab title and then it scrolls right at the bottom to the actual view\".\n  // Selection happens FIRST so the tab's table has begun loading by the time the scroll lands on it.\n  go(index: number): void {\n    this.tabs?.selectTab(index);\n    const header = this.tabs?.headerElement;\n    if (!this.scroller || !header) return;\n    const top = this.scroller.scrollTop + (header.getBoundingClientRect().top - this.scroller.getBoundingClientRect().top) - 8; // 8px of breathing room above the strip\n    this.scroller.scrollTo({ top, behavior: 'smooth' });\n  }\n\n  private schedule(): void {\n    if (this.frame) return;\n    this.frame = requestAnimationFrame(() => { this.frame = 0; this.evaluate(); });\n  }\n\n  // The whole behaviour, in one measurement. `line` is the Y of the TOP edge of the floating strip where it\n  // rests. The float shows only while the real strip's own top is still below that line — i.e. while the real\n  // strip has not yet arrived. The instant it reaches the line the float goes and the real one is already\n  // exactly there, which is why the hand-off has no jump and why two strips are never visible at once.\n  private evaluate(): void {\n    const header = this.tabs?.headerElement;\n    const strip = this.strip?.nativeElement;\n    let show = false;\n\n    if (this.scroller && header && strip && header.offsetParent !== null) {\n      const box = this.scroller.getBoundingClientRect();\n      const height = strip.offsetHeight || 48;\n\n      // A sticky box rests against its container's CONTENT box, so the scroll container's own padding-bottom\n      // leaves a band below the strip that form text scrolls through in full view. Measure that band from the\n      // stuck anchor and hand it to the CSS as --tin-float-gap, which pulls the strip down over it. Measured,\n      // not hard-coded, so a future change to that padding needs no second edit here. Doing it before the\n      // `show` test keeps the release line correct: with the gap applied the strip's top is box.bottom - height.\n      show = header.getBoundingClientRect().top > (box.bottom - height) + 1; // +1 absorbs sub-pixel layout\n\n      // Only while the anchor is actually STUCK: once it releases at the end of the scroll its bottom is\n      // somewhere up the page and the same subtraction yields a nonsense pull. Deliberately NOT gated on\n      // `show` — the dialog measures 12.8px instead of 16px mid open-animation, and gating on `show` froze\n      // that half-settled value until the user happened to scroll.\n      const anchor = this.anchor?.nativeElement;\n      if (anchor) {\n        const anchorBottom = anchor.getBoundingClientRect().bottom;\n        const stuck = anchorBottom <= box.bottom && anchorBottom >= box.top;\n        if (stuck) strip.style.setProperty('--tin-float-gap', Math.max(0, box.bottom - anchorBottom) + 'px');\n      }\n    }\n\n    if (show === this.visible) return;\n    this.zone.run(() => { this.visible = show; this.cdr.markForCheck(); }); // only a real flip costs a CD pass\n  }\n\n  // The dialog's scroll region. Named class first (that IS the container in every details dialog); the\n  // generic walk is a fallback so the component stays correct if it is ever mounted somewhere else.\n  private findScroller(): HTMLElement | null {\n    const named = this.host.nativeElement.closest('.dialog-scroll-content') as HTMLElement | null;\n    if (named) return named;\n    let node = this.host.nativeElement.parentElement;\n    while (node) {\n      const overflow = getComputedStyle(node).overflowY;\n      if (overflow === 'auto' || overflow === 'scroll') return node;\n      node = node.parentElement;\n    }\n    return null;\n  }\n}\n","<!-- Zero-height sticky anchor. It is deliberately ALWAYS in flow and always height 0, so no dialog layout\n     changes in any state; the strip itself is absolutely positioned off its bottom edge. -->\n<div #anchor class=\"tin-float-anchor\" *ngIf=\"tabs\">\n\n  <!-- Kept in the DOM when hidden (opacity/transform, not display:none) for two reasons: its height must be\n       measurable to compute the release line, and the show/hide reads as a slide rather than a blink. -->\n  <!-- Changed: NOT a second tablist. This strip is a scroll shortcut to the real Material tab strip, which is the\n       one authoritative tablist on the page. Declaring role=\"tablist\"/role=\"tab\" here put TWO nodes carrying each\n       tab's accessible name into the a11y tree, which (a) is invalid ARIA anyway — these buttons control no\n       tabpanel and have no aria-controls — and (b) made every `getByRole('tab', { name })` in the estate a\n       strict-mode violation that reads as a MISSING tab. They stay plain <button>s: same click, same focus order,\n       same appearance, still reachable as getByRole('button', { name }). aria-current marks the active one. -->\n  <div #strip class=\"tin-float-strip\" [class.tin-float-on]=\"visible\" [attr.aria-hidden]=\"!visible\" role=\"group\" aria-label=\"Jump to tab\">\n\n    <button type=\"button\" class=\"tin-float-tab\" *ngFor=\"let tab of tabs.visibleTabs; let i = index\"\n      [class.tin-float-tab-active]=\"tabs.selectedTabIndex === i\" [attr.aria-current]=\"tabs.selectedTabIndex === i ? 'true' : null\" [attr.tabindex]=\"visible ? 0 : -1\" (click)=\"go(i)\">\n      <span class=\"tin-float-label\">\n        {{ tabs.getTabTitle(tab.config) }}\n        <!-- Same pill, same rules as the real strip — read straight off spa-tabs, never recomputed here -->\n        <span *ngIf=\"tabs.shouldShowBadge(tab.originalIndex)\" class=\"tin-float-count\" [class.tin-float-count-zero]=\"tabs.getTabCount(tab.originalIndex) === 0\">{{ tabs.getTabCount(tab.originalIndex) }}</span>\n      </span>\n    </button>\n\n  </div>\n\n</div>\n","\nimport { Component, OnInit, Inject, Output, EventEmitter, OnDestroy, NgZone, ViewChild } from '@angular/core'; // TS-20: NgZone to run the autoRefresh interval outside the zone; ViewChild reaches the rendered spa-form\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { FormConfig, Field, TableConfig, Button, DetailsDialogConfig, Action, ApiResponse, StepConfig, StatusConfig, CloseOptions } from '../../classes/Classes';\nimport { MessageService } from '../../services/message.service';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { Core, DetailsDialogProcessor } from '../../classes/TinCore';\nimport { FormComponent } from '../form/form.component'; // Added: reveal the section holding a field rejected by validation\nimport { LoaderService } from '../../services/loader.service';\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';\nimport { Subject, Subscription, config, interval } from 'rxjs';\nimport { ButtonService } from '../../services/button.service';\nimport { DialogService } from '../../services/dialog.service';\nimport { AuthService } from '../../services/auth.service';\nimport { TableConfigService } from '../../services/table-config.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — this dialog is exactly where an unnoticed toast leads to a re-submit\nimport { resolveQuietLoading, QUIET_DELAY_MS, QUIET_MIN_MS } from '../../runtime/quiet-loading'; // Added: Quiet Loading — shared config-over-app precedence resolver\nimport { PerceivedProgress } from '../../classes/perceived-progress'; // Added: same progress curve the table stage uses, so dialog and table move identically\n// Removed: MatTabChangeEvent import - tab logic moved to spa-tabs-internal\n\n// TS-16: precomputed extra-button view-model — buttonWithConfig (the clone the visible/disabled tests need) plus its\n// resolved visible/disabled/color, built once per details/mode change instead of cloning `{ ...button, detailsConfig: {...} }`\n// on every testVisible/testDisabled call per extra button per change-detection cycle.\ninterface ExtraButtonVM { button: Button; visible: boolean; disabled: boolean; color: string; }\n\n@Component({\n    selector: 'spa-detailsDialog',\n    templateUrl: './detailsDialog.component.html',\n    styleUrls: ['./table.component.css'],\n    standalone: false\n})\nexport class DetailsDialog implements OnInit, OnDestroy {\n\n  constructor(private breakpointObserver: BreakpointObserver,private loaderService: LoaderService,public dataService: DataServiceLib,private messageService: MessageService,\n    private dialogRef: MatDialogRef<DetailsDialog>, @Inject(MAT_DIALOG_DATA) public detailsConfig: DetailsDialogConfig, private buttonService: ButtonService,\n    private dialogService: DialogService, private authService: AuthService, public tableConfigService: TableConfigService, private zone: NgZone, // TS-20: NgZone injected\n    private apiErrorService: ApiErrorService) // Added: routes application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n  {\n    // detect screen size changes\n    this.subs.push(this.breakpointObserver.observe([\"(max-width: 600px)\"]).subscribe((result: BreakpointState) => { // Changed: TS-7 track subscription\n\n      if (result.matches) {\n        this.smallScreen = true\n      }else {\n        this.smallScreen = false\n      }\n\n    }));\n  }\n\n  private subs: Subscription[] = []; // TS-7: breakpoint + isLoading subscriptions leaked per dialog open (isLoading fires on every HTTP request), retaining every closed dialog\n\n  // Added: appConfig.dialogStyle === 'modern'. Resolved once at open time; false keeps the existing look exactly.\n  modern = false;\n\n  // Added (Quiet Loading): a DetailsDialogConfig value always wins, including an explicit false; otherwise the\n  // app-wide AppConfig.quietLoading decides. A getter (not a resolved field) so it stays correct if an app\n  // flips appConfig at runtime, and so nothing is written back into the shared config object.\n  get effQuietLoading(): boolean {\n    return resolveQuietLoading(this.detailsConfig, this.dataService.appConfig?.quietLoading);\n  }\n\n  ngOnInit() {\n    // Added: opt-in modern styling. The panel class carries the surface/header/footer treatment from\n    // tin-styles.css, which component CSS cannot apply because the Material surface is an ancestor of this view.\n    this.modern = !!this.dataService?.modernDialogs;\n    if (this.modern) this.dialogRef.addPanelClass('tin-dialog-modern');\n\n    // Changed: Read nestingLevel from injected config and determine if tabs should be shown\n    this.nestingLevel = this.detailsConfig.nestingLevel ?? 0;\n    this.showTabs = this.nestingLevel < 2;\n\n    const { tableConfig, tableConfigs, formConfig, stepConfig, statusConfig, buttons } = DetailsDialogProcessor.initializeConfigs(this.detailsConfig);\n    this.tableConfig = tableConfig;\n    this.tableConfigs = tableConfigs;\n    this.formConfig = formConfig;\n    this.stepConfig = stepConfig;\n    this.statusConfig = statusConfig;\n    this.buttons = buttons;\n\n    let resp = DetailsDialogProcessor.handleFormMode(this.detailsConfig, this.formConfig,);\n\n    // Changed: TinSync — pending offline rows have no server ID yet, so edit/view them from the local row instead of loading by action\n    if (resp.loadByAction && this.detailsConfig.details?._offline) {\n      resp = { ...resp, loadByAction: false, details: this.detailsConfig.details };\n    }\n\n    if (resp.loadByAction){\n      this.loadByAction = true;\n      formConfig.loadAction = resp.action;\n      this.loadData(resp.action, false);\n    }else{\n      this.details = resp.details;\n      DetailsDialogProcessor.setHeroValue(this.detailsConfig, this.details);\n      this.seedFormDefaults(); // Added: Row branch — the record is final here, so defaults apply before the form renders\n      this.loadByAction = false;\n      this.isLoadComplete = true;\n    }\n\n    this.fileField = DetailsDialogProcessor.setFileField(this.formConfig);\n\n    this.subs.push(this.loaderService.isLoading.subscribe(x => this.isProcessing = x)); // Changed: TS-7 track subscription (isLoading fires on every HTTP request)\n\n    const { extraButtons, createButton, editButton, deleteButton } = DetailsDialogProcessor.setupButtons(this.buttons);\n    this.extraButtons = extraButtons;\n    this.createButton = createButton;\n    this.editButton = editButton;\n    this.deleteButton = deleteButton;\n\n    this.setTitleAction();\n    this.initAutoRefresh();\n    this.rebuildButtonVMs(); // TS-16: seed button VMs with current details/mode\n\n    // Changed: Check backend state on open if initAction configured\n    if (this.detailsConfig.initAction) {\n      this.isLoadComplete = false;\n      const quiet = this.effQuietLoading; // Added (Quiet Loading): the initAction backend check is a READ — same treatment as the entity load\n      this.beginRead(quiet);\n      this.dataService.CallApi(this.detailsConfig.initAction, '', quiet ? { silent: true } : undefined).subscribe({\n        error: (err) => { this.settleRead(quiet); throw err; }, // Added (Quiet Loading): an HTTP failure never reaches next — settle the read or the buttons stay disabled forever (rethrow keeps today's error reporting)\n        next: (apiResponse: ApiResponse) => {\n        this.settleRead(quiet, () => {\n          if (apiResponse.success && apiResponse.data?.hasItems) {\n            this.details = apiResponse.data;\n            this.formConfig.mode = 'edit';\n            this.formConfig.loadAction = this.detailsConfig.initAction;\n            this.loadByAction = true;\n            this.setTitleAction();\n            if (this.tableConfigs) {\n              this.tableReload.next(true);\n            }\n          }\n          this.isLoadComplete = true;\n          this.rebuildButtonVMs(); // TS-16: details/mode may have changed after initAction\n        });\n        } // Changed (Quiet Loading): closes the `next` handler of the observer object above\n      });\n    }\n\n  }\n\n  ngOnDestroy() {\n    // Cleanup subscription on component destroy\n    this.stopAutoRefresh();\n    this.subs.forEach(s => s.unsubscribe()); // Changed: TS-7 release breakpoint + isLoading subscriptions so closed dialogs are not retained\n\n    // Added (Quiet Loading): a pending skeleton/settle timer would otherwise fire into a destroyed dialog\n    if (this.skeletonDelayTimer) clearTimeout(this.skeletonDelayTimer);\n    if (this.skeletonSettleTimer) clearTimeout(this.skeletonSettleTimer);\n    this.skeletonDelayTimer = null;\n    this.skeletonSettleTimer = null;\n    this.pending = null;\n\n    // Added (Phase 5): a dialog closed MID-READ left PerceivedProgress's requestAnimationFrame loop\n    // re-scheduling itself for the remaining life of the page, writing progressPercent into a destroyed\n    // component on every frame — and one more leaked loop for every dialog closed that way. The table already\n    // did this through clearStage(); the dialog was the surface that did not.\n    this.progress.stop();\n    this.progressRunning = false;\n    this.readsInFlight = 0;\n  }\n\n  private refreshSubscription: Subscription;\n  autoRefreshEnabled: boolean = false;\n  userKeepOpen: boolean = false; // Added: runtime state for the user-controlled Keep Open checkbox\n  \n  titleAction = \"View\";\n  loadByAction = false;\n  actionPerformed = false; // Changed: set when any successful action (POST) happens while the dialog is open — footer button, nested-tab table action, or nested dialog; drives refreshOnCloseIfActioned\n\n  extraButtons: Button[];\n  buttons: Button[];\n  createButton: Button;\n  editButton: Button;\n  deleteButton: Button;\n\n  // modeButton : Button\n  fileField: Field;\n  files: any[] = [];\n\n  tableReload: Subject<boolean> = new Subject();\n\n  tableConfig: TableConfig\n  tableConfigs : TableConfig[]\n  // GR-1: the form binds to `details` (from the /id fetch). Since the backend now sends translatable\n  // updatedByName + updatedDate instead of the pre-composed updatedByDetails string, compose the audit-footer\n  // string on every details assignment so the includeAudit field has a value to display.\n  private _details: any;\n  get details(): any { return this._details; }\n  set details(value: any) {\n    this._details = value;\n    if (value && !value.updatedByDetails && (value.updatedByName || value.updatedDate) && this.formConfig?.includeAudit === true) {\n      const namePart = (value.updatedByName || '').trim();\n      const datePart = value.updatedDate\n        ? new Date(value.updatedDate).toLocaleString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }).replace(',', '')\n        : '';\n      value.updatedByDetails = `Last updated by ${namePart} on ${datePart}.`;\n    }\n  }\n  formConfig: FormConfig;\n  stepConfig : StepConfig;\n  statusConfig : StatusConfig;\n  smallScreen = false;\n\n  nestingLevel: number = 0; // Changed: Track dialog nesting depth for recursion control\n  showTabs: boolean = true; // Changed: Controls whether tabs are rendered — false when nestingLevel >= 2\n\n  isLoadComplete: boolean = false;\n  isProcessing: boolean = false;\n\n  // ---------------------------------------------------------------------------\n  // Added (Quiet Loading, FSD D6): local read state for the entity load.\n  //\n  // Two SEPARATE flags on purpose:\n  //   entityLoading — true from the instant the request leaves until its data is applied. Silent requests never\n  //                   flip LoaderService.isLoading, so without this every [disabled]=\"isProcessing\" button would\n  //                   stay ENABLED while the record loads and a user could submit an empty form.\n  //   showSkeleton  — the RENDER gate, and deliberately delayed. D2's anti-flicker contract: a response that beats\n  //                   SKELETON_DELAY_MS (a listCache hit resolves synchronously) must paint no placeholder at all,\n  //                   and a skeleton that HAS painted is held at least SKELETON_MIN_MS so it cannot strobe.\n  //\n  // All of it is inert with the flag off: beginRead/settleRead take the original synchronous path, no timer is\n  // armed, and entityLoading simply tracks the same window the global scrim already covered.\n  // ---------------------------------------------------------------------------\n  private static readonly SKELETON_DELAY_MS = QUIET_DELAY_MS; // Changed: shared anti-flicker threshold\n  private static readonly SKELETON_MIN_MS = QUIET_MIN_MS;     // Changed: shared minimum display\n\n  showSkeleton = false;                                 // template gate for spa-form-skeleton\n  private readsInFlight = 0;                            // entity loads + initAction currently outstanding\n  private skeletonDelayTimer: any = null;               // pending \"paint the skeleton\" timer\n  private skeletonSettleTimer: any = null;              // pending \"apply the data\" timer (minimum-display hold)\n  private pending: { apply?: () => void } | null = null; // the deferred application, kept so a second load can flush it\n  private skeletonShownAt = 0;                          // when a skeleton actually painted (0 = none, e.g. a refresh)\n\n  // Added (Quiet Loading): ORed into every button [disabled] alongside isProcessing — see the block above.\n  get entityLoading(): boolean {\n    return this.readsInFlight > 0;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Added 2026-08-05: the dialog's own progress line.\n  //\n  // This REPLACES `<mat-progress-bar mode=\"indeterminate\">`, which looped forever at a constant speed and so\n  // conveyed only \"busy\", never \"progressing\". It now runs the same PerceivedProgress curve as the table's\n  // stage, so a dialog and the table behind it move identically instead of using two different idioms.\n  //\n  // NOTE: this reverses the earlier \"do not touch the dialog mat-progress-bar\" decision. The bar is no longer\n  // a separate feature with its own switch: it is part of the same non-blocking loading story, so\n  // `appConfig.quietLoading` now controls it. // Changed: the old progressLine flag it named has been deleted\n  // ---------------------------------------------------------------------------\n  progressPercent = 0; // float — bar width\n  progressDisplay = 0; // integer — tabular-nums caption, so it never jitters\n\n  private progress = new PerceivedProgress({\n    onChange: p => { this.progressPercent = p; this.progressDisplay = Math.round(p); }\n  });\n\n  private progressRunning = false;\n\n  // Tracks THE FORM'S OWN DATA LOAD, and nothing else.\n  //\n  // Deliberately NOT keyed on isProcessing. isProcessing mirrors the GLOBAL LoaderService.isLoading, so any\n  // request anywhere — including a nested tab's table, which owns its own stage and refresh line — would drive\n  // this bar and it would complete on whichever call happened to finish first. A details dialog always has a\n  // form, so the honest thing for the bar to represent is that form's record arriving. The nested tables\n  // manage themselves, exactly as they do on a page.\n  get showProgressLine(): boolean {\n    return this.effQuietLoading && this.entityLoading;\n  }\n\n  // Drives the curve off whatever the template is about to show. Called from the read lifecycle and from the\n  // isLoading subscription, so a write gets the same bar as a read without either path knowing about the other.\n  private syncProgress(): void {\n    const should = this.showProgressLine;\n    if (should && !this.progressRunning) {\n      this.progressRunning = true;\n      this.progress.start();\n    } else if (!should && this.progressRunning) {\n      this.progressRunning = false;\n      this.progress.complete();\n    }\n  }\n\n  // Added (Quiet Loading): registers a read. With quiet off this only counts; with quiet on it also arms the\n  // anti-flicker delay, so nothing renders until the response has had its 150ms grace.\n  private beginRead(quiet: boolean) {\n    this.readsInFlight++;\n    this.syncProgress(); // Added: the bar starts with the form's read, not with any nested table's\n\n    if (!quiet) return;\n\n    this.flushPending(); // a second load must not swallow the first response's data\n    if (this.skeletonDelayTimer) clearTimeout(this.skeletonDelayTimer);\n    this.skeletonShownAt = 0;\n\n    this.skeletonDelayTimer = setTimeout(() => {\n      this.skeletonDelayTimer = null;\n      this.showSkeleton = true;\n      // Only start the minimum-display clock when the skeleton can ACTUALLY paint. On a refresh the record is\n      // already on screen (the skeleton branch is `!details`), so there is nothing to hold open and the fresh\n      // values must land the instant they arrive.\n      this.skeletonShownAt = this.skeletonWouldRender() ? Date.now() : 0;\n    }, DetailsDialog.SKELETON_DELAY_MS);\n  }\n\n  // Added (Quiet Loading): mirrors the template condition — the skeleton only occupies the screen while there is\n  // no record to render a form from.\n  private skeletonWouldRender(): boolean {\n    return !!this.formConfig && !this.details;\n  }\n\n  // Added (Quiet Loading): ends a read. `apply` lands immediately unless a skeleton is still inside its minimum\n  // display window, in which case it waits out the remainder (at most SKELETON_MIN_MS).\n  private settleRead(quiet: boolean, apply?: () => void) {\n\n    if (!quiet) { // untouched legacy path — no timers, no deferral, identical to pre-Quiet-Loading behaviour\n      this.finishRead(apply);\n      return;\n    }\n\n    if (this.skeletonDelayTimer) { clearTimeout(this.skeletonDelayTimer); this.skeletonDelayTimer = null; }\n\n    const held = this.skeletonShownAt ? DetailsDialog.SKELETON_MIN_MS - (Date.now() - this.skeletonShownAt) : 0;\n    if (held <= 0) { this.finishRead(apply); return; }\n\n    this.pending = { apply };\n    this.skeletonSettleTimer = setTimeout(() => {\n      this.skeletonSettleTimer = null;\n      const run = this.pending;\n      this.pending = null;\n      this.finishRead(run?.apply);\n    }, held);\n  }\n\n  // Added (Quiet Loading): the single place a read is closed out — one decrement per beginRead, whichever path\n  // got here.\n  private finishRead(apply?: () => void) {\n    this.showSkeleton = false;\n    this.skeletonShownAt = 0;\n    if (this.readsInFlight > 0) this.readsInFlight--;\n    this.syncProgress(); // Added: ramps the bar to 100 once the form's record has actually landed\n    if (apply) apply();\n  }\n\n  // Added (Quiet Loading): runs a still-deferred application now, so two loads in quick succession cannot drop the\n  // first response's data (and cannot leave its in-flight count stranded).\n  private flushPending() {\n    if (this.skeletonSettleTimer) { clearTimeout(this.skeletonSettleTimer); this.skeletonSettleTimer = null; }\n    if (!this.pending) return;\n    const run = this.pending;\n    this.pending = null;\n    this.finishRead(run.apply);\n  }\n\n  @Output() inputChange = new EventEmitter();\n\n  @ViewChild(FormComponent) formComponent: FormComponent; // Added: the rendered form — used to reveal the section holding a field that failed validation\n\n  private initAutoRefresh() {\n    const config = this.detailsConfig.autoRefreshConfig;\n    if (!config) return;\n\n    // Set initial state based on defaultOn configuration\n    this.autoRefreshEnabled = config.defaultOn || false;\n\n    // Start auto-refresh if enabled by default\n    if (this.autoRefreshEnabled) {\n      this.startAutoRefresh();\n    }\n  }\n\n  private startAutoRefresh() {\n\n    if (!this.detailsConfig.autoRefreshConfig) return;\n    \n    const refreshInterval = this.detailsConfig.autoRefreshConfig.interval || 5000; // Default to 5 seconds\n    \n    // Clear any existing subscription\n    this.stopAutoRefresh();\n    \n    // TS-20: run the interval outside Angular so idle ticks don't trigger CD; re-enter the zone only to apply an actual refresh\n    this.zone.runOutsideAngular(() => {\n      this.refreshSubscription = interval(refreshInterval).subscribe(() => {\n        if (this.isLoadComplete && !this.isProcessing) {\n          this.zone.run(() => this.refreshData());\n        }\n      });\n    });\n  }\n\n  private stopAutoRefresh() {\n    if (this.refreshSubscription) {\n      this.refreshSubscription.unsubscribe();\n      this.refreshSubscription = null;\n    }\n  }\n\n  toggleAutoRefresh() {\n    // this.autoRefreshEnabled = !this.autoRefreshEnabled;\n    \n    if (this.autoRefreshEnabled) {\n      this.startAutoRefresh();\n    } else {\n      this.stopAutoRefresh();\n    }\n  }\n\n  loadData(action: Action, causeTablesReload) {\n\n    if (action && this.loadByAction) {\n\n      const quiet = this.effQuietLoading; // Added (Quiet Loading): resolved ONCE per load so the request and the render can never disagree\n      this.beginRead(quiet); // Added: buttons disable immediately; the skeleton (if any) is armed, not shown\n\n      // Changed (Quiet Loading): a quiet dialog reads its record silently, so opening it never drops the\n      // full-screen scrim over the app. Passing `undefined` is identical to omitting the argument, so the\n      // non-quiet call is byte-for-byte the call that was here before.\n      this.dataService.CallApi(action, '', quiet ? { silent: true } : undefined).subscribe({\n        error: (err) => {\n          // Added (Quiet Loading): an HTTP failure (401 exhausted, 500, network) errors the observable and NEVER\n          // reaches next. Without this the read would stay counted forever — every button permanently disabled and,\n          // when quiet, a skeleton shimmering behind the interceptor's error dialog. Rethrowing keeps the error\n          // reported exactly as it was before this handler existed (RxJS re-reports a throw from an error handler).\n          this.settleRead(quiet);\n          throw err;\n        },\n        next: (apiResponse: ApiResponse) => {\n\n        if (apiResponse.success) {\n          // Changed (Quiet Loading): the application is routed through settleRead so a painted skeleton can serve\n          // its minimum display time before the form replaces it. With quiet off it runs synchronously, as before.\n          this.settleRead(quiet, () => {\n            this.details = apiResponse.data\n            this.seedFormDefaults(); // Added: Url branch — seed only once the loaded record is in place, so a value the server sent is never overwritten\n            this.isLoadComplete = true;\n            // DetailsDialogProcessor.setHeroValue(this.detailsConfig, this.details);\n            if(causeTablesReload) this.tableReload.next(true);\n\n            const config = this.detailsConfig.autoRefreshConfig;\n            if (this.autoRefreshEnabled && config?.stopCondition && config.stopCondition(this.details)) {\n              this.autoRefreshEnabled = false;\n              this.stopAutoRefresh();\n            }\n\n            this.rebuildButtonVMs(); // TS-16: details changed after (re)load — recompute button VMs\n          });\n        }\n        else{\n          this.settleRead(quiet, () => { // Changed (Quiet Loading): same settle path on failure, or the skeleton shimmers on behind the error dialog\n            // Changed: TinSync — if a by-action load fails offline, fall back to the row the table already passed in so existing records stay editable.\n            // Changed: ...but ONLY when that row is a row of THIS entity. On a column drill-in it is not: shift's Trips\n            // grid drills from a trip row into a driver, so the fallback wrote a TRIP into a driver form, set\n            // isLoadComplete and rendered every field empty with nothing thrown — the dialog \"opened blank\". The\n            // template never gated on isLoadComplete, so leaving details unset would have kept the same blank form;\n            // a details dialog that cannot load its record has nothing to show, so it says why and closes.\n            // Changed: a PERMISSION REFUSAL is not an offline read, and the row fallback below must not swallow it.\n            // The fallback exists so a record stays editable when the network is gone; the server answering\n            // \"Access denied\" is the opposite case - it is present, it has decided, and it will refuse the write too.\n            // Observed in shift-spa: a role holding drivers (cap106) but not employees (cap18) opened a driver from\n            // the Drivers grid and got a form that looked real, populated from the grid row, with no message at all -\n            // the refusal only surfaced on Submit. The drill-in path already refused cleanly; this aligns the two.\n            const accessRefused = this.isAccessRefusal(apiResponse);\n            if (this.detailsConfig.details && !this.detailsConfig.drillIn && !accessRefused) {\n              this.details = this.detailsConfig.details;\n              this.isLoadComplete = true;\n            } else {\n              this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Changed: by-action details load failed with no cached row to fall back on — opaque server text gets the friendly dialog\n              if (this.detailsConfig.drillIn || accessRefused) this.dialogRef.close(); // Changed: a refused record closes on EVERY path, not only a drill-in - there is nothing to show and nothing that could be saved. Closes with undefined, which TableComponent.open already treats as a dismissal — no refresh, no emit, no onSuccessButton\n            }\n\n            if (this.autoRefreshEnabled) {\n              this.autoRefreshEnabled = false;\n              this.stopAutoRefresh();\n            }\n\n            this.rebuildButtonVMs(); // TS-16: details changed after (re)load — recompute button VMs\n          });\n        }\n\n        } // Changed (Quiet Loading): closes the `next` handler of the observer object above\n      });\n    }\n\n  }\n\n  // Added: is this failure the server REFUSING the caller, rather than a read that merely could not complete?\n  // Deliberately narrow. TinWeb generates one sentence for a capability refusal, in one place (BaseController.Get\n  // via HasAccess): \"Access denied for {Entity} - {View|Edit|Create|Full} permission required\". Matching that shape\n  // leaves every other business failure - validation, not-found, a transient server message - on the row-fallback\n  // path above, so this changes behaviour only for the case it was written for.\n  private isAccessRefusal(apiResponse: ApiResponse): boolean {\n    return /access denied/i.test(apiResponse?.message ?? '');\n  }\n\n  inputChanged(event) {\n    this.inputChange.emit({ field: event.field, value: event.value })\n  }\n\n\n  setMode(newMode){\n    this.formConfig.mode = newMode\n    this.setTitleAction()\n    this.rebuildButtonVMs(); // TS-16: mode changed — recompute button VMs\n  }\n\n  setTitleAction(){\n    if (this.formConfig.fixedTitle) {\n      this.titleAction = \"\";\n      return;\n    }\n\n    // Changed: the header renders \"{{titleAction}} {{formConfig.title}}\", so a title that already OPENS with\n    // the button's action word printed it twice — \"Propose Propose an arrangement\" (tenant-transfer.service.ts:51\n    // under the 'Propose' create button) and \"Check In Check In Vehicle\" (shift workshop.service.ts:45 under\n    // 'Check In'). Suppress the prefix in that case; the title already carries the verb.\n    const action = this.buttonService.getTitleAction(this.formConfig.mode, this.buttons);\n    this.titleAction = this.titleOpensWithAction(action, this.formConfig.title) ? \"\" : action;\n  }\n\n  // Added: true when the title's FIRST WORD is the action's first word, compared case-insensitively and on a\n  // whole-word basis. Word-based, not startsWith(), so a title that merely shares a prefix (\"Proposal details\"\n  // under a \"Propose\" button) is left alone and keeps its action word — only a real repeat is dropped.\n  private titleOpensWithAction(action: string, title: string): boolean {\n    const firstWord = (text: string) => (text ?? \"\").trim().toLowerCase().split(/\\s+/)[0] ?? \"\";\n    const actionWord = firstWord(action);\n    return actionWord.length > 0 && actionWord === firstWord(title);\n  }\n\n  // TS-16: template binds these precomputed VMs instead of calling testVisible/testDisabled/getButtonColor (each cloning objects) per CD\n  extraButtonVMs: ExtraButtonVM[] = [];\n  editButtonVM: { visible: boolean; disabled: boolean } = { visible: false, disabled: false };\n\n  // TS-16: build the button-with-config clone once (same shape testVisible/testDisabled used to build on every call)\n  private buildButtonWithConfig(button: Button): Button {\n    return { ...button, detailsConfig: button.detailsConfig ? { ...button.detailsConfig } : this.detailsConfig };\n  }\n\n  // TS-16: recompute button VMs whenever details or mode change (called from ngOnInit, setMode, and async load/save callbacks)\n  private rebuildButtonVMs() {\n    this.extraButtonVMs = (this.extraButtons ?? []).map(button => {\n      const bc = this.buildButtonWithConfig(button);\n      return {\n        button,\n        visible: this.buttonService.testVisible(bc, this.details),\n        disabled: this.buttonService.testDisabled(bc, this.details),\n        color: this.buttonService.getButtonColor(button, this.details),\n      };\n    });\n\n    if (this.editButton) {\n      const ebc = this.buildButtonWithConfig(this.editButton);\n      this.editButtonVM = { visible: this.buttonService.testVisible(ebc, this.details), disabled: this.buttonService.testDisabled(ebc, this.details) };\n    }\n  }\n\n  getButton(name: string) {\n    return this.buttonService.getButton(this.buttons, name);\n  }\n\n  testDisabled(row, buttonName: string): boolean {\n    const button = this.getButton(buttonName);\n\n    if (!button) return false;\n\n    // Create a copy of the button with component's detailsConfig\n    const buttonWithConfig = {\n      ...button,\n      detailsConfig: button.detailsConfig ? { ...button.detailsConfig } : this.detailsConfig\n    };\n\n    return this.buttonService.testDisabled(buttonWithConfig, row);\n  }\n\n\n  testVisible(row, buttonName: string): boolean {\n    const button = this.getButton(buttonName);\n    if (!button) return false;\n\n    // Create a copy of the button with component's detailsConfig\n    const buttonWithConfig = {\n      ...button,\n      detailsConfig: button.detailsConfig ? { ...button.detailsConfig } : this.detailsConfig\n    };\n\n    return this.buttonService.testVisible(buttonWithConfig, row)\n  }\n\n  // Removed: testVisibleTab method - handled by TabService in spa-tabs-internal\n\n  getButtonColor(button: Button, row) {\n    return this.buttonService.getButtonColor(button, row);\n  }\n\n  getVisibleFields() {\n    return this.formConfig.fields?.filter(x => Core.testVisible(this.formConfig, this.details, x, this.authService.currentRoleSource.value))\n  }\n\n  // Added: the dialog twin of TableComponent.seedInlineDefaults, and deliberately the same shape. Core.generateObject\n  // applies defaultValue ONLY on the create branch of handleFormMode, so a CAPTURE dialog declared mode:'edit'\n  // (Record Payment, Dispose Asset, Record Death) rendered every one of its defaults blank and the operator retyped\n  // the obvious answer. Opt-in via detailsConfig.seedDefaults, default off, because a TRUE-edit dialog must not\n  // acquire values simply by being opened. The two guards are the precedent's, unchanged in meaning:\n  //   1. only an EMPTY value is seeded, so a value the row or the server supplied is never overwritten;\n  //   2. only a field that passes testVisible is seeded, because an unrendered field must never be silently\n  //      seeded -- nobody can see or correct what it was seeded with. That covers hidden:true, a hidden/visible\n  //      predicate, hideOnExists and a field the role cannot see.\n  // Fields are walked in declaration order against the record AS IT IS BEING SEEDED, so a predicate that reads an\n  // earlier field (disposalAmount's `hidden: x => x.disposalType !== 0`) sees the value just applied and resolves\n  // exactly as the rendered form will. The value comes from Core.getInitialValue, so a seeded default is identical\n  // to what the same field would have received on the create path -- including defaultValue:'now' for dates.\n  private seedFormDefaults() {\n    if (!this.detailsConfig.seedDefaults || !this.details || !this.formConfig?.fields) return;\n    const currentRole = this.authService.currentRoleSource.value;\n    for (const field of this.formConfig.fields) {\n      if (field.type === 'section' || field.type === 'blank') continue; // matches generateObject — these carry no value\n      if (field.defaultValue === undefined || field.defaultValue === null) continue;\n      const current = this.details[field.name];\n      if (current !== undefined && current !== null && current !== '') continue;\n      if (!Core.testVisible(this.formConfig, this.details, field, currentRole)) continue;\n      this.details[field.name] = Core.getInitialValue(field);\n    }\n  }\n\n  // Added: expand the section a field sits under. Validation runs over every visible field, collapsed or not,\n  // so without this a required field inside a folded section is rejected with nothing on screen to correct.\n  // Delegated to the form component because it owns the cached visible-field list the template renders.\n  private revealSection(field: Field) {\n    this.formComponent?.revealSection(field);\n  }\n\n\n  create() {\n    this.handleButtonAction('create');\n  }\n\n  edit() {\n    this.handleButtonAction('edit');\n  }\n\n  delete() {\n    const button = this.buttonService.getButton(this.buttons, 'delete');\n    if (!button) return;\n\n    // Changed: same shared resolver as table.deleteModel — this is the details-dialog copy of that prompt and\n    // the two must not disagree about what a delete confirmation looks like.\n    // Changed: dropped the `Are you sure you want to delete ?` literal (it interpolated nothing, leaving an empty\n    // gap where the record's name belongs). getConfirmOptions composes the sentence and names the record. No\n    // identityField is passed: a details dialog has no columns, so there is no declared identity to resolve —\n    // getRecordName probes this.details directly.\n    const c = this.buttonService.getConfirmOptions(button, this.details, undefined, this.dataService.namedDestructiveActions);\n\n    // Changed (N22): forwards c.requirePhrase, unwraps both close shapes, and hands the typed phrase on — this\n    // prompt is upstream of executeAction, so without passing it the text the user typed would be dropped here.\n    this.messageService.confirm(c.message, c.confirmLabel, c.cancelLabel, c.destructive, c.requirePhrase).subscribe((result) => {\n      if (this.buttonService.confirmAccepted(result)) {\n        this.handleButtonAction('delete', this.buttonService.confirmPhrase(result));\n      }\n    });\n  }\n\n\n  custom(button: Button ) {\n    if (button.dialog && button.detailsConfig) {\n      this.openNestedDetailsDialog(button);\n    } else {\n      this.handleButtonAction(button.name);\n    }\n  }\n\n  private openNestedDetailsDialog(button: Button): void {\n    // Changed: Use token pattern instead of direct DetailsDialog import, propagate nestingLevel\n    this.dialogService.openDefaultDetailsDialog(button, this.details, this.nestingLevel).subscribe(result => {\n\n      if (!result) return; // Added: same dismissal guard as table.component — Escape/backdrop closes a nested dialog with undefined, and a dismissal must not set actionPerformed or refresh\n      if (result.action === 'inputChange') {\n        this.inputChanged(result.change);\n      } else if (result && result.message === 'success') {\n        this.actionPerformed = true; // Changed: nested dialog completed an action — flag for refreshOnCloseIfActioned\n        this.refreshData();\n      }\n\n    });\n  }\n\n  private refreshData(): void {\n    if (this.formConfig.loadAction) {\n      this.loadData(this.formConfig.loadAction, true);\n    }\n  }\n\n  handleButtonAction(buttonName: string, phrase?: string) { // Changed (N22): optional phrase — delete() confirms before calling here, so the text it collected has to be carried on rather than re-collected\n\n    const button = this.getButton(buttonName);\n    if (!button) return;\n\n\n    if (button.onClick) {\n      button.onClick(this.details);\n    }\n\n    this.processButtonAction(button, phrase);\n  }\n\n  // Added: returns the effective keepOpen value — user checkbox takes precedence when allowUserKeepOpen is enabled\n  private effectiveKeepOpen(button: Button): boolean {\n    if (this.detailsConfig.allowUserKeepOpen) return this.userKeepOpen;\n    return button.keepOpen ?? false;\n  }\n\n  // Added: the acting footer button's own name, for the close payload — but ONLY when it asked for it.\n  // table.component.open() otherwise emits every close under the name of the button that OPENED the dialog, which\n  // makes an `inDialog` button invisible to the host. Returning {} rather than a null name keeps this purely\n  // additive: with no opt-in the payload is byte-identical to what it has always been, so `result.name || buttonName`\n  // at the other end falls straight through to the old behaviour. See Button.emitOwnName for why it is not a default.\n  private ownName(button: Button): { name?: string } {\n    return button?.emitOwnName && button.name ? { name: button.name } : {};\n  }\n\n  processButtonAction(button : Button, phrase?: string) { // Changed (N22): optional phrase, forwarded to executeAction\n    // Added: local mode (one-step create) — validate as usual but return the row to the host table instead of POSTing;\n    // the rows only reach the backend when the parent entity is submitted with them as its navigation property\n    if (this.detailsConfig.localMode) {\n      if (button.name === 'delete') {\n        this.dialogRef.close({ message: 'localDelete' });\n        return;\n      }\n      if (button.name === 'create' || button.name === 'edit') {\n        if (button.skipValidation || this.validateForm()) {\n          this.dialogRef.close({ message: 'success', data: { data: this.details }, ...this.ownName(button) });\n        }\n        return;\n      }\n    }\n\n    if (!button.action) {\n      if (!this.effectiveKeepOpen(button)) { // Changed: use effectiveKeepOpen to respect user checkbox\n        this.dialogRef.close({ message: 'emit', data: this.details, ...this.ownName(button) });\n      }\n      return;\n    }\n\n    if (button.skipValidation || this.validateForm()) {\n      // Changed (C60): was this.details. A value entered while a field was VISIBLE was still posted, and\n      // persisted, once a predicate hid the field — runtime-proven on THIS path (pulse-spa Quick Sale saved a\n      // Deferred sale holding PaymentMethod = Cash and a payment reference the operator could not see).\n      // buildSubmitPayload returns a COPY with predicate-hidden keys omitted; this.details stays intact, so the\n      // dialog keeps its state and re-showing a field restores the typed value. Full rationale on the helper.\n      this.executeAction(button, Core.buildSubmitPayload(this.formConfig, this.details), phrase); // Changed (N22): carry the phrase through\n    }\n  }\n\n  private validateForm(): boolean {\n    let validationResult = Core.validateObject(this.getVisibleFields(), this.details, field => this.revealSection(field)); // Changed: open the offending field's section — collapsed groups must never hide what the toast is complaining about\n    if (validationResult !== '') {\n      this.messageService.toast(validationResult);\n      return false;\n    }\n\n    if (this.files.length < 1 && this.fileField?.required && this.formConfig.mode === 'create') {\n      this.messageService.toast(\"Please attach file(s)\");\n      return false;\n    }\n\n    // Validate composite fields\n    for (const field of this.getVisibleFields()) {\n      if (field.type === 'composite') {\n        validationResult = Core.validateObject(Core.getVisibleSubfields(this.formConfig, this.details, field, this.authService.currentRoleSource.value), this.details, );\n        if (validationResult !== '') {\n          this.messageService.toast(validationResult);\n          return false;\n        }\n      }\n    }\n\n    return true;\n  }\n\n  private prepareActionData(button: Button, data: any): any {\n    if (this.buttonService.isFormButton(button)) {\n      const formData = new FormData();\n      for (let i = 0; i < this.files.length; i++) {\n        formData.append(`uploadFile${i}`, this.files[i], this.files[i].name);\n      }\n      formData.append(\"data\", JSON.stringify(data));\n      return formData;\n    }\n    return data;\n  }\n\n  private executeAction(button: Button, data: any, phrase?: string) {\n    // Changed (N22): the payload is now built LAZILY, because a typed phrase is only known once the dialog has\n    // closed — it has to be folded in BEFORE prepareActionData, or a form button's FormData would carry a\n    // `data` blob with no phrase in it and the server would refuse the write. Merged onto a COPY so `this.details`\n    // never acquires a stray `phrase` key.\n    const buildPayload = (typed?: string) => this.prepareActionData(button, typed !== undefined ? { ...data, phrase: typed } : data);\n\n    if (button.confirm) {\n      // Changed: routed through the shared resolver.\n      // Changed: the `fallback` local is gone. It held the SAME broken literal as the other two call sites — the\n      // name-shaped `button.name == 'delete'` guard disguised that, but it produced the identical \"delete ?\" gap\n      // on this surface. getConfirmOptions now composes the sentence for every recognised destructive name, so\n      // 'remove' gains a real sentence here too instead of the EMPTY dialog body an empty confirm used to give it.\n      const c = this.buttonService.getConfirmOptions(button, this.details, undefined, this.dataService.namedDestructiveActions);\n\n      // Changed (N22): forwards c.requirePhrase and unwraps both close shapes. The phrase collected HERE wins over\n      // one handed in by a caller that already confirmed — this dialog is the more recent statement of intent.\n      this.messageService.confirm(c.message, c.confirmLabel, c.cancelLabel, c.destructive, c.requirePhrase).subscribe((result) => {\n        if (this.buttonService.confirmAccepted(result)) {\n          this.performApiCall(button, buildPayload(this.buttonService.confirmPhrase(result) ?? phrase));\n        }\n      });\n\n    } else {\n      this.performApiCall(button, buildPayload(phrase));\n    }\n\n  }\n\n  private performApiCall(button: Button, data: any) {\n    this.dataService.CallApi(button.action, data).subscribe((apiResponse: ApiResponse) => {\n\n      if (apiResponse.data){\n        this.details = apiResponse.data;\n      }\n\n      if (apiResponse.success) {\n\n        // Added: optimistic-concurrency — adopt the refreshed token so a dialog left open can save again without a stale-write false conflict\n        if (apiResponse.rowVersion && this.details) this.details.rowVersion = apiResponse.rowVersion;\n\n        this.actionPerformed = true; // Changed: a dialog button completed a successful POST — flag for refreshOnCloseIfActioned (matters when keepOpen keeps the dialog alive)\n\n        if (apiResponse.message.includes(\"approval\") || apiResponse.message.includes(\"approve\") || apiResponse.message.includes(\"decline\")) {\n          this.messageService.toast(apiResponse.message);\n        } else if (button.action.successMessage) {\n          this.messageService.toast(button.action.successMessage);\n        } else if (apiResponse.message != \"success\" && apiResponse.message != \"\") {\n          this.messageService.toast(apiResponse.message);\n        } else {\n          this.messageService.toast(\"Updated\");\n        }\n\n        if (button.onSuccess) {\n          button.onSuccess(apiResponse.data, this.details);\n        }\n\n        if (this.effectiveKeepOpen(button)) { // Changed: use effectiveKeepOpen to respect user checkbox\n          if (button.resetMode) {\n            // Changed: Reset values in-place to preserve loaded select options\n            Core.resetObject(this.formConfig.fields, this.details);\n            this.formConfig.mode = button.resetMode;\n            this.loadByAction = false;\n            this.isLoadComplete = true;\n            this.setTitleAction();\n          } else if (button.name === 'create' && this.detailsConfig.allowUserKeepOpen && this.userKeepOpen && this.detailsConfig.keepOpenBehavior === 'reset') {\n            // Changed: Reset values in-place to preserve loaded select options for next capture\n            Core.resetObject(this.formConfig.fields, this.details);\n          } else if (button.name === 'create' && apiResponse.data) {\n            this.details = apiResponse.data;\n\n            if (this.detailsConfig.heroField && apiResponse.data[this.detailsConfig.heroField]) {\n              this.detailsConfig.heroValue = apiResponse.data[this.detailsConfig.heroField];\n              this.formConfig.heroField = this.detailsConfig.heroField;\n              this.formConfig.heroValue = this.detailsConfig.heroValue;\n            }\n\n            // Changed: Re-transform tableConfigs URLs with new details after keepOpen create\n            if (this.tableConfigs) {\n              this.tableConfigs.forEach(tc => {\n                if (tc.loadAction && tc.loadCriteria && tc.loadIDField) {\n                  const idValue = this.details?.[tc.loadIDField];\n                  tc.loadAction.url = `${tc.loadAction.url.split('/')[0]}/${tc.loadCriteria}/${idValue ?? 'x'}`;\n                }\n              });\n              this.tableReload.next(true); // Changed: Trigger nested table reload with resolved URLs\n            }\n\n            // Changed: Set loadAction from initAction for future refreshes\n            if (this.detailsConfig.initAction) {\n              this.formConfig.loadAction = this.detailsConfig.initAction;\n              this.loadByAction = true;\n            }\n\n            this.formConfig.mode = 'edit';\n            this.setTitleAction();\n            this.isLoadComplete = true;\n\n          } else {\n            this.refreshData();\n          }\n          this.rebuildButtonVMs(); // TS-16: dialog stays open with updated details/mode — recompute button VMs\n        }else{\n          this.dialogRef.close({ message: 'success', data: { ...apiResponse, data: button.name == 'create' ? apiResponse.data : this.details  }, ...this.ownName(button) });\n        }\n        \n      } else if (apiResponse.reason === 'conflict') {\n        // Added: optimistic-concurrency (IConcurrency) — server refused a stale write; the fresh server row (with new rowVersion) was already loaded into this.details above, so the user reviews and re-applies their changes\n        this.messageService.toast(`${apiResponse.message} — the latest version has been loaded, please review and re-apply your changes`);\n        this.rebuildButtonVMs(); // Added: details replaced with the fresh server row — recompute button state\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'submit', button.action?.url); // Changed: THE create/edit submit — dialog stays open with the form populated, so a missed toast is what turns one failure into a duplicate record\n      }\n    });\n  }\n\n  getClosePosition(): 'top' | 'bottom' {\n    return this.detailsConfig.closeOptions?.position || 'bottom';\n  }\n\n  getCloseText(): string {\n    return this.detailsConfig.closeOptions?.text || 'Cancel';\n  }\n\n  shouldShowTopClose(): boolean {\n    return this.getClosePosition() === 'top';\n  }\n\n  shouldShowBottomClose(): boolean {\n    return this.getClosePosition() === 'bottom';\n  }\n\n  close(){\n    // Changed: dropped the `refreshOnCloseIfActioned &&` opt-in gate — actionPerformed alone now decides. That flag was\n    // declared (Classes.ts:53), maintained on all three write paths (footer POST under keepOpen :795, nested-tab table\n    // action via spa-tabs (actionSuccess), nested capture dialog :662) and then set by NO config in the library or in any\n    // app — grep for it across Angular\\ returns only its own declaration and these consumers. So this branch was dead and\n    // every such dialog closed 'emit', leaving the parent grid rendering the pre-action row. Measured 2026-08-14: a fixed\n    // asset disposed through the capture dialog still read \"Active\" in the grid until a manual page reload. Disposal is\n    // IRREVERSIBLE (writes off accumulated depreciation, posts a gain/loss journal and a sale transaction, with no\n    // un-dispose action), so a row that still says \"Active\" invites a second disposal — the write succeeded and the screen\n    // said otherwise. Same rule as realtime-refresh-fallback.spec.ts: a write that succeeds must always leave the grid\n    // showing what the server now holds. Safe because actionPerformed is set ONLY inside `if (apiResponse.success)`, so a\n    // pure view-then-close still takes the refresh-free 'emit' branch, and because non-keepOpen footer buttons close at\n    // :857 without ever reaching close() — the neighbouring one-shot actions are untouched by this.\n    // refreshOnClose (unconditional) and refreshOnCloseIfActioned (now implied) both still type-check for any external\n    // consumer that sets them; the latter is redundant rather than removed, to avoid touching the hot Classes.ts.\n    if (this.detailsConfig.refreshOnClose || this.actionPerformed){\n      this.dialogRef.close({ message: 'success', data: this.details });\n    }else{\n      this.dialogRef.close({ message: 'emit', data: this.details });\n    }\n  }\n\n};\n","<!-- Changed: dialog-has-tables mirrors the service's hasTables (tableConfigs?.length)\n     which decides height '90%' vs 'auto' — used to scope scroll behaviour per case -->\n<div class=\"dialog-container\" [class.dialog-has-tables]=\"detailsConfig.tableConfigs?.length > 0\">\n\n  <div class=\"dialog-content\">\n\n    <!-- Changed: was <mat-progress-bar mode=\"indeterminate\">, which looped at a constant speed forever and so\n         only ever said \"busy\". This is the same markup and the same PerceivedProgress curve the table stage\n         uses, so a dialog and the table behind it move identically. It tracks the FORM's record load — nested\n         tab tables run their own stages. Controlled by appConfig.quietLoading. -->\n    <div *ngIf=\"showProgressLine\" class=\"tin-load-line\" aria-hidden=\"true\">\n      <span class=\"tin-load-line-fill\" [style.width.%]=\"progressPercent\"></span>\n    </div>\n\n    <!-- Changed: the header's padding and the title's type were inline styles, which always beat a class and so\n         made a second presentation impossible. Moved into dlg-header-classic / dlg-title-classic, which restate\n         those exact values, so the default look is unchanged while `modern` can swap in the banded header. -->\n    <div class=\"d-flex justify-content-between align-items-center dialog-header\"\n         [class.mt-2]=\"!modern\" [class.dlg-header-classic]=\"!modern\" [class.tin-dlg-head]=\"modern\">\n\n      <div class=\"dialog-header-titles\">\n        <label [class.dlg-title-classic]=\"!modern\" [class.tin-dlg-title]=\"modern\"><ng-container *ngIf=\"titleAction\">{{titleAction | titlecase}} </ng-container>{{formConfig?.title}}</label><!-- Changed: the action word and its separating space are emitted together, so a suppressed prefix (a title that already opens with the action — see setTitleAction) leaves no stray leading space in the heading -->\n      </div>\n\n      <div class=\"d-flex align-items-center\" style=\"gap: 8px;\">\n\n        <!-- Changed: Auto Refresh icon button — grey when off, green when on, with dynamic tooltip -->\n        <button *ngIf=\"detailsConfig.autoRefreshConfig\" mat-icon-button\n          [matTooltip]=\"autoRefreshEnabled ? 'Click to disable auto refresh' : 'Click to enable auto refresh'\" matTooltipPosition=\"above\"\n          [style.color]=\"autoRefreshEnabled ? '#4caf50' : '#9e9e9e'\"\n          (click)=\"autoRefreshEnabled = !autoRefreshEnabled; toggleAutoRefresh()\">\n          <mat-icon>autorenew</mat-icon>\n        </button>\n        <!-- Changed: Keep Open icon button — grey when off, green when on, with dynamic tooltip -->\n        <button *ngIf=\"detailsConfig.allowUserKeepOpen\" mat-icon-button\n          [matTooltip]=\"userKeepOpen ? 'Click to disable keep open' : 'Click to enable keep open'\" matTooltipPosition=\"above\"\n          [style.color]=\"userKeepOpen ? '#4caf50' : '#9e9e9e'\"\n          (click)=\"userKeepOpen = !userKeepOpen\">\n          <mat-icon>push_pin</mat-icon>\n        </button>\n\n        <!-- TS-16: bind precomputed editButtonVM instead of testVisible/testDisabled (which cloned objects) per CD -->\n        <div *ngIf=\"formConfig.mode=='view' && editButton && editButtonVM.visible\">\n          <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Edit\" color=\"primary\" (click)=\"setMode('edit')\" [disabled]=\"editButtonVM.disabled\"><mat-icon>edit</mat-icon></button>\n        </div>\n\n        <!-- Changed (Quiet Loading): every [disabled] below now ORs in entityLoading. A quiet read is silent, so it\n             never flips LoaderService.isLoading and isProcessing alone would leave these buttons live during the\n             load — a user could submit an empty form. With the flag off entityLoading simply tracks the same\n             window isProcessing already covered, so nothing changes. -->\n        <!-- Changed: the icon now spins while the form's record reloads, matching the table's refresh button.\n             Same .tin-spin class, so the two surfaces use one idiom rather than each inventing its own. -->\n        <button [disabled]=\"isProcessing || entityLoading\" *ngIf=\"loadByAction\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Refresh\" color=\"primary\" (click)=\"loadData(formConfig.loadAction, detailsConfig.causeTableRefresh)\"><mat-icon class=\"refreshIcon\" [class.tin-spin]=\"entityLoading\">cached</mat-icon></button>\n        \n        <!-- Added: Top close button when position is 'top' -->\n        <button *ngIf=\"shouldShowTopClose()\" [disabled]=\"isProcessing || entityLoading\" mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Close\" (click)=\"close()\"><mat-icon>close</mat-icon></button>\n\n      </div>\n\n    </div>\n\n    <div style=\"padding-left: 24px; padding-right: 24px;\">\n      <spa-steps *ngIf=\"stepConfig && details && stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\n      <spa-statuses *ngIf=\"statusConfig && details && statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\n      <spa-alert *ngIf=\"formConfig.alertConfig && formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\n    </div>\n\n    <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\n\n      <spa-steps *ngIf=\"stepConfig && details && !stepConfig.sticky\" [config]=\"stepConfig\" [data]=\"details\"></spa-steps>\n      <spa-statuses *ngIf=\"statusConfig && details && !statusConfig?.sticky\" [config]=\"statusConfig\" [data]=\"details\"></spa-statuses>\n      <spa-alert *ngIf=\"formConfig.alertConfig && !formConfig.alertConfig?.sticky\" [config]=\"formConfig.alertConfig\" [data]=\"details\"></spa-alert>\n\n      <div class=\"tin-input\" style=\"font-size:14px\">\n\n        <!-- Changed (Quiet Loading, FSD D6): with the flag OFF this is the original bare \"Loading...\" line, unchanged.\n             With it ON the text is replaced by a skeleton of the real form — and only once showSkeleton has been\n             armed past the 150ms anti-flicker delay, so a cached record renders straight into the form with no flash. -->\n        <p *ngIf=\"formConfig && !details && !effQuietLoading\"><em>Loading...</em></p>\n\n        <spa-form-skeleton *ngIf=\"formConfig && !details && effQuietLoading && showSkeleton\" [config]=\"formConfig\"></spa-form-skeleton>\n\n        <spa-form *ngIf=\"formConfig && details\" [files]=\"files\" [data]=\"details\" [config]=\"formConfig\" (inputChange)=\"inputChanged($event)\">\n          <ng-template #dynamicSelect let-field=\"field\" let-data=\"data\" let-testReadOnly=\"testReadOnly\" let-testRequired=\"testRequired\" let-selectChanged=\"selectChanged\" let-resolveLoadAction=\"resolveLoadAction\">\n            <spa-select\n              [display]=\"field.alias ?? field.name | camelToWords\"\n              [width]=\"field.width\"\n              [nullable]=\"field.nullable\"\n              [options]=\"field.options\"\n              [masterOptions]=\"field.masterOptions\"\n              [masterField]=\"field.masterField\"\n              [optionDisplay]=\"field.optionDisplay ?? 'name'\"\n              [optionValue]=\"field.optionValue ?? 'value'\"\n              [(value)]=\"data[field.name]\"\n              [defaultFirstValue]=\"field.defaultFirstValue\"\n              [required]=\"testRequired(field)\"\n              [readonly]=\"testReadOnly(field)\"\n              [hint]=\"field.hint\"\n              [detailsConfig]=\"field.detailsConfig\"\n              [loadAction]=\"resolveLoadAction ? resolveLoadAction(field) : field.loadAction\"\n              [loadIDField]=\"field.loadIDField\"\n              [field]=\"field\"\n              [data]=\"data\"\n              [infoMessage]=\"field.infoMessage\"\n              [copyContent]=\"field.copyContent\"\n              (valueChange)=\"selectChanged(field)\"\n            ></spa-select>\n          </ng-template>\n        </spa-form>\n\n        <!-- Changed: Use unified spa-tabs with nestingLevel control — tabs hidden when nestingLevel >= 2 -->\n        <!-- Changed: the same condition moved onto a wrapping ng-container (it is byte-identical, and spa-tabs\n             renders exactly when it did before). It has to wrap rather than sit on spa-tabs because a template\n             reference variable declared inside an *ngIf view is not visible to siblings outside it, and\n             spa-tabs-float reads titles, counts and selection off the live spa-tabs instance. -->\n        <ng-container *ngIf=\"showTabs && tableConfigs && !(detailsConfig.hideTablesInCreateMode && formConfig?.mode === 'create')\">\n\n        <spa-tabs #tabsRef\n          [tableConfigs]=\"tableConfigs\"\n          [reload]=\"tableReload\"\n          [parentDetails]=\"details\"\n          [localMode]=\"formConfig?.mode === 'create'\"\n          [nestingLevel]=\"nestingLevel + 1\"\n          (formRefresh)=\"loadData(formConfig.loadAction, false)\"\n          (actionSuccess)=\"actionPerformed = true\">\n        </spa-tabs><!-- Changed: nested-tab table actions flag actionPerformed so refreshOnCloseIfActioned refreshes the parent on close -->\n\n        <!-- Added (owner, 2026-08-20): floating tab-TITLE strip. Must be the LAST child of .tin-input — it is a\n             zero-height sticky anchor, so it needs a container that spans the whole scrolled content, and .tin-input\n             is that container. It shows ONLY while the real strip above is scrolled out of view, so a dialog whose\n             tabs are already visible is untouched. detailsConfig.disableFloatingTabs opts a dialog out entirely. -->\n        <spa-tabs-float *ngIf=\"!detailsConfig.disableFloatingTabs\" [tabs]=\"tabsRef\"></spa-tabs-float>\n\n        </ng-container>\n\n      </div>\n\n    </mat-dialog-content>\n\n\n  </div>\n\n  <mat-dialog-actions >\n\n    <div>\n\n      <button mat-raised-button [disabled]=\"isProcessing || entityLoading\" *ngIf=\"formConfig.mode=='create' && createButton\" color=\"primary\"\n        (click)=\"create()\" cdkFocusInitial>{{createButton.display ?? 'Submit'}}\n      </button>\n\n      <button mat-raised-button [disabled]=\"isProcessing || entityLoading\" *ngIf=\"formConfig.mode=='edit' && editButton\" color=\"primary\"\n        (click)=\"edit()\" cdkFocusInitial>{{editButton.display ?? 'Submit'}}\n      </button>\n\n      <!-- TS-16: bind precomputed extraButtonVMs instead of testVisible/testDisabled/getButtonColor (each cloning objects) per CD -->\n      <ng-container *ngFor=\"let vm of extraButtonVMs\">\n        <button *ngIf=\"formConfig.mode !== 'create' && vm.visible\" mat-stroked-button [disabled]=\"isProcessing || entityLoading || vm.disabled\" [ngStyle]=\"{'color': vm.color}\" (click)=\"custom(vm.button)\" cdkFocusInitial>\n          <mat-icon *ngIf=\"vm.button.icon\" [ngStyle]=\"{'color': vm.color}\">{{vm.button.icon.name}}</mat-icon>\n          {{vm.button.display ?? (vm.button.name | titlecase)}}\n        </button>\n      </ng-container>\n\n      <!-- Changed: Bottom close button now uses conditional display and custom text -->\n      <button *ngIf=\"shouldShowBottomClose()\" mat-stroked-button color=\"primary\" (click)=\"close()\">{{getCloseText()}}</button>\n\n    </div>\n\n    <div class=\"col d-flex justify-content-end\" *ngIf=\"smallScreen\">\n      <button mat-icon-button matTooltipPosition=\"above\" matTooltip=\"Delete\" [disabled]=\"isProcessing || entityLoading\" style=\"color: red;\" (click)=\"delete()\" *ngIf=\"formConfig.mode!='create'  && deleteButton\"><mat-icon>delete</mat-icon></button>\n    </div>\n\n\n  </mat-dialog-actions>\n\n\n</div>\n\n\n\n\n\n\n","// Config surface for the spa-map component and the full-bleed map dialog.\n// Deliberately declared in its own file rather than appended to Classes.ts: Classes.ts is a very hot\n// shared file (it was locked by another worker when this landed), and a self-contained config class\n// keeps the map feature reviewable in one place.\n\nexport class MapConfig {\n  // The position to show. Accepts the raw \"lat,lng\" string a database column would hold — that is the\n  // shape Shift's existing call sites already pass — or a literal. Null/blank/unparseable renders the\n  // designed empty state rather than a misleading default position.\n  position?: string | MapPoint | null;\n\n  title?: string;              // primary identity of the thing being located, e.g. the vehicle name\n  subtitle?: string;           // secondary identity, e.g. the registration number\n  caption?: string;            // small freeform line under the identity, e.g. \"Last seen 12:04\"\n\n  zoom?: number;               // default 15 — street level, close enough to recognise where the vehicle is\n  mapTypeId?: MapTypeId;       // default 'roadmap'. 'satellite'/'hybrid' select imageryTileUrl if one is set\n  showCoordinates?: boolean;   // default true — the monospace lat/lng readout in the identity panel\n  showMapTypeToggle?: boolean; // default true, but the toggle only APPEARS when imageryTileUrl is supplied\n  interactive?: boolean;       // default true — false gives a static, non-draggable preview\n\n  // Changed 2026-08-19: the base layer is now OpenStreetMap via Leaflet — free, keyless, no account.\n  // Override only to point at a mirror or a self-hosted renderer; leave blank for standard OSM.\n  tileUrl?: string;\n  // The attribution shown on the map. OSM's is a LICENCE CONDITION, not decoration — if you override\n  // tileUrl you must supply the matching attribution. See map.component.ts for the defaults.\n  attribution?: string;\n\n  // Optional satellite/aerial layer for the map-type toggle. tin-spa deliberately ships NO imagery\n  // provider of its own (Arbiter ruling, 2026-08-19): OSM has no satellite tiles, and every keyless\n  // imagery endpoint carries licence terms this shared library must not accept on four apps' behalf.\n  // A consumer that has licensed imagery supplies the URL template here and the toggle appears.\n  // Example of a licence-clean (though topographic, not satellite) layer, for reference only —\n  // NOT a default: 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', attribution '© OpenTopoMap (CC-BY-SA)'.\n  imageryTileUrl?: string;\n  imageryAttribution?: string;\n\n  // DEPRECATED and ignored since the switch to Leaflet + OpenStreetMap on 2026-08-19. Kept on the type\n  // so existing callers that still pass it keep compiling; no key is needed and none is ever requested.\n  apiKey?: string;\n\n  emptyMessage?: string;       // default \"No location recorded\"\n  emptyDetail?: string;        // optional second line explaining what to do about it\n\n  height?: string;             // inline (non-dialog) use only, e.g. '360px'. The dialog always fills.\n\n  // Added 2026-08-19 (GPS phase 4): the FLEET surface. Additive — `position` above is untouched and a\n  // config that sets only `position` behaves exactly as before. When `markers` is a non-empty array the\n  // component draws one beacon per marker, keyed by `id`, and `position` is ignored.\n  markers?: MapMarker[];\n  // Fit the viewport to every marker on first draw instead of centring on one at `zoom`. Default true\n  // when markers are supplied — a fleet map whose first frame shows one vehicle is not a fleet map.\n  fitMarkers?: boolean;\n  // Shown in place of the single-vehicle identity panel when nothing is selected, e.g. \"Fleet\".\n  fleetTitle?: string;\n}\n\n// One locatable thing on the map. Deliberately carries NO renderer type: `position` is the same\n// \"lat,lng\" string or {lat,lng} literal `position` accepts, so nothing above this type knows the map is\n// Leaflet. Adding a provider type here is what would force the next engine switch to redo this phase.\nexport interface MapMarker {\n  // Stable identity. Position updates find their marker by this, which is what lets a beacon MOVE\n  // instead of the map being redrawn. For Shift this is the vehicleID.\n  id: string | number;\n  position: string | MapPoint | null | undefined;\n\n  title?: string;              // primary identity, e.g. the vehicle name\n  subtitle?: string;           // secondary identity, e.g. the registration number\n  caption?: string;            // small line, e.g. \"Last seen 12:04\"\n\n  heading?: number | null;     // degrees 0-359; drives the direction wedge when supplied\n  speed?: number | null;       // whatever unit the consumer reports in — shown verbatim with `speedUnit`\n  speedUnit?: string;          // default 'km/h'\n  at?: string | Date | null;   // the instant of the fix, used for the stale treatment\n\n  // Draws the beacon in the muted \"not reporting\" treatment rather than the live green. The consumer\n  // decides what stale means — the library will not invent a threshold on its behalf.\n  stale?: boolean;\n}\n\n// A single position update. This is the provider-agnostic shape a live feed pushes in; the SignalR\n// `VehiclePosition` frame maps onto it field for field, but nothing here depends on SignalR existing.\nexport interface MapPositionUpdate {\n  id: string | number;\n  position?: string | MapPoint | null;\n  lat?: number | null;\n  lng?: number | null;\n  at?: string | Date | null;\n  speed?: number | null;\n  heading?: number | null;\n}\n\n// A marker that has been proved locatable, paired with its parsed point. Returned by normaliseMarkers.\nexport interface ResolvedMapMarker {\n  marker: MapMarker;\n  point: MapPoint;\n  key: string;\n}\n\n// Turns the raw marker array into the subset the map can actually draw. One bad coordinate drops ONE\n// marker and never the map — the fleet screen's whole job is showing the vehicles that ARE reporting.\n// Markers with no id, or with a duplicate id, are dropped too: identity is what position updates address,\n// so an ambiguous id would move the wrong beacon, which is worse than showing no beacon.\nexport function normaliseMarkers(markers: MapMarker[] | null | undefined): ResolvedMapMarker[] {\n  if (!markers || !markers.length) return [];\n\n  const seen = new Set<string>();\n  const out: ResolvedMapMarker[] = [];\n\n  for (const marker of markers) {\n    if (!marker) continue;\n    const key = markerKey(marker.id);\n    if (key === null || seen.has(key)) continue;\n\n    const point = parseMapPoint(marker.position);\n    if (!point) continue;\n\n    seen.add(key);\n    out.push({ marker, point, key });\n  }\n\n  return out;\n}\n\n// The identity string a marker is tracked by. Numeric 7 and string '7' are the SAME vehicle — a list row\n// carries the number and a SignalR frame may carry either, and two beacons for one vehicle is the defect\n// this normalisation exists to prevent. Null/blank/NaN ids are not identities and are rejected.\nexport function markerKey(id: string | number | null | undefined): string | null {\n  if (id === null || id === undefined) return null;\n  if (typeof id === 'number') return isFinite(id) ? String(id) : null;\n  const trimmed = String(id).trim();\n  return trimmed === '' ? null : trimmed;\n}\n\n// The point carried by a position update, in whichever of the two shapes the feed sent it.\nexport function updatePoint(update: MapPositionUpdate | null | undefined): MapPoint | null {\n  if (!update) return null;\n  if (update.position !== undefined && update.position !== null) return parseMapPoint(update.position);\n  if (update.lat === null || update.lat === undefined || update.lng === null || update.lng === undefined) return null;\n  return parseMapPoint({ lat: Number(update.lat), lng: Number(update.lng) });\n}\n\nexport interface MapPoint {\n  lat: number;\n  lng: number;\n}\n\n// Kept verbatim across the Google -> Leaflet switch. Leaflet has no notion of map \"types\", but removing\n// an exported type from public-api is a breaking change to consumers outside this workspace that we\n// cannot see (Arbiter condition, 2026-08-19). 'satellite'/'hybrid' select the imagery layer when one is\n// configured; everything else, including 'terrain', renders the OSM base layer.\nexport type MapTypeId = 'roadmap' | 'satellite' | 'hybrid' | 'terrain';\n\n// Parses the \"lat,lng\" string shape a database value would carry. Returns null for anything it cannot\n// trust — blank, malformed, non-numeric, or out of range — so callers can show the empty state instead\n// of dropping a confident marker on a wrong or default position.\nexport function parseMapPoint(value: string | MapPoint | null | undefined): MapPoint | null {\n  if (value == null) return null;\n\n  if (typeof value !== 'string') {\n    const lat = Number(value.lat), lng = Number(value.lng);\n    return isValidPoint(lat, lng) ? { lat, lng } : null;\n  }\n\n  const parts = value.split(',');\n  if (parts.length !== 2) return null;\n\n  const lat = Number(parts[0].trim());\n  const lng = Number(parts[1].trim());\n  if (parts[0].trim() === '' || parts[1].trim() === '') return null;\n\n  return isValidPoint(lat, lng) ? { lat, lng } : null;\n}\n\nfunction isValidPoint(lat: number, lng: number): boolean {\n  if (!isFinite(lat) || !isFinite(lng)) return false;\n  if (lat < -90 || lat > 90) return false;\n  if (lng < -180 || lng > 180) return false;\n  return true;\n}\n\n// Formats a point for the readout. Six decimals is ~11cm — more than enough for a vehicle, and it stops\n// the raw 15-decimal database values from overflowing the panel.\nexport function formatMapPoint(point: MapPoint | null): string {\n  if (!point) return '';\n  return `${point.lat.toFixed(6)}, ${point.lng.toFixed(6)}`;\n}\n","// spa-map — a config-driven map surface built to be looked AT, not framed.\n//\n// Design intent (owner directive 2026-08-18): the map is the whole surface. Every affordance floats on\n// top of it as thin glass rather than stealing a band of height from it. The vehicle's position is the\n// one thing that must be unmissable, so it gets an animated beacon rather than a default pin.\n//\n// ENGINE (owner directive 2026-08-19, option \"A\"): Leaflet + OpenStreetMap. Free, keyless, no account,\n// no billing, no <script> tag. Leaflet is a real npm dependency, bundled — nothing is loaded from a CDN.\n// Only the map TILES are fetched at runtime, from OpenStreetMap's tile servers.\n//\n// 🔴 ATTRIBUTION IS A LICENCE CONDITION, NOT A NICETY. OSM tiles are ODbL; displaying them obliges us to\n// credit OpenStreetMap visibly on the map. Leaflet's attribution control carries it, it is styled to\n// match the glass chrome rather than hidden, and the controls stack is offset to clear it. Do not remove\n// it, do not make it conditional, and if you override tileUrl you must supply the matching attribution.\n//\n// Provider-agnostic by design: the component owns a single \"current point\" and exposes setPosition() to\n// move it without rebuilding the map. A live vehicle feed attaches there. Nothing above that method\n// knows or cares that the renderer is Leaflet.\n\nimport { Component, ElementRef, EventEmitter, Input, NgZone, OnChanges, OnDestroy, Output, SimpleChanges, ViewChild } from '@angular/core';\nimport * as L from 'leaflet';\nimport { Observable, Subscription } from 'rxjs';\nimport { MapConfig, MapMarker, MapPoint, MapPositionUpdate, MapTypeId, ResolvedMapMarker, formatMapPoint, markerKey, normaliseMarkers, parseMapPoint, updatePoint } from '../../classes/MapClasses';\n\ndeclare const window: any;\n\ntype MapState = 'loading' | 'ready' | 'empty' | 'unavailable';\n\n// Standard OpenStreetMap raster tiles. Keyless and free, subject to OSM's tile usage policy — which\n// normal Leaflet behaviour satisfies: attribution shown, one map at a time, no bulk downloading, and\n// maxZoom capped at 19 because OSM serves no tiles above that and requesting them just yields 404s.\nconst OSM_TILE_URL = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';\nconst OSM_ATTRIBUTION = '&copy; <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\" rel=\"noopener\">OpenStreetMap</a> contributors';\nconst OSM_MAX_ZOOM = 19;\n\n@Component({\n  selector: 'spa-map',\n  templateUrl: './map.component.html',\n  styleUrls: ['./map.component.css'],\n  standalone: false\n})\nexport class MapComponent implements OnChanges, OnDestroy {\n\n  @Input() config: MapConfig = new MapConfig();\n\n  // Added (GPS phase 4): the live feed seam. Any stream of position updates drives the markers — the\n  // component subscribes to it, nothing more. It is an Observable of a PLAIN shape, so a SignalR frame,\n  // a poll result and a test's Subject are all equally valid drivers and none of them is a dependency.\n  @Input() positionStream: Observable<MapPositionUpdate> | null = null;\n  // Pan to keep a moving marker in view. Only ever follows the SELECTED marker — a fleet map that chases\n  // whichever vehicle reported last is unusable.\n  @Input() followSelected = false;\n\n  @Output() closed = new EventEmitter<void>();\n  // Emits the marker the user picked, or null when the selection is cleared. Carries the CONSUMER'S own\n  // MapMarker back, never a renderer object.\n  @Output() markerSelected = new EventEmitter<MapMarker | null>();\n  // Emits after a live update has actually moved a beacon. Consumers use it for \"last update\" chrome.\n  @Output() markerMoved = new EventEmitter<MapMarker>();\n\n  @ViewChild('surface', { static: true }) surface: ElementRef<HTMLDivElement>;\n  @ViewChild('beacon', { static: true }) beacon: ElementRef<HTMLDivElement>;\n\n  state: MapState = 'loading';\n  point: MapPoint | null = null;\n  coordinates = '';\n  mapType: MapTypeId = 'roadmap';\n  // Set when the map has been panned away from the vehicle, which is what makes \"Recenter\" meaningful\n  // rather than permanently-lit chrome.\n  offCentre = false;\n\n  // FLEET MODE — set when the config supplies a `markers` array. The single-`position` path below is\n  // untouched by it, so every existing caller renders exactly as it did.\n  fleet = false;\n  resolved: ResolvedMapMarker[] = [];\n  selected: MapMarker | null = null;\n  selectedCoordinates = '';\n  // Markers the consumer supplied that could NOT be located. Surfaced honestly in the identity panel\n  // rather than silently discarded — \"12 of 14 reporting\" is information; a map three vehicles short\n  // with no explanation is the defect this component exists to remove.\n  dropped = 0;\n\n  private map: L.Map | null = null;\n  private marker: L.Marker | null = null;\n  private layers = new Map<string, { marker: L.Marker; resolved: ResolvedMapMarker }>();\n  private streamSub: Subscription | null = null;\n  private base: L.TileLayer | null = null;\n  private imagery: L.TileLayer | null = null;\n  private tilesSeen = 0;\n  private settleTimer: any = null;\n\n  constructor(private zone: NgZone) { }\n\n  get title(): string { return this.config?.title || 'Location'; }\n  get subtitle(): string { return this.config?.subtitle || ''; }\n  get caption(): string { return this.config?.caption || ''; }\n  get showCoordinates(): boolean { return this.config?.showCoordinates !== false; }\n  get emptyMessage(): string {\n    if (this.config?.emptyMessage) return this.config.emptyMessage;\n    return this.fleet ? 'No vehicles reporting' : 'No location recorded';\n  }\n\n  get emptyDetail(): string {\n    if (this.config?.emptyDetail) return this.config.emptyDetail;\n    return this.fleet\n      ? 'No vehicle has reported a GPS position yet. Positions appear here as soon as one arrives.'\n      : 'This vehicle has not reported a GPS position yet.';\n  }\n\n  get fleetTitle(): string { return this.config?.fleetTitle || this.config?.title || 'Fleet'; }\n  get reportingCount(): number { return this.resolved.length; }\n\n  // The one-line honest summary under the fleet title.\n  get fleetSummary(): string {\n    const n = this.resolved.length;\n    const noun = n === 1 ? 'vehicle' : 'vehicles';\n    return this.dropped > 0 ? `${n} ${noun} reporting · ${this.dropped} without a position` : `${n} ${noun} reporting`;\n  }\n\n  // The toggle needs somewhere to toggle TO. tin-spa ships no imagery provider of its own (Arbiter\n  // ruling 2026-08-19 — OSM has no satellite tiles and keyless imagery endpoints carry licence terms a\n  // shared library must not accept on four apps' behalf), so the button appears only once a consumer\n  // supplies imageryTileUrl. Setting showMapTypeToggle:true WITHOUT a URL therefore shows nothing and\n  // raises no error — that is deliberate, not the house silent-failure bug.\n  get showMapTypeToggle(): boolean { return this.config?.showMapTypeToggle !== false && !!this.config?.imageryTileUrl; }\n\n  ngOnChanges(changes: SimpleChanges) {\n    // 🔴 A new CONFIG OBJECT rebuilds the map, as it always has. To add, remove or move markers WITHOUT\n    // losing the user's pan, zoom and selection, a consumer mutates config.markers in place and calls\n    // refreshMarkers() — that path diffs. Angular does not fire ngOnChanges for an in-place mutation, so\n    // there is no way for the component to notice it on its own, and a poll that replaced the whole\n    // config every few seconds would redraw the fleet under the user's hands.\n    if (changes['config']) this.start();\n\n    if (changes['positionStream']) this.subscribeStream();\n  }\n\n  ngOnDestroy() {\n    if (this.streamSub) { this.streamSub.unsubscribe(); this.streamSub = null; }\n    this.teardown();\n  }\n\n  // Called by a consumer that mutates its marker array in place (the common Angular case: rows reloaded,\n  // same array reference). Cheap and idempotent — it diffs, it does not redraw.\n  refreshMarkers() { this.applyMarkers(this.config?.markers); }\n\n  private start() {\n    this.teardown();\n\n    this.fleet = Array.isArray(this.config?.markers);\n    this.point = parseMapPoint(this.config?.position);\n    this.coordinates = formatMapPoint(this.point);\n    this.mapType = this.config?.mapTypeId || 'roadmap';\n    this.subscribeStream();\n\n    if (this.fleet) {\n      const markers = this.config?.markers || [];\n      this.resolved = normaliseMarkers(markers);\n      this.dropped = markers.length - this.resolved.length;\n      // The fleet's own anchor: the first located vehicle. fitBounds widens to all of them once drawn.\n      this.point = this.resolved.length ? this.resolved[0].point : null;\n      this.coordinates = formatMapPoint(this.point);\n    }\n\n    // No trustworthy position: show the designed empty state. Deliberately NOT a default position —\n    // a confident marker on a wrong spot is the failure mode this component exists to remove.\n    if (!this.point) { this.state = 'empty'; return; }\n\n    this.state = 'loading';\n    // Leaflet is bundled, so there is nothing to wait for before drawing. The one deferral is a tick, so\n    // the host element has been laid out and Leaflet measures a real size rather than 0x0.\n    setTimeout(() => this.draw(), 0);\n  }\n\n  private draw() {\n    if (!this.point || !this.surface?.nativeElement) return;\n\n    // Leaflet attaches high-frequency listeners (mousemove, drag, zoom animation frames). Built inside\n    // Angular's zone every one of those triggers change detection across the whole app while the user\n    // pans. Everything below runs outside the zone and hops back in only to flip a bound field.\n    this.zone.runOutsideAngular(() => {\n      const interactive = this.config?.interactive !== false;\n\n      const map = L.map(this.surface.nativeElement, {\n        center: [this.point!.lat, this.point!.lng],\n        zoom: Math.min(this.config?.zoom || 15, OSM_MAX_ZOOM),\n        // Every default control is off: the floating glass chrome replaces them, so no provider\n        // furniture competes with the imagery. The ONE exception is attribution, which is required.\n        zoomControl: false,\n        attributionControl: true,\n        dragging: interactive,\n        scrollWheelZoom: interactive,\n        doubleClickZoom: interactive,\n        touchZoom: interactive,\n        boxZoom: false,\n        keyboard: false,\n        // Leaflet's default is a fussy zoom-out-then-in animation on setView; the beacon should feel\n        // like it is being tracked, not re-found.\n        zoomAnimation: true\n      });\n      this.map = map;\n\n      map.attributionControl.setPrefix(''); // drop Leaflet's own \"Leaflet\" flag; OSM's credit is the obligation\n\n      this.base = L.tileLayer(this.config?.tileUrl || OSM_TILE_URL, {\n        attribution: this.config?.attribution || OSM_ATTRIBUTION,\n        maxZoom: OSM_MAX_ZOOM\n      });\n\n      if (this.config?.imageryTileUrl) {\n        this.imagery = L.tileLayer(this.config.imageryTileUrl, {\n          attribution: this.config?.imageryAttribution || '',\n          maxZoom: OSM_MAX_ZOOM\n        });\n      }\n\n      const wantsImagery = (this.mapType === 'satellite' || this.mapType === 'hybrid') && !!this.imagery;\n      (wantsImagery ? this.imagery! : this.base).addTo(map);\n      if (!wantsImagery) this.mapType = 'roadmap';\n\n      if (this.fleet) { this.drawMarkers(map); this.fitToMarkers(false); }\n      else this.attachBeacon(map);\n      this.watchTiles();\n\n      // \"Recenter\" only lights up once it has something to do.\n      map.on('move', () => {\n        const c = map.getCenter();\n        if (!c || !this.point) return;\n        const drift = Math.abs(c.lat - this.point.lat) + Math.abs(c.lng - this.point.lng);\n        const off = drift > 0.0004;\n        if (off !== this.offCentre) this.zone.run(() => { this.offCentre = off; });\n      });\n\n      // In a dialog the surface is often measured before the panel has finished sizing; without this the\n      // map paints a single column of tiles into a stale viewport.\n      setTimeout(() => { try { map.invalidateSize(); } catch { } }, 60);\n    });\n  }\n\n  // Tiles are the one thing that can genuinely fail now (offline, blocked, OSM unreachable). The spinner\n  // holds until the first visible batch has painted, then the chrome fades in over real imagery. It is\n  // deliberately NOT \"any tile errored\" -> unavailable: a single 404 at the edge of the world is normal.\n  // Only a layer that errored having painted NOTHING is actually unavailable.\n  private watchTiles() {\n    const layer = this.base;\n    if (!layer || !this.map) return;\n\n    layer.on('tileload', () => {\n      this.tilesSeen++;\n      if (this.state !== 'ready') this.zone.run(() => { this.state = 'ready'; });\n    });\n\n    layer.on('tileerror', () => {\n      if (this.tilesSeen === 0 && this.state === 'loading') {\n        this.zone.run(() => { this.state = 'unavailable'; });\n      }\n    });\n\n    // A tile server that neither loads nor errors (hung connection) must not pin the spinner forever.\n    this.settleTimer = setTimeout(() => {\n      if (this.state === 'loading') {\n        this.zone.run(() => { this.state = this.tilesSeen > 0 ? 'ready' : 'unavailable'; });\n      }\n    }, 12000);\n  }\n\n  // The beacon is a real DOM element carried by a Leaflet DivIcon, not a raster marker image. That is\n  // what lets it hold a CSS pulse and stay crisp at every zoom — a static pin can do neither, and \"see\n  // where their vehicle is at a glance\" is the whole point of the directive. A zero-size icon anchored at\n  // its origin means the marker element's 0,0 IS the coordinate, and the beacon's rings centre on it.\n  private attachBeacon(map: L.Map) {\n    const el = this.beacon.nativeElement;\n\n    const icon = L.divIcon({ className: 'spa-map-beacon-icon', html: '', iconSize: [0, 0], iconAnchor: [0, 0] });\n    const marker = L.marker([this.point!.lat, this.point!.lng], {\n      icon,\n      interactive: false,\n      keyboard: false,\n      // Above the tile panes, below the glass chrome, and never captures a drag.\n      zIndexOffset: 1000\n    }).addTo(map);\n\n    const host = marker.getElement();\n    if (host) {\n      host.appendChild(el);\n      el.style.display = 'block';\n    }\n    this.marker = marker;\n  }\n\n  // ---------------------------------------------------------------------------\n  // FLEET — N beacons, identity by marker id.\n  //\n  // 🔴 The invariant of this whole phase: a marker is CREATED once and thereafter only MOVED. Redrawing\n  // the layer on every frame would restart the pulse animation, drop the user's selection and, on a\n  // twenty-vehicle fleet with a 10s broadcast window, rebuild the DOM twice a second for no reason.\n  // ---------------------------------------------------------------------------\n  private drawMarkers(map: L.Map) {\n    for (const item of this.resolved) this.addMarker(map, item);\n  }\n\n  private addMarker(map: L.Map, item: ResolvedMapMarker) {\n    // A real hit area: a zero-size icon cannot be clicked, and selection is the point of fleet mode.\n    // 34x34 anchored at its centre means the element's centre IS the coordinate, so the CSS rings —\n    // which centre themselves in the box — land on the fix exactly as the single-vehicle beacon does.\n    const icon = L.divIcon({\n      className: 'spa-map-fleet-icon',\n      html: this.beaconHtml(item.marker),\n      iconSize: [34, 34],\n      iconAnchor: [17, 17]\n    });\n\n    const marker = L.marker([item.point.lat, item.point.lng], { icon, keyboard: false, zIndexOffset: 1000, title: item.marker.title || '' }).addTo(map);\n    marker.on('click', () => this.zone.run(() => this.select(item.marker)));\n\n    this.layers.set(item.key, { marker, resolved: item });\n  }\n\n  // The beacon markup, built as a string because Leaflet creates this element at runtime. It carries the\n  // SAME three layers as the single-vehicle beacon — pulse, ring, core — so the fleet reads as the same\n  // instrument, plus a heading wedge and a label chip that only a fleet needs.\n  private beaconHtml(marker: MapMarker): string {\n    const stale = marker.stale ? ' is-stale' : '';\n    const heading = typeof marker.heading === 'number' && isFinite(marker.heading)\n      ? `<span class=\"spa-map-fb-heading\" style=\"transform:rotate(${Math.round(marker.heading)}deg)\"></span>`\n      : '';\n    const label = marker.title ? `<span class=\"spa-map-fb-label\">${escapeHtml(marker.title)}</span>` : '';\n\n    return `<span class=\"spa-map-fb${stale}\">${heading}<span class=\"spa-map-fb-pulse\"></span><span class=\"spa-map-fb-ring\"></span><span class=\"spa-map-fb-core\"></span>${label}</span>`;\n  }\n\n  // Diffs the incoming array against what is drawn: move what is still here, add what is new, remove what\n  // is gone. Nothing else is touched, so pan, zoom, selection and every running animation survive.\n  private applyMarkers(markers: MapMarker[] | null | undefined) {\n    if (!this.fleet) return;\n\n    const incoming = normaliseMarkers(markers);\n    this.resolved = incoming;\n    this.dropped = (markers?.length || 0) - incoming.length;\n\n    // Nothing locatable any more: fall back to the honest empty state rather than an abandoned map.\n    if (!incoming.length) { this.zone.run(() => { this.state = 'empty'; this.clearSelection(); }); this.dropLayers(); return; }\n    if (this.state === 'empty') { this.zone.run(() => { this.state = 'loading'; }); this.start(); return; }\n    if (!this.map) return;\n\n    const live = new Set<string>();\n\n    for (const item of incoming) {\n      live.add(item.key);\n\n      // Changed: keep an OPEN identity panel current over the diff path. The panel binds `selected` and\n      // `selectedCoordinates` directly, and a refresh hands us NEW MapMarker objects — so `selected` went on\n      // pointing at the object captured when the user clicked, and the panel showed the position, speed,\n      // heading and stale dot from the moment of selection for as long as it stayed open. applyPositionUpdate\n      // (the live path) already does this at line ~399; only the poll path was missing it, which is why the\n      // defect appears exactly when real-time is off. Re-pointing is a data refresh, not a selection change,\n      // so markerSelected is deliberately NOT re-emitted.\n      if (this.selected && markerKey(this.selected.id) === item.key)\n        this.zone.run(() => { this.selected = item.marker; this.selectedCoordinates = formatMapPoint(item.point); });\n\n      const existing = this.layers.get(item.key);\n      if (!existing) { this.addMarker(this.map, item); continue; }\n\n      existing.resolved = item;\n      existing.marker.setLatLng([item.point.lat, item.point.lng]);\n      this.restyleMarker(existing.marker, item.marker);\n    }\n\n    for (const [key, entry] of Array.from(this.layers.entries())) {\n      if (live.has(key)) continue;\n      try { this.map.removeLayer(entry.marker); } catch { }\n      this.layers.delete(key);\n      if (this.selected && markerKey(this.selected.id) === key) this.zone.run(() => this.clearSelection());\n    }\n  }\n\n  // Re-renders only the icon's inner markup — heading, stale treatment, label. Leaflet keeps the same\n  // element, so the marker is not recreated and the pulse does not restart.\n  private restyleMarker(marker: L.Marker, data: MapMarker) {\n    const el = marker.getElement();\n    if (!el) return;\n    const next = this.beaconHtml(data);\n    if (el.innerHTML !== next) el.innerHTML = next;\n    if (this.selected && markerKey(this.selected.id) === markerKey(data.id)) el.classList.add('is-selected');\n    else el.classList.remove('is-selected');\n  }\n\n  // 🔴 THE LIVE PATH. One update, one marker moved in place. Returns false when the update could not be\n  // trusted or names a vehicle this map is not showing, so a caller can tell \"moved\" from \"ignored\"\n  // instead of assuming a silent success — the house silent-failure bug.\n  applyPositionUpdate(update: MapPositionUpdate | null | undefined): boolean {\n    const key = markerKey(update?.id);\n    const point = updatePoint(update);\n    if (!key || !point) return false;\n\n    const entry = this.layers.get(key);\n    if (!entry) return false;\n\n    entry.resolved.point = point;\n    entry.resolved.marker.position = point;\n    if (update!.heading !== undefined) entry.resolved.marker.heading = update!.heading;\n    if (update!.speed !== undefined) entry.resolved.marker.speed = update!.speed;\n    if (update!.at !== undefined) entry.resolved.marker.at = update!.at;\n    entry.resolved.marker.stale = false;\n\n    entry.marker.setLatLng([point.lat, point.lng]);\n    this.restyleMarker(entry.marker, entry.resolved.marker);\n\n    const isSelected = this.selected && markerKey(this.selected.id) === key;\n    if (isSelected) this.zone.run(() => { this.selectedCoordinates = formatMapPoint(point); });\n    if (isSelected && this.followSelected && this.map) this.map.panTo([point.lat, point.lng]);\n\n    this.zone.run(() => this.markerMoved.emit(entry.resolved.marker));\n    return true;\n  }\n\n  // Where a marker currently sits, in the library's own point shape. Exists so a test or a consumer can\n  // MEASURE a move rather than infer it from the DOM.\n  markerPosition(id: string | number): MapPoint | null {\n    const key = markerKey(id);\n    const entry = key ? this.layers.get(key) : null;\n    return entry ? { lat: entry.resolved.point.lat, lng: entry.resolved.point.lng } : null;\n  }\n\n  select(marker: MapMarker | null) {\n    this.selected = marker;\n    this.selectedCoordinates = marker ? formatMapPoint(parseMapPoint(marker.position)) : '';\n\n    const key = markerKey(marker?.id);\n    for (const [k, entry] of this.layers) {\n      const el = entry.marker.getElement();\n      if (el) el.classList.toggle('is-selected', k === key);\n    }\n\n    this.markerSelected.emit(marker);\n  }\n\n  clearSelection() { this.select(null); }\n\n  private fitToMarkers(animate = true) {\n    if (!this.map || !this.resolved.length) return;\n    if (this.config?.fitMarkers === false) return;\n\n    const bounds = L.latLngBounds(this.resolved.map(r => L.latLng(r.point.lat, r.point.lng)));\n    // A single marker has no extent to fit — fitBounds would zoom to maximum on a point. Centre instead.\n    if (this.resolved.length === 1) {\n      this.map.setView([this.resolved[0].point.lat, this.resolved[0].point.lng], Math.min(this.config?.zoom || 15, OSM_MAX_ZOOM), { animate });\n    } else {\n      this.map.fitBounds(bounds, { padding: [64, 64], maxZoom: OSM_MAX_ZOOM, animate });\n    }\n\n    // Recenter measures drift from here, so the fleet's own centre becomes the reference point.\n    const centre = bounds.getCenter();\n    this.point = { lat: centre.lat, lng: centre.lng };\n    this.zone.run(() => { this.offCentre = false; });\n  }\n\n  private dropLayers() {\n    for (const entry of this.layers.values()) {\n      if (this.map) { try { this.map.removeLayer(entry.marker); } catch { } }\n    }\n    this.layers.clear();\n  }\n\n  // The stream is subscribed OUTSIDE Angular: a fleet of twenty vehicles pushes a frame every few\n  // hundred milliseconds, and a marker move touches no bound field, so running change detection per\n  // frame would be pure waste. applyPositionUpdate hops back into the zone only for what is bound.\n  private subscribeStream() {\n    if (this.streamSub) { this.streamSub.unsubscribe(); this.streamSub = null; }\n    if (!this.positionStream) return;\n\n    this.zone.runOutsideAngular(() => {\n      this.streamSub = this.positionStream!.subscribe(update => this.applyPositionUpdate(update));\n    });\n  }\n\n  // The seam a live vehicle feed attaches to. Moves the existing beacon rather than rebuilding the map,\n  // so panning/zoom state survives an update. Returns false if the value could not be trusted — the\n  // caller then knows the beacon was NOT moved, instead of it silently sitting on a stale position.\n  setPosition(value: string | MapPoint | null | undefined, follow = false): boolean {\n    const next = parseMapPoint(value);\n    if (!next) return false;\n\n    this.point = next;\n    this.coordinates = formatMapPoint(next);\n\n    if (this.marker) this.marker.setLatLng([next.lat, next.lng]);\n    if (follow && this.map) this.map.panTo([next.lat, next.lng]);\n    return true;\n  }\n\n  recenter() {\n    // In fleet mode \"recenter\" means \"show me everyone again\", not \"go back to one vehicle\".\n    if (this.fleet) { this.fitToMarkers(); return; }\n    if (!this.map || !this.point) return;\n    this.map.setView([this.point.lat, this.point.lng], Math.min(this.config?.zoom || 15, OSM_MAX_ZOOM));\n  }\n\n  zoomBy(delta: number) {\n    if (!this.map) return;\n    this.map.setZoom(this.map.getZoom() + delta);\n  }\n\n  toggleMapType() {\n    if (!this.map || !this.imagery || !this.base) return;\n    const toImagery = this.mapType === 'roadmap';\n    this.map.removeLayer(toImagery ? this.base : this.imagery);\n    (toImagery ? this.imagery : this.base).addTo(this.map);\n    this.mapType = toImagery ? 'satellite' : 'roadmap';\n  }\n\n  copyCoordinates() {\n    // In fleet mode the readout belongs to the SELECTED vehicle, not to the map's anchor point.\n    const value = this.fleet ? this.selectedCoordinates : this.coordinates;\n    if (!value) return;\n    const nav = window.navigator;\n    if (nav && nav.clipboard) nav.clipboard.writeText(value).catch(() => { });\n  }\n\n  close() { this.closed.emit(); }\n\n  private teardown() {\n    if (this.settleTimer) { clearTimeout(this.settleTimer); this.settleTimer = null; }\n    // The stream subscription is NOT dropped here: teardown also runs on a config change, and a live feed\n    // outlives that. It is unsubscribed by subscribeStream (on a new stream) and by ngOnDestroy below.\n    this.dropLayers();\n    this.selected = null;\n    this.selectedCoordinates = '';\n\n    // The beacon element is Angular's, not Leaflet's — reclaim it before remove() disposes the panes,\n    // or the next open finds it detached and the beacon never appears.\n    const el = this.beacon?.nativeElement;\n    if (el) { el.style.display = 'none'; if (el.parentNode) el.parentNode.removeChild(el); }\n\n    if (this.map) { try { this.map.remove(); } catch { } }\n    this.map = null;\n    this.marker = null;\n    this.base = null;\n    this.imagery = null;\n    this.tilesSeen = 0;\n    this.offCentre = false;\n  }\n}\n\n// 🔴 The marker label is built as an HTML STRING because Leaflet's DivIcon takes one, so a vehicle name\n// coming out of the database lands in markup unescaped unless this is applied. Angular's interpolation\n// does not run on it. Every consumer-supplied string that reaches beaconHtml goes through here.\nfunction escapeHtml(value: string): string {\n  return String(value)\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#39;');\n}\n","<!-- The map surface is the root and fills its host absolutely. Everything else floats ON it, so no piece\n     of chrome ever subtracts height from the imagery. -->\n<div class=\"spa-map-root\" [class.spa-map-static]=\"config?.interactive === false\">\n\n  <div #surface class=\"spa-map-surface\"></div>\n\n  <!-- The beacon is declared here so Angular owns its markup and the component CSS reaches it, then it is\n       re-parented into a Leaflet DivIcon marker at runtime. Leaflet positions that marker; these spans\n       centre themselves on its origin. -->\n  <div #beacon class=\"spa-map-beacon\" aria-hidden=\"true\">\n    <span class=\"spa-map-beacon-pulse\"></span>\n    <span class=\"spa-map-beacon-ring\"></span>\n    <span class=\"spa-map-beacon-core\"></span>\n  </div>\n\n  <!-- FLEET IDENTITY — top left, replaces the single-vehicle panel when markers are supplied. Two faces\n       of one panel: the fleet roll-up while nothing is picked, and the picked vehicle's own identity\n       once one is. Same glass, same rise animation, so selecting reads as the panel CHANGING rather\n       than a second panel appearing. -->\n  <div class=\"spa-map-panel spa-map-identity spa-map-fleet-panel\" *ngIf=\"state === 'ready' && fleet\">\n\n    <ng-container *ngIf=\"!selected\">\n      <div class=\"spa-map-identity-head\">\n        <span class=\"spa-map-live\" aria-hidden=\"true\"></span>\n        <span class=\"spa-map-title\">{{ fleetTitle }}</span>\n      </div>\n      <div class=\"spa-map-subtitle\">{{ fleetSummary }}</div>\n      <div class=\"spa-map-caption\" *ngIf=\"caption\">{{ caption }}</div>\n      <div class=\"spa-map-hint\">Select a beacon for detail</div>\n    </ng-container>\n\n    <ng-container *ngIf=\"selected\">\n      <div class=\"spa-map-identity-head\">\n        <span class=\"spa-map-live\" [class.spa-map-live-stale]=\"selected.stale\" aria-hidden=\"true\"></span>\n        <span class=\"spa-map-title\">{{ selected.title || 'Vehicle' }}</span>\n        <button type=\"button\" class=\"spa-map-clear\" (click)=\"clearSelection()\" title=\"Back to fleet\" aria-label=\"Back to fleet\"><mat-icon>close</mat-icon></button>\n      </div>\n      <div class=\"spa-map-subtitle\" *ngIf=\"selected.subtitle\">{{ selected.subtitle }}</div>\n      <button type=\"button\" class=\"spa-map-coords\" *ngIf=\"showCoordinates && selectedCoordinates\"\n              (click)=\"copyCoordinates()\" title=\"Copy coordinates\">\n        <mat-icon>my_location</mat-icon><span>{{ selectedCoordinates }}</span>\n      </button>\n      <div class=\"spa-map-readings\" *ngIf=\"selected.speed != null || selected.heading != null\">\n        <span class=\"spa-map-reading\" *ngIf=\"selected.speed != null\"><mat-icon>speed</mat-icon>{{ selected.speed }} {{ selected.speedUnit || 'km/h' }}</span>\n        <span class=\"spa-map-reading\" *ngIf=\"selected.heading != null\"><mat-icon>navigation</mat-icon>{{ selected.heading }}&deg;</span>\n      </div>\n      <div class=\"spa-map-caption\" *ngIf=\"selected.caption\">{{ selected.caption }}</div>\n    </ng-container>\n\n  </div>\n\n  <!-- IDENTITY — top left. Answers \"what am I looking at, and exactly where is it\". -->\n  <div class=\"spa-map-panel spa-map-identity\" *ngIf=\"state === 'ready' && !fleet\">\n    <div class=\"spa-map-identity-head\">\n      <span class=\"spa-map-live\" aria-hidden=\"true\"></span>\n      <span class=\"spa-map-title\">{{ title }}</span>\n    </div>\n    <div class=\"spa-map-subtitle\" *ngIf=\"subtitle\">{{ subtitle }}</div>\n    <button type=\"button\" class=\"spa-map-coords\" *ngIf=\"showCoordinates && coordinates\"\n            (click)=\"copyCoordinates()\" title=\"Copy coordinates\">\n      <mat-icon>my_location</mat-icon><span>{{ coordinates }}</span>\n    </button>\n    <div class=\"spa-map-caption\" *ngIf=\"caption\">{{ caption }}</div>\n  </div>\n\n  <!-- CONTROLS — bottom right, thumb-reachable on a phone and out of the way of the beacon. -->\n  <div class=\"spa-map-controls\" *ngIf=\"state === 'ready' && config?.interactive !== false\">\n    <button type=\"button\" class=\"spa-map-btn spa-map-recenter\" [class.spa-map-btn-active]=\"offCentre\"\n            (click)=\"recenter()\" [title]=\"fleet ? 'Fit all vehicles' : 'Recenter on vehicle'\"\n            [attr.aria-label]=\"fleet ? 'Fit all vehicles' : 'Recenter on vehicle'\">\n      <mat-icon>gps_fixed</mat-icon>\n    </button>\n    <div class=\"spa-map-zoom\">\n      <button type=\"button\" class=\"spa-map-btn\" (click)=\"zoomBy(1)\" title=\"Zoom in\" aria-label=\"Zoom in\"><mat-icon>add</mat-icon></button>\n      <span class=\"spa-map-zoom-sep\"></span>\n      <button type=\"button\" class=\"spa-map-btn\" (click)=\"zoomBy(-1)\" title=\"Zoom out\" aria-label=\"Zoom out\"><mat-icon>remove</mat-icon></button>\n    </div>\n    <button type=\"button\" class=\"spa-map-btn\" *ngIf=\"showMapTypeToggle\" (click)=\"toggleMapType()\"\n            [title]=\"mapType === 'roadmap' ? 'Satellite view' : 'Map view'\" aria-label=\"Toggle satellite view\">\n      <!-- 'layers'/'map' rather than 'satellite_alt': the newer ligature does not resolve in the Material\n           Icons font the apps ship and rendered as a stray glyph. Verified visually at 1920x1032. -->\n      <mat-icon>{{ mapType === 'roadmap' ? 'layers' : 'map' }}</mat-icon>\n    </button>\n  </div>\n\n  <!-- LOADING — the map surface is dark before tiles paint, so the spinner sits on the same ground. -->\n  <div class=\"spa-map-state\" *ngIf=\"state === 'loading'\">\n    <div class=\"spa-map-state-spinner\" aria-hidden=\"true\"></div>\n    <div class=\"spa-map-state-title\">Locating</div>\n  </div>\n\n  <!-- EMPTY — designed, not broken. The Arbiter's condition: this must read as intentional. -->\n  <div class=\"spa-map-state\" *ngIf=\"state === 'empty'\">\n    <div class=\"spa-map-state-glyph\" aria-hidden=\"true\"><mat-icon>location_searching</mat-icon></div>\n    <div class=\"spa-map-state-title\">{{ emptyMessage }}</div>\n    <div class=\"spa-map-state-detail\">{{ emptyDetail }}</div>\n  </div>\n\n  <!-- UNAVAILABLE — the API could not be reached or no key is configured for this app. -->\n  <div class=\"spa-map-state\" *ngIf=\"state === 'unavailable'\">\n    <div class=\"spa-map-state-glyph\" aria-hidden=\"true\"><mat-icon>public_off</mat-icon></div>\n    <div class=\"spa-map-state-title\">Map unavailable</div>\n    <div class=\"spa-map-state-detail\">Map tiles could not be loaded. The coordinate below is still the recorded position.</div>\n    <div class=\"spa-map-state-coords\" *ngIf=\"coordinates\">{{ coordinates }}</div>\n  </div>\n\n</div>\n","// The full-bleed map dialog.\n//\n// The owner's complaint, verbatim: \"the view must NOT have loads of bezels ... it should almost consume\n// the screen with as few bezels as possible so the MAP AREA is maximized.\"\n//\n// So this dialog has NO mat-dialog-title, NO mat-dialog-content padding and NO mat-dialog-actions bar.\n// Those three bands were the entire problem in the component this replaces: they cost ~140px of vertical\n// chrome around a map that was itself hard-limited to 400px. Sizing and the padding reset live in\n// openMapDialog() and the .spa-map-dialog panel class respectively.\n//\n// BACKWARDS COMPATIBILITY: MAT_DIALOG_DATA is accepted as either a MapConfig or the raw \"lat,lng\" string\n// that Shift's existing call sites already pass. Dropping the string form would break three live call\n// sites, and there is no compatibility waiver on this chunk.\n\nimport { Component, Inject } from '@angular/core';\nimport { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';\nimport { MapConfig } from '../../classes/MapClasses';\n\n@Component({\n  selector: 'spa-map-dialog',\n  templateUrl: './mapDialog.component.html',\n  styleUrls: ['./mapDialog.component.css'],\n  standalone: false\n})\nexport class MapDialogComponent {\n\n  config: MapConfig;\n\n  constructor(public dialogRef: MatDialogRef<MapDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {\n    this.config = normaliseMapData(data);\n  }\n\n  close() { this.dialogRef.close(); }\n}\n\n// Accepts the legacy \"lat,lng\" string, a MapPoint literal, or a full MapConfig, and always yields a\n// MapConfig. Anything unrecognised yields a config with no position, which renders the empty state.\nexport function normaliseMapData(data: any): MapConfig {\n  const config = new MapConfig();\n\n  if (data == null) return config;\n\n  // Legacy shape — the string Shift has always passed.\n  if (typeof data === 'string') { config.position = data; return config; }\n\n  // A bare {lat,lng} literal.\n  if (typeof data.lat === 'number' && typeof data.lng === 'number') { config.position = data; return config; }\n\n  // Already a MapConfig (or config-shaped object).\n  return Object.assign(config, data);\n}\n\n// The single supported way to open the viewer. Centralising the sizing here is what makes \"full bleed\"\n// a property of the component rather than something every call site has to remember — the old call site\n// hard-coded width:\"900px\" and got a 560px dialog with a 400px map inside it.\nexport function openMapDialog(dialog: MatDialog, data: MapConfig | string) {\n  const phone = typeof window !== 'undefined' && window.innerWidth < 600;\n\n  return dialog.open(MapDialogComponent, {\n    data,\n    panelClass: 'spa-map-dialog',\n    // On a phone the dialog IS the screen. On desktop it stops just short of the edges so the app behind\n    // it still reads as context rather than being replaced outright.\n    width: phone ? '100vw' : '94vw',\n    height: phone ? '100vh' : '92vh',\n    maxWidth: phone ? '100vw' : '94vw',\n    maxHeight: phone ? '100vh' : '92vh',\n    autoFocus: false,\n    restoreFocus: true\n  });\n}\n","<!-- No mat-dialog-title, no mat-dialog-content, no mat-dialog-actions. The map is the dialog.\n     The only chrome is one floating close button, which sits ON the map rather than in a band above it. -->\n<div class=\"spa-map-dialog-body\">\n\n  <spa-map [config]=\"config\" (closed)=\"close()\"></spa-map>\n\n  <button type=\"button\" class=\"spa-map-dialog-close\" (click)=\"close()\" title=\"Close\" aria-label=\"Close location viewer\">\n    <mat-icon>close</mat-icon>\n  </button>\n\n</div>\n","import { Component, Inject, OnInit } from '@angular/core';\nimport { FormConfig, ListDialogConfig, TableConfig } from '../../classes/Classes';\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { Subject } from 'rxjs';\n\n@Component({\n    selector: 'spa-list-dialog',\n    templateUrl: './list-dialog.component.html',\n    styleUrls: ['./list-dialog.component.css'],\n    standalone: false\n})\nexport class ListDialogComponent implements OnInit {\n\n  constructor(private dataService: DataServiceLib, private dialogRef: MatDialogRef<ListDialogComponent>, @Inject(MAT_DIALOG_DATA) public data : ListDialogConfig) { }\n\n  ngOnInit(): void {\n\n    this.listConfig = this.data;\n    this.formConfig.fields.find(x => x.name == 'listName').defaultValue = this.listConfig.listName;\n    this.config.loadAction = { url: 'listitems/lists/' + this.listConfig.listName } // Changed: GeneralController was deleted in e344928 (2025-12-16) and replaced by ListItemsController, which still serves the 'lists' criteria — the client was never repointed, so this dialog loaded nothing for ~8 months\n    // this.config.buttons.find(x => x.name == 'create').display = \"New \" + this.listConfig.name\n\n\n  }\n\n  clicked = false;\n\n  actionClicked(){\n    this.clicked = true;\n  }\n\n  close(){\n    if (this.clicked){\n      this.dialogRef.close(\"success\")\n    }else{\n      this.dialogRef.close(\"\")\n    }\n  }\n\n  item: string = \"\";\n  tableReload: Subject<boolean> = new Subject();\n\n\n  listConfig: ListDialogConfig\n\n  formConfig: FormConfig = {\n\n    fields: [\n      { name: 'name', type: 'text' },\n      { name: 'listName', type: 'text',  hidden : true },\n    ],\n\n    reset: true,\n  }\n\n\n  config: TableConfig = {\n\n    showFilter : true,\n    minColumns: ['name',],\n    minButtons: ['edit'],\n    elevation: 'none',\n\n    columns: [\n      { name: 'name', type: 'text' },\n    ],\n\n    buttons: [\n      { name: 'create' , display : 'New', dialog: true, action: { url: 'listitems?action=create', method: 'post' } }, // Changed: repointed off the deleted GeneralController; BaseController's write route is bare [HttpPost], so no criteria segment — matches the working sibling in general.service.ts:167\n      { name: 'edit', dialog: true, action: { url: 'listitems?action=edit', method: 'post' } }, // Changed: repointed off the deleted GeneralController, same bare [HttpPost] shape as general.service.ts:168\n      { name: 'delete', dialog: true, action: { url: 'listitems?action=delete', method: 'post' } }, // Changed: repointed off the deleted GeneralController, same bare [HttpPost] shape as general.service.ts:169\n    ],\n\n    formConfig : this.formConfig\n\n  }\n\n}\n","<div>\n\n  <label style=\"font-size: 24px;\">{{listConfig?.title ?? 'List'}}</label>\n\n</div>\n\n<mat-dialog-content class=\"mat-typography\">\n\n  <div style=\" font-size: 14px;\">\n    <spa-table [config]=\"config\" [reload]=\"tableReload\" (actionClick)=\"actionClicked()\"></spa-table>\n  </div>\n\n\n</mat-dialog-content>\n\n<mat-dialog-actions>\n  <button mat-button (click)=\"close()\" >Ok</button>\n</mat-dialog-actions>\n","import { Component, EventEmitter, OnInit, Output } from '@angular/core';\nimport { ApiResponse, TableConfig } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: accept/decline and the follow-on switch both failed silently (WS-6 Phase 4)\nimport { Subject } from 'rxjs';\n\n@Component({\n    selector: 'spa-invitations-table',\n    templateUrl: './invitations-table.component.html',\n    styleUrls: ['./invitations-table.component.css'],\n    standalone: false\n})\nexport class InvitationsTableComponent implements OnInit {\n\n  constructor(public dataService: DataServiceLib, private messageService: MessageService, public authService: AuthService, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService for the two membership actions\n\n  // Added (2026-08-12): this component wraps a spa-table, so its host had no way to learn how many\n  // invitations were loaded. Tenant settings shows that count on the collapsed card. Purely additive —\n  // the other host (pages/onboarding) simply does not bind it and is unaffected.\n  @Output() totalChange = new EventEmitter<number>();\n\n  ngOnInit(): void {\n  }\n\n  invActionClicked(x) {\n\n    let message = \"Accept\"\n    let action = \"accept\"\n    if (x.name == \"decline\") {\n      action = \"remove\";\n      message = \"Decline\"\n    }\n\n\n\n    //accept / decline\n    this.messageService.confirm(`${message} membership to organisation (${x.data.tenantName}) ?`).subscribe((result) => {\n\n      if (result == \"yes\") {\n        this.dataService.CallApi({ url: 'members/dto?action=' + action, method: 'post', }, x.data).subscribe((apiResponse: ApiResponse) => {\n\n          if (apiResponse.success) {\n            this.tableReload.next(true)\n            this.messageService.toast(\"Updated Successfully\");\n\n            // switch\n            this.messageService.confirm(`Switch to organisation (${x.data.tenantName}) now ?`).subscribe((result) => {\n              if (result == \"yes\") {\n\n                let tenant = {tenantID : x.data.tenantID}\n\n                this.dataService.CallApi({ url: 'tenants/dto?action=switch', method: 'post' }, tenant).subscribe((apiResponse: ApiResponse) => {\n\n                  if (apiResponse.success) {\n                    this.messageService.toast(\"Switched Successfully, please login again\");\n                    this.authService.logoff();\n                  } else {\n                    this.apiErrorService.presentAppFailure(apiResponse, 'action', 'tenants/dto?action=switch'); // Added: was silent. The invitation was already accepted at this point, so silence here left the user believing the switch had happened when they were still in the old organisation\n                  }\n                });\n              }\n            });\n\n          } else {\n            this.apiErrorService.presentAppFailure(apiResponse, 'action', 'members/dto?action=' + action); // Added: was silent. Accept or Decline both left the row exactly as it was with no message, so the natural read is \"it did not register my click\" and the user presses it again\n          }\n        });\n      }\n\n    });\n\n  }\n\n  tableReload: Subject<boolean> = new Subject();\n  invitationsTableConfig: TableConfig = {\n\n    greyOut: (value) => value.accepted == false,\n    elevation: 'low',\n    minColumns: ['tenantName'],\n    minButtons: ['accept', 'decline'],\n    flatButtons : true,\n\n    columns: [\n      { name: 'tenantName', alias: 'Organisation', type: 'text' },\n      { name: 'ownerName', type: 'text', },\n    ],\n\n    buttons: [\n      { name: 'accept', icon: { 'name': 'done', }, color: 'green', confirm: { message: 'Accept ?' }, disabled: (x) => x.accepted },\n      { name: 'decline', icon: { 'name': 'close', }, color: 'red', confirm: { message: 'Decline ?' }, disabled: (x) => x.accepted },\n    ],\n\n    loadAction: { url: 'tenants/invitations/x' },\n\n  }\n}\n","<spa-table [config]=\"invitationsTableConfig\" (actionClick)=\"invActionClicked($event)\" (totalChange)=\"totalChange.emit($event)\" [reload]=\"tableReload\"></spa-table>\n","import { Component, OnInit, Inject } from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { HttpClient } from '@angular/common/http';\nimport { HttpService } from '../../services/http.service';\nimport { MessageService } from '../../services/message.service';\nimport { ImportConfig, StepConfig, TableConfig, TileConfig } from '../../classes/Classes'; // Changed: spa-steps indicator + spa-tiles counters + spa-table review grid\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: every wizard step used to push the server's own message straight into a dialog — classify it first (WS-6 Phase 4)\n\n// Generic AI-assisted import wizard: Upload -> Map -> Review -> Done. Config-driven via ImportConfig.\n@Component({\n  selector: 'spa-import-dialog',\n  templateUrl: './import-dialog.component.html',\n  styleUrls: ['./import-dialog.component.css'],\n  standalone: false\n})\nexport class ImportDialogComponent implements OnInit {\n\n  entity: string;\n  title: string;\n  loading = false;\n\n  // Changed: spa-steps is a read-only indicator driven by stepIndex; footer Next/Back-style buttons are the ONLY navigation\n  stepIndex = 0;\n  stepsConfig: StepConfig = { steps: [{ name: 'Upload', icon: 'upload_file' }, { name: 'Map columns', icon: 'rule' }, { name: 'Review', icon: 'fact_check' }, { name: 'Done', icon: 'check_circle' }] };\n\n  // Changed: the review grid is a real spa-table with the table-INTEGRATED tiles (TableConfig.tileConfig):\n  // full icon tiles with description footers, clickable — a tile click filters the rows in memory via\n  // Tile.filter (replaces the \"Only show rows with problems\" checkbox). Rows are flattened copies\n  // (values + status + issues) so standard Column defs read them; editing opens the panel above the table.\n  reviewTableConfig: TableConfig = null;\n  reviewRows: any[] = [];\n  editingRow: any = null;\n\n  private buildReviewTable() {\n    this.computeReviewColumns(); // Changed: refresh the materialized columns from the current mappings\n    const cols: any[] = [\n      { name: 'rowNumber', alias: '#' },\n      ...this.reviewColumns.map(c => ({ name: c.property, alias: c.display })),\n      { name: 'statusName', alias: 'Status', type: 'chip', colors: [{ name: '#A5D6A7', condition: (x: any) => x.status === 1 }, { name: '#FFCC80', condition: (x: any) => x.status === 2 }, { name: '#EF9A9A', condition: (x: any) => x.status === 3 }] },\n      { name: 'issueText', alias: 'Issues', maxLength: 45 }\n    ];\n    this.reviewTableConfig = {\n      columns: cols, elevation: 'none', showFilter: false, showFilterButton: false, noDataMessage: 'No rows',\n      buttons: [{ name: 'edit', tip: 'Edit row', onClick: (row: any) => this.startEdit(row.__row) }],\n      tileConfig: { clickable: true, headerPosition: 'top', tiles: [\n        { name: 'total', alias: 'Total', style: 'icon', icon: 'inventory_2', footer: 'All rows in this file', filter: () => true },\n        { name: 'ready', alias: 'Ready', style: 'icon', icon: 'check_circle', color: '#2e7d32', footer: 'Will import cleanly', filter: (r: any) => r.status === 1 },\n        { name: 'warning', alias: 'Warnings', style: 'icon', icon: 'warning_amber', color: '#ef6c00', footer: 'Will import — check the issues', filter: (r: any) => r.status === 2 },\n        { name: 'error', alias: 'Errors', style: 'icon', icon: 'error_outline', color: '#c62828', footer: 'Must be fixed before import', filter: (r: any) => r.status === 3 }\n      ] }\n    } as TableConfig;\n    this.rebuildReviewRows();\n  }\n\n  rebuildReviewRows() {\n    this.reviewRows = this.rows.map(r => ({ rowNumber: r.rowNumber, statusName: r.statusName, status: r.status, issueText: this.rowIssueText(r), ...(r.values || {}), __row: r }));\n  }\n\n  // batch state\n  batchId: number = null;\n  status: number = null;         // ImportBatchStatus\n  reversible = false;            // Added (lifecycle): entity supports undo after commit (from the batch payload)\n  fileName = '';\n  fields: any[] = [];            // ImportFieldSchema[]\n  headers: any[] = [];           // [{ header, columnIndex, samples[] }]\n  mappings: any[] = [];          // [{ header, property, method, confidence, reasoning, ignore }]\n  counts = { total: 0, ready: 0, warning: 0, error: 0 };\n  rows: any[] = [];              // review rows\n  committedCount = 0;\n\n  selectedFile: File = null; // Changed: onlyProblems checkbox removed — the integrated tiles filter the grid\n\n  // inline row editing\n  editingRowId: number = null;\n  editModel: any = {};\n\n  constructor(\n    private httpService: HttpService,\n    private http: HttpClient,\n    private messageService: MessageService,\n    private apiErrorService: ApiErrorService, // Changed: injected so a step failure is classified rather than shown verbatim\n    private dialogRef: MatDialogRef<ImportDialogComponent>,\n    @Inject(MAT_DIALOG_DATA) public config: ImportConfig\n  ) { }\n\n  ngOnInit() {\n    this.entity = this.config.entity;\n    this.title = this.config.title || ('Import ' + this.entity);\n    this.loadActive();\n  }\n\n  // ---- Step 1: Upload ----\n\n  loadActive() {\n    this.loading = true;\n    this.httpService.Get(`import/active/${this.entity}`).subscribe(r => {\n      this.loading = false;\n      // Changed: a Committed (4) OR Reversed (6) batch is finished — reopening starts a NEW import instead of\n      // resuming to a stale screen. Reversed was missed when Undo was added, so after undoing an import the\n      // wizard reopened onto the undone batch's mapping step.\n      // Deliberately silent: this is the \"is there a batch to resume?\" probe fired the instant the dialog\n      // opens, before the user has asked for anything. When it fails the wizard falls back to step 0 — a\n      // fully working fresh upload — so there is nothing for the user to do differently and nothing lost.\n      // A dialog here would greet them with an error for a screen that works. (WS-6 Phase 4 triage)\n      if (r?.success && r.data?.hasItems && r.data.status !== 4 && r.data.status !== 6) {\n        this.applyBatch(r.data);\n        this.gotoStepForStatus();\n      }\n    }, () => { this.loading = false; });\n  }\n\n  onFileSelected(event: any) {\n    const files = event?.target?.files;\n    this.selectedFile = files && files.length ? files[0] : null;\n  }\n\n  doUpload() {\n    if (!this.selectedFile) { this.messageService.toast('Choose a .xlsx file first'); return; }\n\n    const formData = new FormData();\n    formData.append('uploadFile0', this.selectedFile, this.selectedFile.name);\n\n    this.loading = true;\n    this.httpService.Post_FormData(`import/upload/${this.entity}`, formData).subscribe((r: any) => {\n      this.loading = false;\n      if (r?.success) {\n        this.applyBatch(r.data);\n        this.goToStep(1);\n      } else {\n        this.apiErrorService.presentAppFailure(r, 'submit', `import/upload/${this.entity}`); // Changed: was messageService.error(r?.message ...), which put the server's own words in a dialog — \"Error processing request\", or a leaked SQL fragment when the parse fails. The file the user chose is still selected, which is exactly what the 'submit' copy promises\n      }\n      // The transport-error callback below is deliberately left as-is: it shows FIXED text, never server\n      // text, and the underlying HttpErrorResponse already reaches ApiErrorService through the interceptor.\n      // Same decision, same reasoning, as groups.component.ts in WS-6 Phase 3.\n    }, () => { this.loading = false; this.messageService.error('Upload failed'); });\n  }\n\n  downloadTemplate() {\n    const url = this.httpService.apiUrl + `import/template/${this.entity}`;\n    this.http.get(url, { responseType: 'blob' }).subscribe((blob: Blob) => {\n      const link = document.createElement('a');\n      link.href = URL.createObjectURL(blob);\n      link.download = `${this.entity}-import-template.xlsx`;\n      link.click();\n      URL.revokeObjectURL(link.href);\n    }, () => this.messageService.error('Could not download template'));\n  }\n\n  // ---- Step 2: Map ----\n\n  // Added: shared empty array so samplesFor() never allocates a fresh [] into the template\n  private static readonly NO_SAMPLES: string[] = [];\n\n  // Added: stable-reference cache for the per-header field lists (bound to the mapping *ngFor of mat-option);\n  // cleared whenever a mapping changes, which is the only thing that can change what is available.\n  private availableFieldsCache = new Map<string, any[]>();\n\n  samplesFor(header: string): string[] {\n    const h = this.headers.find(x => x.header === header);\n    return h && h.samples ? h.samples : ImportDialogComponent.NO_SAMPLES; // Changed: was a fresh [] every call\n  }\n\n  fieldUsedElsewhere(property: string, header: string): boolean {\n    if (!property) return false;\n    return this.mappings.some(m => m.header !== header && !m.ignore && m.property === property);\n  }\n\n  availableFields(header: string): any[] { // Changed: now returns a cached, stable reference\n    let fields = this.availableFieldsCache.get(header);\n    if (!fields) {\n      fields = this.fields.filter(f => !this.fieldUsedElsewhere(f.property, header));\n      this.availableFieldsCache.set(header, fields);\n    }\n    return fields;\n  }\n\n  // Changed: materialized — was a getter running .filter().map() on every change-detection cycle\n  unmappedRequired: string[] = [];\n\n  // Added: single recompute point for everything derived from the current mappings\n  private buildMappingDerived() {\n    this.availableFieldsCache.clear();\n    const mapped = this.mappings.filter(m => !m.ignore && m.property).map(m => m.property);\n    this.unmappedRequired = this.fields.filter(f => f.required && !mapped.includes(f.property)).map(f => f.display);\n  }\n\n  confidenceClass(m: any): string {\n    if (!m.property) return 'chip-grey';\n    if (m.method === 'Exact' || m.method === 'Synonym' || m.method === 'Manual') return 'chip-green';\n    return m.confidence >= 0.7 ? 'chip-blue' : 'chip-orange';\n  }\n\n  onMappingChange(m: any) {\n    m.method = m.property ? 'Manual' : 'Unmapped';\n    m.ignore = !m.property;\n    this.buildMappingDerived(); // Added: a mapping changed — recompute the derived lists once, here\n  }\n\n  confirmMapping() {\n    if (this.unmappedRequired.length) { this.messageService.toast('Map all required fields first'); return; }\n\n    const payload = this.mappings.map(m => ({ header: m.header, property: m.property || null, ignore: !m.property }));\n    this.loading = true;\n    this.httpService.Post(`import/map/${this.batchId}`, payload).subscribe(r => {\n      this.loading = false;\n      if (r?.success) {\n        this.applySummary(r.data);\n        this.loadRows(() => this.goToStep(2));\n      } else {\n        this.apiErrorService.presentAppFailure(r, 'submit', `import/map/${this.batchId}`); // Changed: was messageService.error(r?.message ...). 'submit' is literally true here — the mapping the user built is still on screen and does not have to be redone\n      }\n    }, () => { this.loading = false; this.messageService.error('Mapping failed'); });\n  }\n\n  // ---- Step 3: Review ----\n\n  // Changed: materialized (was a getter creating a NEW array every change-detection cycle — the edit\n  // panel's *ngFor + ngModel inputs over it re-created DOM endlessly and livelocked the page)\n  reviewColumns: any[] = [];\n\n  private computeReviewColumns() {\n    this.reviewColumns = this.mappings.filter(m => !m.ignore && m.property)\n      .map(m => ({ property: m.property, display: this.displayFor(m.property) }));\n  }\n\n  // Changed: displayedColumns/cellValue/cellSeverity removed with the custom mat-table — spa-table owns rendering now\n  displayFor(property: string): string {\n    const f = this.fields.find(x => x.property === property);\n    return f ? f.display : property;\n  }\n\n  rowIssueText(row: any): string {\n    return (row.issues || []).map(i => i.message).join('; ');\n  }\n\n  loadRows(after?: () => void) {\n    this.httpService.Get(`import/rows/${this.batchId}`).subscribe(r => {\n      if (!r?.success) this.apiErrorService.presentAppFailure(r, 'load', `import/rows/${this.batchId}`); // Added: was silent. A failed row fetch fell through to [] and rendered an EMPTY review grid — indistinguishable from a spreadsheet that mapped to nothing, which is the exact \"empty or broken?\" ambiguity WS-6 exists to kill\n      this.rows = (r?.success && r.data) ? r.data : [];\n      this.buildReviewTable(); // Changed: (re)build the spa-table config + flattened rows whenever fresh rows land\n      if (after) after();\n    });\n  }\n\n  startEdit(row: any) {\n    this.editingRow = row; // Changed: edit panel above the table works off the ORIGINAL row object\n    this.editingRowId = row.importRowID;\n    this.editModel = {};\n    this.reviewColumns.forEach(c => { this.editModel[c.property] = row.values ? row.values[c.property] : ''; });\n  }\n\n  cancelEdit() {\n    this.editingRow = null;\n    this.editingRowId = null;\n    this.editModel = {};\n  }\n\n  saveEdit() { // Changed: parameterless — uses editingRow captured by the edit panel\n    const row = this.editingRow;\n    if (!row) return;\n    // Translate property -> header so the server merges edits into the raw row for re-validation\n    const values: any = {};\n    this.mappings.filter(m => !m.ignore && m.property).forEach(m => {\n      if (this.editModel[m.property] !== undefined) values[m.header] = String(this.editModel[m.property] ?? '');\n    });\n\n    this.loading = true;\n    this.httpService.Post(`import/row/${row.importRowID}`, values).subscribe(r => {\n      this.loading = false;\n      if (r?.success) {\n        this.editingRowId = null; // Changed: only close the edit panel once the save actually succeeded\n        this.editingRow = null;\n        this.refreshBatch();\n      } else {\n        // Changed: the panel is no longer closed before this branch. It was closed unconditionally, which\n        // discarded everything the user had typed the moment a save failed — they had to reopen the row and\n        // re-enter it from memory. The panel now stays open with editModel intact; Cancel remains the way out.\n        // Changed: context is now 'submit' rather than 'action'. 'action' was chosen only because the panel\n        // used to close regardless, which made the 'submit' copy (\"your details are still on the form\") a lie.\n        // That is now literally true, and this is exactly the case that copy exists for — one deliberate save,\n        // with its own dedupe key, where a missed message makes the user press Save again.\n        this.apiErrorService.presentAppFailure(r, 'submit', `import/row/${row.importRowID}`);\n      }\n    }, () => { this.loading = false; this.messageService.error('Could not update row'); });\n  }\n\n  refreshBatch() {\n    this.httpService.Get(`import/batch/${this.batchId}`).subscribe(r => {\n      // Deliberately silent: loadRows() below fires against the same backend a moment later and DOES report,\n      // so anything that breaks this call is reported there. Adding a second call site for one outage is the\n      // dialog storm this channel was built to stop. Counts going stale is the only consequence, and the\n      // very next successful refresh corrects them. (WS-6 Phase 4 triage)\n      if (r?.success && r.data) this.applyBatch(r.data);\n      this.loadRows();\n    });\n  }\n\n  doCommit() {\n    if (this.counts.error > 0) { this.messageService.toast('Fix all errors before importing'); return; }\n\n    this.messageService.confirm(`Import ${this.counts.total - this.counts.error} record(s) into ${this.entity}?`).subscribe(result => {\n      if (result !== 'yes') return;\n\n      this.loading = true;\n      this.httpService.Post(`import/commit/${this.batchId}`, {}).subscribe(r => {\n        this.loading = false;\n        if (r?.success) {\n          this.committedCount = r.data?.committedRows ?? 0;\n          this.goToStep(3);\n          if (this.config.onComplete) this.config.onComplete(r.data);\n        } else {\n          this.apiErrorService.presentAppFailure(r, 'submit', `import/commit/${this.batchId}`); // Changed: was messageService.error(r?.message ...). This is the one press in the whole wizard that writes records, so it is exactly where the 'submit' copy — nothing was saved, do not press repeatedly, it can create duplicates — has to appear\n          this.refreshBatch();\n        }\n      }, () => { this.loading = false; this.messageService.error('Import failed'); });\n    });\n  }\n\n  // ---- shared ----\n\n  startOver() {\n    if (!this.batchId) { this.resetState(); this.goToStep(0); return; }\n    this.httpService.Post(`import/clear/${this.batchId}`, {}).subscribe(() => {\n      this.resetState();\n      this.goToStep(0);\n    });\n  }\n\n  close() {\n    this.dialogRef.close(this.committedCount > 0 ? 'success' : null);\n  }\n\n  // Added (lifecycle): undo the committed batch — soft-deletes/removes the created records server-side\n  undoImport() {\n    if (!this.batchId) return;\n    // Changed: \"removed\" was wrong for entities whose undo is a domain reversal rather than a delete —\n    // a transaction import is undone by posting reversing entries (VoidTransaction), not by deleting rows.\n    this.messageService.confirm(`Undo this import? The ${this.committedCount} imported record(s) will be reversed.`).subscribe(result => {\n      if (result !== 'yes') return;\n      this.loading = true;\n      this.httpService.Post(`import/reverse/${this.batchId}`, {}).subscribe(r => {\n        this.loading = false;\n        if (r?.success) {\n          this.messageService.toast(r.message || 'Import undone');\n          this.resetState();\n          this.goToStep(0); // batch is Reversed — start fresh\n        } else {\n          this.apiErrorService.presentAppFailure(r, 'action', `import/reverse/${this.batchId}`); // Changed: was messageService.error(r?.message ...). 'action' rather than 'submit' — this sits behind a confirm, there is no form still holding the user's input, and the 'submit' wording would describe a screen that is not there\n        }\n      }, () => { this.loading = false; this.messageService.error('Undo failed'); });\n    });\n  }\n\n  private applyBatch(data: any) {\n    this.batchId = data.batchID;\n    this.status = data.status;\n    this.reversible = !!data.reversible; // Added (lifecycle)\n    this.fileName = data.fileName || '';\n    this.fields = data.fields || [];\n    this.headers = data.headers || [];\n    this.mappings = data.mappings || [];\n    this.buildMappingDerived(); // Added: batch loaded — seed the derived mapping lists\n    this.applySummary(data);\n  }\n\n  private applySummary(data: any) {\n    this.counts = {\n      total: data.totalRows ?? this.counts.total,\n      ready: data.readyRows ?? 0,\n      warning: data.warningRows ?? 0,\n      error: data.errorRows ?? 0\n    };\n    if (data.status !== undefined && data.status !== null) this.status = data.status;\n  }\n\n  private resetState() {\n    this.batchId = null; this.status = null; this.fileName = '';\n    this.fields = []; this.headers = []; this.mappings = []; this.rows = [];\n    this.buildMappingDerived(); // Added: state reset — clear the derived mapping lists too\n    this.counts = { total: 0, ready: 0, warning: 0, error: 0 };\n    this.selectedFile = null; this.committedCount = 0; this.editingRowId = null;\n  }\n\n  private gotoStepForStatus() {\n    if (this.status === 4) { this.goToStep(3); }                 // Committed\n    else if (this.status === 2) { this.loadRows(() => this.goToStep(2)); } // Validated\n    else { this.goToStep(1); }                                   // Uploaded / Mapped\n  }\n\n  private goToStep(index: number) {\n    this.stepIndex = index; // Changed: drives the spa-steps indicator + the *ngIf step panes directly\n  }\n}\n","<!-- Changed: shell rebuilt on the details-dialog conventions — modern band header (tin-dlg-head), scrollable\n     mat-dialog-content, banded mat-dialog-actions footer (left-aligned, house rule). The stepper is spa-steps\n     as a read-only position indicator driven by stepIndex; navigation is ONLY via the footer buttons. -->\n<div class=\"import-dialog\">\n\n  <div class=\"tin-dlg-head import-head\">\n    <h2 class=\"tin-dlg-title\">{{ title }}</h2>\n    <button mat-icon-button class=\"import-close\" (click)=\"close()\" aria-label=\"Close\"><mat-icon>close</mat-icon></button>\n  </div>\n\n  <mat-progress-bar *ngIf=\"loading\" mode=\"indeterminate\" class=\"import-load-line\"></mat-progress-bar>\n\n  <mat-dialog-content class=\"mat-typography dialog-scroll-content\">\n\n    <spa-steps class=\"import-steps\" [config]=\"stepsConfig\" [activeIndex]=\"stepIndex\"></spa-steps>\n\n    <!-- Step 1: Upload -->\n    <div *ngIf=\"stepIndex === 0\" class=\"step-body\">\n      <p class=\"hint\">Upload an Excel (.xlsx) file. Not sure of the format? Download a template with the expected columns.</p>\n      <div class=\"upload-row\">\n        <button mat-stroked-button color=\"primary\" (click)=\"fileInput.click()\"><mat-icon>attach_file</mat-icon>{{ selectedFile?.name || 'Choose file' }}</button>\n        <input type=\"file\" #fileInput accept=\".xlsx\" (change)=\"onFileSelected($event)\" hidden />\n        <button mat-stroked-button color=\"primary\" (click)=\"downloadTemplate()\"><mat-icon>download</mat-icon> Download template</button>\n      </div>\n    </div>\n\n    <!-- Step 2: Map columns -->\n    <div *ngIf=\"stepIndex === 1\" class=\"step-body\">\n      <div *ngIf=\"unmappedRequired.length\" class=\"alert alert-warn\">\n        Required fields not yet mapped: <strong>{{ unmappedRequired.join(', ') }}</strong>\n      </div>\n\n      <table class=\"map-table\">\n        <thead>\n          <tr><th>Spreadsheet column</th><th>Sample values</th><th>Maps to field</th><th>Match</th></tr>\n        </thead>\n        <tbody>\n          <tr *ngFor=\"let m of mappings\">\n            <td class=\"col-header\">{{ m.header }}</td>\n            <td class=\"col-samples\">\n              <span *ngFor=\"let s of samplesFor(m.header)\" class=\"sample\">{{ s }}</span>\n            </td>\n            <td>\n              <mat-select [(ngModel)]=\"m.property\" (selectionChange)=\"onMappingChange(m)\" placeholder=\"— Ignore —\">\n                <mat-option [value]=\"null\">— Ignore —</mat-option>\n                <mat-option *ngFor=\"let f of availableFields(m.header)\" [value]=\"f.property\">\n                  {{ f.display }}<span *ngIf=\"f.required\"> *</span>\n                </mat-option>\n              </mat-select>\n            </td>\n            <td>\n              <span class=\"chip\" [ngClass]=\"confidenceClass(m)\" [matTooltip]=\"m.reasoning || ''\">\n                {{ m.property ? (m.method === 'AI' ? ((m.confidence * 100) | number:'1.0-0') + '%' : m.method) : 'Unmapped' }}\n              </span>\n            </td>\n          </tr>\n        </tbody>\n      </table>\n    </div>\n\n    <!-- Step 3: Review -->\n    <div *ngIf=\"stepIndex === 2\" class=\"step-body\">\n      <!-- Changed: row edit panel — sits above the table because saving re-validates via the import endpoint -->\n      <div class=\"edit-panel\" *ngIf=\"editingRow\">\n        <div class=\"edit-title\">Edit row {{ editingRow.rowNumber }}</div>\n        <div class=\"edit-fields\">\n          <label class=\"edit-field\" *ngFor=\"let col of reviewColumns\">\n            <span>{{ col.display }}</span>\n            <input class=\"cell-input\" [(ngModel)]=\"editModel[col.property]\" />\n          </label>\n        </div>\n        <div class=\"edit-actions\">\n          <button mat-flat-button color=\"primary\" [disabled]=\"loading\" (click)=\"saveEdit()\">Save</button>\n          <button mat-stroked-button (click)=\"cancelEdit()\">Cancel</button>\n        </div>\n      </div>\n\n      <!-- Changed: the review grid IS spa-table with its INTEGRATED tiles (tileConfig on the TableConfig):\n           clickable icon tiles filter the rows in memory — the \"Only show rows with problems\" checkbox is gone -->\n      <spa-table *ngIf=\"reviewTableConfig\" [config]=\"reviewTableConfig\" [data]=\"reviewRows\" [tileData]=\"counts\"></spa-table>\n    </div>\n\n    <!-- Step 4: Done -->\n    <div *ngIf=\"stepIndex === 3\" class=\"step-body done-body\">\n      <mat-icon class=\"done-icon\">check_circle</mat-icon>\n      <h3>Imported {{ committedCount }} record(s)</h3>\n      <p *ngIf=\"counts.warning > 0\" class=\"hint\">{{ counts.warning }} row(s) imported with warnings.</p>\n    </div>\n\n  </mat-dialog-content>\n\n  <!-- Changed: per-step actions moved into the banded footer, LEFT-aligned (house rule) -->\n  <mat-dialog-actions>\n    <button mat-flat-button color=\"primary\" *ngIf=\"stepIndex === 0\" [disabled]=\"!selectedFile || loading\" (click)=\"doUpload()\">Upload</button>\n    <button mat-flat-button color=\"primary\" *ngIf=\"stepIndex === 1\" [disabled]=\"unmappedRequired.length > 0 || loading\" (click)=\"confirmMapping()\">Next</button>\n    <button mat-flat-button color=\"primary\" *ngIf=\"stepIndex === 2\" [disabled]=\"counts.error > 0 || loading\" (click)=\"doCommit()\">Import {{ counts.total - counts.error }} record(s)</button>\n    <button mat-stroked-button *ngIf=\"stepIndex === 1 || stepIndex === 2\" (click)=\"startOver()\">Start over</button>\n    <button mat-flat-button color=\"primary\" *ngIf=\"stepIndex === 3\" (click)=\"close()\">Close</button>\n    <button mat-stroked-button *ngIf=\"stepIndex === 3 && reversible && committedCount > 0\" [disabled]=\"loading\" (click)=\"undoImport()\"><mat-icon>undo</mat-icon>Undo import</button> <!-- Added (lifecycle) -->\n    <button mat-button *ngIf=\"stepIndex !== 3\" (click)=\"close()\">Close</button>\n  </mat-dialog-actions>\n\n</div>\n","import { Component, Inject } from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { TableConfig, TableDialogConfig } from '../../classes/Classes';\n\n// Added: spa-table-dialog — a READ-ONLY window onto an entity list, hosted in a MatDialog. Built for the Getting\n// Started page's View action, where someone mid-setup wants to see what is already captured without leaving the\n// page. list-dialog is the shape this copies; it could not be reused because it is hard-wired to\n// general/lists/{listName} and carries create/edit/delete.\n//\n// NG3003: this component renders <spa-table>, and table.component.ts imports dialog.service — so DialogService\n// must NEVER import this file. It arrives through the TABLE_DIALOG_COMPONENT InjectionToken, exactly as\n// ImportDialogComponent does, and for exactly the same reason. It also cannot be standalone: spa-table lives in\n// TinSpaModule, so a standalone dialog would have to import that module circularly.\n\n// Added: READ-ONLY IS ENFORCED HERE, NOT ASSUMED OF THE CALLER.\n// The caller spreads the entity's own TableConfig, so the dialog inherits EVERYTHING that config declares — not\n// just its buttons. `buttons: []` neutralises the button row and nothing else; every other affordance below\n// survives a spread untouched and still reaches a write path. Each one is therefore turned off by name, and the\n// list is the enumeration, not a sample. A consumer app that forgets to strip anything still gets a read-only\n// dialog, because the dialog is what strips it.\nexport function readOnlyTableConfig(config: TableConfig): TableConfig {\n  const source = config ?? ({} as TableConfig);\n\n  return {\n    ...source,\n\n    // 1. buttons — the header Create AND the per-row view/edit/delete action column both render from this ONE\n    //    array (table-header.component.html:25-30 and table.component.html:129-133 via displayedButtons).\n    buttons: [],\n    minButtons: [],\n\n    // 2. columns[].detailsConfig — a CELL drill-in. table.component.ts columnClicked() opens a full details\n    //    dialog, with that config's own buttons, from a chip / button / monogram cell. It has nothing to do with\n    //    the buttons array and survives `buttons: []` completely. This is the affordance that would have been\n    //    missed: the button row is gone, the mechanism is still live.\n    // 2b. …and a 'button' COLUMN is downgraded to plain text. Stripping its detailsConfig makes it inert, but it\n    //     still RENDERS as a button — a chip the eye reads as clickable that now silently does nothing when\n    //     clicked. Removing the mechanism and leaving the affordance is the same defect as the reverse, just\n    //     pointing the other way, so the affordance goes too. Observed live on the chart of accounts, whose Name\n    //     column is exactly this. 'chip' / 'chips' / 'monogram' are left alone: those are legitimate READINGS of\n    //     a value (a status pill, a person's initials) that merely happen to be drillable, and Column's own\n    //     contract already makes them inert without a detailsConfig to drill into.\n    columns: (source.columns ?? []).map(c => ({ ...c, detailsConfig: undefined, type: c.type === 'button' ? 'text' as const : c.type })),\n\n    // 3. sectionConfig.buttons — bulk buttons drawn in the flat section header (table.component.html:13).\n    sectionConfig: undefined,\n\n    // 4. groupConfig — headerButtons, contextMenuEnabled, dragEnabled and dropAction (a POST fired on drop).\n    groupConfig: undefined,\n\n    // 4b. …which means a config declaring viewType 'grouped' would now render a group view with no group config.\n    //     A dialog list is a list: fix the presentation to the shape the paginator, filter and empty state were\n    //     all designed against.\n    viewType: 'table',\n\n    // 5-7. the three header icons: the import wizard (writes), upload (POSTs a file), download (exports).\n    import: undefined,\n    upload: undefined,\n    download: undefined,\n\n    // 8. inline row editing — cells swap to live editors with save/cancel icons (table.component.html:104,122-126).\n    inlineEdit: false,\n\n    // 9. one-step create — a nested tab that collects child rows against the parent.\n    createConfig: undefined,\n\n    // 10. formConfig — the form every create/edit dialog would have opened, plus the source of inline fields.\n    formConfig: undefined,\n    allowUserKeepOpen: false,\n\n    // 11-12. THESE TWO ARE NOT NEUTRALISED BY `undefined`. table.component.ts:234 and :238 fall back to the\n    //     app-wide runtime tableDefaults whenever the config leaves them undefined, and grip already ships\n    //     tableDefaults.realTime = true. So they must be an explicit false. offline is the sharper one: the\n    //     customers config declares offline.queue { create, edit, delete } — an offline WRITE QUEUE.\n    realTime: false,\n    offline: false,\n\n    // 13. tab-visibility predicates, written against a parent record that does not exist inside this dialog.\n    //     Left set, they can evaluate false and hide the whole table — an empty dialog with no error, which is\n    //     precisely the silent-success shape this codebase keeps being bitten by.\n    hidden: undefined,\n    visible: undefined,\n\n    // 14. lazyLoad only defers `&& inTab` (table.component.ts:637) so it is inert here, but an explicit false\n    //     makes a dialog that never issues its load impossible rather than merely unlikely.\n    lazyLoad: false,\n\n    // 15-17. tiles and search are clickable and read-only, but both cost vertical space a dialog does not have;\n    //     spa-steps is indicator-only and means nothing without the flow around it.\n    tileConfig: undefined,\n    searchConfig: undefined,\n    stepConfig: undefined,\n\n    // Presentation: the dialog surface IS the frame, so the table must not draw a second one inside it.\n    elevation: 'none',\n    noDataMessage: source.noDataMessage ?? 'Nothing here yet.',\n  };\n}\n\n@Component({\n  selector: 'spa-table-dialog',\n  templateUrl: './table-dialog.component.html',\n  styleUrls: ['./table-dialog.component.css'],\n  standalone: false\n})\nexport class TableDialogComponent {\n\n  config: TableConfig;\n\n  constructor(private dialogRef: MatDialogRef<TableDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: TableDialogConfig) {\n    // Hardened at construction, not in ngOnInit: there is no window in which the template can bind the raw config.\n    this.config = readOnlyTableConfig(this.data?.config);\n  }\n\n  close() {\n    this.dialogRef.close();\n  }\n}\n","<!-- Added: read-only entity list in a dialog. Shell follows the import-dialog / details-dialog conventions —\n     tin-dlg-head band header (which the modern dialog style picks up, and which degrades to a plain header when\n     the app has not opted in), scrollable mat-dialog-content, banded left-aligned mat-dialog-actions footer.\n     No subtitle is drawn anywhere: tin-styles.css:886 records that the details dialog's band subtitle was removed\n     on request as noise, and the read-only note that used to carry it was itself removed on 2026-08-19. The body\n     therefore opens straight onto the table's filter row. -->\n<div class=\"tbldlg\">\n\n  <div class=\"tin-dlg-head tbldlg-head\">\n    <h2 class=\"tin-dlg-title\">{{ data?.title || 'Records' }}</h2>\n    <button mat-icon-button (click)=\"close()\" aria-label=\"Close\"><mat-icon>close</mat-icon></button>\n  </div>\n\n  <mat-dialog-content class=\"mat-typography tbldlg-content\">\n\n    <!-- Changed: the read-only annotation bar (eye icon + \"Read only. Use Go to page to add or change anything.\")\n         was REMOVED on the owner's instruction — \"no one needs to read that\". The vacated space is reclaimed, so\n         the table's own filter row now sits at the top of the dialog body. Read-only ENFORCEMENT is untouched:\n         readOnlyTableConfig() in table-dialog.component.ts still strips every mutator by name. -->\n    <spa-table [config]=\"config\"></spa-table>\n\n  </mat-dialog-content>\n\n  <mat-dialog-actions>\n    <button mat-stroked-button color=\"primary\" (click)=\"close()\">Close</button>\n  </mat-dialog-actions>\n\n</div>\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { Field, Action, ApiResponse } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Changed: central visibility resolver\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: option loads fail the same HTTP-200 way — classify so a leaked SQL fragment never reaches a dropdown label\n\n@Component({\n    selector: 'spa-title-actions',\n    templateUrl: './title-actions.component.html',\n    styleUrls: ['./title-actions.component.css'],\n    standalone: false\n})\nexport class TitleActionsComponent implements OnInit {\n\n  constructor(\n    private dataService: DataServiceLib,\n    private messageService: MessageService,\n    private apiErrorService: ApiErrorService // Added: routes application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n  ) { }\n\n  ngOnInit(): void {\n    // Load options for select/multi-select fields with loadAction\n    this.titleActions?.forEach(action => {\n      if (action.loadAction && (action.type === 'select' || action.type === 'select-multi')) { // Changed: multi-select -> select-multi\n        this.loadActionOptions(action);\n      }\n    });\n\n    // Set default values\n    this.titleActions?.forEach(action => {\n      if (action.defaultValue !== undefined && this.actionValues[action.name] === undefined) {\n        this.actionValues[action.name] = action.defaultValue;\n      }\n    });\n  }\n\n  @Input() titleActions: Field[] = [];\n  @Output() actionChange = new EventEmitter<{ name: string, value: any }>();\n\n  // Store values for each action\n  actionValues: { [key: string]: any } = {};\n\n  // Load options for select/multi-select fields\n  private loadActionOptions(action: Field) {\n    if (!action.loadAction) return;\n\n    this.dataService.CallApi(action.loadAction).subscribe((apiResponse: ApiResponse) => {\n      if (apiResponse.success) {\n        action.options = apiResponse.data;\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'load', action.loadAction!.url); // Changed: dropdown option load — a leaked SQL fragment was being shown where the user expected a list of choices\n      }\n    });\n  }\n\n  // Handle value changes for any action type\n  onActionChange(action: Field, value: any) {\n    this.actionValues[action.name] = value;\n    \n    // Call custom onChange callback if provided\n    if (action.onChange) {\n      action.onChange(value, this.actionValues);\n    }\n    \n    // Emit event to parent component\n    this.actionChange.emit({\n      name: action.name,\n      value: value\n    });\n  }\n\n  // Handle button clicks\n  onButtonClick(action: Field) {\n    // Call custom onChange callback if provided\n    if (action.onChange) {\n      action.onChange(null, this.actionValues);\n    }\n    \n    // Emit event with current value (null for buttons)\n    this.actionChange.emit({\n      name: action.name,\n      value: null\n    });\n  }\n\n  // Get display value for options\n  getOptionDisplay(action: Field): string {\n    return action.optionDisplay ?? 'name';\n  }\n\n  // Get value field for options\n  getOptionValue(action: Field): string {\n    return action.optionValue ?? 'value';\n  }\n\n  // Check if action should be hidden\n  isHidden(action: Field): boolean {\n    return !Core.isItemVisible(action, this.actionValues); // Changed: unified visible/hidden replaces hidden + hiddenCondition\n  }\n\n  // Check if action should be readonly\n  isReadonly(action: Field): boolean {\n    if (action.readonly) return true;\n    if (action.readonlyCondition) {\n      return action.readonlyCondition(this.actionValues);\n    }\n    return false;\n  }\n\n  // Get value for a field\n  getValue(action: Field): any {\n    return this.actionValues[action.name];\n  }\n\n  // Set value for a field\n  setValue(action: Field, value: any) {\n    this.actionValues[action.name] = value;\n  }\n}\n","<div class=\"title-actions-container\" *ngIf=\"titleActions && titleActions.length > 0\">\n  \n  <ng-container *ngFor=\"let action of titleActions\">\n    \n    <!-- Date Field -->\n    <spa-date \n      *ngIf=\"action.type === 'date' && !isHidden(action)\"\n      [display]=\"action.alias ?? action.name | camelToWords\"\n      [width]=\"action.width\"\n      [(value)]=\"actionValues[action.name]\"\n      [required]=\"action.required\"\n      [readonly]=\"isReadonly(action)\"\n      [hint]=\"action.hint\"\n      (valueChange)=\"onActionChange(action, actionValues[action.name])\">\n    </spa-date>\n\n    <!-- DateTime Field -->\n    <spa-datetime \n      *ngIf=\"action.type === 'datetime' && !isHidden(action)\"\n      [display]=\"action.alias ?? action.name | camelToWords\"\n      [width]=\"action.width\"\n      [(value)]=\"actionValues[action.name]\"\n      [readonly]=\"isReadonly(action)\"\n      (valueChange)=\"onActionChange(action, actionValues[action.name])\">\n    </spa-datetime>\n\n    <!-- Select Field -->\n    <spa-select \n      *ngIf=\"action.type === 'select' && !isHidden(action)\"\n      [display]=\"action.alias ?? action.name | camelToWords\"\n      [width]=\"action.width\"\n      [nullable]=\"action.nullable\"\n      [options]=\"action.options\"\n      [optionDisplay]=\"getOptionDisplay(action)\"\n      [optionValue]=\"getOptionValue(action)\"\n      [(value)]=\"actionValues[action.name]\"\n      [defaultFirstValue]=\"action.defaultFirstValue\"\n      [required]=\"action.required\"\n      [readonly]=\"isReadonly(action)\"\n      [hint]=\"action.hint\"\n      (valueChange)=\"onActionChange(action, actionValues[action.name])\">\n    </spa-select>\n\n    <!-- Multi-Select Field -->\n    <spa-select-multi \n      *ngIf=\"action.type === 'select-multi' && !isHidden(action)\"\n      [display]=\"action.alias ?? action.name | camelToWords\"\n      [width]=\"action.width\"\n      [options]=\"action.options\"\n      [optionDisplay]=\"getOptionDisplay(action)\"\n      [optionValue]=\"getOptionValue(action)\"\n      [(value)]=\"actionValues[action.name]\"\n      [required]=\"action.required\"\n      [readonly]=\"isReadonly(action)\"\n      [hint]=\"action.hint\"\n      (valueChange)=\"onActionChange(action, actionValues[action.name])\">\n    </spa-select-multi>\n\n    <!-- Checkbox Field -->\n    <spa-check \n      *ngIf=\"action.type === 'checkbox' && !isHidden(action)\"\n      [display]=\"action.alias ?? action.name | camelToWords\"\n      [(value)]=\"actionValues[action.name]\"\n      [readonly]=\"isReadonly(action)\"\n      (valueChange)=\"onActionChange(action, actionValues[action.name])\">\n    </spa-check>\n\n    <!-- Button Field -->\n    <button \n      *ngIf=\"action.type === 'button' && !isHidden(action)\"\n      mat-icon-button\n      [disabled]=\"isReadonly(action)\"\n      [matTooltip]=\"action.hint ?? (action.alias ?? action.name | camelToWords)\"\n      matTooltipPosition=\"above\"\n      [color]=\"action.color ?? 'primary'\"\n      (click)=\"onButtonClick(action)\">\n      <mat-icon *ngIf=\"action.icon\">{{action.icon.name}}</mat-icon>\n      <span *ngIf=\"!action.icon\">{{action.alias ?? action.name | camelToWords}}</span>\n    </button>\n\n  </ng-container>\n\n</div>\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { ApiResponse, PageConfig, TableConfig } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { Subject } from 'rxjs';\nimport { MessageService } from '../../services/message.service';\n\n@Component({\n    selector: 'spa-page',\n    templateUrl: './page.component.html',\n    styleUrls: ['./page.component.css'],\n    standalone: false\n})\nexport class PageComponent implements OnInit {\n\n  constructor(public dataServiceLib: DataServiceLib, private messageService: MessageService,) { }\n\n  ngOnInit(): void {\n\n    this.normalTableConfig = this.getNormalTableConfig();\n    this.searchTableConfig = this.getSearchTableConfig();\n\n  }\n\n  @Input() config: PageConfig = new PageConfig();\n  @Output() searchModeActivated = new EventEmitter();\n  @Output() searchModeDeactivated = new EventEmitter();\n  @Output() refreshClick = new EventEmitter();\n  @Output() actionClick = new EventEmitter();\n  @Output() actionResponse = new EventEmitter();\n  @Output() inputChange = new EventEmitter();\n  @Output() createClick = new EventEmitter();\n  @Output() searchClick = new EventEmitter();\n  @Output() dataLoad = new EventEmitter();\n  @Output() titleActionChange = new EventEmitter<{ name: string, value: any }>();\n\n  tableReload: Subject<boolean> = new Subject();\n\n  searchMode = false;\n\n  normalTableConfig: TableConfig;\n  searchTableConfig: TableConfig;\n\n  toggleSearch() {\n    if (this.searchMode) {\n      this.searchModeActivated.emit();\n    }\n    else{\n      this.searchModeDeactivated.emit();\n    }\n  }\n\n\n  titleActionChanged(event: { name: string, value: any }) {\n    this.titleActionChange.emit(event);\n  }\n\n\n\n  getNormalTableConfig() : TableConfig {\n    return {\n      ...this.config.tableConfig,\n      searchConfig: null\n    }\n  }\n\n\n  getSearchTableConfig() : TableConfig {\n\n    return {\n      ...this.config.searchTableConfig,\n      loadAction: null,\n      showFilter: false,\n      holdHeaderButtonSpace: true,\n    }\n\n  }\n\n  refreshClicked(){\n    this.refreshClick.emit();\n  }\n\n  actionClicked(x){\n    this.actionClick.emit(x);\n  }\n\n  actionResponded(x){\n    this.actionResponse.emit(x);\n  }\n\n  inputChanged(x){\n    this.inputChange.emit(x);\n  }\n\n  createClicked(x){\n    this.createClick.emit(x);\n  }\n\n  searchClicked(x){\n    this.searchClick.emit(x);\n  }\n\n  dataLoaded(x){\n    this.dataLoad.emit(x);\n  }\n\n}\n","<div class=\"row\">\n\n  <div class=\"col-auto\">\n    <h4>{{config.title ?? 'Untitled'}} </h4>\n  </div>\n\n  <div class=\"col d-flex justify-content-end align-items-center\" style=\"font-size: 14px; gap: 15px;\">\n    <!-- Added: Title actions component -->\n    <spa-title-actions \n      *ngIf=\"config.titleActions\" \n      [titleActions]=\"config.titleActions\"\n      (actionChange)=\"titleActionChanged($event)\">\n    </spa-title-actions>\n    \n    <spa-check *ngIf=\"config.searchTableConfig\" [(value)]=\"searchMode\" display=\"Search Mode\" (valueChange)=\"toggleSearch()\" style=\"margin-right: 10px;\"></spa-check>\n  </div>\n\n</div>\n\n<hr style=\"margin-top: 0px;\" />\n\n\n<div style=\" font-size: 14px;\">\n  <!-- Normal -->\n  <spa-table *ngIf=\"!searchMode\"  [config]=\"normalTableConfig\" [reload]=\"tableReload\"\n    (refreshClick)=\"refreshClicked()\" (actionClick)=\"actionClicked($event)\" (actionResponse)=\"actionResponded($event)\"\n    (inputChange)=\"inputChanged($event)\" (createClick)=\"createClicked($event)\" (searchClick)=\"searchClicked($event)\" (dataLoad)=\"dataLoaded($event)\">\n  </spa-table>\n\n  <!-- Search -->\n  <spa-table *ngIf=\"searchMode\" [config]=\"searchTableConfig\" [reload]=\"tableReload\"\n    (refreshClick)=\"refreshClicked()\" (actionClick)=\"actionClicked($event)\" (actionResponse)=\"actionResponded($event)\"\n    (inputChange)=\"inputChanged($event)\" (createClick)=\"createClicked($event)\" (searchClick)=\"searchClicked($event)\" (dataLoad)=\"dataLoaded($event)\">\n  </spa-table>\n</div>\n\n","import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';\n\n@Directive({\n    selector: '[selectContext]',\n    standalone: false\n})\nexport class SelectContextDirective {\n  constructor(\n    private templateRef: TemplateRef<any>,\n    private viewContainer: ViewContainerRef\n  ) { }\n\n  @Input() set selectContext(context: any) {\n    this.viewContainer.clear();\n    this.viewContainer.createEmbeddedView(this.templateRef, context);\n  }\n}\n","import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\nimport { BitwiseOption, Icon } from '../../classes/Classes';\nimport { derivePlaceholder } from '../../runtime/field-placeholder'; // Added: one shared derivation of the resting placeholder per component type\n\n@Component({\n    selector: 'spa-select-bitwise',\n    templateUrl: './select-bitwise.component.html',\n    styleUrls: ['./select-bitwise.component.css'],\n    standalone: false\n})\nexport class SelectBitwiseComponent implements OnInit {\n\n  @Input() display = '';\n  @Input() placeholder = ''; // Added: this component declared no placeholder input, so with the label now permanently floated its empty state was a blank box with no affordance at all\n  // Added: derived resting placeholder. A bitwise field is a multi-select — picked from a list, never typed — so it\n  // takes the same \"Select\" verb as spa-select and spa-select-multi.\n  get computedPlaceholder(): string { return derivePlaceholder('select', this.display, this.placeholder, this.readonly); }\n  @Input() hint = '';\n  @Input() required = false;\n  @Input() readonly = false;\n  @Input() width = '100%';\n  @Input() infoMessage: string;\n  @Input() options: { name?: string; value: number; icon?: Icon; }[] = [];\n\n  @Input() set value(val: number) {\n    this._value = val;\n    this.updateSelectedValues();\n  }\n  get value(): number {\n    return this._value;\n  }\n\n  @Output() valueChange = new EventEmitter<number>();\n  @Output() infoClick = new EventEmitter<void>();\n\n  private _value = 0;\n  bitwiseOptions: BitwiseOption[] = [];\n  selectedValues: number[] = [];\n  hasNames = false;  // Flag to track if options have names\n\n  // Changed: materialized — a getter returning .filter() allocated a new array on every change-detection cycle\n  selectedOptions: BitwiseOption[] = [];\n\n  private buildSelectedOptions() {\n    this.selectedOptions = this.bitwiseOptions.filter(opt => this.selectedValues.includes(opt.value));\n  }\n\n  ngOnInit() {\n    this.bitwiseOptions = this.options.map(opt => ({\n      ...opt,\n      selected: false\n    }));\n    // Check if any options have names\n    this.hasNames = this.options.some(opt => !!opt.name);\n    this.updateSelectedValues();\n  }\n\n  onSelectionChange(event: any) {\n    const newValue = this.selectedValues.reduce((acc, curr) => acc | curr, 0);\n    this._value = newValue;\n    this.buildSelectedOptions(); // Added: the user changed the selection — rebuild the materialized list\n    this.valueChange.emit(newValue);\n  }\n\n  private updateSelectedValues() {\n    this.selectedValues = this.options\n      .filter(opt => (this._value & opt.value) === opt.value)\n      .map(opt => opt.value);\n    this.buildSelectedOptions(); // Added: selected values changed — rebuild the materialized list\n  }\n\n  onInfoClick(event: MouseEvent): void {\n    event.stopPropagation();\n    this.infoClick.emit();\n  }\n}\n","<mat-form-field [ngStyle]=\"{'width':width ?? '100%'}\" subscriptSizing=\"dynamic\">\n  <mat-label>{{display}}</mat-label>\n\n  <mat-select multiple [placeholder]=\"computedPlaceholder\" [(ngModel)]=\"selectedValues\" (selectionChange)=\"onSelectionChange($event)\" [required]=\"required\" [disabled]=\"readonly\">\n    <mat-option *ngFor=\"let option of bitwiseOptions\" [value]=\"option.value\">\n\n      <mat-icon *ngIf=\"option.icon && !hasNames\" [ngStyle]=\"{'color': option.icon.color}\" [matTooltip]=\"option.icon.tip\" >\n        {{option.icon.name}}\n      </mat-icon>\n\n      <span *ngIf=\"hasNames\">\n        {{option.name}}\n      </span>\n\n    </mat-option>\n  </mat-select>\n\n  <mat-hint *ngIf=\"hint\">{{hint}}</mat-hint>\n\n  <div matSuffix class=\"suffix-icons\">\n\n    <ng-container *ngIf=\"!hasNames\">\n      <mat-icon *ngFor=\"let option of selectedOptions\" [ngStyle]=\"{'color': option.icon?.color, 'margin-right': '4px'}\" style=\"font-size: 14px;\" [matTooltip]=\"option.icon?.tip\">\n        {{option.icon?.name}}\n      </mat-icon>\n    </ng-container>\n\n    <button mat-icon-button *ngIf=\"infoMessage\" (click)=\"onInfoClick($event)\" matTooltip=\"Info\" matTooltipPosition=\"above\">\n      <mat-icon style=\"color: steelblue;\">info</mat-icon>\n    </button>\n\n  </div>\n\n</mat-form-field>\n","// Tin-SPA Welcome Component - Showcases the comprehensive modules and features available in the framework\nimport { Component, OnInit } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { DataServiceLib } from '../../services/datalib.service';\n\n@Component({\n  selector: 'spa-welcome',\n  templateUrl: './welcome.component.html',\n  styleUrls: ['./welcome.component.css'],\n  standalone: false\n})\nexport class WelcomeComponent implements OnInit {\n\n  constructor(private router: Router, public dataService: DataServiceLib) { }\n\n  ngOnInit(): void {\n    this.calculateModuleStats();\n  }\n\n  // Core business modules available in Tin-SPA\n  businessModules = [\n    {\n      name: 'Accounting',\n      icon: this.dataService.capAccounts.icon, // Changed: Use centralized capItem icon\n      description: 'Comprehensive financial management with accounts, transactions, and invoicing',\n      features: [\n        'Chart of Accounts',\n        'Transaction Management',\n        'Invoice Tracking',\n        'Outstanding Payments',\n        'Financial Reports'\n      ],\n      components: 5,\n      demoUrl: this.dataService.capAccounts.link, // Changed: Use centralized capItem link\n      color: '#667eea'\n    },\n    {\n      name: 'Inventory',\n      icon: this.dataService.capInventoryDashboard.icon, // Changed: Use centralized capItem icon\n      description: 'Full inventory lifecycle from procurement to sales and stock management',\n      features: [\n        'Product Catalog',\n        'Stock Management',\n        'Purchase Orders',\n        'Sales Orders',\n        'Inventory Adjustments',\n        'Requisitions',\n        'Real-time Dashboard'\n      ],\n      components: 12,\n      demoUrl: this.dataService.capInventoryDashboard.link, // Changed: Use centralized capItem link\n      color: '#4CAF50'\n    },\n    {\n      name: 'Loans',\n      icon: this.dataService.capLoanProducts.icon, // Changed: Use centralized capItem icon\n      description: 'Loan origination and management for customers and employees',\n      features: [\n        'Loan Products',\n        'Loan Applications',\n        'Payment Tracking',\n        'Interest Calculations',\n        'Outstanding Balances'\n      ],\n      components: 3,\n      demoUrl: this.dataService.capLoanProducts.link, // Changed: Use centralized capItem link\n      color: '#FF9800'\n    },\n    {\n      name: 'Human Resources',\n      icon: this.dataService.capEmployees.icon, // Changed: Use centralized capItem icon\n      description: 'Employee information and organizational structure management',\n      features: [\n        'Employee Records',\n        'Department Management',\n        'Position Tracking',\n        'Employment Status',\n        'User Integration'\n      ],\n      components: 3,\n      demoUrl: this.dataService.capEmployees.link, // Changed: Use centralized capItem link\n      color: '#E91E63'\n    }\n  ];\n\n  // Advanced features demonstrated across modules\n  advancedFeatures = [\n    { \n      name: 'Workflow Automation', \n      modules: 'Accounting, Inventory, Loans',\n      description: 'Status tracking, approval flows, and automated transitions'\n    },\n    { \n      name: 'Dashboard Analytics', \n      modules: 'Inventory, Accounting',\n      description: 'Real-time tiles and KPIs with visual indicators'\n    },\n    { \n      name: 'Document Management', \n      modules: 'All Modules',\n      description: 'File attachments and document tracking'\n    },\n    { \n      name: 'Relationship Management', \n      modules: 'Inventory, Accounting, Loans',\n      description: 'Customer, supplier, and employee linking'\n    },\n    { \n      name: 'Financial Tracking', \n      modules: 'Accounting, Loans, Inventory',\n      description: 'Money fields, calculations, and reporting'\n    },\n    { \n      name: 'Complex Forms', \n      modules: 'All Modules',\n      description: 'Multi-section layouts with conditional fields'\n    },\n    { \n      name: 'Activity Logging', \n      modules: 'All Modules',\n      description: 'Audit trails and notes for all entities'\n    },\n    { \n      name: 'Advanced Search', \n      modules: 'All Modules',\n      description: 'Multi-field filtering with operators'\n    }\n  ];\n\n  // Supporting modules\n  supportingModules = [\n    { name: 'Customers', icon: this.dataService.capCustomers.icon, link: this.dataService.capCustomers.link, description: 'Customer database management' }, // Changed: Use centralized capItem icon and link\n    { name: 'Suppliers', icon: this.dataService.capSuppliers.icon, link: this.dataService.capSuppliers.link, description: 'Supplier relationship management' }, // Changed: Use centralized capItem icon and link\n    { name: 'Brands', icon: this.dataService.capBrands.icon, link: this.dataService.capBrands.link, description: 'Product brand catalog' }, // Changed: Use centralized capItem icon and link\n    { name: 'Categories', icon: this.dataService.capCategories.icon, link: this.dataService.capCategories.link, description: 'Product categorization' }, // Changed: Use centralized capItem icon and link\n    { name: 'Departments', icon: this.dataService.capDepartments.icon, link: this.dataService.capDepartments.link, description: 'Organizational departments' }, // Changed: Use centralized capItem icon and link\n    { name: 'Tasks', icon: this.dataService.capTasks.icon, link: this.dataService.capTasks.link, description: 'Task management system' }, // Changed: Use centralized capItem icon and link\n    { name: 'Approvals', icon: this.dataService.capApprovals.icon, link: this.dataService.capApprovals.link, description: 'Workflow approvals' }, // Changed: Use centralized capItem icon and link\n    { name: 'Notifications', icon: this.dataService.capNotifications.icon, link: this.dataService.capNotifications.link, description: 'System notifications' } // Changed: Use centralized capItem icon and link\n  ];\n\n  // Component features available in Tin-SPA\n  componentFeatures = [\n    { category: 'Form', count: 15, items: 'Text, Money, Date, Select, Multi-Select, Checkbox, File Upload, Email, etc.' },\n    { category: 'Display', count: 13, items: 'Tables, Cards, Capsules, Tiles, Steps, Notes, Chips, Icons, etc.' },\n    { category: 'Layout', count: 5, items: 'Sections, Tabs, Multi-Column, Composite Fields, Responsive Design' },\n    { category: 'Actions', count: 8, items: 'Buttons, Dialogs, Workflows, Custom Actions, Bulk Operations' }\n  ];\n\n  moduleStats = {\n    totalModules: 0,\n    totalComponents: 0,\n    totalFeatures: 0\n  };\n\n  navigateTo(url: string): void {\n    this.router.navigate([url]);\n  }\n\n  private calculateModuleStats(): void {\n    this.moduleStats.totalModules = this.businessModules.length;\n    this.moduleStats.totalComponents = this.businessModules.reduce((sum, m) => sum + m.components, 0);\n    this.moduleStats.totalFeatures = this.advancedFeatures.length;\n    \n    console.log(`Tin-SPA Framework Overview:`);\n    console.log(`- ${this.moduleStats.totalModules} Core Business Modules`);\n    console.log(`- ${this.moduleStats.totalComponents} Module Components`);\n    console.log(`- ${this.moduleStats.totalFeatures} Advanced Features`);\n  }\n}\n","<div class=\"welcome-container\">\n  <div class=\"header-section\">\n    <h2>Tin-SPA Business Framework</h2>\n    <p class=\"subtitle\">Comprehensive enterprise modules for Accounting, Inventory, Loans, and HR Management</p>\n  </div>\n\n  <!-- Quick Navigation to Core Modules -->\n  <div class=\"row mb-4\">\n    <div class=\"col-md-12\">\n      <h4>Quick Access</h4>\n      <div class=\"navigation-grid\">\n        <button mat-raised-button (click)=\"navigateTo(dataService.capAccounts.link)\" class=\"nav-button accounting\">\n          <mat-icon>{{dataService.capAccounts.icon}}</mat-icon>\n          Accounting\n        </button>\n        <button mat-raised-button (click)=\"navigateTo(dataService.capInventoryDashboard.link)\" class=\"nav-button inventory\">\n          <mat-icon>{{dataService.capInventoryDashboard.icon}}</mat-icon>\n          Inventory\n        </button>\n        <button mat-raised-button (click)=\"navigateTo(dataService.capLoanProducts.link)\" class=\"nav-button loans\">\n          <mat-icon>{{dataService.capLoanProducts.icon}}</mat-icon>\n          Loans\n        </button>\n        <button mat-raised-button (click)=\"navigateTo(dataService.capEmployees.link)\" class=\"nav-button hr\">\n          <mat-icon>{{dataService.capEmployees.icon}}</mat-icon>\n          Human Resources\n        </button>\n      </div>\n    </div>\n  </div>\n\n  <!-- Core Business Modules -->\n  <div class=\"row mb-4\">\n    <div class=\"col-md-12\">\n      <h4>Core Business Modules</h4>\n      <div class=\"row\">\n        <div class=\"col-md-6 mb-3\" *ngFor=\"let module of businessModules\">\n          <div class=\"module-card\" (click)=\"navigateTo(module.demoUrl)\" [style.border-left]=\"'4px solid ' + module.color\">\n            <div class=\"module-header\">\n              <mat-icon [style.color]=\"module.color\" class=\"module-icon\">{{module.icon}}</mat-icon>\n              <div class=\"module-title\">\n                <h5>{{module.name}}</h5>\n                <span class=\"component-count\">{{module.components}} Components</span>\n              </div>\n            </div>\n            <div class=\"module-content\">\n              <p class=\"module-description\">{{module.description}}</p>\n              <div class=\"features-list\">\n                <span class=\"feature-tag\" *ngFor=\"let feature of module.features\">\n                  <mat-icon class=\"feature-icon\">check_circle</mat-icon>\n                  {{feature}}\n                </span>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Quick Navigation to Core Modules -->\n  <div class=\"row mb-4\">\n    <div class=\"col-md-12\">\n      <h4>Advanced Features Across Modules</h4>\n      <div class=\"features-grid\">\n        <div class=\"feature-item\" *ngFor=\"let feature of advancedFeatures\">\n          <div class=\"feature-name\">{{feature.name}}</div>\n          <div class=\"feature-modules\">\n            <mat-icon class=\"small-icon\">widgets</mat-icon>\n            {{feature.modules}}\n          </div>\n          <div class=\"feature-description\">{{feature.description}}</div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Supporting Modules -->\n  <div class=\"row mb-4\">\n    <div class=\"col-md-12\">\n      <h4>Supporting Modules</h4>\n      <div class=\"supporting-grid\">\n        <div class=\"support-item\" *ngFor=\"let support of supportingModules\" (click)=\"navigateTo(support.link)\">\n          <mat-icon>{{support.icon}}</mat-icon>\n          <div class=\"support-details\">\n            <div class=\"support-name\">{{support.name}}</div>\n            <div class=\"support-description\">{{support.description}}</div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <!-- Module Details Sections -->\n  <div class=\"row\">\n    <div class=\"col-md-12\">\n      <h4>Module Details</h4>\n      \n      <!-- Accounting Details -->\n      <div class=\"detail-section\">\n        <div class=\"detail-header\">\n          <mat-icon style=\"color: #667eea\">account_balance</mat-icon>\n          <h5>Accounting Module</h5>\n        </div>\n        <p>\n          The Accounting module provides comprehensive financial management capabilities including:\n        </p>\n        <ul>\n          <li><strong>Chart of Accounts:</strong> Hierarchical account structure with categories and types</li>\n          <li><strong>Transactions:</strong> Record debits and credits with full audit trail</li>\n          <li><strong>Invoicing:</strong> Create and track invoices with multiple status workflows</li>\n          <li><strong>Outstanding Management:</strong> Monitor and manage outstanding payments</li>\n          <li><strong>Financial Reporting:</strong> Real-time financial summaries and analytics</li>\n        </ul>\n      </div>\n\n      <!-- Inventory Details -->\n      <div class=\"detail-section\">\n        <div class=\"detail-header\">\n          <mat-icon style=\"color: #4CAF50\">inventory</mat-icon>\n          <h5>Inventory Module</h5>\n        </div>\n        <p>\n          The Inventory module covers the complete inventory lifecycle from procurement to sales:\n        </p>\n        <ul>\n          <li><strong>Product Management:</strong> Catalog with categories, brands, and pricing</li>\n          <li><strong>Stock Control:</strong> Real-time stock levels with location tracking</li>\n          <li><strong>Purchase Orders:</strong> Supplier ordering with receipt management</li>\n          <li><strong>Sales Orders:</strong> Customer orders with fulfillment tracking</li>\n          <li><strong>Requisitions:</strong> Internal requests and transfers between locations</li>\n          <li><strong>Adjustments & Returns:</strong> Stock adjustments and return processing</li>\n          <li><strong>Dashboard:</strong> Visual analytics with tiles showing key metrics</li>\n        </ul>\n      </div>\n\n      <!-- Loans Details -->\n      <div class=\"detail-section\">\n        <div class=\"detail-header\">\n          <mat-icon style=\"color: #FF9800\">payments</mat-icon>\n          <h5>Loans Module</h5>\n        </div>\n        <p>\n          The Loans module enables loan origination and management for both customers and employees:\n        </p>\n        <ul>\n          <li><strong>Loan Products:</strong> Define loan types with interest rates and terms</li>\n          <li><strong>Loan Applications:</strong> Customer and employee loan processing</li>\n          <li><strong>Payment Tracking:</strong> Record and monitor loan payments</li>\n          <li><strong>Interest Calculations:</strong> Automated interest computation based on method</li>\n          <li><strong>Outstanding Balances:</strong> Real-time balance and status monitoring</li>\n        </ul>\n      </div>\n\n      <!-- HR Details -->\n      <div class=\"detail-section\">\n        <div class=\"detail-header\">\n          <mat-icon style=\"color: #E91E63\">diversity_3</mat-icon>\n          <h5>Human Resources Module</h5>\n        </div>\n        <p>\n          The HR module manages employee information and organizational structure:\n        </p>\n        <ul>\n          <li><strong>Employee Records:</strong> Comprehensive employee database with demographics</li>\n          <li><strong>Department Management:</strong> Organizational department structure</li>\n          <li><strong>Position Tracking:</strong> Job positions and hierarchies</li>\n          <li><strong>Employment Status:</strong> Track employment and active status</li>\n          <li><strong>User Integration:</strong> Link employees to system user accounts</li>\n        </ul>\n      </div>\n    </div>\n  </div>\n\n  <!-- Footer -->\n  <div class=\"footer-section mt-5\">\n    <p class=\"text-center\">\n      <strong>Tin-SPA Business Framework</strong> - Enterprise-grade modules for complete business management\n      <br>\n      <small>Built with Angular Material and designed for scalability and extensibility</small>\n    </p>\n  </div>\n</div>\n","import { Component, Input, OnChanges, OnInit } from '@angular/core'; // Changed: OnChanges added — the chart cache is invalidated when inputs change\nimport { Action, ChartConfig, ChartItem, ApiResponse } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore'; // Changed: central visibility resolver\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: charts sit on the same dashboards as tiles/tables, so they must share the classify + dedupe path or they leak raw text beside the friendly dialog\nimport { Subject } from 'rxjs';\nimport { Chart, ChartData, ChartOptions, Plugin } from 'chart.js'; // Changed: Added Chart import for animation control\n// Removed (sweep-1, 2026-08-20): the `chartjs-plugin-datalabels` import was DEAD — ChartDataLabels was\n// imported here and never registered or referenced anywhere in the library, so it was tree-shaken out of\n// the shipped bundle. It was also an ARMED TRAP: the package is declared in NEITHER tin-spa's dependencies\n// NOR its peerDependencies, and it is absent from all five consumer apps' node_modules (it resolves only\n// inside ng-space, which is why test-spa never noticed). Registering it would have added an external import\n// of an uninstallable package and broken every consumer at once. The pie/doughnut callouts this was meant\n// for are drawn by OuterCalloutPlugin below instead — see the `datalabels: { display: false }` options.\n\n// Changed: Callout plugin — projects labels strictly left/right to maximize pie vertical space\nconst OuterCalloutPlugin: Plugin = {\n  id: 'outerCallout',\n  afterDraw: (chart: any) => {\n    const { ctx } = chart;\n    const meta = chart.getDatasetMeta(0);\n    if (!meta?.data?.length) return;\n\n    const dataset = chart.data.datasets[0];\n    const total = dataset.data.reduce((a: number, b: number) => a + b, 0);\n    if (total === 0) return;\n\n    const labels = chart.data.labels || [];\n    const colors = dataset.backgroundColor || [];\n\n    // Changed: Reset clip region so callout labels can draw in the padding area outside chartArea\n    ctx.save();\n    ctx.resetTransform();\n    ctx.beginPath();\n    ctx.rect(0, 0, chart.canvas.width, chart.canvas.height);\n    ctx.clip();\n    const dpr = window.devicePixelRatio || 1;\n    ctx.scale(dpr, dpr);\n\n    // Changed: Collect callout items per side, then space vertically to avoid overlap\n    const leftItems: any[] = [];\n    const rightItems: any[] = [];\n\n    meta.data.forEach((arc: any, i: number) => {\n      const value = dataset.data[i];\n      const pct = Math.round((value / total) * 100);\n      if (pct < 5) return; // Changed: Skip tiny segments\n\n      const midAngle = (arc.startAngle + arc.endAngle) / 2;\n      const outerRadius = arc.outerRadius;\n      const cx = arc.x;\n      const cy = arc.y;\n      const edgeX = cx + Math.cos(midAngle) * outerRadius;\n      const edgeY = cy + Math.sin(midAngle) * outerRadius;\n      const isRight = Math.cos(midAngle) >= 0; // Changed: Use cos to determine left/right\n      const color = Array.isArray(colors) ? colors[i % colors.length] : '#333';\n      const item = { edgeX, edgeY, cx, cy, outerRadius, pct, label: labels[i] ? String(labels[i]) : '', color, isRight };\n      if (isRight) rightItems.push(item); else leftItems.push(item);\n    });\n\n    // Changed: Sort by Y and enforce minimum vertical gap between labels\n    leftItems.sort((a: any, b: any) => a.edgeY - b.edgeY);\n    rightItems.sort((a: any, b: any) => a.edgeY - b.edgeY);\n    // Changed: Space labels vertically — minimum 16px (single row needs less gap)\n    const spaceLabels = (items: any[]) => {\n      const minGap = 16;\n      for (let j = 1; j < items.length; j++) {\n        if (items[j].edgeY - items[j - 1].edgeY < minGap) {\n          items[j].edgeY = items[j - 1].edgeY + minGap;\n        }\n      }\n    };\n    spaceLabels(leftItems);\n    spaceLabels(rightItems);\n\n    // Changed: Draw callouts — label name and percentage on the SAME row, side by side\n    const drawSide = (items: any[]) => {\n      items.forEach((item: any) => {\n        const { edgeX, edgeY, cx, outerRadius, pct, label, color, isRight } = item;\n\n        // Changed: Connector endpoint near the pie edge\n        const tailX = isRight ? cx + outerRadius + 16 : cx - outerRadius - 16;\n        const tailY = edgeY;\n\n        // Changed: Draw connector line from arc edge to label area\n        ctx.beginPath();\n        ctx.moveTo(edgeX, edgeY);\n        ctx.lineTo(tailX, tailY);\n        ctx.strokeStyle = '#999';\n        ctx.lineWidth = 1;\n        ctx.stroke();\n\n        // Changed: Same row — percentage near pie, label name further out\n        ctx.textBaseline = 'middle';\n        const textX = tailX + (isRight ? 4 : -4);\n\n        // Changed: Percentage closest to pie — bold, segment-colored\n        ctx.font = 'bold 12px Arial';\n        ctx.fillStyle = color;\n        ctx.textAlign = isRight ? 'left' : 'right';\n        ctx.fillText(pct + '%', textX, tailY);\n\n        // Changed: Label name next to percentage — muted\n        if (label) {\n          ctx.font = '11px Arial';\n          ctx.fillStyle = '#888';\n          if (isRight) {\n            const pctWidth = ctx.measureText(pct + '%').width;\n            ctx.textAlign = 'left';\n            ctx.fillText(label, textX + pctWidth + 4, tailY); // Changed: Right of percentage\n          } else {\n            const pctWidth = ctx.measureText(pct + '%').width;\n            ctx.textAlign = 'right';\n            ctx.fillText(label, textX - pctWidth - 4, tailY); // Changed: Left of percentage\n          }\n        }\n      });\n    };\n\n    drawSide(leftItems);\n    drawSide(rightItems);\n    ctx.restore();\n  }\n};\n\n@Component({\n    selector: 'spa-charts',\n    templateUrl: './charts.component.html',\n    styleUrls: ['./charts.component.css'],\n    standalone: false\n})\nexport class ChartsComponent implements OnInit, OnChanges { // Changed: OnChanges — invalidate the chart cache when inputs change\n\n  constructor(private dataService: DataServiceLib, private messageService: MessageService, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService for application-level (HTTP 200, success:false) failures\n\n  @Input() config: ChartConfig;\n  @Input() data: any;\n  @Input() reload: Subject<boolean>;\n\n  ngOnInit(): void {\n    // Auto-load data on init if configured\n    if (this.config?.loadAction && this.config.loadInit) {\n      this.loadData(this.config.loadAction, '');\n    }\n\n    // Subscribe to reload trigger from parent\n    if (this.reload) {\n      this.reload.subscribe(v => {\n        if (v == true) {\n          if (this.config?.loadAction) {\n            this.loadData(this.config.loadAction, '');\n          }\n        }\n      });\n    }\n  }\n\n  // Load chart data from API endpoint\n  loadData(action: Action, data: any) {\n    if (action) {\n      this.dataService.CallApi(action, data).subscribe((apiResponse: ApiResponse) => {\n        if (apiResponse.success) {\n          this.data = apiResponse.data;\n          this.chartCache = new WeakMap(); // Added: data is set imperatively here (not via @Input), so ngOnChanges will not fire — invalidate explicitly\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'load', action.url); // Changed: verified in the browser — with tiles/tables converted but this left raw, one broken dashboard showed the friendly dialog AND a raw \"Error: Error processing request\" toast side by side\n        }\n      });\n    }\n  }\n\n  // Added: stable-reference cache — getChartData/getChartOptions are bound to ng2-charts [data]/[options],\n  // so returning a fresh object every change-detection cycle re-triggered the chart's ngOnChanges forever.\n  // Mirrors the WeakMap cache already used by tiles.component (getChartCache).\n  private chartCache = new WeakMap<ChartItem, { data: ChartData, options: ChartOptions, plugins: Plugin[] }>();\n\n  ngOnChanges() {\n    this.chartCache = new WeakMap(); // Added: inputs changed (e.g. [data]) — rebuild once, then stay stable\n  }\n\n  private getCache(chart: ChartItem) {\n    let c = this.chartCache.get(chart);\n    if (!c) {\n      c = { data: this.buildChartData(chart), options: this.buildChartOptions(chart), plugins: this.buildPlugins(chart) };\n      this.chartCache.set(chart, c);\n    }\n    return c;\n  }\n\n  getChartData(chart: ChartItem): ChartData { return this.getCache(chart).data; } // Changed: now returns a cached, stable reference\n  getChartOptions(chart: ChartItem): ChartOptions { return this.getCache(chart).options; } // Changed: now returns a cached, stable reference\n\n  // Build Chart.js data object for a chart item\n  private buildChartData(chart: ChartItem): ChartData { // Changed: renamed from getChartData — now called only on a cache miss\n    // Gauge mode: auto-generate doughnut data from percentage value\n    if (chart.gaugeValue != null) {\n      return {\n        datasets: [{\n          data: [chart.gaugeValue, 100 - chart.gaugeValue],\n          backgroundColor: [chart.gaugeColor ?? '#4acccd', '#e8e8e8'],\n          borderWidth: 0\n        }]\n      };\n    }\n    // Standard mode: resolve data from API response by chart name, or use pre-loaded data\n    const chartData: any = this.data?.[chart.name] ?? chart.data ?? { labels: [], datasets: [] };\n\n    // Changed: Apply chart.colors to dataset backgroundColor if not already set (ensures pie/doughnut render correctly)\n    if (chart.colors?.length && chartData.datasets?.length) {\n      chartData.datasets.forEach((ds: any) => {\n        if (!ds.backgroundColor) {\n          ds.backgroundColor = chart.colors;\n        }\n      });\n    }\n\n    return chartData;\n  }\n\n  // Changed: Enhanced chart options for all chart types — better styling, datalabels for pie/doughnut\n  private buildChartOptions(chart: ChartItem): ChartOptions { // Changed: renamed from getChartOptions — now called only on a cache miss\n    const options: any = chart.options ?? {};\n\n    options.responsive = true;\n    options.maintainAspectRatio = false;\n\n    // Changed: Animate once on initial load, then disable animation to prevent re-triggering on hover/click\n    options.animation = options.animation ?? {};\n    options.animation.onComplete = function(this: Chart) { this.options.animation = { duration: 0 }; };\n\n    if (chart.type === 'line') {\n      // Changed: Line chart — smooth curves, subtle grid\n      options.elements = options.elements ?? {};\n      options.elements.line = { tension: chart.tension ?? 0.4, borderWidth: 2.5 };\n      options.elements.point = { radius: chart.showPoints ? 4 : 0, hoverRadius: 6, hitRadius: 10 };\n      options.plugins = options.plugins ?? {};\n      options.plugins.legend = chart.showLegend ? { display: true, position: 'bottom', labels: { usePointStyle: true, pointStyle: 'circle', padding: 16, font: { size: 12 } } } : { display: false }; // Changed: Show Chart.js legend only when showLegend is true\n      options.plugins.tooltip = options.plugins.tooltip ?? { mode: 'index', intersect: false, backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };\n      options.plugins.datalabels = { display: false }; // Changed: No datalabels on line charts\n      options.scales = options.scales ?? {};\n      options.scales.x = options.scales.x ?? { grid: { display: false }, ticks: { font: { size: 11 }, color: '#999' } };\n      options.scales.y = options.scales.y ?? { grid: { color: '#f0f0f0', drawBorder: false }, ticks: { font: { size: 11 }, color: '#999' }, border: { display: false } };\n    }\n\n    if (chart.type === 'bar') {\n      // Changed: Bar chart — clean grid, rounded bars\n      options.plugins = options.plugins ?? {};\n      options.plugins.legend = chart.showLegend ? { display: true, position: 'bottom', labels: { usePointStyle: true, pointStyle: 'circle', padding: 16, font: { size: 12 } } } : { display: false }; // Changed: Show Chart.js legend only when showLegend is true\n      options.plugins.tooltip = options.plugins.tooltip ?? { backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };\n      options.plugins.datalabels = { display: false }; // Changed: No datalabels on bar charts\n      options.scales = options.scales ?? {};\n      options.scales.x = options.scales.x ?? { grid: { display: false }, ticks: { font: { size: 11 }, color: '#999' } };\n      options.scales.y = options.scales.y ?? { grid: { color: '#f0f0f0', drawBorder: false }, ticks: { font: { size: 11 }, color: '#999' }, border: { display: false }, beginAtZero: true };\n      options.elements = options.elements ?? {};\n      options.elements.bar = options.elements.bar ?? { borderRadius: 4 }; // Changed: Rounded bar corners\n    }\n\n    if (chart.type === 'pie') {\n      // Changed: Pie chart — outer callout labels, legend always disabled (callout plugin handles labeling)\n      options.plugins = options.plugins ?? {};\n      options.plugins.legend = { display: false };\n      options.plugins.tooltip = options.plugins.tooltip ?? { backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };\n      options.plugins.datalabels = { display: false }; // Changed: Disabled — outerCallout plugin draws labels instead\n      options.layout = options.layout ?? { padding: { top: 10, bottom: 10, left: 70, right: 70 } }; // Changed: Minimal top/bottom — callouts project left/right only\n    }\n\n    if (chart.type === 'doughnut') {\n      // Changed: Doughnut — outer callout labels\n      options.plugins = options.plugins ?? {};\n      if (chart.gaugeValue != null) {\n        // Changed: Gauge mode — no legend, no tooltip, center text via plugin\n        options.plugins.legend = { display: false };\n        options.plugins.tooltip = { enabled: false };\n        options.plugins.datalabels = { display: false };\n        options.cutout = options.cutout ?? '70%';\n        options.layout = options.layout ?? { padding: 10 };\n      } else {\n        // Changed: Standard doughnut — legend always disabled (callout plugin handles labeling)\n        options.plugins.legend = { display: false };\n        options.plugins.tooltip = options.plugins.tooltip ?? { backgroundColor: 'rgba(0,0,0,0.8)', padding: 10, cornerRadius: 6 };\n        options.plugins.datalabels = { display: false }; // Changed: Disabled — outerCallout plugin draws labels\n        options.cutout = options.cutout ?? '50%';\n        options.layout = options.layout ?? { padding: { top: 10, bottom: 10, left: 70, right: 70 } }; // Changed: Minimal top/bottom — callouts project left/right only\n      }\n    }\n\n    return options;\n  }\n\n  getPlugins(chart: ChartItem): Plugin[] { return this.getCache(chart).plugins; } // Changed: cached — [plugins] binding needs a stable reference too\n\n  // Changed: Return Chart.js plugins array — outer callout for pie/doughnut, center text for gauges\n  private buildPlugins(chart: ChartItem): Plugin[] { // Changed: renamed from getPlugins — now called only on a cache miss\n    const plugins: Plugin[] = [];\n\n    // Changed: Add outer callout plugin for pie and doughnut (non-gauge) — draws labels with connector lines\n    if (chart.type === 'pie' || (chart.type === 'doughnut' && chart.gaugeValue == null)) {\n      plugins.push(OuterCalloutPlugin);\n    }\n\n    // Changed: Center text plugin for doughnut gauge — displays percentage inside the ring\n    if (chart.type === 'doughnut' && chart.gaugeValue != null) {\n      plugins.push({\n        id: 'centerText',\n        afterDraw: (chartInstance: any) => {\n          const ctx = chartInstance.ctx;\n          const { width, height } = chartInstance;\n          ctx.save();\n          const text = chart.gaugeValue + '%';\n          ctx.font = 'bold 28px Arial';\n          ctx.fillStyle = chart.gaugeColor ?? '#4acccd';\n          ctx.textAlign = 'center';\n          ctx.textBaseline = 'middle';\n          ctx.fillText(text, width / 2, height / 2);\n          ctx.restore();\n        }\n      });\n    }\n\n    return plugins;\n  }\n\n  // Check if a chart should be hidden\n  isHidden(chart: ChartItem): boolean {\n    return !Core.isItemVisible(chart, this.data); // Changed: unified visible/hidden replaces hidden + hiddenCondition\n  }\n}\n","<div class=\"charts-grid\" [style.--columns]=\"config?.columns\">\n  <ng-container *ngFor=\"let chart of config?.charts\">\n    <mat-card *ngIf=\"!isHidden(chart)\" class=\"chart-card\">\n\n      <!-- Header -->\n      <div class=\"chart-header\" *ngIf=\"chart.title\">\n        <h4 class=\"chart-title\">{{ chart.title }}</h4>\n        <p class=\"chart-subtitle\" *ngIf=\"chart.subtitle\">{{ chart.subtitle }}</p>\n      </div>\n\n      <!-- Chart Area -->\n      <div class=\"chart-body\" [style.height]=\"chart.height ?? '300px'\">\n        <canvas baseChart\n          [type]=\"chart.type\"\n          [data]=\"getChartData(chart)\"\n          [options]=\"getChartOptions(chart)\"\n          [plugins]=\"getPlugins(chart)\">\n        </canvas>\n      </div>\n\n      <!-- Footer -->\n      <div class=\"chart-footer\" *ngIf=\"chart.footer\">\n        <mat-divider></mat-divider>\n        <div class=\"footer-content\">\n          <mat-icon *ngIf=\"chart.footerIcon\">{{ chart.footerIcon }}</mat-icon>\n          <span>{{ chart.footer }}</span>\n        </div>\n      </div>\n\n    </mat-card>\n  </ng-container>\n</div>\n","import { Component, Input, OnInit, AfterViewInit, OnDestroy, HostListener, ElementRef } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser'; // Changed: needed for SVG injection\nimport { Router } from '@angular/router';\nimport { AuthService } from '../../services/auth.service';\nimport { LastRouteService } from '../../services/last-route.service'; // Added: resumeLastRoute\nimport { LandingConfig } from './landing.config';\n\n@Component({\n  selector: 'spa-landing',\n  templateUrl: './landing.component.html',\n  styleUrls: ['./landing.component.css'],\n  standalone: false\n})\nexport class SpaLandingComponent implements OnInit, AfterViewInit, OnDestroy {\n  @Input() config!: LandingConfig;\n\n  mobileMenuOpen = false;\n  navScrolled = false;\n  restoring = false; // Added: silent session restore in flight — template shows the \"Signing you back in\" pill\n  currentYear = new Date().getFullYear(); // Used in footer copyright\n  private observer: IntersectionObserver | null = null;\n\n  constructor(\n    private router: Router,\n    private authService: AuthService,\n    private lastRouteService: LastRouteService, // Added: resumeLastRoute\n    private el: ElementRef,\n    private sanitizer: DomSanitizer // Changed: inject sanitizer for safe SVG rendering\n  ) {}\n\n  // Sanitizes the navBrand SVG string so Angular allows [innerHTML] binding (developer config, not user input)\n  // Changed: inject width/height before sanitising — CSS ::ng-deep cannot reach innerHTML content in library builds\n  get safeNavBrandSvg(): SafeHtml | null {\n    if (!this.config.navBrand?.svgMarkup) return null;\n    const sized = this.config.navBrand.svgMarkup.replace(/^<svg/, '<svg width=\"36\" height=\"36\"');\n    return this.sanitizer.bypassSecurityTrustHtml(sized);\n  }\n\n  // Sanitizes the hero watermark SVG string\n  get safeHeroWatermarkSvg(): SafeHtml | null {\n    return this.config.hero.watermarkSvg\n      ? this.sanitizer.bypassSecurityTrustHtml(this.config.hero.watermarkSvg)\n      : null;\n  }\n\n  // Sanitizes the footer brand SVG string\n  // Changed: inject width/height before sanitising — same encapsulation fix as navBrand\n  get safeFooterBrandSvg(): SafeHtml | null {\n    if (!this.config.footerBrand?.svgMarkup) return null;\n    const sized = this.config.footerBrand.svgMarkup.replace(/^<svg/, '<svg width=\"36\" height=\"36\"');\n    return this.sanitizer.bypassSecurityTrustHtml(sized);\n  }\n\n  ngOnInit(): void {\n    // Apply brand colors as CSS variables on the host element so all child rules inherit them\n    this.applyColors();\n    // Restore session if possible and redirect to home\n    // Changed: with resumeLastRoute on, an already-signed-in visitor lands back on their last page, not 'home'\n    this.restoring = this.authService.hasValidSession() || this.authService.hasRefreshToken(); // Added: a restore will actually run — show the \"Signing you back in\" pill so returning visitors know why\n    this.authService.tryRestoreSession().then(async success => {\n      if (!success) { this.restoring = false; return; } // Changed: restore over — drop the pill and leave the landing page as-is\n      const last = await this.lastRouteService.resolve();\n      this.lastRouteService.navigateTo(last ?? 'home'); // Changed: navigateTo falls back to home if the saved page no longer exists\n    });\n  }\n\n  ngAfterViewInit(): void {\n    // Scroll-triggered fade-in for sections with lp-animate class\n    this.observer = new IntersectionObserver((entries) => {\n      entries.forEach(entry => {\n        if (entry.isIntersecting) entry.target.classList.add('lp-visible');\n      });\n    }, { threshold: 0.1 });\n    // Observe only within this component's DOM to avoid affecting other pages\n    this.el.nativeElement.querySelectorAll('.lp-animate').forEach((el: Element) => {\n      this.observer?.observe(el);\n    });\n  }\n\n  ngOnDestroy(): void {\n    this.observer?.disconnect();\n  }\n\n  @HostListener('window:scroll')\n  onWindowScroll(): void {\n    // Add frosted-glass background to navbar after scrolling past hero\n    this.navScrolled = window.scrollY > 50;\n  }\n\n  scrollToSection(target: string): void {\n    this.mobileMenuOpen = false; // Close mobile menu on nav click\n    const element = document.getElementById(target);\n    element?.scrollIntoView({ behavior: 'smooth' });\n  }\n\n  toggleMobileMenu(): void {\n    this.mobileMenuOpen = !this.mobileMenuOpen;\n  }\n\n  navigateTo(path: string): void {\n    this.router.navigate([path]);\n    this.mobileMenuOpen = false;\n  }\n\n  // Returns light tinted background for feature icon (hex + '20' = ~12% opacity)\n  iconBg(hex: string): string {\n    return hex + '20';\n  }\n\n  // Sets CSS custom properties on host element so child rules use app-specific brand colors\n  private applyColors(): void {\n    const s = this.el.nativeElement.style;\n    const c = this.config.colors;\n    s.setProperty('--lp-primary', c.primary);\n    s.setProperty('--lp-primary-dark', c.primaryDark);\n    s.setProperty('--lp-primary-light', c.primaryLight);\n    s.setProperty('--lp-secondary', c.secondary);\n    s.setProperty('--lp-secondary-light', c.secondaryLight);\n  }\n}\n","<!-- Added: \"Signing you back in\" pill — visible while the silent session restore runs, gone on failure -->\n<div class=\"lp-resume-pill\" *ngIf=\"restoring\" role=\"status\" aria-live=\"polite\">\n  <span class=\"lp-resume-spinner\" aria-hidden=\"true\"></span>\n  <span>Signing you back in…</span>\n</div>\n\n<!-- ===== NAVBAR ===== -->\n<nav class=\"lp-navbar\" [class.lp-navbar-scrolled]=\"navScrolled\">\n  <div class=\"lp-container lp-nav-inner\">\n    <!-- Brand: custom SVG override OR default img+name -->\n    <div class=\"lp-nav-brand\" (click)=\"scrollToSection('lp-hero')\">\n      <ng-container *ngIf=\"config.navBrand; else defaultNavBrand\">\n        <span class=\"lp-nav-brand-svg\" [innerHTML]=\"safeNavBrandSvg\"></span>\n        <div *ngIf=\"config.navBrand.wordmarkLine1\" class=\"lp-nav-brand-wordmark\">\n          <span class=\"lp-nav-wordmark-line1\">{{ config.navBrand.wordmarkLine1 }}</span>\n          <span *ngIf=\"config.navBrand.wordmarkLine2\" class=\"lp-nav-wordmark-line2\">{{ config.navBrand.wordmarkLine2 }}</span>\n        </div>\n      </ng-container>\n      <ng-template #defaultNavBrand>\n        <img [src]=\"config.logoSrc\" [alt]=\"config.appName\" class=\"lp-nav-logo\">\n        <span class=\"lp-nav-brand-text\">{{ config.appName }}</span>\n      </ng-template>\n    </div>\n    <!-- Desktop nav links -->\n    <div class=\"lp-nav-links\">\n      <a *ngFor=\"let link of config.navLinks\" (click)=\"scrollToSection(link.target)\">{{ link.label }}</a>\n    </div>\n    <!-- Mobile menu overlay -->\n    <div class=\"lp-mobile-menu\" [class.lp-mobile-menu-open]=\"mobileMenuOpen\">\n      <a *ngFor=\"let link of config.navLinks\" (click)=\"scrollToSection(link.target)\">{{ link.label }}</a>\n      <div class=\"lp-mobile-auth\">\n        <a class=\"lp-nav-login\" (click)=\"navigateTo('login')\">Log in</a>\n        <button class=\"lp-btn lp-btn-primary\" (click)=\"navigateTo(config.hero.primaryCTARoute || 'signup')\">Get Started</button>\n      </div>\n    </div>\n    <!-- Desktop auth -->\n    <div class=\"lp-nav-auth\">\n      <a class=\"lp-nav-login\" (click)=\"navigateTo('login')\">Log in</a>\n      <button class=\"lp-btn lp-btn-primary lp-btn-sm\" (click)=\"navigateTo(config.hero.primaryCTARoute || 'signup')\">Get Started</button>\n    </div>\n    <!-- Hamburger for mobile -->\n    <button class=\"lp-hamburger\" (click)=\"toggleMobileMenu()\" [class.lp-hamburger-open]=\"mobileMenuOpen\">\n      <span></span><span></span><span></span>\n    </button>\n  </div>\n</nav>\n\n<!-- ===== HERO ===== -->\n<section id=\"lp-hero\" class=\"lp-hero-bg\" [class.lp-hero-split]=\"config.hero.layout === 'split'\">\n  <!-- Optional faded watermark SVG (e.g. company logo) -->\n  <!-- Changed: wrapper div gets Angular scoping attribute; inner div holds innerHTML so svg size CSS applies to scoped .lp-hero-watermark-inner -->\n  <div *ngIf=\"config.hero.watermarkSvg\" class=\"lp-hero-watermark\" aria-hidden=\"true\">\n    <div class=\"lp-hero-watermark-inner\" [innerHTML]=\"safeHeroWatermarkSvg\"></div>\n  </div>\n\n  <div class=\"lp-container lp-hero-content\">\n    <!-- Left / centered column: brand, headline, CTAs -->\n    <div class=\"lp-hero-main\">\n      <!-- App brand: logo + name + decorative divider -->\n      <div class=\"lp-hero-brand\">\n        <div class=\"lp-hero-brand-logo\">\n          <img [src]=\"config.logoSrc\" [alt]=\"config.appName\" class=\"lp-hero-brand-icon\">\n          <span class=\"lp-hero-brand-name\">{{ config.appName }}</span>\n        </div>\n        <div class=\"lp-hero-divider\" aria-hidden=\"true\">\n          <span class=\"lp-hero-divider-line\"></span>\n          <span class=\"lp-hero-divider-dot\"></span>\n          <span class=\"lp-hero-divider-line\"></span>\n        </div>\n      </div>\n      <!-- Hero text: headline, subtitle, CTAs, trust signals -->\n      <div class=\"lp-hero-text\">\n        <div *ngIf=\"config.hero.badge\" class=\"lp-hero-badge\">{{ config.hero.badge }}</div>\n        <h1>{{ config.hero.headline }} <span class=\"lp-gradient-text\">{{ config.hero.gradientText }}</span></h1>\n        <p class=\"lp-hero-subtitle\">{{ config.hero.subtitle }}</p>\n        <div class=\"lp-hero-ctas\">\n          <button class=\"lp-btn lp-btn-primary lp-btn-lg\" (click)=\"navigateTo(config.hero.primaryCTARoute || 'signup')\">\n            {{ config.hero.primaryCTA }}\n          </button>\n          <button class=\"lp-btn lp-btn-outline lp-btn-lg\" (click)=\"scrollToSection(config.hero.secondaryCTASection)\">\n            {{ config.hero.secondaryCTA }}\n          </button>\n        </div>\n        <!-- Trust signals with checkmark SVG icons -->\n        <div class=\"lp-trust-signals\">\n          <div *ngFor=\"let signal of config.hero.trustSignals\" class=\"lp-trust-item\">\n            <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n              <path d=\"M20 6L9 17l-5-5\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n            </svg>\n            <span>{{ signal }}</span>\n          </div>\n        </div>\n      </div>\n    </div>\n    <!-- App visual: always rendered when projected content exists (stacked below hero text) -->\n    <!-- Changed: removed *ngIf so visual always renders below text; layout is always stacked/column -->\n    <div class=\"lp-hero-visual\">\n      <ng-content select=\"[lpHeroVisual]\"></ng-content>\n    </div>\n  </div>\n</section>\n\n<!-- ===== METRICS (optional) ===== -->\n<section *ngIf=\"config.metrics\" class=\"lp-section lp-animate\">\n  <div class=\"lp-container\">\n    <div class=\"lp-metrics-grid\">\n      <div *ngFor=\"let metric of config.metrics\" class=\"lp-metric-card\">\n        <div class=\"lp-metric-value\">{{ metric.value }}</div>\n        <div class=\"lp-metric-label\">{{ metric.label }}</div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- ===== FEATURES ===== -->\n<section id=\"lp-features\" class=\"lp-section lp-animate\">\n  <div class=\"lp-container\">\n    <div class=\"lp-section-header\">\n      <h2>{{ config.features.title }}</h2>\n      <p>{{ config.features.subtitle }}</p>\n    </div>\n    <div class=\"lp-features-grid\">\n      <div *ngFor=\"let feature of config.features.items\" class=\"lp-feature-card\">\n        <!-- Icon tint: hex + '20' = ~12% opacity background -->\n        <div class=\"lp-feature-icon\"\n             [style.background]=\"iconBg(feature.color)\"\n             [style.color]=\"feature.color\">\n          <span class=\"material-icons\">{{ feature.icon }}</span>\n        </div>\n        <h3 class=\"lp-feature-title\">{{ feature.title }}</h3>\n        <p class=\"lp-feature-desc\">{{ feature.description }}</p>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- ===== WORKFLOW (optional) ===== -->\n<section *ngIf=\"config.workflow\" id=\"lp-workflow\" class=\"lp-section lp-section-alt lp-animate\">\n  <div class=\"lp-container\">\n    <div class=\"lp-section-header\">\n      <h2>{{ config.workflow!.title }}</h2>\n      <p *ngIf=\"config.workflow!.subtitle\">{{ config.workflow!.subtitle }}</p>\n    </div>\n\n    <!-- Road metaphor layout: horizontal road line with waypoints -->\n    <div *ngIf=\"config.workflow!.style === 'road'\" class=\"lp-workflow-road\">\n      <div class=\"lp-road-line\"></div>\n      <div *ngFor=\"let step of config.workflow!.steps\" class=\"lp-waypoint\">\n        <div class=\"lp-waypoint-marker\">\n          <span class=\"material-icons\">{{ step.icon }}</span>\n        </div>\n        <div class=\"lp-waypoint-number\">Step {{ step.number }}</div>\n        <div class=\"lp-waypoint-title\">{{ step.title }}</div>\n        <div class=\"lp-waypoint-desc\">{{ step.description }}</div>\n      </div>\n    </div>\n\n    <!-- Default steps grid layout -->\n    <div *ngIf=\"!config.workflow!.style || config.workflow!.style === 'steps'\" class=\"lp-steps-grid\">\n      <div *ngFor=\"let step of config.workflow!.steps; let i = index\" class=\"lp-step-card\">\n        <div class=\"lp-step-number\">{{ step.number }}</div>\n        <div class=\"lp-step-icon\">\n          <span class=\"material-icons\">{{ step.icon }}</span>\n        </div>\n        <h3 class=\"lp-step-title\">{{ step.title }}</h3>\n        <p class=\"lp-step-desc\">{{ step.description }}</p>\n        <!-- Connector line between steps, not after last -->\n        <div *ngIf=\"i < config.workflow!.steps.length - 1\" class=\"lp-step-connector\"></div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- ===== CUSTOM SECTION SLOT ===== -->\n<!-- Consumer projects app-specific sections here (fleet board, benefits rows, etc.)\n     using [lpCustomSection] attribute on a wrapper element -->\n<ng-content select=\"[lpCustomSection]\"></ng-content>\n\n<!-- ===== MODULES (optional) ===== -->\n<section *ngIf=\"config.modules\" id=\"lp-modules\" class=\"lp-section lp-section-alt lp-animate\">\n  <div class=\"lp-container\">\n    <div class=\"lp-section-header\">\n      <h2>{{ config.modules!.title }}</h2>\n      <p>{{ config.modules!.subtitle }}</p>\n    </div>\n    <div class=\"lp-modules-grid\">\n      <div *ngFor=\"let group of config.modules!.groups\" class=\"lp-module-group\">\n        <div class=\"lp-module-group-label\">{{ group.category }}</div>\n        <div class=\"lp-module-tiles\">\n          <div *ngFor=\"let tile of group.tiles\" class=\"lp-module-tile\">\n            <span class=\"material-icons\">{{ tile.icon }}</span>\n            <span>{{ tile.name }}</span>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- ===== SECURITY (optional — dark background) ===== -->\n<section *ngIf=\"config.security\" class=\"lp-section lp-section-dark lp-animate\">\n  <div class=\"lp-container\">\n    <div class=\"lp-section-header lp-header-light\">\n      <h2>{{ config.security!.title }}</h2>\n      <p>{{ config.security!.subtitle }}</p>\n    </div>\n    <div class=\"lp-security-grid\">\n      <div *ngFor=\"let item of config.security!.items\" class=\"lp-security-card\">\n        <div class=\"lp-security-icon\">\n          <span class=\"material-icons\">{{ item.icon }}</span>\n        </div>\n        <h3>{{ item.title }}</h3>\n        <p>{{ item.description }}</p>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- ===== TESTIMONIALS (optional) ===== -->\n<section *ngIf=\"config.testimonials\" class=\"lp-section lp-animate\">\n  <div class=\"lp-container\">\n    <div class=\"lp-section-header\">\n      <h2>{{ config.testimonials!.title }}</h2>\n      <p *ngIf=\"config.testimonials!.subtitle\">{{ config.testimonials!.subtitle }}</p>\n    </div>\n    <div class=\"lp-testimonials-grid\">\n      <div *ngFor=\"let item of config.testimonials!.items\" class=\"lp-testimonial-card\">\n        <div class=\"lp-stars\">\n          <span class=\"material-icons\">star</span>\n          <span class=\"material-icons\">star</span>\n          <span class=\"material-icons\">star</span>\n          <span class=\"material-icons\">star</span>\n          <span class=\"material-icons\">star</span>\n        </div>\n        <p class=\"lp-testimonial-quote\">\"{{ item.quote }}\"</p>\n        <div class=\"lp-testimonial-author\">\n          <div class=\"lp-author-avatar\">{{ item.authorInitials }}</div>\n          <div>\n            <div class=\"lp-author-name\">{{ item.authorName }}</div>\n            <div class=\"lp-author-role\">{{ item.authorRole }}</div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- ===== PRICING (optional) ===== -->\n<section *ngIf=\"config.pricing\" id=\"lp-pricing\" class=\"lp-section lp-animate\">\n  <div class=\"lp-container\">\n    <div class=\"lp-section-header\">\n      <h2>{{ config.pricing!.title }}</h2>\n      <p *ngIf=\"config.pricing!.subtitle\">{{ config.pricing!.subtitle }}</p>\n    </div>\n    <div class=\"lp-pricing-grid\">\n      <div *ngFor=\"let plan of config.pricing!.plans\"\n           class=\"lp-pricing-card\"\n           [class.lp-pricing-popular]=\"plan.popular\">\n        <div *ngIf=\"plan.popular\" class=\"lp-popular-badge\">Most Popular</div>\n        <div class=\"lp-pricing-header\">\n          <h3>{{ plan.name }}</h3>\n          <div class=\"lp-pricing-price\">\n            <span class=\"lp-price-amount\">{{ plan.price }}</span>\n            <span *ngIf=\"plan.period\" class=\"lp-price-period\">{{ plan.period }}</span>\n          </div>\n          <p class=\"lp-pricing-desc\">{{ plan.description }}</p>\n        </div>\n        <ul class=\"lp-pricing-features\">\n          <li *ngFor=\"let feature of plan.features\">{{ feature }}</li>\n        </ul>\n        <!-- Popular plans get primary button, others get outline -->\n        <button *ngIf=\"plan.popular\"\n                class=\"lp-btn lp-btn-primary lp-btn-block\"\n                (click)=\"plan.ctaRoute ? navigateTo(plan.ctaRoute) : scrollToSection(plan.ctaSection || '')\">\n          {{ plan.ctaLabel }}\n        </button>\n        <button *ngIf=\"!plan.popular\"\n                class=\"lp-btn lp-btn-outline lp-btn-block\"\n                (click)=\"plan.ctaRoute ? navigateTo(plan.ctaRoute) : scrollToSection(plan.ctaSection || '')\">\n          {{ plan.ctaLabel }}\n        </button>\n      </div>\n    </div>\n  </div>\n</section>\n\n<!-- ===== FINAL CTA BANNER (optional) ===== -->\n<section *ngIf=\"config.finalCta\" class=\"lp-final-cta lp-animate\">\n  <div class=\"lp-container lp-cta-content\">\n    <h2>{{ config.finalCta!.headline }}</h2>\n    <p>{{ config.finalCta!.subtitle }}</p>\n    <div class=\"lp-cta-buttons\">\n      <button class=\"lp-btn lp-btn-white lp-btn-lg\"\n              (click)=\"navigateTo(config.finalCta!.primaryCTARoute || 'signup')\">\n        {{ config.finalCta!.primaryCTA }}\n      </button>\n      <button *ngIf=\"config.finalCta!.secondaryCTA\"\n              class=\"lp-btn lp-btn-outline-white lp-btn-lg\"\n              (click)=\"scrollToSection(config.finalCta!.secondaryCTASection || '')\">\n        {{ config.finalCta!.secondaryCTA }}\n      </button>\n    </div>\n  </div>\n</section>\n\n<!-- ===== FOOTER ===== -->\n<footer class=\"lp-footer\" id=\"lp-footer\">\n  <div class=\"lp-container\">\n\n    <!-- Rich multi-column footer when footerColumns provided -->\n    <div *ngIf=\"config.footerColumns && config.footerColumns.length; else simpleFooter\" class=\"lp-footer-grid\">\n      <!-- Brand column -->\n      <div class=\"lp-footer-brand-col\">\n        <!-- Custom SVG footer brand OR default img+name -->\n        <ng-container *ngIf=\"config.footerBrand; else defaultFooterBrand\">\n          <div class=\"lp-footer-brand-custom\">\n            <span class=\"lp-footer-brand-svg\" [innerHTML]=\"safeFooterBrandSvg\"></span>\n            <div *ngIf=\"config.footerBrand.wordmarkLine1\" class=\"lp-footer-brand-wordmark\">\n              <span class=\"lp-footer-wordmark-line1\">{{ config.footerBrand.wordmarkLine1 }}</span>\n              <span *ngIf=\"config.footerBrand.wordmarkLine2\" class=\"lp-footer-wordmark-line2\">{{ config.footerBrand.wordmarkLine2 }}</span>\n            </div>\n          </div>\n        </ng-container>\n        <ng-template #defaultFooterBrand>\n          <div class=\"lp-footer-brand-default\">\n            <img [src]=\"config.logoSrc\" [alt]=\"config.appName\" class=\"lp-footer-logo\">\n            <span class=\"lp-footer-name\">{{ config.appName }}</span>\n          </div>\n        </ng-template>\n        <p *ngIf=\"config.footerTagline\" class=\"lp-footer-tagline\">{{ config.footerTagline }}</p>\n      </div>\n      <!-- Link columns -->\n      <div *ngFor=\"let col of config.footerColumns\" class=\"lp-footer-col\">\n        <h4>{{ col.title }}</h4>\n        <a *ngFor=\"let link of col.links\"\n           (click)=\"link.section ? scrollToSection(link.section) : (link.route ? navigateTo(link.route) : null)\">\n          {{ link.label }}\n        </a>\n      </div>\n    </div>\n\n    <!-- Simple single-row footer (default) -->\n    <ng-template #simpleFooter>\n      <div class=\"lp-footer-inner\">\n        <div class=\"lp-footer-brand\">\n          <img [src]=\"config.logoSrc\" [alt]=\"config.appName\" class=\"lp-footer-logo\">\n          <span class=\"lp-footer-name\">{{ config.appName }}</span>\n        </div>\n        <div class=\"lp-footer-links\">\n          <a (click)=\"navigateTo('login')\">Log in</a>\n          <a (click)=\"navigateTo(config.hero.primaryCTARoute || 'signup')\">Sign up</a>\n        </div>\n        <div class=\"lp-footer-copy\">\n          &copy; {{ currentYear }} {{ config.footerCompany || 'alsquare technologies' }}. All rights reserved.\n        </div>\n      </div>\n    </ng-template>\n\n    <!-- Footer bottom bar (shown for both layouts) -->\n    <div *ngIf=\"config.footerColumns && config.footerColumns.length\" class=\"lp-footer-bottom\">\n      <span>&copy; {{ currentYear }} {{ config.footerCompany || 'alsquare technologies' }}. All rights reserved.</span>\n    </div>\n  </div>\n</footer>\n","import { NgModule } from '@angular/core';\nimport { TinSpaComponent } from './components/tin-spa.component';\nimport { SpaMatModule } from \"./modules/spa-mat.module\";\nimport { OfflineIndicatorComponent } from './components/offline/offline-indicator.component'; // Added: TinSync toolbar indicator\nimport { TextComponent } from './components/text/text.component';\nimport { TextMaskComponent } from './components/text-mask/text-mask.component';\nimport { TextAreaComponent } from './components/text-area/text-area.component';\nimport { TextSingleComponent } from './components/text-single/text-single.component';\nimport { CheckComponent } from './components/check/check.component';\nimport { DateComponent } from './components/date/date.component';\nimport { DatetimeComponent } from './components/datetime/datetime.component';\nimport { LabelComponent } from './components/label/label.component';\nimport { SelectComponent } from './components/select/select.component';\nimport { ActivityComponent } from './components/activity/activity.component';\nimport { FilterComponent } from './components/filter/filter.component';\nimport { messageDialog } from './components/message/messageDialog.component';\nimport { MoneyComponent } from './components/money/money.component';\nimport { OptionComponent } from './components/option/option.component';\nimport { TilesComponent } from './components/tiles/tiles.component';\nimport { FilterChipsComponent } from './components/filter-chips/filter-chips.component'; // Added: opt-in quick-filter chip row rendered directly under the tile row\nimport { StepsComponent } from './components/steps/steps.component';\nimport { ChecklistComponent } from './components/checklist/checklist.component'; // Added: flat collapsible checklist (Getting Started actions)\nimport { ProgressRingComponent } from './components/progress-ring/progress-ring.component'; // Added: circular n-of-m ring (Getting Started category groups)\nimport { AttachComponent } from './components/attach/attach.component';\nimport { ChipsComponent } from './components/chips/chips.component';\nimport { LoaderComponent } from './components/loader/loader.component';\nimport { NavMenuComponent } from './components/nav-menu/nav-menu.component';\nimport { LoaderInterceptor } from './services/loader-interceptor.service';\nimport { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';\nimport { CurrencyPipe, DatePipe, HashLocationStrategy, LocationStrategy } from '@angular/common';\nimport { MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';\nimport { CurrencyInputModule } from './components/money/currency-input-mask.module';\nimport { TableComponent } from './components/table/table.component';\nimport { DetailsDialog as DetailsDialog } from './components/table/detailsDialog.component';\nimport { FormComponent } from './components/form/form.component';\nimport { FormSkeletonComponent } from './components/form-skeleton/form-skeleton.component'; // Added: Quiet Loading — details-dialog form skeleton (FSD D6)\nimport { CamelToWordsPipe } from './pipes/camelToWords.pipe';\nimport { AgentMarkdownPipe } from './pipes/agent-markdown.pipe'; // Changed: the agent writes markdown; the widget used to print it verbatim\nimport { NumberComponent } from './components/number/number.component';\nimport { SearchComponent } from './components/search/search.component';\n// Removed (Phase 7, BREAKING): ViewerComponent (<spa-viewer>) and viewerDialog are deleted — DocumentComponent and DocumentViewerDialogComponent below replace them.\nimport { MapComponent } from './components/map/map.component'; // Added: spa-map — config-driven full-bleed map surface\nimport { DocumentViewerDialogComponent } from './components/document-viewer/documentViewerDialog.component'; // Added: the full-bleed document viewer — replaces viewerDialog (deleted in Phase 7)\nimport { DocumentComponent } from './components/document-viewer/document.component'; // Added (Phase 6): <spa-document>, the file-view field's shelf. 🔴 It is a COMPONENT, so it MUST be declared below — which is exactly why the Word/Excel RENDERERS are plain functions instead: a declarations entry is a static import and would re-merge their lazy chunks into every consumer's initial bundle (the regression recorded at line 45)\nimport { MapDialogComponent } from './components/map/mapDialog.component'; // Added: the full-bleed map dialog\n// GS-1: NgxDocViewerModule removed — viewerDialog only used its \"url\" mode (an iframe); the dependency shipped mammoth into every consumer's initial bundle\nimport { ListDialogComponent } from './components/list-dialog/list-dialog.component';\nimport { InvitationsTableComponent } from './pages/invitations-table/invitations-table.component';\nimport { TableHeaderComponent } from './components/table-header/table-header.component';\nimport { ImportDialogComponent } from './components/import/import-dialog.component'; // Added: generic data import wizard\nimport { TableDialogComponent } from './components/table-dialog/table-dialog.component'; // Added: spa-table-dialog — read-only entity list in a MatDialog\nimport { TableRowComponent } from './components/table-row/table-row.component';\nimport { MonogramComponent } from './components/monogram/monogram.component'; // Added: monogram column type\nimport { InlineCellComponent } from './components/table/inline-cell.component'; // Added: inline row editing cell editor\nimport { TableActionComponent } from './components/table-action/table-action.component';\nimport { AlertComponent } from './components/alert/alert.component';\nimport { EmailComponent } from './components/email/email.component';\nimport { PageComponent } from './components/page/page.component';\nimport { SelectCommonComponent } from './components/select-common/select-common.component';\nimport { SuffixComponent } from './components/suffix/suffix.component';\nimport { SelectContextDirective } from './select-context.directive';\nimport { SelectLiteComponent } from './components/select-lite/select-lite.component';\nimport { TextMultiComponent } from './components/text-multi/text-multi.component';\nimport { SelectMultiComponent } from './components/select-multi/select-multi.component';\nimport { SelectBitwiseComponent } from './components/select-bitwise/select-bitwise.component';\nimport { HtmlComponent } from './components/html/html.component';\nimport { EditorComponent } from './components/editor/editor.component'; // Added: rich-text/WYSIWYG field (type:'editor')\nimport { AngularEditorModule } from '@kolkov/angular-editor'; // Added: WYSIWYG editor module for spa-editor\nimport { NotesComponent } from './components/notes/notes.component';\nimport { CapsulesComponent } from './components/capsules/capsules.component';\nimport { CardsComponent } from './components/cards/cards.component';\nimport { TabsComponent } from './components/tabs/tabs.component';\nimport { TabsFloatComponent } from './components/tabs/tabsFloat.component'; // Added: spa-tabs-float — the details dialog's floating tab-title strip\nimport { StatusesComponent } from './components/statuses/statuses.component';\nimport { GroupsComponent } from './components/groups/groups.component';\nimport { TitleActionsComponent } from './components/title-actions/title-actions.component';\nimport { AccountingService } from './services/accounting.service';\nimport { LoansService } from './services/loans.service';\nimport { TabService } from './services/tab.service'; // Changed: Import tab service\nimport { DETAILS_DIALOG_COMPONENT, IMPORT_DIALOG_COMPONENT, TABLE_DIALOG_COMPONENT } from './services/dialog-component.token'; // Changed: also provide the import wizard and read-only table dialog tokens\nimport { WelcomeComponent } from './pages/welcome/welcome.component'; // Tin-SPA business modules welcome page\nimport { TermsDialogComponent } from './components/terms-dialog/terms-dialog.component'; // Changed: Added terms dialog\nimport { PrivacyDialogComponent } from './components/privacy-dialog/privacy-dialog.component'; // Changed: Added privacy dialog\nimport { BaseChartDirective, provideCharts, withDefaultRegisterables } from 'ng2-charts'; // Changed: Added Chart.js support for spa-charts and tile mini charts\nimport { ChartsComponent } from './components/charts/charts.component'; // Changed: Added ChartsComponent for config-driven chart cards\nimport { DragDropModule } from '@angular/cdk/drag-drop'; // Changed: Added for CDK drag-drop between groups\nimport { FeatureDirective } from './directives/feature.directive'; // Added: Structural directive for plan-based feature gating\nimport { EllipsisDirective } from './directives/ellipsis.directive'; // Added: reports real text clipping so a tooltip fires only when content is actually hidden\nimport { SubscriptionService } from './services/subscription.service'; // Added: Subscription feature-checking service\nimport { AnalyticsService } from './services/analytics.service'; // Changed: GA4 route tracking service\nimport { SpaLandingComponent } from './pages/landing/landing.component'; // Added: Config-driven landing page component\nimport { ToastComponent } from './components/toast/toast.component'; // Changed: Cascading toast notifications for real-time entity changes\nimport { AgentComponent } from './components/agent/agent.component'; // Changed: Renamed from AgentComponent\nimport { AgentPageComponent } from './pages/agent-page/agent-page.component'; // Added: routed chat page (home/agent) — declared here so its template resolves spa-agent\nimport { BottomTabsComponent } from './components/bottom-tabs/bottom-tabs.component'; // Added: mobile bottom tab bar — nav-menu mounts it, so it must be declared alongside NavMenuComponent\n\n@NgModule({\n  declarations: [\n    // Changed: Removed page components now declared in domain-specific modules (accounting, inventory, sales, purchasing, hr, payroll, manufacturing, loans, general, tenancy, workflow, overview)\n    TinSpaComponent, TextComponent, TextMaskComponent, TextAreaComponent, TextSingleComponent, CheckComponent,DateComponent,DatetimeComponent,LabelComponent,SelectComponent,\n    ActivityComponent, FilterComponent, messageDialog, MoneyComponent, OptionComponent, TilesComponent, FilterChipsComponent, StepsComponent, ChecklistComponent, ProgressRingComponent, // Changed: declare spa-checklist and spa-progress-ring\n    AttachComponent, ChipsComponent, LoaderComponent, NavMenuComponent, TableComponent, DetailsDialog, FormComponent, FormSkeletonComponent, CamelToWordsPipe, AgentMarkdownPipe, NumberComponent, SearchComponent, MapComponent, MapDialogComponent, DocumentViewerDialogComponent, DocumentComponent,\n    ListDialogComponent,\n    InvitationsTableComponent,\n    TableHeaderComponent, TableRowComponent, TableActionComponent, InlineCellComponent, MonogramComponent, // Changed: added InlineCellComponent (inline row editing), MonogramComponent (monogram column type)\n    AlertComponent, EmailComponent, PageComponent, SelectCommonComponent, SuffixComponent, SelectContextDirective, SelectLiteComponent,\n    TextMultiComponent,\n    SelectMultiComponent, SelectBitwiseComponent,\n    HtmlComponent, EditorComponent, NotesComponent, CapsulesComponent, CardsComponent, TabsComponent, StatusesComponent, GroupsComponent, TitleActionsComponent,\n    WelcomeComponent,\n    TermsDialogComponent, PrivacyDialogComponent,\n    ChartsComponent,\n    FeatureDirective,\n    EllipsisDirective,\n    SpaLandingComponent,\n    ToastComponent,\n    AgentComponent,\n    AgentPageComponent, // Added: spa-agent-page — the home/agent route target\n    TabsFloatComponent, // Added: spa-tabs-float — the floating tab-TITLE strip. Declared but NOT exported, matching BottomTabsComponent/ToastComponent: it is chrome the details dialog mounts itself, so no consumer ever names it\n    BottomTabsComponent, // Added: spa-bottom-tabs — the mobile bottom tab bar. Declared but NOT exported, matching ToastComponent: both are chrome that nav-menu mounts, so no consumer ever names them\n    OfflineIndicatorComponent, // Changed: TinSync toolbar indicator (the sync page lives in the workflow module)\n    ImportDialogComponent, // Added: generic AI-assisted data import wizard\n    TableDialogComponent // Added: spa-table-dialog. Declared (not standalone) because it renders spa-table, which lives in THIS module — a standalone version would have to import TinSpaModule circularly\n\n  ],\n  imports: [\n    SpaMatModule,\n    HttpClientModule,\n    CurrencyInputModule,\n    AngularEditorModule, // Added: WYSIWYG editor for spa-editor (type:'editor')\n    BaseChartDirective, // Changed: Added for Chart.js canvas rendering in charts and tiles\n    DragDropModule // Changed: Added for CDK drag-drop between groups\n\n  ],\n  exports: [\n    TinSpaComponent,\n    SpaMatModule,\n    MonogramComponent, // Added: monogram column type — exported so hosts can render a person outside a table too\n    AlertComponent,\n    TextComponent,\n    TextMaskComponent,\n    TextAreaComponent,\n    TextSingleComponent,\n    TextMultiComponent,\n    messageDialog,\n    NavMenuComponent,\n    LoaderComponent,\n    TilesComponent,\n    FilterChipsComponent, // Added: exported so a consumer can place the chip row itself if it ever needs one outside a table\n    DateComponent,\n    SelectComponent,\n    SelectBitwiseComponent,\n    SelectMultiComponent,\n    DatetimeComponent,\n    CheckComponent,\n    AttachComponent,\n    MoneyComponent,\n    ChipsComponent,\n    ActivityComponent,\n    OptionComponent,\n    LabelComponent,\n    StepsComponent,\n    ChecklistComponent, // Added: spa-checklist export\n    ProgressRingComponent, // Added: spa-progress-ring export\n    FilterComponent,\n    TableComponent, DetailsDialog,\n    FormComponent,\n    FormSkeletonComponent, // Added: Quiet Loading — exported so consumers can render the skeleton outside the dialog\n    NumberComponent,\n    SearchComponent,\n    MapComponent, // Added: map viewer revamp — consumers use <spa-map> or openMapDialog()\n    MapDialogComponent, // Added: map viewer revamp\n    DocumentViewerDialogComponent, // Added: document viewer redesign — opened via DialogService.openDocumentViewer()\n    DocumentComponent, // Added (Phase 6): <spa-document> — exported so a consumer template can place the shelf outside a form field\n    ImportDialogComponent,\n    TableDialogComponent, // Added: exported so a consumer app can name it if it ever opens the dialog directly\n    ListDialogComponent,\n\n    ListDialogComponent,\n    EmailComponent, PageComponent,\n    HtmlComponent,\n    EditorComponent,\n    NotesComponent,\n    CapsulesComponent, TabsComponent, StatusesComponent, GroupsComponent, TitleActionsComponent,\n\n    WelcomeComponent,\n    InvitationsTableComponent, // Changed: Exported for use in HRModule (onboarding) and TenancyModule (tenant-settings)\n    TermsDialogComponent, PrivacyDialogComponent,\n    SelectLiteComponent,\n    ChartsComponent,\n    FeatureDirective,\n    EllipsisDirective,\n    SpaLandingComponent,\n    AgentComponent,\n    AgentPageComponent, // Added: exported alongside AgentComponent so consumer apps can route to it directly\n    OfflineIndicatorComponent // Changed: TinSync toolbar indicator exported for consumer app toolbars\n\n  ],\n  providers: [\n    { provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true },\n    { provide: LocationStrategy, useClass: HashLocationStrategy },\n    {provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: {appearance: 'outline', floatLabel: 'always'}}, // Changed: floatLabel 'always' added as the LIBRARY DEFAULT, so every mat-form-field the library renders shows its label at the top permanently and its derived placeholder is visible in the empty state. f041f7a had to set floatLabel=\"always\" on three components by hand; setting it here covers the rest (text, number, money, text-area, text-mask, text-multi, select-bitwise, email, datetime) and any component added later, without a per-template attribute. Material's resting label otherwise sits OVER the placeholder, so the \"Enter X\"/\"Pick X\"/\"Select X\" affordance could never be read in the empty state it exists for\n    { provide: DETAILS_DIALOG_COMPONENT, useValue: DetailsDialog }, // Changed: Token now provides unified DetailsDialog (was DetailsDialogInternal)\n    { provide: IMPORT_DIALOG_COMPONENT, useValue: ImportDialogComponent }, // Added: DialogService.openImportDialog resolves the wizard here instead of importing it\n    { provide: TABLE_DIALOG_COMPONENT, useValue: TableDialogComponent }, // Added: DialogService.openTableDialog resolves the read-only table dialog here instead of importing it (NG3003)\n    CurrencyPipe, DatePipe,\n    AccountingService,\n    LoansService,\n    TabService, // Changed: Added TabService to providers\n    provideCharts(withDefaultRegisterables()), // Changed: Register Chart.js with all default chart types\n    SubscriptionService, // Added: Subscription feature-checking service\n    AnalyticsService // Changed: GA4 route tracking for SPA page views\n\n  ],\n})\nexport class TinSpaModule {\n  // Changed: Removed auto-init — consumer apps now call analytics.init() with environment config\n}\n","import { MessageService } from \"../../services/message.service\";\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { StorageService } from \"../../services/storage.service\";\nimport { AuthService } from \"../../services/auth.service\";\nimport { Component, OnInit, Input, Inject, Optional } from \"@angular/core\"; // Changed: Added Inject/Optional for SSO diagnostics\nimport { ActivatedRoute, Router } from \"@angular/router\";\nimport { DataServiceLib } from \"../../services/datalib.service\";\nimport { LogService } from \"../../services/log.service\";\nimport { AppConfig, ApiResponse, Constants } from \"../../classes/Classes\";\nimport { HttpService } from \"../../services/http.service\";\nimport { GoogleLoginProvider, SocialAuthService, SocialAuthServiceConfig, SocialUser } from '@abacritt/angularx-social-login'; // Changed: Added GoogleLoginProvider + config type for SSO diagnostics\nimport { TIN_SPA_RUNTIME_CONFIG, TinSpaRuntimeConfig } from '../../runtime/tinspa-runtime'; // Added: cross-check enabled SSO methods against actual configuration\nimport { SignupData, User } from \"../../classes/LibClasses\"; // Changed: Added SignupData import\nimport { NotificationsService } from \"../../services/notifications.service\";\nimport { SetupService } from \"../../services/setup.service\"; // Added: Setup readiness badge count on login\nimport { LastRouteService } from \"../../services/last-route.service\"; // Added: resumeLastRoute — land on the user's last page\nimport { SignalRService } from \"../../services/signalr.service\"; // Changed: Added for starting SignalR connection after login\nimport { MsalService } from '@azure/msal-angular';\nimport { MatDialog } from '@angular/material/dialog'; // Changed: Added MatDialog for terms/privacy dialogs\nimport { TermsDialogComponent } from '../../components/terms-dialog/terms-dialog.component'; // Changed: Added terms dialog\nimport { PrivacyDialogComponent } from '../../components/privacy-dialog/privacy-dialog.component'; // Changed: Added privacy dialog\n\n\n@Component({\n    selector: \"spa-login\",\n    templateUrl: \"./login.component.html\",\n    styleUrls: [\"./login.component.css\"],\n    standalone: false\n})\nexport class LoginComponent implements OnInit {\n\n\n  constructor(private httpService: HttpService, private storageService: StorageService, public router: Router, private messageService: MessageService, public dataService: DataServiceLib,\n    public authService: AuthService, private logService: LogService, private route: ActivatedRoute,\n    private notificationsService: NotificationsService, private signalRService: SignalRService, private msalService : MsalService, private dialog: MatDialog,\n    private setupService: SetupService,\n    private lastRouteService: LastRouteService,\n    @Inject(TIN_SPA_RUNTIME_CONFIG) private runtimeConfig: TinSpaRuntimeConfig,\n    private apiErrorService: ApiErrorService, // Added: routes application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n    @Optional() @Inject('SocialAuthServiceConfig') private socialAuthConfig: SocialAuthServiceConfig | null ) { } // Changed: Added SignalRService injection // Changed: Added MatDialog injection // Added: SetupService for setup badge // Added: LastRouteService for resumeLastRoute // Added: runtime + social configs for SSO diagnostics\n\n  // Added: where a successful login/resume should land. An explicit ?redirectTo= always wins (it means the\n  // user was bounced out of a specific page); otherwise resumeLastRoute lands them on their last page.\n  private async resumeTarget(): Promise<string> {\n    if (this.route.snapshot.queryParams[\"redirectTo\"]) return this.redirectPath; // Changed: was `!= undefined` — a present-but-EMPTY redirectTo (the old hash-derived expiry redirect produced exactly that) beat the saved last-route with a blank target\n    const last = await this.lastRouteService.resolve();\n    return last ?? this.redirectPath;\n  }\n\n  ngOnInit() {\n\n\n    this.dataService.appConfigObserv.subscribe(x => { this.appConfig = x; this.style = x.loginStyle ?? 'default'; }); // Changed: resolve the login style immediately — the restore panel must render in the app's configured style, not flip from default to modern when the form appears\n\n    if (this.route.snapshot.queryParams[\"redirectTo\"]) { // Changed: was `!= undefined` — an empty param must fall back to home, not adopt \"\"\n      this.redirectPath = this.route.snapshot.queryParams[\"redirectTo\"]\n    }else{\n      this.redirectPath = \"home\"\n    }\n\n    // Changed: Use shared tryRestoreSession — handles valid-session check and silent refresh in one call\n    this.isProcessing = true;\n    this.restoring = this.authService.hasValidSession() || this.authService.hasRefreshToken(); // Added: a restore will actually run — swap the credential form for the \"Signing you back in\" panel so the user can't fight the auto sign-in\n    this.authService.tryRestoreSession().then(async success => {\n      this.isProcessing = false;\n      if (this.manualLogin) return; // Added: user chose \"Use a different account\" mid-restore — stay on the form, never yank them away\n      if (success) { this.notifications(); this.lastRouteService.navigateTo(await this.resumeTarget(), this.redirectPath); return; } // Changed: navigateTo falls back to the redirect path if the saved page no longer exists\n      this.restoreOffline = this.restoring && this.authService.hasRefreshToken(); // Added: the token surviving the failure means a network error (a rejected token is cleared) — tell the user why auto sign-in stopped\n      this.restoring = false; // Added: restore is over — reveal the credential form\n      this.setupForm(); // Changed: Only set up login form if no session could be restored\n    });\n\n  }\n\n  loginWithMS() {\n    // MSAL v3 throws uninitialized_public_client_application unless initialize() has\n    // completed; it is idempotent, so awaiting here is safe even when already done.\n    this.msalService.instance.initialize().then(() => this.doMsalLoginPopup(),\n      (error) => { console.error('MSAL initialize error:', error); this.messageService.toast(\"Microsoft login failed. Please try again.\"); });\n  }\n\n  private doMsalLoginPopup() {\n    this.msalService.loginPopup({\n      scopes: [\"openid\", \"profile\", \"email\"],\n      // prompt: \"select_account\"\n    }).subscribe({\n      next: (response) => {\n        \n\n        // Get user claims from response\n        const claims = response.account;\n        \n        // Set user details\n        this.user.userName = claims.username;\n        this.user.password = response.requestId;\n        this.user.token = response.idToken;\n        this.user.authType = 'MSAL';\n \n\n        // Proceed with your existing login flow\n        this.login();\n      },\n      error: (error) => {\n        console.error('MSAL login error:', error);\n        this.messageService.toast(\"Microsoft login failed. Please try again.\");\n      }\n    });\n  }\n\n  \n  autoLogin: boolean;\n  socialUser: SocialUser | null;\n  rememberMe: boolean = false; // Changed: Added for \"Keep me signed in\" checkbox\n\n  style: string = \"default\";\n\n  email: string = \"\";\n  password: string = \"\";\n\n  redirectPath\n\n  public user = new User();\n  hide = true;\n  isProcessing: boolean = false;\n  restoring: boolean = false; // Added: silent session restore in flight — template shows the \"Signing you back in\" panel instead of the credential form\n  restoreOffline: boolean = false; // Added: restore failed because the server was unreachable — a small note above the form explains why\n  private manualLogin: boolean = false; // Added: user opted out of the automatic restore, so a late success must not auto-navigate\n\n  appConfig = new AppConfig();\n\n  public signup() {\n    this.router.navigate([\"signup\"]);\n  }\n\n  public recoverAccount() {\n    this.router.navigate([\"recover-account\"]);\n  }\n\n  // Added: escape hatch on the \"Signing you back in\" panel — reveals the credential form immediately while the\n  // restore finishes in the background; a late restore success no longer navigates, and a fresh login simply replaces it\n  public signInManually() {\n    this.manualLogin = true;\n    this.restoring = false;\n    this.isProcessing = false;\n    this.setupForm();\n  }\n\n  // Added: SSO troubleshooting — when a sign-in method is enabled (appConfig) but its\n  // configuration is missing or incomplete, say so in the console instead of failing silently.\n  private logSsoDiagnostics(): void {\n    if (this.appConfig.microsoftAuth) {\n      if (!this.runtimeConfig.microsoftAuth) {\n        console.error('[tin-spa] appConfig.microsoftAuth is TRUE (the login page shows the Microsoft button) but the runtime has Microsoft SSO disabled. ' +\n          'Set \"MicrosoftAuth\": true in assets/appsettings.json (or microsoftAuth: true in provideTinSpaRuntime) — clicking the button will fail until then.');\n      }\n      // Missing/empty ClientId or Authority is reported by tinSpaMsalInstanceFactory the moment\n      // this page injects MsalService, so it is not repeated here.\n    }\n\n    if (this.appConfig.googleAuth) {\n      const google = this.socialAuthConfig?.providers?.find(p => p.id === GoogleLoginProvider.PROVIDER_ID);\n      const clientId = (google?.provider as any)?.clientId;\n      if (!google) {\n        console.error('[tin-spa] appConfig.googleAuth is TRUE (the login page shows Google sign-in) but no Google provider is registered in SocialAuthServiceConfig. ' +\n          'Google sign-in will not work — check GoogleClientID in assets/appsettings.json.');\n      } else if (typeof clientId === 'string' && !clientId.trim()) {\n        console.error('[tin-spa] appConfig.googleAuth is TRUE but the registered Google provider has an EMPTY client id. ' +\n          'Google sign-in will not work — set GoogleClientID in assets/appsettings.json.');\n      }\n    }\n  }\n\n  // Changed: Extracted from ngOnInit — runs only when no session could be restored\n  private setupForm(): void {\n    this.logSsoDiagnostics(); // Added: surface SSO misconfiguration in the browser console\n    if (this.route.snapshot.queryParams[\"sso\"] == \"msal\" && this.appConfig.microsoftAuth) {\n      this.loginWithMS();\n    }\n    this.authService.autoLoginObserv.subscribe(x => { this.autoLogin = x; });\n    this.socialUser = null;\n    this.authService.socialUserObserv.subscribe((socialUser: SocialUser | null) => {\n      if (!socialUser) return;\n      this.socialUser = socialUser;\n      this.user.userName = socialUser.id;\n      this.user.password = socialUser.id;\n      this.user.token = socialUser.idToken;\n      this.user.authType = socialUser.provider;\n      this.login();\n    });\n    this.style = this.dataService.appConfig.loginStyle ?? 'default';\n  }\n\n  public login() {\n\n\n    if (this.user.userName == \"\" || this.user.password == \"\") {\n      this.messageService.toast(\"Please enter your credentials\");\n      return;\n    }\n\n\n    // this.logService.info(\"logging in\");\n\n    this.isProcessing = true;\n\n\n    this.user.userName = this.user.userName\n    this.user.rememberMe = this.rememberMe; // Changed: Set before API call so backend receives the flag\n\n    this.dataService.Login(this.user).subscribe((apiResponse: ApiResponse) => {\n\n      this.isProcessing = false;\n\n\n      if (apiResponse.success) {\n\n        // Changed: Use centralized applyLoginResponse + store username separately\n        this.authService.UpdateCurrentUser(this.user.userName);\n        this.authService.applyLoginResponse(apiResponse.data, this.rememberMe);\n        this.storageService.store(Constants.AUTH_USER, this.user.userName);\n\n        this.dataService.ClearCache();\n\n        this.notifications();\n\n\n        if (apiResponse.data.changePassword == true && apiResponse.data.authType == 'local') {\n\n          this.router.navigate([\"home/user/change-password\"], {\n            queryParams: { redirectTo: this.redirectPath },\n            queryParamsHandling: 'merge',\n            skipLocationChange: false\n          });\n          return\n        }\n\n        this.resumeTarget().then(target => this.lastRouteService.navigateTo(target, this.redirectPath)); // Changed: land on the user's last page when resumeLastRoute is on, falling back to the redirect path if that page is gone\n\n\n\n\n      } else if (apiResponse.message == \"signup_required\" && apiResponse.data) {\n        // Changed: Detect signup_required response and redirect to signup page\n        let signupData = new SignupData();\n        signupData.token = this.user.token;\n        signupData.authType = this.user.authType;\n        signupData.firstName = apiResponse.data.firstName;\n        signupData.lastName = apiResponse.data.lastName;\n        signupData.email = apiResponse.data.email;\n        signupData.orgName = apiResponse.data.firstName + \"'s Org\";\n        signupData.invitations = apiResponse.data.invitations || [];\n        this.dataService.SetPendingSignup(signupData);\n        this.router.navigate([\"signup\"]);\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n        this.user.password = \"\";\n      }\n    },\n      (error) => {\n        this.isProcessing = false;\n\n        this.messageService.toast(this.httpService.Error(error));\n      }\n    );\n  }\n\n  notifications(){\n    if (this.appConfig.multitenant){\n      this.notificationsService.loadNotifications()\n      this.setupService.loadCount(); // Added: Load setup readiness badge count on login\n\n      // Changed: Start single consolidated SignalR connection for notifications and entity broadcasts\n      const appHubUrl = this.httpService.apiUrl.replace(/\\/api\\/$/, '/hubs/app');\n      this.storageService.get(Constants.AUTH_TOKEN).then((token: string) => {\n        if (token) {\n          this.signalRService.startConnection(appHubUrl, token);\n        }\n      });\n    }\n\n  }\n\n  // Changed: Opens terms dialog or redirects to URL based on appConfig\n  openTerms() {\n    if (this.appConfig.termsUrl && this.appConfig.termsUrl.trim() !== '') {\n      window.open(this.appConfig.termsUrl, '_blank');\n    } else {\n      this.dialog.open(TermsDialogComponent, { width: '600px', maxHeight: '80vh', panelClass: this.dataService?.dialogPanelClass ?? [] });\n    }\n  }\n\n  // Changed: Opens privacy dialog or redirects to URL based on appConfig\n  openPrivacy() {\n    if (this.appConfig.privacyUrl && this.appConfig.privacyUrl.trim() !== '') {\n      window.open(this.appConfig.privacyUrl, '_blank');\n    } else {\n      this.dialog.open(PrivacyDialogComponent, { width: '600px', maxHeight: '80vh', panelClass: this.dataService?.dialogPanelClass ?? [] });\n    }\n  }\n\n}\n","\n  <div *ngIf=\"style=='default'\" class=\"login-page background tin-bg-login\">\n\n    <div class=\"container\" >\n\n      <div class=\"logo\">\n        <img *ngIf=\"appConfig.logoSize=='normal'\"  [src]=\"appConfig.logo\" style=\"width: 100px\" />\n        <img *ngIf=\"appConfig.logoSize=='medium'\"  [src]=\"appConfig.logo\" style=\"width: 150px\" />\n        <img *ngIf=\"appConfig.logoSize=='large'\"  [src]=\"appConfig.logo\" style=\"width: 250px\" />\n      </div>\n\n      <mat-card class=\"mat-elevation-z3 \" style=\"width:400px; \">\n\n        <mat-card-header style=\"margin-bottom: 30px;margin-top: 30px;\">\n          <mat-card-title style=\"font-size: 40px;margin-bottom: 10px; margin-top: 20px; font-weight: 300\">{{appConfig.appName}}</mat-card-title>\n        </mat-card-header>\n\n        <!-- Added: silent-restore state — replaces the credential form while the session is being restored -->\n        <mat-card-content *ngIf=\"restoring\">\n          <div class=\"restore-panel\" role=\"status\" aria-live=\"polite\">\n            <mat-spinner diameter=\"40\"></mat-spinner>\n            <p class=\"restore-title\">Signing you back in…</p>\n            <p class=\"restore-hint\">Restoring your session — this can take a few seconds.</p>\n            <button id=\"btnManualLogin\" mat-button color=\"primary\" class=\"restore-manual\" (click)=\"signInManually()\">Use a different account</button>\n          </div>\n        </mat-card-content>\n\n        <!-- Added: automatic sign-in failed because the server was unreachable — explain before asking for credentials -->\n        <mat-card-content *ngIf=\"restoreOffline && !restoring\">\n          <div class=\"restore-note\" role=\"alert\">We couldn't sign you back in automatically — please check your connection and log in below.</div>\n        </mat-card-content>\n\n        <mat-card-content *ngIf=\"!restoring && (appConfig.localAuth || appConfig.ADAuth)\"> <!-- Changed: hidden while the silent restore runs -->\n\n          <div class=\"tin-input mt-2\">\n\n            <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\" style=\"margin-bottom: 20px;\"></spa-text>\n\n            <spa-text-mask id=\"txtPassword\" display=\"Password\" [(value)]=\"user.password\" (enterPress)=\"login()\"></spa-text-mask>\n\n            <!-- Changed: \"Keep me signed in\" now opt-in via appConfig.keepSignedIn -->\n            <mat-checkbox *ngIf=\"appConfig.keepSignedIn\" [(ngModel)]=\"rememberMe\" color=\"primary\" style=\"margin-top: 10px;\">Keep me signed in</mat-checkbox>\n\n          </div>\n\n        </mat-card-content>\n\n\n        <mat-card-actions style=\"margin-bottom: 10px;\" *ngIf=\"!restoring\"> <!-- Changed: no clickable sign-in options while the silent restore runs -->\n\n          <!-- Changed: Widths removed — all elements aligned to one column via .container CSS -->\n          <div class=\"button\" *ngIf=\"appConfig.localAuth || appConfig.ADAuth\">\n            <button id=\"btnLogin\" mat-flat-button [disabled]=\"isProcessing\" (click)=\"login()\" color=\"primary\">Login</button>\n          </div>\n\n          <!-- Changed: Show signup button whenever selfService is enabled, not just for local/AD auth -->\n          <div class=\"button\" *ngIf=\"appConfig.selfService\" >\n            <button  id=\"btnSignup\" mat-stroked-button color=\"primary\" (click)=\"signup()\">Create an account</button>\n          </div>\n\n          <div class=\"divider\" *ngIf=\"appConfig.googleAuth || appConfig.microsoftAuth\">\n            <span>OR</span>\n          </div>\n\n          <!-- Changed: Match modern Google button — pill shape + width aligned to the column -->\n          <div class=\"button\" *ngIf=\"appConfig.googleAuth\">\n            <asl-google-signin-button type='standard' width=\"350\" size='large' shape=\"pill\" logo_alignment=\"center\" style=\"text-align: center;\"></asl-google-signin-button> <!-- Changed: size 'medium' renders a 32px GSI button, 8px shorter than the 40px Material buttons; 'large' renders 40px so all three align -->\n          </div>\n\n          <div class=\"button\" *ngIf=\"appConfig.microsoftAuth\">\n            <button mat-stroked-button color=\"primary\" (click)=\"loginWithMS()\">{{appConfig.microsoftAuthMessage}}</button>\n          </div>\n\n        </mat-card-actions>\n\n      </mat-card>\n\n      <a *ngIf=\"appConfig.selfService && !restoring\" mat-button id=\"lnkRecover\" style=\"margin-top: 1em\" (click)=\"recoverAccount()\">Forgot your password ?</a> <!-- Changed: hidden while the silent restore runs -->\n\n\n\n\n    </div>\n  </div>\n\n\n <div *ngIf=\"style=='modern'\" class=\"modern-login\">\n  <mat-card class=\"login-card\">\n    <!-- Logo -->\n    <div class=\"logo-container\">\n        <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px\" />\n        <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px\" />\n        <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px\" />\n    </div>\n\n    <!-- Welcome text -->\n    <div class=\"header-section\"> <!-- Changed: Use custom div instead of mat-card-header -->\n      <h2 class=\"login-title\">{{appConfig.loginTitle ?? appConfig.appName}}</h2> <!-- Changed: Use h2 for title -->\n      <p class=\"login-subtitle\" *ngIf=\"appConfig.loginMessage\">{{appConfig.loginMessage}}</p> <!-- Changed: Use p for subtitle -->\n    </div>\n\n    <mat-card-content>\n      <!-- Added: silent-restore state — replaces the credential form while the session is being restored -->\n      <div class=\"restore-panel\" *ngIf=\"restoring\" role=\"status\" aria-live=\"polite\">\n        <mat-spinner diameter=\"40\"></mat-spinner>\n        <p class=\"restore-title\">Signing you back in…</p>\n        <p class=\"restore-hint\">Restoring your session — this can take a few seconds.</p>\n        <button id=\"btnManualLogin\" mat-button color=\"primary\" class=\"restore-manual\" (click)=\"signInManually()\">Use a different account</button>\n      </div>\n\n      <div class=\"login-form\" *ngIf=\"!restoring\"> <!-- Changed: hidden while the silent restore runs -->\n        <!-- Added: automatic sign-in failed because the server was unreachable — explain before asking for credentials -->\n        <div class=\"restore-note\" *ngIf=\"restoreOffline\" role=\"alert\">We couldn't sign you back in automatically — please check your connection and log in below.</div>\n        <!-- Username -->\n        <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"user.userName\" [appearance]=\"'outline'\" style=\"margin-bottom: 20px;\"></spa-text>\n\n        <!-- Password -->\n        <spa-text-mask id=\"txtPassword\" display=\"Password\" [(value)]=\"user.password\" [appearance]=\"'outline'\" (enterPress)=\"login()\"></spa-text-mask>\n\n        <!-- Changed: \"Keep me signed in\" now opt-in via appConfig.keepSignedIn -->\n        <mat-checkbox *ngIf=\"appConfig.keepSignedIn\" [(ngModel)]=\"rememberMe\" color=\"primary\" style=\"margin-top: 10px; margin-bottom: 10px;\">Keep me signed in</mat-checkbox>\n\n        <!-- Login Button -->\n        <div class=\"button-container\">\n          <button id=\"btnLogin\" mat-flat-button color=\"primary\" [disabled]=\"isProcessing\" (click)=\"login()\">\n            Login\n          </button>\n        </div>\n\n        <!-- Divider -->\n        <div class=\"divider\">\n          <span>OR</span>\n        </div>\n\n        <!-- Social Login -->\n        <div *ngIf=\"appConfig.googleAuth\" class=\"social-login\">\n          <asl-google-signin-button type='standard' size='large' width=\"320\" logo_alignment=\"center\" shape=\"pill\"></asl-google-signin-button> <!-- Changed: size 'medium' renders a 32px GSI button, 8px shorter than the 40px Material buttons; 'large' renders 40px so all three align -->\n        </div>\n\n         <!-- Microsoft Login -->\n        <div class=\"button\" *ngIf=\"appConfig.microsoftAuth\">\n          <button mat-stroked-button color=\"primary\" style=\"width: 350px;\" (click)=\"loginWithMS()\">{{appConfig.microsoftAuthMessage}}</button>\n        </div>\n\n        <!-- Links -->\n        <div class=\"links-container mb-5\">\n          <a *ngIf=\"appConfig.selfService\" mat-button id=\"lnkRecover\" color=\"primary\" (click)=\"recoverAccount()\">\n            Forgot password?\n          </a>\n\n          <div *ngIf=\"appConfig.selfService\" class=\"signup-container\">\n            <span>Don't have an account?</span>\n            <a mat-button id=\"btnSignup\" color=\"primary\" (click)=\"signup()\">Sign up</a>\n          </div>\n        </div>\n      </div>\n    </mat-card-content>\n\n    <mat-card-footer>\n      <div class=\"terms-container\">\n        <mat-divider></mat-divider>\n          <p class=\"terms-text\">\n            By continuing, you acknowledge that you accept our\n            <a mat-button color=\"primary\" class=\"terms-link\" (click)=\"openTerms()\">Terms and Conditions</a>\n            and\n            <a mat-button color=\"primary\" class=\"terms-link\" (click)=\"openPrivacy()\">Privacy Policy</a>.\n          </p>\n      </div>\n    </mat-card-footer>\n  </mat-card>\n</div>\n\n\n\n","import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; // Changed: Added ChangeDetectorRef for invitation toggle\nimport { Router } from '@angular/router';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { AuthService } from '../../services/auth.service';\nimport { StorageService } from '../../services/storage.service';\nimport { ApiResponse, AppConfig, Constants } from '../../classes/Classes';\nimport { HttpService } from '../../services/http.service';\nimport { SignupData, User } from '../../classes/LibClasses';\nimport { SocialAuthService, SocialUser } from '@abacritt/angularx-social-login';\nimport { MsalService } from '@azure/msal-angular';\nimport { NotificationsService } from '../../services/notifications.service';\nimport { SetupService } from '../../services/setup.service'; // Added: Setup readiness badge count after signup\nimport { MatDialog } from '@angular/material/dialog';\nimport { TermsDialogComponent } from '../../components/terms-dialog/terms-dialog.component';\nimport { PrivacyDialogComponent } from '../../components/privacy-dialog/privacy-dialog.component';\n\n// Rewritten: Step-based signup flow for Google/MSAL OAuth users\n@Component({\n    selector: 'spa-signup',\n    templateUrl: './signup.component.html',\n    styleUrls: ['./signup.component.css'],\n    standalone: false\n})\nexport class SignupComponent implements OnInit {\n\n  constructor(\n    private httpService: HttpService,\n    private messageService: MessageService,\n    public dataService: DataServiceLib,\n    public authService: AuthService,\n    private storageService: StorageService,\n    public router: Router,\n    private msalService: MsalService,\n    private notificationsService: NotificationsService,\n    private setupService: SetupService, // Added: SetupService for setup badge\n    private dialog: MatDialog,\n    private cdr: ChangeDetectorRef, // Changed: Inject ChangeDetectorRef for invitation toggle\n    private apiErrorService: ApiErrorService // Added: routes application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n  ) { }\n\n  ngOnInit() {\n    this.dataService.appConfigObserv.subscribe(x => this.appConfig = x);\n    this.style = this.dataService.appConfig.loginStyle ?? 'default';\n\n    // Check for pending signup data from login redirect\n    this.dataService.pendingSignup$.subscribe(data => {\n      if (data) {\n        this.signupData = data;\n        this.dataService.ClearPendingSignup();\n        // Skip provider step since we already have token from login\n        this.step = data.invitations.length > 0 ? 'invitations' : 'form';\n      }\n    });\n\n    // Listen for Google social login events (for direct /signup visits)\n    this.authService.socialUserObserv.subscribe((socialUser: SocialUser | null) => {\n      if (!socialUser || this.step !== 'provider') return;\n      this.handleProviderAuth(socialUser.idToken, socialUser.provider, socialUser.id);\n    });\n  }\n\n  appConfig = new AppConfig();\n  style: string = 'default';\n  signupData = new SignupData();\n  step: 'provider' | 'form' | 'invitations' | 'complete' = 'provider';\n  isProcessing: boolean = false;\n\n  // Handle provider authentication from direct /signup visit\n  handleProviderAuth(token: string, authType: string, userName: string) {\n    this.isProcessing = true;\n\n    // Use the login endpoint to validate token and get user details\n    let user = new User();\n    user.userName = userName;\n    user.password = userName;\n    user.token = token;\n    user.authType = authType;\n\n    this.dataService.Login(user).subscribe((apiResponse: ApiResponse) => {\n      this.isProcessing = false;\n\n      if (apiResponse.message == \"signup_required\" && apiResponse.data) {\n        // Expected: user doesn't exist, populate signup data\n        this.signupData.token = token;\n        this.signupData.authType = authType;\n        this.signupData.firstName = apiResponse.data.firstName;\n        this.signupData.lastName = apiResponse.data.lastName;\n        this.signupData.email = apiResponse.data.email;\n        this.signupData.orgName = apiResponse.data.firstName + \"'s Org\";\n        this.signupData.invitations = apiResponse.data.invitations || [];\n        this.step = this.signupData.invitations.length > 0 ? 'invitations' : 'form';\n      } else if (apiResponse.success) {\n        // User already exists, complete login normally\n        this.completeLogin(apiResponse);\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n      }\n    },\n    (error) => {\n      this.isProcessing = false;\n      this.messageService.toast(this.httpService.Error(error));\n    });\n  }\n\n  // Login with Microsoft from signup page\n  loginWithMS() {\n    // MSAL v3 throws uninitialized_public_client_application unless initialize() has\n    // completed; it is idempotent, so awaiting here is safe even when already done.\n    this.msalService.instance.initialize().then(() => this.doMsalLoginPopup(),\n      (error) => { console.error('MSAL initialize error:', error); this.messageService.toast(\"Microsoft login failed. Please try again.\"); });\n  }\n\n  private doMsalLoginPopup() {\n    this.msalService.loginPopup({\n      scopes: [\"openid\", \"profile\", \"email\"],\n    }).subscribe({\n      next: (response) => {\n        this.handleProviderAuth(response.idToken, 'MSAL', response.account.username);\n      },\n      error: (error) => {\n        console.error('MSAL login error:', error);\n        this.messageService.toast(\"Microsoft login failed. Please try again.\");\n      }\n    });\n  }\n\n  // Toggle invitation acceptance\n  toggleInvitation(invitation: any) {\n    invitation.accepted = !invitation.accepted;\n    this.cdr.detectChanges(); // Changed: Force change detection for invitation card icon update\n  }\n\n  // Submit signup form\n  submit() {\n    if (!this.signupData.termsAccepted) {\n      this.messageService.toast(\"Please accept the terms and conditions\");\n      return;\n    }\n\n    if (!this.signupData.firstName.trim() || !this.signupData.lastName.trim()) {\n      this.messageService.toast(\"Please enter your first and last name\");\n      return;\n    }\n\n    // For invitation flow, collect accepted invitation IDs\n    if (this.step === 'invitations') {\n      this.signupData.acceptedInvitationIds = this.signupData.invitations\n        .filter(inv => inv.accepted)\n        .map(inv => inv.memberID);\n\n      if (this.signupData.acceptedInvitationIds.length === 0) {\n        this.messageService.toast(\"Please accept at least one invitation\");\n        return;\n      }\n    }\n\n    this.isProcessing = true;\n\n    this.dataService.Signup(this.signupData).subscribe((apiResponse: ApiResponse) => {\n      this.isProcessing = false;\n\n      if (apiResponse.success) {\n        // Store auth data and show completion\n        this.completeLogin(apiResponse);\n        this.step = 'complete';\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n      }\n    },\n    (error) => {\n      this.isProcessing = false;\n      this.messageService.toast(this.httpService.Error(error));\n    });\n  }\n\n  // Store auth data (same pattern as login component)\n  completeLogin(apiResponse: ApiResponse) {\n    this.authService.Updateloggedin(true);\n    this.authService.UpdateToken(apiResponse.data.token);\n    this.storageService.store(Constants.AUTH_TOKEN, apiResponse.data.token);\n    this.authService.UpdateTokenExpire(apiResponse.data.expiration);\n    this.storageService.store(Constants.AUTH_TOKEN_EXPIRE, apiResponse.data.expiration);\n    this.authService.UpdateCurrentUser(this.signupData.email.toUpperCase());\n    this.storageService.store(Constants.AUTH_USER, this.signupData.email.toUpperCase());\n    this.authService.updateLoggedUserFullName(apiResponse.data.firstName);\n    this.storageService.store(Constants.AUTH_NAME, apiResponse.data.firstName);\n    this.authService.UpdateRole(apiResponse.data.role);\n    this.storageService.store(Constants.AUTH_ROLES, JSON.stringify(apiResponse.data.role));\n    this.authService.updateTenantName(apiResponse.data.tenantName);\n    this.storageService.store(Constants.AUTH_TENANT_NAME, apiResponse.data.tenantName);\n    this.dataService.ClearCache();\n\n    if (this.appConfig.multitenant) {\n      this.notificationsService.loadNotifications();\n      this.setupService.loadCount(); // Added: Load setup readiness badge count after signup\n    }\n  }\n\n  // Navigate to dashboard after signup completion\n  goToDashboard() {\n    this.router.navigate([\"home\"]);\n  }\n\n  // Navigate back to login\n  goToLogin() {\n    this.router.navigate([\"login\"]);\n  }\n\n  // Open terms dialog or URL\n  openTerms() {\n    if (this.appConfig.termsUrl && this.appConfig.termsUrl.trim() !== '') {\n      window.open(this.appConfig.termsUrl, '_blank');\n    } else {\n      this.dialog.open(TermsDialogComponent, { width: '600px', maxHeight: '80vh', panelClass: this.dataService?.dialogPanelClass ?? [] });\n    }\n  }\n\n  // Open privacy dialog or URL\n  openPrivacy() {\n    if (this.appConfig.privacyUrl && this.appConfig.privacyUrl.trim() !== '') {\n      window.open(this.appConfig.privacyUrl, '_blank');\n    } else {\n      this.dialog.open(PrivacyDialogComponent, { width: '600px', maxHeight: '80vh', panelClass: this.dataService?.dialogPanelClass ?? [] });\n    }\n  }\n}\n","<!-- Modern Style -->\n<div *ngIf=\"style=='modern'\" class=\"modern-signup\">\n  <mat-card class=\"signup-card\">\n\n    <!-- Logo -->\n    <div class=\"logo-container\">\n      <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px\" />\n      <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px\" />\n      <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px\" />\n    </div>\n\n    <!-- Provider Step -->\n    <div *ngIf=\"step === 'provider'\">\n      <div class=\"header-section\">\n        <h2 class=\"signup-title\">Create your account</h2>\n        <p class=\"signup-subtitle\">Get started with {{appConfig.appName}}</p>\n      </div>\n\n      <div class=\"provider-buttons\">\n        <div *ngIf=\"appConfig.googleAuth\" class=\"social-login\">\n          <asl-google-signin-button type='standard' size='medium' width=\"320\" logo_alignment=\"center\" shape=\"pill\"></asl-google-signin-button>\n        </div>\n\n        <div class=\"button\" *ngIf=\"appConfig.microsoftAuth\">\n          <button mat-stroked-button color=\"primary\" (click)=\"loginWithMS()\">{{appConfig.microsoftAuthMessage ?? 'Continue with Microsoft'}}</button>\n        </div>\n      </div>\n\n      <div class=\"links-container\">\n        <div class=\"login-link-container\">\n          <span>Already have an account?</span>\n          <a mat-button color=\"primary\" (click)=\"goToLogin()\">Log in</a>\n        </div>\n      </div>\n    </div>\n\n    <!-- Form Step (New Org) -->\n    <div *ngIf=\"step === 'form'\">\n      <div class=\"header-section\">\n        <h2 class=\"signup-title\">Almost there</h2>\n        <p class=\"signup-subtitle\">Confirm your details to get started</p>\n      </div>\n\n      <div class=\"signup-form\">\n        <div class=\"name-row\">\n          <mat-form-field appearance=\"outline\" class=\"name-field\">\n            <mat-label>First Name</mat-label>\n            <input matInput [(ngModel)]=\"signupData.firstName\">\n          </mat-form-field>\n\n          <mat-form-field appearance=\"outline\" class=\"name-field\">\n            <mat-label>Last Name</mat-label>\n            <input matInput [(ngModel)]=\"signupData.lastName\">\n          </mat-form-field>\n        </div>\n\n        <mat-form-field appearance=\"outline\" class=\"full-width\">\n          <mat-label>Email</mat-label>\n          <input matInput [value]=\"signupData.email\" readonly>\n        </mat-form-field>\n\n        <mat-form-field appearance=\"outline\" class=\"full-width\">\n          <mat-label>Organisation Name</mat-label>\n          <input matInput [(ngModel)]=\"signupData.orgName\">\n        </mat-form-field>\n\n        <mat-checkbox [(ngModel)]=\"signupData.termsAccepted\" color=\"primary\" class=\"terms-checkbox\">\n          I agree to the\n          <a (click)=\"openTerms(); $event.preventDefault()\" class=\"terms-link\">Terms and Conditions</a>\n          and\n          <a (click)=\"openPrivacy(); $event.preventDefault()\" class=\"terms-link\">Privacy Policy</a>\n        </mat-checkbox>\n\n        <div class=\"button-container\">\n          <button mat-flat-button color=\"primary\" [disabled]=\"isProcessing\" (click)=\"submit()\">\n            <mat-spinner *ngIf=\"isProcessing\" diameter=\"20\" class=\"inline-spinner\"></mat-spinner>\n            <span *ngIf=\"!isProcessing\">Create Account</span>\n          </button>\n        </div>\n\n        <div class=\"links-container\">\n          <a mat-button color=\"primary\" (click)=\"goToLogin()\">Back to Login</a>\n        </div>\n      </div>\n    </div>\n\n    <!-- Invitations Step (Join Existing Org) -->\n    <div *ngIf=\"step === 'invitations'\">\n      <div class=\"header-section\">\n        <mat-icon class=\"invite-icon\" color=\"primary\">mail</mat-icon>\n        <h2 class=\"signup-title\">You've been invited!</h2>\n        <p class=\"signup-subtitle\">Accept an invitation to get started</p>\n      </div>\n\n      <div class=\"signup-form\">\n        <div class=\"invitation-list\">\n          <mat-card *ngFor=\"let inv of signupData.invitations\" class=\"invitation-card\" [class.accepted]=\"inv.accepted\" (click)=\"toggleInvitation(inv)\">\n            <div class=\"invitation-content\">\n              <mat-icon [color]=\"inv.accepted ? 'primary' : ''\">{{inv.accepted ? 'check_circle' : 'circle'}}</mat-icon>\n              <span class=\"invitation-org-name\">{{inv.tenantName}}</span>\n            </div>\n          </mat-card>\n        </div>\n\n        <div class=\"name-row\">\n          <mat-form-field appearance=\"outline\" class=\"name-field\">\n            <mat-label>First Name</mat-label>\n            <input matInput [(ngModel)]=\"signupData.firstName\">\n          </mat-form-field>\n\n          <mat-form-field appearance=\"outline\" class=\"name-field\">\n            <mat-label>Last Name</mat-label>\n            <input matInput [(ngModel)]=\"signupData.lastName\">\n          </mat-form-field>\n        </div>\n\n        <mat-checkbox [(ngModel)]=\"signupData.termsAccepted\" color=\"primary\" class=\"terms-checkbox\">\n          I agree to the\n          <a (click)=\"openTerms(); $event.preventDefault()\" class=\"terms-link\">Terms and Conditions</a>\n          and\n          <a (click)=\"openPrivacy(); $event.preventDefault()\" class=\"terms-link\">Privacy Policy</a>\n        </mat-checkbox>\n\n        <div class=\"button-container\">\n          <button mat-flat-button color=\"primary\" [disabled]=\"isProcessing\" (click)=\"submit()\">\n            <mat-spinner *ngIf=\"isProcessing\" diameter=\"20\" class=\"inline-spinner\"></mat-spinner>\n            <span *ngIf=\"!isProcessing\">Complete Signup</span>\n          </button>\n        </div>\n\n        <div class=\"links-container\">\n          <a mat-button color=\"primary\" (click)=\"goToLogin()\">Back to Login</a>\n        </div>\n      </div>\n    </div>\n\n    <!-- Complete Step -->\n    <div *ngIf=\"step === 'complete'\" class=\"complete-section\">\n      <mat-icon class=\"complete-icon\">check_circle</mat-icon>\n      <h2 class=\"signup-title\">You're all set!</h2>\n      <p class=\"signup-subtitle\">Welcome to {{appConfig.appName}}</p>\n      <div class=\"button-container\">\n        <button mat-flat-button color=\"primary\" (click)=\"goToDashboard()\">Go to Dashboard</button>\n      </div>\n    </div>\n\n  </mat-card>\n</div>\n\n\n<!-- Default Style -->\n<div *ngIf=\"style=='default'\" class=\"default-signup background tin-bg-login\">\n  <div class=\"container\">\n\n    <div class=\"logo\">\n      <img *ngIf=\"appConfig.logoSize=='normal'\" [src]=\"appConfig.logo\" style=\"width: 100px\" />\n      <img *ngIf=\"appConfig.logoSize=='medium'\" [src]=\"appConfig.logo\" style=\"width: 150px\" />\n      <img *ngIf=\"appConfig.logoSize=='large'\" [src]=\"appConfig.logo\" style=\"width: 250px\" />\n    </div>\n\n    <mat-card class=\"mat-elevation-z3\" style=\"width:400px;\">\n\n      <!-- Provider Step -->\n      <div *ngIf=\"step === 'provider'\">\n        <mat-card-header style=\"margin-bottom: 30px; margin-top: 30px;\">\n          <mat-card-title style=\"font-size: 28px; margin-bottom: 10px; margin-top: 20px; font-weight: 300\">Create Account</mat-card-title>\n          <mat-card-subtitle>Get started with {{appConfig.appName}}</mat-card-subtitle>\n        </mat-card-header>\n\n        <mat-card-actions style=\"margin-bottom: 10px;\">\n          <div *ngIf=\"appConfig.googleAuth\" class=\"button\">\n            <asl-google-signin-button type='standard' width=\"320px\" size='medium' logo_alignment=\"center\" style=\"text-align: center;\"></asl-google-signin-button>\n          </div>\n\n          <div class=\"button\" *ngIf=\"appConfig.microsoftAuth\">\n            <button mat-stroked-button color=\"primary\" style=\"width: 350px;\" (click)=\"loginWithMS()\">{{appConfig.microsoftAuthMessage ?? 'Continue with Microsoft'}}</button>\n          </div>\n\n          <div class=\"button\" style=\"margin-top: 20px;\">\n            <a mat-button color=\"primary\" (click)=\"goToLogin()\">Already have an account? Log in</a>\n          </div>\n        </mat-card-actions>\n      </div>\n\n      <!-- Form Step (New Org) -->\n      <div *ngIf=\"step === 'form'\">\n        <mat-card-header style=\"margin-bottom: 20px; margin-top: 20px;\">\n          <mat-card-title style=\"font-size: 28px; margin-bottom: 10px; font-weight: 300\">Almost there</mat-card-title>\n          <mat-card-subtitle>Confirm your details to get started</mat-card-subtitle>\n        </mat-card-header>\n\n        <mat-card-content>\n          <div class=\"signup-form-default\">\n            <mat-form-field class=\"full-width\">\n              <mat-label>First Name</mat-label>\n              <input matInput [(ngModel)]=\"signupData.firstName\">\n            </mat-form-field>\n\n            <mat-form-field class=\"full-width\">\n              <mat-label>Last Name</mat-label>\n              <input matInput [(ngModel)]=\"signupData.lastName\">\n            </mat-form-field>\n\n            <mat-form-field class=\"full-width\">\n              <mat-label>Email</mat-label>\n              <input matInput [value]=\"signupData.email\" readonly>\n            </mat-form-field>\n\n            <mat-form-field class=\"full-width\">\n              <mat-label>Organisation Name</mat-label>\n              <input matInput [(ngModel)]=\"signupData.orgName\">\n            </mat-form-field>\n\n            <mat-checkbox [(ngModel)]=\"signupData.termsAccepted\" color=\"primary\" class=\"terms-checkbox\">\n              I agree to the\n              <a (click)=\"openTerms(); $event.preventDefault()\" class=\"terms-link\">Terms</a>\n              and\n              <a (click)=\"openPrivacy(); $event.preventDefault()\" class=\"terms-link\">Privacy Policy</a>\n            </mat-checkbox>\n          </div>\n        </mat-card-content>\n\n        <mat-card-actions style=\"margin-bottom: 10px;\">\n          <div class=\"button\">\n            <button mat-flat-button color=\"primary\" style=\"width: 350px;\" [disabled]=\"isProcessing\" (click)=\"submit()\">\n              <mat-spinner *ngIf=\"isProcessing\" diameter=\"20\" class=\"inline-spinner\"></mat-spinner>\n              <span *ngIf=\"!isProcessing\">Create Account</span>\n            </button>\n          </div>\n          <div class=\"button\">\n            <a mat-button color=\"primary\" (click)=\"goToLogin()\">Back to Login</a>\n          </div>\n        </mat-card-actions>\n      </div>\n\n      <!-- Invitations Step -->\n      <div *ngIf=\"step === 'invitations'\">\n        <mat-card-header style=\"margin-bottom: 20px; margin-top: 20px;\">\n          <mat-card-title style=\"font-size: 28px; margin-bottom: 10px; font-weight: 300\">You've been invited!</mat-card-title>\n          <mat-card-subtitle>Accept an invitation to get started</mat-card-subtitle>\n        </mat-card-header>\n\n        <mat-card-content>\n          <div class=\"signup-form-default\">\n            <div class=\"invitation-list\">\n              <mat-card *ngFor=\"let inv of signupData.invitations\" class=\"invitation-card\" [class.accepted]=\"inv.accepted\" (click)=\"toggleInvitation(inv)\">\n                <div class=\"invitation-content\">\n                  <mat-icon [color]=\"inv.accepted ? 'primary' : ''\">{{inv.accepted ? 'check_circle' : 'circle'}}</mat-icon>\n                  <span class=\"invitation-org-name\">{{inv.tenantName}}</span>\n                </div>\n              </mat-card>\n            </div>\n\n            <mat-form-field class=\"full-width\">\n              <mat-label>First Name</mat-label>\n              <input matInput [(ngModel)]=\"signupData.firstName\">\n            </mat-form-field>\n\n            <mat-form-field class=\"full-width\">\n              <mat-label>Last Name</mat-label>\n              <input matInput [(ngModel)]=\"signupData.lastName\">\n            </mat-form-field>\n\n            <mat-checkbox [(ngModel)]=\"signupData.termsAccepted\" color=\"primary\" class=\"terms-checkbox\">\n              I agree to the\n              <a (click)=\"openTerms(); $event.preventDefault()\" class=\"terms-link\">Terms</a>\n              and\n              <a (click)=\"openPrivacy(); $event.preventDefault()\" class=\"terms-link\">Privacy Policy</a>\n            </mat-checkbox>\n          </div>\n        </mat-card-content>\n\n        <mat-card-actions style=\"margin-bottom: 10px;\">\n          <div class=\"button\">\n            <button mat-flat-button color=\"primary\" style=\"width: 350px;\" [disabled]=\"isProcessing\" (click)=\"submit()\">\n              <mat-spinner *ngIf=\"isProcessing\" diameter=\"20\" class=\"inline-spinner\"></mat-spinner>\n              <span *ngIf=\"!isProcessing\">Complete Signup</span>\n            </button>\n          </div>\n          <div class=\"button\">\n            <a mat-button color=\"primary\" (click)=\"goToLogin()\">Back to Login</a>\n          </div>\n        </mat-card-actions>\n      </div>\n\n      <!-- Complete Step -->\n      <div *ngIf=\"step === 'complete'\" class=\"complete-section-default\">\n        <mat-icon class=\"complete-icon-default\">check_circle</mat-icon>\n        <h3 style=\"font-weight: 300; font-size: 28px;\">You're all set!</h3>\n        <p style=\"color: rgba(0,0,0,0.6);\">Welcome to {{appConfig.appName}}</p>\n        <div class=\"button\" style=\"margin-bottom: 20px;\">\n          <button mat-flat-button color=\"primary\" style=\"width: 350px;\" (click)=\"goToDashboard()\">Go to Dashboard</button>\n        </div>\n      </div>\n\n    </mat-card>\n\n  </div>\n</div>\n","import { Component, OnInit } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { AuthService } from '../../services/auth.service';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { ApiResponse } from '../../classes/Classes';\nimport { Location } from '@angular/common';\nimport { User } from '../../classes/LibClasses';\n\n@Component({\n    selector: 'spa-recover-account',\n    templateUrl: './recover-account.component.html',\n    styleUrls: ['./recover-account.component.css'],\n    standalone: false\n})\nexport class RecoverAccountComponent implements OnInit {\n\n  constructor(private location: Location, private dataService: DataServiceLib, public authService: AuthService, private messageService: MessageService, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService to route application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n\n  ngOnInit() {\n  }\n\n  userName: string = \"\";\n\n  recover(){\n\n\n    if (this.userName == \"\") {\n\n      this.messageService.toast(\"Please enter your userName\");\n      return;\n    } else {\n      let u = new User();\n      u.userName = this.userName;\n\n      this.dataService.SelfReset(u).subscribe((apiResponse: ApiResponse) => {\n        if (apiResponse.message == \"success\") {\n          this.messageService.toast(\"The password has been sent to your email\");\n          this.location.back();\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n        }\n      });\n    }\n  }\n\n\n}\n","\n<div class=\"container\" style=\"padding-top: 30px;\">\n<h4>Recover Account</h4>\n\n<hr />\n\nSubmit your Username and we will send you details to your registered email address.\n\n<div style=\"font-size: 14px;\">\n  <spa-text class=\"mt-3\" display=\"Username\" [(value)]=\"userName\"></spa-text>\n\n  <div class=\"tin-center\">\n    <button class=\"mt-3 w-50\" mat-raised-button color=\"primary\" (click)=\"recover()\" cdkFocusInitial>Submit</button>\n  </div>\n\n</div>\n\n</div>\n\n","import { SpaMatModule } from \"./spa-mat.module\";\nimport { Injector, NgModule, NgZone, Optional, SkipSelf } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport { FormsModule, ReactiveFormsModule } from \"@angular/forms\";\nimport { LoginComponent } from \"../pages/login/login.component\";\nimport { SignupComponent } from \"../pages/signup/signup.component\";\nimport { RecoverAccountComponent } from \"../pages/recover-account/recover-account.component\";\nimport { TinSpaModule } from \"../tin-spa.module\";\nimport { SocialAuthService, SocialAuthServiceConfig, SocialLoginModule } from \"@abacritt/angularx-social-login\";\n\n@NgModule({\n  declarations: [LoginComponent, SignupComponent, RecoverAccountComponent],\n\n\n\n  imports: [\n    ReactiveFormsModule.withConfig({ warnOnNgModelWithFormControl: \"never\" }),\n    CommonModule,\n    FormsModule,\n    ReactiveFormsModule,\n    TinSpaModule,\n    SocialLoginModule\n  ],\n\n  exports: [\n    CommonModule,\n    FormsModule,\n    TinSpaModule,\n    LoginComponent,\n    SignupComponent,\n    RecoverAccountComponent,\n  ],\n\n  // Added (2026-08-19): kills the duplicate `google.accounts.id.initialize()` reported on every login page load\n  // (\"[GSI_LOGGER]: google.accounts.id.initialize() is called multiple times\").\n  //\n  // The cause is that the vendor registers SocialAuthService TWICE, in two different ways:\n  //   1. `@Injectable({ providedIn: 'root' })` on the service itself, and\n  //   2. `providers: [SocialAuthService]` on SocialLoginModule, which this module imports.\n  // Its constructor calls each login provider's initialize(), and GoogleLoginProvider.initialize() is what\n  // calls google.accounts.id.initialize(). So one instance == one GSI init.\n  //\n  // Consumers load this module LAZILY (test-spa app-routing.module.ts:16 loadChildren -> IndexModule ->\n  // SpaIndexModule), which gives it its own child environment injector. Route (2) therefore builds a SECOND\n  // SocialAuthService there, while AuthService (providedIn: 'root', auth.service.ts:32 injects\n  // SocialAuthService) has already built the ROOT one at bootstrap. Two instances, two GSI inits.\n  //\n  // Overriding the token here wins over the one inherited from the SocialLoginModule import, so the lazy\n  // injector reuses the root instance instead of constructing its own. The fallback covers a consumer that\n  // imports SpaIndexModule EAGERLY: there is then no parent holding the root record, so this provider is the\n  // only one and constructs exactly once. Either way the app ends up with one SocialAuthService and one\n  // google.accounts.id.initialize() per page load.\n  providers: [\n    {\n      provide: SocialAuthService,\n      useFactory: (parent: Injector | null, config: SocialAuthServiceConfig | null, zone: NgZone, injector: Injector) =>\n        (parent && parent.get(SocialAuthService, null)) || new SocialAuthService(config as SocialAuthServiceConfig, zone, injector),\n      deps: [[new Optional(), new SkipSelf(), Injector], [new Optional(), 'SocialAuthServiceConfig'], NgZone, Injector]\n    }\n  ],\n})\nexport class SpaIndexModule {}\n","\nimport { ApiResponse } from './../../classes/Classes';\nimport { Component, OnInit } from '@angular/core';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { AuthService } from '../../services/auth.service';\nimport { Location } from '@angular/common';\nimport { HttpService } from '../../services/http.service';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { ChangeUserPassword } from '../../classes/LibClasses';\nimport { PasswordPolicyService, PasswordRequirement, PasswordPolicyDescription } from '../../services/password-policy.service'; // Added: the rule shown here is now generated from the tenant's PasswordConfig instead of being hard-coded in the template\n\n@Component({\n    selector: 'spa-change-password',\n    templateUrl: './change-password.component.html',\n    styleUrls: ['./change-password.component.css'],\n    standalone: false\n})\nexport class ChangePasswordComponent implements OnInit {\n\n  constructor(public router: Router, private location: Location, private httpService: HttpService, private messageService: MessageService, public dataService: DataServiceLib, private authService: AuthService, private route: ActivatedRoute, private apiErrorService: ApiErrorService, private passwordPolicyService: PasswordPolicyService) { } // Changed: injected ApiErrorService to route application-level (HTTP 200, success:false) failures through the shared classify + dedupe path; Changed: injected PasswordPolicyService so the requirements panel states the policy that will actually refuse this user\n\n  ngOnInit() {\n    this.myRole = this.authService.currentRoleSource.value\n    this.loadRequirements(); // Added: the panel was five hard-coded lines, two of which were wrong\n\n    // Added: SUBSCRIBED, not read once. On a cold direct-URL load checkAuthentication restores the auth type\n    // from storage in a promise that is not awaited, so a single read in ngOnInit can land before it resolves\n    // and see the empty (unknown) value. The BehaviorSubject replays the current value immediately and then\n    // corrects it, which also keeps the panel right across a silent refresh.\n    this.authService.authTypeObserv.subscribe(() => this.showRequirements = this.authService.isLocalAuth());\n\n    if (this.dataService.tmpProfileuserName==\"\"){\n      this.changePassword.userName = this.authService.currentUser;\n\n    }else{\n      this.changePassword.userName = this.dataService.tmpProfileuserName;\n      this.dataService.tmpProfileuserName = \"\";\n    }\n\n    if (this.route.snapshot.queryParams[\"redirectTo\"] != undefined) {\n      this.redirectPath = this.route.snapshot.queryParams[\"redirectTo\"]\n    } else {\n      this.redirectPath = \"home\"\n    }\n\n  }\n\n  myRole;\n  redirectPath\n  isProcessing: boolean = false;\n  changePassword = new ChangeUserPassword();\n\n  // Added: MATERIALIZED, never a template-bound getter — an *ngFor handed a freshly-allocated array on every\n  // change-detection pass is the livelock the table/day-book pages already paid for once.\n  requirements: PasswordRequirement[] = [];\n  effectiveLength = 0;\n  effectiveLengthBinds = false;\n\n  // Added: the local password policy is only true for password-backed accounts. Both UI entry points to this\n  // page are already gated to local (login.component.ts:227, profile.component.html:28), so an AD user only\n  // arrives here by typing the URL — but arriving here they were told to satisfy rules we do not enforce and\n  // cannot apply, since we hold no password for them. Seeded TRUE, matching isLocalAuth's fail-open direction.\n  showRequirements = true;\n\n  // Seeded SYNCHRONOUSLY with the legacy wording before the request goes out, so the panel is never blank — not\n  // even for the frame before the policy arrives, and not if the request never comes back. A user asked to invent\n  // a password with no stated rule, who is then refused by one, is worse off than a user shown a stale rule.\n  // (Deliberately seeded here rather than in a field initializer: with useDefineForClassFields the injected\n  // service is not assigned yet when field initializers run.)\n  private loadRequirements() {\n    this.applyDescription(this.passwordPolicyService.describe(PasswordPolicyService.LegacyDefaults));\n    this.passwordPolicyService.getDescription().subscribe(described => this.applyDescription(described));\n  }\n\n  private applyDescription(described: PasswordPolicyDescription) {\n    this.requirements = described.requirements.filter(r => r.required); // a rule switched off is not something the user must DO, so it is dropped rather than listed as \"No number required\"\n    this.effectiveLength = described.effectiveLength;\n    this.effectiveLengthBinds = described.effectiveLengthBinds;\n  }\n\n  public change() {\n\n    if (!this.myRole[this.dataService.capUsers.name]){\n      if (this.changePassword.currentPassword == \"\") {\n        this.messageService.toast(\"Please enter current Password\");\n        return;\n      }\n    }\n\n    if (this.changePassword.newPassword == \"\") {\n      this.messageService.toast(\"Please enter new Password\");\n      return;\n    }\n\n    if (this.changePassword.confirmPassword == \"\") {\n      this.messageService.toast(\"Please confirm new Password\");\n      return;\n    }\n\n    if (this.changePassword.confirmPassword != this.changePassword.newPassword ) {\n      this.messageService.toast(\"Passwords do not match\");\n      return;\n    }\n\n    this.isProcessing = true;\n\n    if (this.myRole[this.dataService.capUsers.name]){\n\n\n      this.dataService.ChangePasswordAdmin(this.changePassword).subscribe((apiResponse: ApiResponse) => {\n        this.isProcessing = false;\n\n        if (apiResponse.message == \"success\") {\n          this.messageService.toast(\"Password Changed\");\n\n          this.router.navigate([this.redirectPath]);\n\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n        }\n      }\n      );\n\n    }else{\n\n      this.dataService.ChangePassword(this.changePassword).subscribe((apiResponse: ApiResponse) => {\n        this.isProcessing = false;\n\n        if (apiResponse.message == \"success\") {\n          this.messageService.toast(\"Password Changed\");\n\n          this.router.navigate([this.redirectPath]);\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n        }\n      }\n      );\n\n    }\n  }\n}\n","<h4>Change Password</h4>\n<hr>\n\n\n<div class=\"container tin-grid\" style=\"font-size:14px;\">\n\n  <div class=\"fill\">\n\n    <spa-text id=\"txtuserName\" display=\"Username\" [(value)]=\"changePassword.userName\"  [readonly]=\"true\"></spa-text>\n    <spa-text-mask id=\"txtPassword\" display=\"Current Password\" [(value)]=\"changePassword.currentPassword\"  type=\"password\"></spa-text-mask>\n    <spa-text-mask id=\"txtNewPassword\" display=\"New Password\" [(value)]=\"changePassword.newPassword\" type=\"password\"></spa-text-mask>\n    <spa-text-mask id=\"txtConfirmPassword\" display=\"Confirm Password\" [(value)]=\"changePassword.confirmPassword\"  type=\"password\"></spa-text-mask>\n    <button id=\"btnChange\" mat-raised-button color=\"primary\" (click)=\"change()\" cdkFocusInitial>Change</button>\n\n  </div>\n\n      <!-- Changed: these five lines were hard-coded, and two of them were WRONG — \"At least 2 lowercase letters\"\n           against a rule that has only ever required 1, and no line at all reflected a tenant's configured policy.\n           They are now generated by PasswordPolicyService from the same PasswordConfig row the server validates\n           against, so this panel and the refusal cannot disagree. Same panel, same typography, same placement —\n           only the words are now true. -->\n      <!-- Changed: gated on showRequirements — these rules describe the LOCAL password policy, so an AD/external\n           account reaching this page by direct URL must not be shown requirements we neither enforce nor own.\n           Only the panel is gated; the form, its typography and its placement are untouched. -->\n      <div class=\"alert alert-info\" style=\"font-size: 14px;\" role=\"alert\" *ngIf=\"showRequirements\">\n        <b>*Please consider these requirements for your new password.</b> <br><br>\n\n        <ng-container *ngFor=\"let requirement of requirements\">{{ requirement.text }}<br></ng-container>\n\n        <!-- Plain arithmetic, not a rule of its own: the character-class minimums are counted inside the length, so\n             their sum can bind above the configured minimum length. Shown only when it actually differs, matching\n             the Password Policy admin page. -->\n        <ng-container *ngIf=\"effectiveLengthBinds\">\n          <br>Nothing shorter than {{ effectiveLength }} characters can pass.\n        </ng-container>\n\n      </div>\n\n</div>\n","import { AuthService } from './../../services/auth.service';\nimport { MessageService } from './../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { Component, Input, OnInit } from '@angular/core';\nimport { ApiResponse, AppConfig } from '../../classes/Classes';\nimport { Router } from '@angular/router';\nimport { HttpService } from '../../services/http.service';\nimport { Profile } from '../../classes/LibClasses';\n\n@Component({\n    selector: 'spa-profile',\n    templateUrl: './profile.component.html',\n    styleUrls: ['./profile.component.css'],\n    standalone: false\n})\nexport class ProfileComponent implements OnInit {\n\n  constructor(public dataService: DataServiceLib, private messageService: MessageService, private httpService: HttpService, private router: Router, private authService: AuthService, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService to route application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n\n  ngOnInit() {\n\n    this.myRole = this.authService.currentRoleSource.value\n\n    if (this.dataService.tmpProfileuserName==\"\"){\n      this.loadProfile(this.authService.currentUser);\n\n    }else{\n      this.loadProfile(this.dataService.tmpProfileuserName);\n      this.dataService.tmpProfileuserName = \"\";\n    }\n\n\n\n  }\n\n  isProcessing: boolean;\n  myRole;\n  initials = \"\";\n  @Input() appConfig = new AppConfig();\n\n\n  selfProfile : boolean = false;\n\n  profile = new Profile ;\n  roles;\n  approvalRoles;\n  employees;\n\n\n  loadProfile(userName: string){\n\n    let action = \"all\";\n\n    this.dataService.GetUserByID(userName).subscribe( (apiResponse: ApiResponse) => {\n\n        this.profile = apiResponse.data;\n\n        if (this.profile.userName.toLocaleLowerCase() == this.authService.currentUser.toLocaleLowerCase()){\n          this.selfProfile = true\n        }\n        this.loadRoles()\n        this.initials = `${this.profile.firstName?.toUpperCase().charAt(0)}${this.profile.lastName?.toUpperCase().charAt(0)}`\n      },\n      (error) => {\n        this.isProcessing = false;\n        this.messageService.toast(this.httpService.Error(error));\n      }\n    );\n  }\n\n  loadRoles(){\n\n    this.dataService.GetRole(\"all\", \"\").subscribe(\n      (apiResponse: ApiResponse) => {\n        this.roles = apiResponse;\n      },\n      (error) => {\n        this.isProcessing = false;\n        this.messageService.toast(this.httpService.Error(error));\n      }\n    );\n\n  }\n\n  changePassword(){\n    this.dataService.tmpProfileuserName = this.profile.userName;\n    this.router.navigate([\"home/user/change-password\"]);\n  }\n\n  gotoUsers(){\n    this.router.navigate([\"home/admin/users\"]);\n  }\n\n  update(){\n\n  }\n\n  updateProfile(){\n    this.isProcessing = true;\n\n    // return\n    this.dataService.UpdateUser(this.profile).subscribe(\n      (apiResponse: ApiResponse) => {\n        this.isProcessing = false;\n\n        if (apiResponse.success) {\n          this.messageService.toast(\"Profile Updated\");\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n        }\n      },\n      (error) => {\n        this.messageService.toast(\"Connection failed \");\n        this.isProcessing = false;\n      }\n    );\n   }\n\n}\n","\n<h4>Profile</h4>\n<hr>\n\n<div class=\"container tin-grid-auto\" style=\"font-size:14px;\">\n\n  <div class=\"tin-center centa\">\n    <div class=\"profileImage\">{{initials}}</div>\n    <mat-label id=\"lbluserName\" >{{profile?.userName}}</mat-label>\n  </div>\n\n  <div>\n\n    <spa-text id=\"txtFirstName\" display=\"First Name\" [(value)]=\"profile.firstName\" [readonly]=\"selfProfile\"></spa-text>\n    <spa-text id=\"txtLastName\" display=\"Last Name\" [(value)]=\"profile.lastName\" [readonly]=\"selfProfile\"></spa-text>\n    <spa-text id=\"txtAuth\" display=\"Authentication\" [(value)]=\"profile.authType\" [readonly]=\"true\"></spa-text>\n    <spa-text id=\"txtEmail\" display=\"Email\" [(value)]=\"profile.email\" [readonly]=\"selfProfile\"></spa-text>\n    <spa-text id=\"txtRole\" display=\"Role\" [(value)]=\"profile.role.roleName\" [readonly]=\"selfProfile\"></spa-text>\n    <!-- <spa-select id=\"cboRole\" display=\"Role\" [options]=\"roles\" optionDisplay=\"roleName\" optionValue=\"roleID\" [(value)]=\"profile.roleID\" [readonly]=\"selfProfile\"></spa-select> -->\n    <spa-label *ngIf=\"dataService.appConfig.multitenant\" display=\"Code\" [value]=\"profile.code\" ></spa-label>\n\n    <button id=\"btnUpdate\" class=\"w-100\"   mat-raised-button color=\"primary\" *ngIf=\"!selfProfile\" [disabled]=\"isProcessing\" (click)=\"updateProfile()\">Update Profile</button>\n  </div>\n\n\n  <div class=\"tin-center centa\">\n    <a mat-button id=\"lnkUserManager\" style=\"margin-left: 1em\" *ngIf=\"!selfProfile\" (click)=\"gotoUsers()\">User Manager</a>\n    <a mat-button id=\"lnkChangePassword\" style=\"margin-left: 1em\" *ngIf=\"(selfProfile || myRole[dataService.capUsers.name]) && profile.authType=='local'\" (click)=\"changePassword()\">Change Password</a>\n  </div>\n\n\n</div>\n\n\n\n\n\n","import { SpaMatModule } from \"./spa-mat.module\";\nimport { NgModule } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport { FormsModule, ReactiveFormsModule } from \"@angular/forms\";\nimport { ChangePasswordComponent } from \"../pages/change-password/change-password.component\";\nimport { ProfileComponent } from \"../pages/profile/profile.component\";\nimport { TinSpaModule } from \"../tin-spa.module\";\n\n@NgModule({\n  declarations: [ChangePasswordComponent, ProfileComponent],\n\n\n\n  imports: [\n    ReactiveFormsModule.withConfig({ warnOnNgModelWithFormControl: \"never\" }),\n    CommonModule,\n    FormsModule,\n    ReactiveFormsModule,\n    TinSpaModule\n  ],\n\n  exports: [\n    CommonModule,\n    FormsModule,\n    TinSpaModule,\n    ChangePasswordComponent,\n    ProfileComponent,\n  ],\n})\nexport class SpaUserModule {}\n","import { Component, OnInit } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { ApiResponse } from '../../classes/Classes';\n\n@Component({\n    selector: 'spa-settings',\n    templateUrl: './settings.component.html',\n    styleUrls: ['./settings.component.css'],\n    standalone: false\n})\nexport class SettingsComponent implements OnInit {\n\n  constructor(private dataService: DataServiceLib, private messageService: MessageService, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService to route application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n\n  ngOnInit(): void {\n    this.loadSettings();\n  }\n\n  _filterText = \"\";\n  settings;\n  isProcessing = false;\n\n  applyFilter(filterValue: string) {\n    this.settings.filter = filterValue.trim().toLowerCase();\n  }\n\n  loadSettings(){\n    this.dataService.GetSetting(\"all\", \"\").subscribe((apiResponse : ApiResponse) => {\n        this.settings = apiResponse.data;\n      }\n    );\n\n  }\n\n  updateSetting(setting) {\n\n    this.isProcessing = true;\n    this.dataService.UpdateSetting(setting, \"edit\").subscribe((apiResponse: ApiResponse) => {\n      this.isProcessing = false;\n\n      if (apiResponse.success) {\n        this.messageService.toast(`Setting ${setting.sName} Updated`);\n        this.loadSettings();\n\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n      }\n\n    });\n\n  };\n\n  addSetting() {\n\n    this.messageService.toast(\"Feature not Available\");\n\n  }\n\n}\n","<h4>Settings</h4>\n<hr>\n\n<div class=\"container\">\n\n  <div class=\"header-row\">\n    <button mat-raised-button (click)=\"loadSettings()\">Refresh</button>\n  </div>\n\n  <div class=\"tin-row setting-row\" *ngFor=\"let setting of settings\">\n\n    <mat-form-field *ngIf=\"!setting.encrypted\" class=\"setting-input\" subscriptSizing=\"dynamic\"><!-- Changed: added subscriptSizing=\"dynamic\" — this was the ONLY field in tin-spa still reserving the 20px subscript band (all 13 field components, including the spa-text-mask on the next line, already set it). That empty band pushed the control box 12.5px above the tick button and caption, which is what made the row read as misaligned. -->\n      <mat-label>{{setting.sName}}</mat-label>\n      <input matInput autocomplete=\"off\" [(ngModel)]=\"setting.sValue\">\n    </mat-form-field>\n\n    <spa-text-mask *ngIf=\"setting.encrypted\" class=\"setting-input\" [display]=\"setting.sName\" [(value)]=\"setting.sValue\"></spa-text-mask>\n\n    <button mat-mini-fab color=\"primary\" (click)=\"updateSetting(setting)\"><mat-icon>done_all</mat-icon></button>\n\n    <span class=\"setting-meta\">Last Updated by {{setting.updatedBy}} on {{setting.updatedDate | date: 'dd MMM yy HH:mm'}}</span>\n\n  </div>\n\n</div>\n\n","import { Component, OnInit } from '@angular/core';\nimport { DataServiceLib } from \"../../services/datalib.service\";\nimport { AuthService } from '../../services/auth.service';\nimport { PageConfig, TableConfig } from '../../classes/Classes';\n\n@Component({\n    selector: 'spa-logs',\n    templateUrl: './logs.component.html',\n    styleUrls: ['./logs.component.css'],\n    standalone: false\n})\nexport class LogsComponent implements OnInit {\n  constructor(private authService: AuthService, private dataService: DataServiceLib,) { }\n\n\n  logsPageConfig: PageConfig;\n\n  ngOnInit() {\n    this.authService.isAuthorised(this.dataService.capLogs.name);\n\n    this.initializeConfig();\n  }\n\n\n  private initializeConfig(): void {\n\n    const logsTableConfig: TableConfig = { // Changed: extracted so search mode can reuse the identical columns\n        showFilter: true,\n        minColumns: ['dateLogged', 'userFullName', 'details'],\n        flatButtons : this.dataService.appConfig.multitenant,\n        logResponse : true,\n        columns: [\n          { name: 'dateLogged', type : 'datetimesec', alias: 'Date' },\n          { name: 'userName', alias: 'User' },\n          { name: 'userFullName', alias: 'Name' },\n          { name: 'source', },\n          { name: 'details', maxLength : 150 }, // the reference is written at the HEAD of details, so it survives this truncation; the row's \"Show more\" icon opens the full text\n          { name: 'tenantName', alias: 'Tenant', hidden: x =>  !this.dataService.appConfig.multitenant },\n\n        ],\n        loadAction: { url: 'logs/all/x' },\n        buttons :[\n          // { name: 'view', dialog : true, tip: 'View Log' },\n        ]\n      };\n\n    this.logsPageConfig = {\n      title : 'Logs',\n\n      tableConfig: logsTableConfig,\n\n      // Added: an error dialog tells the user to quote a reference (e.g. \"K7M2QP4T\"). Search Mode turns that\n      // code back into the row it names. It goes through LogReader's \"reference\" search parameter, which\n      // queries the whole table — the normal read is capped at the 500 most recent rows, which is exactly the\n      // window a reference from an hour ago has already fallen out of. Search Mode loads nothing until asked\n      // (spa-page nulls loadAction), so the page opens on a single field: paste the code, press Enter.\n      searchTableConfig: {\n        ...logsTableConfig,\n        searchConfig: {\n          fields: [\n            { name: 'reference', type: 'text', alias: 'Error Reference', show: true }\n          ],\n          searchAction: { url: 'logs/search', method: 'post' }\n        }\n      }\n    }\n  }\n\n}\n","\n <spa-page [config]=\"logsPageConfig\"></spa-page>\n","import { Component, OnInit, Inject, ViewChild, inject } from \"@angular/core\";\nimport { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from \"@angular/material/dialog\";\nimport { DataServiceLib } from \"../../services/datalib.service\";\nimport { Router } from \"@angular/router\";\nimport { MessageService } from \"../../services/message.service\";\nimport { AuthService } from \"../../services/auth.service\";\nimport { TableConfig, ApiResponse, FormConfig, Button, DetailsDialogConfig, PageConfig } from '../../classes/Classes';\nimport { HttpService } from \"../../services/http.service\";\nimport { User } from \"../../classes/LibClasses\";\nimport { ApiErrorService } from \"../../services/api-error.service\"; // Added: the AD lookup toasted the server's raw text (WS-6 Phase 4)\nimport { PasswordPolicyService, PasswordPolicyDescription } from \"../../services/password-policy.service\"; // Added: one shared generator for the password rule wording, instead of a hard-coded copy per surface\nimport { AlertMessage } from \"../../classes/Classes\"; // Added: the generated rule lines are AlertMessages\n\n@Component({\n    selector: \"spa-users\",\n    templateUrl: \"./users.component.html\",\n    styleUrls: [\"./users.component.css\"],\n    standalone: false\n})\n\nexport class UsersComponent implements OnInit {\n  private httpService = inject(HttpService);\n  private router = inject(Router);\n  private authService = inject(AuthService);\n  private dataService = inject(DataServiceLib);\n  private dialog = inject(MatDialog);\n  private messageService = inject(MessageService);\n  private apiErrorService = inject(ApiErrorService); // Added: classifies the AD directory lookup failure\n  private passwordPolicyService = inject(PasswordPolicyService); // Added: generates the password rule text from the tenant's configured policy\n\n  // Declared before passwordDialog on purpose — field initializers run in declaration order, so this has to exist\n  // by the time the dialog config below reads it.\n  private passwordAlertHeader = '*Please consider these requirements for your new password.';\n\n  // Added: the password rule is only meaningful for an account whose password WE hold. An AD/external account's\n  // password lives in the directory and is never validated against PasswordConfig, so stating our policy against\n  // one describes a rule that will never be applied. Create User already dropped the password FIELDS for a\n  // non-local authType (hidden conditions above) and the rule TEXT was the one piece of the password UI left\n  // behind — it kept listing requirements for a password the dialog no longer even collects.\n  // Deliberately the same predicate as those fields and as the row's Change Password button below, so all three\n  // agree from one condition rather than three hand-written copies — the drift this whole area already paid for.\n  // Evaluated by spa-alert against the dialog's live form data (AlertMessage.visible, Classes.ts), so switching\n  // Authentication Type in the Create User dialog hides and shows the block as it is switched.\n  private localAuthOnly = (x: any) => x?.authType === 'local';\n\n  userBaseFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capUsers] }, // Added: gate user form by users cap\n    fields: [\n      { name: 'userName', type: 'text', alias: 'Username', required: true, span : true, readonly : true },\n      { name: 'authType', type: 'select', alias: 'Authentication Type', readonly: true, span: true, required: true, defaultFirstValue: true },\n      {\n        name: 'firstName', type: 'text', required: true,\n        readonlyCondition: x => x.authType !== 'local',\n      },\n      {\n        name: 'lastName', type: 'text', required: true,\n        readonlyCondition: x => x.authType !== 'local',\n      },\n      {\n        name: 'password', type: 'text-mask', required: true, // Changed: password -> text-mask\n        hidden: x => x.authType !== 'local', span: true,\n      },\n      {\n        name: 'confirmPassword', type: 'text-mask', required: true, // Changed: password -> text-mask\n        hidden: x => x.authType !== 'local', span: true\n      },\n      { name: 'email', type: 'text', required: false, span: true },\n      { name: 'roleID', type: 'select', alias: 'Role', required: true,  span: true, defaultFirstValue: true },\n    ],\n  };\n\n  createDialog: DetailsDialogConfig = {\n    formConfig: {\n      title: 'User',\n      // Added: Create User had NO statement of the password rules anywhere on the dialog, so the server's\n      // refusal was the only place they appeared — and on a narrow screen that refusal covers the Role field\n      // and the Submit/Cancel row. Same mechanism, same wording and same placement as the Change Password\n      // dialog directly below (alertConfig on the formConfig); only the header is a literal here, the rule\n      // lines are filled in by applyPasswordRequirements from the tenant's configured policy. Pure addition.\n      alertConfig: { messages: [ { type: 'info', message: this.passwordAlertHeader } ] },\n      fields: [\n        { name: 'userName', type: 'text', alias: 'Username', required: true, span: true },\n        { \n          name: 'authType', type: 'select', alias: 'Authentication Type', span: true, required: true, defaultFirstValue: true,\n          onSelectChange: (value, data) => {\n            if (value === 'AD' && data.userName?.trim()) {\n              this.dataService.CallApi({ url: `user/ad/${data.userName}` }).subscribe((response: ApiResponse) => {\n                if (response.success && response.data) {\n                  data.firstName = response.data.firstName || '';\n                  data.lastName = response.data.surname || '';\n                  data.email = response.data.emailAddress || '';\n                  this.messageService.toast('AD user found');\n                } else {\n                  // Changed: was toast(response.message || 'AD user not found'), which echoed whatever the\n                  // directory lookup returned. CONVERTED rather than left silent because the user is watching\n                  // three fields that were supposed to auto-fill and did not. Behaviour is unchanged for the\n                  // common case — \"AD user not found\" is a human sentence, so classifyMessage keeps it a\n                  // toast — while an LDAP or connection dump now gets replaced instead of displayed.\n                  this.apiErrorService.presentAppFailure(response, 'load', `user/ad/${data.userName}`);\n                }\n              });\n            }\n          }\n        },\n        { name: 'firstName', type: 'text', required: true, readonlyCondition: x => x.authType !== 'local' },\n        { name: 'lastName', type: 'text', required: true, readonlyCondition: x => x.authType !== 'local' },\n        { name: 'password', type: 'text-mask', required: true, hidden: x => x.authType !== 'local', span: true }, // Changed: password -> text-mask\n        { name: 'confirmPassword', type: 'text-mask', required: true, hidden: x => x.authType !== 'local', span: true }, // Changed: password -> text-mask\n        { name: 'email', type: 'text', required: false, span: true },\n        { name: 'roleID', type: 'select', alias: 'Role', required: true, span: true, defaultFirstValue: true },\n      ]\n    },\n    mode: 'create',\n    buttons: [\n      { name: 'create', action: { method: 'post', url: 'User/register', successMessage: \"User Created\" }}\n    ]\n  };\n\n  editDialog: DetailsDialogConfig = {\n    formConfig: {\n      ...this.userBaseFormConfig,\n      title : 'User',\n      fields : this.userBaseFormConfig.fields.filter(x => x.name !== 'password' && x.name !== 'confirmPassword')\n    },\n    mode: 'view',\n    buttons: [\n      { name: 'edit', action: { method: 'post', url: 'User/edit', successMessage: \"User Updated\" } }\n    ]\n  };\n\n  passwordDialog: DetailsDialogConfig = {\n    formConfig: {\n      ...this.userBaseFormConfig,\n      title : 'Change Password',\n      fixedTitle: true,\n      // Changed: the five rule lines were hard-coded here and \"At least 2 lowercase letters (a-z)\" was simply\n      // false — PasswordConfig has only ever required 1 — while none of the lines reflected a tenant's configured\n      // policy at all. They are now generated by PasswordPolicyService from the same PasswordConfig row the server\n      // validates against (see applyPasswordRequirements below), so an admin setting someone's password reads the\n      // rule that will actually refuse it. Only the header survives as a literal; the rest is filled in on init.\n      alertConfig: { messages: [ { type: 'info', message: this.passwordAlertHeader } ] },\n      fields: [\n        { name: 'newPassword', type: 'text-mask', required: true }, // Changed: password -> text-mask\n        { name: 'confirmPassword', type: 'text-mask',  required: true } // Changed: password -> text-mask\n      ]\n    },\n    mode: 'edit',\n    buttons: [\n      { name: 'edit', action: { method: 'post', url: 'User/changepassword-admin', successMessage: 'Password Changed' }    }\n    ]\n  };\n\n  usersTableConfig: TableConfig = {\n    showFilter: true,\n    minButtons: ['fullName','roleName'],\n    greyOut : (value) => value.disabled == 1,\n    collapseButtons: true,\n    minColumns: ['userName', 'fullName', 'roleName', 'locked', 'dateCreated'],\n    flatButtons: this.dataService.appConfig.multitenant,\n    columns: [\n      { name: 'userName', type: 'text'},\n      { name: 'fullName', type: 'text' },\n      { name: 'roleName', type: 'text' },\n      { name: 'locked', type: 'checkbox' },\n      { name: 'createdDate', type: 'date' },\n    ],\n    buttons: [\n      { name: 'create', display: 'New User', dialog: true, detailsConfig : this.createDialog  },\n      { name: 'view', dialog: true, icon: { name: 'account_circle' }, detailsConfig: this.editDialog },\n      {\n        name: 'changePassword', display: 'Change Password', tip : 'Change Password', icon: { name: 'key' }, dialog: true, detailsConfig: this.passwordDialog,\n        visible: x => x.authType === 'local'\n      },\n      { name: 'lock', action: { method: 'post', url: 'User/lock', successMessage: \"User locked\" }, color: 'red', tip: 'Lock', icon: { name: 'lock' }, // Changed: 'lock' -> 'Lock'. The tooltip binding no longer title-cases an author's explicit tip (that was the pipe-precedence bug), so a lowercase tip would now render lowercase. Capitalised to keep the rendered text byte-identical to what the user saw before.\n        visible: (value) => value.locked == 0\n      },\n      { name: 'unlock', action: { method: 'post', url: 'User/unlock', successMessage: \"User Unlocked\" }, color: 'green', tip: 'Unlock', icon: { name: 'lock_open' }, // Changed: 'unlock' -> 'Unlock', same reason as the Lock button above — preserves the rendered text under the corrected binding.\n        visible: (value) => value.locked == 1\n      },\n      { name: 'delete', action: { method: 'post', url: 'User/delete', successMessage: \"User Deleted\" }, color: 'red' },\n    ],\n    loadAction: { url: 'User/all/x' },\n  };\n  \n  pageConfig: PageConfig = {\n    title: 'Users',\n    tableConfig: this.usersTableConfig\n  };\n\n  ngOnInit() {\n    this.authService.isAuthorised(this.dataService.capUsers.name);\n    this.loadMeta();\n    this.loadPasswordRequirements(); // Added: fill the change-password dialog's rule panel from the configured policy\n  }\n\n  // Seeded SYNCHRONOUSLY with the legacy wording before the request goes out, so the panel is never blank — not\n  // while the policy is in flight, and not if it never arrives. A blank rule list is worse than a stale one: the\n  // admin is being asked to invent a password with no stated constraint and will then simply be refused.\n  private loadPasswordRequirements() {\n    this.applyPasswordRequirements(this.passwordPolicyService.describe(PasswordPolicyService.LegacyDefaults));\n    this.passwordPolicyService.getDescription().subscribe(described => this.applyPasswordRequirements(described));\n  }\n\n  // Rebuilds the alert in place. The dialog config is read when the button is clicked, which is always after this\n  // has run, so mutating the array here is what the dialog will show.\n  private applyPasswordRequirements(described: PasswordPolicyDescription) {\n    // Changed: every line carries the local-auth condition, the header included — the owner's instruction is that\n    // the message appears only for local authentication, and a bare header over an empty list is still the message.\n    const messages: AlertMessage[] = [{ type: 'info', message: this.passwordAlertHeader, visible: this.localAuthOnly }];\n    described.requirements.filter(r => r.required).forEach(r => messages.push({ type: 'info', message: r.text, visible: this.localAuthOnly })); // a rule switched off is not something to DO, so it is dropped rather than listed as \"No number required\"\n    if (described.effectiveLengthBinds) messages.push({ type: 'info', message: `Nothing shorter than ${described.effectiveLength} characters can pass.`, visible: this.localAuthOnly }); // plain arithmetic: the class minimums are counted inside the length and can bind above it\n    this.passwordDialog.formConfig.alertConfig.messages = messages;\n    this.createDialog.formConfig.alertConfig.messages = [...messages]; // Added: Create User states the same rule from the same source. Copied rather than shared so the two panels can never alias one array; processDetailsConfig deep-clones on open, so this is belt-and-braces, not a fix.\n  }\n\n  inputChanged(x) {\n    console.log(x);\n  }\n\n  loadMeta(){\n    this.dataService.CallApi({ url: 'role/meta/x' }).subscribe((apiResponse: ApiResponse) => {\n      console.log(apiResponse.data);\n      this.userBaseFormConfig.fields.find(x => x.name == 'roleID').options = apiResponse.data.roles;\n      this.userBaseFormConfig.fields.find(x => x.name == 'authType').options = apiResponse.data.authTypes;\n\n      this.createDialog.formConfig.fields.find(x => x.name == 'roleID').options = apiResponse.data.roles;\n      this.createDialog.formConfig.fields.find(x => x.name == 'authType').options = apiResponse.data.authTypes.filter(x => x.value == 'local' || x.value == 'AD');\n    })\n  }\n\n}\n","\n<spa-page [config]=\"pageConfig\" (inputChange)=\"inputChanged($event)\"></spa-page>\n\n","import { ApiResponse, AppConfig, Button, CapItem, DetailsDialogConfig, RoleAccess } from './../../classes/Classes';\nimport { Component, OnInit, Input } from \"@angular/core\";\nimport { MatDialog } from \"@angular/material/dialog\";\nimport { DataServiceLib } from \"../../services/datalib.service\";\nimport { Router } from \"@angular/router\";\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { AuthService } from '../../services/auth.service';\nimport { HttpService } from '../../services/http.service';\nimport { DetailsDialog } from '../../components/table/detailsDialog.component';\nimport { DialogService } from '../../services/dialog.service';\nimport { Role } from '../../classes/LibClasses';\n\n// Added: what the page knows about ONE capability, for ONE role. Precomputed rather than derived in the\n// template — the tree is 200 capabilities wide and a template-bound method would recompute all of it on\n// every change-detection pass (the livelock this codebase has already been bitten by once).\ninterface CapStat {\n  self: boolean;      // is this capability itself on\n  on: number;         // how many capabilities BELOW it are on\n  total: number;      // how many capabilities are below it at all\n  matches: number;    // how many below it match the current search term\n  inconsistent: boolean; // self off while something below it is on — the thing the old red asterisk marked\n}\n\n// Added: the per-role view model. Holds only what the template reads, so the template does no work.\ninterface RoleView {\n  role: Role;\n  expanded: boolean;\n  on: number;        // capabilities on, whole tree\n  total: number;     // capabilities in the tree\n  issues: number;    // how many capabilities are flagged inconsistent\n  stats: { [capName: string]: CapStat };\n  visible: { [capName: string]: boolean }; // search + \"enabled only\" result\n  // Changed: is this capability GROUP open, kept entirely separate from whether it is TICKED. The body used\n  // to be gated on the tick, so the only way to find out what was inside a section was to grant it — you had\n  // to switch a section on to read it, then remember to switch it back. Browsing and granting are now two\n  // different actions: this map answers \"am I looking at it\", role[cap.name] answers \"does the role have it\".\n  capOpen: { [capName: string]: boolean };\n  joined: { [capName: string]: boolean };  // does this section have a body or a note attached below its header\n  anyPages: boolean; // is anything left in the \"Pages\" band after search & filter — the band header must not survive its own contents\n  anyVisible: boolean;\n}\n\n@Component({\n    selector: \"spa-roles\",\n    templateUrl: \"./roles.component.html\",\n    styleUrls: [\"./roles.component.css\"],\n    standalone: false\n})\nexport class RolesComponent implements OnInit {\n\n  constructor(private httpService: HttpService, private router: Router, private authService: AuthService, private dataService: DataServiceLib, private dialogService : DialogService, public dialog: MatDialog, private messageService: MessageService, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService to route application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n\n  ngOnInit() {\n    this.authService.isAuthorised(this.dataService.capRoles.name);\n    this.loadRoles();\n    this.dataService.appConfigObserv.subscribe(x => { this.appConfig = x; this.splitCaps(); this.buildViews(); }); // Changed: capItems can arrive after the roles do, so the view model is rebuilt on either\n  }\n\n  isProcessing = false;\n  roles: Role[];\n  RoleAccess = RoleAccess;\n\n  appConfig = new AppConfig();\n\n  roleAccessOptions = [\n    { value: RoleAccess.None, name: 'None' },\n    { value: RoleAccess.View, name: 'View' },\n    { value: RoleAccess.Edit, name: 'Edit' },\n    { value: RoleAccess.Create, name: 'Create' },\n    { value: RoleAccess.Full, name: 'Full' }\n  ];\n\n  // Added: the two shapes a TOP-LEVEL capability can take, split once when config arrives rather than with a\n  // template getter. `topPages` are top-level entries with nothing underneath them (Home, Day Book, Demo …);\n  // `topGroups` are the ones that own sub-capabilities and become the page's sections.\n  topPages: CapItem[] = [];\n  topGroups: CapItem[] = [];\n\n  views: RoleView[] = []; // Added: one entry per role, in load order\n  loaded = false; // Added: distinguishes \"still loading\" from \"this tenant genuinely has no roles\"\n\n  filter = ''; // Added: live client-side search over capability names\n  enabledOnly = false; // Added: \"show only what is switched on\" — the at-a-glance answer to \"what does this role actually have\"\n\n  loadRoles() {\n    this.dataService.GetRole(\"all\", \"\").subscribe((apiResponse : ApiResponse) => {\n      this.roles = apiResponse.data;\n      this.loaded = true;\n      this.buildViews(); // Changed: the view model is derived from the roles, so it is rebuilt with them\n    });\n  }\n\n  refresh() {\n    this.loadRoles();\n  }\n\n  // Added: splits top-level capabilities into \"pages\" and \"groups\". Called once per config change.\n  private splitCaps() {\n    const caps = this.appConfig?.capItems || [];\n    this.topPages = caps.filter(c => !c.capSubItems || c.capSubItems.length === 0);\n    this.topGroups = caps.filter(c => c.capSubItems && c.capSubItems.length > 0);\n  }\n\n  // Added: a capability is \"on\" whether it is stored as a boolean (parents / bool caps) or as a RoleAccess\n  // level (0 = None). `true > 0` is true in JS, so one comparison covers both — the same test the old\n  // hasSubItemsAccess() used.\n  isOn(value: any): boolean {\n    return value > 0;\n  }\n\n  // Added: rebuilds every role's view model. Cheap enough to run whole (200 capabilities x a handful of\n  // roles) and only ever runs on load, not per change-detection pass.\n  private buildViews() {\n    if (!this.roles) { this.views = []; return; }\n\n    const previous: { [id: number]: boolean } = {};\n    const previousCaps: { [id: number]: { [capName: string]: boolean } } = {};\n    // Changed: a refresh preserves the OPEN SECTIONS too, not just which role was open. Without this, saving\n    // a role reloads the list and slams every section you had open — and the whole point of the rework is\n    // that you opened exactly the one section you came here for.\n    this.views.forEach(v => { previous[v.role.roleID] = v.expanded; previousCaps[v.role.roleID] = v.capOpen; });\n\n    this.views = this.roles.map((role, i) => {\n      const view: RoleView = { role: role, expanded: false, on: 0, total: 0, issues: 0, stats: {}, visible: {}, joined: {}, anyPages: true, anyVisible: true, capOpen: previousCaps[role.roleID] || {} }; // Changed: carries the open sections through a refresh\n      this.recount(view);\n      // Changed: EVERY role now lands shut — not even the first one. The old `i === 0` opened the first role\n      // to stop the page looking empty, but a role holds 146 capabilities: auto-opening one buried the list of\n      // roles under the contents of a role nobody had asked for yet. The collapsed summaries ARE the overview,\n      // and they only work if they are all you see. A refresh still restores whatever was open before it.\n      view.expanded = previous[role.roleID] !== undefined ? previous[role.roleID] : false;\n      return view;\n    });\n  }\n\n  // Added: recomputes one role's counts. `inconsistent` is the old red asterisk's meaning, kept exactly —\n  // this capability is off while something underneath it is on. It is REPORTED, never resolved: nothing here\n  // writes to the role, because a parent being off with children on is a deliberate configuration this page\n  // has supported since onCapItemChange() was disabled.\n  recount(view: RoleView) {\n    const stats: { [name: string]: CapStat } = {};\n    let on = 0, total = 0, issues = 0;\n    const term = (this.filter || '').trim().toLowerCase();\n\n    const visit = (cap: CapItem): { on: number, total: number, matches: number } => {\n      let subOn = 0, subTotal = 0, subMatches = 0;\n\n      (cap.capSubItems || []).forEach(sub => {\n        const r = visit(sub);\n        subOn += r.on; subTotal += r.total; subMatches += r.matches;\n      });\n\n      const self = this.isOn(view.role[cap.name]);\n      const selfMatch = !term || (cap.display || '').toLowerCase().indexOf(term) >= 0;\n\n      const stat: CapStat = { self: self, on: subOn, total: subTotal, matches: subMatches, inconsistent: !self && subOn > 0 };\n      stats[cap.name] = stat;\n      if (stat.inconsistent) issues++;\n\n      return { on: subOn + (self ? 1 : 0), total: subTotal + 1, matches: subMatches + (selfMatch ? 1 : 0) };\n    };\n\n    (this.appConfig?.capItems || []).forEach(cap => visit(cap));\n\n    // The role-level tally counts each capability NAME once, not each position in the menu tree. Several\n    // menu entries deliberately share one cap number — capAccountingDashboard is declared as \"cap27\", the\n    // same field as capAccounting itself (\"Reuses module cap number for dashboard visibility\"), and eight\n    // more do the same. Counting positions would report one capability twice and make the headline number\n    // on the collapsed card wrong, which is the one number that has to be trustworthy.\n    const seen: { [name: string]: boolean } = {};\n    const tally = (cap: CapItem) => {\n      if (!seen[cap.name]) {\n        seen[cap.name] = true;\n        total++;\n        if (this.isOn(view.role[cap.name])) on++;\n      }\n      (cap.capSubItems || []).forEach(sub => tally(sub));\n    };\n    (this.appConfig?.capItems || []).forEach(cap => tally(cap));\n\n    view.stats = stats;\n    view.on = on;\n    view.total = total;\n    view.issues = issues;\n    this.recomputeVisibility(view);\n  }\n\n  // Added: works out what the search box and the \"enabled only\" switch leave on screen. Two passes, because\n  // a capability shows when its own name matches, when a DESCENDANT matches (so the group survives), or when\n  // an ANCESTOR matches (so searching \"Inventory\" shows all of Inventory).\n  private recomputeVisibility(view: RoleView) {\n    const term = (this.filter || '').trim().toLowerCase();\n    const self: { [name: string]: boolean } = {};    // this capability's OWN name matches\n    const subtree: { [name: string]: boolean } = {}; // it or anything below it matches\n    const visible: { [name: string]: boolean } = {};\n\n    const mark = (cap: CapItem): boolean => {\n      const own = !term || (cap.display || '').toLowerCase().indexOf(term) >= 0;\n      // OR-accumulated for the same reason `visible` is: nine cap names occupy two menu positions each, and a\n      // plain assignment let the second position erase the first. Searching \"payroll\" set self[cap72]=true on\n      // the Payroll section and its own \"Dashboard\" child then reset it to false, so the section stopped\n      // passing \"an ancestor matched\" down and showed 2 of its 9 rows. Two labels for one field: if either\n      // matches, the field matches.\n      self[cap.name] = self[cap.name] || own;\n      let hit = own;\n      (cap.capSubItems || []).forEach(sub => { if (mark(sub)) hit = true; });\n      subtree[cap.name] = subtree[cap.name] || hit;\n      return hit;\n    };\n\n    // A capability stays on screen when it matches, when something BELOW it matches (so its section survives\n    // and you can still get to the match), or when an ancestor matched BY NAME (so searching \"Payroll\" shows\n    // all of Payroll). The ancestor test deliberately uses self[], not subtree[] — passing subtree down meant\n    // one matching child pulled its 8 non-matching siblings back onto the screen with it, which is a section\n    // filter, not a search.\n    const show = (cap: CapItem, ancestorMatched: boolean) => {\n      const hasChildren = !!(cap.capSubItems && cap.capSubItems.length);\n      // Only a SECTION is kept alive by a match below it; a leaf has to match on its own name (or sit under\n      // an ancestor that matched). Without the hasChildren guard, a leaf that shares its cap number with its\n      // own parent inherits the parent's subtree result and appears in searches it does not match — Payroll\n      // and its \"Dashboard\" child are both cap72, and nine such pairs exist across the library.\n      const matched = self[cap.name] || (hasChildren && subtree[cap.name]) || ancestorMatched;\n      const stat = view.stats[cap.name];\n      // \"Enabled only\" hides what is off — EXCEPT anything flagged inconsistent. Filtering an inconsistency\n      // off the screen would quietly defeat the one marker this page exists to show.\n      const enabledOk = !this.enabledOnly || stat.self || stat.on > 0 || stat.inconsistent;\n      // OR-accumulated, never assigned. These maps are keyed by cap NAME and nine names occupy two menu\n      // positions each (Payroll and its own \"Dashboard\" child are both cap72). A plain assignment let the\n      // second position overwrite the first, which silently hid the whole Payroll section from a search for\n      // \"commission\" — the section was correctly resolved to visible, then its child reset the same key to\n      // false. A capability is shown if ANY of its positions should show it.\n      visible[cap.name] = visible[cap.name] || (matched && enabledOk);\n      (cap.capSubItems || []).forEach(sub => show(sub, self[cap.name] || ancestorMatched));\n    };\n\n    (this.appConfig?.capItems || []).forEach(cap => mark(cap));\n    (this.appConfig?.capItems || []).forEach(cap => show(cap, false));\n\n    view.visible = visible;\n    view.anyVisible = (this.appConfig?.capItems || []).some(cap => visible[cap.name]);\n    view.anyPages = this.topPages.some(cap => visible[cap.name]); // a band header must not outlive its contents\n\n    // Added: does this section have anything attached under its header (a body, an inconsistency line, or a\n    // \"matches are inside\" line)? Purely cosmetic — it squares the header's bottom corners. Precomputed\n    // rather than expressed as :has() so the look does not depend on selector support, and rather than as a\n    // template expression so it costs nothing per change-detection pass.\n    const joined: { [name: string]: boolean } = {};\n    this.topGroups.forEach(cap => {\n      const stat = view.stats[cap.name];\n      const open = !!view.capOpen[cap.name]; // Changed: was isOn(role[cap.name]) — the body follows the OPEN state now, not the tick, so the squared corner has to follow the same thing or a shut section draws a joined edge with nothing under it\n      joined[cap.name] = open || (stat && stat.inconsistent) || (!!term && !open && !!stat && stat.matches > 0);\n    });\n    view.joined = joined;\n  }\n\n  // Added: search / filter changed — every role's visibility has to be reworked, not just the open one,\n  // because the collapsed summaries are counted from the same maps.\n  filterChanged() {\n    this.views.forEach(v => this.recomputeVisibility(v));\n  }\n\n  clearFilter() {\n    this.filter = '';\n    this.filterChanged();\n  }\n\n  toggleEnabledOnly() {\n    this.enabledOnly = !this.enabledOnly;\n    this.filterChanged();\n  }\n\n  toggleRole(view: RoleView) {\n    view.expanded = !view.expanded;\n  }\n\n  // Added: open or shut ONE capability group. Deliberately writes nothing to the role — this is the browse\n  // action, and it is the whole of item 5. It is reachable whether the group is ticked or not, so an unticked\n  // section can be read before it is granted. recomputeVisibility() re-runs only to refresh the `joined` map,\n  // which squares the header's bottom corners against whatever is now attached beneath it.\n  toggleCap(view: RoleView, cap: CapItem, event?: Event) {\n    if (event) event.stopPropagation(); // the checkbox sits inside this header; ticking must never also toggle the body\n    view.capOpen[cap.name] = !view.capOpen[cap.name];\n    this.recomputeVisibility(view);\n  }\n\n  isCapOpen(view: RoleView, cap: CapItem): boolean {\n    return !!view.capOpen[cap.name];\n  }\n\n  // Added: single write path for every control on the page, so the counts and the inconsistency markers can\n  // never drift away from what the checkboxes actually say.\n  setValue(view: RoleView, cap: CapItem, value: any, topLevel: boolean = false) {\n    view.role[cap.name] = value;\n    if (topLevel) this.onCapItemChange(cap, value, view.role); // preserved: the top-level seam below\n    this.recount(view);\n  }\n\n  trackByRole(index: number, view: RoleView) { return view.role.roleID; }\n  trackByCap(index: number, cap: CapItem) { return cap.name; }\n\n  onCapItemChange(capItem: CapItem, checked: boolean, role: any) {\n\n    return; //disabled to allow sub component access without granting whole menu access\n\n    if (!checked && capItem.capSubItems) {\n      // When parent is unchecked, set all subitems to Restricted\n      capItem.capSubItems.forEach(subItem => {\n        role[subItem.name] = RoleAccess.None;\n      });\n    }\n  }\n\n  hasSubItemsAccess(capItem: CapItem, role: any): boolean {\n    if (!capItem.capSubItems) return false;\n\n    // Check if any sub-item has access\n    return capItem.capSubItems.some(subItem => {\n      // Check direct sub-items\n      if (role[subItem.name] > 0) return true;\n\n      // Check sub-sub-items recursively\n      if (subItem.capSubItems) {\n        return subItem.capSubItems.some(subSubItem => role[subSubItem.name] > 0);\n      }\n      return false;\n    });\n  }\n\n\n  addRole() {\n    // Create empty role object with just the roleName field\n    const newRole = { roleName: '' };\n\n    // Open add role dialog using the same approach as rename\n    const dialogRef = this.dialogService.openConfiguredDetailsDialog(\n      this.addRoleButton,\n      newRole,\n      DetailsDialog\n    ).subscribe(result => {\n      if (result?.message === 'success') { // Changed: a dismissed role dialog closes with undefined — read through it rather than throwing\n        this.loadRoles();\n      }\n    });\n  }\n\n  updateRole(role: Role) {\n\n    this.messageService.confirm(`UPDATE ${role.roleName} ?`).subscribe((result) => {\n\n      if (result == \"yes\") {\n\n        this.dataService.PostRole(role, \"edit\").subscribe((apiResponse: ApiResponse) => {\n\n          if (apiResponse.success) {\n            this.messageService.toast(\"Role Updated\");\n            this.loadRoles();\n          } else {\n            this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: was concatenating the ApiResponse OBJECT, so this rendered the literal 'Error: [object Object]' — passing the response reads .message properly and classifies it\n          }\n        });\n\n      }\n\n    })\n\n\n  };\n\n  deleteRole(role: Role) {\n\n    this.messageService.confirm(`DELETE ${role.roleName} ?`).subscribe((result) => {\n\n      if (result == \"yes\") {\n\n        this.dataService.PostRole(role, \"delete\").subscribe((apiResponse: ApiResponse) => {\n          if (apiResponse.success) {\n            this.messageService.toast(\"Role Deleted\");\n            this.loadRoles();\n          } else {\n            this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: was concatenating the ApiResponse OBJECT, so this rendered the literal 'Error: [object Object]' — passing the response reads .message properly and classifies it\n          }\n        });\n\n      }\n\n    })\n\n  }\n\n  renameDialogConfig: DetailsDialogConfig = {\n    formConfig: {\n      security: { allow: [this.dataService.capRoles] }, // Added: gate rename role form by roles cap\n      title: 'Rename Role',\n      fixedTitle: true,\n      fields: [\n        { name: 'roleName', type: 'text', required: true, span: true, alias: 'Role Name' }\n      ]\n    },\n    mode: 'edit',\n    buttons: [\n      { name: 'edit', dialog: true, action: { url: 'role?action=edit', method: 'post', successMessage: 'Role renamed successfully' } }\n    ]\n  };\n\n  renameButton : Button = {name : 'edit', dialog : true, detailsConfig : this.renameDialogConfig};\n\n  // Add role dialog configuration\n  addRoleDialogConfig: DetailsDialogConfig = {\n    formConfig: {\n      security: { allow: [this.dataService.capRoles] }, // Added: gate add role form by roles cap\n      title: 'Add New Role',\n      fixedTitle: true,\n      fields: [\n        { name: 'roleName', type: 'text', required: true, span: true, alias: 'Role Name' }\n      ]\n    },\n    mode: 'create',\n    buttons: [\n      { name: 'create', dialog: true, action: { url: 'role?action=create', method: 'post', successMessage: 'Role created successfully' } }\n    ]\n  };\n\n  addRoleButton : Button = {name : 'create', dialog : true, detailsConfig : this.addRoleDialogConfig};\n\n  renameRole(role: Role) {\n    // Create role copy to avoid modifying the original during editing\n    const roleData = { ...role };\n\n    // Open rename dialog\n    const dialogRef = this.dialogService.openConfiguredDetailsDialog(\n      this.renameButton,\n      roleData,\n      DetailsDialog\n    ).subscribe(result => {\n      if (result?.message === 'success') { // Changed: a dismissed role dialog closes with undefined — read through it rather than throwing\n        this.loadRoles();\n      }\n    });\n  }\n\n\n}\n","<!-- Changed: the page was one wrapping run of 100+ controls per role with no grouping, no hierarchy and no way\n     to find anything. Same controls, same rules, rearranged: roles collapse to a summary line, capabilities are\n     grouped under the section they belong to, and there is a search. Two rules are load-bearing and unchanged —\n     a section's sub-items exist only while that section is switched on, and a section that is OFF while\n     something underneath it is ON is FLAGGED, never corrected. -->\n\n<div class=\"rp-page\">\n\n  <div class=\"rp-head\">\n\n    <div class=\"rp-head-text\">\n      <h1>Roles</h1>\n      <!-- Changed: the old lead read \"Switch a section on to see and set the pages inside it\", which described\n           the exact behaviour this rework removes. Opening a section no longer costs a grant, so the sentence\n           would have been actively misleading — it told you to do the thing the page now does for free. -->\n      <p class=\"rp-lead\">What each role can reach. Open a role, then open any section to see what is inside it.</p>\n    </div>\n\n    <div class=\"rp-head-actions\">\n      <!-- Changed (item 4): refresh moved BEFORE New Role and given the page's own 38px bordered-pill idiom\n           (the same one .rp-search and .rp-toggle use) instead of being a bare mat-icon-button. It was sitting\n           to the RIGHT of the primary action, which put the quietest control at the loudest position — the far\n           page edge, past the button the eye is aimed at — and a 40px icon button next to a 36px raised button\n           never shared a baseline. Secondary left, primary right, one height for both. -->\n      <button id=\"btnRefresh\" type=\"button\" class=\"rp-icon-btn\" (click)=\"refresh()\" matTooltip=\"Refresh roles\" aria-label=\"Refresh roles\"><mat-icon>refresh</mat-icon></button>\n      <button id=\"btnNewRole\" mat-raised-button color=\"primary\" (click)=\"addRole()\">New Role</button>\n    </div>\n\n  </div>\n\n  <!-- Added: the two ways of finding something in 200 capabilities — search it, or show only what is on. -->\n  <div class=\"rp-tools\" *ngIf=\"views.length\">\n\n    <div class=\"rp-search\">\n      <mat-icon>search</mat-icon>\n      <input type=\"text\" name=\"capFilter\" placeholder=\"Search capabilities\" autocomplete=\"off\" [(ngModel)]=\"filter\" (ngModelChange)=\"filterChanged()\" />\n      <button mat-icon-button *ngIf=\"filter\" (click)=\"clearFilter()\" matTooltip=\"Clear search\"><mat-icon>close</mat-icon></button>\n    </div>\n\n    <button type=\"button\" class=\"rp-toggle\" [class.active]=\"enabledOnly\" (click)=\"toggleEnabledOnly()\">\n      <mat-icon>{{ enabledOnly ? 'check_box' : 'check_box_outline_blank' }}</mat-icon>\n      Only what is switched on\n    </button>\n\n  </div>\n\n  <div class=\"rp-empty\" *ngIf=\"loaded && !views.length\">\n    <mat-icon>work_outline</mat-icon>\n    <p>No roles yet. Create one to start granting access.</p>\n  </div>\n\n  <mat-card class=\"rp-role\" *ngFor=\"let view of views; trackBy: trackByRole\" [class.open]=\"view.expanded\">\n\n    <!-- The whole strip is the control that opens the role, so a collapsed role still says everything it has\n         to say: its name, how much is on, and whether anything inside it needs looking at. -->\n    <div class=\"rp-rhead\">\n\n      <!-- Changed: was two glyphs swapped (expand_more / chevron_right). The estate has ONE disclosure marker —\n           .tin-disc in tin-styles.css: a single chevron_right rotated 90deg on open, already used by the Day\n           Book, Getting Started and the checklist. Adopting it is the owner's item 2, and it also kills the\n           glyph swap, which made the marker change shape between its two states. -->\n      <button type=\"button\" class=\"rp-rtoggle tin-disc-row\" (click)=\"toggleRole(view)\" [attr.aria-expanded]=\"view.expanded\">\n        <span class=\"tin-disc\" [class.open]=\"view.expanded\"><mat-icon>chevron_right</mat-icon></span>\n        <span class=\"rp-name\">{{ view.role.roleName }}</span>\n        <span class=\"rp-summary\">{{ view.on }} of {{ view.total }} capabilities on</span>\n        <span class=\"rp-issues\" *ngIf=\"view.issues\" matTooltip=\"A section is off while capabilities inside it are on\"><mat-icon>error_outline</mat-icon>{{ view.issues }} {{ view.issues === 1 ? 'inconsistency' : 'inconsistencies' }}</span>\n      </button>\n\n      <!-- Changed (item 3): given a class so it can be centred. It was an unstyled mat-icon-button sitting\n           beside a 44px-min toggle; the button box centred but the GLYPH inside it did not, because mat-icon\n           inherits the button's line-height rather than centring itself. .rp-rename fixes both halves. -->\n      <button class=\"rp-rename\" mat-icon-button color=\"primary\" matTooltip=\"Rename Role\" aria-label=\"Rename role\" (click)=\"renameRole(view.role)\"><mat-icon>edit</mat-icon></button>\n\n    </div>\n\n    <div class=\"rp-rbody\" *ngIf=\"view.expanded\">\n\n      <p class=\"rp-none\" *ngIf=\"!view.anyVisible\">Nothing matches the current search or filter.</p>\n\n      <!-- Top-level entries that own nothing underneath them. -->\n      <div class=\"rp-band\" *ngIf=\"topPages.length && view.anyPages\">\n\n        <div class=\"rp-band-head\">\n          <span class=\"rp-band-name\">Pages</span>\n          <span class=\"rp-band-note\">top-level menu items with no sub-items</span>\n        </div>\n\n        <div class=\"rp-grid\">\n          <ng-container *ngFor=\"let cap of topPages; trackBy: trackByCap\">\n            <div class=\"rp-item\" *ngIf=\"view.visible[cap.name]\">\n              <mat-checkbox *ngIf=\"cap.isBool\" color=\"primary\" [ngModel]=\"view.role[cap.name]\" (ngModelChange)=\"setValue(view, cap, $event, true)\">{{ cap.display }}</mat-checkbox>\n              <spa-select *ngIf=\"!cap.isBool\" [options]=\"roleAccessOptions\" optionDisplay=\"name\" optionValue=\"value\" [required]=\"false\" [display]=\"cap.display\" [value]=\"view.role[cap.name]\" (valueChange)=\"setValue(view, cap, $event, true)\" width=\"100%\"></spa-select>\n            </div>\n          </ng-container>\n        </div>\n\n      </div>\n\n      <!-- One section per top-level capability that owns sub-items. -->\n      <div class=\"rp-groups\">\n\n        <ng-container *ngFor=\"let cap of topGroups; trackBy: trackByCap\">\n\n          <section class=\"rp-group\" *ngIf=\"view.visible[cap.name]\">\n\n            <!-- Changed: the header is now TWO controls, not one. The checkbox on the left GRANTS the section;\n                 the rest of the strip BROWSES it. They used to be the same act — the checkbox's label wrapped\n                 the icon and the name, and the body was gated on the tick, so reading a section meant granting\n                 it first. Splitting them is the whole of the owner's item 5. -->\n            <div class=\"rp-ghead\" [class.on]=\"view.stats[cap.name].self\" [class.flag]=\"view.stats[cap.name].inconsistent\" [class.joined]=\"view.joined[cap.name]\" [class.open]=\"view.capOpen[cap.name]\">\n\n              <mat-checkbox class=\"rp-gcheck\" color=\"primary\" [attr.aria-label]=\"'Grant ' + cap.display\" [ngModel]=\"view.role[cap.name]\" (ngModelChange)=\"setValue(view, cap, $event, true)\" (click)=\"$event.stopPropagation()\"></mat-checkbox>\n\n              <button type=\"button\" class=\"rp-gtoggle tin-disc-row\" (click)=\"toggleCap(view, cap, $event)\" [attr.aria-expanded]=\"!!view.capOpen[cap.name]\">\n                <span class=\"tin-disc\" [class.open]=\"view.capOpen[cap.name]\"><mat-icon>chevron_right</mat-icon></span>\n                <mat-icon class=\"rp-gicon\">{{ cap.icon }}</mat-icon>\n                <span class=\"rp-gtext\">\n                  <span class=\"rp-gname\">{{ cap.display }}</span>\n                  <span class=\"rp-gcount\">{{ view.stats[cap.name].on }} of {{ view.stats[cap.name].total }} inside are on</span>\n                </span>\n                <mat-icon class=\"rp-gflag\" *ngIf=\"view.stats[cap.name].inconsistent\">error_outline</mat-icon>\n              </button>\n\n            </div>\n\n            <!-- The inconsistency, said in words. The section is off, so its body is hidden and this line has\n                 the space; it reports and does nothing else — the values underneath are left exactly as set. -->\n            <div class=\"rp-note flag\" *ngIf=\"!view.capOpen[cap.name] && view.stats[cap.name].inconsistent\">\n              <mat-icon>error_outline</mat-icon>\n              <span><strong>{{ view.stats[cap.name].on }}</strong> of {{ view.stats[cap.name].total }} capabilities inside {{ cap.display }} are switched on while {{ cap.display }} itself is off, so they are probably unreachable. Nothing has been changed — open {{ cap.display }} to review them.</span> <!-- Changed: \"switch on to review\" was the old bargain, where reading cost you a grant. Opening is now free, so the instruction is simply to open it. -->\n            </div>\n\n            <div class=\"rp-note\" *ngIf=\"!view.capOpen[cap.name] && !view.stats[cap.name].inconsistent && filter && view.stats[cap.name].matches\">\n              <mat-icon>search</mat-icon>\n              <span>{{ view.stats[cap.name].matches }} capabilities inside {{ cap.display }} match this search. Open {{ cap.display }} to set them.</span> <!-- Changed: opening no longer costs a grant -->\n            </div>\n\n            <!-- Changed: the body is gated on capOpen, NOT on the tick. This one expression was the reason you\n                 had to switch a section on to find out what was in it. Ticking still controls whether the\n                 controls inside are USABLE (see [disabled]/[readonly] below) — it no longer controls whether\n                 they are VISIBLE. Browse freely; grant deliberately. -->\n            <div class=\"rp-gbody\" *ngIf=\"cap.capSubItems && view.capOpen[cap.name]\">\n\n              <!-- Added: an open-but-unticked section shows every control greyed out, which without a word of\n                   explanation reads as broken rather than as locked. This says which switch unlocks them. -->\n              <div class=\"rp-locked\" *ngIf=\"!view.role[cap.name]\">\n                <mat-icon>lock_outline</mat-icon>\n                <span>Browsing only. Tick <strong>{{ cap.display }}</strong> to change anything inside it.</span>\n              </div>\n\n              <div class=\"rp-grid\">\n\n                <ng-container *ngFor=\"let sub of cap.capSubItems; trackBy: trackByCap\">\n\n                  <ng-container *ngIf=\"view.visible[sub.name]\">\n\n                    <!-- A sub-item with its own sub-items gets its own block. Its children are NOT gated on its\n                         value — that is how the page has always behaved at this level and changing it would put\n                         capabilities out of reach. -->\n                    <div class=\"rp-sub\" *ngIf=\"sub.capSubItems && sub.capSubItems.length\" [class.flag]=\"view.stats[sub.name].inconsistent\">\n\n                      <div class=\"rp-subhead\">\n                        <!-- Changed: [disabled]/[readonly] bound to the PARENT's tick. Preserved rule — you cannot set a sub-item without the section it lives under; the controls are now visible-but-locked rather than absent. spa-select has no `disabled` input; its `readonly` is bound straight to mat-select's [disabled]. -->\n                        <mat-checkbox *ngIf=\"sub.isBool\" color=\"primary\" [disabled]=\"!view.role[cap.name]\" [ngModel]=\"view.role[sub.name]\" (ngModelChange)=\"setValue(view, sub, $event)\">{{ sub.display }}</mat-checkbox>\n                        <spa-select *ngIf=\"!sub.isBool\" [options]=\"roleAccessOptions\" optionDisplay=\"name\" optionValue=\"value\" [required]=\"false\" [readonly]=\"!view.role[cap.name]\" [display]=\"sub.display\" [value]=\"view.role[sub.name]\" (valueChange)=\"setValue(view, sub, $event)\" width=\"100%\"></spa-select>\n                        <mat-icon class=\"rp-gflag\" *ngIf=\"view.stats[sub.name].inconsistent\" matTooltip=\"{{ view.stats[sub.name].on }} capabilities below this are on while it is off\">error_outline</mat-icon>\n                      </div>\n\n                      <div class=\"rp-grid inner\">\n                        <ng-container *ngFor=\"let leaf of sub.capSubItems; trackBy: trackByCap\">\n                          <div class=\"rp-item\" *ngIf=\"view.visible[leaf.name]\">\n                            <mat-checkbox *ngIf=\"leaf.isBool\" color=\"primary\" [disabled]=\"!view.role[cap.name]\" [ngModel]=\"view.role[leaf.name]\" (ngModelChange)=\"setValue(view, leaf, $event)\">{{ leaf.display }}</mat-checkbox>\n                            <spa-select *ngIf=\"!leaf.isBool\" [options]=\"roleAccessOptions\" optionDisplay=\"name\" optionValue=\"value\" [required]=\"false\" [readonly]=\"!view.role[cap.name]\" [display]=\"leaf.display\" [value]=\"view.role[leaf.name]\" (valueChange)=\"setValue(view, leaf, $event)\" width=\"100%\"></spa-select>\n                          </div>\n                        </ng-container>\n                      </div>\n\n                    </div>\n\n                    <!-- Changed: the parent-tick gate, on the branch that renders a sub-item with NO children of\n                         its own. This is the commonest shape on the page — Inventory's 11 entries all take it —\n                         and it was the branch the first pass missed, which showed up as an open-but-unticked\n                         Inventory whose 11 selects were all still live. -->\n                    <div class=\"rp-item\" *ngIf=\"!sub.capSubItems || !sub.capSubItems.length\">\n                      <mat-checkbox *ngIf=\"sub.isBool\" color=\"primary\" [disabled]=\"!view.role[cap.name]\" [ngModel]=\"view.role[sub.name]\" (ngModelChange)=\"setValue(view, sub, $event)\">{{ sub.display }}</mat-checkbox>\n                      <spa-select *ngIf=\"!sub.isBool\" [options]=\"roleAccessOptions\" optionDisplay=\"name\" optionValue=\"value\" [required]=\"false\" [readonly]=\"!view.role[cap.name]\" [display]=\"sub.display\" [value]=\"view.role[sub.name]\" (valueChange)=\"setValue(view, sub, $event)\" width=\"100%\"></spa-select>\n                    </div>\n\n                  </ng-container>\n\n                </ng-container>\n\n              </div>\n\n            </div>\n\n          </section>\n\n        </ng-container>\n\n      </div>\n\n      <div class=\"rp-actions\">\n        <button mat-raised-button color=\"primary\" (click)=\"updateRole(view.role)\"><mat-icon>done_all</mat-icon> Update</button>\n        <button mat-raised-button (click)=\"deleteRole(view.role)\"><mat-icon>delete</mat-icon> Delete</button>\n      </div>\n\n    </div>\n\n  </mat-card>\n\n</div>\n","import { DataServiceLib } from '../../services/datalib.service';\nimport { Component, Input, OnInit } from '@angular/core';\nimport { MessageService } from '../../services/message.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: classifies HTTP-200 success:false failures — opaque server text gets a friendly dialog, business messages stay toasts\nimport { AuthService } from '../../services/auth.service';\nimport { AppConfig, ApiResponse } from '../../classes/Classes';\nimport { Router } from '@angular/router';\nimport { HttpService } from '../../services/http.service';\nimport { Register } from '../../classes/LibClasses';\n\n@Component({\n    selector: 'spa-create-account',\n    templateUrl: './create-account.component.html',\n    styleUrls: ['./create-account.component.css'],\n    standalone: false\n})\nexport class CreateAccountComponent implements OnInit {\n\n  constructor(private httpService: HttpService, private messageService: MessageService, private dataService: DataServiceLib, private authService: AuthService, public router: Router, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService to route application-level (HTTP 200, success:false) failures through the shared classify + dedupe path\n\n  ngOnInit() {\n    this.appConfig = this.dataService.appConfig;\n    this.loadRoles();\n  }\n\n\n\n  @Input() appConfig = new AppConfig();\n\n  isProcessing: boolean = false;\n  register = new Register();\n  confirmPassword: string;\n  openProfile: boolean = true;\n\n  authTypes = [\n    { name: \"Local Authentication\", value: \"local\" },\n    { name: \"AD Authentication\", value: \"AD\" }\n  ]\n\n  roles;\n\n  check(){\n\n    if ( this.register.authType != \"AD\") {\n\n      return;\n    }\n\n    if (this.register.userName == \"\"){\n      this.messageService.toast(\"Please enter UserName\")\n      return;\n    }\n\n    this.dataService.CallApi({url: 'User/ad/' + this.register.userName}, '').subscribe((apiResponse : ApiResponse) => {\n\n      if (apiResponse.success){\n        this.register.firstName = apiResponse.data.firstName;\n        this.register.lastName = apiResponse.data.surname;\n        this.register.email = apiResponse.data.emailAddress;\n      }\n      else{\n        this.messageService.toast(apiResponse.message)\n      }\n\n    })\n  }\n\n  loadRoles() {\n\n    this.dataService.GetRole(\"all\", \"\").subscribe(\n      (apiResponse: ApiResponse) => {\n        this.roles = apiResponse;\n      },\n      (error) => {\n        this.isProcessing = false;\n        this.messageService.toast(this.httpService.Error(error));\n      }\n    );\n\n  }\n\n  create() {\n\n    if (this.register.authType == \"\") {\n      this.messageService.toast(\"Choose Authentication Type\");\n      return;\n    }\n\n    if (this.register.firstName == \"\") {\n      this.messageService.toast(\"Enter First Name\");\n      return;\n    }\n\n    if (this.register.lastName == \"\") {\n      this.messageService.toast(\"Enter Last Name\");\n      return;\n    }\n\n\n    this.isProcessing = true;\n    this.dataService.RegisterAccount(this.register).subscribe((apiResponse: ApiResponse) => {\n        this.isProcessing = false;\n\n        if (apiResponse.success) {\n          this.messageService.toast(\"Account Created\");\n\n          if (this.openProfile) {\n            this.viewProfile(this.register.userName);\n          } else {\n            // this.user = new User();\n            this.register = new Register();\n            this.confirmPassword = \"\";\n          }\n\n\n        } else {\n          this.apiErrorService.presentAppFailure(apiResponse, 'submit'); // Changed: auth/profile submit — business messages (e.g. 'Invalid User Credentials') stay toasts, opaque server text now gets the friendly dialog\n        }\n      },\n      (error) => {\n        this.isProcessing = false;\n        this.messageService.toast(this.httpService.Error(error));\n      }\n    );\n  }\n\n  viewProfile(userName: string) {\n\n    this.dataService.tmpProfileuserName = userName;\n    this.router.navigate([\"home/user/profile\"]);\n\n  }\n\n}\n","<h4>Create User</h4>\n\n<hr/>\n\n<div class=\"container tin-grid\" style=\"font-size:14px; max-width: 70%;\">\n\n  <spa-text id=\"txtUserName\" display=\"Username\" [(value)]=\"register.userName\"></spa-text>\n\n  &nbsp;\n\n  <spa-select id=\"cboAuth\" display=\"Authentication Type\" [options]=\"authTypes\" optionDisplay=\"name\" optionValue=\"value\" [(value)]=\"register.authType\" (valueChange)=\"check()\" ></spa-select>\n\n  &nbsp;\n\n  <spa-text id=\"txtFirstName\" display=\"FirstName\" [(value)]=\"register.firstName\" [readonly]=\"register.authType =='AD'\"></spa-text>\n\n  <spa-text id=\"txtLastName\" display=\"LastName\" [(value)]=\"register.lastName\" [readonly]=\"register.authType =='AD'\"></spa-text>\n\n\n  <spa-text-mask *ngIf=\"register.authType == 'local'\" id=\"txtPassword\" display=\"Password\" [(value)]=\"register.password\" ></spa-text-mask>\n\n  <spa-text-mask *ngIf=\"register.authType == 'local'\" id=\"txtConfirmPassword\" display=\"Confirm Password\" [(value)]=\"confirmPassword\" ></spa-text-mask>\n\n  <spa-text id=\"txtEmail\" display=\"Email\" [(value)]=\"register.email\"></spa-text>\n\n  &nbsp;\n\n  <spa-select id=\"cboRole\" display=\"Role\" [options]=\"roles\" optionDisplay=\"roleName\" optionValue=\"roleID\" [(value)]=\"register.roleID\"></spa-select>\n\n  &nbsp;\n\n  <spa-check display=\"Open profile after creation\" [(value)]=\"openProfile\"></spa-check>\n\n  <div class=\"span-col-center\">\n    <button id=\"btnCreate\" [disabled]=\"register.authType ==''\" mat-raised-button color=\"primary\" (click)=\"create()\" cdkFocusInitial>Create</button>\n  </div>\n\n\n\n</div>\n\n\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../classes/Classes';\nimport { TinSpaModule } from '../../tin-spa.module';\nimport { GeneralService } from '../../services/general.service';\n\n\n@Component({\n    selector: 'spa-categories',\n    standalone: true,\n    imports: [TinSpaModule],\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class CategoriesComponent {\n  private generalService = inject(GeneralService);\n  \n  pageConfig: PageConfig = {\n    title: 'Categories',\n    tableConfig: this.generalService.categoriesTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../classes/Classes';\nimport { TinSpaModule } from '../../tin-spa.module';\nimport { GeneralService } from '../../services/general.service';\n\n\n@Component({\n    selector: 'spa-subcategories',\n    standalone: true,\n    imports: [TinSpaModule],\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class SubCategoriesComponent {\n  private generalService = inject(GeneralService);\n  \n  pageConfig: PageConfig = {\n    title: 'Sub Categories',\n    tableConfig: this.generalService.subCategoriesTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../classes/Classes';\nimport { TinSpaModule } from '../../tin-spa.module';\nimport { GeneralService } from '../../services/general.service';\n\n\n@Component({\n    selector: 'spa-brands',\n    standalone: true,\n    imports: [TinSpaModule],\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class BrandsComponent {\n  private generalService = inject(GeneralService);\n  \n  pageConfig: PageConfig = {\n    title: 'Brands',\n    tableConfig: this.generalService.brandsTableConfig\n  };\n}\n","import { SettingsComponent } from '../pages/settings/settings.component';\nimport { PasswordPolicyComponent } from '../pages/password-policy/password-policy.component'; // Added (N8): per-tenant password policy admin page\nimport { LogsComponent } from '../pages/logs/logs.component';\nimport { SpaMatModule } from \"./spa-mat.module\";\nimport { NgModule } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport { FormsModule, ReactiveFormsModule } from \"@angular/forms\";\nimport { UsersComponent } from \"../pages/users/users.component\";\nimport { RolesComponent } from \"../pages/roles/roles.component\";\nimport { CreateAccountComponent } from \"../pages/create-account/create-account.component\";\nimport { TinSpaModule } from '../tin-spa.module';\nimport { CategoriesComponent } from '../pages/categories/categories.component';\nimport { SubCategoriesComponent } from '../pages/subcategories/subcategories.component';\nimport { BrandsComponent } from '../pages/brands/brands.component';\n\n\n@NgModule({\n  declarations: [\n    UsersComponent,\n    RolesComponent,\n    CreateAccountComponent,\n    LogsComponent,\n    SettingsComponent,\n    PasswordPolicyComponent // Added (N8)\n\n\n  ],\n\n\n\n  imports: [\n    ReactiveFormsModule.withConfig({ warnOnNgModelWithFormControl: \"never\" }),\n    CommonModule,\n    FormsModule,\n    ReactiveFormsModule,\n    TinSpaModule,\n\n    CategoriesComponent,\n    SubCategoriesComponent,\n    BrandsComponent\n  ],\n\n  exports: [\n    CommonModule,\n    FormsModule,\n    TinSpaModule,\n    UsersComponent,\n    RolesComponent,\n    CreateAccountComponent,\n    LogsComponent,\n    SettingsComponent,\n    PasswordPolicyComponent, // Added (N8)\n\n    CategoriesComponent,\n    SubCategoriesComponent,\n    BrandsComponent\n\n\n  ],\n})\nexport class SpaAdminModule {}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { SignupComponent } from '../../pages/signup/signup.component';\nimport { RecoverAccountComponent } from '../../pages/recover-account/recover-account.component';\nimport { LoginComponent } from '../../pages/login/login.component';\n\nconst routes: Routes = [\n\n    { path: \"signup\", component: SignupComponent },\n    { path: 'recover-account', component: RecoverAccountComponent },\n    { path: 'login', component: LoginComponent },\n    { path: '', redirectTo: 'login', pathMatch: 'full' },\n    { path: '**', redirectTo: '' },\n\n];\n\n\n@NgModule({\n  imports: [RouterModule.forChild(routes)],\n  exports: [RouterModule]\n})\nexport class IndexRoutingModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\nimport { IndexRoutingModule } from './index-routing.module';\nimport { SpaIndexModule } from '../spa-index.module';\n\n\n@NgModule({\n  declarations: [],\n  imports: [\n    CommonModule,\n    IndexRoutingModule,\n    SpaIndexModule\n  ]\n})\nexport class IndexModule { }\n","import { Component, inject } from '@angular/core';\nimport { DataServiceLib } from \"../../services/datalib.service\";\nimport { PageConfig } from '../../classes/Classes';\nimport { TinSpaModule } from '../../tin-spa.module';\n\n@Component({\n    selector: 'spa-gpt-caches',\n    standalone: true,\n    imports: [TinSpaModule],\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class GptCachesComponent {\n  private dataService = inject(DataServiceLib);\n  \n  pageConfig: PageConfig = {\n    title: 'GPT Cache',\n    tableConfig: this.dataService.gptCachesTableConfig\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { GptCachesComponent } from '../../pages/gpt-caches/gpt-caches.component';\n// Changed: PreferencesComponent deleted — its financial calendar now lives on spa-app-configuration (SetupModule)\n\n@NgModule({\n  declarations: [\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule,\n    GptCachesComponent // Changed: Standalone component must be imported\n  ]\n})\nexport class AdminModule { }\n","\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaUserModule } from '../spa-user.module';\n\n@NgModule({\n  declarations: [],\n  imports: [\n    CommonModule,\n    SpaUserModule\n  ]\n})\nexport class UserModule { }\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { ChangePasswordComponent } from '../../pages/change-password/change-password.component';\nimport { ProfileComponent } from '../../pages/profile/profile.component';\n\n// Changed: Exported routes array for use by SpaHomeRoutingModule\nexport const USER_ROUTES: Routes = [\n  {path: \"change-password\", component: ChangePasswordComponent },\n  {path: \"profile\", component: ProfileComponent },\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(USER_ROUTES)],\n  exports: [RouterModule]\n})\nexport class UserRoutingModule { }\n","\nimport { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { UsersComponent } from '../../pages/users/users.component';\nimport { RolesComponent } from '../../pages/roles/roles.component';\nimport { CreateAccountComponent } from '../../pages/create-account/create-account.component';\nimport { LogsComponent } from '../../pages/logs/logs.component';\nimport { SettingsComponent } from '../../pages/settings/settings.component';\nimport { PasswordPolicyComponent } from '../../pages/password-policy/password-policy.component'; // Added (N8): per-tenant password policy admin page\nimport { GptCachesComponent } from '../../pages/gpt-caches/gpt-caches.component';\n// Changed: PreferencesComponent removed — Preferences merged into the per-app App Configuration page (home/app-configuration)\n\n// Changed: Exported routes array for use by SpaHomeRoutingModule\nexport const ADMIN_ROUTES: Routes = [\n  { path: \"users\", component: UsersComponent },\n  { path: \"roles\", component: RolesComponent },\n  { path: \"password-policy\", component: PasswordPolicyComponent }, // Added (N8): routed beside users and roles, because that is where the rule those accounts are held to belongs\n  { path: \"create-account\", component: CreateAccountComponent },\n  { path: \"logs\", component: LogsComponent },\n  { path: \"gpt-caches\", component: GptCachesComponent },\n  { path: \"settings\", component: SettingsComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(ADMIN_ROUTES)],\n  exports: [RouterModule]\n})\nexport class AdminRoutingModule { }\n","import { Component, OnInit } from '@angular/core';\nimport { TableConfig, TileConfig, ApiResponse } from '../../../classes/Classes';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { DataServiceLib } from '../../../services/datalib.service';\n\n@Component({\n  selector: 'spa-accounts',\n  template: `\n    <h4>Accounts</h4>\n    <hr>\n\n    <spa-tiles [config]=\"accountTileConfig\"></spa-tiles>\n\n    <spa-tabs [tableConfigs]=\"accountTabConfigs\"></spa-tabs>\n  `,\n  standalone: false\n})\nexport class AccountsComponent implements OnInit {\n\n  constructor(private dataServiceLib: DataServiceLib, public accountingService: AccountingService) {\n    this.accountTabConfigs = [\n      {\n        ...this.accountingService.accountsTableConfig,\n        tabTitle: 'Assets',\n        loadAction: { url: 'accounts/type/asset' },\n        countAction: { url: 'accounts/count/asset' }\n      },\n      {\n        ...this.accountingService.accountsTableConfig,\n        tabTitle: 'Liabilities',\n        loadAction: { url: 'accounts/type/liability' },\n        countAction: { url: 'accounts/count/liability' }\n      },\n      {\n        ...this.accountingService.accountsTableConfig,\n        tabTitle: 'Income',\n        loadAction: { url: 'accounts/type/income' },\n        countAction: { url: 'accounts/count/income' }\n      },\n      {\n        ...this.accountingService.accountsTableConfig,\n        tabTitle: 'Expenses',\n        loadAction: { url: 'accounts/type/expense' },\n        countAction: { url: 'accounts/count/expense' }\n      },\n      {\n        ...this.accountingService.accountsTableConfig,\n        tabTitle: 'Equity',\n        loadAction: { url: 'accounts/type/equity' },\n        countAction: { url: 'accounts/count/equity' }\n      },\n      // Removed: Aggregate tab - no longer used\n    ];\n  }\n\n  ngOnInit(): void {\n  }\n\n  accountTabConfigs: TableConfig[];\n\n  // Changed: Tile config with Cash, Bank, Income MTD, and Expenses MTD\n  accountTileConfig: TileConfig = {\n    tiles: [\n      { name: 'cashBalance', alias: 'Cash', color: '#4CAF50', icon: 'payments', style: 'icon', info: 'Total balance of all cash accounts' },\n      { name: 'bankBalance', alias: 'Bank', color: '#2196F3', icon: 'account_balance', style: 'icon', info: 'Total balance of all bank accounts' },\n      { name: 'mtdIncome', alias: 'Income (MTD)', color: '#9C27B0', icon: 'trending_up', style: 'icon', info: 'Month-to-date income from revenue accounts' },\n      { name: 'mtdExpenses', alias: 'Expenses (MTD)', color: '#F44336', icon: 'trending_down', style: 'icon', info: 'Month-to-date expenses' },\n    ],\n    loadAction: { url: 'accounts/summary/tiles' },\n    loadInit: true\n  };\n}\n","// Accounting Aggregates component with monthly aggregated financial data\nimport { Component, OnInit } from '@angular/core';\nimport { TableConfig, ApiResponse } from '../../../classes/Classes';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { DataServiceLib } from '../../../services/datalib.service';\n\n@Component({\n  selector: 'spa-aggregates',\n  template: `\n    <h4>Aggregates</h4>\n    <hr>\n\n    <spa-tabs [tableConfigs]=\"aggregateTabConfigs\"></spa-tabs>\n  `,\n  standalone: false\n})\nexport class AggregatesComponent implements OnInit {\n\n  constructor(private dataServiceLib: DataServiceLib, public accountingService: AccountingService) {\n    this.aggregateTabConfigs = [\n      {\n        ...this.accountingService.aggregatesTableConfig,\n        tabTitle: 'Monthly Summary',\n        loadAction: { url: 'accounts/aggregates/monthly' },\n      },\n      {\n        ...this.accountingService.cashFlowAggregatesTableConfig,\n        tabTitle: 'Cash Flow',\n        loadAction: { url: 'accounts/aggregates/cashflow' },\n      },\n      {\n        ...this.accountingService.cumulativeAggregatesTableConfig,\n        tabTitle: 'Cumulative Balances',\n        loadAction: { url: 'accounts/aggregates/cumulative' },\n      },\n      {\n        ...this.accountingService.balanceSheetAggregatesTableConfig,\n        tabTitle: 'Balance Sheet',\n        loadAction: { url: 'accounts/aggregates/balancesheet' },\n      }\n    ];\n  }\n\n  ngOnInit(): void {\n  }\n\n  aggregateTabConfigs: TableConfig[];\n}\n","// Aging report component for accounts receivable tracking\nimport { Component, inject, OnInit } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { ApiResponse, TableConfig, TileConfig } from '../../../classes/Classes';\nimport { DataServiceLib } from '../../../services/datalib.service';\nimport { MessageService } from '../../../services/message.service'; // Changed: Confirm + toast for provision action\nimport { ApiErrorService } from '../../../services/api-error.service'; // Added: the summary tiles failed silently and the provision action toasted raw server text (WS-6 Phase 4)\n\n@Component({\n  selector: 'spa-aging',\n  template: `\n    <div style=\"display: flex; align-items: center; justify-content: space-between;\">\n      <h4>Accounts Receivable Aging</h4>\n      <!-- Changed: Post IFRS 9 bad-debt provision delta from the aging matrix -->\n      <button mat-stroked-button color=\"warn\" (click)=\"postProvision()\"><mat-icon>account_balance</mat-icon> Post Bad-Debt Provision</button>\n    </div>\n    <hr>\n    <div *ngIf=\"summaryData\" class=\"mt-3 mb-3\">\n      <spa-tiles [config]=\"tileConfig\" [data]=\"summaryData\"></spa-tiles>\n    </div>\n    \n    <spa-tabs [tableConfigs]=\"agingTableConfigs\"></spa-tabs>\n  `,\n  standalone: false\n})\nexport class AgingComponent implements OnInit {\n\n  public accountingService = inject(AccountingService);\n\n  ngOnInit(): void {\n    this.loadSummaryData();\n  }\n\n  summaryData: any;\n\n  loadSummaryData(): void {\n    this.dataServiceLib.CallApi({ url: 'invoices/aging-summary/x' }, '').subscribe((apiResponse: ApiResponse) => {\n      if (apiResponse.success) {\n        this.summaryData = apiResponse.data;\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'load', 'invoices/aging-summary/x'); // Added: was silent. summaryData stayed undefined, the *ngIf dropped the whole tile strip, and an accounts-receivable page with NO aging totals reads as \"you are owed nothing\" rather than \"we could not work it out\"\n      }\n    });\n  }\n\n  // Changed: Post IFRS 9 bad-debt provision — confirms, calls invoices provision custom action, shows returned summary\n  postProvision(): void {\n    this.messageService.confirm('Post the bad-debt provision? This posts the allowance delta per the aging matrix as a GL journal.').subscribe((result) => {\n      if (result == 'yes') {\n        this.dataServiceLib.CallApi({ url: 'invoices?action=provision', method: 'post' }, {}).subscribe((apiResponse: ApiResponse) => {\n          // Changed: REPLACES the old `'Error: ' + apiResponse.message` toast rather than layering on it.\n          // That string prefixed the server's raw words with a second word for \"error\" and pushed the useful\n          // part right; a leaked SQL fragment reached the user unchanged. 'action' rather than 'submit' —\n          // this is a confirmed page button, not a form, so the 'submit' copy would describe a screen the\n          // user is not looking at.\n          if (apiResponse.success) { this.messageService.toast(apiResponse.message); this.loadSummaryData(); }\n          else this.apiErrorService.presentAppFailure(apiResponse, 'action', 'invoices?action=provision');\n        });\n      }\n    });\n  }\n\n  private messageService = inject(MessageService); // Changed: Injected for provision confirm/toast\n  private apiErrorService = inject(ApiErrorService); // Changed: Injected for the summary load and the provision failure\n\n  agingTableConfigs: TableConfig[];\n  tileConfig = this.accountingService.agingTileConfig;\n\n  constructor(private dataServiceLib: DataServiceLib) {\n\n    // this.tileConfig = this.accountingService.agingTileConfig;\n    this.agingTableConfigs = [\n      {\n        ...this.accountingService.agingBaseTableConfig,\n        tabTitle: 'Current',\n        loadAction: { url: 'invoices/aging-current/x' },\n        countAction: { url: 'invoices/count/aging-current' }\n      },\n      {\n        ...this.accountingService.agingBaseTableConfig,\n        tabTitle: '1-30 Days',\n        loadAction: { url: 'invoices/aging-30/x' },\n        countAction: { url: 'invoices/count/aging-30' }\n      },\n      {\n        ...this.accountingService.agingBaseTableConfig,\n        tabTitle: '31-60 Days',\n        loadAction: { url: 'invoices/aging-60/x' },\n        countAction: { url: 'invoices/count/aging-60' }\n      },\n      {\n        ...this.accountingService.agingBaseTableConfig,\n        tabTitle: '61-90 Days',\n        loadAction: { url: 'invoices/aging-90/x' },\n        countAction: { url: 'invoices/count/aging-90' }\n      },\n      {\n        ...this.accountingService.agingBaseTableConfig,\n        tabTitle: '90+ Days',\n        loadAction: { url: 'invoices/aging-90plus/x' },\n        countAction: { url: 'invoices/count/aging-90plus' }\n      }\n    ];\n  }\n\n}\n","// AP Aging report component for accounts payable tracking — mirrors AR AgingComponent pattern\nimport { Component, inject, OnInit } from '@angular/core';\nimport { PurchasingService } from '../../../services/purchasing.service';\nimport { ApiResponse, TableConfig, TileConfig } from '../../../classes/Classes';\nimport { DataServiceLib } from '../../../services/datalib.service';\nimport { ApiErrorService } from '../../../services/api-error.service'; // Added: the AP summary tiles failed silently, exactly as the AR ones did (WS-6 Phase 4)\n\n@Component({\n  selector: 'spa-supplier-aging',\n  template: `\n    <h4>Accounts Payable Aging</h4>\n    <hr>\n    <div *ngIf=\"summaryData\" class=\"mt-3 mb-3\">\n      <spa-tiles [config]=\"tileConfig\" [data]=\"summaryData\"></spa-tiles>\n    </div>\n\n    <spa-tabs [tableConfigs]=\"agingTableConfigs\"></spa-tabs>\n  `,\n  standalone: false\n})\nexport class SupplierAgingComponent implements OnInit {\n\n  public purchasingService = inject(PurchasingService);\n  private apiErrorService = inject(ApiErrorService); // Changed: Injected so a failed summary load says so\n\n  ngOnInit(): void {\n    this.loadSummaryData();\n  }\n\n  summaryData: any;\n\n  loadSummaryData(): void {\n    this.dataServiceLib.CallApi({ url: 'purchases/aging-summary/x' }, '').subscribe((apiResponse: ApiResponse) => {\n      if (apiResponse.success) {\n        this.summaryData = apiResponse.data;\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'load', 'purchases/aging-summary/x'); // Added: was silent. The tile strip vanished behind its *ngIf, so an accounts-payable page that could not compute its totals looked like a company that owes nothing\n      }\n    });\n  }\n\n  agingTableConfigs: TableConfig[];\n  tileConfig = this.purchasingService.apAgingTileConfig;\n\n  constructor(private dataServiceLib: DataServiceLib) {\n    // Changed: Build 5-tab aging table layout using AP aging base config from PurchasingService\n    this.agingTableConfigs = [\n      {\n        ...this.purchasingService.apAgingBaseTableConfig,\n        tabTitle: 'Current',\n        loadAction: { url: 'purchases/aging-current/x' },\n        countAction: { url: 'purchases/count/aging-current' }\n      },\n      {\n        ...this.purchasingService.apAgingBaseTableConfig,\n        tabTitle: '1-30 Days',\n        loadAction: { url: 'purchases/aging-30/x' },\n        countAction: { url: 'purchases/count/aging-30' }\n      },\n      {\n        ...this.purchasingService.apAgingBaseTableConfig,\n        tabTitle: '31-60 Days',\n        loadAction: { url: 'purchases/aging-60/x' },\n        countAction: { url: 'purchases/count/aging-60' }\n      },\n      {\n        ...this.purchasingService.apAgingBaseTableConfig,\n        tabTitle: '61-90 Days',\n        loadAction: { url: 'purchases/aging-90/x' },\n        countAction: { url: 'purchases/count/aging-90' }\n      },\n      {\n        ...this.purchasingService.apAgingBaseTableConfig,\n        tabTitle: '90+ Days',\n        loadAction: { url: 'purchases/aging-90plus/x' },\n        countAction: { url: 'purchases/count/aging-90plus' }\n      }\n    ];\n  }\n\n}\n","import { Component, OnInit, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n  selector: 'spa-transaction-types',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class TransactionTypesComponent implements OnInit {\n  private accountingService = inject(AccountingService);\n  \n  pageConfig: PageConfig = {\n    title: 'Transaction Types',\n    tableConfig: this.accountingService.transactionTypesTableConfig\n  };\n\n  ngOnInit(): void {\n  }\n}\n","// Transactions page\n// Changed (journal-dialog-conform): the \"New Journal\" button used to be drawn HERE, in a flex row above <spa-page>,\n// which floated it on the app shell outside the page. It is now journalCreateButton on transactionsTableConfig with\n// inHeader: true, so the table header renders it in line with Create Transaction. The hand-rolled\n// JournalEntryDialogComponent it opened is gone — the button now carries the house details dialog config.\nimport { Component, OnInit, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n  selector: 'spa-transactions',\n  template: `<spa-page [config]=\"pageConfig\"></spa-page>`,\n  standalone: false\n})\nexport class TransactionsComponent implements OnInit {\n  private accountingService = inject(AccountingService);\n\n  pageConfig: PageConfig = {\n    title: 'Transactions',\n    tableConfig: this.accountingService.transactionsTableConfig,\n    searchTableConfig: this.accountingService.transactionSearchTableConfig // Changed: Enable search mode with date range, description, account filters\n  };\n\n  ngOnInit(): void {\n  }\n}\n","// Invoice management component for tin-spa library\nimport { HttpClient } from '@angular/common/http';\nimport { Component, OnInit, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { PageConfig } from '../../../classes/Classes';\nimport { HttpService } from '../../../services/http.service';\nimport { MessageService } from '../../../services/message.service';\n\n@Component({\n  selector: 'spa-invoices',\n  template: '<spa-page [config]=\"pageConfig\" (actionClick)=\"actionClicked($event)\"></spa-page>',\n  standalone: false\n})\nexport class InvoicesComponent implements OnInit {\n  public accountingService = inject(AccountingService);\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n  private messageService = inject(MessageService);\n\n  pageConfig: PageConfig = {\n    title: 'Invoices',\n    tableConfig: this.accountingService.invoicesTableConfig\n  };\n\n  ngOnInit(): void {\n  }\n\n  // Handle action click events from the table\n  actionClicked(event: { name: string, data: any }) {\n    if (event.name === 'pdf') {\n      this.messageService.confirm(`Download Invoice ?`).subscribe((result) => {\n        if (result == \"yes\") {\n          this.download(event.data);\n        }\n      });\n    }\n  }\n\n  // Download invoice as PDF\n  download(invoice: any) {\n    this.http.post(`${this.httpService.apiUrl}invoices/pdf?action=x`, invoice,\n      { responseType: 'blob' })\n      .subscribe((response: Blob) => {\n        const blob = new Blob([response], { type: 'application/pdf' });\n        const url = window.URL.createObjectURL(blob);\n        const link = document.createElement('a');\n        link.href = url;\n        link.download = `Invoice_${invoice.invoiceID}.pdf`;\n        link.click();\n        window.URL.revokeObjectURL(url);\n      });\n  }\n}\n","// Statement page (B4) — invoice history plus open-item customer/supplier statements with Excel/PDF export\n// Changed: the two open-item tabs were hand-written markup (a flex row of totals and a raw <table>). They are\n// now the library's own spa-tiles + spa-table, driven by config in AccountingService, so the page picks up\n// every table behaviour centrally: responsive minColumns, the filter box, money formatting and empty states.\n// The PDF and Excel downloads are untouched — both are produced SERVER-SIDE and nothing here contributes to them.\nimport { Component, OnInit, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { HttpService } from '../../../services/http.service';\nimport { PageConfig, TableConfig, TileConfig, Action } from '../../../classes/Classes';\n\n@Component({\n  selector: 'spa-statement',\n  template: `\n    <mat-tab-group>\n      <mat-tab label=\"Invoice History\">\n        <div style=\"padding-top: 8px;\">\n          <spa-page [config]=\"pageConfig\"></spa-page>\n        </div>\n      </mat-tab>\n\n      <mat-tab label=\"Customer Statement\">\n        <ng-container *ngTemplateOutlet=\"statementTab; context: { kind: 'customer' }\"></ng-container>\n      </mat-tab>\n\n      <mat-tab label=\"Supplier Statement\">\n        <ng-container *ngTemplateOutlet=\"statementTab; context: { kind: 'supplier' }\"></ng-container>\n      </mat-tab>\n    </mat-tab-group>\n\n    <ng-template #statementTab let-kind=\"kind\">\n      <div style=\"padding: 16px 0;\">\n\n        <!-- Changed: library inputs instead of raw mat-form-field markup — same three filters, same Run/Export/PDF rules -->\n        <div style=\"display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 12px;\">\n          <spa-select-lite [display]=\"state[kind].entityLabel\" [loadAction]=\"state[kind].listAction\" optionDisplay=\"name\" optionValue=\"value\" [required]=\"false\" [(value)]=\"state[kind].entityId\" width=\"240px\"></spa-select-lite><!-- optionDisplay/optionValue are NOT defaulted by spa-select-common; without them every option binds undefined and nothing can be selected -->\n          <spa-date display=\"From\" width=\"170px\" [required]=\"false\" [value]=\"state[kind].from\" (valueChange)=\"state[kind].from = $event\"></spa-date>\n          <spa-date display=\"To\" width=\"170px\" [required]=\"false\" [value]=\"state[kind].to\" (valueChange)=\"state[kind].to = $event\"></spa-date>\n          <button mat-flat-button color=\"primary\" (click)=\"load(kind)\" [disabled]=\"!state[kind].entityId\">Run</button>\n          <button mat-stroked-button (click)=\"export(kind)\" [disabled]=\"!state[kind].entityId\">\n            <mat-icon>download</mat-icon> Export to Excel\n          </button>\n          <button mat-stroked-button *ngIf=\"kind === 'customer'\" (click)=\"exportPdf(kind)\" [disabled]=\"!state[kind].entityId\">\n            <mat-icon>picture_as_pdf</mat-icon> Download PDF\n          </button>\n        </div>\n\n        <!-- Changed: totals are spa-tiles, lines are spa-table. Nothing renders until a statement has been run,\n             which is exactly what the old *ngIf on the results card did. -->\n        <ng-container *ngIf=\"state[kind].data\">\n          <spa-tiles [config]=\"state[kind].tileConfig\" [data]=\"state[kind].data\"></spa-tiles>\n          <div style=\"margin-top: 12px;\">\n            <spa-table [config]=\"state[kind].tableConfig\" [data]=\"state[kind].lines\" (refreshClick)=\"load(kind)\"></spa-table>\n          </div>\n        </ng-container>\n\n      </div>\n    </ng-template>\n  `,\n  standalone: false\n})\nexport class StatementComponent implements OnInit {\n  public accountingService = inject(AccountingService);\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n\n  pageConfig: PageConfig = {\n    title: 'Statement',\n    tableConfig: this.accountingService.statementTableConfig,\n    searchTableConfig: this.accountingService.statementSearchTableConfig\n  };\n\n  // Per-kind UI state for the customer/supplier open-item tabs.\n  // Changed: each kind carries its OWN cloned table config — two grids are on screen at once and a TableConfig\n  // is mutated by the table it belongs to, so sharing one object between the tabs would cross their state.\n  state: any = {\n    customer: {\n      entityLabel: 'Customer', entityId: null, from: null, to: null, data: null, lines: [],\n      listAction: { url: 'customers/list/x' } as Action,\n      tileConfig: this.accountingService.customerStatementTileConfig as TileConfig,\n      tableConfig: { ...this.accountingService.statementLinesTableConfig } as TableConfig\n    },\n    supplier: {\n      entityLabel: 'Supplier', entityId: null, from: null, to: null, data: null, lines: [],\n      listAction: { url: 'suppliers/list/x' } as Action,\n      tileConfig: this.accountingService.supplierStatementTileConfig as TileConfig,\n      tableConfig: { ...this.accountingService.statementLinesTableConfig } as TableConfig\n    }\n  };\n\n  // Changed: the customer/supplier option lists are loaded by spa-select-lite's own loadAction now, so there is\n  // no hand-rolled options fetch left here. ngOnInit is kept for the interface and for future per-kind defaults.\n  ngOnInit(): void { }\n\n  private query(kind: string): string {\n    const s = this.state[kind];\n    const params = [];\n    if (s.from) params.push(`from=${s.from}`);\n    if (s.to) params.push(`to=${s.to}`);\n    return params.length ? `?${params.join('&')}` : '';\n  }\n\n  load(kind: string) {\n    const s = this.state[kind];\n    if (!s.entityId) return; // Added: the header refresh icon routes here too, and it must not fire before an entity is chosen\n    this.http.get<any>(`${this.httpService.apiUrl}reports/${kind}-statement/${s.entityId}${this.query(kind)}`)\n      .subscribe(res => {\n        s.data = res?.data ?? res?.Data ?? null;\n        s.lines = s.data?.lines ?? []; // Changed: held as a stable reference — binding `data.lines || []` inline would hand spa-table a new array on every change-detection pass\n      });\n  }\n\n  // C8: open-item customer statement as PDF — generated entirely server-side (reports/pdf/customer-statement);\n  // this method only asks for the blob and saves it. Unchanged by the page rewrite.\n  exportPdf(kind: string) {\n    const s = this.state[kind];\n    this.http.get(`${this.httpService.apiUrl}reports/pdf/${kind}-statement${this.query(kind) ? this.query(kind) + '&' : '?'}${kind}Id=${s.entityId}`, { responseType: 'blob' })\n      .subscribe((response: Blob) => {\n        const url = window.URL.createObjectURL(new Blob([response], { type: 'application/pdf' }));\n        const link = document.createElement('a');\n        link.href = url;\n        link.download = `${kind}-statement-${s.entityId}.pdf`;\n        link.click();\n        window.URL.revokeObjectURL(url);\n      });\n  }\n\n  export(kind: string) {\n    const s = this.state[kind];\n    this.http.get(`${this.httpService.apiUrl}reports/export/${kind}-statement${this.query(kind) ? this.query(kind) + '&' : '?'}${kind}Id=${s.entityId}`, { responseType: 'blob' })\n      .subscribe((response: Blob) => {\n        const url = window.URL.createObjectURL(new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }));\n        const link = document.createElement('a');\n        link.href = url;\n        link.download = `${kind}-statement-${s.entityId}.xlsx`;\n        link.click();\n        window.URL.revokeObjectURL(url);\n      });\n  }\n}\n","// Financial Reports component with Trial Balance, P&L, Balance Sheet, General Ledger tabs + Excel exports (B5/B7) and from/to date range (Phase 1)\nimport { Component, OnInit, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { TableConfig } from '../../../classes/Classes';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { DataServiceLib } from '../../../services/datalib.service';\nimport { HttpService } from '../../../services/http.service';\n\n@Component({\n  selector: 'spa-reports',\n  template: `\n    <div style=\"display: flex; align-items: center; justify-content: space-between;\">\n      <h4>Financial Reports</h4>\n      <button mat-stroked-button [matMenuTriggerFor]=\"exportMenu\">\n        <mat-icon>download</mat-icon> Export to Excel\n      </button>\n      <mat-menu #exportMenu=\"matMenu\">\n        <button mat-menu-item (click)=\"export('trial-balance')\">Trial Balance</button>\n        <button mat-menu-item (click)=\"export('pnl')\">Profit &amp; Loss</button>\n        <button mat-menu-item (click)=\"export('balance-sheet')\">Balance Sheet</button>\n        <button mat-menu-item (click)=\"export('gl')\">General Ledger</button>\n        <button mat-menu-item (click)=\"export('vat-return')\">VAT Return (current month)</button>\n        <button mat-menu-item (click)=\"export('cash-flow')\">Cash Flow (current month)</button>\n        <button mat-menu-item (click)=\"export('equity-changes')\">Changes in Equity (current month)</button>\n      </mat-menu>\n    </div>\n    <hr>\n\n    <!-- Changed: From/To date range controls applied to all report tabs (pattern copied from VatReturnComponent) -->\n    <div style=\"display: flex; gap: 16px; align-items: center; margin-bottom: 16px;\">\n      <mat-form-field>\n        <mat-label>From</mat-label>\n        <input matInput type=\"date\" [(ngModel)]=\"from\">\n      </mat-form-field>\n      <mat-form-field>\n        <mat-label>To</mat-label>\n        <input matInput type=\"date\" [(ngModel)]=\"to\">\n      </mat-form-field>\n      <button mat-flat-button color=\"primary\" (click)=\"buildTabs()\">Run</button>\n    </div>\n\n    <spa-tabs [tableConfigs]=\"reportTabConfigs\"></spa-tabs>\n  `,\n  standalone: false\n})\nexport class ReportsComponent implements OnInit {\n\n  private httpService = inject(HttpService); // Changed: For export downloads\n  private http = inject(HttpClient); // Changed: For export downloads\n\n  from = ''; // Changed: Optional report period start\n  to = ''; // Changed: Optional report period end\n\n  constructor(private dataServiceLib: DataServiceLib, public accountingService: AccountingService) {\n    this.buildTabs(); // Changed: Tabs built via method so Run can rebuild with date params\n  }\n\n  ngOnInit(): void {\n  }\n\n  reportTabConfigs: TableConfig[] = [];\n\n  // Changed: Append from/to query params when set — backends that ignore them are unaffected\n  private withRange(url: string): string {\n    const params: string[] = [];\n    if (this.from) params.push(`from=${this.from}`);\n    if (this.to) params.push(`to=${this.to}`);\n    return params.length ? `${url}?${params.join('&')}` : url;\n  }\n\n  // Changed: Rebuild tab configs with the current date range applied to every report URL\n  buildTabs() {\n    this.reportTabConfigs = [\n      {\n        ...this.accountingService.trialBalanceTableConfig,\n        tabTitle: 'Trial Balance',\n        loadAction: { url: this.withRange('accounts/reports/trialbalance') },\n      },\n      {\n        ...this.accountingService.pnlTableConfig,\n        tabTitle: 'Profit & Loss',\n        loadAction: { url: this.withRange('accounts/reports/pnl') },\n      },\n      {\n        ...this.accountingService.balanceSheetReportTableConfig,\n        tabTitle: 'Balance Sheet',\n        loadAction: { url: this.withRange('accounts/reports/balancesheet') },\n      },\n      { // Changed: General Ledger detail tab (B5)\n        ...this.accountingService.generalLedgerTableConfig,\n        tabTitle: 'General Ledger',\n        loadAction: { url: this.withRange('reports/gl') },\n      },\n      { // Changed: IAS 7 cash flow statement tab (C5)\n        ...this.accountingService.cashFlowTableConfig,\n        tabTitle: 'Cash Flow',\n        loadAction: { url: this.withRange('reports/cash-flow') },\n      },\n      { // Changed: Statement of changes in equity tab (C5)\n        ...this.accountingService.equityChangesTableConfig,\n        tabTitle: 'Changes in Equity',\n        loadAction: { url: this.withRange('reports/equity-changes') },\n      }\n    ];\n  }\n\n  // Changed: Download an xlsx export from the shared reports endpoint (B7) with the selected date range applied\n  export(report: string) {\n    this.http.get(`${this.httpService.apiUrl}${this.withRange(`reports/export/${report}`)}`, { responseType: 'blob' })\n      .subscribe((response: Blob) => {\n        const url = window.URL.createObjectURL(new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }));\n        const link = document.createElement('a');\n        link.href = url;\n        link.download = `${report}.xlsx`;\n        link.click();\n        window.URL.revokeObjectURL(url);\n      });\n  }\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { TinSpaModule } from '../../../tin-spa.module';\nimport { AccountingService } from '../../../services/accounting.service';\n\n// Tax Rates management page - CRUD for VAT tax rates\n@Component({\n  selector: 'spa-tax-rates',\n  standalone: true,\n  imports: [TinSpaModule],\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class TaxRatesComponent {\n  private accountingService = inject(AccountingService);\n\n  pageConfig: PageConfig = {\n    title: 'Tax Rates',\n    tableConfig: this.accountingService.taxRatesTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { TinSpaModule } from '../../../tin-spa.module';\nimport { AccountingService } from '../../../services/accounting.service';\n\n// Standing Orders management page — CRUD for recurring scheduled transactions\n@Component({\n  selector: 'spa-standing-orders',\n  standalone: true,\n  imports: [TinSpaModule],\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class StandingOrdersComponent {\n  private accountingService = inject(AccountingService);\n\n  pageConfig: PageConfig = {\n    title: 'Standing Orders',\n    tableConfig: this.accountingService.standingOrdersTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { TinSpaModule } from '../../../tin-spa.module';\nimport { AccountingService } from '../../../services/accounting.service';\n\n// Currency management page - CRUD for multi-currency support\n@Component({\n  selector: 'spa-currencies',\n  standalone: true,\n  imports: [TinSpaModule],\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class CurrenciesComponent {\n  private accountingService = inject(AccountingService);\n\n  pageConfig: PageConfig = {\n    title: 'Currencies',\n    tableConfig: this.accountingService.currenciesTableConfig\n  };\n}\n","// Budget management component for CRUD operations\nimport { Component, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n  selector: 'spa-budgets',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class BudgetsComponent {\n  private accountingService = inject(AccountingService);\n\n  pageConfig: PageConfig = {\n    title: 'Budgets',\n    tableConfig: this.accountingService.budgetsTableConfig\n  };\n}\n","// Budget vs Actual report component with budget selector, tiles, and tabbed tables\nimport { Component, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { TableConfig, TileConfig } from '../../../classes/Classes';\nimport { HttpService } from '../../../services/http.service';\n\n@Component({\n  selector: 'spa-budget-vs-actual',\n  template: `\n    <h4>Budget vs Actual</h4>\n    <hr>\n\n    <div style=\"max-width: 300px; margin-bottom: 16px;\">\n      <spa-select-lite display=\"Select Budget\" [loadAction]=\"{ url: 'budgets/list/x' }\" optionDisplay=\"name\" optionValue=\"value\" [(value)]=\"selectedBudgetID\" (valueChange)=\"onBudgetSelected()\"></spa-select-lite><!-- Changed: optionDisplay/optionValue are NOT defaulted by spa-select-common (both default to \"\"), so every option rendered blank and bound undefined — no budget could be picked. 'name'/'value' match BaseController.GetList's ListOption shape, same as the statement page -->\n    </div>\n\n    <spa-tiles *ngIf=\"summaryTileConfig.loadAction\" [config]=\"summaryTileConfig\"></spa-tiles>\n\n    <spa-tabs *ngIf=\"reportTabConfigs.length > 0\" [tableConfigs]=\"reportTabConfigs\"></spa-tabs>\n  `,\n  standalone: false\n})\nexport class BudgetVsActualComponent {\n  private accountingService = inject(AccountingService);\n  private httpService = inject(HttpService);\n\n  selectedBudgetID: number | null = null;\n  reportTabConfigs: TableConfig[] = [];\n\n  summaryTileConfig: TileConfig = { ...this.accountingService.budgetSummaryTileConfig };\n\n  // Load report data when a budget is selected\n  onBudgetSelected() {\n    if (!this.selectedBudgetID) {\n      this.reportTabConfigs = [];\n      return;\n    }\n\n    // Update tile config to load summary for selected budget\n    this.summaryTileConfig = {\n      ...this.accountingService.budgetSummaryTileConfig,\n      loadAction: { url: `budgetreport/summary/${this.selectedBudgetID}` }\n    };\n\n    // Build tab configs with dynamic URLs for selected budget\n    this.reportTabConfigs = [\n      {\n        ...this.accountingService.budgetVsActualByPeriodTableConfig,\n        loadAction: { url: `budgetreport/vsactual/${this.selectedBudgetID}` }\n      },\n      {\n        ...this.accountingService.budgetVsActualByAccountTableConfig,\n        loadAction: { url: `budgetreport/summary/${this.selectedBudgetID}` }\n      }\n    ];\n  }\n}\n","import { Component } from '@angular/core';\nimport { TileConfig, ChartConfig } from '../../../classes/Classes';\n\n// Accounting module dashboard — pure financial/account performance (invoice-specific moved to invoicing)\n@Component({\n  selector: 'spa-accounting-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>account_balance</mat-icon> Accounting Dashboard</h4>\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n      <!-- Changed: Separate cash/bank balance chart with own data source -->\n      <spa-charts [config]=\"cashBankChartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n  `],\n  standalone: false\n})\nexport class AccountingDashboardComponent {\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'inflows', alias: 'Inflows (MTD)', color: '#4caf50', icon: 'arrow_downward', style: 'icon', info: 'MTD cash inflows' }, // Changed: Cash inflows tile\n      { name: 'outflows', alias: 'Outflows (MTD)', color: '#f44336', icon: 'arrow_upward', style: 'icon', info: 'MTD cash outflows' }, // Changed: Cash outflows tile\n      { name: 'netCashFlow', alias: 'Net Cash Flow', color: '#2196f3', icon: 'swap_vert', style: 'icon', info: 'Net cash movement' }, // Changed: Net cash flow tile\n      { name: 'revenue', alias: 'Revenue (MTD)', color: '#4caf50', icon: 'trending_up', style: 'icon', info: 'MTD revenue' },\n      { name: 'expenses', alias: 'Expenses (MTD)', color: '#f44336', icon: 'trending_down', style: 'icon', info: 'MTD expenses' },\n      { name: 'cashBalance', alias: 'Cash & Bank', color: '#ff9800', icon: 'account_balance_wallet', style: 'icon', info: 'Cash + bank total' },\n    ],\n    loadAction: { url: 'accounts/dashboard-summary/x' },\n    loadInit: true\n  };\n\n  // Changed: Replaced collectionRate/invoiceStatusSplit with profitMargin/expenseBreakdown\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'profitMargin', alias: 'Profit Margin', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'profitMargin' }, footer: 'Net profit / revenue', footerIcon: 'pie_chart' }, // Changed: Replaced collectionRate\n      { name: 'revenueTrendSpark', alias: 'Revenue Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'revenueTrendSpark' }, footer: 'Last 12 months', footerIcon: 'show_chart' },\n      { name: 'expenseBreakdown', alias: 'Expense Breakdown', color: '#ff9800', chart: { type: 'pie', colors: ['#f44336', '#ff5722', '#ff9800', '#ffc107', '#ffeb3b', '#9e9e9e'], height: 130, dataField: 'expenseBreakdown' }, footer: 'Top 5 + Other', footerIcon: 'donut_large' }, // Changed: Replaced invoiceStatusSplit\n      { name: 'expenseTrendSpark', alias: 'Expense Trend', color: '#f44336', chart: { type: 'bar', colors: ['#f44336', '#ef5350', '#e57373', '#ef9a9a', '#ffcdd2', '#f44336'], height: 100, dataField: 'expenseTrendSpark' }, footer: 'Last 6 months', footerIcon: 'trending_down' },\n    ],\n    loadAction: { url: 'accounts/dashboard-chart-tiles/x' },\n    loadInit: true\n  };\n\n  // Changed: Replaced arAging/invoiceStatus with cashFlow/transactionVolume\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'revenueTrend', title: 'Revenue vs Expenses Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336'], showLegend: true },\n      { name: 'cashFlow', title: 'Monthly Cash Flow', type: 'bar', height: '300px', colors: ['#4caf50', '#f44336'], showLegend: true }, // Changed: Replaced arAging\n      { name: 'accountBalances', title: 'Account Balances by Type', type: 'bar', height: '300px', colors: ['#2196f3', '#f44336', '#4caf50', '#ff9800', '#9c27b0'] },\n      { name: 'transactionVolume', title: 'Monthly Transaction Volume', type: 'bar', height: '300px', colors: ['#7c4dff'] }, // Changed: Replaced invoiceStatus\n    ],\n    loadAction: { url: 'accounts/dashboard-charts/x' },\n    loadInit: true,\n    columns: 2\n  };\n\n  // Changed: New cash/bank running balance line chart with separate data source\n  cashBankChartConfig: ChartConfig = {\n    charts: [\n      { name: 'cashBankBalances', title: 'Cash & Bank Balances (30 Days)', type: 'line', height: '500px', showPoints: true, tension: 0.4, showLegend: true,\n        options: { scales: { y: { grid: { color: '#f0f0f0', drawBorder: false }, ticks: { font: { size: 11 }, color: '#999', maxTicksLimit: 12 }, border: { display: false } } } } }, // Changed: More granular Y-axis ticks for better readability\n    ],\n    loadAction: { url: 'accounts/dashboard-cash-balances/x' },\n    loadInit: true,\n    columns: 1\n  };\n}\n","import { Component, OnInit } from '@angular/core';\nimport { TileConfig, ChartConfig, ApiResponse } from '../../../classes/Classes';\nimport { DataServiceLib } from '../../../services/datalib.service';\n\n// Invoice module dashboard with pipeline visibility, aging, and collection KPIs\n@Component({\n  selector: 'spa-invoice-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>receipt_long</mat-icon> Invoice Dashboard</h4>\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n\n      <!-- Attention Required sub-table -->\n      <div *ngIf=\"attentionItems.length > 0\" class=\"attention-section\">\n        <h5 class=\"section-title\">\n          <mat-icon style=\"vertical-align: middle; margin-right: 4px; color: #f44336;\">warning</mat-icon>\n          Needs Attention\n        </h5>\n        <table class=\"kpi-table\">\n          <thead>\n            <tr>\n              <th>Invoice</th>\n              <th>Customer</th>\n              <th>Due Date</th>\n              <th>Days Overdue</th>\n              <th>Outstanding</th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr *ngFor=\"let item of attentionItems\">\n              <td>{{ item.invoiceNumber }}</td>\n              <td>{{ item.customerName }}</td>\n              <td>{{ item.dueDate | date:'mediumDate' }}</td>\n              <td style=\"color: #f44336; font-weight: 500;\">{{ item.daysOverdue }}</td>\n              <td>{{ item.outstandingAmount | currency }}</td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n    .attention-section { margin-top: 16px; }\n    .section-title { display: flex; align-items: center; margin-bottom: 8px; color: #333; font-weight: 500; }\n    .kpi-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n    .kpi-table th { text-align: left; padding: 8px 12px; background: #f5f5f5; border-bottom: 2px solid #e0e0e0; font-weight: 500; }\n    .kpi-table td { padding: 8px 12px; border-bottom: 1px solid #eee; }\n    .kpi-table tr:hover { background: #fafafa; }\n  `],\n  standalone: false\n})\nexport class InvoiceDashboardComponent implements OnInit {\n\n  constructor(private dataService: DataServiceLib) { }\n\n  attentionItems: any[] = [];\n\n  // Changed: Summary tiles — invoice pipeline KPIs\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'totalInvoices', alias: 'Total Invoices', color: '#1565c0', icon: 'receipt_long', style: 'icon', info: 'All active invoices' },\n      { name: 'drafts', alias: 'Drafts', color: '#9e9e9e', icon: 'edit_note', style: 'icon', info: 'Invoices awaiting submission' },\n      { name: 'outstandingAmount', alias: 'Outstanding', color: '#ff9800', icon: 'pending', style: 'icon', prefix: '$', info: 'Total unpaid amount' },\n      { name: 'overdueCount', alias: 'Overdue', color: '#f44336', icon: 'warning', style: 'icon', info: 'Invoices past due date' },\n      { name: 'paidThisMonth', alias: 'Paid (Month)', color: '#4caf50', icon: 'check_circle', style: 'icon', info: 'Fully paid this month' },\n      { name: 'avgDaysToPay', alias: 'Avg Days to Pay', color: '#7b1fa2', icon: 'schedule', style: 'icon', suffix: ' days', info: 'Average payment turnaround' },\n    ],\n    loadAction: { url: 'invoices/dashboard-summary/x' },\n    loadInit: true\n  };\n\n  // Changed: Chart tiles — collection gauge, trend sparkline, status pie, aging bar\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'collectionRate', alias: 'Collection Rate', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'collectionRate' }, footer: 'Amount collected vs invoiced', footerIcon: 'check_circle' },\n      { name: 'invoiceTrend', alias: 'Invoice Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'invoiceTrend' }, footer: 'Last 12 months', footerIcon: 'timeline' },\n      { name: 'statusDistribution', alias: 'Status Split', color: '#ff9800', chart: { type: 'pie', colors: ['#9e9e9e', '#2196f3', '#ff9800', '#4caf50', '#f44336'], height: 130, dataField: 'statusDistribution' }, footer: 'Current distribution', footerIcon: 'pie_chart' },\n      { name: 'agingSnapshot', alias: 'Aging Snapshot', color: '#f44336', chart: { type: 'bar', colors: ['#4caf50', '#ff9800', '#ff5722', '#f44336', '#b71c1c'], height: 100, dataField: 'agingSnapshot' }, footer: 'Outstanding by age', footerIcon: 'bar_chart' },\n    ],\n    loadAction: { url: 'invoices/dashboard-chart-tiles/x' },\n    loadInit: true\n  };\n\n  // Changed: Full charts — revenue pipeline, aging breakdown, top customers, payment trend\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'revenuePipeline', title: 'Invoiced vs Collected', type: 'bar', height: '300px', showLegend: true, colors: ['#2196f3', '#4caf50'] },\n      { name: 'agingBreakdown', title: 'AR Aging Breakdown', type: 'bar', height: '300px', colors: ['#4caf50', '#ff9800', '#ff5722', '#f44336', '#b71c1c'] },\n      { name: 'topCustomers', title: 'Top Customers by Outstanding', type: 'bar', height: '300px', colors: ['#1565c0', '#1976d2', '#1e88e5', '#2196f3', '#42a5f5'] },\n      { name: 'paymentTrend', title: 'Payment Collection Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50'], showLegend: true },\n      { name: 'collectionPerformance', title: 'Collection Performance (12 Months)', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#f57c00', '#4caf50'], showLegend: true }, // Changed: Avg days to pay + on-time rate trend\n    ],\n    loadAction: { url: 'invoices/dashboard-charts/x' },\n    loadInit: true,\n    columns: 2\n  };\n\n  ngOnInit(): void {\n    // Load attention items — top overdue invoices needing action\n    this.dataService.CallApi({ url: 'invoices/dashboard-attention/x' }).subscribe((res: ApiResponse) => {\n      if (res.success) this.attentionItems = res.data || [];\n    });\n  }\n}\n","// Credit Notes page (B6) — invoice corrections/returns with GL reversal posting\nimport { Component, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n  selector: 'spa-credit-notes',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class CreditNotesComponent {\n  public accountingService = inject(AccountingService);\n\n  pageConfig: PageConfig = {\n    title: 'Credit Notes',\n    tableConfig: this.accountingService.creditNotesTableConfig\n  };\n}\n","// VAT Return page (B2) — ZIMRA VAT7-style summary for a selected tax period\n// Phase 2 compliance: sales splits (standard/zero-rated/exempt), per-currency breakdown, GL reconciliation, WHT remittance tab\nimport { Component, OnInit, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { HttpService } from '../../../services/http.service';\n\n@Component({\n  selector: 'spa-vat-return',\n  template: `\n    <div style=\"display: flex; align-items: center; justify-content: space-between;\">\n      <h4>VAT Return</h4>\n      <button mat-stroked-button (click)=\"export()\" [disabled]=\"!data\">\n        <mat-icon>download</mat-icon> Export to Excel\n      </button>\n    </div>\n    <hr>\n\n    <div style=\"display: flex; gap: 16px; align-items: center; margin-bottom: 16px;\">\n      <mat-form-field>\n        <mat-label>From</mat-label>\n        <input matInput type=\"date\" [(ngModel)]=\"from\">\n      </mat-form-field>\n      <mat-form-field>\n        <mat-label>To</mat-label>\n        <input matInput type=\"date\" [(ngModel)]=\"to\">\n      </mat-form-field>\n      <button mat-flat-button color=\"primary\" (click)=\"load()\">Run</button>\n    </div>\n\n    <mat-tab-group>\n      <mat-tab label=\"VAT Return\">\n        <mat-card *ngIf=\"data\" style=\"max-width: 640px; padding: 16px; margin-top: 16px;\">\n          <table style=\"width: 100%; border-collapse: collapse;\">\n            <tr><td style=\"padding: 6px 0;\">Standard Rated Sales (excl. VAT)</td><td style=\"text-align: right;\">{{ data.standardRatedSales | number:'1.2-2' }}</td></tr>\n            <tr><td style=\"padding: 6px 0;\">Zero Rated Sales</td><td style=\"text-align: right;\">{{ data.zeroRatedSales | number:'1.2-2' }}</td></tr>\n            <tr *ngIf=\"data.exemptSales != null\"><td style=\"padding: 6px 0;\">Exempt Sales</td><td style=\"text-align: right;\">{{ data.exemptSales | number:'1.2-2' }}</td></tr>\n            <tr style=\"border-top: 1px solid #ddd;\"><td style=\"padding: 6px 0;\"><b>Total Sales</b></td><td style=\"text-align: right;\"><b>{{ data.totalSales | number:'1.2-2' }}</b></td></tr>\n            <tr><td style=\"padding: 6px 0;\">Output VAT</td><td style=\"text-align: right;\">{{ data.outputVat | number:'1.2-2' }}</td></tr>\n            <tr><td style=\"padding: 6px 0;\">Total Purchases (excl. VAT)</td><td style=\"text-align: right;\">{{ data.totalPurchases | number:'1.2-2' }}</td></tr>\n            <tr><td style=\"padding: 6px 0;\">Input VAT</td><td style=\"text-align: right;\">{{ data.inputVat | number:'1.2-2' }}</td></tr>\n            <tr style=\"border-top: 2px solid #333;\">\n              <td style=\"padding: 8px 0;\"><b>{{ data.isPayable ? 'VAT Payable to ZIMRA' : 'VAT Refundable' }}</b></td>\n              <td style=\"text-align: right;\"><b [style.color]=\"data.isPayable ? 'red' : 'green'\">{{ data.netVat | number:'1.2-2' }}</b></td>\n            </tr>\n          </table>\n        </mat-card>\n\n        <!-- Added: per-currency breakdown from byCurrency -->\n        <mat-card *ngIf=\"data?.byCurrency?.length\" style=\"max-width: 900px; padding: 16px; margin-top: 16px;\">\n          <h5 style=\"margin-top: 0;\">Breakdown by Currency</h5>\n          <table style=\"width: 100%; border-collapse: collapse;\">\n            <tr style=\"border-bottom: 1px solid #ddd;\">\n              <th style=\"text-align: left; padding: 6px 0;\">Currency</th>\n              <th style=\"text-align: right;\">Standard Sales</th>\n              <th style=\"text-align: right;\">Zero Rated</th>\n              <th style=\"text-align: right;\">Exempt</th>\n              <th style=\"text-align: right;\">Output VAT</th>\n              <th style=\"text-align: right;\">Input VAT</th>\n              <th style=\"text-align: right;\">Net VAT</th>\n            </tr>\n            <tr *ngFor=\"let c of data.byCurrency\">\n              <td style=\"padding: 6px 0;\">{{ c.currencyCode }}</td>\n              <td style=\"text-align: right;\">{{ c.standardRatedSales | number:'1.2-2' }}</td>\n              <td style=\"text-align: right;\">{{ c.zeroRatedSales | number:'1.2-2' }}</td>\n              <td style=\"text-align: right;\">{{ c.exemptSales | number:'1.2-2' }}</td>\n              <td style=\"text-align: right;\">{{ c.outputVat | number:'1.2-2' }}</td>\n              <td style=\"text-align: right;\">{{ c.inputVat | number:'1.2-2' }}</td>\n              <td style=\"text-align: right;\"><b>{{ c.netVat | number:'1.2-2' }}</b></td>\n            </tr>\n          </table>\n        </mat-card>\n\n        <!-- Added: GL reconciliation — output VAT per GL vs per documents -->\n        <mat-card *ngIf=\"data?.glReconciliation\" style=\"max-width: 640px; padding: 16px; margin-top: 16px;\">\n          <h5 style=\"margin-top: 0;\">GL Reconciliation (Output VAT)</h5>\n          <table style=\"width: 100%; border-collapse: collapse;\">\n            <tr><td style=\"padding: 6px 0;\">Output VAT per GL</td><td style=\"text-align: right;\">{{ data.glReconciliation.outputVatGL | number:'1.2-2' }}</td></tr>\n            <tr><td style=\"padding: 6px 0;\">Output VAT per Documents</td><td style=\"text-align: right;\">{{ data.glReconciliation.outputVatFromDocuments | number:'1.2-2' }}</td></tr>\n            <tr style=\"border-top: 1px solid #ddd;\">\n              <td style=\"padding: 6px 0;\"><b>Difference</b></td>\n              <td style=\"text-align: right;\"><b [style.color]=\"(data.glReconciliation.difference | number:'1.2-2') !== '0.00' ? '#e65100' : 'inherit'\">{{ data.glReconciliation.difference | number:'1.2-2' }}</b></td>\n            </tr>\n          </table>\n          <p *ngIf=\"(data.glReconciliation.difference | number:'1.2-2') !== '0.00'\" style=\"color: #e65100; margin: 8px 0 0;\">\n            <mat-icon style=\"vertical-align: middle; font-size: 18px;\">warning</mat-icon>\n            GL does not agree with document totals — investigate before filing.\n          </p>\n        </mat-card>\n      </mat-tab>\n\n      <!-- Added: WHT remittance report — 30% withholding on payments to suppliers without valid ITF263 -->\n      <mat-tab label=\"Withholding Tax\">\n        <mat-card style=\"max-width: 900px; padding: 16px; margin-top: 16px;\">\n          <h5 style=\"margin-top: 0;\">Withholding Tax Remittance (30% — no valid ITF263)</h5>\n          <table *ngIf=\"whtData?.length\" style=\"width: 100%; border-collapse: collapse;\">\n            <tr style=\"border-bottom: 1px solid #ddd;\">\n              <th style=\"text-align: left; padding: 6px 0;\">Supplier</th>\n              <th style=\"text-align: left;\">Date</th>\n              <th style=\"text-align: right;\">Gross</th>\n              <th style=\"text-align: right;\">WHT</th>\n              <th style=\"text-align: right;\">Net Paid</th>\n            </tr>\n            <tr *ngFor=\"let w of whtData\">\n              <td style=\"padding: 6px 0;\">{{ w.supplierName || w.supplier }}</td>\n              <td>{{ (w.paymentDate || w.date) | date:'mediumDate' }}</td>\n              <td style=\"text-align: right;\">{{ (w.grossAmount ?? w.gross) | number:'1.2-2' }}</td>\n              <td style=\"text-align: right;\">{{ (w.whtAmount ?? w.wht) | number:'1.2-2' }}</td>\n              <td style=\"text-align: right;\">{{ (w.netAmount ?? w.net) | number:'1.2-2' }}</td>\n            </tr>\n          </table>\n          <p *ngIf=\"!whtData?.length\" style=\"color: #757575;\">No withheld supplier payments in this period.</p>\n        </mat-card>\n      </mat-tab>\n    </mat-tab-group>\n  `,\n  standalone: false\n})\nexport class VatReturnComponent implements OnInit {\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n\n  from = '';\n  to = '';\n  data: any = null;\n  whtData: any[] = []; // Added: WHT remittance rows for the selected period\n\n  ngOnInit(): void {\n    // Default period: current calendar month\n    const now = new Date();\n    this.from = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().substring(0, 10);\n    this.to = new Date(now.getFullYear(), now.getMonth() + 1, 0).toISOString().substring(0, 10);\n    this.load();\n  }\n\n  load() {\n    this.http.get<any>(`${this.httpService.apiUrl}reports/vat-return?from=${this.from}&to=${this.to}`)\n      .subscribe(res => this.data = res?.data ?? res?.Data ?? null);\n    // Added: load WHT remittance rows for the same period (SupplierPayments criteria, value = \"from,to\")\n    this.http.get<any>(`${this.httpService.apiUrl}supplierpayments/wht-remittance/${this.from},${this.to}`) // Changed: aligned with backend SupplierPaymentsController.CustomCriteria route shape\n      .subscribe(res => this.whtData = res?.data ?? res?.Data ?? []);\n  }\n\n  export() {\n    this.http.get(`${this.httpService.apiUrl}reports/export/vat-return?from=${this.from}&to=${this.to}`, { responseType: 'blob' })\n      .subscribe((response: Blob) => {\n        const url = window.URL.createObjectURL(new Blob([response]));\n        const link = document.createElement('a');\n        link.href = url;\n        link.download = `vat-return-${this.from}-to-${this.to}.xlsx`;\n        link.click();\n        window.URL.revokeObjectURL(url);\n      });\n  }\n}\n","// Fiscal Periods page (C2) — period create/close/reopen/lock management\nimport { Component, OnInit, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n  selector: 'spa-fiscal-periods',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class FiscalPeriodsComponent implements OnInit {\n  public accountingService = inject(AccountingService);\n\n  pageConfig: PageConfig = {\n    title: 'Fiscal Periods',\n    tableConfig: this.accountingService.fiscalPeriodsTableConfig\n  };\n\n  ngOnInit(): void {\n  }\n}\n","// Customer Receipts page (C3) — receipts list with new-receipt and allocate actions\nimport { Component, OnInit, ViewChild, inject } from '@angular/core';\n// Changed: HttpClient import dropped with the injection above — the PDF download moved to AccountingService.\nimport { MatDialog } from '@angular/material/dialog';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { DataServiceLib } from '../../../services/datalib.service'; // Added: single resolution point for the modern dialog surface\nimport { PageConfig } from '../../../classes/Classes';\nimport { PageComponent } from '../../../components/page/page.component';\nimport { ReceiptDialogComponent } from './receipt-dialog.component';\n\n@Component({\n  selector: 'spa-receipts',\n  template: `\n    <div style=\"display: flex; justify-content: flex-end;\">\n      <button mat-stroked-button (click)=\"openDialog()\">\n        <mat-icon>receipt</mat-icon> New Receipt\n      </button>\n    </div>\n    <spa-page [config]=\"pageConfig\"></spa-page>\n  `,\n  standalone: false\n})\nexport class ReceiptsComponent implements OnInit {\n  public accountingService = inject(AccountingService);\n  private dataService = inject(DataServiceLib); // Added: supplies dialogPanelClass so this dialog honours appConfig.dialogStyle\n  private dialog = inject(MatDialog);\n  // Changed: the HttpService/HttpClient injections are gone — the PDF blob download they existed for now lives\n  // in AccountingService, and this page no longer makes any HTTP call of its own.\n\n  @ViewChild(PageComponent) page?: PageComponent;\n\n  pageConfig: PageConfig = {\n    title: 'Customer Receipts',\n    tableConfig: this.accountingService.customerReceiptsTableConfig\n  };\n\n  constructor() {\n    // Changed: the allocate wiring is GONE from here. AccountingService now owns receiptAllocateButton.onClick,\n    // so the button works in every consumer instead of only on this page — this constructor was the single\n    // reason shift's and grip's Day Book allocate lanes could not use it. Re-assigning it here would just\n    // narrow it back to this page's dialog, and the service's handler is the same dialog with the same data.\n    // Changed: the PDF wiring is GONE from here too — AccountingService now owns receiptPdfButton.onClick via\n    // downloadReceiptPdf, so the button works in every consumer. That was the last library backlog row of the\n    // pair. This constructor is now empty of wiring and exists only to satisfy the class.\n  }\n\n  ngOnInit(): void {\n  }\n\n  // Changed: this is now the NEW RECEIPT path only — allocation moved to AccountingService.openReceiptAllocation.\n  // The optional row parameter is kept so the signature stays compatible for any consumer holding a reference.\n  openDialog(row?: any) {\n    this.dialog.open(ReceiptDialogComponent, { width: '860px', maxWidth: '95vw', data: row ?? null, panelClass: this.dataService?.dialogPanelClass ?? [] }) // Changed: was missing panelClass, so this dialog never picked up the modern surface\n      .afterClosed().subscribe(saved => { if (saved) this.page?.tableReload.next(true); });\n  }\n\n  // Changed: the blob download itself moved to AccountingService.downloadReceiptPdf. This method is kept as a\n  // thin delegate so the signature stays available to any consumer holding a reference to this component,\n  // exactly as openDialog's optional row parameter was kept in 3a681d6.\n  downloadPdf(receipt: any) {\n    this.accountingService.downloadReceiptPdf(receipt);\n  }\n}\n","// Bank statement import dialog (C4) — paste CSV lines (date, description, reference, amount) for a GL cash/bank account\nimport { Component, OnInit, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { MatDialogRef } from '@angular/material/dialog';\nimport { HttpService } from '../../../services/http.service';\nimport { MessageService } from '../../../services/message.service';\n\n@Component({\n  selector: 'spa-statement-import-dialog',\n  template: `\n    <h2 mat-dialog-title>Import Bank Statement</h2>\n    <mat-dialog-content>\n      <div style=\"display: flex; gap: 16px; flex-wrap: wrap;\">\n        <mat-form-field style=\"min-width: 220px;\">\n          <mat-label>Account</mat-label>\n          <mat-select [(ngModel)]=\"accountID\">\n            <mat-option *ngFor=\"let option of accounts\" [value]=\"option.value\">{{ option.name }}</mat-option>\n          </mat-select>\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>From</mat-label>\n          <input matInput type=\"date\" [(ngModel)]=\"statementFrom\">\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>To</mat-label>\n          <input matInput type=\"date\" [(ngModel)]=\"statementTo\">\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>Closing Balance</mat-label>\n          <input matInput type=\"number\" [(ngModel)]=\"closingBalance\">\n        </mat-form-field>\n      </div>\n      <mat-form-field style=\"width: 100%;\">\n        <mat-label>Statement lines (CSV: date, description, reference, amount — money out negative)</mat-label>\n        <textarea matInput rows=\"10\" [(ngModel)]=\"csv\" (ngModelChange)=\"parseCsv()\" placeholder=\"2026-07-01, Deposit ABC, REF001, 1500.00&#10;2026-07-03, Bank charges, , -25.50\"></textarea>\n      </mat-form-field>\n      <p *ngIf=\"parseError\" style=\"color: red;\"><em>{{ parseError }}</em></p>\n      <p *ngIf=\"parsedLines.length\"><em>{{ parsedLines.length }} line(s) parsed, net movement {{ netMovement | number:'1.2-2' }}</em></p>\n    </mat-dialog-content>\n    <mat-dialog-actions align=\"end\">\n      <button mat-button (click)=\"dialogRef.close(false)\">Cancel</button>\n      <button mat-flat-button color=\"primary\" (click)=\"save()\" [disabled]=\"!canSave\">Import</button>\n    </mat-dialog-actions>\n  `,\n  standalone: false\n})\nexport class StatementImportDialogComponent implements OnInit {\n  public dialogRef = inject(MatDialogRef<StatementImportDialogComponent>);\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n  private messageService = inject(MessageService);\n\n  accountID: number | null = null;\n  statementFrom = '';\n  statementTo = '';\n  closingBalance = 0;\n  csv = '';\n  parseError = '';\n  accounts: any[] = [];\n\n  ngOnInit(): void {\n    this.http.get<any>(`${this.httpService.apiUrl}accounts/list/x`)\n      .subscribe(res => this.accounts = res?.data ?? []);\n    const now = new Date();\n    this.statementFrom = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().substring(0, 10);\n    this.statementTo = new Date(now.getFullYear(), now.getMonth() + 1, 0).toISOString().substring(0, 10);\n  }\n\n  // Changed: materialized — parsedLines/netMovement were getters read 4x per change-detection cycle\n  // (twice in the template, plus netMovement and canSave), each call re-parsing the whole CSV, allocating a\n  // new array AND writing this.parseError from inside a getter (a side effect during change detection).\n  parsedLines: any[] = [];\n  netMovement = 0;\n\n  // Added: recomputed only when the CSV text actually changes (bound via (ngModelChange))\n  parseCsv() {\n    this.parseError = '';\n    const lines: any[] = [];\n    for (const raw of this.csv.split('\\n').map(l => l.trim()).filter(l => l)) {\n      const parts = raw.split(',').map(p => p.trim());\n      if (parts.length < 2) { this.parseError = `Cannot parse: \"${raw}\"`; this.parsedLines = []; this.netMovement = 0; return; }\n      const amount = parseFloat(parts[parts.length - 1]);\n      if (isNaN(amount)) { this.parseError = `Invalid amount in: \"${raw}\"`; this.parsedLines = []; this.netMovement = 0; return; }\n      lines.push({ date: parts[0], description: parts[1] ?? '', reference: parts.length > 3 ? parts[2] : '', amount });\n    }\n    this.parsedLines = lines;\n    this.netMovement = lines.reduce((sum, line) => sum + line.amount, 0);\n  }\n\n  get canSave(): boolean { return !!this.accountID && this.parsedLines.length > 0 && !this.parseError; } // Returns a primitive — safe to leave as a getter\n\n  save() {\n    const dto = {\n      accountID: this.accountID,\n      statementFrom: this.statementFrom,\n      statementTo: this.statementTo,\n      closingBalance: this.closingBalance,\n      lines: this.parsedLines\n    };\n    this.http.post<any>(`${this.httpService.apiUrl}bankstatementimports/dto?action=create`, dto)\n      .subscribe(res => {\n        this.messageService.toast(res?.message ?? (res?.success ? 'Statement imported' : 'Import failed'));\n        if (res?.success) this.dialogRef.close(true);\n      });\n  }\n}\n","// Bank reconciliation match screen (C4) — statement lines vs unreconciled book entries; auto/manual match, unmatch, complete\nimport { Component, OnInit, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';\nimport { HttpService } from '../../../services/http.service';\nimport { MessageService } from '../../../services/message.service';\n\n@Component({\n  selector: 'spa-reconcile-dialog',\n  template: `\n    <h2 mat-dialog-title>Reconcile: {{ rec?.name }}</h2>\n    <mat-dialog-content>\n      <div *ngIf=\"rec\" style=\"display: flex; gap: 32px; flex-wrap: wrap; margin-bottom: 12px;\">\n        <div><small>Book Balance</small><br><b>{{ rec.bookBalance | number:'1.2-2' }}</b></div>\n        <div><small>Statement Balance</small><br><b>{{ rec.statementBalance | number:'1.2-2' }}</b></div>\n        <div><small>Difference</small><br><b [style.color]=\"difference ? 'red' : 'green'\">{{ difference | number:'1.2-2' }}</b></div>\n        <div><small>Matched</small><br><b>{{ rec.matchedCount }} / {{ rec.lineCount }}</b></div>\n      </div>\n\n      <div style=\"display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap;\" *ngIf=\"rec\">\n        <div style=\"flex: 1; min-width: 380px;\">\n          <h4>Statement Lines</h4>\n          <table style=\"width: 100%; border-collapse: collapse;\">\n            <tr style=\"text-align: left; border-bottom: 1px solid #ccc;\">\n              <th style=\"padding: 4px;\"></th><th style=\"padding: 4px;\">Date</th><th style=\"padding: 4px;\">Description</th>\n              <th style=\"padding: 4px; text-align: right;\">Amount</th><th style=\"padding: 4px;\">Status</th>\n            </tr>\n            <tr *ngFor=\"let line of rec.lines\" style=\"border-bottom: 1px solid #eee;\"\n                [style.background]=\"selectedLine === line ? '#E3F2FD' : line.isMatched ? '#F1F8E9' : ''\">\n              <td style=\"padding: 4px;\">\n                <mat-checkbox *ngIf=\"!line.isMatched\" [checked]=\"selectedLine === line\" (change)=\"selectedLine = $event.checked ? line : null\"></mat-checkbox>\n              </td>\n              <td style=\"padding: 4px;\">{{ line.date }}</td>\n              <td style=\"padding: 4px;\">{{ line.description }}</td>\n              <td style=\"padding: 4px; text-align: right;\">{{ line.amount | number:'1.2-2' }}</td>\n              <td style=\"padding: 4px;\">\n                <span *ngIf=\"line.isMatched\" title=\"{{ line.matchedDescription }}\">✔</span>\n                <button mat-button *ngIf=\"line.isMatched\" (click)=\"unmatch(line)\">Unmatch</button>\n              </td>\n            </tr>\n          </table>\n        </div>\n\n        <div style=\"flex: 1; min-width: 380px;\">\n          <h4>Unreconciled Book Entries</h4>\n          <table style=\"width: 100%; border-collapse: collapse;\">\n            <tr style=\"text-align: left; border-bottom: 1px solid #ccc;\">\n              <th style=\"padding: 4px;\"></th><th style=\"padding: 4px;\">Date</th><th style=\"padding: 4px;\">Description</th>\n              <th style=\"padding: 4px; text-align: right;\">Amount</th>\n            </tr>\n            <tr *ngFor=\"let entry of rec.unreconciledEntries\" style=\"border-bottom: 1px solid #eee;\"\n                [style.background]=\"selectedEntry === entry ? '#E3F2FD' : ''\">\n              <td style=\"padding: 4px;\">\n                <mat-checkbox [checked]=\"selectedEntry === entry\" (change)=\"selectedEntry = $event.checked ? entry : null\"></mat-checkbox>\n              </td>\n              <td style=\"padding: 4px;\">{{ entry.date }}</td>\n              <td style=\"padding: 4px;\">{{ entry.description }}</td>\n              <td style=\"padding: 4px; text-align: right;\">{{ entry.amount | number:'1.2-2' }}</td>\n            </tr>\n          </table>\n        </div>\n      </div>\n    </mat-dialog-content>\n    <mat-dialog-actions align=\"end\">\n      <button mat-button (click)=\"dialogRef.close(changed)\">Close</button>\n      <button mat-stroked-button (click)=\"autoMatch()\">Auto Match</button>\n      <button mat-stroked-button (click)=\"match()\" [disabled]=\"!selectedLine || !selectedEntry\">Match Selected</button>\n      <button mat-flat-button color=\"primary\" (click)=\"complete()\" [disabled]=\"!rec || rec.matchedCount != rec.lineCount\">Complete Reconciliation</button>\n    </mat-dialog-actions>\n  `,\n  standalone: false\n})\nexport class ReconcileDialogComponent implements OnInit {\n  public dialogRef = inject(MatDialogRef<ReconcileDialogComponent>);\n  public data: any = inject(MAT_DIALOG_DATA);\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n  private messageService = inject(MessageService);\n\n  rec: any = null;\n  selectedLine: any = null;\n  selectedEntry: any = null;\n  changed = false;\n\n  get difference(): number { return (this.rec?.bookBalance ?? 0) - (this.rec?.statementBalance ?? 0); }\n\n  ngOnInit(): void { this.load(); }\n\n  load() {\n    this.selectedLine = null;\n    this.selectedEntry = null;\n    this.http.get<any>(`${this.httpService.apiUrl}bankstatementimports/reconciliation/${this.data.bankStatementImportID}`)\n      .subscribe(res => this.rec = res?.data ?? null);\n  }\n\n  autoMatch() {\n    this.http.post<any>(`${this.httpService.apiUrl}bankstatementimports/dto?action=auto-match`, { bankStatementImportID: this.data.bankStatementImportID })\n      .subscribe(res => { this.messageService.toast(res?.message ?? ''); this.changed = true; this.load(); });\n  }\n\n  match() {\n    this.http.post<any>(`${this.httpService.apiUrl}bankstatementimports/match?action=match`,\n      { bankStatementLineID: this.selectedLine.bankStatementLineID, transactionEntryID: this.selectedEntry.transactionEntryID })\n      .subscribe(res => { this.messageService.toast(res?.message ?? ''); this.changed = true; this.load(); });\n  }\n\n  unmatch(line: any) {\n    this.http.post<any>(`${this.httpService.apiUrl}bankstatementimports/match?action=unmatch`, { bankStatementLineID: line.bankStatementLineID, transactionEntryID: 0 })\n      .subscribe(res => { this.messageService.toast(res?.message ?? ''); this.changed = true; this.load(); });\n  }\n\n  complete() {\n    this.http.post<any>(`${this.httpService.apiUrl}bankstatementimports/dto?action=complete`, { bankStatementImportID: this.data.bankStatementImportID })\n      .subscribe(res => {\n        this.messageService.toast(res?.message ?? '');\n        if (res?.success) this.dialogRef.close(true);\n      });\n  }\n}\n","// Bank Reconciliation page (C4) — statement imports list + import/reconcile dialogs\nimport { Component, OnInit, ViewChild, inject } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { DataServiceLib } from '../../../services/datalib.service'; // Added: single resolution point for the modern dialog surface\nimport { PageConfig } from '../../../classes/Classes';\nimport { PageComponent } from '../../../components/page/page.component';\nimport { StatementImportDialogComponent } from './statement-import-dialog.component';\nimport { ReconcileDialogComponent } from './reconcile-dialog.component';\n\n@Component({\n  selector: 'spa-bank-reconciliation',\n  template: `\n    <div style=\"display: flex; justify-content: flex-end;\">\n      <button mat-stroked-button (click)=\"newImport()\">\n        <mat-icon>upload_file</mat-icon> Import Statement\n      </button>\n    </div>\n    <spa-page [config]=\"pageConfig\"></spa-page>\n  `,\n  standalone: false\n})\nexport class BankReconciliationComponent implements OnInit {\n  public accountingService = inject(AccountingService);\n  private dialog = inject(MatDialog);\n  private dataService = inject(DataServiceLib); // Added: supplies dialogPanelClass so these dialogs honour appConfig.dialogStyle\n\n  @ViewChild(PageComponent) page?: PageComponent;\n\n  pageConfig: PageConfig = {\n    title: 'Bank Reconciliation',\n    tableConfig: this.accountingService.bankStatementImportsTableConfig\n  };\n\n  constructor() {\n    // Reconcile row button opens the match screen (configs live in the service, dialogs in the component)\n    this.accountingService.bankReconcileButton.onClick = (row: any) =>\n      this.dialog.open(ReconcileDialogComponent, { width: '1100px', maxWidth: '95vw', data: row, panelClass: this.dataService?.dialogPanelClass ?? [] }) // Changed: was missing panelClass, so this dialog never picked up the modern surface\n        .afterClosed().subscribe(changed => { if (changed) this.page?.tableReload.next(true); });\n  }\n\n  ngOnInit(): void {\n  }\n\n  newImport() {\n    this.dialog.open(StatementImportDialogComponent, { width: '860px', maxWidth: '95vw', panelClass: this.dataService?.dialogPanelClass ?? [] }) // Changed: was missing panelClass, so this dialog never picked up the modern surface\n      .afterClosed().subscribe(saved => { if (saved) this.page?.tableReload.next(true); });\n  }\n}\n","import { Component } from '@angular/core';\nimport { TenantTransferService } from '../../../services/tenant-transfer.service';\n\n// Moved (N11) from grip-spa into tin-spa, under Accounting (owner directive 2026-08-17). The design notes\n// from the Grip original hold: the two tables are one story, so an action on the arrangements table\n// refreshes the transfers list beneath it via the service's shared Subject.\n@Component({\n  selector: 'spa-tenant-transfers',\n  templateUrl: './tenant-transfers.component.html',\n  styleUrls: ['./tenant-transfers.component.css'],\n  standalone: false\n})\nexport class TenantTransfersComponent {\n\n  constructor(public tenantTransferService: TenantTransferService) { }\n\n  // Any successful action on an arrangement can change the transfers list — sending money adds a row, and\n  // revoking is worth re-reading the list after too. Refreshing unconditionally is correct and cheap.\n  arrangementActioned() {\n    this.tenantTransferService.transfersReload.next(true);\n  }\n\n}\n","<!-- Organisation Transfers — the handshake and the money that flows over it. Two sections in one page\n     deliberately: an arrangement is meaningless without the transfers it permits, and a transfer is\n     unreadable without the arrangement that authorised it. -->\n<h4>Organisation Transfers</h4>\n<hr>\n\n<div class=\"mt-3 tenant-transfers\" style=\"font-size: 14px;\">\n\n  <p class=\"tt-lead\">\n    Money can only move between two organisations that have <strong>agreed an arrangement</strong> first.\n    One side proposes it, the other accepts it, and only then can the proposing side send.\n  </p>\n\n  <!-- (actionSuccess) — Send Money is a button on THIS table, so without this wire the Transfers list below\n       still shows the previous rows after money has already moved. -->\n  <spa-table [config]=\"tenantTransferService.linksTableConfig\" (actionSuccess)=\"arrangementActioned()\"></spa-table>\n\n  <div class=\"tt-gap\"></div>\n\n  <spa-table [config]=\"tenantTransferService.transfersTableConfig\" [reload]=\"tenantTransferService.transfersReload\"></spa-table>\n\n</div>\n","// New revenue schedule dialog (C7) — defer a submitted invoice's net revenue over a date range\nimport { Component, OnInit, inject } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { MatDialogRef } from '@angular/material/dialog';\nimport { HttpService } from '../../../services/http.service';\nimport { MessageService } from '../../../services/message.service';\n\n@Component({\n  selector: 'spa-revenue-schedule-dialog',\n  template: `\n    <h2 mat-dialog-title>Defer Invoice Revenue</h2>\n    <mat-dialog-content>\n      <div style=\"display: flex; gap: 16px; flex-wrap: wrap;\">\n        <mat-form-field style=\"min-width: 280px;\">\n          <mat-label>Invoice</mat-label>\n          <mat-select [(ngModel)]=\"invoiceID\">\n            <mat-option *ngFor=\"let option of invoices\" [value]=\"option.value\">{{ option.name }}</mat-option>\n          </mat-select>\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>Service Period Start</mat-label>\n          <input matInput type=\"date\" [(ngModel)]=\"startDate\">\n        </mat-form-field>\n        <mat-form-field>\n          <mat-label>Service Period End</mat-label>\n          <input matInput type=\"date\" [(ngModel)]=\"endDate\">\n        </mat-form-field>\n      </div>\n      <p><em>The invoice's net revenue (excl. VAT) moves to Deferred Revenue and is recognized monthly, pro-rata by days, as each period ends.</em></p>\n    </mat-dialog-content>\n    <mat-dialog-actions align=\"end\">\n      <button mat-button (click)=\"dialogRef.close(false)\">Cancel</button>\n      <button mat-flat-button color=\"primary\" (click)=\"save()\" [disabled]=\"!invoiceID || !startDate || !endDate || endDate <= startDate\">Defer Revenue</button>\n    </mat-dialog-actions>\n  `,\n  standalone: false\n})\nexport class RevenueScheduleDialogComponent implements OnInit {\n  public dialogRef = inject(MatDialogRef<RevenueScheduleDialogComponent>);\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n  private messageService = inject(MessageService);\n\n  invoiceID: number | null = null;\n  startDate = '';\n  endDate = '';\n  invoices: any[] = [];\n\n  ngOnInit(): void {\n    this.http.get<any>(`${this.httpService.apiUrl}revenueschedules/eligible-invoices/x`)\n      .subscribe(res => this.invoices = res?.data ?? []);\n  }\n\n  save() {\n    const dto = { invoiceID: this.invoiceID, startDate: this.startDate, endDate: this.endDate };\n    this.http.post<any>(`${this.httpService.apiUrl}revenueschedules/dto?action=create`, dto)\n      .subscribe(res => {\n        this.messageService.toast(res?.message ?? (res?.success ? 'Schedule created' : 'Failed'));\n        if (res?.success) this.dialogRef.close(true);\n      });\n  }\n}\n","// Revenue Schedules page (C7) — deferred revenue schedules with recognize-due sweep and cancel\nimport { Component, OnInit, ViewChild, inject } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { DataServiceLib } from '../../../services/datalib.service'; // Added: single resolution point for the modern dialog surface\nimport { PageConfig } from '../../../classes/Classes';\nimport { PageComponent } from '../../../components/page/page.component';\nimport { RevenueScheduleDialogComponent } from './revenue-schedule-dialog.component';\n\n@Component({\n  selector: 'spa-revenue-schedules',\n  template: `\n    <div style=\"display: flex; justify-content: flex-end;\">\n      <button mat-stroked-button (click)=\"newSchedule()\">\n        <mat-icon>schedule_send</mat-icon> Defer Invoice Revenue\n      </button>\n    </div>\n    <spa-page [config]=\"pageConfig\"></spa-page>\n  `,\n  standalone: false\n})\nexport class RevenueSchedulesComponent implements OnInit {\n  public accountingService = inject(AccountingService);\n  private dataService = inject(DataServiceLib); // Added: supplies dialogPanelClass so this dialog honours appConfig.dialogStyle\n  private dialog = inject(MatDialog);\n\n  @ViewChild(PageComponent) page?: PageComponent;\n\n  pageConfig: PageConfig = {\n    title: 'Revenue Schedules',\n    tableConfig: this.accountingService.revenueSchedulesTableConfig\n  };\n\n  ngOnInit(): void {\n  }\n\n  newSchedule() {\n    this.dialog.open(RevenueScheduleDialogComponent, { width: '760px', maxWidth: '95vw', panelClass: this.dataService?.dialogPanelClass ?? [] }) // Changed: was missing panelClass, so this dialog never picked up the modern surface\n      .afterClosed().subscribe(saved => { if (saved) this.page?.tableReload.next(true); });\n  }\n}\n","// Quotations page (C10) — two-step create pattern with send/accept/reject/convert lifecycle + PDF download (C8)\nimport { HttpClient } from '@angular/common/http';\nimport { Component, OnInit, inject } from '@angular/core';\nimport { AccountingService } from '../../../services/accounting.service';\nimport { PageConfig } from '../../../classes/Classes';\nimport { HttpService } from '../../../services/http.service';\n\n@Component({\n  selector: 'spa-quotes',\n  template: '<spa-page [config]=\"pageConfig\" (actionClick)=\"actionClicked($event)\"></spa-page>',\n  standalone: false\n})\nexport class QuotesComponent implements OnInit {\n  public accountingService = inject(AccountingService);\n  private httpService = inject(HttpService);\n  private http = inject(HttpClient);\n\n  pageConfig: PageConfig = {\n    title: 'Quotations',\n    tableConfig: this.accountingService.quotesTableConfig\n  };\n\n  ngOnInit(): void {\n  }\n\n  // PDF button emits actionClick; download the blob (mirrors invoice PDF flow)\n  actionClicked(event: { name: string, data: any }) {\n    if (event.name === 'pdf') this.download(event.data);\n  }\n\n  download(quote: any) {\n    this.http.post(`${this.httpService.apiUrl}quotes/pdf?action=x`, quote, { responseType: 'blob' })\n      .subscribe((response: Blob) => {\n        const blob = new Blob([response], { type: 'application/pdf' });\n        const url = window.URL.createObjectURL(blob);\n        const link = document.createElement('a');\n        link.href = url;\n        link.download = `Quote_${quote.quoteID}.pdf`;\n        link.click();\n        window.URL.revokeObjectURL(url);\n      });\n  }\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { AccountsComponent as AccountingAccountsComponent } from '../../pages/accounting/accounts/accounts.component';\nimport { AggregatesComponent as AccountingAggregatesComponent } from '../../pages/accounting/aggregates/aggregates.component';\nimport { AgingComponent as AccountingAgingComponent } from '../../pages/accounting/aging/aging.component';\nimport { SupplierAgingComponent as AccountingSupplierAgingComponent } from '../../pages/accounting/supplier-aging/supplier-aging.component';\nimport { TransactionTypesComponent } from '../../pages/accounting/transaction-types/transaction-types.component';\nimport { TransactionsComponent as AccountingTransactionsComponent } from '../../pages/accounting/transactions/transactions.component';\nimport { InvoicesComponent as AccountingInvoicesComponent } from '../../pages/accounting/invoices/invoices.component';\nimport { StatementComponent as AccountingStatementComponent } from '../../pages/accounting/outstanding-invoices/outstanding-invoices.component';\nimport { ReportsComponent as AccountingReportsComponent } from '../../pages/accounting/reports/reports.component';\nimport { TaxRatesComponent } from '../../pages/accounting/tax-rates/tax-rates.component';\nimport { StandingOrdersComponent } from '../../pages/accounting/standing-orders/standing-orders.component';\nimport { CurrenciesComponent } from '../../pages/accounting/currencies/currencies.component'; // Changed: Removed Fixed Assets imports — moved to Assets module\nimport { BudgetsComponent as AccountingBudgetsComponent } from '../../pages/accounting/budgets/budgets.component';\nimport { BudgetVsActualComponent as AccountingBudgetVsActualComponent } from '../../pages/accounting/budget-vs-actual/budget-vs-actual.component';\nimport { AccountingDashboardComponent } from '../../pages/accounting/accounting-dashboard/accounting-dashboard.component';\nimport { InvoiceDashboardComponent } from '../../pages/accounting/invoice-dashboard/invoice-dashboard.component';\nimport { CreditNotesComponent } from '../../pages/accounting/credit-notes/credit-notes.component'; // Changed: Credit notes page (B6)\nimport { VatReturnComponent } from '../../pages/accounting/vat-return/vat-return.component'; // Changed: VAT return page (B2)\nimport { FiscalPeriodsComponent } from '../../pages/accounting/fiscal-periods/fiscal-periods.component'; // Changed: Fiscal periods page (C2)\nimport { ReceiptsComponent } from '../../pages/accounting/receipts/receipts.component'; // Changed: Customer receipts page (C3)\nimport { BankReconciliationComponent } from '../../pages/accounting/bank-reconciliation/bank-reconciliation.component'; // Changed: Bank reconciliation page (C4)\nimport { TenantTransfersComponent } from '../../pages/accounting/tenant-transfers/tenant-transfers.component'; // Added (N11): Organisation Transfers — cross-organisation money, routed under Accounting per owner directive\nimport { RevenueSchedulesComponent } from '../../pages/accounting/revenue-schedules/revenue-schedules.component'; // Changed: Deferred revenue page (C7)\nimport { QuotesComponent } from '../../pages/accounting/quotes/quotes.component'; // Changed: Quotations page (C10)\n\n// Changed: Exported routes array for use by SpaHomeRoutingModule\n//\n// Added (F3): leaf-level data.moduleKey. INERT metadata — nothing in this library reads it and no guard is\n// attached here; a consumer opts in from its own home route. The path says \"accounting\" but three separate\n// ModuleCatalog modules have pages under it, so the leaves that do NOT belong to Accounting say so explicitly\n// (deepest data wins in the resolver, so a leaf overrides the area). Keys are transcribed from the CapItem\n// tree in datalib.service.ts — the same source the nav menu already gates on — not invented:\n//   invoicing  -> capInvoicing.capSubItems (datalib.service.ts:372) — dashboard, quotes, invoices,\n//                 credit notes, receipts, revenue schedules, aging, statements\n//   purchasing -> capSupplierAging (:520) is a child of capPurchasingModule (:456) despite its accounting path\n// Everything left bare here is a capAccounting sub-item (:267) and correctly inherits the area's \"accounting\".\nexport const ACCOUNTING_ROUTES: Routes = [\n  { path: \"accounts\", component: AccountingAccountsComponent },\n  { path: \"aggregates\", component: AccountingAggregatesComponent },\n  { path: \"transaction-types\", component: TransactionTypesComponent },\n  { path: \"transactions\", component: AccountingTransactionsComponent },\n  { path: \"invoices\", component: AccountingInvoicesComponent, data: { moduleKey: 'invoicing' } }, // Added (F3): Invoicing, not Accounting\n  { path: \"aging\", component: AccountingAgingComponent, data: { moduleKey: 'invoicing', capName: 'cap58' } }, // Added (F3): capAging is a capInvoicing sub-item // Changed: added INERT capName — nothing in this library reads it; cap58 is capAging, whose menu link is exactly \"home/accounting/aging\" (datalib.service.ts:489,491). A consumer that attaches capabilityGuard() in its OWN route table refuses the deep link; an app that never adds that line is unaffected\n  { path: \"supplier-aging\", component: AccountingSupplierAgingComponent, data: { moduleKey: 'purchasing', capName: 'cap63' } }, // Added (F3): AP Aging belongs to Purchasing // Changed: added INERT capName — cap63 is capSupplierAging, menu link exactly \"home/accounting/supplier-aging\" (datalib.service.ts:597,599)\n  { path: \"statements\", component: AccountingStatementComponent, data: { moduleKey: 'invoicing' } }, // Added (F3): customer statement is an Invoicing page\n  { path: \"reports\", component: AccountingReportsComponent },\n  { path: \"tax-rates\", component: TaxRatesComponent },\n  { path: \"standing-orders\", component: StandingOrdersComponent },\n  { path: \"currencies\", component: CurrenciesComponent }, // Changed: Removed Fixed Assets routes — moved to Assets module\n  { path: \"budgets\", component: AccountingBudgetsComponent },\n  { path: \"budget-vs-actual\", component: AccountingBudgetVsActualComponent },\n  { path: \"dashboard\", component: AccountingDashboardComponent },\n  { path: \"invoice-dashboard\", component: InvoiceDashboardComponent, data: { moduleKey: 'invoicing' } }, // Added (F3): Invoicing dashboard\n  { path: \"credit-notes\", component: CreditNotesComponent, data: { moduleKey: 'invoicing' } }, // Changed: Credit notes route (B6) // Added (F3)\n  { path: \"vat-return\", component: VatReturnComponent }, // Changed: VAT return route (B2)\n  { path: \"fiscal-periods\", component: FiscalPeriodsComponent }, // Changed: Fiscal periods route (C2)\n  { path: \"receipts\", component: ReceiptsComponent, data: { moduleKey: 'invoicing' } }, // Changed: Customer receipts route (C3) // Added (F3)\n  { path: \"bank-reconciliation\", component: BankReconciliationComponent }, // Changed: Bank reconciliation route (C4)\n  { path: \"tenant-transfers\", component: TenantTransfersComponent }, // Added (N11): Organisation Transfers\n  { path: \"revenue-schedules\", component: RevenueSchedulesComponent, data: { moduleKey: 'invoicing' } }, // Changed: Deferred revenue route (C7) // Added (F3)\n  { path: \"quotes\", component: QuotesComponent, data: { moduleKey: 'invoicing' } } // Changed: Quotations route (C10) // Added (F3)\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(ACCOUNTING_ROUTES)],\n  exports: [RouterModule]\n})\nexport class AccountingRoutingModule { }\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// Component now uses centralized inventory service for configurations\n@Component({\n  selector: 'spa-products',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class ProductsComponent implements OnInit {\n\n  private inventoryService = inject(InventoryService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Products',\n    tableConfig: this.inventoryService.productsTableConfig\n  };\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// Component now uses centralized inventory service for configurations\n@Component({\n  selector: 'spa-inventory-items',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class InventoryItemsComponent implements OnInit {\n\n  private inventoryService = inject(InventoryService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Inventory Items',\n    tableConfig: this.inventoryService.inventoryItemsTableConfig\n  };\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// Component now uses centralized inventory service for configurations\n@Component({\n  selector: 'spa-requisitions',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class RequisitionsComponent implements OnInit {\n\n  private inventoryService = inject(InventoryService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Requisitions',\n    tableConfig: this.inventoryService.requisitionsTableConfig\n  };\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// Component now uses centralized inventory service for configurations\n@Component({\n  selector: 'spa-inventory-adjustments',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class InventoryAdjustmentsComponent implements OnInit {\n\n  private inventoryService = inject(InventoryService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Inventory Adjustments',\n    tableConfig: this.inventoryService.inventoryAdjustmentsTableConfig\n  };\n}\n","import { Component, OnInit, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n@Component({\n  selector: 'spa-inventory-returns',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class InventoryReturnsComponent implements OnInit {\n  // Changed: Inject InventoryService and use shared config instead of inline config\n  private inventoryService = inject(InventoryService);\n\n  tableConfig = this.inventoryService.inventoryReturnsTableConfig;\n\n  pageConfig: PageConfig = {\n    title: 'Inventory Returns',\n    tableConfig: this.tableConfig\n  };\n\n  ngOnInit(): void { }\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// Component now uses centralized inventory service for configurations\n@Component({\n  selector: 'spa-inventory-transactions',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class InventoryTransactionsComponent implements OnInit {\n\n  private inventoryService = inject(InventoryService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Inventory Transactions',\n    tableConfig: this.inventoryService.inventoryTransactionsTableConfig\n  };\n}\n","import { Component } from '@angular/core';\nimport { TileConfig, ChartConfig } from '../../../classes/Classes';\n\n// Inventory module dashboard with stock KPI tiles and charts\n@Component({\n  selector: 'spa-inventory-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>inventory_2</mat-icon> Inventory Dashboard</h4>\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <!-- Changed: Spacer div ensures margin between summary and chart tiles -->\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n  `],\n  standalone: false\n})\nexport class InventoryDashboardComponent {\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'totalProducts', alias: 'Total Products', color: '#2196f3', icon: 'category', style: 'icon', info: 'Total active products' },\n      { name: 'lowStockItems', alias: 'Low Stock Items', color: '#f44336', icon: 'warning', style: 'icon', info: 'Products below reorder level' },\n      { name: 'totalStockValue', alias: 'Stock Value', color: '#4caf50', icon: 'attach_money', style: 'icon', info: 'Total inventory value' }, // Changed: Removed prefix\n      { name: 'itemsInStock', alias: 'Items In Stock', color: '#ff9800', icon: 'inventory', style: 'icon', info: 'Total inventory item count' },\n      { name: 'adjustmentsThisMonth', alias: 'Adjustments (MTD)', color: '#9c27b0', icon: 'tune', style: 'icon', info: 'Inventory adjustments this month' },\n    ],\n    loadAction: { url: 'products/dashboard-summary/x' }, // Changed: Use module-specific CustomCriteria endpoint\n    loadInit: true\n  };\n\n  // Changed: Chart-style tiles now use loadAction with dataField for dynamic data\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'stockHealth', alias: 'Stock Health', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'stockHealth' }, footer: 'Items above reorder level', footerIcon: 'health_and_safety' }, // Changed: dataField replaces gaugeValue\n      { name: 'movementSpark', alias: 'Stock Movement', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 130, dataField: 'movementSpark' }, footer: 'Last 12 months', footerIcon: 'trending_up' }, // Changed: dataField replaces inline data\n      { name: 'categorySplit', alias: 'By Category', color: '#ff9800', chart: { type: 'pie', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0'], height: 130, dataField: 'categorySplit' }, footer: 'Value distribution', footerIcon: 'donut_large' }, // Changed: dataField replaces inline data\n    ],\n    loadAction: { url: 'products/dashboard-chart-tiles/x' }, // Changed: Load chart tile data from API\n    loadInit: true\n  };\n\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'stockByCategory', title: 'Stock Levels by Category', type: 'bar', height: '300px', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0', '#795548', '#607d8b'] },\n      { name: 'lowStockProducts', title: 'Low Stock Products', type: 'bar', height: '300px', colors: ['#f44336'] },\n      { name: 'valueByCategory', title: 'Value by Category', type: 'pie', height: '300px', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0', '#795548', '#607d8b'] },\n      { name: 'movementTrend', title: 'Stock Movement Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336', '#2196f3'], showLegend: true }, // Changed: showLegend for line chart\n    ],\n    loadAction: { url: 'products/dashboard-charts/x' }, // Changed: Use module-specific CustomCriteria endpoint\n    loadInit: true,\n    columns: 2\n  };\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// Component to display inventory stock grouped by product\n@Component({\n  selector: 'spa-inventory-stock',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class InventoryStockComponent implements OnInit {\n\n  private inventoryService = inject(InventoryService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Inventory Stock',\n    tableConfig: this.inventoryService.inventoryStockTableConfig\n  };\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// Component for managing bundle/combo products\n@Component({\n  selector: 'spa-bundle-products',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class BundleProductsComponent implements OnInit {\n\n  private inventoryService = inject(InventoryService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Bundle Products',\n    tableConfig: this.inventoryService.bundleProductsTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { InventoryService } from '../../../services/inventory.service';\n\n// ServiceItems component for managing service items\n@Component({\n  selector: 'spa-service-items',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class ServiceItemsComponent {\n  private inventoryService = inject(InventoryService);\n\n  pageConfig: PageConfig = {\n    title: 'Services',\n    tableConfig: this.inventoryService.serviceItemsTableConfig\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { ProductsComponent } from '../../pages/inventory/products/products.component';\nimport { InventoryItemsComponent } from '../../pages/inventory/inventory-items/inventory-items.component';\nimport { RequisitionsComponent } from '../../pages/inventory/requisitions/requisitions.component';\nimport { InventoryAdjustmentsComponent } from '../../pages/inventory/inventory-adjustments/inventory-adjustments.component';\nimport { InventoryReturnsComponent } from '../../pages/inventory/inventory-returns/inventory-returns.component';\nimport { InventoryTransactionsComponent } from '../../pages/inventory/inventory-transactions/inventory-transactions.component';\nimport { InventoryDashboardComponent } from '../../pages/inventory/inventory-dashboard/inventory-dashboard.component';\nimport { InventoryStockComponent } from '../../pages/inventory/inventory-stock/inventory-stock.component';\nimport { BundleProductsComponent } from '../../pages/inventory/bundle-products/bundle-products.component';\nimport { ServiceItemsComponent } from '../../pages/inventory/service-items/service-items.component';\n\n// Changed: Exported routes array for use by SpaHomeRoutingModule\nexport const INVENTORY_ROUTES: Routes = [\n  { path: \"products\", component: ProductsComponent },\n  { path: \"service-items\", component: ServiceItemsComponent },\n  { path: \"items\", component: InventoryItemsComponent },\n  { path: \"requisitions\", component: RequisitionsComponent },\n  { path: \"adjustments\", component: InventoryAdjustmentsComponent },\n  { path: \"returns\", component: InventoryReturnsComponent },\n  { path: \"transactions\", component: InventoryTransactionsComponent },\n  { path: \"dashboard\", component: InventoryDashboardComponent },\n  { path: \"stock\", component: InventoryStockComponent },\n  { path: \"bundle-products\", component: BundleProductsComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(INVENTORY_ROUTES)],\n  exports: [RouterModule]\n})\nexport class InventoryRoutingModule { }\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { SalesService } from '../../../services/sales.service'; // Changed: Use SalesService instead of InventoryService\n\n@Component({\n  selector: 'spa-sales-orders',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class SalesOrdersComponent implements OnInit {\n  private salesService = inject(SalesService); // Changed: Use SalesService\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Sales Orders',\n    tableConfig: this.salesService.salesOrdersTableConfig // Changed: Use SalesService\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { SalesService } from '../../../services/sales.service'; // Changed: Use SalesService instead of InventoryService\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n  selector: 'app-sales',\n  template: '<spa-page [config]=\"config\"></spa-page>',\n  standalone: false\n})\nexport class SalesComponent {\n  private salesService = inject(SalesService); // Changed: Use SalesService\n\n  config: PageConfig = {\n    title: 'Sales',\n    tableConfig: this.salesService.salesTableConfig // Changed: Use SalesService\n  };\n}\n","import { Component } from '@angular/core';\nimport { TileConfig, ChartConfig } from '../../../classes/Classes';\n\n// Sales module dashboard with revenue tracking and pipeline visibility\n@Component({\n  selector: 'spa-sales-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>point_of_sale</mat-icon> Sales Dashboard</h4>\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <!-- Changed: Chart tiles for sales visual indicators -->\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n  `],\n  standalone: false\n})\nexport class SalesDashboardComponent {\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'salesRevenue', alias: 'Sales Revenue (MTD)', color: '#4caf50', icon: 'attach_money', style: 'icon', info: 'Total sales revenue this month' }, // Changed: Removed prefix\n      { name: 'salesCount', alias: 'Sales Count', color: '#2196f3', icon: 'shopping_cart', style: 'icon', info: 'Number of sales this month' },\n      { name: 'avgSaleValue', alias: 'Avg Sale Value', color: '#ff9800', icon: 'analytics', style: 'icon', info: 'Average sale value this month' }, // Changed: Removed prefix\n      { name: 'creditSalesOutstanding', alias: 'Credit Outstanding', color: '#f44336', icon: 'credit_card', style: 'icon', info: 'Outstanding credit sale amounts' }, // Changed: Removed prefix\n      { name: 'topProduct', alias: 'Top Product', color: '#9c27b0', icon: 'star', style: 'icon', info: 'Best selling product this month' },\n    ],\n    loadAction: { url: 'sales/dashboard-summary/x' }, // Changed: Use module-specific CustomCriteria endpoint\n    loadInit: true\n  };\n\n  // Changed: Chart-style tiles now use loadAction with dataField for dynamic data\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'conversionRate', alias: 'Conversion Rate', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'conversionRate' }, footer: 'Quote to sale conversion', footerIcon: 'swap_horiz' }, // Changed: dataField replaces gaugeValue\n      { name: 'salesTrendSpark', alias: 'Sales Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'salesTrendSpark' }, footer: 'Last 12 months', footerIcon: 'show_chart' }, // Changed: dataField replaces inline data\n      { name: 'paymentSplit', alias: 'Payment Methods', color: '#9c27b0', chart: { type: 'doughnut', colors: ['#4caf50', '#2196f3', '#ff9800', '#9c27b0'], height: 130, dataField: 'paymentSplit' }, footer: 'Current distribution', footerIcon: 'payment' }, // Changed: dataField replaces inline data\n    ],\n    loadAction: { url: 'sales/dashboard-chart-tiles/x' }, // Changed: Load chart tile data from API\n    loadInit: true\n  };\n\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'salesTrend', title: 'Sales Revenue Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#2196f3'], showLegend: true }, // Changed: showLegend for line chart\n      { name: 'paymentMethods', title: 'Payment Method Breakdown', type: 'doughnut', height: '300px', colors: ['#4caf50', '#2196f3', '#ff9800', '#9c27b0', '#f44336'] },\n      { name: 'topProducts', title: 'Top Selling Products', type: 'bar', height: '300px', colors: ['#4caf50', '#66bb6a', '#81c784', '#a5d6a7', '#c8e6c9'] },\n      { name: 'orderPipeline', title: 'Sales Order Pipeline', type: 'bar', height: '300px', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336', '#ff9800'] },\n    ],\n    loadAction: { url: 'sales/dashboard-charts/x' }, // Changed: Use module-specific CustomCriteria endpoint\n    loadInit: true,\n    columns: 2\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { SalesOrdersComponent } from '../../pages/sales/sales-orders/sales-orders.component';\nimport { SalesComponent } from '../../pages/sales/sales/sales.component';\nimport { SalesDashboardComponent } from '../../pages/sales/sales-dashboard/sales-dashboard.component';\n\nexport const SALES_ROUTES: Routes = [\n  { path: \"orders\", component: SalesOrdersComponent, data: { capName: \"cap39\" } }, // Added (Phase 4): INERT metadata, exactly like data.moduleKey — nothing in this library reads it. It declares which capability the PAGE requires (sales.service.ts:59 gates the grid on capSalesOrders, datalib.service.ts:600), so a consumer that opts in by attaching capabilityGuard() in its OWN route table refuses the deep link; an app that never adds that line is unaffected\n  { path: \"sales\", component: SalesComponent },\n  { path: \"dashboard\", component: SalesDashboardComponent, data: { capName: \"cap61\" } } // Changed: added INERT capName — cap61 is capSalesDashboard, menu link exactly \"home/sales/dashboard\" (datalib.service.ts:522,524). NOTE: capSalesDashboard deliberately reuses the capSalesModule number (datalib.service.ts:516), so this gate is module-wide, not page-specific — faithful to the menu authority but weaker than a dedicated cap\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(SALES_ROUTES)],\n  exports: [RouterModule]\n})\nexport class SalesRoutingModule { }\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { PurchasingService } from '../../../services/purchasing.service'; // Changed: Use PurchasingService instead of InventoryService\n\n@Component({\n  selector: 'spa-supplier-purchase-orders',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class SupplierPurchaseOrdersComponent implements OnInit {\n\n  private purchasingService = inject(PurchasingService); // Changed: Inject PurchasingService\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Purchase Orders',\n    tableConfig: this.purchasingService.supplierPurchaseOrdersTableConfig // Changed: Use PurchasingService config\n  };\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { PurchasingService } from '../../../services/purchasing.service'; // Changed: Use PurchasingService instead of InventoryService\n\n// Changed: Component moved from inventory module to purchasing module\n@Component({\n  selector: 'spa-inventory-receipts',\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>',\n  standalone: false\n})\nexport class InventoryReceiptsComponent implements OnInit {\n\n  private purchasingService = inject(PurchasingService); // Changed: Inject PurchasingService\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Purchases', // Changed: \"Inventory Receipts\" → \"Purchases\"\n    tableConfig: this.purchasingService.purchasesTableConfig // Changed: inventoryReceiptsTableConfig → purchasesTableConfig\n  };\n}\n","import { Component } from '@angular/core';\nimport { TileConfig, ChartConfig } from '../../../classes/Classes';\n\n// Purchasing module dashboard with procurement tracking\n@Component({\n  selector: 'spa-purchasing-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>local_shipping</mat-icon> Purchasing Dashboard</h4>\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <!-- Changed: Chart tiles for purchasing visual indicators -->\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n  `],\n  standalone: false\n})\nexport class PurchasingDashboardComponent {\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'totalPurchases', alias: 'Purchases (MTD)', color: '#2196f3', icon: 'shopping_bag', style: 'icon', info: 'Total purchase amount this month' },\n      { name: 'openPOs', alias: 'Open POs', color: '#ff9800', icon: 'pending_actions', style: 'icon', info: 'Purchase orders awaiting fulfillment' },\n      { name: 'pendingPurchases', alias: 'Pending Purchases', color: '#9c27b0', icon: 'inventory_2', style: 'icon', info: 'Purchases awaiting processing' }, // Changed: pendingReceipts → pendingPurchases\n      { name: 'supplierPaymentsOutstanding', alias: 'AP Outstanding', color: '#f44336', icon: 'payments', style: 'icon', info: 'Outstanding supplier payment amounts' },\n      { name: 'purchasesThisMonth', alias: 'Purchases (MTD)', color: '#4caf50', icon: 'receipt', style: 'icon', info: 'Purchases processed this month' }, // Changed: receiptsThisMonth → purchasesThisMonth\n    ],\n    loadAction: { url: 'purchases/dashboard-summary/x' }, // Changed: inventoryreceipts → purchases\n    loadInit: true\n  };\n\n  // Changed: Chart-style tiles now use loadAction with dataField for dynamic data\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'fulfillmentRate', alias: 'Fulfillment Rate', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'fulfillmentRate' }, footer: 'PO fulfillment rate', footerIcon: 'verified' }, // Changed: dataField replaces gaugeValue\n      { name: 'spendTrendSpark', alias: 'Spend Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'spendTrendSpark' }, footer: 'Last 12 months', footerIcon: 'show_chart' }, // Changed: dataField replaces inline data\n      { name: 'poStatusSplit', alias: 'PO Status', color: '#ff9800', chart: { type: 'doughnut', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336'], height: 130, dataField: 'poStatusSplit' }, footer: 'Current distribution', footerIcon: 'assignment' }, // Changed: dataField replaces inline data\n    ],\n    loadAction: { url: 'purchases/dashboard-chart-tiles/x' }, // Changed: inventoryreceipts → purchases\n    loadInit: true\n  };\n\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'purchaseTrend', title: 'Purchase Spend Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#2196f3', '#f44336'], showLegend: true }, // Changed: showLegend for line chart\n      { name: 'poStatus', title: 'PO Status Distribution', type: 'doughnut', height: '300px', colors: ['#9e9e9e', '#2196f3', '#4caf50', '#f44336', '#ff9800'] },\n      { name: 'topSuppliers', title: 'Top Suppliers by Spend', type: 'bar', height: '300px', colors: ['#2196f3', '#42a5f5', '#64b5f6', '#90caf9', '#bbdefb'] },\n      { name: 'apAging', title: 'AP Aging Breakdown', type: 'bar', height: '300px', colors: ['#4caf50', '#ff9800', '#ff5722', '#f44336', '#b71c1c'] },\n    ],\n    loadAction: { url: 'purchases/dashboard-charts/x' }, // Changed: inventoryreceipts → purchases\n    loadInit: true,\n    columns: 2\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { SupplierPurchaseOrdersComponent } from '../../pages/purchasing/supplier-purchase-orders/supplier-purchase-orders.component';\nimport { InventoryReceiptsComponent } from '../../pages/purchasing/inventory-receipts/inventory-receipts.component';\nimport { PurchasingDashboardComponent } from '../../pages/purchasing/purchasing-dashboard/purchasing-dashboard.component';\n\nexport const PURCHASING_ROUTES: Routes = [\n  { path: \"orders\", component: SupplierPurchaseOrdersComponent },\n  { path: \"purchases\", component: InventoryReceiptsComponent },\n  { path: \"dashboard\", component: PurchasingDashboardComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(PURCHASING_ROUTES)],\n  exports: [RouterModule]\n})\nexport class PurchasingRoutingModule { }\n","import { Component, inject } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { PageConfig } from '../../classes/Classes';\nimport { AuthService } from '../../services/auth.service';\n\n\n@Component({\n    selector: 'spa-employees',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class EmployeesComponent {\n  private dataService = inject(DataServiceLib);\n  private authService = inject(AuthService);\n  \n  pageConfig: PageConfig = {\n    title: 'Employees',\n    tableConfig: this.dataService.employeesTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { PageConfig } from '../../classes/Classes';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\n\n\n@Component({\n    selector: 'spa-departments',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class DepartmentsComponent {\n  private dataService = inject(DataServiceLib);\n  private messageService = inject(MessageService);\n  private authService = inject(AuthService);\n  \n  pageConfig: PageConfig = {\n    title: 'Departments',\n    tableConfig: this.dataService.departmentTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { AuthService } from '../../services/auth.service';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { PageConfig } from '../../classes/Classes';\n\n\n@Component({\n    selector: 'spa-positions',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class PositionsComponent {\n  private dataService = inject(DataServiceLib);\n  private authService = inject(AuthService);\n  \n  pageConfig: PageConfig = {\n    title: 'Positions',\n    tableConfig: this.dataService.positionsTableConfig\n  };\n}\n","import { Component, OnInit } from '@angular/core';\n\n@Component({\n    selector: 'spa-grades',\n    templateUrl: './grades.component.html',\n    styleUrls: ['./grades.component.css'],\n    standalone: false\n})\nexport class GradesComponent implements OnInit {\n\n  constructor() { }\n\n  ngOnInit(): void {\n  }\n\n}\n","<h4>Grades</h4>\n<hr>\n","import { Component, OnInit } from '@angular/core';\nimport { TableConfig, ApiResponse } from '../../classes/Classes';\nimport { AuthService } from '../../services/auth.service';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: a failed rename during onboarding left the organisation with its default name and said nothing (WS-6 Phase 4)\n\n@Component({\n    selector: 'spa-onboarding', // Changed: renamed selector from spa-welcome\n    templateUrl: './onboarding.component.html', // Changed: updated template file reference\n    styleUrls: ['./onboarding.component.css'], // Changed: updated style file reference\n    standalone: false\n})\nexport class OnboardingComponent implements OnInit { // Changed: renamed class from WelcomeComponent\n\n  constructor(public dataService : DataServiceLib, public authService: AuthService, private apiErrorService: ApiErrorService) { } // Changed: injected ApiErrorService for the rename step\n\n  ngOnInit(): void {\n    this.loadMeta();\n\n    this.authService.loggedUserFullName.subscribe(x => this.username = x)\n  }\n\n  username;\n\n  step = \"terms\"\n  agree = false\n  own = true;\n  invitations = false;\n\n  myTenant\n\n  loadMeta(){\n    this.dataService.CallApi({ url:'tenants/welcome_meta/x'}).subscribe((api) => {\n      this.invitations = api.data.invitations;\n      this.own = api.data.own;\n      this.myTenant = api.data.tenant;\n    })\n  }\n\n  renameTenant() {\n\n    this.dataService.CallApi({ url: 'tenants/dto?action=rename', method: 'post' }, this.myTenant).subscribe((apiResponse: ApiResponse) => {\n\n      if (apiResponse.success) {\n        this.authService.updateTenantName(this.myTenant.name)\n      } else {\n        this.apiErrorService.presentAppFailure(apiResponse, 'action', 'tenants/dto?action=rename'); // Added: was silent, and next() advances the wizard regardless of the outcome — so the user typed their company name, moved on, and only discovered weeks later that the organisation was still called whatever it defaulted to\n      }\n    });\n  }\n\n  next(){\n\n    if (this.step == 'terms' && this.own){\n      this.step = \"name\"\n      return;\n    }\n    else if (this.step == \"terms\" && !this.own) {\n      this.step = \"hi\"\n      return;\n    }\n    else if (this.step == \"name\" && this.own){\n\n      this.renameTenant();\n      if (this.invitations == true){\n        this.step = \"invitations\"\n        return;\n      }\n\n\n    }\n\n\n    this.setWelcome();\n  }\n\n  setWelcome() {\n    this.dataService.CallApi({ url: 'tenants/set_welcome/x' }).subscribe((api) => {\n      this.home();\n    })\n  }\n\n  home(){\n    this.dataService.Navigate('home');\n  }\n\n\n  invTableConfig: TableConfig = {\n\n    greyOut: (value) => value.accepted == false,\n    elevation: 'low',\n    minColumns: ['tenantName'],\n    minButtons: ['accept', 'decline'],\n\n    columns: [\n      { name: 'tenantName', alias: 'Organisation', type: 'text' },\n      { name: 'owner', type: 'text', },\n    ],\n\n    buttons: [\n      { name: 'accept', icon: { 'name': 'done', }, color: 'green', action: { url: 'members/dto?action=accept', method: 'post', }, confirm: { message: 'Accept ?' }, disabled: (x) => x.accepted },\n      { name: 'decline', icon: { 'name': 'close', }, color: 'red', action: { url: 'members/dto?action=remove', method: 'post', }, confirm: { message: 'Decline ?' }, disabled: (x) => x.accepted },\n    ],\n\n    loadAction: { url: 'tenants/invitations/x' },\n\n  }\n\n}\n","<label class=\"title\">Welcome,  {{username}}</label>\n\n\n\n<!-- terms -->\n<div class=\"mt-3\" *ngIf=\"step=='terms'\">\n\n  <label class=\"subtitle text-muted mb-2\" >We care about our users and are dedicated to protecting your data and privacy -\n    thats why we want to be clear about what data we collect and how we use it to improve your experience.</label>\n\n  <br>\n  <spa-check display=\"I agree to the Terms and Privacy Policy\" [(value)]=\"agree\"></spa-check>\n</div>\n\n<!-- owner -->\n<div class=\"mt-3\" *ngIf=\"step=='name' && own\">\n\n  <label class=\"subtitle text-muted\" style=\" margin-bottom: 20px;\">The follow steps will guide you to customise your application.</label>\n\n  <div style=\"max-width: 400px;\">\n   <spa-text display=\"Organisation Name\" [(value)]=\"myTenant.name\" ></spa-text>\n  </div>\n\n  <label class=\"text-muted\" style=\" font-size: 12px;\">You can change the Organisation's name to your team or company name.</label><br>\n  <label class=\"text-muted\" style=\" font-size: 12px;margin-top: 10px;\">The name can be changed later.</label>\n\n</div>\n\n<!-- guest -->\n<div *ngIf=\"step=='hi' && !own\">\n  <label class=\"subtitle text-muted\">You are now signed in to {{myTenant.name}}.</label>\n</div>\n\n\n<!-- invitations -->\n<div class=\"mt-3\" *ngIf=\"step=='invitations' && own\">\n\n  <label class=\"subtitle text-muted\">You have been requested to join the following organisations. If you accept, you have the option to switch to that org now or stay in you org.</label><br>\n  <label class=\"text-muted\" style=\" font-size: 12px;margin-top: 10px;\">You will be able to switch later.</label>\n  <spa-invitations-table></spa-invitations-table>\n\n</div>\n\n\n<!-- Actions -->\n<div class=\"mt-3\">\n  <button  mat-stroked-button color=\"primary\" [disabled]=\"!agree\" (click)=\"next()\">Next <mat-icon>arrow_right_alt</mat-icon></button>\n</div>\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { EmployeesComponent } from '../../pages/employees/employees.component';\nimport { DepartmentsComponent } from '../../pages/departments/departments.component';\nimport { PositionsComponent } from '../../pages/positions/positions.component';\nimport { GradesComponent } from '../../pages/grades/grades.component';\nimport { OnboardingComponent } from '../../pages/onboarding/onboarding.component';\n\nexport const HR_ROUTES: Routes = [\n  { path: \"employees\", component: EmployeesComponent },\n  { path: \"departments\", component: DepartmentsComponent },\n  { path: \"positions\", component: PositionsComponent },\n  { path: \"grades\", component: GradesComponent },\n  { path: \"onboarding\", component: OnboardingComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(HR_ROUTES)],\n  exports: [RouterModule]\n})\nexport class HRRoutingModule { }\n","import { Component, inject } from '@angular/core';\nimport { PayrollService } from '../../../services/payroll.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n    selector: 'spa-salary-structures',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class SalaryStructuresComponent {\n  private payrollService = inject(PayrollService);\n\n  pageConfig: PageConfig = {\n    title: 'Salary Structures',\n    tableConfig: this.payrollService.salaryStructuresTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PayrollService } from '../../../services/payroll.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n    selector: 'spa-statutory-deductions',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class StatutoryDeductionsComponent {\n  private payrollService = inject(PayrollService);\n\n  pageConfig: PageConfig = {\n    title: 'Statutory Deductions',\n    tableConfig: this.payrollService.statutoryDeductionTypesTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PayrollService } from '../../../services/payroll.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n    selector: 'spa-payroll-runs',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class PayrollRunsComponent {\n  private payrollService = inject(PayrollService);\n\n  pageConfig: PageConfig = {\n    title: 'Payroll Runs',\n    tableConfig: this.payrollService.payrollRunsTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PayrollService } from '../../../services/payroll.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n    selector: 'spa-commission-configs',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class CommissionConfigsComponent {\n  private payrollService = inject(PayrollService);\n\n  pageConfig: PageConfig = {\n    title: 'Commission Configs',\n    tableConfig: this.payrollService.commissionConfigsTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PayrollService } from '../../../services/payroll.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n    selector: 'spa-commission-entries',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class CommissionEntriesComponent {\n  private payrollService = inject(PayrollService);\n\n  pageConfig: PageConfig = {\n    title: 'Commission Entries',\n    tableConfig: this.payrollService.commissionEntriesTableConfig\n  };\n}\n","import { Component, OnInit, inject } from '@angular/core';\nimport { ApiResponse } from '../../../classes/Classes';\nimport { DataServiceLib } from '../../../services/datalib.service';\nimport { ConfigService } from '../../../services/config.service';\nimport { MessageService } from '../../../services/message.service';\n\n// Added (Phase 6): the Driver Commission Statement, and the only place the response-level warnings from\n// preview and generate reach a human. Phases 2-5 surfaced the ROW-level ones — a 0.00 entry, a rule scoped\n// to nobody — but a rule skipped because it expired, and an invoice excluded because a credit note settled\n// it rather than cash, live on the RESPONSE, and nothing rendered them. `execAction` on the table component\n// toasts apiResponse.message and drops apiResponse.data, so a Preview button bound to a table config would\n// have shown the one-line summary and silently discarded every named reason. Hence a page.\n@Component({\n  selector: 'spa-commission-statement',\n  template: `\n    <div class=\"cs-container\">\n\n      <h4 class=\"cs-title\"><mat-icon>receipt_long</mat-icon> Driver Commission Statement</h4>\n\n      <!-- Period, and the two actions. Preview and Generate render only where trip commission is switched on,\n           which in practice means Shift — every other app gets the statement without the generator. -->\n      <div class=\"cs-bar\">\n        <div class=\"cs-period\">\n          <mat-form-field appearance=\"outline\" class=\"cs-year\">\n            <mat-label>Year</mat-label>\n            <input matInput type=\"number\" [(ngModel)]=\"periodYear\" (change)=\"clearResults()\">\n          </mat-form-field>\n          <mat-form-field appearance=\"outline\" class=\"cs-month\">\n            <mat-label>Month</mat-label>\n            <mat-select [(ngModel)]=\"periodMonth\" (selectionChange)=\"clearResults()\">\n              <mat-option *ngFor=\"let m of months\" [value]=\"m.value\">{{ m.name }}</mat-option>\n            </mat-select>\n          </mat-form-field>\n          <button mat-stroked-button color=\"primary\" (click)=\"loadStatement()\" [disabled]=\"busy\">Show Statement</button>\n        </div>\n\n        <div class=\"cs-actions\" *ngIf=\"tripCommissionEnabled\">\n          <button mat-stroked-button (click)=\"preview()\" [disabled]=\"busy\"><mat-icon>visibility</mat-icon> Preview (writes nothing)</button>\n          <button mat-flat-button color=\"primary\" (click)=\"generate()\" [disabled]=\"busy\"><mat-icon>playlist_add</mat-icon> Generate from Trips</button>\n        </div>\n      </div>\n\n      <div class=\"alert alert-secondary cs-note\" *ngIf=\"!tripCommissionEnabled\">\n        Commission is not generated from trips in this app, so this page reports what has been recorded rather than\n        proposing anything new.\n      </div>\n\n      <!-- ============ PREVIEW RESULT — the whole point of this page ============ -->\n      <div class=\"cs-panel\" *ngIf=\"previewResult\">\n        <div class=\"alert alert-info cs-headline\">\n          <strong>Preview only — nothing was written.</strong>\n          {{ previewResult.entries?.length || 0 }} {{ (previewResult.entries?.length === 1) ? 'entry' : 'entries' }}\n          totalling {{ previewTotal | number:'1.2-2' }} for {{ previewResult.periodName || periodLabel() }}.\n          Generating turns these into <strong>Draft</strong> entries, which still have to be approved before payroll can pay them.\n        </div>\n\n        <!-- Response-level warnings: the ones that were invisible until now -->\n        <div class=\"alert alert-warning\" *ngIf=\"previewResult.warnings?.length\">\n          <strong>{{ previewResult.warnings.length }} warning{{ previewResult.warnings.length === 1 ? '' : 's' }} about this period</strong>\n          <ul class=\"cs-list\"><li *ngFor=\"let w of previewResult.warnings\">{{ w }}</li></ul>\n        </div>\n\n        <!-- Skipped rules, each with the reason the evaluator refused it -->\n        <div class=\"alert alert-danger\" *ngIf=\"previewResult.skippedRules?.length\">\n          <strong>{{ previewResult.skippedRules.length }} rule{{ previewResult.skippedRules.length === 1 ? '' : 's' }} paid nobody</strong>\n          <ul class=\"cs-list\">\n            <li *ngFor=\"let s of previewResult.skippedRules\"><strong>{{ s.configName }}</strong> — {{ s.reason }}</li>\n          </ul>\n        </div>\n\n        <table class=\"cs-table\" *ngIf=\"previewResult.entries?.length\">\n          <thead>\n            <tr>\n              <th>Employee</th><th>Rule</th><th>Basis</th><th>Earned When</th>\n              <th class=\"cs-num\">Measured</th><th class=\"cs-num\">Rate</th><th class=\"cs-num\">Raw</th><th class=\"cs-num\">Would Pay</th><th>Notes</th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr *ngFor=\"let e of previewResult.entries\">\n              <td>{{ e.employeeName }}</td>\n              <td>{{ e.configName }}</td>\n              <td>{{ e.basisName }}</td>\n              <td>{{ e.earnEventName }}</td>\n              <td class=\"cs-num\">{{ e.metricValue | number:'1.0-2' }}</td>\n              <td class=\"cs-num\">{{ e.rate | number:'1.0-4' }}</td>\n              <td class=\"cs-num\">{{ e.rawAmount | number:'1.2-2' }}</td>\n              <td class=\"cs-num cs-strong\" [class.cs-zero]=\"e.commissionAmount === 0\">{{ e.commissionAmount | number:'1.2-2' }}</td>\n              <td class=\"cs-notes\">\n                <span class=\"cs-flag\" *ngIf=\"e.usedTiers\">tiered</span>\n                <span class=\"cs-flag\" *ngIf=\"e.minimumApplied\">floor applied</span>\n                <span class=\"cs-flag\" *ngIf=\"e.maximumApplied\">cap applied</span>\n                <span class=\"cs-warn\" *ngFor=\"let w of e.warnings\">{{ w }}</span>\n              </td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n\n      <!-- ============ GENERATE RESULT ============ -->\n      <div class=\"cs-panel\" *ngIf=\"generateResult\">\n        <div class=\"alert alert-success cs-headline\">\n          <strong>{{ generateResult.entriesCreated }} Draft entr{{ generateResult.entriesCreated === 1 ? 'y' : 'ies' }}</strong>\n          created from {{ generateResult.linesCreated }} source line{{ generateResult.linesCreated === 1 ? '' : 's' }},\n          totalling {{ generateResult.totalAmount | number:'1.2-2' }} for {{ generateResult.periodName || periodLabel() }}.\n          Draft entries do <strong>not</strong> reach a payslip until they are approved.\n        </div>\n\n        <!-- What a regeneration MOVED. These three are the ones nobody must discover from a payslip. -->\n        <div class=\"alert alert-warning\" *ngIf=\"generateResult.draftEntriesReplaced || generateResult.approvedEntriesNeutralised || generateResult.paidEntriesReversed\">\n          <ul class=\"cs-list\">\n            <li *ngIf=\"generateResult.draftEntriesReplaced\">{{ generateResult.draftEntriesReplaced }} previous draft entr{{ generateResult.draftEntriesReplaced === 1 ? 'y was' : 'ies were' }} replaced.</li>\n            <li *ngIf=\"generateResult.approvedEntriesNeutralised\"><strong>{{ generateResult.approvedEntriesNeutralised }} already-approved entr{{ generateResult.approvedEntriesNeutralised === 1 ? 'y was' : 'ies were' }} reversed and must be approved again.</strong></li>\n            <li *ngIf=\"generateResult.paidEntriesReversed\"><strong>{{ generateResult.paidEntriesReversed }} already-paid entr{{ generateResult.paidEntriesReversed === 1 ? 'y' : 'ies' }} raised a negative clawback awaiting approval.</strong> The original payment stands.</li>\n          </ul>\n        </div>\n\n        <div class=\"alert alert-warning\" *ngIf=\"generateResult.entriesWithWarnings?.length\">\n          <strong>{{ generateResult.entriesWithWarnings.length }} entr{{ generateResult.entriesWithWarnings.length === 1 ? 'y needs' : 'ies need' }} attention before approval</strong>\n          <ul class=\"cs-list\">\n            <li *ngFor=\"let e of generateResult.entriesWithWarnings\">\n              <strong>{{ e.employeeName }}</strong> — {{ e.configName }} — {{ e.commissionAmount | number:'1.2-2' }}\n              <span *ngFor=\"let w of e.warnings\" class=\"cs-warn\">{{ w }}</span>\n            </li>\n          </ul>\n        </div>\n\n        <div class=\"alert alert-warning\" *ngIf=\"generateResult.warnings?.length\">\n          <ul class=\"cs-list\"><li *ngFor=\"let w of generateResult.warnings\">{{ w }}</li></ul>\n        </div>\n\n        <div class=\"alert alert-danger\" *ngIf=\"generateResult.skippedRules?.length\">\n          <strong>{{ generateResult.skippedRules.length }} rule{{ generateResult.skippedRules.length === 1 ? '' : 's' }} paid nobody</strong>\n          <ul class=\"cs-list\">\n            <li *ngFor=\"let s of generateResult.skippedRules\"><strong>{{ s.configName }}</strong> — {{ s.reason }}</li>\n          </ul>\n        </div>\n      </div>\n\n      <!-- ============ THE STATEMENT ITSELF ============ -->\n      <div class=\"cs-panel\" *ngIf=\"statementLoaded\">\n        <h5 class=\"cs-section\">Recorded for {{ periodLabel() }}</h5>\n\n        <div class=\"cs-totals\">\n          <div class=\"cs-total\"><span class=\"cs-total-label\">Proposed (Draft)</span><span class=\"cs-total-value cs-draft\">{{ totals.draft | number:'1.2-2' }}</span><span class=\"cs-total-note\">not payable until approved</span></div>\n          <div class=\"cs-total\"><span class=\"cs-total-label\">Payable (Approved)</span><span class=\"cs-total-value cs-approved\">{{ totals.approved | number:'1.2-2' }}</span><span class=\"cs-total-note\">will be picked up by a payroll run</span></div>\n          <div class=\"cs-total\"><span class=\"cs-total-label\">Settled (Paid)</span><span class=\"cs-total-value\">{{ totals.paid | number:'1.2-2' }}</span><span class=\"cs-total-note\">already on a payslip line</span></div>\n          <div class=\"cs-total\"><span class=\"cs-total-label\">Reversed</span><span class=\"cs-total-value cs-reversed\">{{ totals.reversed | number:'1.2-2' }}</span><span class=\"cs-total-note\">clawbacks against earlier entries</span></div>\n          <div class=\"cs-total\"><span class=\"cs-total-label\">Carried forward in</span><span class=\"cs-total-value\">{{ totals.carried | number:'1.2-2' }}</span><span class=\"cs-total-note\">earned in an earlier period</span></div>\n        </div>\n\n        <div class=\"alert alert-secondary cs-note\" *ngIf=\"!entries.length\">\n          Nothing has been recorded for this period yet.\n        </div>\n\n        <table class=\"cs-table\" *ngIf=\"entries.length\">\n          <thead>\n            <tr><th>Employee</th><th>Description</th><th>Source</th><th class=\"cs-num\">Measured</th><th class=\"cs-num\">Amount</th><th>Status</th><th>Paid</th><th>Lines</th></tr>\n          </thead>\n          <tbody>\n            <tr *ngFor=\"let e of entries\">\n              <td>{{ e.employeeName }}</td>\n              <td>\n                {{ e.description }}\n                <span class=\"cs-flag\" *ngIf=\"e.isCarriedForward\">from {{ e.originPeriodMonth }}/{{ e.originPeriodYear }}</span>\n                <span class=\"cs-flag cs-flag-warn\" *ngIf=\"e.isReversal\">reverses #{{ e.reversesCommissionEntryID }}</span>\n              </td>\n              <td>{{ e.sourceType }}</td>\n              <td class=\"cs-num\">{{ e.metricValue | number:'1.0-2' }}</td>\n              <td class=\"cs-num cs-strong\" [class.cs-negative]=\"e.commissionAmount < 0\">{{ e.commissionAmount | number:'1.2-2' }}</td>\n              <td><span [ngClass]=\"statusClass(e)\">{{ e.statusName }}</span></td>\n              <td>{{ e.isPaid ? 'Yes' : '' }}</td>\n              <td>{{ e.lineCount }}</td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n\n    </div>\n  `,\n  styles: [`\n    .cs-container { padding: 16px; }\n    .cs-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n    .cs-bar { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; justify-content: space-between; margin-bottom: 8px; }\n    .cs-period { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }\n    .cs-actions { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }\n    .cs-year { width: 110px; }\n    .cs-month { width: 160px; }\n    .cs-note { font-size: 14px; }\n    .cs-panel { margin-top: 8px; }\n    .cs-headline { font-size: 14px; }\n    .cs-section { color: #333; font-weight: 500; margin: 16px 0 8px; }\n    .cs-list { margin: 6px 0 0; padding-left: 20px; }\n    .cs-list li { margin-bottom: 3px; }\n    .cs-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n    .cs-table th { text-align: left; padding: 8px 12px; background: #f5f5f5; border-bottom: 2px solid #e0e0e0; font-weight: 500; white-space: nowrap; }\n    .cs-table td { padding: 8px 12px; border-bottom: 1px solid #eee; vertical-align: top; }\n    .cs-table tr:hover { background: #fafafa; }\n    .cs-num { text-align: right; white-space: nowrap; }\n    .cs-strong { font-weight: 600; }\n    .cs-zero { color: #e65100; }\n    .cs-negative { color: #c62828; }\n    .cs-notes { max-width: 320px; }\n    .cs-flag { display: inline-block; margin: 1px 4px 1px 0; padding: 1px 7px; border-radius: 10px; background: #eceff1; color: #455a64; font-size: 11px; white-space: nowrap; }\n    .cs-flag-warn { background: #fff3cd; color: #664d03; }\n    .cs-warn { display: block; color: #664d03; font-size: 12px; margin-top: 2px; }\n    .cs-totals { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; }\n    .cs-total { display: flex; flex-direction: column; min-width: 170px; flex: 1 1 170px; padding: 10px 14px; border: 1px solid #e0e0e0; border-radius: 6px; background: #fff; }\n    .cs-total-label { font-size: 12px; color: #607d8b; }\n    .cs-total-value { font-size: 20px; font-weight: 600; }\n    .cs-total-note { font-size: 11px; color: #90a4ae; }\n    .cs-draft { color: #757575; }\n    .cs-approved { color: #2e7d32; }\n    .cs-reversed { color: #c62828; }\n    .cs-status-draft { color: #757575; }\n    .cs-status-approved { color: #2e7d32; font-weight: 600; }\n    .cs-status-reversed { color: #c62828; }\n\n    /* Phones: the two control groups stop competing for one row and the wide tables scroll inside\n       themselves rather than pushing the page sideways. */\n    @media (max-width: 700px) {\n      .cs-bar { flex-direction: column; align-items: stretch; }\n      .cs-actions button { flex: 1 1 auto; }\n      .cs-panel { overflow-x: auto; }\n      .cs-notes { max-width: none; }\n    }\n  `],\n  standalone: false\n})\nexport class CommissionStatementComponent implements OnInit {\n\n  private dataService = inject(DataServiceLib);\n  private configService = inject(ConfigService);\n  private messageService = inject(MessageService);\n\n  months = [\n    { value: 1, name: 'January' }, { value: 2, name: 'February' }, { value: 3, name: 'March' },\n    { value: 4, name: 'April' }, { value: 5, name: 'May' }, { value: 6, name: 'June' },\n    { value: 7, name: 'July' }, { value: 8, name: 'August' }, { value: 9, name: 'September' },\n    { value: 10, name: 'October' }, { value: 11, name: 'November' }, { value: 12, name: 'December' },\n  ];\n\n  periodYear = new Date().getFullYear();\n  periodMonth = new Date().getMonth() + 1;\n\n  busy = false;\n  previewResult: any = null;\n  generateResult: any = null;\n  entries: any[] = [];\n  statementLoaded = false;\n  totals = { draft: 0, approved: 0, paid: 0, reversed: 0, carried: 0 };\n\n  // Reads the one shared App Configuration record. An app whose configuration has no EnableTripCommission\n  // property simply gets undefined, so the generator hides — this fails CLOSED on purpose, matching the\n  // server's own late-bound read of the flag. A button that offers to write commission in an app that does\n  // not generate it is worse than no button.\n  tripCommissionEnabled = false;\n\n  ngOnInit(): void {\n    this.tripCommissionEnabled = !!this.configService.value?.enableTripCommission;\n    this.configService.config$.subscribe((config: any) => {\n      this.tripCommissionEnabled = !!config?.enableTripCommission;\n    });\n    this.loadStatement();\n  }\n\n  periodLabel(): string {\n    return `${this.months.find(m => m.value === this.periodMonth)?.name ?? this.periodMonth} ${this.periodYear}`;\n  }\n\n  get previewTotal(): number {\n    return (this.previewResult?.entries || []).reduce((sum: number, e: any) => sum + (e.commissionAmount || 0), 0);\n  }\n\n  statusClass(entry: any): string {\n    if (entry?.status === 1) return 'cs-status-draft';\n    if (entry?.status === 2) return 'cs-status-approved';\n    if (entry?.status === 4) return 'cs-status-reversed';\n    return '';\n  }\n\n  // Changing the period invalidates both result panels — leaving July's preview on screen above August's\n  // statement is how someone approves the wrong month.\n  clearResults() {\n    this.previewResult = null;\n    this.generateResult = null;\n    this.statementLoaded = false;\n  }\n\n  loadStatement() {\n    if (!this.validPeriod()) return;\n\n    this.busy = true;\n    this.dataService.CallApi({ url: `commissionentries/period/${this.periodYear}-${this.periodMonth}` }).subscribe({\n      next: (res: ApiResponse) => {\n        this.busy = false;\n        if (!res.success) { this.messageService.toast(res.message || 'Could not load the statement'); return; }\n        this.entries = res.data || [];\n        this.statementLoaded = true;\n        this.recalculateTotals();\n      },\n      error: () => { this.busy = false; }\n    });\n  }\n\n  // Draft, Approved, Paid and Reversed are summed separately and never rolled into one figure. A single\n  // \"total commission\" would read as owed when most of it is a proposal nobody has approved.\n  private recalculateTotals() {\n    this.totals = { draft: 0, approved: 0, paid: 0, reversed: 0, carried: 0 };\n\n    for (const e of this.entries) {\n      const amount = e.commissionAmount || 0;\n      if (e.isPaid || e.status === 3) this.totals.paid += amount;\n      else if (e.status === 2) this.totals.approved += amount;\n      else if (e.status === 4) this.totals.reversed += amount;\n      else this.totals.draft += amount;\n\n      if (e.isCarriedForward) this.totals.carried += amount;\n    }\n  }\n\n  // PREVIEW WRITES NOTHING. It is gated on cap77 VIEW server-side for exactly that reason, and the result\n  // panel repeats it — a figure on screen that looks committed is the failure this button exists to avoid.\n  preview() {\n    if (!this.validPeriod()) return;\n\n    this.busy = true;\n    this.generateResult = null;\n    this.dataService.CallApi({ url: 'shiftcommission/preview', method: 'post' }, { periodYear: this.periodYear, periodMonth: this.periodMonth }).subscribe({\n      next: (res: ApiResponse) => {\n        this.busy = false;\n        if (!res.success) { this.messageService.toast(res.message || 'Preview failed'); return; }\n        this.previewResult = res.data || {};\n      },\n      error: () => { this.busy = false; }\n    });\n  }\n\n  // GENERATE WRITES. Every entry lands as Draft, so nothing here can pay anybody without a separate\n  // approval — the confirm says so rather than leaving it to be discovered.\n  generate() {\n    if (!this.validPeriod()) return;\n\n    this.messageService.confirm(`Generate commission entries for ${this.periodLabel()}? They are created as Draft and still have to be approved before a payroll run can pay them. Regenerating a period reverses entries that were already approved or paid.`)\n      .subscribe((answer: any) => {\n        if (answer !== 'yes') return;\n\n        this.busy = true;\n        this.previewResult = null;\n        this.dataService.CallApi({ url: 'shiftcommission/generate', method: 'post' }, { periodYear: this.periodYear, periodMonth: this.periodMonth }).subscribe({\n          next: (res: ApiResponse) => {\n            this.busy = false;\n            if (!res.success) { this.messageService.toast(res.message || 'Generation failed'); return; }\n            this.generateResult = res.data || {};\n            this.loadStatement(); // the statement below must agree with what was just written\n          },\n          error: () => { this.busy = false; }\n        });\n      });\n  }\n\n  private validPeriod(): boolean {\n    if (!this.periodMonth || this.periodMonth < 1 || this.periodMonth > 12) { this.messageService.toast('Choose a month'); return false; }\n    if (!this.periodYear || this.periodYear < 2000 || this.periodYear > 2100) { this.messageService.toast('Year must be between 2000 and 2100'); return false; }\n    return true;\n  }\n}\n","import { Component, inject } from '@angular/core';\nimport { PayrollService } from '../../../services/payroll.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n    selector: 'spa-salary-advances',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class SalaryAdvancesComponent {\n  private payrollService = inject(PayrollService);\n\n  pageConfig: PageConfig = {\n    title: 'Salary Advances',\n    tableConfig: this.payrollService.salaryAdvancesTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PayrollService } from '../../../services/payroll.service';\nimport { PageConfig } from '../../../classes/Classes';\n\n@Component({\n    selector: 'spa-overtime-entries',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class OvertimeEntriesComponent {\n  private payrollService = inject(PayrollService);\n\n  pageConfig: PageConfig = {\n    title: 'Overtime Entries',\n    tableConfig: this.payrollService.overtimeEntriesTableConfig\n  };\n}\n","import { Component, OnInit } from '@angular/core';\nimport { TileConfig, ChartConfig, ApiResponse } from '../../../classes/Classes';\nimport { DataServiceLib } from '../../../services/datalib.service';\n\n// Payroll module dashboard with cost tracking, department analysis, and employee metrics\n@Component({\n  selector: 'spa-payroll-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>payments</mat-icon> Payroll Dashboard</h4>\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n\n      <!-- Recent Payroll Runs sub-table -->\n      <div *ngIf=\"recentRuns.length > 0\" class=\"runs-section\">\n        <h5 class=\"section-title\">\n          <mat-icon style=\"vertical-align: middle; margin-right: 4px;\">play_circle</mat-icon>\n          Recent Payroll Runs\n        </h5>\n        <table class=\"kpi-table\">\n          <thead>\n            <tr>\n              <th>Period</th>\n              <th>Pay Date</th>\n              <th>Status</th>\n              <th>Employees</th>\n              <th>Gross Pay</th>\n              <th>Net Pay</th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr *ngFor=\"let run of recentRuns\">\n              <td>{{ run.periodName }}</td>\n              <td>{{ run.payDate | date:'mediumDate' }}</td>\n              <td>\n                <span class=\"status-chip\" [style.background]=\"run.statusColor\">{{ run.statusName }}</span>\n              </td>\n              <td>{{ run.payslipCount }}</td>\n              <td>{{ run.totalGrossPay | currency }}</td>\n              <td>{{ run.totalNetPay | currency }}</td>\n            </tr>\n          </tbody>\n        </table>\n      </div>\n\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n    .runs-section { margin-top: 16px; }\n    .section-title { display: flex; align-items: center; margin-bottom: 8px; color: #333; font-weight: 500; }\n    .kpi-table { width: 100%; border-collapse: collapse; font-size: 13px; }\n    .kpi-table th { text-align: left; padding: 8px 12px; background: #f5f5f5; border-bottom: 2px solid #e0e0e0; font-weight: 500; }\n    .kpi-table td { padding: 8px 12px; border-bottom: 1px solid #eee; }\n    .kpi-table tr:hover { background: #fafafa; }\n    .status-chip { padding: 2px 8px; border-radius: 12px; color: white; font-size: 11px; font-weight: 500; }\n  `],\n  standalone: false\n})\nexport class PayrollDashboardComponent implements OnInit {\n\n  constructor(private dataService: DataServiceLib) { }\n\n  recentRuns: any[] = [];\n\n  // Changed: Summary tiles — payroll KPIs\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'eligibleEmployees', alias: 'Eligible Employees', color: '#1565c0', icon: 'group', style: 'icon', info: 'Active employees with salary structures' },\n      { name: 'lastPayrollNet', alias: 'Last Payroll (Net)', color: '#4caf50', icon: 'account_balance', style: 'icon', prefix: '$', info: 'Net pay of last completed run' },\n      { name: 'pendingAdvances', alias: 'Pending Advances', color: '#f44336', icon: 'money_off', style: 'icon', info: 'Undeducted salary advances' },\n      { name: 'overtimeMTD', alias: 'Overtime (MTD)', color: '#ff9800', icon: 'more_time', style: 'icon', prefix: '$', info: 'Total overtime this month' },\n      { name: 'payrollRunsYTD', alias: 'Runs (YTD)', color: '#7b1fa2', icon: 'play_circle', style: 'icon', info: 'Payroll runs this year' },\n      { name: 'totalPayrollCostYTD', alias: 'Payroll Cost (YTD)', color: '#00695c', icon: 'attach_money', style: 'icon', prefix: '$', info: 'Year-to-date gross payroll' },\n    ],\n    loadAction: { url: 'payrollruns/dashboard-summary/x' },\n    loadInit: true\n  };\n\n  // Changed: Chart tiles — cost ratio gauge, trend sparkline, department pie, run status bar\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'payrollCostRatio', alias: 'Payroll Cost Ratio', color: '#ff9800', chart: { type: 'doughnut', gaugeColor: '#ff9800', height: 130, dataField: 'payrollCostRatio' }, footer: 'Payroll as % of expenses', footerIcon: 'info' },\n      { name: 'payrollTrend', alias: 'Payroll Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'payrollTrend' }, footer: 'Last 12 months gross', footerIcon: 'timeline' },\n      { name: 'departmentSplit', alias: 'By Department', color: '#4caf50', chart: { type: 'pie', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0'], height: 130, dataField: 'departmentSplit' }, footer: 'Employee distribution', footerIcon: 'pie_chart' },\n      { name: 'runStatusSplit', alias: 'Run Status', color: '#9c27b0', chart: { type: 'bar', colors: ['#9e9e9e', '#2196f3', '#ff9800', '#4caf50'], height: 100, dataField: 'runStatusSplit' }, footer: 'All-time run status', footerIcon: 'bar_chart' },\n    ],\n    loadAction: { url: 'payrollruns/dashboard-chart-tiles/x' },\n    loadInit: true\n  };\n\n  // Changed: Full charts — cost trend, department breakdown, earnings vs deductions, commission & overtime\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'payrollCostTrend', title: 'Payroll Cost Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#2196f3', '#4caf50', '#f44336'], showLegend: true },\n      { name: 'departmentCosts', title: 'Cost by Department', type: 'bar', height: '300px', colors: ['#2196f3', '#4caf50', '#ff9800', '#f44336', '#9c27b0'] },\n      { name: 'earningsVsDeductions', title: 'Earnings vs Deductions', type: 'doughnut', height: '300px', colors: ['#4caf50', '#f44336'] },\n      { name: 'variablePayTrend', title: 'Commission & Overtime', type: 'bar', height: '300px', showLegend: true, colors: ['#9c27b0', '#ff9800'] },\n    ],\n    loadAction: { url: 'payrollruns/dashboard-charts/x' },\n    loadInit: true,\n    columns: 2\n  };\n\n  ngOnInit(): void {\n    // Load recent payroll runs for sub-table\n    this.dataService.CallApi({ url: 'payrollruns/dashboard-recent/x' }).subscribe((res: ApiResponse) => {\n      if (res.success) this.recentRuns = res.data || [];\n    });\n  }\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { SalaryStructuresComponent } from '../../pages/payroll/salary-structures/salary-structures.component';\nimport { StatutoryDeductionsComponent } from '../../pages/payroll/statutory-deductions/statutory-deductions.component';\nimport { PayrollRunsComponent } from '../../pages/payroll/payroll-runs/payroll-runs.component';\nimport { CommissionConfigsComponent } from '../../pages/payroll/commission-configs/commission-configs.component';\nimport { CommissionEntriesComponent } from '../../pages/payroll/commission-entries/commission-entries.component';\nimport { CommissionStatementComponent } from '../../pages/payroll/commission-statement/commission-statement.component'; // Added (Phase 6)\nimport { SalaryAdvancesComponent } from '../../pages/payroll/salary-advances/salary-advances.component';\nimport { OvertimeEntriesComponent } from '../../pages/payroll/overtime-entries/overtime-entries.component';\nimport { PayrollDashboardComponent } from '../../pages/payroll/payroll-dashboard/payroll-dashboard.component';\n\nexport const PAYROLL_ROUTES: Routes = [\n  { path: \"salary-structures\", component: SalaryStructuresComponent },\n  { path: \"statutory-deductions\", component: StatutoryDeductionsComponent },\n  { path: \"runs\", component: PayrollRunsComponent },\n  { path: \"commission-configs\", component: CommissionConfigsComponent },\n  { path: \"commission-entries\", component: CommissionEntriesComponent },\n  { path: \"commission-statement\", component: CommissionStatementComponent, data: { capName: 'cap86' } }, // Added (Phase 6): cap86 — routed and registered, granted in no role template // Changed: added INERT capName — cap86 is capCommissionStatement, menu link exactly \"home/payroll/commission-statement\" (datalib.service.ts:276,278)\n  { path: \"salary-advances\", component: SalaryAdvancesComponent },\n  { path: \"overtime-entries\", component: OvertimeEntriesComponent },\n  { path: \"dashboard\", component: PayrollDashboardComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(PAYROLL_ROUTES)],\n  exports: [RouterModule]\n})\nexport class PayrollRoutingModule { }\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { ProductionService } from '../../../services/production.service';\n\n// Component for managing production recipes\n@Component({\n  selector: 'spa-production-recipes',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class ProductionRecipesComponent implements OnInit {\n\n  private productionService = inject(ProductionService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Production Recipes',\n    tableConfig: this.productionService.recipesTableConfig\n  };\n}\n","import { Component, inject, OnInit } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { ProductionService } from '../../../services/production.service';\n\n// Component for managing production orders\n@Component({\n  selector: 'spa-production-orders',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class ProductionOrdersComponent implements OnInit {\n\n  private productionService = inject(ProductionService);\n\n  ngOnInit(): void { }\n\n  pageConfig: PageConfig = {\n    title: 'Production Orders',\n    tableConfig: this.productionService.ordersTableConfig\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { ProductionRecipesComponent } from '../../pages/manufacturing/production-recipes/production-recipes.component';\nimport { ProductionOrdersComponent } from '../../pages/manufacturing/production-orders/production-orders.component';\n\nexport const MANUFACTURING_ROUTES: Routes = [\n  { path: \"production-recipes\", component: ProductionRecipesComponent },\n  { path: \"production-orders\", component: ProductionOrdersComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(MANUFACTURING_ROUTES)],\n  exports: [RouterModule]\n})\nexport class ManufacturingRoutingModule { }\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { LoansService } from '../../../services/loans.service';\n\n\n@Component({\n  selector: 'spa-loan-products',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class LoanProductsComponent {\n  private loansService = inject(LoansService);\n  \n  pageConfig: PageConfig = {\n    title: 'Loan Products',\n    tableConfig: this.loansService.loanProductTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { LoansService } from '../../../services/loans.service';\n\n\n@Component({\n  selector: 'spa-loans',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class LoansComponent {\n  private loansService = inject(LoansService);\n  \n  pageConfig: PageConfig = {\n    title: 'Loans',\n    tableConfig: this.loansService.loanTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { LoansService } from '../../../services/loans.service';\n\n\n@Component({\n  selector: 'spa-loan-payments',\n  standalone: false,\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class LoanPaymentsComponent {\n  private loansService = inject(LoansService);\n  \n  pageConfig: PageConfig = {\n    title: 'Loan Payments',\n    tableConfig: this.loansService.loanPaymentTableConfig\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { LoanProductsComponent } from '../../pages/loans/loan-products/loan-products.component';\nimport { LoansComponent } from '../../pages/loans/loans/loans.component';\nimport { LoanPaymentsComponent } from '../../pages/loans/loan-payments/loan-payments.component';\n\nexport const LOANS_ROUTES: Routes = [\n  { path: \"products\", component: LoanProductsComponent },\n  { path: \"loans\", component: LoansComponent },\n  { path: \"payments\", component: LoanPaymentsComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(LOANS_ROUTES)],\n  exports: [RouterModule]\n})\nexport class LoansRoutingModule { }\n","import { Component, inject } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { PageConfig } from '../../classes/Classes';\n\n\n@Component({\n    selector: 'spa-customers',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class CustomersComponent {\n  private dataService = inject(DataServiceLib);\n  \n  pageConfig: PageConfig = {\n    title: 'Customers',\n    tableConfig: this.dataService.customersTableConfig\n  };\n\n}\n","import { Component, inject } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { PageConfig } from '../../classes/Classes';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\n\n\n@Component({\n    selector: 'spa-suppliers',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class SuppliersComponent {\n  private dataService = inject(DataServiceLib);\n  private messageService = inject(MessageService);\n  private authService = inject(AuthService);\n  \n  pageConfig: PageConfig = {\n    title: 'Suppliers',\n    tableConfig: this.dataService.suppliersTableConfig\n  };\n\n\n\n}\n","import { Component, OnInit } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { FormConfig, ListDialogConfig, TableConfig, ApiResponse } from '../../classes/Classes';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\nimport { ListDialogComponent } from '../../components/list-dialog/list-dialog.component';\nimport { MatDialog } from '@angular/material/dialog';\nimport { Subject } from 'rxjs';\n\n@Component({\n    selector: 'spa-tasks',\n    templateUrl: './tasks.component.html',\n    styleUrls: ['./tasks.component.css'],\n    standalone: false\n})\nexport class TasksComponent implements OnInit {\n\n  constructor(private dataService: DataServiceLib, private messageService: MessageService, public authService: AuthService, public dialog: MatDialog) { }\n\n  ngOnInit(): void {\n    this.loadData();\n  }\n\n  loadData(){\n    this.dataService.CallApi({ url:'tasks/meta/x'}).subscribe((api : ApiResponse) => {\n      this.formConfig.fields.find(x => x.name == 'assignee').options = api.data.members;\n      this.formConfig.fields.find(x => x.name == 'assignee').defaultValue = this.authService.currentUser;\n      this.formConfig.fields.find(x => x.name == 'categoryID').options = api.data.categories;\n    })\n  }\n\n  cats() {\n\n    let conf: ListDialogConfig = { title: \"Task Categories\", name: 'Category', listName: 'TaskCategories' }\n\n    const dialogRef = this.dialog.open(ListDialogComponent, {\n      width: \"900px\",\n      panelClass: this.dataService?.dialogPanelClass ?? [], // Added: modern surface treatment when the app opts in\n      data: conf,\n    });\n\n    dialogRef.afterClosed().subscribe((result) => {\n\n      if (result == 'success') {\n        this.reload.next(true);\n      }\n    });\n\n  }\n\n\n  reload: Subject<boolean> = new Subject();\n\n  statuses = [\n    { name: 'Not Started', value: 0 },\n    { name: 'In-Progress', value: 1 },\n    { name: 'Completed', value: 2 },\n  ]\n\n  formConfig: FormConfig = {\n    security: { allow: [this.dataService.capTasks] }, // Added: gate task form by tasks cap\n\n    fields: [\n      { name: 'name', type: 'text', span : true, required : true },\n      { name: 'status', type: 'select', options : this.statuses, defaultFirstValue : true, required : true },\n      { name: 'dueDate', type: 'date' },\n      { name: 'assignee', type: 'select', optionDisplay : 'name', optionValue : 'userName' },\n      { name: 'categoryID', alias: 'Category', type: 'select', optionDisplay: 'name', optionValue: 'listItemID', defaultFirstValue: true, required: true },\n    ],\n\n    reset: true,\n  }\n\n  tasksTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'assigneeName'],\n    flatButtons: true,\n\n    columns: [\n\n      { name: 'name', type: 'text'},\n      { name: 'statusName', type: 'text' },\n      { name: 'dueDate', type: 'date' },\n      { name: 'assigneeName', alias:'assignee', type: 'text'},\n      { name: 'categoryName', alias: 'Category', type: 'text' },\n      { name: 'createdDate', alias : 'Created', type: 'date' },\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'tasks?action=create', method: 'post' } },\n      { name: 'view', dialog: true },\n      { name: 'edit', dialog: true, action: { url: 'tasks?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'tasks?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'tasks/all/x' },\n\n    formConfig: this.formConfig\n\n  }\n}\n","<div class=\"d-flex align-items-center justify-content-between mt-0\" style=\"margin-left: 10px\">\n\n  <label style=\"font-size: 16px;\">Tasks</label>\n\n  <div>\n    <button mat-mini-fab color=\"primary\" style=\"margin-right:1em;\" (click)=\"cats()\" matTooltip=\"Categories\" matTooltipPosition=\"above\"><mat-icon>category</mat-icon></button>\n  </div>\n\n</div>\n<hr>\n\n<div class=\"mt-3\" style=\" font-size: 14px;\">\n  <spa-table [config]=\"tasksTableConfig\" [reload]=\"reload\"></spa-table>\n</div>\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { CustomersComponent } from '../../pages/customers/customers.component';\nimport { SuppliersComponent } from '../../pages/suppliers/suppliers.component';\nimport { CategoriesComponent } from '../../pages/categories/categories.component';\nimport { SubCategoriesComponent } from '../../pages/subcategories/subcategories.component';\nimport { BrandsComponent } from '../../pages/brands/brands.component';\nimport { TasksComponent } from '../../pages/tasks/tasks.component';\n\n// Added (F3): leaf-level data.moduleKey, inert metadata only — no guard is attached in this library. The general\n// AREA stays bare because \"general\" is a Core module the server always reports enabled, but Tasks & Notes is a\n// separate switchable module whose page happens to live under this path (capTasks.moduleKey = \"tasks\",\n// datalib.service.ts:146, a sub-item of capGeneral). Deepest data wins, so this leaf key is what a consumer's\n// guard resolves for home/general/tasks; everything else here correctly stays ungated.\nexport const GENERAL_ROUTES: Routes = [\n  { path: \"customers\", component: CustomersComponent },\n  { path: \"suppliers\", component: SuppliersComponent },\n  { path: \"categories\", component: CategoriesComponent },\n  { path: \"subcategories\", component: SubCategoriesComponent },\n  { path: \"brands\", component: BrandsComponent },\n  { path: \"tasks\", component: TasksComponent, data: { moduleKey: 'tasks' } } // Added (F3): Tasks & Notes is its own module\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(GENERAL_ROUTES)],\n  exports: [RouterModule]\n})\nexport class GeneralRoutingModule { }\n","import { Component, OnInit } from '@angular/core';\nimport { FormConfig, TableConfig, ApiResponse, DetailsDialogConfig, Field } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: a refused organisation switch used to do nothing at all (WS-6 Phase 4)\nimport { MatDialog } from '@angular/material/dialog';\nimport { Subject } from 'rxjs';\n\n// Added: the four collapsible sections on this page, named once so toggle() is type-checked.\ntype SectionKey = 'members' | 'orgs' | 'invites' | 'email';\n\n@Component({\n    selector: 'spa-tenant-settings',\n    templateUrl: './tenant-settings.component.html',\n    styleUrls: ['./tenant-settings.component.css'],\n    standalone: false\n})\nexport class TenantSettingsComponent implements OnInit {\n\n  constructor(public dataService: DataServiceLib, private messageService: MessageService, public authService: AuthService, public dialog: MatDialog, private apiErrorService: ApiErrorService ) { } // Changed: injected ApiErrorService for the switch failure\n\n  ngOnInit(): void {\n    this.authService.myRoleObserv.subscribe(rol => this.myRole = rol);\n    this.loadData();\n    this.loadTenants()\n  }\n\n  newName;\n\n  myRole\n  tenants;\n  currTenant;\n  currentTenantID;\n  ownTenant;\n\n  // Added (2026-08-12): which cards are shut. Members is left open, the rest closed — the Day Book's\n  // arrangement (first open, the others showing only their identity). Every closed card still states\n  // what it holds, so nothing is hidden behind a click you would have to make to find out.\n  closed: { [K in SectionKey]: boolean } = { members: false, orgs: true, invites: true, email: true };\n\n  // Added: row totals reported by each table's existing (totalChange) output. Declared field-by-field\n  // rather than as an index signature: the library compiles with noPropertyAccessFromIndexSignature, so\n  // counts.members in a template is an error under an index signature. undefined = the table has not\n  // reported yet, which is why the summary tells that apart from a genuine zero.\n  counts: { members?: number, orgs?: number, invites?: number, email?: number } = {};\n\n  // Added (2026-08-12, owner): the hero's \"you are here\" line. Both are plain fields set when data arrives —\n  // NOT template getters, which allocate on every change-detection pass (the livelock written up for this\n  // library). currentTenantName is resolved from currTenant.tenantID, deliberately not from currentTenantID:\n  // currentTenantID is the DROPDOWN's value and changes the moment the user picks another organisation, so\n  // binding to it would make the line claim you had already moved before you pressed Switch.\n  currentTenantName = '';\n  belongText = '';\n\n  setWhere() {\n    const list = this.tenants || [];\n    const id = this.currTenant ? this.currTenant.tenantID : null;\n    const found = list.find(x => x.tenantID == id);\n    this.currentTenantName = found ? found.name : (this.currTenant && this.currTenant.name ? this.currTenant.name : '');\n    // Worded, never a bare figure — a lone number on a card does not say what it counts.\n    this.belongText = list.length > 1 ? 'you belong to ' + list.length + ' organisations' : (list.length === 1 ? 'your only organisation' : '');\n  }\n\n  toggle(key: SectionKey) { this.closed[key] = !this.closed[key]; }\n\n  // The collapsed summary. It always names what it is counting — '2 organisations', never a bare '2',\n  // which on a card reads as an identifier as readily as a quantity.\n  summary(n: number | undefined, one: string, many: string): string {\n    if (n === undefined || n === null) return '';\n    if (n === 0) return 'No ' + many;\n    return n + ' ' + (n === 1 ? one : many);\n  }\n\n  emailSummary(n: number | undefined): string {\n    if (n === undefined || n === null) return '';\n    return n === 0 ? 'Not configured' : (n === 1 ? '1 configuration' : n + ' configurations');\n  }\n\n  roles = [\n    { roleName: 'Default', roleID: 1 },\n  ]\n\n  loadData(){\n    this.dataService.CallApi({ url: 'tenants/meta/x' }, \"\").subscribe((apiResponse: ApiResponse) => {\n      this.currTenant = apiResponse.data.tenant;\n      this.currentTenantID = apiResponse.data.currentTenantID;\n      this.ownTenant = apiResponse.data.ownTenant\n      this.membersFormConfig.fields.find(x => x.name == 'roleID').options = apiResponse.data.roles;\n      this.setWhere(); // Added: the two calls land in either order, so the hero line is recomputed by both\n    });\n  }\n\n  loadTenants() {\n    this.dataService.CallApi({ url: 'tenants/meta_tenants/x' }, \"\").subscribe((apiResponse: ApiResponse) => {\n      this.tenants = apiResponse.data.tenants;\n      this.setWhere(); // Added: the organisation names live on this response, so the line cannot resolve before it\n    });\n  }\n\n\n  updateTenant(x){\n\n    if (x.name == \"edit\" && x.data.success ) {\n      if (x.data.data.tenantID == this.currentTenantID){\n        this.authService.updateTenantName(x.data.data.name)\n      }\n      this.refreshOrgsLists();\n    }\n\n    if (x.name == \"login\" && x.data.success) {\n      this.forceLogin();\n    }\n\n    if (x.name == \"leave\" && x.data.success) {\n      this.refreshOrgsLists();\n    }\n  }\n\n  refreshOrgsLists(){\n    this.loadTenants();\n  }\n\n  switchTenant() {\n\n    this.messageService.confirm(`Switch Organisation ?`).subscribe((result) => {\n      if (result == \"yes\") {\n\n        this.currTenant.tenantID = this.currentTenantID;\n\n        this.dataService.CallApi({ url: 'tenants/dto?action=switch', method: 'post' }, this.currTenant).subscribe((apiResponse: ApiResponse) => {\n\n          if (apiResponse.success) {\n            this.forceLogin()\n          } else {\n            this.apiErrorService.presentAppFailure(apiResponse, 'action', 'tenants/dto?action=switch'); // Added: was silent. The user picked an organisation, confirmed it, and got NOTHING — no switch, no message — leaving them unable to tell whether they had changed organisation or not, on the one screen where that question matters most\n          }\n        });\n      }\n    });\n  }\n\n  forceLogin(){\n    this.messageService.toast(\"Switched Successfully, please login again\");\n    this.authService.logoff();\n  }\n\n\n\n\n  //Members\n\n  roleField: Field = { name: 'roleID', type: 'select', required: true, span : true, options: this.roles, optionDisplay: 'roleName', optionValue: 'roleID', defaultFirstValue: true }\n\n  inviteDialogConfig: DetailsDialogConfig = {\n    formConfig: {\n      title: 'Add Member',\n      fixedTitle: true,\n      fields: [\n        { name: 'email', type: 'text', required: true, span: true },\n        { name: 'firstName', type: 'text', required: true, min: 2, },\n        { name: 'lastName', type: 'text', required: true, min: 2, },\n        this.roleField,\n      ]\n    },\n    mode: 'create',\n    buttons: [\n      { name: 'create', action: { url: 'members/dto?action=invite', method: 'post', successMessage: 'Updated successfully' } }\n    ]\n  };\n\n  membersFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSettings] }, // Added: gate member access form by settings cap (tenant settings page)\n\n    title : 'Member Access',\n    alertConfig : {messages :[ {type : 'warn', message : 'You can amend the member\\'s role here'}] },  // Changed: content to message\n    fields: [\n      { name: 'email', type: 'text',readonly: true, span: true },\n      { name: 'firstName', type: 'text', readonly: true },\n      { name: 'lastName', type: 'text',  readonly: true },\n      this.roleField,\n    ],\n\n  }\n\n  tableReload: Subject<boolean> = new Subject();\n  membersTableConfig: TableConfig = {\n\n    greyOut : (value) => value.accepted == false,\n    elevation: 'low',\n    logResponse : true,\n    minColumns: ['memberName'],\n    minButtons: ['edit','remove'],\n    flatButtons: true,\n\n    columns: [\n      { name: 'memberName', type: 'text', icons : [\n        { name: 'schedule', tip : 'Waiting for user to accept invitation',  condition: x => !x.accepted }\n      ] },\n      { name: 'email', type: 'text' },\n      { name: 'roleName', alias : 'Role', type: 'text'},\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Add Member', dialog : true, detailsConfig: this.inviteDialogConfig },\n      { name: 'edit', icon: { name: 'security' }, tip : 'Edit Access', dialog: true, action: { url: 'members/dto?action=role', method: 'post' }, },\n      { name: 'remove', icon: { name: 'close', color : 'red' }, tip : 'Remove Member', confirm: { message: 'Remove Member from this Organisation ?' }, action: { url: 'members/dto?action=remove', method: 'post' }, disabled : x => x.own },\n    ],\n\n    loadAction: { url: 'members/all/x' },\n\n    formConfig: this.membersFormConfig,\n  }\n\n\n\n  //Organsations\n\n  orgFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSettings] }, // Added: gate organisation form by settings cap (tenant settings page)\n    fixedTitle: true,\n    fields: [\n      { name: 'name', type: 'text', required: true, min: 2 },\n    ]\n  }\n  createOrgDialogConfig: DetailsDialogConfig = {\n    formConfig: {...this.orgFormConfig, title: 'New Organisation'},\n    mode: 'create',\n    buttons: [\n      { name: 'create', action: { url: 'tenants/dto?action=create', method: 'post', successMessage: 'Created successfully' } }\n    ]\n  };\n\n  renameOrgDialogConfig: DetailsDialogConfig = {\n    formConfig: {\n      ...this.orgFormConfig,\n      title: 'Organisation Details',\n      fields: [\n        ...this.orgFormConfig.fields,\n        { name: 'companyDetails', type: 'section', },\n        { name: 'companyName', type: 'text', span: true, alias: 'Company Name' },\n        { name: 'address', type: 'text', rows : 3, span: true },\n        { name: 'phone', type: 'text' },\n        { name: 'email', type: 'text' },\n        { name: 'vatNumber', type: 'text', alias: 'VAT Number' }, // Added: Phase 2 compliance — company VAT registration number\n        { name: 'tin', type: 'text', alias: 'TIN' } // Added: Phase 2 compliance — taxpayer identification number\n      ]\n\n    },\n    mode: 'edit',\n    buttons: [\n      { name: 'edit', action: { url: 'tenants?action=edit', method: 'post', successMessage: 'Renamed successfully' } }\n    ]\n  }\n\n  orgsReload: Subject<boolean> = new Subject();\n  orgsTableConfig: TableConfig = {\n\n    greyOut: (value) => value.accepted == false,\n    elevation: 'low',\n    minColumns: ['name'],\n    minButtons: ['login','edit','leave'],\n    flatButtons: true,\n    collapseButtons : true,\n\n    columns: [\n      { name: 'name', alias : 'Organisation', type: 'text', icons: [{ name: 'radio_button_checked', tip : 'Current Organisation', color: 'green', condition: x => x.tenantID == this.currentTenantID }] },\n      { name: 'ownerName', type: 'text', alias: 'Owner' },\n    ],\n\n    buttons: [\n      { name: 'create', display: 'New Organisation', dialog: true, detailsConfig: this.createOrgDialogConfig },\n      {\n        name: 'login', display: 'Switch to this Organisation', confirm: { message: 'Switch to this Organisation ?' }, action: { url: 'tenants/dto?action=switch', method: 'post' }, icon: { name: 'login', },\n        visible: x => x.tenantID != this.currentTenantID\n      },\n      {\n        name: 'edit', display: 'Rename Organisation', dialog: true, detailsConfig: this.renameOrgDialogConfig ,\n        visible: x => x.own\n      },\n      {\n        name: 'leave', tip: 'Leave', icon: { name: 'directions_run', color : 'red'}, confirm: { message: 'Leave this Organisation ?' }, action: { url: 'members/dto?action=remove', method: 'post' } ,\n        disabled : x => x.own\n      },\n    ],\n\n    loadAction: { url: 'tenants/my_tenants/x' },\n\n  }\n\n\n\n  //Email\n  mailerFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capSettings] }, // Added: gate mailer form by settings cap (tenant settings page)\n    fields: [\n      { name: 'smtp', type: 'text', required: true, alias: 'SMTP Server' },\n      { name: 'port', type: 'number', required: true, defaultValue: 587 },\n      { name: 'address', type: 'text', required: true, alias: 'Email Address' },\n      { name: 'display', type: 'text', required: true, alias: 'Display Name' },\n      { name: 'password', type: 'text-mask', required: true, span: true }, // Changed: password -> text-mask\n\n      { name: 'enableSsl', type: 'checkbox', alias: 'Enable SSL' },\n      { name: 'isBodyHtml', type: 'checkbox', alias: 'HTML Body' },\n\n\n    ]\n  }\n\n  mailerTableConfig: TableConfig = {\n    showFilter: true,\n    elevation: 'low',\n    minColumns: ['smtp', 'address'],\n    flatButtons: true,\n\n    columns: [\n      { name: 'smtp', type: 'text', alias: 'SMTP Server' },\n      { name: 'port', type: 'number' },\n      { name: 'address', type: 'text', alias: 'Email Address' },\n      { name: 'display', type: 'text', alias: 'Display Name' },\n      { name: 'enableSsl', type: 'checkbox', alias: 'SSL Enabled' },\n      { name: 'isBodyHtml', type: 'checkbox', alias: 'HTML Body' },\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Configure Email', dialog: true, action: { url: 'mailerconfigs?action=create', method: 'post' } },\n      { name: 'edit', dialog: true, action: { url: 'mailerconfigs?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'mailerconfigs?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'mailerconfigs/all/x' },\n    formConfig: this.mailerFormConfig\n  }\n}\n","<!-- Changed (2026-08-12): the page was five bare <label class=\"title\"> + <hr> blocks with tables hanging\n     under them, and it had not been modernised alongside the Day Book and Getting Started. It is now the\n     same language as those two: a page shell, one mat-card per section, and a header strip that is itself\n     the button. Members / My Organisations / My Invitations / Email Configuration collapse; collapsed, each\n     card still says what it holds (\"2 organisations\") so the page can be read without opening anything. -->\n<div class=\"ts-page\">\n\n  <!-- Changed (2026-08-12, owner feedback on the top section): the page opened with a bare <h1> sitting on the\n       page background, and a separate switcher card underneath holding one half-width select and a button —\n       with 513px of empty card to the right of them (measured). Getting Started, the page he named as the\n       reference, opens with a HERO CARD instead: title, purpose and a status line on the left, and the page's\n       one live control on the right (there, the readiness bar). Same idiom here. The organisation switcher IS\n       this page's live control, so it now stands where that bar stands and fills the space that read as empty,\n       rather than occupying a near-empty card of its own. The 24px padding, the 24px column gap and the type\n       sizes are Getting Started's own values — nothing new was invented. -->\n  <mat-card class=\"ts-hero\">\n    <div class=\"ts-hero-content\">\n\n      <div class=\"ts-hero-text\">\n        <h1>Organisation Details</h1>\n        <p class=\"ts-sub\">Your organisation, who belongs to it, and the invitations waiting for you.</p>\n        <!-- The \"you are here\" line, standing in Getting Started's .hero-counter slot. It names the organisation\n             you are ACTUALLY in, taken from currTenant and not from the dropdown's value, so it keeps telling the\n             truth after you pick a different organisation and before you press Switch. -->\n        <span class=\"ts-where\" *ngIf=\"currentTenantName\">You are working in <strong>{{ currentTenantName }}</strong><ng-container *ngIf=\"belongText\"> &middot; {{ belongText }}</ng-container></span>\n      </div>\n\n      <!-- Current organisation. Changed: the gate was `currTenant && plan` — `plan` existed only to feed the\n           Billing block that has now gone, and leaving it in the condition would have hidden the switcher\n           outright. It never had anything to do with switching organisation. -->\n      <div class=\"ts-switch\" *ngIf=\"currTenant\">\n        <div class=\"ts-switch-row\">\n          <spa-select class=\"ts-switch-select\" display=\"Current Organisation\" [options]=\"tenants\" optionDisplay=\"name\" optionValue=\"tenantID\" [(value)]=\"currentTenantID\" hint=\"You are required to login again after switching organisations.\"></spa-select>\n          <button mat-flat-button color=\"primary\" class=\"ts-switch-btn\" [disabled]=\"currentTenantID == currTenant.tenantID\" (click)=\"switchTenant()\">Switch</button>\n        </div>\n      </div>\n\n    </div>\n  </mat-card>\n\n  <ng-container *ngIf=\"ownTenant\">\n\n    <!-- Members -->\n    <mat-card class=\"ts-card\" [class.closed]=\"closed.members\">\n      <!-- Changed (2026-08-19): was two glyphs swapped at the far right — expand_more/expand_less. The estate has\n           ONE disclosure marker, .tin-disc in tin-styles.css: a single chevron_right rotated 90deg on open, leading\n           the row. A swap cannot animate and changes shape between states; the rotation reads as \"this opens\".\n           Already the pattern on the Day Book, Getting Started, Roles, the checklist, spa-table sections and the\n           form section header. These four cards were the last holdouts in tin-spa. -->\n      <button type=\"button\" class=\"ts-chead tin-disc-row\" (click)=\"toggle('members')\" [attr.aria-expanded]=\"!closed.members\" [attr.aria-controls]=\"'ts-body-members'\">\n        <span class=\"tin-disc\" [class.open]=\"!closed.members\"><mat-icon>chevron_right</mat-icon></span> <!-- Changed: leading rotated marker replaces the trailing swap -->\n        <mat-icon class=\"ts-icon\">group</mat-icon>\n        <span class=\"ts-label\">Members</span>\n        <span class=\"ts-summary\">{{ summary(counts.members, 'member', 'members') }}</span>\n      </button>\n      <!-- Requirement, owner 2026-08-12: unlike the Day Book, the description stays readable while the card\n           is SHUT — you should be able to tell what a section is for without having to open it first. -->\n      <p class=\"ts-why\">Invite other users to join your organisation as partners or employees to form a partnership or company.</p>\n      <div class=\"ts-body\" id=\"ts-body-members\">\n        <spa-table [config]=\"membersTableConfig\" [reload]=\"tableReload\" (totalChange)=\"counts.members = $event\"></spa-table>\n      </div>\n    </mat-card>\n\n    <!-- My Organisations -->\n    <mat-card class=\"ts-card\" [class.closed]=\"closed.orgs\">\n      <button type=\"button\" class=\"ts-chead tin-disc-row\" (click)=\"toggle('orgs')\" [attr.aria-expanded]=\"!closed.orgs\" [attr.aria-controls]=\"'ts-body-orgs'\">\n        <span class=\"tin-disc\" [class.open]=\"!closed.orgs\"><mat-icon>chevron_right</mat-icon></span> <!-- Changed: leading rotated marker replaces the trailing expand_more/expand_less swap -->\n        <mat-icon class=\"ts-icon\">apartment</mat-icon>\n        <span class=\"ts-label\">My Organisations</span>\n        <span class=\"ts-summary\">{{ summary(counts.orgs, 'organisation', 'organisations') }}</span>\n      </button>\n      <p class=\"ts-why\">Organisations that you are a member of.</p>\n      <div class=\"ts-body\" id=\"ts-body-orgs\">\n        <spa-table [config]=\"orgsTableConfig\" [reload]=\"orgsReload\" (actionResponse)=\"updateTenant($event)\" (totalChange)=\"counts.orgs = $event\"></spa-table>\n      </div>\n    </mat-card>\n\n    <!-- My Invitations -->\n    <mat-card class=\"ts-card\" [class.closed]=\"closed.invites\">\n      <button type=\"button\" class=\"ts-chead tin-disc-row\" (click)=\"toggle('invites')\" [attr.aria-expanded]=\"!closed.invites\" [attr.aria-controls]=\"'ts-body-invites'\">\n        <span class=\"tin-disc\" [class.open]=\"!closed.invites\"><mat-icon>chevron_right</mat-icon></span> <!-- Changed: leading rotated marker replaces the trailing expand_more/expand_less swap -->\n        <mat-icon class=\"ts-icon\">mark_email_unread</mat-icon>\n        <span class=\"ts-label\">My Invitations</span>\n        <span class=\"ts-summary\">{{ summary(counts.invites, 'invitation', 'invitations') }}</span>\n      </button>\n      <p class=\"ts-why\">Requests for you to join other organisations.</p>\n      <div class=\"ts-body\" id=\"ts-body-invites\">\n        <spa-invitations-table (totalChange)=\"counts.invites = $event\"></spa-invitations-table>\n      </div>\n    </mat-card>\n\n    <!-- Removed (2026-08-12, owner): the \"Billing and Subscription\" block. It was a placeholder — a plan\n         name, a plan price and a due date HARDCODED to \"2024-01-01\" — and it has been superseded by the\n         real pages already routed at tenancy/billing and tenancy/subscription. -->\n\n    <!-- Email Configuration. Deliberately left exactly where it is (owner, 2026-08-12: app configuration is\n         per-application, so this stays on the organisation page for now). Only the card treatment changed. -->\n    <mat-card class=\"ts-card\" [class.closed]=\"closed.email\">\n      <button type=\"button\" class=\"ts-chead tin-disc-row\" (click)=\"toggle('email')\" [attr.aria-expanded]=\"!closed.email\" [attr.aria-controls]=\"'ts-body-email'\">\n        <span class=\"tin-disc\" [class.open]=\"!closed.email\"><mat-icon>chevron_right</mat-icon></span> <!-- Changed: leading rotated marker replaces the trailing expand_more/expand_less swap -->\n        <mat-icon class=\"ts-icon\">mail</mat-icon>\n        <span class=\"ts-label\">Email Configuration</span>\n        <span class=\"ts-summary\">{{ emailSummary(counts.email) }}</span>\n      </button>\n      <p class=\"ts-why\">Configure email settings for sending notifications.</p>\n      <div class=\"ts-body\" id=\"ts-body-email\">\n        <spa-table [config]=\"mailerTableConfig\" (totalChange)=\"counts.email = $event\"></spa-table>\n      </div>\n    </mat-card>\n\n  </ng-container>\n\n</div>\n","import { Component, inject } from '@angular/core';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { FormConfig, TableConfig, PageConfig } from '../../classes/Classes';\nimport { MessageService } from '../../services/message.service';\nimport { AuthService } from '../../services/auth.service';\n\n\n@Component({\n    selector: 'spa-tenants',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class TenantsComponent {\n  private dataService = inject(DataServiceLib);\n  private messageService = inject(MessageService);\n  private authService = inject(AuthService);\n\n  tenantFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capTenants] }, // Added: gate tenant form by tenants cap\n\n    fields: [\n      { name: 'name', type: 'text', required: true, min: 2 },\n      { name: 'planID', alias :'Plan', type: 'number', required: true },\n    ],\n\n    reset: true,\n\n  }\n\n  tenantsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name'],\n    flatButtons: true,\n\n    columns: [\n      { name: 'tenantID', type: 'number', alias: 'ID' },\n      { name: 'name', type: 'text' },\n      { name: 'planName', alias : 'Plan', type: 'text' },\n\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'tenants?action=create', method: 'post' }},\n      { name: 'view', dialog: true },\n      { name: 'edit', dialog: true, action: { url: 'tenants?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'tenants?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'tenants/all_tenants/x' },\n\n    formConfig: this.tenantFormConfig\n\n  }\n  \n  pageConfig: PageConfig = {\n    title: 'Tenants',\n    tableConfig: this.tenantsTableConfig\n  };\n}\n","import { Component, OnInit } from '@angular/core';\n\n@Component({\n    selector: 'spa-bug',\n    templateUrl: './bug.component.html',\n    styleUrls: ['./bug.component.css'],\n    standalone: false\n})\nexport class BugComponent implements OnInit {\n\n  constructor() { }\n\n  ngOnInit(): void {\n  }\n\n}\n","<p>Report a fault</p>\n","import { Component, inject } from '@angular/core';\nimport { FormConfig, TableConfig, PageConfig } from '../../classes/Classes';\nimport { AuthService } from '../../services/auth.service';\nimport { DataServiceLib } from '../../services/datalib.service'; // Added: for capability references\n\n\n@Component({\n    selector: 'spa-membership',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class MembershipComponent {\n  private authService = inject(AuthService);\n  private dataService = inject(DataServiceLib); // Added: for capability references\n\n  formConfig: FormConfig = {\n    security: { allow: [this.dataService.capMembership] }, // Added: gate membership form by membership cap\n\n    fields: [\n      { name: 'tenantName', type: 'text', required: true, readonly: true },\n      { name: 'memberName', type: 'text', required: true, min: 2, readonly: true },\n\n    ],\n\n    reset: true,\n  }\n\n  membersTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['memberName','tenantName', 'roleName'],\n    flatButtons: true,\n\n    columns: [\n      { name: 'tenantName', type: 'text' },\n      { name: 'memberName', type: 'text' },\n      { name: 'roleName', type: 'text' },\n      { name: 'status', type: 'text' },\n    ],\n\n    buttons: [\n      // { name: 'create', display: 'Create', dialog: true, action: { url: 'members?action=create', method: 'post' } },\n      { name: 'view', dialog: true },\n      { name: 'edit', dialog: true, action: { url: 'members?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'members?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'members/every/x' },\n\n    formConfig: this.formConfig\n  }\n  \n  pageConfig: PageConfig = {\n    title: 'Membership',\n    tableConfig: this.membersTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { FormConfig, TableConfig, PageConfig } from '../../classes/Classes';\nimport { AuthService } from '../../services/auth.service';\nimport { DataServiceLib } from '../../services/datalib.service'; // Added: for capability references\n\n\n@Component({\n    selector: 'spa-plans',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class PlansComponent {\n  private authService = inject(AuthService);\n  private dataService = inject(DataServiceLib); // Added: for capability references\n\n  formConfig: FormConfig = {\n    security: { allow: [this.dataService.capPlans] }, // Added: gate plan form by plans cap\n\n    fields: [\n      { name: 'name', type: 'text', required: true, min: 2, span: true },\n      { name: 'description', type: 'text', required: true, min: 2, span: true },\n      { name: 'price', type: 'money', required: true, span: true },\n      { name: 'billingCycle', alias: 'Billing Cycle', type: 'select', required: true, span: true, options: [{ value: 0, display: 'Monthly' }, { value: 1, display: 'Annual' }] }, // Added: billing period\n\n      // Changed: sectioned — what the plan is and what it costs stays up top; the limits and listing controls\n      // are set once and fold away on an existing plan\n      { name: 'planLimits', type: 'section', alias: 'Limits & Listing', collapseOnView: true },\n      { name: 'trialDays', alias: 'Trial Days', type: 'number', span: true, section: 'planLimits' }, // Added: free trial length\n      { name: 'maxUsers', alias: 'Max Users', type: 'number', span: true, section: 'planLimits' }, // Added: user count limit (0 = unlimited)\n      { name: 'isActive', alias: 'Active', type: 'checkbox', span: true, section: 'planLimits' }, // Added: plan visibility toggle\n      { name: 'sortOrder', alias: 'Sort Order', type: 'number', span: true, section: 'planLimits' }, // Added: display ordering\n    ],\n\n    reset: true,\n  }\n\n  plansTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name'],\n    flatButtons: true,\n\n    columns: [\n      { name: 'planID', type: 'text' },\n      { name: 'name', type: 'text' },\n      { name: 'price', type: 'money' },\n      { name: 'billingCycle', alias: 'Billing', type: 'text', options: [{ value: 0, display: 'Monthly' }, { value: 1, display: 'Annual' }] }, // Added: billing period column\n      { name: 'trialDays', alias: 'Trial Days', type: 'text' }, // Added: trial days column\n      { name: 'maxUsers', alias: 'Max Users', type: 'text' }, // Added: user limit column\n      { name: 'isActive', alias: 'Active', type: 'checkbox' }, // Added: active status column\n      { name: 'sortOrder', alias: 'Order', type: 'text' }, // Added: sort order column\n      { name: 'featureCount', alias: 'Features', type: 'text' }, // Added: enabled feature count\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'plans?action=create', method: 'post' } },\n      { name: 'view', dialog: true },\n      { name: 'edit', dialog: true, action: { url: 'plans?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'plans?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'plans/all/x' },\n\n    formConfig: this.formConfig\n\n  }\n  \n  pageConfig: PageConfig = {\n    title: 'Plans',\n    tableConfig: this.plansTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { FormConfig, TableConfig, PageConfig } from '../../classes/Classes';\nimport { AuthService } from '../../services/auth.service';\nimport { DataServiceLib } from '../../services/datalib.service'; // Added: for capability references\n\n// Feature registry admin component — CRUD for master feature list (admin-only, TenantID=1)\n@Component({\n    selector: 'spa-features',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class FeaturesComponent {\n  private authService = inject(AuthService);\n  private dataService = inject(DataServiceLib); // Added: for capability references\n\n  formConfig: FormConfig = {\n    security: { allow: [this.dataService.capFeatures] }, // Added: gate feature form by features cap\n\n    fields: [\n      { name: 'featureKey', alias: 'Feature Key', type: 'text', required: true, min: 2, span: true },\n      { name: 'name', type: 'text', required: true, min: 2, span: true },\n      { name: 'description', type: 'text', required: true, min: 2, span: true },\n      { name: 'featureType', alias: 'Feature Type', type: 'select', required: true, span: true, options: [{ value: 0, display: 'Module' }, { value: 1, display: 'Feature' }] },\n      { name: 'moduleCapName', alias: 'Module Cap Name', type: 'text', span: true },\n    ],\n\n    reset: true,\n  }\n\n  featuresTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['name', 'featureKey'],\n    flatButtons: true,\n\n    columns: [\n      { name: 'featureID', alias: 'ID', type: 'text' },\n      { name: 'featureKey', alias: 'Feature Key', type: 'text' },\n      { name: 'name', type: 'text' },\n      { name: 'description', type: 'text' },\n      { name: 'featureType', alias: 'Type', type: 'text', options: [{ value: 0, display: 'Module' }, { value: 1, display: 'Feature' }] },\n      { name: 'moduleCapName', alias: 'Cap Name', type: 'text' },\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'features?action=create', method: 'post' } },\n      { name: 'view', dialog: true },\n      { name: 'edit', dialog: true, action: { url: 'features?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'features?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'features/all/x' },\n\n    formConfig: this.formConfig\n\n  }\n\n  pageConfig: PageConfig = {\n    title: 'Features',\n    tableConfig: this.featuresTableConfig\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { FormConfig, TableConfig, PageConfig } from '../../classes/Classes';\nimport { AuthService } from '../../services/auth.service';\nimport { DataServiceLib } from '../../services/datalib.service'; // Added: for capability references\n\n// Plan-Feature mapping admin component — manage which features are enabled per plan (admin-only, TenantID=1)\n@Component({\n    selector: 'spa-plan-features',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class PlanFeaturesComponent {\n  private authService = inject(AuthService);\n  private dataService = inject(DataServiceLib); // Added: for capability references\n\n  formConfig: FormConfig = {\n    security: { allow: [this.dataService.capPlanFeatures] }, // Added: gate plan-feature form by plan features cap\n\n    fields: [\n      { name: 'planID', alias: 'Plan', type: 'select', required: true, span: true, loadAction: { url: 'plans/list/x' } },\n      { name: 'featureID', alias: 'Feature', type: 'select', required: true, span: true, loadAction: { url: 'features/list/x' } },\n      { name: 'enabled', type: 'checkbox', span: true },\n      { name: 'limit', type: 'number', span: true },\n    ],\n\n    reset: true,\n  }\n\n  planFeaturesTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['planName', 'featureName'],\n    flatButtons: true,\n\n    columns: [\n      { name: 'planFeatureID', alias: 'ID', type: 'text' },\n      { name: 'planName', alias: 'Plan', type: 'text' },\n      { name: 'featureName', alias: 'Feature', type: 'text' },\n      { name: 'featureKey', alias: 'Feature Key', type: 'text' },\n      { name: 'featureType', alias: 'Type', type: 'text', options: [{ value: 0, display: 'Module' }, { value: 1, display: 'Feature' }] },\n      { name: 'enabled', type: 'checkbox' },\n      { name: 'limit', type: 'text' },\n    ],\n\n    buttons: [\n      { name: 'create', display: 'Create', dialog: true, action: { url: 'planfeatures?action=create', method: 'post' } },\n      { name: 'view', dialog: true },\n      { name: 'edit', dialog: true, action: { url: 'planfeatures?action=edit', method: 'post' } },\n      { name: 'delete', dialog: true, action: { url: 'planfeatures?action=delete', method: 'post' } },\n    ],\n\n    loadAction: { url: 'planfeatures/all/x' },\n\n    formConfig: this.formConfig\n\n  }\n\n  pageConfig: PageConfig = {\n    title: 'Plan Features',\n    tableConfig: this.planFeaturesTableConfig\n  };\n}\n","// Subscription management page — current plan display, plan comparison, upgrade/downgrade\nimport { Component, OnInit } from '@angular/core';\nimport { HttpService } from '../../services/http.service';\nimport { SubscriptionService } from '../../services/subscription.service';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: two silent loads and one raw-text snackbar on the plan-change path (WS-6 Phase 4)\n\n@Component({\n  selector: 'spa-subscription',\n  template: `\n    <div class=\"subscription-container\">\n      <h4 class=\"page-title\"><mat-icon>card_membership</mat-icon> Subscription</h4>\n\n      <!-- Current Plan Card -->\n      <mat-card class=\"current-plan-card\" *ngIf=\"currentSubscription\">\n        <mat-card-header>\n          <mat-icon mat-card-avatar class=\"plan-avatar\">verified</mat-icon>\n          <mat-card-title>{{ currentSubscription.planName || 'No Plan' }}</mat-card-title>\n          <mat-card-subtitle>\n            <span class=\"status-badge\" [ngClass]=\"'status-' + (currentSubscription.status || 0)\">\n              {{ getStatusLabel(currentSubscription.status) }}\n            </span>\n          </mat-card-subtitle>\n        </mat-card-header>\n        <mat-card-content>\n          <div class=\"plan-details\">\n            <div class=\"detail-item\">\n              <span class=\"detail-label\">Price</span>\n              <span class=\"detail-value\">\\${{ currentSubscription.planPrice | number:'1.2-2' }}/{{ currentSubscription.planBillingCycle === 1 ? 'year' : 'month' }}</span>\n            </div>\n            <div class=\"detail-item\">\n              <span class=\"detail-label\">Start Date</span>\n              <span class=\"detail-value\">{{ currentSubscription.startDate | date:'mediumDate' }}</span>\n            </div>\n            <div class=\"detail-item\">\n              <span class=\"detail-label\">End Date</span>\n              <span class=\"detail-value\">{{ currentSubscription.endDate | date:'mediumDate' }}</span>\n            </div>\n            <div class=\"detail-item\" *ngIf=\"currentSubscription.trialEndDate\">\n              <span class=\"detail-label\">Trial Ends</span>\n              <span class=\"detail-value\">{{ currentSubscription.trialEndDate | date:'mediumDate' }}</span>\n            </div>\n          </div>\n        </mat-card-content>\n      </mat-card>\n\n      <!-- No Subscription Message -->\n      <mat-card class=\"current-plan-card\" *ngIf=\"!currentSubscription && !loading\">\n        <mat-card-content>\n          <p class=\"no-plan-message\"><mat-icon>info</mat-icon> No active subscription. Choose a plan below to get started.</p>\n        </mat-card-content>\n      </mat-card>\n\n      <!-- Plan Comparison Grid -->\n      <h5 class=\"section-title\">Available Plans</h5>\n      <div class=\"plans-grid\">\n        <mat-card *ngFor=\"let plan of availablePlans\" class=\"plan-card\" [ngClass]=\"{'current': plan.planID === currentSubscription?.planID}\">\n          <mat-card-header>\n            <mat-card-title>{{ plan.name }}</mat-card-title>\n            <mat-card-subtitle>{{ plan.description }}</mat-card-subtitle>\n          </mat-card-header>\n          <mat-card-content>\n            <div class=\"plan-price\">\n              <span class=\"price-amount\">\\${{ plan.price | number:'1.2-2' }}</span>\n              <span class=\"price-period\">/{{ plan.billingCycle === 1 ? 'year' : 'month' }}</span>\n            </div>\n            <div class=\"plan-limits\">\n              <div class=\"limit-item\">\n                <mat-icon>group</mat-icon>\n                <span>{{ plan.maxUsers === 0 ? 'Unlimited' : plan.maxUsers }} users</span>\n              </div>\n              <div class=\"limit-item\" *ngIf=\"plan.trialDays > 0\">\n                <mat-icon>schedule</mat-icon>\n                <span>{{ plan.trialDays }}-day free trial</span>\n              </div>\n            </div>\n            <mat-divider></mat-divider>\n            <div class=\"feature-list\">\n              <div *ngFor=\"let feature of plan.features\" class=\"feature-item\">\n                <mat-icon class=\"feature-check\">check_circle</mat-icon>\n                <span>{{ feature.name }}</span>\n                <span class=\"feature-limit\" *ngIf=\"feature.limit > 0\">(limit: {{ feature.limit }})</span>\n              </div>\n              <div *ngIf=\"!plan.features || plan.features.length === 0\" class=\"no-features\">\n                <mat-icon>info_outline</mat-icon> No features configured\n              </div>\n            </div>\n          </mat-card-content>\n          <mat-card-actions>\n            <button mat-raised-button *ngIf=\"plan.planID === currentSubscription?.planID\" disabled color=\"primary\">\n              <mat-icon>check</mat-icon> Current Plan\n            </button>\n            <button mat-raised-button *ngIf=\"plan.planID !== currentSubscription?.planID\" color=\"accent\" (click)=\"confirmChangePlan(plan)\">\n              <mat-icon>{{ isPlanUpgrade(plan) ? 'upgrade' : 'arrow_downward' }}</mat-icon>\n              {{ isPlanUpgrade(plan) ? 'Upgrade' : 'Switch' }}\n            </button>\n          </mat-card-actions>\n        </mat-card>\n      </div>\n\n      <!-- Confirmation Dialog (inline) -->\n      <div class=\"overlay\" *ngIf=\"showConfirmation\" (click)=\"cancelChange()\">\n        <mat-card class=\"confirm-dialog\" (click)=\"$event.stopPropagation()\">\n          <mat-card-header>\n            <mat-card-title>Confirm Plan Change</mat-card-title>\n          </mat-card-header>\n          <mat-card-content>\n            <p>Are you sure you want to {{ isPlanUpgrade(selectedPlan) ? 'upgrade' : 'switch' }} to the <strong>{{ selectedPlan?.name }}</strong> plan?</p>\n            <p class=\"price-info\">Price: <strong>\\${{ selectedPlan?.price | number:'1.2-2' }}/{{ selectedPlan?.billingCycle === 1 ? 'year' : 'month' }}</strong></p>\n            <p *ngIf=\"selectedPlan?.trialDays > 0\" class=\"trial-info\">\n              <mat-icon>schedule</mat-icon> Includes {{ selectedPlan?.trialDays }}-day free trial\n            </p>\n          </mat-card-content>\n          <mat-card-actions align=\"end\">\n            <button mat-button (click)=\"cancelChange()\">Cancel</button>\n            <button mat-raised-button color=\"primary\" (click)=\"executePlanChange()\" [disabled]=\"changingPlan\">\n              <mat-icon *ngIf=\"changingPlan\">hourglass_empty</mat-icon>\n              {{ changingPlan ? 'Processing...' : 'Confirm' }}\n            </button>\n          </mat-card-actions>\n        </mat-card>\n      </div>\n    </div>\n  `,\n  styles: [`\n    .subscription-container { padding: 16px; max-width: 1200px; }\n    .page-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n    .section-title { margin: 24px 0 16px; color: #555; }\n\n    .current-plan-card { margin-bottom: 24px; }\n    .plan-avatar { font-size: 40px; width: 40px; height: 40px; color: #1976d2; }\n    .plan-details { display: flex; gap: 32px; flex-wrap: wrap; padding: 8px 0; }\n    .detail-item { display: flex; flex-direction: column; }\n    .detail-label { font-size: 12px; color: #888; text-transform: uppercase; }\n    .detail-value { font-size: 16px; font-weight: 500; }\n\n    .status-badge { padding: 2px 10px; border-radius: 12px; font-size: 12px; font-weight: 500; }\n    .status-0 { background: #e3f2fd; color: #1565c0; } /* Trial */\n    .status-1 { background: #e8f5e9; color: #2e7d32; } /* Active */\n    .status-2 { background: #fff3e0; color: #e65100; } /* PastDue */\n    .status-3 { background: #fce4ec; color: #c62828; } /* Cancelled */\n    .status-4 { background: #f5f5f5; color: #616161; } /* Expired */\n\n    .no-plan-message { display: flex; align-items: center; gap: 8px; color: #666; margin: 0; }\n\n    .plans-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }\n    .plan-card { display: flex; flex-direction: column; }\n    .plan-card.current { border: 2px solid #1976d2; }\n    .plan-price { text-align: center; padding: 16px 0; }\n    .price-amount { font-size: 32px; font-weight: 700; color: #1976d2; }\n    .price-period { font-size: 14px; color: #888; }\n\n    .plan-limits { display: flex; gap: 16px; justify-content: center; padding-bottom: 12px; }\n    .limit-item { display: flex; align-items: center; gap: 4px; font-size: 13px; color: #666; }\n    .limit-item mat-icon { font-size: 18px; width: 18px; height: 18px; }\n\n    .feature-list { padding: 12px 0; }\n    .feature-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 14px; }\n    .feature-check { color: #4caf50; font-size: 18px; width: 18px; height: 18px; }\n    .feature-limit { font-size: 12px; color: #999; }\n    .no-features { display: flex; align-items: center; gap: 4px; color: #999; font-size: 13px; }\n\n    mat-card-actions { margin-top: auto; }\n    mat-card-actions button { width: 100%; }\n\n    .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 1000; }\n    .confirm-dialog { max-width: 440px; width: 90%; }\n    .price-info { font-size: 16px; }\n    .trial-info { display: flex; align-items: center; gap: 4px; color: #1976d2; font-size: 14px; }\n  `],\n  standalone: false\n})\nexport class SubscriptionPageComponent implements OnInit {\n\n  currentSubscription: any = null;\n  availablePlans: any[] = [];\n  loading = true;\n  showConfirmation = false;\n  selectedPlan: any = null;\n  changingPlan = false;\n\n  constructor(\n    private httpService: HttpService,\n    private subscriptionService: SubscriptionService,\n    private snackBar: MatSnackBar,\n    private apiErrorService: ApiErrorService // Changed: injected so a failed load or plan change is classified rather than swallowed or echoed\n  ) { }\n\n  ngOnInit() {\n    this.loadCurrentSubscription();\n    this.loadAvailablePlans();\n  }\n\n  // Load the current tenant's active subscription\n  loadCurrentSubscription() {\n    this.httpService.Get('subscriptions/current').subscribe({\n      next: (response: any) => {\n        if (response?.success) {\n          this.currentSubscription = response.data;\n        } else {\n          this.apiErrorService.presentAppFailure(response, 'load', 'subscriptions/current'); // Added: was silent — the \"your current plan\" panel stayed blank, and a user comparing plans could not tell which one they were already on\n        }\n        this.loading = false;\n      },\n      error: () => { this.loading = false; }\n    });\n  }\n\n  // Load all available plans with their features\n  loadAvailablePlans() {\n    this.httpService.Get('subscriptions/plans').subscribe({\n      next: (response: any) => {\n        if (response?.success) {\n          this.availablePlans = response.data || [];\n        } else {\n          this.apiErrorService.presentAppFailure(response, 'load', 'subscriptions/plans'); // Added: was silent. A plan-comparison page with no plans on it reads as \"there is nothing to upgrade to\", which is a commercially wrong thing to tell someone by accident\n        }\n      }\n    });\n  }\n\n  // Get human-readable subscription status label\n  getStatusLabel(status: number): string {\n    const labels: Record<number, string> = { 0: 'Trial', 1: 'Active', 2: 'Past Due', 3: 'Cancelled', 4: 'Expired' };\n    return labels[status] || 'Unknown';\n  }\n\n  // Check if the target plan is an upgrade (higher price)\n  isPlanUpgrade(plan: any): boolean {\n    if (!this.currentSubscription) return true;\n    return (plan?.price || 0) > (this.currentSubscription?.planPrice || 0);\n  }\n\n  // Show confirmation dialog for plan change\n  confirmChangePlan(plan: any) {\n    this.selectedPlan = plan;\n    this.showConfirmation = true;\n  }\n\n  // Cancel the plan change dialog\n  cancelChange() {\n    this.showConfirmation = false;\n    this.selectedPlan = null;\n  }\n\n  // Execute the plan change via API\n  executePlanChange() {\n    if (!this.selectedPlan) return;\n    this.changingPlan = true;\n\n    this.httpService.Post('subscriptions/change', { planID: this.selectedPlan.planID }).subscribe({\n      next: (response: any) => {\n        this.changingPlan = false;\n        this.showConfirmation = false;\n        if (response?.success) {\n          this.snackBar.open('Plan changed successfully', '', { duration: 3000 });\n          this.loadCurrentSubscription(); // Refresh current subscription\n          this.subscriptionService.loadFeatures(); // Refresh enabled features for UI gating\n        } else {\n          this.apiErrorService.presentAppFailure(response, 'action', 'subscriptions/change'); // Changed: was a bare MatSnackBar carrying response.message verbatim for 3 seconds. 'action' rather than 'submit' — this sits behind a confirmation panel with nothing typed into it, so the 'submit' wording about a still-populated form would not be true\n        }\n      },\n      error: () => {\n        this.changingPlan = false;\n        this.snackBar.open('Failed to change plan', '', { duration: 3000 });\n      }\n    });\n  }\n}\n","// Billing page — invoice history table, invoice detail dialog, and payment flow dialog\nimport { Component, OnInit } from '@angular/core';\nimport { HttpService } from '../../services/http.service';\nimport { MatSnackBar } from '@angular/material/snack-bar';\nimport { ApiErrorService } from '../../services/api-error.service'; // Added: this page had four unhandled `success` checks, two of them on a money path (WS-6 Phase 4)\n\n@Component({\n  selector: 'spa-billing',\n  template: `\n    <div class=\"billing-container\">\n      <h4 class=\"page-title\"><mat-icon>receipt_long</mat-icon> Billing & Invoices</h4>\n\n      <!-- Current Subscription Summary -->\n      <mat-card class=\"summary-card\" *ngIf=\"currentSubscription\">\n        <mat-card-content>\n          <div class=\"summary-row\">\n            <div class=\"summary-item\">\n              <span class=\"summary-label\">Current Plan</span>\n              <span class=\"summary-value\">{{ currentSubscription.planName || 'No Plan' }}</span>\n            </div>\n            <div class=\"summary-item\">\n              <span class=\"summary-label\">Status</span>\n              <span class=\"status-badge\" [ngClass]=\"'status-' + (currentSubscription.status || 0)\">\n                {{ getStatusLabel(currentSubscription.status) }}\n              </span>\n            </div>\n            <div class=\"summary-item\">\n              <span class=\"summary-label\">Next Billing</span>\n              <span class=\"summary-value\">{{ currentSubscription.endDate | date:'mediumDate' }}</span>\n            </div>\n          </div>\n        </mat-card-content>\n      </mat-card>\n\n      <!-- Invoice History Table -->\n      <mat-card class=\"invoices-card\">\n        <mat-card-header>\n          <mat-card-title>Invoice History</mat-card-title>\n        </mat-card-header>\n        <mat-card-content>\n          <div class=\"table-container\" *ngIf=\"invoices.length > 0\">\n            <table class=\"invoice-table\">\n              <thead>\n                <tr>\n                  <th>Date</th>\n                  <th>Description</th>\n                  <th>Amount</th>\n                  <th>Status</th>\n                  <th>Payment Method</th>\n                  <th>Actions</th>\n                </tr>\n              </thead>\n              <tbody>\n                <tr *ngFor=\"let invoice of invoices\">\n                  <td>{{ invoice.invoiceDate | date:'mediumDate' }}</td>\n                  <td>{{ invoice.description || invoice.planName + ' Subscription' }}</td>\n                  <td>{{ invoice.currency }} {{ invoice.amount | number:'1.2-2' }}</td>\n                  <td>\n                    <span class=\"invoice-status\" [ngClass]=\"'inv-status-' + invoice.status\">\n                      {{ getInvoiceStatusLabel(invoice.status) }}\n                    </span>\n                  </td>\n                  <td>{{ invoice.paymentMethod || '-' }}</td>\n                  <td>\n                    <button mat-icon-button (click)=\"viewInvoiceDetail(invoice)\" matTooltip=\"View Details\">\n                      <mat-icon>launch</mat-icon><!-- Changed: 'visibility' (eye) -> 'launch'. This opens the invoice detail, so it is a view action and must carry the same icon as every other view in the estate -->\n                    </button>\n                    <button mat-icon-button *ngIf=\"invoice.status === 0\" (click)=\"initiatePayment(invoice)\" matTooltip=\"Pay Now\" color=\"primary\">\n                      <mat-icon>payment</mat-icon>\n                    </button>\n                  </td>\n                </tr>\n              </tbody>\n            </table>\n          </div>\n          <div class=\"empty-state\" *ngIf=\"invoices.length === 0 && !loading\">\n            <mat-icon>receipt</mat-icon>\n            <p>No invoices yet</p>\n          </div>\n          <div class=\"loading-state\" *ngIf=\"loading\">\n            <mat-spinner diameter=\"32\"></mat-spinner>\n            <p>Loading invoices...</p>\n          </div>\n        </mat-card-content>\n      </mat-card>\n\n      <!-- Invoice Detail Dialog (inline overlay) -->\n      <div class=\"overlay\" *ngIf=\"showDetail\" (click)=\"closeDetail()\">\n        <mat-card class=\"detail-dialog\" (click)=\"$event.stopPropagation()\">\n          <mat-card-header>\n            <mat-card-title>Invoice Detail</mat-card-title>\n            <button mat-icon-button class=\"close-btn\" (click)=\"closeDetail()\">\n              <mat-icon>close</mat-icon>\n            </button>\n          </mat-card-header>\n          <mat-card-content *ngIf=\"selectedInvoice\">\n            <div class=\"detail-grid\">\n              <div class=\"detail-field\">\n                <span class=\"field-label\">Plan</span>\n                <span class=\"field-value\">{{ selectedInvoice.planName }}</span>\n              </div>\n              <div class=\"detail-field\">\n                <span class=\"field-label\">Amount</span>\n                <span class=\"field-value\">{{ selectedInvoice.currency }} {{ selectedInvoice.amount | number:'1.2-2' }}</span>\n              </div>\n              <div class=\"detail-field\">\n                <span class=\"field-label\">Status</span>\n                <span class=\"invoice-status\" [ngClass]=\"'inv-status-' + selectedInvoice.status\">\n                  {{ getInvoiceStatusLabel(selectedInvoice.status) }}\n                </span>\n              </div>\n              <div class=\"detail-field\">\n                <span class=\"field-label\">Invoice Date</span>\n                <span class=\"field-value\">{{ selectedInvoice.invoiceDate | date:'medium' }}</span>\n              </div>\n              <div class=\"detail-field\" *ngIf=\"selectedInvoice.paidDate\">\n                <span class=\"field-label\">Paid Date</span>\n                <span class=\"field-value\">{{ selectedInvoice.paidDate | date:'medium' }}</span>\n              </div>\n              <div class=\"detail-field\" *ngIf=\"selectedInvoice.paymentReference\">\n                <span class=\"field-label\">Payment Reference</span>\n                <span class=\"field-value\">{{ selectedInvoice.paymentReference }}</span>\n              </div>\n              <div class=\"detail-field\" *ngIf=\"selectedInvoice.paymentMethod\">\n                <span class=\"field-label\">Payment Method</span>\n                <span class=\"field-value\">{{ selectedInvoice.paymentMethod }}</span>\n              </div>\n            </div>\n\n            <!-- Payment Transaction Audit Trail -->\n            <div class=\"transactions-section\" *ngIf=\"selectedInvoice.transactions?.length > 0\">\n              <h5>Payment Transactions</h5>\n              <table class=\"transaction-table\">\n                <thead>\n                  <tr>\n                    <th>Date</th>\n                    <th>Reference</th>\n                    <th>Amount</th>\n                    <th>Status</th>\n                  </tr>\n                </thead>\n                <tbody>\n                  <tr *ngFor=\"let txn of selectedInvoice.transactions\">\n                    <td>{{ txn.createdDate | date:'medium' }}</td>\n                    <td>{{ txn.gatewayReference || '-' }}</td>\n                    <td>{{ txn.currency }} {{ txn.amount | number:'1.2-2' }}</td>\n                    <td>\n                      <span class=\"txn-status\" [ngClass]=\"'txn-status-' + txn.status\">\n                        {{ getPaymentStatusLabel(txn.status) }}\n                      </span>\n                    </td>\n                  </tr>\n                </tbody>\n              </table>\n            </div>\n            <div class=\"transactions-section\" *ngIf=\"!selectedInvoice.transactions || selectedInvoice.transactions.length === 0\">\n              <h5>Payment Transactions</h5>\n              <p class=\"no-transactions\">No payment transactions recorded</p>\n            </div>\n          </mat-card-content>\n        </mat-card>\n      </div>\n\n      <!-- Payment Flow Dialog (inline overlay) -->\n      <div class=\"overlay\" *ngIf=\"showPayment\" (click)=\"closePayment()\">\n        <mat-card class=\"payment-dialog\" (click)=\"$event.stopPropagation()\">\n          <mat-card-header>\n            <mat-card-title>Process Payment</mat-card-title>\n          </mat-card-header>\n          <mat-card-content *ngIf=\"paymentInvoice\">\n            <div class=\"payment-summary\">\n              <p>Plan: <strong>{{ paymentInvoice.planName }}</strong></p>\n              <p>Amount: <strong>{{ paymentInvoice.currency }} {{ paymentInvoice.amount | number:'1.2-2' }}</strong></p>\n            </div>\n\n            <!-- Payment processing state -->\n            <div class=\"payment-state\" *ngIf=\"paymentProcessing\">\n              <mat-spinner diameter=\"40\"></mat-spinner>\n              <p>Processing payment...</p>\n            </div>\n\n            <!-- Payment success state -->\n            <div class=\"payment-state success\" *ngIf=\"paymentResult?.success\">\n              <mat-icon class=\"result-icon success-icon\">check_circle</mat-icon>\n              <p>Payment completed successfully!</p>\n              <p class=\"payment-ref\" *ngIf=\"paymentResult.reference\">Reference: {{ paymentResult.reference }}</p>\n            </div>\n\n            <!-- Payment redirect state (live mode) -->\n            <div class=\"payment-state redirect\" *ngIf=\"paymentResult && !paymentResult.success && paymentResult.redirectUrl\">\n              <mat-icon class=\"result-icon redirect-icon\">open_in_new</mat-icon>\n              <p>You will be redirected to complete payment</p>\n              <a mat-raised-button color=\"primary\" [href]=\"paymentResult.redirectUrl\" target=\"_blank\">\n                <mat-icon>payment</mat-icon> Complete Payment\n              </a>\n            </div>\n\n            <!-- Payment failure state -->\n            <div class=\"payment-state error\" *ngIf=\"paymentResult && !paymentResult.success && !paymentResult.redirectUrl\">\n              <mat-icon class=\"result-icon error-icon\">error</mat-icon>\n              <p>{{ paymentResult.message || 'Payment failed. Please try again.' }}</p>\n            </div>\n          </mat-card-content>\n          <mat-card-actions align=\"end\">\n            <button mat-button (click)=\"closePayment()\">{{ paymentResult?.success ? 'Done' : 'Cancel' }}</button>\n            <button mat-raised-button color=\"primary\" *ngIf=\"!paymentProcessing && !paymentResult\" (click)=\"processPayment()\">\n              <mat-icon>payment</mat-icon> Pay Now\n            </button>\n          </mat-card-actions>\n        </mat-card>\n      </div>\n    </div>\n  `,\n  styles: [`\n    .billing-container { padding: 16px; max-width: 1200px; }\n    .page-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n\n    .summary-card { margin-bottom: 24px; }\n    .summary-row { display: flex; gap: 32px; flex-wrap: wrap; }\n    .summary-item { display: flex; flex-direction: column; }\n    .summary-label { font-size: 12px; color: #888; text-transform: uppercase; }\n    .summary-value { font-size: 16px; font-weight: 500; }\n\n    .status-badge { padding: 2px 10px; border-radius: 12px; font-size: 12px; font-weight: 500; }\n    .status-0 { background: #e3f2fd; color: #1565c0; }\n    .status-1 { background: #e8f5e9; color: #2e7d32; }\n    .status-2 { background: #fff3e0; color: #e65100; }\n    .status-3 { background: #fce4ec; color: #c62828; }\n    .status-4 { background: #f5f5f5; color: #616161; }\n\n    .invoices-card { margin-bottom: 24px; }\n    .table-container { overflow-x: auto; }\n    .invoice-table, .transaction-table { width: 100%; border-collapse: collapse; }\n    .invoice-table th, .invoice-table td,\n    .transaction-table th, .transaction-table td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #e0e0e0; font-size: 14px; }\n    .invoice-table th, .transaction-table th { font-weight: 500; color: #666; font-size: 12px; text-transform: uppercase; }\n    .invoice-table tbody tr:hover { background: #f5f5f5; }\n\n    .invoice-status { padding: 2px 8px; border-radius: 10px; font-size: 12px; font-weight: 500; }\n    .inv-status-0 { background: #fff3e0; color: #e65100; } /* Pending */\n    .inv-status-1 { background: #e8f5e9; color: #2e7d32; } /* Paid */\n    .inv-status-2 { background: #fce4ec; color: #c62828; } /* Failed */\n    .inv-status-3 { background: #f3e5f5; color: #6a1b9a; } /* Refunded */\n\n    .txn-status { padding: 2px 8px; border-radius: 10px; font-size: 12px; font-weight: 500; }\n    .txn-status-0 { background: #e3f2fd; color: #1565c0; } /* Initiated */\n    .txn-status-1 { background: #fff3e0; color: #e65100; } /* Pending */\n    .txn-status-2 { background: #e8f5e9; color: #2e7d32; } /* Success */\n    .txn-status-3 { background: #fce4ec; color: #c62828; } /* Failed */\n    .txn-status-4 { background: #f5f5f5; color: #616161; } /* Cancelled */\n\n    .empty-state, .loading-state { display: flex; flex-direction: column; align-items: center; padding: 32px; color: #999; }\n    .empty-state mat-icon { font-size: 48px; width: 48px; height: 48px; margin-bottom: 8px; }\n\n    .overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 1000; }\n    .detail-dialog { max-width: 640px; width: 90%; max-height: 80vh; overflow-y: auto; }\n    .payment-dialog { max-width: 440px; width: 90%; }\n\n    .close-btn { position: absolute; top: 8px; right: 8px; }\n\n    .detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 16px; }\n    .detail-field { display: flex; flex-direction: column; }\n    .field-label { font-size: 12px; color: #888; text-transform: uppercase; }\n    .field-value { font-size: 14px; font-weight: 500; }\n\n    .transactions-section { margin-top: 16px; }\n    .transactions-section h5 { margin: 0 0 8px; color: #555; }\n    .no-transactions { color: #999; font-size: 13px; }\n\n    .payment-summary { margin-bottom: 16px; }\n    .payment-summary p { margin: 4px 0; font-size: 15px; }\n\n    .payment-state { display: flex; flex-direction: column; align-items: center; padding: 24px; text-align: center; }\n    .result-icon { font-size: 48px; width: 48px; height: 48px; margin-bottom: 8px; }\n    .success-icon { color: #4caf50; }\n    .redirect-icon { color: #1976d2; }\n    .error-icon { color: #f44336; }\n    .payment-ref { font-size: 12px; color: #888; }\n  `],\n  standalone: false\n})\nexport class BillingPageComponent implements OnInit {\n\n  currentSubscription: any = null;\n  invoices: any[] = [];\n  loading = true;\n\n  // Invoice detail dialog state\n  showDetail = false;\n  selectedInvoice: any = null;\n\n  // Payment dialog state\n  showPayment = false;\n  paymentInvoice: any = null;\n  paymentProcessing = false;\n  paymentResult: any = null;\n\n  constructor(\n    private httpService: HttpService,\n    private snackBar: MatSnackBar,\n    private apiErrorService: ApiErrorService // Changed: injected so failures on this page are classified, not swallowed or echoed\n  ) { }\n\n  ngOnInit() {\n    this.loadCurrentSubscription();\n    this.loadInvoices();\n  }\n\n  // Load current subscription summary\n  loadCurrentSubscription() {\n    this.httpService.Get('subscriptions/current').subscribe({\n      next: (response: any) => {\n        if (response?.success) {\n          this.currentSubscription = response.data;\n        } else {\n          this.apiErrorService.presentAppFailure(response, 'load', 'subscriptions/current'); // Added: was silent — the subscription summary card simply did not render, so a tenant could not tell a broken read from having no plan\n        }\n      }\n    });\n  }\n\n  // Load invoice history for the current tenant\n  loadInvoices() {\n    this.httpService.Get('tenantinvoices/all/x').subscribe({\n      next: (response: any) => {\n        if (response?.success) {\n          this.invoices = response.data || [];\n        } else {\n          this.apiErrorService.presentAppFailure(response, 'load', 'tenantinvoices/all/x'); // Added: was silent. An empty invoice list is a perfectly normal state for a new tenant, which is precisely why a FAILED one must not look the same — \"you have no invoices\" is a different fact from \"we could not fetch them\"\n        }\n        this.loading = false;\n      },\n      error: () => { this.loading = false; }\n    });\n  }\n\n  // Subscription status label mapping\n  getStatusLabel(status: number): string {\n    const labels: Record<number, string> = { 0: 'Trial', 1: 'Active', 2: 'Past Due', 3: 'Cancelled', 4: 'Expired' };\n    return labels[status] || 'Unknown';\n  }\n\n  // Invoice status label mapping (TenantInvoiceStatus enum)\n  getInvoiceStatusLabel(status: number): string {\n    const labels: Record<number, string> = { 0: 'Pending', 1: 'Paid', 2: 'Failed', 3: 'Refunded' };\n    return labels[status] || 'Unknown';\n  }\n\n  // Payment transaction status label mapping (GatewayPaymentStatus enum)\n  getPaymentStatusLabel(status: number): string {\n    const labels: Record<number, string> = { 0: 'Initiated', 1: 'Pending', 2: 'Success', 3: 'Failed', 4: 'Cancelled' };\n    return labels[status] || 'Unknown';\n  }\n\n  // View invoice detail with payment transaction audit trail\n  viewInvoiceDetail(invoice: any) {\n    this.httpService.Get('tenantinvoices/detail/' + invoice.tenantInvoiceID).subscribe({\n      next: (response: any) => {\n        if (response?.success) {\n          this.selectedInvoice = response.data;\n          this.showDetail = true;\n        } else {\n          this.apiErrorService.presentAppFailure(response, 'action', 'tenantinvoices/detail/' + invoice.tenantInvoiceID); // Changed: was a bare MatSnackBar carrying response.message — raw server text for 3 seconds, ApiErrorService bypassed entirely, the same shape Phase 3 removed from groups.component.ts\n        }\n      },\n      error: () => {\n        this.snackBar.open('Failed to load invoice detail', '', { duration: 3000 });\n      }\n    });\n  }\n\n  // Close the invoice detail dialog\n  closeDetail() {\n    this.showDetail = false;\n    this.selectedInvoice = null;\n  }\n\n  // Open payment dialog for a pending invoice\n  initiatePayment(invoice: any) {\n    this.paymentInvoice = invoice;\n    this.paymentProcessing = false;\n    this.paymentResult = null;\n    this.showPayment = true;\n  }\n\n  // Process payment via payments API\n  processPayment() {\n    if (!this.paymentInvoice) return;\n    this.paymentProcessing = true;\n\n    this.httpService.Post('payments/process/' + this.paymentInvoice.tenantInvoiceID, {}).subscribe({\n      next: (response: any) => {\n        this.paymentProcessing = false;\n        if (response?.success) {\n          // Dev mode: payment auto-completed\n          this.paymentResult = { success: true, reference: response.data?.reference };\n          this.loadInvoices(); // Refresh invoice list\n        } else if (response?.data?.redirectUrl) {\n          // Live mode: redirect to Paynow\n          this.paymentResult = { success: false, redirectUrl: response.data.redirectUrl };\n        } else {\n          this.paymentResult = { success: false, message: this.paymentFailureText(response, 'payments/process/' + this.paymentInvoice.tenantInvoiceID) }; // Changed: was `response?.message || 'Payment failed'` rendered verbatim at the template's failure state\n        }\n      },\n      error: () => {\n        this.paymentProcessing = false;\n        this.paymentResult = { success: false, message: 'Payment request failed. Please try again.' };\n      }\n    });\n  }\n\n  // Added: the payment dialog is the one place in this sweep where a MODAL is the WRONG answer. It already\n  // owns a dedicated failure state — error icon, red panel, inside the dialog the user is staring at — so\n  // stacking presentAppFailure's dialog on top of it would talk over a surface that is already doing the job,\n  // and would leave the panel underneath still showing the raw sentence anyway.\n  //\n  // What was actually wrong was the TEXT, not the surface. So the classifier is reused directly: a message a\n  // backend author wrote for a human (\"Insufficient funds\", \"Card declined\") is exactly what someone paying an\n  // invoice needs and is shown unchanged, while an implementation leak is replaced. The reference, when the\n  // catch-all minted one, is kept — a failed payment is the single most likely thing a tenant phones about.\n  private paymentFailureText(response: any, url: string): string {\n    const raw = response?.message;\n    console.error('[tin-spa] payment failure', { url, message: raw, response }); // the technical detail still reaches the console, exactly as presentAppFailure does\n\n    if (this.apiErrorService.classifyMessage(raw) === 'business') return raw;\n\n    const reference = this.apiErrorService.extractReference(raw);\n    return `We couldn't complete that payment because of a technical problem — not anything you did wrong. Nothing was charged.` +\n           (reference ? ` Please try again shortly, and quote reference ${reference} if you contact your administrator.` : ` Please try again shortly.`);\n  }\n\n  // Close the payment dialog\n  closePayment() {\n    this.showPayment = false;\n    this.paymentInvoice = null;\n    this.paymentResult = null;\n    if (this.paymentResult?.success) {\n      this.loadInvoices(); // Refresh if payment was successful\n    }\n  }\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { TenantSettingsComponent } from '../../pages/tenant-settings/tenant-settings.component';\nimport { TenantsComponent } from '../../pages/tenants/tenants.component';\nimport { BugComponent } from '../../pages/bug/bug.component';\nimport { MembershipComponent } from '../../pages/membership/membership.component';\nimport { PlansComponent } from '../../pages/plans/plans.component';\nimport { FeaturesComponent } from '../../pages/features/features.component';\nimport { PlanFeaturesComponent } from '../../pages/plan-features/plan-features.component';\nimport { SubscriptionPageComponent } from '../../pages/subscription/subscription.component';\nimport { BillingPageComponent } from '../../pages/billing/billing.component';\n\nexport const TENANCY_ROUTES: Routes = [\n  { path: \"settings\", component: TenantSettingsComponent }, // Changed: Removed \"tenant-\" prefix — module path provides the namespace\n  { path: \"tenants\", component: TenantsComponent },\n  { path: \"bug\", component: BugComponent },\n  { path: \"membership\", component: MembershipComponent },\n  { path: \"plans\", component: PlansComponent },\n  { path: \"features\", component: FeaturesComponent },\n  { path: \"plan-features\", component: PlanFeaturesComponent },\n  { path: \"subscription\", component: SubscriptionPageComponent },\n  { path: \"billing\", component: BillingPageComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(TENANCY_ROUTES)],\n  exports: [RouterModule]\n})\nexport class TenancyRoutingModule { }\n","import { Component, OnInit } from '@angular/core';\nimport { DetailsDialogConfig, FormConfig, PageConfig, TableConfig } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\n\n@Component({\n    selector: 'spa-approvals',\n    templateUrl: './approvals.component.html',\n    styleUrls: ['./approvals.component.css'],\n    standalone: false\n})\nexport class ApprovalsComponent implements OnInit {\n\n  constructor(public dataService : DataServiceLib) { }\n\n  ngOnInit(): void {\n  }\n\n\n}\n","<h4>Approvals</h4>\n<hr>\n\n<mat-tab-group>\n  <mat-tab label=\"Received\">\n    <div class=\"mt-3\">\n      <spa-table [config]=\"dataService.receivedApprovalsTableConfig\"></spa-table>\n    </div>\n  </mat-tab>\n  <mat-tab label=\"Sent\">\n    <div class=\"mt-3\">\n      <spa-table [config]=\"dataService.sentApprovalsTableConfig\"></spa-table>\n    </div>\n  </mat-tab>\n</mat-tab-group>\n","import { Component, OnInit } from '@angular/core';\nimport { Button, DetailsDialogConfig, FormConfig, PageConfig, TableConfig } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\n\n@Component({\n    selector: 'spa-approvals-config',\n    templateUrl: './approvals-config.component.html',\n    styleUrls: ['./approvals-config.component.css'],\n    standalone: false\n})\nexport class ApprovalsConfigComponent implements OnInit {\n\n  constructor(private dataService : DataServiceLib) { }\n\n\n  approvalRoleFormConfig: FormConfig;\n  approvalRolesTableConfig: TableConfig;\n  approvalLevelOptions: any[];\n  approvalLevelFormConfig: FormConfig;\n  approvalLevelDetailsConfig: DetailsDialogConfig;\n  approvalLevelsTableConfig: TableConfig;\n  approvalConfigFormConfig: FormConfig;\n  approvalConfigDetailsConfig: DetailsDialogConfig;\n  approvalConfigTable: TableConfig;\n  pageConfig: PageConfig;\n\n  ngOnInit(): void {\n\n    this.initializeConfigs();\n  }\n\n\n  private initializeConfigs(): void {\n    // Approval Roles\n    this.approvalRoleFormConfig = {\n      title: 'Approval Role',\n      security: { allow: [this.dataService.capApprovalsConfig] },\n      fields: [\n        { name: 'roleID', type: 'select', required: true, alias: 'Role', loadAction: { url: 'role/list/x' } }\n      ]\n    };\n\n    this.approvalRolesTableConfig = {\n      tabTitle: 'Level Roles',\n      showFilter: true,\n      elevation: 'none',\n      flatButtons: true,\n      minColumns: ['roleName'],\n      columns: [\n        { name: 'roleName', type: 'text', alias: 'Role' }\n      ],\n      buttons: [\n        { name: 'create', display: 'Add Role', dialog: true, action: { url: 'approvalroles?action=create', method: 'post' } },\n        { name: 'delete', dialog: true, action: { url: 'approvalroles?action=delete', method: 'post' } }\n      ],\n      loadAction: { url: 'approvalroles/level/x' },\n      loadCriteria: 'level',\n      loadIDField: 'approvalLevelID',\n      formConfig: this.approvalRoleFormConfig\n    };\n\n\n    // Approval Levels\n\n    this.approvalLevelOptions = [1,2,3,4,5].map(x => ({name: x, value: x}));\n\n    this.approvalLevelFormConfig = {\n      title: 'Approval Level',\n      security: { allow: [this.dataService.capApprovalsConfig] },\n      fields: [\n        { name: 'name', type: 'text', required: true, span: true, infoMessage: 'Name of approval level e.g. Supervisor Approval' },\n        { name: 'level', type: 'select', required: true, min: 1, defaultFirstValue : true, infoMessage: 'Order of approval',\n          options: this.approvalLevelOptions\n        }\n      ],\n    };\n\n    this.approvalLevelDetailsConfig = {\n      formConfig: this.approvalLevelFormConfig,\n      heroField: 'approvalLevelID',\n      tableConfigs: [this.approvalRolesTableConfig],\n      buttons: [\n        { name: 'edit', dialog: true, action: { url: 'approvallevels?action=edit', method: 'post' } }\n      ]\n    };\n\n    // Changed: view + create after detailsConfig for onSuccessButton\n    const approvalLevelViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.approvalLevelDetailsConfig };\n    const approvalLevelCreateButton: Button = { name: 'create', display: 'Add Level', dialog: true, onSuccessButton: approvalLevelViewButton, action: { url: 'approvallevels?action=create', method: 'post' } };\n\n    this.approvalLevelsTableConfig = {\n      tabTitle: 'Approval Levels',\n      showFilter: true,\n      elevation: 'none',\n      flatButtons: true,\n      minColumns: ['level','name', ],\n      minButtons : ['up', 'down', 'view'],\n      collapseButtons : true,\n      columns: [\n        { name: 'level', type: 'number' },\n        { name: 'name', type: 'chip', detailsConfig: this.approvalLevelDetailsConfig },\n        { name: 'rolesDisplay', type: 'text', alias: 'Roles' }\n      ],\n      buttons: [\n        approvalLevelCreateButton, // Changed: uses onSuccessButton to auto-open view after create\n        { name: 'up', display: 'Move Up', icon: { name: 'arrow_upward' }, action: { url: 'approvallevels?action=up', method: 'post' }, visible: x => x.level > 1 },\n        { name: 'down', display: 'Move Down', icon: { name: 'arrow_downward' }, action: { url: 'approvallevels?action=down', method: 'post' } },\n        approvalLevelViewButton,\n        { name: 'delete', dialog: true, action: { url: 'approvallevels?action=delete', method: 'post' } }\n      ],\n\n      formConfig: this.approvalLevelFormConfig,\n      loadAction: { url: 'approvallevels/config/x' },\n      loadCriteria: 'config',\n      loadIDField: 'approvalConfigID'\n    };\n\n\n    // Approval Config\n    this.approvalConfigFormConfig = {\n      title: 'Approval Configuration',\n      includeAudit: true,\n      security : {allow : [this.dataService.capApprovalsConfig]},\n      fields: [\n        // { name: 'modelName', type: 'text', required: true, alias: 'Entity Name', span: true, },\n        { name: 'enabled', type: 'checkbox', span: true, alias: 'Enable Approvals', defaultValue : true, infoMessage: 'Enable or disable approval workflow for this entity' },\n        // { name: 'modelName', type: 'select', required: true, span: true, alias: 'Entity', optionDisplay: 'name', optionValue: 'value', loadAction: { url: 'approvalconfigs/meta/x' }, },\n        { name: 'appModelID', type: 'text-single', required: true, span: true, alias: 'Entity', optionDisplay: 'name', optionValue: 'value', loadAction: { url: 'appmodels/list/approvable' }, }, // Changed: select -> text-single for typeable autocomplete\n        { name: 'createApprovalRequired', type: 'checkbox', span: true, alias: 'Create Approval' },\n        { name: 'editApprovalRequired', type: 'checkbox', span: true, alias: 'Edit Approval' },\n        { name: 'deleteApprovalRequired', type: 'checkbox', span: true, alias: 'Delete Approval' },\n        { name: 'customActions', type: 'text', span: true, alias: 'Custom Actions', infoMessage: 'Comma-separated list of actions that require approval e.g receive,disburse' },\n        { name: 'notify', type: 'checkbox', defaultValue : true,},\n        {\n          name: 'channels', type: 'select', alias: 'Notification Channels', span: false, defaultFirstValue: true, required: true,\n          hidden : x => x.notify === false,\n          options: this.dataService.notificationOptions,\n        }\n      ]\n    }\n\n    this.approvalConfigDetailsConfig = {\n      formConfig: this.approvalConfigFormConfig,\n      heroField: 'approvalConfigID',\n      tableConfigs: [this.approvalLevelsTableConfig],\n      buttons: [\n        { name: 'edit', dialog: true, action: { url: 'approvalconfigs?action=edit', method: 'post' } },\n      ]\n    };\n\n    // Changed: view + create after detailsConfig for onSuccessButton\n    const approvalConfigViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.approvalConfigDetailsConfig };\n    const approvalConfigCreateButton: Button = { name: 'create', display: 'Create', dialog: true, onSuccessButton: approvalConfigViewButton, action: { url: 'approvalconfigs?action=create', method: 'post' } };\n\n    this.approvalConfigTable = {\n      showFilter: true,\n      flatButtons: true,\n      minColumns: ['modelNameDisplay', 'enabled', 'approvalTypes'],\n      columns: [\n        { name: 'modelNameDisplay', type: 'text', alias: 'Entity' },\n        { name: 'enabled', type: 'checkbox',\n          icons: [\n            { name: 'warning', color: 'orange', tip: 'No approval levels or roles configured', condition: x => x.enabled && (x.hasNoLevels || x.hasNoRoles) }\n          ]\n        },\n        {\n          name: 'approvalTypes',\n          type: 'icon',\n          alias: 'Approval Types',\n          icons: [\n            { name: 'add_circle', color: 'green', tip: 'Create Approval Required', condition: x => x.enabled && x.createApprovalRequired },\n            { name: 'edit', color: 'orange', tip: 'Edit Approval Required', condition: x => x.enabled && x.editApprovalRequired },\n            { name: 'delete', color: 'red', tip: 'Delete Approval Required', condition: x => x.enabled && x.deleteApprovalRequired },\n            { name: 'settings', color: 'blue', tip: 'Custom Actions', condition: x => x.enabled && x.customActions?.length > 0, tipField: 'customActions' }\n          ]\n        },\n        { name: 'customActions', type: 'text', alias: 'Custom Actions' },\n        {\n          name: 'levelCount', type: 'number', alias: 'Levels',\n          icons: [\n            {\n              name: 'warning', color: 'orange', tip: 'No approval levels configured',\n              condition: x => x.levelCount === 0\n            }\n          ]\n        },\n      ],\n\n      buttons: [\n        approvalConfigCreateButton, // Changed: uses onSuccessButton to auto-open view after create\n        approvalConfigViewButton,\n        { name: 'edit', dialog: true, detailsConfig: this.approvalConfigDetailsConfig },\n        { name: 'delete', action: { url: 'approvalconfigs?action=delete', method: 'post' } },\n      ],\n\n      loadAction: { url: 'approvalconfigs/all/x' },\n      formConfig: this.approvalConfigFormConfig\n    };\n\n    this.pageConfig ={\n      title: 'Approval Configuration',\n      tableConfig: this.approvalConfigTable\n    }\n  }\n\n}\n","<spa-page [config]=\"pageConfig\"></spa-page>\n","import { Component, OnInit, inject } from '@angular/core';\nimport { ApiResponse, DetailsDialogConfig, FormConfig, PageConfig, TableConfig } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\nimport { NotificationsService } from '../../services/notifications.service';\n\n@Component({\n    selector: 'spa-notifications',\n    templateUrl: './notifications.component.html',\n    styleUrls: ['./notifications.component.css'],\n    standalone: false\n})\nexport class NotificationsComponent implements OnInit {\n  private dataService = inject(DataServiceLib);\n  private notificationsService = inject(NotificationsService);\n\n  createDialog: DetailsDialogConfig = {\n    formConfig: {\n      security : { allow : [this.dataService.capNotifications] },\n      title: 'Send Notification',\n      fixedTitle: true,\n      fields: [\n        { name: 'message', type: 'text', required: true,  span: true },\n        {\n          name: 'category', type: 'select', required: true, defaultFirstValue : true,\n          options: [\n            { name: 'System', value: 0 },\n            { name: 'Security', value: 1 },\n            { name: 'Task', value: 2 },\n            { name: 'Approval', value: 3 },\n            { name: 'Other', value: 4 }\n          ]\n        },\n        {\n          name: 'type', type: 'select', required: true, defaultFirstValue: true,\n          options: [\n            { name: 'Info', value: 'info' },\n            { name: 'Warning', value: 'warn' },\n            { name: 'Error', value: 'error' }\n          ]\n        },\n        { name: 'durationHours', type: 'number', required: true, defaultValue: 24, hint: 'How long to keep this notification active' },\n        { name: 'notifyAllUsers', type: 'checkbox', alias: 'Notify All Users', span: false },\n        { name: 'usernames', type: 'text-multi', alias: 'Recipients', copyContent : true, clearContent : true, span: true,  hidden: x => x.notifyAllUsers, loadAction : { url: 'user/list/x' } }, // Changed: multi-text -> text-multi\n        { name: 'roleIDs', type: 'select-multi', strict : true, copyContent : true, alias: 'Roles',  span: false, hidden: x => x.notifyAllUsers,  loadAction : { url: 'role/list/x' } }, // Changed: multi-select -> select-multi\n        {\n          name: 'channels', type: 'select', alias: 'Notification Channels', span: false, defaultFirstValue: true, required: true,\n          options: this.dataService.notificationOptions,\n        }\n      ]\n    },\n    mode: 'create',\n    buttons: [\n      { name: 'create', display: 'Send', action: { url: 'notifications?action=notify', method: 'post', successMessage: 'Notification sent successfully' } }\n    ]\n  };\n\n  notificationsTableConfig: TableConfig = {\n    showFilter: true,\n    minColumns: ['message', 'categoryName'],\n    flatButtons: true,\n    columns: [\n      {\n        name: 'type', type: 'icon',\n        icons: [\n          {name : 'info',  color: 'steelblue', condition: x => x.type === 'info' },\n          { name: 'warning', color: '#FF9800', condition: x => x.type === 'warn' },\n          { name: 'error', color: '#f44336', condition: x => x.type === 'error' }\n        ]\n      },\n      { name: 'createdDate', type: 'datetime', alias: 'Date' },\n      { name: 'message', type: 'text' },\n      { name: 'categoryName', type: 'text', alias: 'Category' },\n\n      // { name: 'createdByName', type: 'text', alias: 'From' }\n    ],\n    buttons: [\n      { name: 'create', display: 'Send Notification', dialog: true, detailsConfig: this.createDialog },\n      { name: 'dismiss', icon: { name: 'done' }, color: 'green', action: { url: 'notifications?action=dismiss', method: 'post' }, visible: x => x.canDismiss },\n      { name: 'dismissAll', display: 'Dismiss All', inHeader : true, icon: { name: 'done_all' }, color: 'green', action: { url: 'notifications/dismiss-all', method: 'post' } },\n      { name: 'delete', action: { url: 'notifications?action=delete', method: 'post' } }\n    ],\n\n    loadAction: { url: 'notifications/all/x' }\n  };\n  \n  pageConfig: PageConfig = {\n    title: 'Notifications',\n    tableConfig: this.notificationsTableConfig\n  };\n\n  ngOnInit(): void {\n    this.notificationsService.loadNotifications();\n  }\n\n\n  actionClicked(x){\n    this.notificationsService.loadNotifications()\n  }\n}\n","<spa-page [config]=\"pageConfig\" (actionResponse)=\"actionClicked($event)\"></spa-page>\n","import { Component } from '@angular/core';\nimport { DetailsDialogConfig, FormConfig, PageConfig, TableConfig } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\n\n\n@Component({\n    selector: 'spa-app-models',\n    standalone: false,\n    template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class AppModelsComponent {\n  constructor(private dataService: DataServiceLib) { }\n\n  appModelFormConfig: FormConfig = {\n    security: { allow: [this.dataService.capAppModels] }, // Added: gate app model form by app models cap\n    title: 'Application Model',\n    includeAudit: true,\n    fields: [\n      { name: 'fullModelName', type: 'text', required: true, span: true, alias: 'Full Model Name', readonly: true },\n      { name: 'name', type: 'text', span: true, alias: 'Display Name', infoMessage: 'Custom display name (optional)' },\n      { name: 'endpoint', type: 'text', span: true, alias: 'Endpoint Name', infoMessage: 'Name of associated endpoint (optional)' },\n      { name: 'approvable', type: 'checkbox', span: true, alias: 'Approvable', readonly: true }\n    ]\n  };\n\n  appModelDetailsConfig: DetailsDialogConfig = {\n    formConfig: this.appModelFormConfig,\n    heroField: 'appModelID',\n    buttons: [\n      { name: 'edit', dialog: true, action: { url: 'appmodels?action=edit', method: 'post' } }\n    ]\n  };\n\n  appModelTableConfig: TableConfig = {\n    showFilter: true,\n    elevation: 'none',\n    flatButtons: true,\n    minColumns: ['displayName', 'approvable'],\n    columns: [\n      { name: 'displayName', type: 'chip', alias: 'Name', detailsConfig: this.appModelDetailsConfig },\n      { name: 'fullModelName', type: 'text', alias: 'Full Model Name' },\n      { name: 'endpoint', type: 'text', alias: 'Endpoint' },\n      { name: 'approvable', type: 'checkbox', alias: 'Approvable' }\n    ],\n    buttons: [\n      { name: 'view', dialog: true, detailsConfig: this.appModelDetailsConfig },\n      { name: 'edit', dialog: true, detailsConfig: this.appModelDetailsConfig },\n    ],\n    loadAction: { url: 'appmodels/all/x' }\n  };\n\n  pageConfig: PageConfig = {\n    title: 'Application Models',\n    tableConfig: this.appModelTableConfig\n  };\n}\n","import { Component, OnInit } from '@angular/core';\nimport { Button, DetailsDialogConfig, FormConfig, PageConfig, TableConfig } from '../../classes/Classes';\nimport { DataServiceLib } from '../../services/datalib.service';\n\n@Component({\n    selector: 'spa-notifications-config',\n    templateUrl: './notifications-config.component.html',\n    standalone: false\n})\nexport class NotificationsConfigComponent implements OnInit {\n\n  constructor(private dataService: DataServiceLib) { }\n\n\n  notificationOperationFormConfig: FormConfig;\n  notificationOperationsTableConfig: TableConfig;\n  notificationConfigFormConfig: FormConfig;\n  notificationConfigDetailsConfig: DetailsDialogConfig;\n  notificationConfigTable: TableConfig;\n  pageConfig: PageConfig;\n\n  ngOnInit(): void {\n\n    this.initializeConfigs();\n  }\n\n\n  private initializeConfigs(): void {\n    // Notification Operations\n    this.notificationOperationFormConfig = {\n      title: 'Notification Operation',\n      security: { allow: [this.dataService.capNotificationsConfig] },\n      fields: [\n        { name: 'operationType', type: 'select', required: true, alias: 'Operation Type', loadAction: { url: 'notificationconfigs/meta/x' }, optionDisplay: 'name', optionValue: 'value' },\n        { name: 'customAction', type: 'text', required: true, alias: 'Custom Action', hidden: x => x.operationType !== 4 }, // 4 = Custom\n        { name: 'enabled', type: 'checkbox', alias: 'Enable Notifications', defaultValue: true },\n        { name: 'roleIDs', type: 'select-multi', alias: 'Notify Roles', required: true, loadAction: { url: 'role/list/x' }, }, //hidden: x => !x.enabled // Changed: multi-select -> select-multi\n        {\n            name: 'channels', type: 'select', alias: 'Notification Channels', span: false, defaultFirstValue: true, required: true,\n            options: this.dataService.notificationOptions,\n          }\n      ]\n    };\n\n    this.notificationOperationsTableConfig = {\n      tabTitle: 'Notification Operations',\n      showFilter: true,\n      elevation: 'none',\n      flatButtons: true,\n      minColumns: ['operationTypeName', 'enabled', 'channels'],\n      columns: [\n        { name: 'operationTypeName', type: 'text', alias: 'Operation' },\n        { name: 'customAction', type: 'text', alias: 'Custom Action' },\n        { name: 'enabled', type: 'checkbox' },\n        { name: 'roleIDs', type: 'text', alias: 'Roles' },\n        { name: 'channels', type: 'text', alias: 'Channels' }\n      ],\n      buttons: [\n        { name: 'create', display: 'Add Operation', dialog: true, action: { url: 'notificationoperations?action=create', method: 'post' } },\n        { name: 'edit', dialog: true, action: { url: 'notificationoperations?action=edit', method: 'post' } },\n        { name: 'delete', dialog: true, action: { url: 'notificationoperations?action=delete', method: 'post' } }\n      ],\n      loadAction: { url: 'notificationoperations/config/x' },\n      loadCriteria: 'config',\n      loadIDField: 'notificationConfigID',\n      formConfig: this.notificationOperationFormConfig\n    };\n\n    // Main Notification Config\n    this.notificationConfigFormConfig = {\n      title: 'Notification Configuration',\n      includeAudit: true,\n      security: { allow: [this.dataService.capNotificationsConfig] },\n      fields: [\n        { name: 'enabled', type: 'checkbox', alias: 'Enable Notifications', defaultValue: true, span: true },\n        { name: 'appModelID', type: 'text-single', required: true, span: true, alias: 'Entity', loadAction: { url: 'appmodels/list/x' } }, // Changed: select -> text-single for typeable autocomplete\n        // { name: 'customActions', type: 'text', span: true, alias: 'Custom Actions', infoMessage: 'Comma-separated list of actions that can trigger notifications e.g receive,disburse' }\n      ]\n    };\n\n    this.notificationConfigDetailsConfig = {\n      formConfig: this.notificationConfigFormConfig,\n      heroField: 'notificationConfigID',\n      tableConfigs: [this.notificationOperationsTableConfig],\n      buttons: [\n        { name: 'edit', dialog: true, action: { url: 'notificationconfigs?action=edit', method: 'post' } }\n      ]\n    };\n\n    // Changed: view + create after detailsConfig for onSuccessButton\n    const notifConfigViewButton: Button = { name: 'view', dialog: true, detailsConfig: this.notificationConfigDetailsConfig };\n    const notifConfigCreateButton: Button = { name: 'create', display: 'Create', dialog: true, onSuccessButton: notifConfigViewButton, action: { url: 'notificationconfigs?action=create', method: 'post' } };\n\n    this.notificationConfigTable = {\n      showFilter: true,\n      flatButtons: true,\n      minColumns: ['modelNameDisplay', 'enabled', 'operations'],\n      columns: [\n        { name: 'modelNameDisplay', type: 'chip', alias: 'Entity', detailsConfig: this.notificationConfigDetailsConfig },\n        {\n          name: 'enabled', type: 'checkbox',\n          icons: [\n            { name: 'warning', color: 'orange', tip: 'No operations configured', condition: x => x.enabled && x.hasNoOperations },\n            { name: 'warning', color: 'orange', tip: 'Some operations have no roles configured', condition: x => x.enabled && x.hasNoRoles },\n            { name: 'warning', color: 'orange', tip: 'Some operations have no channels configured', condition: x => x.enabled && x.hasIncompleteChannels }\n          ]\n        },\n        {\n          name: 'operations', type: 'icon', alias: 'Operations',\n          icons: [\n            { name: 'done_all', color: 'green', tip: 'All Operations', condition: x => x.enabled && x.operations.some(o => o.operationType === 0) },\n            { name: 'add_circle', color: 'green', tip: 'Create', condition: x => x.enabled && x.operations.some(o => o.operationType === 1) },\n            { name: 'edit', color: 'orange', tip: 'Edit', condition: x => x.enabled && x.operations.some(o => o.operationType === 2) },\n            { name: 'delete', color: 'red', tip: 'Delete', condition: x => x.enabled && x.operations.some(o => o.operationType === 3) },\n            { name: 'settings', color: 'blue', tip: 'Custom Actions', condition: x => x.enabled && x.operations.some(o => o.operationType === 4) }\n          ]\n        }\n      ],\n      buttons: [\n        notifConfigCreateButton, // Changed: uses onSuccessButton to auto-open view after create\n        notifConfigViewButton,\n        { name: 'edit', dialog: true, detailsConfig: this.notificationConfigDetailsConfig },\n        { name: 'delete', action: { url: 'notificationconfigs?action=delete', method: 'post' } }\n      ],\n      loadAction: { url: 'notificationconfigs/all/x' },\n      formConfig: this.notificationConfigFormConfig\n    };\n\n    this.pageConfig = {\n      title: 'Notification Configuration',\n      tableConfig: this.notificationConfigTable\n    };\n  }\n}\n","<spa-page [config]=\"pageConfig\"></spa-page>\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { ApprovalsComponent } from '../../pages/approvals/approvals.component';\nimport { ApprovalsConfigComponent } from '../../pages/approvals-config/approvals-config.component';\nimport { NotificationsComponent } from '../../pages/notifications/notifications.component';\nimport { AppModelsComponent } from '../../pages/app-models/app-models.component';\nimport { NotificationsConfigComponent } from '../../pages/notifications-config/notifications-config.component';\nimport { SyncComponent } from '../../pages/sync/sync.component'; // Added: TinSync pending-changes page\n\n// Added (F3): leaf-level data.moduleKey, inert metadata only — no guard is attached in this library. The workflow\n// AREA is deliberately bare because it is not a module: only Approvals is one (capApprovals.moduleKey = \"approvals\",\n// datalib.service.ts:235). Approvals Config, notifications, app models and sync carry no moduleKey in the CapItem\n// tree, so they stay unkeyed and fail open, which is the safe direction. Tasks & Notes (\"tasks\") is NOT here — its\n// page is home/general/tasks (capTasks:146), so its key lives on that leaf in general-routing.module.ts. Document\n// Management (\"documents\") has no page in this library at all; its only route is shift-spa's own doctypes.\nexport const WORKFLOW_ROUTES: Routes = [\n  { path: \"approvals\", component: ApprovalsComponent, data: { moduleKey: 'approvals' } }, // Added (F3): the one workflow page that is a module\n  { path: \"approvals-config\", component: ApprovalsConfigComponent },\n  { path: \"notifications\", component: NotificationsComponent },\n  { path: \"appmodels\", component: AppModelsComponent },\n  { path: \"notifications-config\", component: NotificationsConfigComponent },\n  { path: \"sync\", component: SyncComponent } // Added: TinSync pending-changes page (reached from the toolbar cloud indicator)\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(WORKFLOW_ROUTES)],\n  exports: [RouterModule]\n})\nexport class WorkflowRoutingModule { }\n","import { Component } from '@angular/core';\nimport { TileConfig, ChartConfig } from '../../../classes/Classes';\n\n// Executive overview dashboard combining key metrics from all ERP modules\n@Component({\n  selector: 'spa-overview-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>dashboard</mat-icon> Overview Dashboard</h4>\n      <!-- Changed: Icon tiles for primary KPIs -->\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <!-- Changed: Chart tiles for mini visual indicators -->\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n  `],\n  standalone: false\n})\nexport class OverviewDashboardComponent {\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'revenue', alias: 'Revenue (MTD)', color: '#4caf50', icon: 'trending_up', style: 'icon', info: 'MTD revenue' },\n      { name: 'expenses', alias: 'Expenses (MTD)', color: '#f44336', icon: 'trending_down', style: 'icon', info: 'MTD expenses' },\n      { name: 'netProfit', alias: 'Net Profit (MTD)', color: '#2196f3', icon: 'account_balance', style: 'icon', info: 'MTD profit' },\n      { name: 'stockValue', alias: 'Stock Value', color: '#ff9800', icon: 'inventory_2', style: 'icon', info: 'Inventory value' },\n      { name: 'netCashFlow', alias: 'Net Cash Flow', color: '#9c27b0', icon: 'swap_vert', style: 'icon', info: 'Net cash movement' }, // Changed: Replaced totalLiabilities with net cash flow\n      { name: 'cashBalance', alias: 'Cash & Bank', color: '#e91e63', icon: 'account_balance_wallet', style: 'icon', info: 'Cash + bank total' },\n    ],\n    loadAction: { url: 'dashboard/overview/summary' },\n    loadInit: true\n  };\n\n  // Changed: Chart-style tiles now use loadAction with dataField for dynamic data\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'profitMarginValue', alias: 'Profit Margin', color: '#4caf50', chart: { type: 'doughnut', gaugeColor: '#4caf50', height: 130, dataField: 'profitMarginValue' }, footer: 'Based on all-time revenue', footerIcon: 'info' }, // Changed: dataField replaces gaugeValue\n      { name: 'revenueSparkline', alias: 'Revenue Trend', color: '#2196f3', chart: { type: 'line', color: '#2196f3', height: 100, dataField: 'revenueSparkline' }, footer: 'Last 12 months', footerIcon: 'timeline' }, // Changed: dataField replaces inline data\n      { name: 'expenseBreakdown', alias: 'Expense Split', color: '#ff9800', chart: { type: 'doughnut', colors: ['#ff9800', '#f44336', '#9c27b0', '#2196f3', '#4caf50'], height: 130, dataField: 'expenseBreakdown' }, footer: 'By category', footerIcon: 'pie_chart' }, // Changed: dataField replaces inline data\n      { name: 'monthlyOrders', alias: 'Monthly Orders', color: '#9c27b0', chart: { type: 'bar', colors: ['#9c27b0', '#ba68c8', '#ce93d8', '#e1bee7', '#9c27b0', '#ba68c8'], height: 100, dataField: 'monthlyOrders' }, footer: 'Last 6 months', footerIcon: 'bar_chart' }, // Changed: dataField replaces inline data\n    ],\n    loadAction: { url: 'dashboard/overview/chart-tiles' }, // Changed: Load chart tile data from API\n    loadInit: true\n  };\n\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'revenueTrend', title: 'Revenue vs Expenses Trend', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#4caf50', '#f44336'], showLegend: true }, // Changed: showLegend for line chart\n      { name: 'cashFlow', title: 'Monthly Cash Flow', type: 'bar', height: '300px', colors: ['#4caf50', '#f44336'], showLegend: true }, // Changed: showLegend for multi-dataset bar chart\n      { name: 'profitMargin', title: 'Profit Margin', type: 'doughnut', height: '300px', colors: ['#4caf50', '#e0e0e0'] },\n      { name: 'healthIndicators', title: 'Business Health Indicators', type: 'doughnut', height: '300px', colors: ['#4caf50', '#e0e0e0', '#2196f3', '#e0e0e0', '#ff9800', '#e0e0e0'] },\n    ],\n    loadAction: { url: 'dashboard/overview/charts' },\n    loadInit: true,\n    columns: 2\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { OverviewDashboardComponent } from '../../pages/overview/overview-dashboard/overview-dashboard.component';\n\nexport const OVERVIEW_ROUTES: Routes = [\n  { path: \"dashboard\", component: OverviewDashboardComponent }\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(OVERVIEW_ROUTES)],\n  exports: [RouterModule]\n})\nexport class OverviewRoutingModule { }\n","import { Component } from '@angular/core';\nimport { TileConfig, ChartConfig } from '../../../classes/Classes';\n\n// Fixed Assets module dashboard — asset performance, depreciation trends, and portfolio overview\n@Component({\n  selector: 'spa-fixed-assets-dashboard',\n  template: `\n    <div class=\"dashboard-container\">\n      <h4 class=\"dashboard-title\"><mat-icon>precision_manufacturing</mat-icon> Fixed Assets Dashboard</h4>\n      <spa-tiles [config]=\"summaryTiles\"></spa-tiles>\n      <div style=\"margin-top: 16px;\"></div>\n      <spa-tiles [config]=\"chartTiles\"></spa-tiles>\n      <spa-charts [config]=\"chartConfig\"></spa-charts>\n    </div>\n  `,\n  styles: [`\n    .dashboard-container { padding: 16px; }\n    .dashboard-title { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; color: #333; font-weight: 500; }\n  `],\n  standalone: false\n})\nexport class FixedAssetsDashboardComponent {\n  summaryTiles: TileConfig = {\n    tiles: [\n      { name: 'draft', alias: 'Draft', color: '#FFC107', icon: 'edit_note', style: 'icon', info: 'Assets awaiting activation' },\n      { name: 'active', alias: 'Active', color: '#4CAF50', icon: 'check_circle', style: 'icon', info: 'Actively depreciating assets' },\n      { name: 'fullyDepreciated', alias: 'Fully Depreciated', color: '#2196F3', icon: 'task_alt', style: 'icon', info: 'Zero book value assets' },\n      { name: 'disposed', alias: 'Disposed', color: '#9E9E9E', icon: 'delete_forever', style: 'icon', info: 'Sold or retired assets' },\n      { name: 'totalCost', alias: 'Total Cost', color: '#ff9800', icon: 'attach_money', style: 'icon', info: 'Total acquisition cost' },\n      { name: 'totalNBV', alias: 'Net Book Value', color: '#4CAF50', icon: 'trending_up', style: 'icon', info: 'Current net book value' },\n      { name: 'depreciationThisMonth', alias: 'Depreciation (MTD)', color: '#f44336', icon: 'trending_down', style: 'icon', info: 'Depreciation posted this month' },\n    ],\n    loadAction: { url: 'fixedassets/dashboard/summary' },\n    loadInit: true\n  };\n\n  chartTiles: TileConfig = {\n    tiles: [\n      { name: 'depreciationGauge', alias: 'Depreciation %', color: '#2196F3', chart: { type: 'doughnut', gaugeColor: '#2196F3', height: 130, dataField: 'depreciationGauge' }, footer: 'Total depreciated vs cost', footerIcon: 'pie_chart' },\n      { name: 'depreciationSparkline', alias: 'Depreciation Trend', color: '#f44336', chart: { type: 'bar', colors: ['#f44336', '#ef5350', '#e57373', '#ef9a9a', '#ffcdd2', '#f44336', '#ef5350', '#e57373', '#ef9a9a', '#ffcdd2', '#f44336', '#ef5350'], height: 100, dataField: 'depreciationSparkline' }, footer: 'Last 12 months', footerIcon: 'trending_down' },\n      { name: 'costByCategory', alias: 'Cost by Category', color: '#ff9800', chart: { type: 'pie', colors: ['#ff9800', '#f44336', '#9c27b0', '#2196F3', '#4CAF50', '#607d8b'], height: 130, dataField: 'costByCategory' }, footer: 'Acquisition cost split', footerIcon: 'donut_large' },\n      { name: 'nbvTrend', alias: 'NBV Trend', color: '#4CAF50', chart: { type: 'line', color: '#4CAF50', height: 100, dataField: 'nbvTrend' }, footer: 'Last 6 months', footerIcon: 'show_chart' },\n    ],\n    loadAction: { url: 'fixedassets/dashboard/chart-tiles' },\n    loadInit: true\n  };\n\n  chartConfig: ChartConfig = {\n    charts: [\n      { name: 'depreciationTrend', title: 'Monthly Depreciation', type: 'bar', height: '300px', colors: ['#2196F3'] },\n      { name: 'statusDistribution', title: 'Asset Status Distribution', type: 'doughnut', height: '300px', colors: ['#FFC107', '#4CAF50', '#2196F3', '#9E9E9E'] },\n      { name: 'costByCategory', title: 'Cost by Category', type: 'bar', height: '300px', colors: ['#ff9800'] },\n      { name: 'nbvVsCost', title: 'Cost vs Net Book Value', type: 'line', height: '300px', showPoints: true, showLegend: true, tension: 0.4, colors: ['#ff9800', '#4CAF50'] },\n      { name: 'remainingLife', title: 'Remaining Useful Life', type: 'bar', height: '300px', colors: ['#7c4dff'] },\n      { name: 'acquisitionsTimeline', title: 'Acquisitions Timeline', type: 'line', height: '300px', showPoints: true, tension: 0.4, colors: ['#2196F3'] },\n    ],\n    loadAction: { url: 'fixedassets/dashboard/charts' },\n    loadInit: true,\n    columns: 2\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { TinSpaModule } from '../../../tin-spa.module';\nimport { AssetsService } from '../../../services/assets.service'; // Changed: Moved to AssetsService\n\n// Fixed Assets management page — full lifecycle with tiles, CRUD, activation, depreciation, and disposal\n@Component({\n  selector: 'spa-fixed-assets',\n  standalone: true,\n  imports: [TinSpaModule],\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class FixedAssetsComponent {\n  private assetsService = inject(AssetsService); // Changed: Use AssetsService\n\n  pageConfig: PageConfig = {\n    title: 'Fixed Assets',\n    tableConfig: this.assetsService.assetsTableConfig // Changed: Use AssetsService\n  };\n}\n","import { Component, inject } from '@angular/core';\nimport { PageConfig } from '../../../classes/Classes';\nimport { TinSpaModule } from '../../../tin-spa.module';\nimport { AssetsService } from '../../../services/assets.service';\n\n// Depreciation Categories management page — CRUD for depreciation categories with default settings\n@Component({\n  selector: 'spa-fixed-asset-categories',\n  standalone: true,\n  imports: [TinSpaModule],\n  template: '<spa-page [config]=\"pageConfig\"></spa-page>'\n})\nexport class FixedAssetCategoriesComponent { // Changed: display title renamed, component class kept for routing compatibility\n  private assetsService = inject(AssetsService);\n\n  pageConfig: PageConfig = {\n    title: 'Depreciation Categories', // Changed: Renamed from Asset Categories\n    tableConfig: this.assetsService.categoryTableConfig\n  };\n}\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { FixedAssetsDashboardComponent } from '../../pages/assets/fixed-assets-dashboard/fixed-assets-dashboard.component';\nimport { FixedAssetsComponent } from '../../pages/accounting/fixed-assets/fixed-assets.component';\nimport { FixedAssetCategoriesComponent } from '../../pages/accounting/fixed-asset-categories/fixed-asset-categories.component';\n\n// Changed: Fixed Assets routes — separated from Accounting module\nexport const ASSETS_ROUTES: Routes = [\n  { path: \"dashboard\", component: FixedAssetsDashboardComponent },\n  { path: \"register\", component: FixedAssetsComponent },\n  { path: \"depreciation-categories\", component: FixedAssetCategoriesComponent }, // Changed: Renamed from categories\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(ASSETS_ROUTES)],\n  exports: [RouterModule]\n})\nexport class AssetsRoutingModule { }\n","// Added (Phase 4, C5): the destination capabilityGuard sends a deep link to when the role was never granted the\n// page. The grid tier (table.component.html) refuses INSIDE a page that has already been built; this refuses the\n// page itself, so a bookmarked or typed URL produces one clear statement instead of full chrome — title, tabs,\n// action bar — wrapped around a small line in an empty grid.\n//\n// 🔑 The WORDING is not restated here. Both sentences come from Core.noAccessTitle/noAccessHint, the same source\n// the grid tier reads, because two tiers that each own a copy of the same sentence drift apart the first time\n// one of them is edited — and then a user who followed a link and a user who opened a tab get two different\n// accounts of the same denial.\n//\n// Standalone (like brands/categories/currencies and six others in this library) so it needs no declaration in a\n// module — the route table references it directly and a consumer app inherits it with no plumbing.\nimport { Component, OnInit, OnDestroy, inject } from '@angular/core'; // Changed: OnInit/OnDestroy — the wording is now recomputed per refusal, so it needs a lifecycle and an unsubscribe\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs'; // Added: the queryParamMap subscription, held so ngOnDestroy can release it (house pattern — bottom-tabs.component.ts:24)\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { TinSpaModule } from '../../tin-spa.module';\nimport { CapItem } from '../../classes/Classes';\nimport { Core } from '../../classes/TinCore';\nimport { DataServiceLib } from '../../services/datalib.service';\n\n@Component({\n  selector: 'spa-no-access',\n  standalone: true,\n  imports: [CommonModule, TinSpaModule],\n  templateUrl: './no-access.component.html',\n  styleUrls: ['./no-access.component.css']\n})\n// 🔴 Changed (defect fix, 2026-08-18): every member below WAS a field initializer reading `route.snapshot`, and\n// field initializers run ONCE — at construction. Angular's default route-reuse strategy REUSES this component\n// instance when only the query params change (same route config), so a second refusal in one session re-rendered\n// the FIRST refusal's sentence: `cap=cap86` (Commission Statement) still read \"You do not have access to Aging\n// Report\". The gate and the `cap=` param were correct throughout; only the visible words were stale, which is the\n// worst possible failure for a security page — it states a falsehood about what was denied.\n// The fix reads the queryParamMap OBSERVABLE instead, so each refusal recomputes its own wording. The template is\n// untouched: the same four members are still bound, they are simply assigned per emission rather than once.\nexport class NoAccessComponent implements OnInit, OnDestroy {\n  private route = inject(ActivatedRoute);\n  private router = inject(Router);\n  private dataService = inject(DataServiceLib);\n\n  capName = ''; // the raw capN — for support and the log line, never the primary text\n  from = ''; // where they were trying to go, so the page can say it\n  title = Core.noAccessTitle(null); // Added: shared with the grid tier — see Core.noAccessTitle\n  hint = Core.noAccessHint(null); // Added: shared with the grid tier — see Core.noAccessHint\n\n  private paramSub: Subscription | undefined; // Added: released in ngOnDestroy\n\n  // queryParamMap emits the CURRENT params synchronously on subscribe, so the first paint is unchanged from the\n  // old field-initializer behaviour — this only adds the emissions the old code could never see.\n  ngOnInit() {\n    this.paramSub = this.route.queryParamMap.subscribe(params => this.applyRefusal(params.get('cap') || '', params.get('from') || ''));\n  }\n\n  ngOnDestroy() {\n    if (this.paramSub) this.paramSub.unsubscribe();\n  }\n\n  // Added: the whole derivation, in one place, so a re-entry recomputes EVERY member together. Splitting these\n  // across separate subscriptions is what would let them drift back out of step.\n  private applyRefusal(capName: string, from: string) {\n    this.capName = capName;\n    this.from = from;\n    // The menu already knows every capability's human name, so the display is looked up rather than passed through\n    // the query string — a URL a user can edit must never be the source of the words on the page.\n    const cap: CapItem | null = this.flatten(this.dataService.appConfig?.capItems).find(x => x.name === capName) ?? null;\n    this.title = Core.noAccessTitle(cap?.display);\n    this.hint = Core.noAccessHint(cap?.display);\n  }\n\n  // Cap items nest (group → sub items), so the whole tree is flattened before matching. Sibling implementation at\n  // last-route.service.ts:124; that one is private to its service, so this is a deliberate 1-line restatement\n  // rather than a refactor of a working service that is not in this chunk's scope.\n  private flatten(items: CapItem[] | undefined): CapItem[] {\n    return (items || []).reduce((all: CapItem[], x) => all.concat(x, this.flatten(x.capSubItems)), []);\n  }\n\n  // Home is always reachable and is never itself capability-gated, so it is the one guaranteed-safe destination.\n  // Deliberately NOT \"back\": back is the URL that was just refused, which would bounce the user straight here again.\n  goHome() { this.router.navigate(['/home']); }\n}\n","<!-- Added (Phase 4, C5): the route-tier refusal. Same two sentences as the grid tier, from the same source\n     (Core.noAccessTitle/noAccessHint via the component), given the room a whole page allows: a lock glyph so it\n     reads as a deliberate state rather than a failure, the requested URL so the user can see WHAT was refused,\n     and the raw capN quoted small at the bottom for the support engineer who needs it.\n     role=\"status\" matches every other empty state in this library (table.component.html :264/:283/:291). -->\n<div class=\"tin-no-access\" role=\"status\">\n  <mat-icon class=\"tin-no-access-icon\" aria-hidden=\"true\">lock</mat-icon>\n\n  <h2 class=\"tin-no-access-title\">{{title}}</h2>\n  <p class=\"tin-no-access-hint\">{{hint}}</p>\n\n  <p class=\"tin-no-access-from\" *ngIf=\"from\">You tried to open <code>{{from}}</code>.</p>\n\n  <button mat-raised-button color=\"primary\" class=\"tin-no-access-action\" (click)=\"goHome()\">Go to Home</button>\n\n  <!-- The key never appears in the sentences above — a user cannot act on \"cap39\" — but a support engineer asked\n       \"what exactly is she missing?\" needs it verbatim, and this is the only place it is visible in the UI. -->\n  <p class=\"tin-no-access-key\" *ngIf=\"capName\">Reference: {{capName}}</p>\n</div>\n","import { NgModule } from '@angular/core';\nimport { Routes, RouterModule } from '@angular/router';\nimport { USER_ROUTES } from './user/user-routing.module';\nimport { ADMIN_ROUTES } from './admin/admin-routing.module';\nimport { ACCOUNTING_ROUTES } from './accounting/accounting-routing.module';\nimport { INVENTORY_ROUTES } from './inventory/inventory-routing.module';\nimport { SALES_ROUTES } from './sales/sales-routing.module';\nimport { PURCHASING_ROUTES } from './purchasing/purchasing-routing.module';\nimport { HR_ROUTES } from './hr/hr-routing.module';\nimport { PAYROLL_ROUTES } from './payroll/payroll-routing.module';\nimport { MANUFACTURING_ROUTES } from './manufacturing/manufacturing-routing.module';\nimport { LOANS_ROUTES } from './loans/loans-routing.module';\nimport { GENERAL_ROUTES } from './general/general-routing.module';\nimport { TENANCY_ROUTES } from './tenancy/tenancy-routing.module';\nimport { WORKFLOW_ROUTES } from './workflow/workflow-routing.module';\nimport { OVERVIEW_ROUTES } from './overview/overview-routing.module';\nimport { ASSETS_ROUTES } from './assets/assets-routing.module'; // Changed: Added Fixed Assets module routes\nimport { SetupGuideComponent } from '../pages/setup-guide/setup-guide.component'; // Added: Setup readiness (\"Getting Started\") page\nimport { DayBookComponent } from '../pages/day-book/day-book.component'; // Added: centralized Day Book page\nimport { AppConfigurationComponent } from '../pages/app-configuration/app-configuration.component'; // Added: centralized App Configuration page (replaces home/admin/preferences + the per-app components)\nimport { AgentPageComponent } from '../pages/agent-page/agent-page.component'; // Added: full-page chat, the mobile chat surface\nimport { NoAccessComponent } from '../pages/no-access/no-access.component'; // Added (Phase 4): where capabilityGuard sends a refused deep link\n\n// All domain routes nested under their module path\n// Consumer apps import SpaHomeModule once — no need to declare routes per app\n//\n// Added (F3): data.moduleKey is INERT metadata and nothing here reads it. It declares which ModuleCatalog module a\n// route belongs to (keys transcribed from ModuleCatalog.Library and the CapItem.moduleKey assignments in\n// datalib.service.ts, not invented). The library deliberately attaches NO guard of its own: a consumer opts in by\n// attaching moduleGuard() as a child guard on its OWN home route, so an app outside this workspace that never adds\n// that line sees an identical app on this version. (The word is spelled out nowhere in this folder on purpose —\n// the acceptance check for this phase is a literal grep for a route guard inside the library's route tables, and\n// it must return a clean zero.) Deliberately left bare — user, admin, tenancy, workflow,\n// overview, general (a Core module), setup, day-book and app-configuration — because the route back to Getting\n// Started, which is the only way to switch a module back on, must never itself be gateable.\nconst routes: Routes = [\n  { path: 'user', children: USER_ROUTES }, // Ungated — account pages\n  { path: 'admin', children: ADMIN_ROUTES }, // Ungated — administration\n  { path: 'accounting', children: ACCOUNTING_ROUTES, data: { moduleKey: 'accounting' } }, // Added (F3): inert metadata, no guard\n  { path: 'inventory', children: INVENTORY_ROUTES, data: { moduleKey: 'inventory' } }, // Added (F3)\n  { path: 'sales', children: SALES_ROUTES, data: { moduleKey: 'sales' } }, // Added (F3)\n  { path: 'purchasing', children: PURCHASING_ROUTES, data: { moduleKey: 'purchasing' } }, // Added (F3)\n  { path: 'hr', children: HR_ROUTES, data: { moduleKey: 'hr' } }, // Added (F3)\n  { path: 'payroll', children: PAYROLL_ROUTES, data: { moduleKey: 'payroll' } }, // Added (F3)\n  { path: 'manufacturing', children: MANUFACTURING_ROUTES, data: { moduleKey: 'manufacturing' } }, // Added (F3)\n  { path: 'loans', children: LOANS_ROUTES, data: { moduleKey: 'loans' } }, // Added (F3)\n  { path: 'general', children: GENERAL_ROUTES }, // Ungated — \"general\" is a Core module the server always reports enabled (its tasks leaf carries its own \"tasks\" key, F3)\n  { path: 'tenancy', children: TENANCY_ROUTES }, // Ungated — tenancy administration\n  { path: 'workflow', children: WORKFLOW_ROUTES }, // Ungated at area level — Approvals is a module in its own right and now carries a leaf key (F3)\n  { path: 'overview', children: OVERVIEW_ROUTES }, // Ungated — dashboards\n  { path: 'fixed-assets', children: ASSETS_ROUTES, data: { moduleKey: 'fixed-assets' } }, // Changed: Added Fixed Assets module // Added (F3): inert metadata\n  { path: 'setup', component: SetupGuideComponent }, // Added: Getting Started page — home/setup in all consumer apps // NEVER gated: the way back on\n  { path: 'day-book', component: DayBookComponent }, // Added: Day Book page — home/day-book, renders empty state when unconfigured\n  { path: 'app-configuration', component: AppConfigurationComponent }, // Added: App Configuration page — home/app-configuration, falls back to the library base sections when the app registers none\n  { path: 'agent', component: AgentPageComponent, data: { moduleKey: 'agent' } }, // Added: Chat page — home/agent, every consumer app inherits it // Added (F3): inert metadata\n  { path: 'no-access', component: NoAccessComponent } // Added (Phase 4): the route-tier refusal page. NEVER gated, for the same reason home/setup is not — the page a refused user is sent to must always be reachable, or the refusal becomes a redirect loop\n];\n\n@NgModule({\n  imports: [RouterModule.forChild(routes)],\n  exports: [RouterModule]\n})\nexport class SpaHomeRoutingModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { AccountsComponent as AccountingAccountsComponent } from '../../pages/accounting/accounts/accounts.component';\nimport { AggregatesComponent as AccountingAggregatesComponent } from '../../pages/accounting/aggregates/aggregates.component';\nimport { AgingComponent as AccountingAgingComponent } from '../../pages/accounting/aging/aging.component';\nimport { SupplierAgingComponent as AccountingSupplierAgingComponent } from '../../pages/accounting/supplier-aging/supplier-aging.component';\nimport { TransactionTypesComponent } from '../../pages/accounting/transaction-types/transaction-types.component';\nimport { TransactionsComponent as AccountingTransactionsComponent } from '../../pages/accounting/transactions/transactions.component';\nimport { InvoicesComponent as AccountingInvoicesComponent } from '../../pages/accounting/invoices/invoices.component';\nimport { StatementComponent as AccountingStatementComponent } from '../../pages/accounting/outstanding-invoices/outstanding-invoices.component';\nimport { ReportsComponent as AccountingReportsComponent } from '../../pages/accounting/reports/reports.component';\nimport { TaxRatesComponent } from '../../pages/accounting/tax-rates/tax-rates.component';\nimport { StandingOrdersComponent } from '../../pages/accounting/standing-orders/standing-orders.component';\nimport { CurrenciesComponent } from '../../pages/accounting/currencies/currencies.component'; // Changed: Removed Fixed Assets imports — moved to Assets module\nimport { BudgetsComponent as AccountingBudgetsComponent } from '../../pages/accounting/budgets/budgets.component';\nimport { BudgetVsActualComponent as AccountingBudgetVsActualComponent } from '../../pages/accounting/budget-vs-actual/budget-vs-actual.component';\nimport { AccountingDashboardComponent } from '../../pages/accounting/accounting-dashboard/accounting-dashboard.component';\nimport { InvoiceDashboardComponent } from '../../pages/accounting/invoice-dashboard/invoice-dashboard.component';\nimport { CreditNotesComponent } from '../../pages/accounting/credit-notes/credit-notes.component'; // Changed: Credit notes page (B6)\nimport { VatReturnComponent } from '../../pages/accounting/vat-return/vat-return.component'; // Changed: VAT return page (B2)\nimport { FiscalPeriodsComponent } from '../../pages/accounting/fiscal-periods/fiscal-periods.component'; // Changed: Fiscal periods page (C2)\nimport { ReceiptsComponent } from '../../pages/accounting/receipts/receipts.component'; // Changed: Customer receipts page (C3)\nimport { ReceiptDialogComponent } from '../../pages/accounting/receipts/receipt-dialog.component'; // Changed: Receipt allocation dialog (C3)\nimport { BankReconciliationComponent } from '../../pages/accounting/bank-reconciliation/bank-reconciliation.component'; // Changed: Bank reconciliation page (C4)\nimport { TenantTransfersComponent } from '../../pages/accounting/tenant-transfers/tenant-transfers.component'; // Added (N11): Organisation Transfers page\nimport { StatementImportDialogComponent } from '../../pages/accounting/bank-reconciliation/statement-import-dialog.component'; // Changed: Statement import dialog (C4)\nimport { ReconcileDialogComponent } from '../../pages/accounting/bank-reconciliation/reconcile-dialog.component'; // Changed: Reconcile match screen (C4)\nimport { RevenueSchedulesComponent } from '../../pages/accounting/revenue-schedules/revenue-schedules.component'; // Changed: Deferred revenue page (C7)\nimport { RevenueScheduleDialogComponent } from '../../pages/accounting/revenue-schedules/revenue-schedule-dialog.component'; // Changed: Defer revenue dialog (C7)\nimport { QuotesComponent } from '../../pages/accounting/quotes/quotes.component'; // Changed: Quotations page (C10)\n\n@NgModule({\n  declarations: [\n    AccountingAccountsComponent,\n    AccountingAggregatesComponent,\n    AccountingAgingComponent,\n    AccountingSupplierAgingComponent,\n    TransactionTypesComponent,\n    AccountingTransactionsComponent,\n    AccountingInvoicesComponent,\n    AccountingStatementComponent,\n    AccountingReportsComponent,\n    AccountingBudgetsComponent,\n    AccountingBudgetVsActualComponent,\n    AccountingDashboardComponent,\n    InvoiceDashboardComponent,\n    CreditNotesComponent, // Changed: Credit notes page (B6)\n    VatReturnComponent, // Changed: VAT return page (B2)\n    FiscalPeriodsComponent, // Changed: Fiscal periods page (C2)\n    ReceiptsComponent, // Changed: Customer receipts page (C3)\n    ReceiptDialogComponent, // Changed: Receipt allocation dialog (C3)\n    BankReconciliationComponent, // Changed: Bank reconciliation page (C4)\n    TenantTransfersComponent, // Added (N11): Organisation Transfers page\n    StatementImportDialogComponent, // Changed: Statement import dialog (C4)\n    ReconcileDialogComponent, // Changed: Reconcile match screen (C4)\n    RevenueSchedulesComponent, // Changed: Deferred revenue page (C7)\n    RevenueScheduleDialogComponent, // Changed: Defer revenue dialog (C7)\n    QuotesComponent // Changed: Quotations page (C10)\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule,\n    // Changed: Standalone components must be imported, not declared\n    TaxRatesComponent,\n    StandingOrdersComponent,\n    CurrenciesComponent // Changed: Removed Fixed Assets — moved to Assets module\n  ]\n})\nexport class AccountingModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { ProductsComponent } from '../../pages/inventory/products/products.component';\nimport { InventoryItemsComponent } from '../../pages/inventory/inventory-items/inventory-items.component';\nimport { RequisitionsComponent } from '../../pages/inventory/requisitions/requisitions.component';\nimport { InventoryAdjustmentsComponent } from '../../pages/inventory/inventory-adjustments/inventory-adjustments.component';\nimport { InventoryReturnsComponent } from '../../pages/inventory/inventory-returns/inventory-returns.component';\nimport { InventoryTransactionsComponent } from '../../pages/inventory/inventory-transactions/inventory-transactions.component';\nimport { InventoryDashboardComponent } from '../../pages/inventory/inventory-dashboard/inventory-dashboard.component';\nimport { InventoryStockComponent } from '../../pages/inventory/inventory-stock/inventory-stock.component';\nimport { BundleProductsComponent } from '../../pages/inventory/bundle-products/bundle-products.component';\nimport { ServiceItemsComponent } from '../../pages/inventory/service-items/service-items.component';\n\n@NgModule({\n  declarations: [\n    ProductsComponent,\n    InventoryItemsComponent,\n    RequisitionsComponent,\n    InventoryAdjustmentsComponent,\n    InventoryReturnsComponent,\n    InventoryTransactionsComponent,\n    InventoryDashboardComponent,\n    InventoryStockComponent,\n    BundleProductsComponent,\n    ServiceItemsComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class InventoryModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { SalesOrdersComponent } from '../../pages/sales/sales-orders/sales-orders.component';\nimport { SalesComponent } from '../../pages/sales/sales/sales.component';\nimport { SalesDashboardComponent } from '../../pages/sales/sales-dashboard/sales-dashboard.component';\n\n@NgModule({\n  declarations: [\n    SalesOrdersComponent,\n    SalesComponent,\n    SalesDashboardComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class SalesModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { SupplierPurchaseOrdersComponent } from '../../pages/purchasing/supplier-purchase-orders/supplier-purchase-orders.component';\nimport { InventoryReceiptsComponent } from '../../pages/purchasing/inventory-receipts/inventory-receipts.component';\nimport { PurchasingDashboardComponent } from '../../pages/purchasing/purchasing-dashboard/purchasing-dashboard.component';\n\n@NgModule({\n  declarations: [\n    SupplierPurchaseOrdersComponent,\n    InventoryReceiptsComponent,\n    PurchasingDashboardComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class PurchasingModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { EmployeesComponent } from '../../pages/employees/employees.component';\nimport { DepartmentsComponent } from '../../pages/departments/departments.component';\nimport { PositionsComponent } from '../../pages/positions/positions.component';\nimport { GradesComponent } from '../../pages/grades/grades.component';\nimport { OnboardingComponent } from '../../pages/onboarding/onboarding.component';\n\n@NgModule({\n  declarations: [\n    EmployeesComponent,\n    DepartmentsComponent,\n    PositionsComponent,\n    GradesComponent,\n    OnboardingComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class HRModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { SalaryStructuresComponent } from '../../pages/payroll/salary-structures/salary-structures.component';\nimport { StatutoryDeductionsComponent } from '../../pages/payroll/statutory-deductions/statutory-deductions.component';\nimport { PayrollRunsComponent } from '../../pages/payroll/payroll-runs/payroll-runs.component';\nimport { CommissionConfigsComponent } from '../../pages/payroll/commission-configs/commission-configs.component';\nimport { CommissionEntriesComponent } from '../../pages/payroll/commission-entries/commission-entries.component';\nimport { CommissionStatementComponent } from '../../pages/payroll/commission-statement/commission-statement.component'; // Added (Phase 6)\nimport { SalaryAdvancesComponent } from '../../pages/payroll/salary-advances/salary-advances.component';\nimport { OvertimeEntriesComponent } from '../../pages/payroll/overtime-entries/overtime-entries.component';\nimport { PayrollDashboardComponent } from '../../pages/payroll/payroll-dashboard/payroll-dashboard.component';\n\n@NgModule({\n  declarations: [\n    SalaryStructuresComponent,\n    StatutoryDeductionsComponent,\n    PayrollRunsComponent,\n    CommissionConfigsComponent,\n    CommissionEntriesComponent,\n    CommissionStatementComponent,\n    SalaryAdvancesComponent,\n    OvertimeEntriesComponent,\n    PayrollDashboardComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class PayrollModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { ProductionRecipesComponent } from '../../pages/manufacturing/production-recipes/production-recipes.component';\nimport { ProductionOrdersComponent } from '../../pages/manufacturing/production-orders/production-orders.component';\n\n@NgModule({\n  declarations: [\n    ProductionRecipesComponent,\n    ProductionOrdersComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class ManufacturingModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { LoanProductsComponent } from '../../pages/loans/loan-products/loan-products.component';\nimport { LoansComponent } from '../../pages/loans/loans/loans.component';\nimport { LoanPaymentsComponent } from '../../pages/loans/loan-payments/loan-payments.component';\n\n@NgModule({\n  declarations: [\n    LoanProductsComponent,\n    LoansComponent,\n    LoanPaymentsComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class LoansModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { CustomersComponent } from '../../pages/customers/customers.component';\nimport { SuppliersComponent } from '../../pages/suppliers/suppliers.component';\nimport { TasksComponent } from '../../pages/tasks/tasks.component';\n\n@NgModule({\n  declarations: [\n    CustomersComponent,\n    SuppliersComponent,\n    TasksComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class GeneralModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { TenantSettingsComponent } from '../../pages/tenant-settings/tenant-settings.component';\nimport { TenantsComponent } from '../../pages/tenants/tenants.component';\nimport { BugComponent } from '../../pages/bug/bug.component';\nimport { MembershipComponent } from '../../pages/membership/membership.component';\nimport { PlansComponent } from '../../pages/plans/plans.component';\nimport { FeaturesComponent } from '../../pages/features/features.component';\nimport { PlanFeaturesComponent } from '../../pages/plan-features/plan-features.component';\nimport { SubscriptionPageComponent } from '../../pages/subscription/subscription.component';\nimport { BillingPageComponent } from '../../pages/billing/billing.component';\n\n@NgModule({\n  declarations: [\n    TenantSettingsComponent,\n    TenantsComponent,\n    BugComponent,\n    MembershipComponent,\n    PlansComponent,\n    FeaturesComponent,\n    PlanFeaturesComponent,\n    SubscriptionPageComponent,\n    BillingPageComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class TenancyModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { ApprovalsComponent } from '../../pages/approvals/approvals.component';\nimport { ApprovalsConfigComponent } from '../../pages/approvals-config/approvals-config.component';\nimport { NotificationsComponent } from '../../pages/notifications/notifications.component';\nimport { AppModelsComponent } from '../../pages/app-models/app-models.component';\nimport { NotificationsConfigComponent } from '../../pages/notifications-config/notifications-config.component';\nimport { SyncComponent } from '../../pages/sync/sync.component'; // Added: TinSync pending-changes page\n\n@NgModule({\n  declarations: [\n    ApprovalsComponent,\n    ApprovalsConfigComponent,\n    NotificationsComponent,\n    AppModelsComponent,\n    NotificationsConfigComponent,\n    SyncComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class WorkflowModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { OverviewDashboardComponent } from '../../pages/overview/overview-dashboard/overview-dashboard.component';\n\n@NgModule({\n  declarations: [\n    OverviewDashboardComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule\n  ]\n})\nexport class OverviewModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaAdminModule } from '../spa-admin.module';\nimport { FixedAssetsDashboardComponent } from '../../pages/assets/fixed-assets-dashboard/fixed-assets-dashboard.component';\nimport { FixedAssetsComponent } from '../../pages/accounting/fixed-assets/fixed-assets.component';\nimport { FixedAssetCategoriesComponent } from '../../pages/accounting/fixed-asset-categories/fixed-asset-categories.component';\n\n// Changed: Fixed Assets module — separated from Accounting module\n@NgModule({\n  declarations: [\n    FixedAssetsDashboardComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaAdminModule,\n    FixedAssetsComponent,\n    FixedAssetCategoriesComponent\n  ]\n})\nexport class AssetsModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaMatModule } from '../../modules/spa-mat.module';\nimport { TinSpaModule } from '../../tin-spa.module'; // spa-tiles / spa-table for the config-driven sections\nimport { DayBookComponent } from './day-book.component';\n\n// Changed: the module now declares and exports <spa-day-book> and nothing else — the *spaDayBookSection /\n// *spaDayBookSectionHeader template slots are gone, and with them the reason an app ever had to host the page\n// in a component of its own. It is still a separate module (rather than folded away) for the two entry points\n// that remain: SpaHomeRoutingModule's route, and an app that wants the page inside its own shell — both get\n// the same config-driven rendering now. Carries no routes and no providers, so importing it is free. Named\n// SpaDayBookModule because the DTO interface `SetupModule` already owns the plain `SetupModule` name in\n// Classes.ts, which makes it unexportable from the public entry point.\n@NgModule({\n  declarations: [\n    DayBookComponent\n  ],\n  imports: [\n    CommonModule,\n    SpaMatModule,\n    TinSpaModule\n  ],\n  exports: [\n    DayBookComponent\n  ]\n})\nexport class SpaDayBookModule { }\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { SpaMatModule } from '../spa-mat.module';\nimport { TinSpaModule } from '../../tin-spa.module'; // Added: spa-checklist for the step groups\nimport { SetupGuideComponent } from '../../pages/setup-guide/setup-guide.component';\nimport { SpaDayBookModule } from '../../pages/day-book/day-book.module'; // Changed: the Day Book page moved into its own exportable module (apps host it and project row templates)\nimport { AppConfigurationComponent } from '../../pages/app-configuration/app-configuration.component'; // Added: centralized App Configuration page\n\n// Setup readiness (\"Getting Started\") + Day Book + App Configuration module — component declarations only,\n// routed by SpaHomeRoutingModule. These three are the config-driven \"how this app runs\" pages.\n@NgModule({\n  declarations: [\n    SetupGuideComponent,\n    AppConfigurationComponent // Added: spa-app-configuration\n  ],\n  imports: [\n    CommonModule,\n    SpaMatModule,\n    TinSpaModule, // Changed: replaces FormsModule — checkboxes gave way to spa-checklist + state-icon rows\n    SpaDayBookModule // Changed: spa-day-book is declared there now, so SpaHomeRoutingModule can still route to it\n  ]\n})\nexport class SetupModule { }\n","import { NgModule } from '@angular/core';\nimport { SpaHomeRoutingModule } from './spa-home-routing.module';\n// Domain modules (component declarations only, no routing)\nimport { AdminModule } from './admin/admin.module';\nimport { UserModule } from './user/user.module';\nimport { AccountingModule } from './accounting/accounting.module';\nimport { InventoryModule } from './inventory/inventory.module';\nimport { SalesModule } from './sales/sales.module';\nimport { PurchasingModule } from './purchasing/purchasing.module';\nimport { HRModule } from './hr/hr.module';\nimport { PayrollModule } from './payroll/payroll.module';\nimport { ManufacturingModule } from './manufacturing/manufacturing.module';\nimport { LoansModule } from './loans/loans.module';\nimport { GeneralModule } from './general/general.module';\nimport { TenancyModule } from './tenancy/tenancy.module';\nimport { WorkflowModule } from './workflow/workflow.module';\nimport { OverviewModule } from './overview/overview.module';\nimport { AssetsModule } from './assets/assets.module'; // Changed: Added Fixed Assets module\nimport { SetupModule } from './setup/setup.module'; // Added: Setup readiness (\"Getting Started\") module\n\n// Single import for consumer apps — provides all domain routes and components\n// Usage in consumer home-routing.module.ts:\n//   { path: '', loadChildren: () => import('tin-spa').then(m => m.SpaHomeModule) }\n@NgModule({\n  imports: [\n    SpaHomeRoutingModule,\n    AdminModule,\n    UserModule,\n    AccountingModule,\n    InventoryModule,\n    SalesModule,\n    PurchasingModule,\n    HRModule,\n    PayrollModule,\n    ManufacturingModule,\n    LoansModule,\n    GeneralModule,\n    TenancyModule,\n    WorkflowModule,\n    OverviewModule,\n    AssetsModule, // Changed: Added Fixed Assets module\n    SetupModule // Added: Setup readiness (\"Getting Started\") module\n  ]\n})\nexport class SpaHomeModule { }\n","// Config surface for the authorized document pipeline (viewer, fetch, type detection).\n// Deliberately declared in its own file rather than appended to Classes.ts, following the MapClasses.ts\n// precedent: Classes.ts is a very hot shared file and was locked by another worker when this landed, and a\n// self-contained contract keeps the document feature reviewable in one place.\n//\n// 🔴 THE CENTRAL DESIGN CONSTRAINT: there is deliberately NO url / blobUrl / storageUrl member anywhere in\n// this file. Every document byte is fetched from the app's OWN API through DocumentService, so the bearer\n// token, the capability gate and tenant scoping apply to all of them. Documents used to be pulled\n// browser-direct out of an Azure container marked PublicAccessType.Blob — world-readable by URL, with no\n// capability check and no audit. A direct-to-storage URL is made UNREPRESENTABLE here so that hole cannot be\n// reopened by configuration. If you find yourself wanting to add one, the answer is a streamUrl instead.\n\nimport { Action } from './Classes';\n\n// Describes where a field's documents come from. The list gives the NAMES, the stream gives the BYTES —\n// both through the app's API.\nexport interface DocumentSource {\n  // Returns the file names for one parent row, e.g. { url: 'docs/files/{keyField}' }.\n  listAction: Action;\n\n  // The authorized per-document stream, e.g. 'docs/document/{keyField}/{fileName}'.\n  // Served by BaseController.GetDocument, which returns raw bytes on success and a real 403/404 on refusal.\n  streamUrl: string;\n\n  // Offer \"Save a copy\" as a secondary action. Default true. This downloads the ALREADY-FETCHED blob from\n  // its object URL — it never constructs a second, unauthorized route to the bytes.\n  downloadable?: boolean;\n\n  // Optional client-side filter on what the viewer will list/offer. Purely cosmetic: the server remains the\n  // only authority on what may be read, and this must never be mistaken for a security control.\n  allowedExtensions?: string[];\n}\n\n// What a document turns out to be, which decides which renderer Phase 4/5 mounts.\nexport type DocumentKind = 'pdf' | 'image' | 'word' | 'excel' | 'text' | 'unsupported';\n\n// A document that has been fetched and is ready to render.\nexport interface LoadedDocument {\n  fileName: string;\n  kind: DocumentKind;\n  contentType: string;\n  size: number;\n\n  // An object URL over the fetched blob. This is what replaces the old remote iframe src, and it is the\n  // reason nothing needs a public URL. 🔴 It MUST be released through DocumentService.release() /\n  // releaseAll() — an unrevoked object URL pins its whole blob in memory for the life of the document.\n  objectUrl: string;\n\n  blob: Blob;\n}\n\n// What openDocumentViewer() is handed. Note what is NOT here: no url, no base path, no container name —\n// only a streamUrl TEMPLATE that resolves against the app's own API, for the same reason DocumentSource\n// carries none. The viewer cannot address storage directly even if a caller wanted it to.\nexport interface DocumentViewerData {\n  // The file names in the set. ONE name means no picker rail is rendered at all — see the FSD's\n  // \"picker rule\": with a single document the rail is absent from the DOM, not merely hidden by CSS.\n  documents: string[];\n\n  // Which of them opens first. Falls back to the first entry when absent or not in the set.\n  fileName?: string;\n\n  // The authorized per-document stream template, e.g. 'docs/document/{keyField}/{fileName}'.\n  // {fileName} is substituted per document; everything else comes from `values`.\n  streamUrl: string;\n\n  // The placeholder bag for every token in streamUrl other than {fileName}, e.g. { keyField: 42 }.\n  values?: { [key: string]: any };\n\n  // Offer \"Save a copy\". Defaults to true. Saves the ALREADY-FETCHED blob out of its object URL, so it\n  // never constructs a second, unauthorized route to the bytes.\n  downloadable?: boolean;\n\n  // Optional label for the set, shown in the toolbar beside the file name.\n  title?: string;\n}\n\n// A refusal, surfaced rather than swallowed. The house bug this exists to prevent is the silent failure:\n// a viewer that renders an empty stage on a 403 tells the user nothing and looks like a broken document.\nexport interface DocumentError {\n  // 🔴 The stream branches on HTTP STATUS, never on response.Success. Its success body is raw bytes, not a\n  // RepoResponse, so a 200 carrying JSON would be indistinguishable from a 200 carrying a PDF.\n  status: number;\n\n  // 'denied' 403 · 'missing' 404 · 'unauthenticated' 401 · 'network' 0 · 'failed' anything else.\n  reason: 'denied' | 'missing' | 'unauthenticated' | 'network' | 'failed';\n\n  // Already phrased for a human — the viewer shows this directly.\n  message: string;\n\n  fileName: string;\n}\n","// Config interfaces for the spa-landing component\n// Consumer apps provide this config to drive the entire landing page\n\nexport interface LandingColors {\n  primary: string;        // e.g. '#1E3A5F'\n  primaryDark: string;    // e.g. '#152C4A'\n  primaryLight: string;   // e.g. '#EBF0F7'\n  secondary: string;      // e.g. '#F59E0B'\n  secondaryLight: string; // e.g. '#FEF3C7'\n}\n\n// Custom navbar/footer brand (replaces img+appName with inline SVG + wordmark)\nexport interface LandingBrandOverride {\n  svgMarkup: string;         // raw SVG string — will be sanitized before rendering\n  wordmarkLine1?: string;    // e.g. 'alsquare'\n  wordmarkLine2?: string;    // e.g. 'TECHNOLOGIES'\n}\n\nexport interface LandingNavLink {\n  label: string;  // 'Features'\n  target: string; // section ID e.g. 'lp-features'\n}\n\nexport interface LandingFeature {\n  title: string;\n  description: string;\n  icon: string;  // material icon name e.g. 'directions_bus'\n  color: string; // hex color for icon tint e.g. '#1E3A5F'\n}\n\nexport interface LandingStep {\n  number: string;      // e.g. '01', '02'\n  title: string;\n  description: string;\n  icon: string;        // material icon name\n}\n\nexport interface LandingModuleTile {\n  name: string;\n  icon: string; // material icon name\n}\n\nexport interface LandingModuleGroup {\n  category: string;\n  tiles: LandingModuleTile[];\n}\n\nexport interface LandingMetric {\n  value: string; // e.g. '35%'\n  label: string; // e.g. 'Reduction in fuel costs'\n}\n\nexport interface LandingSecurityItem {\n  icon: string;        // material icon name e.g. 'shield'\n  title: string;\n  description: string;\n}\n\nexport interface LandingTestimonial {\n  quote: string;\n  authorName: string;\n  authorRole: string;\n  authorInitials: string; // 2-letter initials for the avatar circle e.g. 'MN'\n}\n\nexport interface LandingPricingPlan {\n  name: string;         // 'Starter', 'Fleet', 'Enterprise'\n  price: string;        // '$0', '$99', 'Custom'\n  period?: string;      // '/month' (omit for Custom)\n  description: string;\n  features: string[];\n  ctaLabel: string;     // 'Get Started Free', 'Start Free Trial'\n  ctaRoute?: string;    // navigateTo route e.g. 'signup'\n  ctaSection?: string;  // scrollToSection target e.g. 'lp-footer'\n  popular?: boolean;    // shows 'Most Popular' badge + primary button styling\n  outline?: boolean;    // use outline button (default when popular is not set)\n}\n\nexport interface LandingFooterLink {\n  label: string;\n  section?: string;  // scrollToSection target\n  route?: string;    // navigateTo route\n}\n\nexport interface LandingFooterColumn {\n  title: string;\n  links: LandingFooterLink[];\n}\n\nexport interface LandingConfig {\n  // Branding\n  appName: string;    // 'Shift', 'Pulse', etc.\n  logoSrc: string;    // './assets/icon.png'\n  colors: LandingColors;\n\n  // Custom navbar brand (optional — replaces img+appName with SVG+wordmark)\n  navBrand?: LandingBrandOverride;\n\n  // Navbar\n  navLinks: LandingNavLink[];\n\n  // Hero section\n  hero: {\n    badge?: string;              // optional pill above headline e.g. '✦ Now available'\n    headline: string;            // text before gradientText\n    gradientText: string;        // colored/gradient portion of headline\n    subtitle: string;\n    primaryCTA: string;          // 'Start Free Trial'\n    primaryCTARoute?: string;    // defaults to 'signup'\n    secondaryCTA: string;        // 'Explore Features'\n    secondaryCTASection: string; // section ID to scroll to\n    trustSignals: string[];      // ['No credit card required', ...]\n    layout?: 'centered' | 'split'; // 'split' shows ng-content[lpHeroVisual] on right. Default: 'centered'\n    watermarkSvg?: string;       // raw SVG string shown as faded background watermark\n  };\n\n  // Features section\n  features: {\n    title: string;\n    subtitle: string;\n    items: LandingFeature[];\n  };\n\n  // Workflow/Steps section (optional)\n  workflow?: {\n    title: string;\n    subtitle?: string;\n    style?: 'steps' | 'road'; // 'steps' = numbered card grid (default), 'road' = waypoints on a road line\n    steps: LandingStep[];\n  };\n\n  // Modules section (optional)\n  modules?: {\n    title: string;\n    subtitle: string;\n    groups: LandingModuleGroup[];\n  };\n\n  // Metrics/stats section (optional)\n  metrics?: LandingMetric[];\n\n  // Security section (optional — dark background, icon cards)\n  security?: {\n    title: string;\n    subtitle: string;\n    items: LandingSecurityItem[];\n  };\n\n  // Testimonials section (optional)\n  testimonials?: {\n    title: string;\n    subtitle?: string;\n    items: LandingTestimonial[];\n  };\n\n  // Pricing section (optional)\n  pricing?: {\n    title: string;\n    subtitle?: string;\n    plans: LandingPricingPlan[];\n  };\n\n  // Final CTA banner section (optional)\n  finalCta?: {\n    headline: string;\n    subtitle: string;\n    primaryCTA: string;\n    primaryCTARoute?: string;    // navigateTo route\n    secondaryCTA?: string;\n    secondaryCTASection?: string; // scrollToSection target\n  };\n\n  // Footer\n  footerCompany?: string;        // copyright name — defaults to 'alsquare technologies'\n  footerTagline?: string;        // tagline text below footer brand\n  footerBrand?: LandingBrandOverride; // custom SVG brand in footer (same type as navBrand)\n  footerColumns?: LandingFooterColumn[]; // multi-column link groups (Product, Resources, Contact…)\n}\n\n// Alsquare brand SVG — dark variant (for navbar on light backgrounds)\nexport const ALSQUARE_SVG_DARK = `<svg viewBox=\"0 0 80 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n  <path d=\"M32 62C17.6 62 6 50.4 6 36S17.6 10 32 10c9.2 0 17.3 4.9 21.8 12.2\" stroke=\"#1a3a7a\" stroke-width=\"9\" stroke-linecap=\"round\" fill=\"none\"/>\n  <circle cx=\"32\" cy=\"36\" r=\"10\" fill=\"white\" stroke=\"#1a3a7a\" stroke-width=\"7\"/>\n  <circle cx=\"32\" cy=\"36\" r=\"5.5\" fill=\"#e8a020\"/>\n  <line x1=\"48\" y1=\"22\" x2=\"48\" y2=\"62\" stroke=\"#1a3a7a\" stroke-width=\"9\" stroke-linecap=\"round\"/>\n  <rect x=\"56\" y=\"6\" width=\"7\" height=\"56\" rx=\"3.5\" fill=\"#e8a020\"/>\n  <rect x=\"67\" y=\"0\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#1a3a7a\"/>\n  <rect x=\"67\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#1a3a7a\"/>\n  <rect x=\"75\" y=\"0\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#1a3a7a\" opacity=\"0.7\"/>\n  <rect x=\"75\" y=\"8\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#1a3a7a\" opacity=\"0.5\"/>\n</svg>`;\n\n// Alsquare brand SVG — white variant (for footer on dark backgrounds)\nexport const ALSQUARE_SVG_WHITE = `<svg viewBox=\"0 0 80 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n  <path d=\"M32 62C17.6 62 6 50.4 6 36S17.6 10 32 10c9.2 0 17.3 4.9 21.8 12.2\" stroke=\"#ffffff\" stroke-width=\"9\" stroke-linecap=\"round\" fill=\"none\"/>\n  <circle cx=\"32\" cy=\"36\" r=\"10\" fill=\"#0f172a\" stroke=\"#ffffff\" stroke-width=\"7\"/>\n  <circle cx=\"32\" cy=\"36\" r=\"5.5\" fill=\"#e8a020\"/>\n  <line x1=\"48\" y1=\"22\" x2=\"48\" y2=\"62\" stroke=\"#ffffff\" stroke-width=\"9\" stroke-linecap=\"round\"/>\n  <rect x=\"56\" y=\"6\" width=\"7\" height=\"56\" rx=\"3.5\" fill=\"#e8a020\"/>\n  <rect x=\"67\" y=\"0\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#ffffff\"/>\n  <rect x=\"67\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" fill=\"#ffffff\"/>\n  <rect x=\"75\" y=\"0\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#ffffff\" opacity=\"0.7\"/>\n  <rect x=\"75\" y=\"8\" width=\"5\" height=\"5\" rx=\"1\" fill=\"#ffffff\" opacity=\"0.5\"/>\n</svg>`;\n","/*\n * Public API Surface of tin-spa\n */\n\n\n\n//Services\nexport * from './lib/services/tin-spa.service';\nexport * from './lib/services/storage.service';\nexport * from './lib/services/message.service';\nexport * from './lib/services/export.service';\nexport * from './lib/services/auth.service';\nexport * from './lib/services/datalib.service';\nexport * from './lib/services/log.service';\nexport * from './lib/services/http.service';\nexport * from './lib/services/loader.service';\nexport * from './lib/services/dialog.service';\nexport * from './lib/services/accounting.service';\nexport * from './lib/services/assets.service'; // Changed: Added Fixed Assets service export\nexport * from './lib/services/loans.service';\nexport * from './lib/services/inventory.service';\nexport * from './lib/services/sales.service'; // Added: consumer apps need saleCreateButton for the Getting Started \"record a sale\" step\nexport * from './lib/services/purchasing.service'; // Added: quickPurchaseButton for the Getting Started \"record a purchase\" step\nexport * from './lib/services/production.service'; // Added: recipeCreateButton for the Getting Started \"create a recipe\" step\nexport * from './lib/services/payroll.service'; // Added: salaryStructuresTableConfig for the Getting Started \"salary structure\" step\nexport * from './lib/services/general.service';\nexport * from './lib/services/tab.service'; // Changed: Export tab service\nexport * from './lib/services/subscription.service'; // Added: Subscription feature-checking service\nexport * from './lib/services/update.service'; // Added: PWA update notification service\nexport * from './lib/services/push-notification.service'; // Changed: PWA push notification service\nexport * from './lib/services/notifications.service'; // Changed: Notification count + push message listener\nexport * from './lib/services/agent.service'; // Changed: Agent chat state management + API service (renamed from assistant)\nexport * from './lib/services/analytics.service'; // Changed: GA4 route tracking service for SPA page_view events\nexport * from './lib/services/offline.service'; // Added: TinSync unified offline service\nexport * from './lib/services/api-error.service'; // Added: friendly, de-duplicated API failure messages\nexport * from './lib/services/setup.service'; // Added: Setup readiness (\"Getting Started\") badge/status service\nexport * from './lib/services/config.service'; // Added: shared app-wide App Configuration record (config$)\nexport * from './lib/services/last-route.service'; // Added: resumeLastRoute — resume a session on the user's last page\nexport * from './lib/services/tenant-transfer.service'; // Added (N11): Organisation Transfers — shared cross-organisation money page\nexport * from './lib/services/password-policy.service'; // Added: ONE generator for the password rule wording, built from the tenant's PasswordConfig — replaces three hard-coded copies that had drifted from the enforced rule\nexport * from './lib/pages/setup-guide/setup-guide.component'; // Added: Getting Started page component\nexport * from './lib/pages/day-book/day-book.component'; // Added: centralized Day Book page component\nexport * from './lib/pages/app-configuration/app-configuration.component'; // Added: centralized App Configuration page component\nexport * from './lib/pages/password-policy/password-policy.component'; // Added: per-tenant Password Policy admin page (N8)\nexport * from './lib/pages/agent-page/agent-page.component'; // Added: routed chat page component (home/agent)\nexport * from './lib/components/offline/offline-indicator.component'; // Added: TinSync toolbar indicator\nexport * from './lib/pages/sync/sync.component'; // Added: TinSync pending-changes page\n\n// Guards\n\nexport * from './lib/guards/auth.guard';\nexport * from './lib/guards/feature.guard'; // Added: Plan-based feature route guard\nexport * from './lib/guards/module.guard'; // Added (F3): tenant module route guard — exported only; the library never attaches it to a route\nexport * from './lib/guards/capability.guard'; // Added (Phase 4): role capability route guard — exported only, on the same terms as moduleGuard; the library declares inert data.capName but attaches no guard of its own\n\n// Directives\nexport * from './lib/directives/feature.directive'; // Added: *spaFeature structural directive\nexport * from './lib/directives/ellipsis.directive'; // Added: tinEllipsis — truncation probe behind the tile/section tooltips\n\n//classes\nexport * from './lib/classes/Classes';\nexport * from './lib/classes/TinCore';\nexport * from './lib/classes/LibClasses';\nexport * from './lib/classes/perceived-progress'; // Added: Quiet Loading — perceived-progress easing engine\n\n\n// Runtime configuration (routing strategy, real-time, MSAL) — provideTinSpaRuntime()\nexport * from './lib/runtime/tinspa-runtime';\n// Server-editable per-environment settings (assets/appsettings.json) — loadTinSpaAppSettings()\nexport * from './lib/runtime/appsettings';\n// Quiet Loading — silent-request context token + the config-over-app precedence resolver\nexport * from './lib/runtime/silent-request';\nexport * from './lib/runtime/quiet-loading';\n// Added: spinning-refresh state for form fields that load options from a loadAction (same anti-flicker contract)\nexport * from './lib/runtime/field-load-indicator';\n\n//modules\nexport * from './lib/tin-spa.module';\nexport * from './lib/modules/spa-mat.module'\nexport * from './lib/modules/spa-index.module'\nexport * from './lib/modules/spa-user.module'\nexport * from './lib/modules/spa-admin.module'\nexport * from './lib/modules/index/index.module'\nexport * from './lib/modules/admin/admin.module'\nexport * from './lib/modules/user/user.module'\n// Changed: SpaHomeModule — single import for consumer apps (includes all domain modules + routing)\nexport * from './lib/modules/spa-home.module'\n// Changed: SpaDayBookModule now exports spa-day-book alone. The *spaDayBookSection / *spaDayBookSectionHeader\n// template slots are gone — the Day Book is config-driven and has exactly one rendering path.\nexport * from './lib/pages/day-book/day-book.module'\n// Domain-specific feature modules (used internally by SpaHomeModule)\nexport * from './lib/modules/accounting/accounting.module'\nexport * from './lib/modules/inventory/inventory.module'\nexport * from './lib/modules/sales/sales.module'\nexport * from './lib/modules/purchasing/purchasing.module'\nexport * from './lib/modules/hr/hr.module'\nexport * from './lib/modules/payroll/payroll.module'\nexport * from './lib/modules/manufacturing/manufacturing.module'\nexport * from './lib/modules/loans/loans.module'\nexport * from './lib/modules/general/general.module'\nexport * from './lib/modules/tenancy/tenancy.module'\nexport * from './lib/modules/workflow/workflow.module'\nexport * from './lib/modules/overview/overview.module'\n\n\n\n//components\nexport * from './lib/components/import/import-dialog.component'; // Added: generic AI-assisted data import wizard\nexport * from './lib/components/tin-spa.component';\nexport * from './lib/components/tiles/tiles.component';\nexport * from './lib/components/filter-chips/filter-chips.component'; // Added: FilterChipsComponent — the opt-in quick-filter chip row (FilterChip / FilterChipConfig come from Classes)\nexport * from './lib/components/alert/alert.component';\nexport * from './lib/components/date/date.component';\nexport * from './lib/components/text/text.component';\nexport * from './lib/components/text-mask/text-mask.component'; // Changed: Export text-mask instead of password\nexport * from './lib/components/text-area/text-area.component'; // Changed: Export text-area component\nexport * from './lib/components/text-single/text-single.component'; // Changed: Export text-single (autocomplete)\nexport * from './lib/components/text-multi/text-multi.component'; // Changed: Renamed from multi-text\nexport * from './lib/components/label/label.component';\nexport * from './lib/components/datetime/datetime.component';\nexport * from './lib/components/select/select.component';\nexport * from './lib/components/select-lite/select-lite.component'; // Changed: Export select-lite component\nexport * from './lib/components/select-multi/select-multi.component'; // Changed: Renamed from multi-select\nexport * from './lib/components/select-bitwise/select-bitwise.component';\nexport * from './lib/components/attach/attach.component';\nexport * from './lib/components/check/check.component';\nexport * from './lib/components/money/money.component';\nexport * from './lib/components/chips/chips.component';\nexport * from './lib/components/activity/activity.component';\n// export * from './lib/components/html/html.component';\nexport * from './lib/components/option/option.component';\nexport * from './lib/components/steps/steps.component';\nexport * from './lib/components/checklist/checklist.component'; // Added: flat collapsible checklist (spa-checklist)\nexport * from './lib/components/progress-ring/progress-ring.component'; // Added: circular n-of-m ring (spa-progress-ring)\nexport * from './lib/components/filter/filter.component';\nexport * from './lib/components/message/messageDialog.component';\nexport * from './lib/components/loader/loader.component';\n\nexport * from './lib/components/monogram/monogram.component'; // Added: monogram column type + its pure initials/palette helpers\nexport * from './lib/components/table/table.component';\nexport * from './lib/components/table/detailsDialog.component';\nexport * from './lib/components/form/form.component';\nexport * from './lib/components/form-skeleton/form-skeleton.component'; // Added: Quiet Loading — form skeleton (FSD D6)\nexport * from './lib/components/number/number.component';\nexport * from './lib/components/search/search.component';\n// Removed (Phase 7, BREAKING): spa-viewer and viewerDialog are deleted. Use Field.documentSource (<spa-document>) and DialogService.openDocumentViewer().\nexport * from './lib/components/map/map.component'; // Added: map viewer revamp — <spa-map>\nexport * from './lib/components/map/mapDialog.component'; // Added: exports openMapDialog(), the supported way to open the viewer\nexport * from './lib/classes/MapClasses'; // Added: MapConfig, MapPoint, parseMapPoint, formatMapPoint. Added (GPS phase 4): MapMarker, MapPositionUpdate, normaliseMarkers, markerKey, updatePoint — the multi-marker + live-position surface, all renderer-agnostic\nexport * from './lib/services/signalr.service'; // Added (GPS phase 4): SignalRService + VehiclePositionFrame. It was previously internal, but a consumer's fleet page has to subscribe to vehiclePosition$ to drive the map, and reaching into a deep path is not a supported import. Additive — the service is already provided in root, so nothing changes for anyone who does not import it\n// Removed 2026-08-19: map-loader.service resolved the Google Maps JS API global. spa-map now bundles\n// Leaflet and loads no third-party script at all, so the service had no remaining purpose and leaving a\n// Google loader exported from a keyless-OSM component would be a trap. Nothing consumed it — verified by\n// grep across the workspace before deleting.\nexport * from './lib/classes/DocumentClasses'; // Added: DocumentSource, DocumentKind, LoadedDocument, DocumentError — the document contract, which deliberately cannot express a direct storage URL\nexport * from './lib/services/document.service'; // Added: authorized document fetch + object-URL lifecycle\nexport * from './lib/components/document-viewer/documentViewerDialog.component'; // Added: the full-bleed document viewer, opened via DialogService.openDocumentViewer()\nexport * from './lib/components/document-viewer/document.component'; // Added (Phase 6): DocumentComponent (<spa-document>) + DocumentEntry — the file-view field's shelf. This line previously repeated the documentViewerDialog export immediately above it, which exported nothing new\nexport * from './lib/components/nav-menu/nav-menu.component';\nexport * from './lib/components/list-dialog/list-dialog.component';\nexport * from './lib/components/table-dialog/table-dialog.component'; // Added: spa-table-dialog + readOnlyTableConfig (the hardening a consumer can reuse outside the dialog)\nexport * from './lib/components/terms-dialog/terms-dialog.component';  // Changed: Added missing export\nexport * from './lib/components/privacy-dialog/privacy-dialog.component';  // Changed: Added missing export\nexport * from './lib/components/email/email.component';\nexport * from './lib/components/page/page.component';\nexport * from './lib/components/html/html.component';\nexport * from './lib/components/editor/editor.component'; // Added: rich-text/WYSIWYG field (type:'editor')\nexport * from './lib/components/notes/notes.component';\nexport * from './lib/components/capsules/capsules.component';\nexport * from './lib/components/tabs/tabs.component';\n// Removed: tabs-internal and tabs-lite exports — consolidated into TabsComponent\nexport * from './lib/components/statuses/statuses.component';\nexport * from './lib/components/groups/groups.component';\nexport * from './lib/components/title-actions/title-actions.component';\nexport * from './lib/components/charts/charts.component'; // Changed: Export ChartsComponent for consumer apps\nexport * from './lib/components/agent/agent.component'; // Changed: Agent chat widget (renamed from assistant)\n\n//pages\nexport * from './lib/pages/tasks/tasks.component';\n\nexport * from './lib/pages/departments/departments.component';\nexport * from './lib/pages/employees/employees.component';\nexport * from './lib/pages/positions/positions.component';\nexport * from './lib/pages/grades/grades.component';\nexport * from './lib/pages/onboarding/onboarding.component'; // Changed: updated path from welcome to onboarding\nexport * from './lib/pages/customers/customers.component';\nexport * from './lib/pages/suppliers/suppliers.component';\nexport * from './lib/pages/categories/categories.component';\nexport * from './lib/pages/subcategories/subcategories.component';\nexport * from './lib/pages/brands/brands.component';\n\nexport * from './lib/pages/tenants/tenants.component';\nexport * from './lib/pages/membership/membership.component';\nexport * from './lib/pages/plans/plans.component';\nexport * from './lib/pages/subscription/subscription.component'; // Added: Subscription management page export\nexport * from './lib/pages/billing/billing.component'; // Added: Billing & invoice history page export\nexport * from './lib/pages/app-models/app-models.component';\nexport * from './lib/pages/users/users.component';\nexport * from './lib/pages/login/login.component';\n\nexport * from './lib/pages/roles/roles.component';\nexport * from './lib/pages/signup/signup.component';\nexport * from './lib/pages/change-password/change-password.component';\nexport * from './lib/pages/profile/profile.component';\nexport * from './lib/pages/recover-account/recover-account.component';\nexport * from './lib/pages/create-account/create-account.component';\n\nexport * from './lib/pages/logs/logs.component';\nexport * from './lib/pages/settings/settings.component';\n\n// Accounting Module - New accounting components\nexport { AccountsComponent as AccountingAccountsComponent } from './lib/pages/accounting/accounts/accounts.component';\nexport { AggregatesComponent as AccountingAggregatesComponent } from './lib/pages/accounting/aggregates/aggregates.component'; // Added: Aggregates component export\nexport { AgingComponent as AccountingAgingComponent } from './lib/pages/accounting/aging/aging.component'; // Added: Aging component export\nexport { TransactionTypesComponent as AccountingTransactionTypesComponent } from './lib/pages/accounting/transaction-types/transaction-types.component';\nexport { TransactionsComponent as AccountingTransactionsComponent } from './lib/pages/accounting/transactions/transactions.component';\nexport { InvoicesComponent as AccountingInvoicesComponent } from './lib/pages/accounting/invoices/invoices.component';\nexport { StatementComponent as AccountingStatementComponent } from './lib/pages/accounting/outstanding-invoices/outstanding-invoices.component'; // Changed: Export StatementComponent (replaces OutstandingInvoicesComponent)\nexport { ReportsComponent as AccountingReportsComponent } from './lib/pages/accounting/reports/reports.component'; // Added: Financial Reports component export\nexport { CreditNotesComponent as AccountingCreditNotesComponent } from './lib/pages/accounting/credit-notes/credit-notes.component'; // Changed: Credit notes page export (B6)\nexport { VatReturnComponent as AccountingVatReturnComponent } from './lib/pages/accounting/vat-return/vat-return.component'; // Changed: VAT return page export (B2)\nexport { FiscalPeriodsComponent } from './lib/pages/accounting/fiscal-periods/fiscal-periods.component'; // Changed: Fiscal periods page export (C2)\nexport { ReceiptsComponent } from './lib/pages/accounting/receipts/receipts.component'; // Changed: Customer receipts page export (C3)\nexport { ReceiptDialogComponent } from './lib/pages/accounting/receipts/receipt-dialog.component'; // Changed: Receipt dialog export (C3)\nexport { BankReconciliationComponent } from './lib/pages/accounting/bank-reconciliation/bank-reconciliation.component'; // Changed: Bank reconciliation page export (C4)\nexport { StatementImportDialogComponent } from './lib/pages/accounting/bank-reconciliation/statement-import-dialog.component'; // Changed: Statement import dialog export (C4)\nexport { ReconcileDialogComponent } from './lib/pages/accounting/bank-reconciliation/reconcile-dialog.component'; // Changed: Reconcile dialog export (C4)\nexport { RevenueSchedulesComponent } from './lib/pages/accounting/revenue-schedules/revenue-schedules.component'; // Changed: Deferred revenue page export (C7)\nexport { RevenueScheduleDialogComponent } from './lib/pages/accounting/revenue-schedules/revenue-schedule-dialog.component'; // Changed: Defer revenue dialog export (C7)\nexport { QuotesComponent } from './lib/pages/accounting/quotes/quotes.component'; // Changed: Quotations page export (C10)\nexport { CurrenciesComponent as AccountingCurrenciesComponent } from './lib/pages/accounting/currencies/currencies.component'; // Changed: Currencies component export for multi-currency support\n\n// Accounting Dashboard\nexport { AccountingDashboardComponent } from './lib/pages/accounting/accounting-dashboard/accounting-dashboard.component'; // Changed: Added accounting dashboard export\n\n// Inventory Dashboard (re-export for consumer apps)\nexport { InventoryDashboardComponent } from './lib/pages/inventory/inventory-dashboard/inventory-dashboard.component'; // Changed: Added inventory dashboard export\n\n// Sales Dashboard\nexport { SalesDashboardComponent } from './lib/pages/sales/sales-dashboard/sales-dashboard.component'; // Changed: Added sales dashboard export\n\n// Purchasing Dashboard\nexport { PurchasingDashboardComponent } from './lib/pages/purchasing/purchasing-dashboard/purchasing-dashboard.component'; // Changed: Added purchasing dashboard export\n\n// Overview Dashboard\nexport { OverviewDashboardComponent } from './lib/pages/overview/overview-dashboard/overview-dashboard.component'; // Changed: Added overview dashboard export\n\n// Invoice Dashboard\nexport { InvoiceDashboardComponent } from './lib/pages/accounting/invoice-dashboard/invoice-dashboard.component'; // Changed: Added invoice dashboard export\n\n// Payroll Dashboard\nexport { PayrollDashboardComponent } from './lib/pages/payroll/payroll-dashboard/payroll-dashboard.component'; // Changed: Added payroll dashboard export\n\n// Loans Module\nexport * from './lib/pages/loans/loan-products/loan-products.component';\nexport * from './lib/pages/loans/loans/loans.component';\nexport * from './lib/pages/loans/loan-payments/loan-payments.component';\n\n// Changed: Preferences component DELETED — merged into spa-app-configuration (exported near the Day Book above)\n\n// Invitations Table Component\nexport * from './lib/pages/invitations-table/invitations-table.component'; // Changed: Exported for use in HRModule and TenancyModule\n\n// Welcome/Overview Component\nexport * from './lib/pages/welcome/welcome.component';\n\n// Landing Page Component\nexport * from './lib/pages/landing/landing.config';\nexport * from './lib/pages/landing/landing.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i1","i3","i4","i5","i6","i1.MessageService","i3.StorageService","i4.HttpService","i5.MessageService","i6.LogService","i7.SignalRService","tap","catchError","i1.HttpService","i3.AuthService","i4.OfflineService","i2.DataServiceLib","i7","i3.DataServiceLib","i1.AuthService","i1.DataServiceLib","i2.AuthService","i2.ButtonService","i3.TableConfigService","i2.SignalRService","i3.MessageService","i3.ApiErrorService","i2.ApiErrorService","filter","i2.StorageService","finalize","i8","i9","i10","i11","i12.SuffixComponent","i6.SelectMultiComponent","i7.ChecklistComponent","i5.SuffixComponent","i2.DialogService","i3.ButtonService","i4.MessageService","i5.ApiErrorService","i6.OfflineService","i12","i13","i15","i16.SuffixComponent","i6.SuffixComponent","i11.SuffixComponent","i1.SelectCommonComponent","i14.SuffixComponent","i8.TextComponent","i9.TextSingleComponent","i10.DateComponent","i11.SelectLiteComponent","i12.TextMultiComponent","i13.SelectMultiComponent","i14.EditorComponent","i5.FilterComponent","i6.OptionComponent","i7.CamelToWordsPipe","i2.MessageService","i11.EllipsisDirective","i12.CamelToWordsPipe","i1.ButtonService","i4.CsvService","i9.FilterComponent","i10.TilesComponent","i11.FilterChipsComponent","i6.CheckComponent","i7.MonogramComponent","i8.SelectLiteComponent","i3.DialogService","i4.ButtonService","i11.SelectCommonComponent","i5.CurrencyInputMaskDirective","i9.SuffixComponent","i2.TextComponent","i3.TextAreaComponent","i4.CheckComponent","i5.DateComponent","i6.DatetimeComponent","i7.SelectComponent","i8.MoneyComponent","i9.NumberComponent","i10.EmailComponent","i2.ConditionService","i1.ConditionService","i14","i13.LogService","i17","i18","i19","i20","i21.SearchComponent","i22.TableHeaderComponent","i23.TableRowComponent","i24.TableActionComponent","i25.InlineCellComponent","i26.CapsulesComponent","i27.CardsComponent","i28.GroupsComponent","i29.CamelToWordsPipe","i6.TilesComponent","i7.TableComponent","i3.DocumentService","i4.ApiErrorService","i5.OfflineService","i9.TextComponent","i10.TextMaskComponent","i11.TextAreaComponent","i12.TextSingleComponent","i13.CheckComponent","i14.DateComponent","i15.DatetimeComponent","i16.LabelComponent","i17.SelectComponent","i18.MoneyComponent","i19.AttachComponent","i20.NumberComponent","i21.DocumentComponent","i22.EmailComponent","i23.TextMultiComponent","i24.SelectMultiComponent","i25.HtmlComponent","i26.EditorComponent","i27.NotesComponent","i28.CamelToWordsPipe","i5.CheckComponent","i6.FormComponent","i5.FormComponent","i1.AgentService","i13.CamelToWordsPipe","i14.AgentMarkdownPipe","i2.AgentComponent","switchMap","startWith","map","i1.OfflineService","i2.AlertComponent","i3.TableComponent","timeout","i1.SubscriptionService","i1.LoaderService","i1.SignalRService","i3.NotificationsService","i4.SetupService","i4.NotificationsService","i6.DataServiceLib","i8.SubscriptionService","i9.SetupService","i10.LastRouteService","i11.OfflineService","i16","i22.LoaderComponent","i23.ToastComponent","i24.AgentComponent","i25.BottomTabsComponent","i26.OfflineIndicatorComponent","i5.LogService","i6.StorageService","i7.OfflineService","i8.ApiErrorService","i1.TabService","i4.TableComponent","i6.ButtonService","i7.DialogService","i8.AuthService","i9.TableConfigService","i10.ApiErrorService","i15.SelectComponent","i16.StepsComponent","i17.FormComponent","i18.FormSkeletonComponent","i19.AlertComponent","i20.TabsComponent","i21.StatusesComponent","i22.TabsFloatComponent","i23.CamelToWordsPipe","i3.MapComponent","i5.TableComponent","i13.StepsComponent","i14.TableComponent","i8.CheckComponent","i9.DateComponent","i10.DatetimeComponent","i11.SelectComponent","i12.SelectMultiComponent","i6.TitleActionsComponent","i3.LastRouteService","i5.DataServiceLib","i6.AuthService","i7.LogService","i8.NotificationsService","i9.SignalRService","i12.SetupService","i13.LastRouteService","i14.ApiErrorService","i21","i22.TextComponent","i23.TextMaskComponent","i24","i4.AuthService","i5.StorageService","i11.ApiErrorService","i7.TextComponent","i3.HttpService","i7.ApiErrorService","i8.PasswordPolicyService","i10.TextComponent","i11.TextMaskComponent","i5.AuthService","i6.ApiErrorService","i11.LabelComponent","i3.PageComponent","i1.PageComponent","i4.DataServiceLib","i5.DialogService","i7.MessageService","i16.SelectComponent","i12.CheckComponent","routes","i2.AccountingService","i3.TilesComponent","i4.TabsComponent","i3.TabsComponent","i5.TilesComponent","i6.TabsComponent","i6.DateComponent","i8.PageComponent","i9.SelectLiteComponent","i9.TabsComponent","i2.TilesComponent","i4.SelectLiteComponent","i3.ChartsComponent","i4.TilesComponent","i5.ChartsComponent","i1.TenantTransferService","i2.TableComponent","AccountingAccountsComponent","AccountingAggregatesComponent","AccountingTransactionsComponent","AccountingInvoicesComponent","AccountingAgingComponent","AccountingSupplierAgingComponent","AccountingStatementComponent","AccountingReportsComponent","AccountingBudgetsComponent","AccountingBudgetVsActualComponent","i9.InvitationsTableComponent","i8.TableComponent","i10.SelectComponent","i11.TableComponent","i12.InvitationsTableComponent","i2.SubscriptionService","i2.PageComponent"],"mappings":"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U;AAC1B,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;AAClB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;;AAEnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;AACnB,QAAA,IAAI,CAAC,MAAM,GAAG,KA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"}